From b6cfecf25f212abbd52764835016ee628707ea3b Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 10 Feb 2023 17:15:05 +0100 Subject: [PATCH 01/34] added extra check on transfer_canceled --- src/wallet/wallets_manager.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 02874be6..34b35b2b 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -1901,7 +1901,13 @@ void wallets_manager::on_transfer_canceled(size_t wallet_id, const tools::wallet tei.ti = wti; SHARED_CRITICAL_REGION_LOCAL(m_wallets_lock); - auto& w = m_wallets[wallet_id].w; + auto it = m_wallets.find(wallet_id); + if (it == m_wallets.end()) + { + LOG_ERROR(get_wallet_log_prefix(wallet_id) + "on_transfer_canceled() wallet with id = " << wallet_id << " not found"); + return; + } + auto& w = it->second.w; if (w->get() != nullptr) { w->get()->balance(tei.balances, tei.total_mined); @@ -1909,7 +1915,7 @@ void wallets_manager::on_transfer_canceled(size_t wallet_id, const tools::wallet } else { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "on_transfer() wallet with id = " << wallet_id << " not found"); + LOG_ERROR(get_wallet_log_prefix(wallet_id) + "on_transfer_canceled() wallet with id = " << wallet_id << " has nullptr"); } m_pview->money_transfer_cancel(tei); } From 4a2f0c21650b540fdf2dcfb28493bf66abddc66b Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 14 Feb 2023 14:14:18 +0100 Subject: [PATCH 02/34] moved UI to latest commit with bunch of fixes --- src/gui/qt-daemon/layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index f8d6ed1b..b45d5a82 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit f8d6ed1bbe38d48d7e762154ea9ccbdb33d88424 +Subproject commit b45d5a82285a8804c859e9d3548fae693716cd6a From 123e59920265edc52b40fa3246d97a1d86fc580c Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 15 Feb 2023 19:55:00 +0100 Subject: [PATCH 03/34] small fixes over bug reports --- src/gui/qt-daemon/application/mainwindow.cpp | 18 ++++++++++-------- src/wallet/wallets_manager.cpp | 2 ++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index c4f44b7a..d80df78a 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -18,6 +18,7 @@ #define PREPARE_ARG_FROM_JSON(arg_type, var_name) \ arg_type var_name = AUTO_VAL_INIT(var_name); \ view::api_response default_ar = AUTO_VAL_INIT(default_ar); \ + LOG_PRINT_BLUE("[REQUEST]: " << param.toStdString(), LOG_LEVEL_3); \ if (!epee::serialization::load_t_from_json(var_name, param.toStdString())) \ { \ default_ar.error_code = API_RETURN_CODE_BAD_ARG; \ @@ -28,6 +29,7 @@ template QString make_response(const T& r) { std::string str = epee::serialization::store_t_to_json(r); + LOG_PRINT_BLUE("[RESPONSE]: " << str, LOG_LEVEL_3); return str.c_str(); } @@ -549,6 +551,14 @@ void MainWindow::store_pos(bool consider_showed) void MainWindow::restore_pos(bool consider_showed) { TRY_ENTRY(); + if (consider_showed) + { + if (m_config.is_showed) + this->showNormal(); + else + this->showMinimized(); + } + if (m_config.is_maximazed) { this->setWindowState(windowState() | Qt::WindowMaximized); @@ -580,14 +590,6 @@ void MainWindow::restore_pos(bool consider_showed) } } - if (consider_showed) - { - if (m_config.is_showed) - this->showNormal(); - else - this->showMinimized(); - } - CATCH_ENTRY2(void()); } void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason) diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 34b35b2b..63e06328 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -1275,6 +1275,8 @@ std::string wallets_manager::get_alias_info_by_name(const std::string& name, cur if (!r) return API_RETURN_CODE_FAIL; + if (res.status == API_RETURN_CODE_NOT_FOUND) + return API_RETURN_CODE_NOT_FOUND; res_details.alias = name; res_details.details = res.alias_details; From 8f483db05ef0a6ff17534e6611882f5df6bc4995 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 20 Feb 2023 21:39:36 +0100 Subject: [PATCH 04/34] ionc swaps implementation: inital code --- src/wallet/wallet2.h | 3 +++ src/wallet/wallets_manager.cpp | 17 +++++++++++++++++ src/wallet/wallets_manager.h | 1 + 3 files changed, 21 insertions(+) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index b00bbe1b..92772955 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -914,6 +914,9 @@ namespace tools void redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin, currency::transaction& result_tx); void redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin); bool check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id); + + // ionic swaps: + bool create_ionic_swap_proposal(uint64_t wallet_id, const view::ionic_swap_proposal_info& proposal); private: // -------- t_transport_state_notifier ------------------------------------------------ diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 63e06328..5d2ce51a 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -854,6 +854,23 @@ std::string wallets_manager::get_fav_offers(const std::listget()->create_ionic_swap_proposal(proposal); + + } + catch (...) + { + return API_RETURN_CODE_FAIL; + } + return API_RETURN_CODE_OK; + + return true; +} + + std::string wallets_manager::get_my_offers(const bc_services::core_offers_filter& filter, std::list& offers) { if (m_remote_node_mode) diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index b5c2922f..f744b2db 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -136,6 +136,7 @@ public: std::string backup_wallet(uint64_t wallet_id, const std::wstring& path); std::string reset_wallet_password(uint64_t wallet_id, const std::string& pass); std::string is_wallet_password_valid(uint64_t wallet_id, const std::string& pass); + std::string create_ionic_swap_proposal(uint64_t wallet_id, const view::ionic_swap_proposal_info& proposal); std::string get_my_offers(const bc_services::core_offers_filter& filter, std::list& offers); std::string get_fav_offers(const std::list& hashes, const bc_services::core_offers_filter& filter, std::list& offers); std::string get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INFO::response& res); From 2328a2cced0eeb28017ea7a520f9f5af72716954 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 23 Feb 2023 19:10:22 +0100 Subject: [PATCH 05/34] Implemented basics for building ionic_swap template --- src/gui/qt-daemon/application/mainwindow.cpp | 19 ++++++++ src/wallet/view_iface.h | 47 ++++++++++++++++++-- src/wallet/wallet2.cpp | 40 +++++++++++++++++ src/wallet/wallet2.h | 6 ++- src/wallet/wallets_manager.cpp | 9 +++- src/wallet/wallets_manager.h | 2 +- 6 files changed, 116 insertions(+), 7 deletions(-) diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index d80df78a..76e20a74 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -2162,7 +2162,26 @@ QString MainWindow::get_wallet_info(const QString& param) return MAKE_RESPONSE(ar); CATCH_ENTRY_FAIL_API_RESPONCE(); } +QString create_ionic_swap_proposal(const QString& param) +{ + TRY_ENTRY(); + LOG_API_TIMING(); + PREPARE_ARG_FROM_JSON(view::create_ionic_swap_proposal_request, cispr); + PREPARE_RESPONSE(view::api_response_t, ar); + ar.error_code = m_backend.create_ionic_swap_proposal(waid.wallet_id, cispr, ar.response_data); + return MAKE_RESPONSE(ar); + CATCH_ENTRY_FAIL_API_RESPONCE(); +} +QString get_ionic_swap_proposal_info(const QString& param) +{ + + +} + +QString accept_ionic_swap_proposal(const QString& param) +{ +} QString MainWindow::backup_wallet_keys(const QString& param) { TRY_ENTRY(); diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index f4c295ab..a3515655 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -686,14 +686,11 @@ public: }; - - struct wallet_and_contract_id_param { uint64_t wallet_id; crypto::hash contract_id; - BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(wallet_id) KV_SERIALIZE_POD_AS_HEX_STRING(contract_id) @@ -742,6 +739,50 @@ public: END_KV_SERIALIZE_MAP() }; + + struct asset_funds + { + crypto::hash token_id; + uint64_t amount; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(token_id) + KV_SERIALIZE(amount) + END_KV_SERIALIZE_MAP() + }; + + struct ionic_swap_proposal_info + { + std::vector from; + std::vector to; + uint64_t mixins; + uint64_t fee; + uint64_t expiration_time; + + BEGIN_KV_SERIALIZE_MAP() + + KV_SERIALIZE(from) + KV_SERIALIZE(to) + KV_SERIALIZE(mixins) + KV_SERIALIZE(fee) + KV_SERIALIZE(expiration_time) + END_KV_SERIALIZE_MAP() + }; + + struct create_ionic_swap_proposal_request + { + uint64_t wallet_id; + ionic_swap_proposal_info proposal; + std::string destination_add; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(wallet_id) + KV_SERIALIZE(proposal) + KV_SERIALIZE(destination_add) + END_KV_SERIALIZE_MAP() + }; + + struct address_validation_response { std::string error_code; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index d710c52e..b3191ed1 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4877,6 +4877,46 @@ bool wallet2::check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& o } return false; } +bool wallet2::create_ionic_swap_proposal(uint64_t wallet_id, const view::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr) +{ + crypto::secret_key one_time_key = AUTO_VAL_INIT(one_time_key); + std::vector selected_transfers_for_template; + transaction tx_template; + build_ionic_swap_template(proposal_details, destination_addr, tx_template, selected_transfers_for_template, one_time_key); + + const uint32_t mask_to_mark_escrow_template_locked_transfers = WALLET_TRANSFER_DETAIL_FLAG_BLOCKED | WALLET_TRANSFER_DETAIL_FLAG_ESCROW_PROPOSAL_RESERVATION; + mark_transfers_with_flag(selected_transfers_for_template, mask_to_mark_escrow_template_locked_transfers, "preparing escrow template tx, contract: " + epee::string_tools::pod_to_hex(ms_id)); + +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::build_ionic_swap_template(const view::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, + currency::transaction& template_tx, + std::vector& selected_transfers_for_template, + crypto::secret_key& one_time_key) +{ + construct_tx_param ctp = get_default_construct_tx_param(); + + ctp.fake_outputs_count = proposal_detais.mixins; + ctp.fee = 0; + ctp.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; + ctp.mark_tx_as_complete = false; + + etc_tx_details_expiration_time t = AUTO_VAL_INIT(t); + t.v = proposal_detais.expiration_time; + ctp.extra.push_back(t); + + //TODO: + + currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); + ftp.tx_version = this->get_current_tx_version(); + prepare_transaction(ctp, ftp, tx); + + selected_transfers = ftp.selected_transfers; + + finalize_transaction(ftp, tx, one_time_key, false); + +} +//---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake_outputs_count, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money) { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 92772955..5239a39e 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -916,7 +916,11 @@ namespace tools bool check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id); // ionic swaps: - bool create_ionic_swap_proposal(uint64_t wallet_id, const view::ionic_swap_proposal_info& proposal); + bool create_ionic_swap_proposal(uint64_t wallet_id, const view::ionic_swap_proposal_info& proposal, const currency::account_public_address& destination_addr); + bool build_ionic_swap_template(const view::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, + currency::transaction& template_tx, + std::vector& selected_transfers_for_template, + crypto::secret_key& one_time_key); private: // -------- t_transport_state_notifier ------------------------------------------------ diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 5d2ce51a..6ed688fd 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -854,12 +854,17 @@ std::string wallets_manager::get_fav_offers(const std::listget()->create_ionic_swap_proposal(proposal); + currency::account_public_address dest_account = AUTO_VAL_INIT(dest_account); + if (!currency::get_account_address_from_str(proposal.destination_add)) + { + return API_RETURN_CODE_BAD_ARG; + } + bool r = wo.w->get()->create_ionic_swap_proposal(proposal, dest_account); } catch (...) { diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index f744b2db..f88b024f 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -136,7 +136,7 @@ public: std::string backup_wallet(uint64_t wallet_id, const std::wstring& path); std::string reset_wallet_password(uint64_t wallet_id, const std::string& pass); std::string is_wallet_password_valid(uint64_t wallet_id, const std::string& pass); - std::string create_ionic_swap_proposal(uint64_t wallet_id, const view::ionic_swap_proposal_info& proposal); + std::string create_ionic_swap_proposal(uint64_t wallet_id, const view::create_ionic_swap_proposal_request& proposal, std::string& result_proposal_hex); std::string get_my_offers(const bc_services::core_offers_filter& filter, std::list& offers); std::string get_fav_offers(const std::list& hashes, const bc_services::core_offers_filter& filter, std::list& offers); std::string get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INFO::response& res); From 404bfc15768705c50e33444dd65ba2b383047723 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 28 Feb 2023 21:35:28 +0100 Subject: [PATCH 06/34] Creating outpus, minor fixes for ionic_swap --- src/wallet/view_iface.h | 4 ++-- src/wallet/wallet2.cpp | 38 ++++++++++++++++++++++++-------------- src/wallet/wallet2.h | 1 + 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index a3515655..2773084b 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -742,11 +742,11 @@ public: struct asset_funds { - crypto::hash token_id; + crypto::public_key asset_id; uint64_t amount; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(token_id) + KV_SERIALIZE(asset_id) KV_SERIALIZE(amount) END_KV_SERIALIZE_MAP() }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index b3191ed1..71b62bd5 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4885,36 +4885,46 @@ bool wallet2::create_ionic_swap_proposal(uint64_t wallet_id, const view::ionic_s build_ionic_swap_template(proposal_details, destination_addr, tx_template, selected_transfers_for_template, one_time_key); const uint32_t mask_to_mark_escrow_template_locked_transfers = WALLET_TRANSFER_DETAIL_FLAG_BLOCKED | WALLET_TRANSFER_DETAIL_FLAG_ESCROW_PROPOSAL_RESERVATION; - mark_transfers_with_flag(selected_transfers_for_template, mask_to_mark_escrow_template_locked_transfers, "preparing escrow template tx, contract: " + epee::string_tools::pod_to_hex(ms_id)); - + mark_transfers_with_flag(selected_transfers_for_template, mask_to_mark_escrow_template_locked_transfers, "preparing ionic_swap"); + return true; } //---------------------------------------------------------------------------------------------------- bool wallet2::build_ionic_swap_template(const view::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, currency::transaction& template_tx, - std::vector& selected_transfers_for_template, + std::vector& selected_transfers, crypto::secret_key& one_time_key) { construct_tx_param ctp = get_default_construct_tx_param(); - - ctp.fake_outputs_count = proposal_detais.mixins; - ctp.fee = 0; - ctp.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; - ctp.mark_tx_as_complete = false; - - etc_tx_details_expiration_time t = AUTO_VAL_INIT(t); t.v = proposal_detais.expiration_time; ctp.extra.push_back(t); - //TODO: + ctp.dsts.resize(proposal_detais.from.size() + proposal_detais.to.size()); + size_t i = 0; + // Here is an proposed for exchange funds + for (; i != proposal_detais.from.size(); i++) + { + ctp.dsts[i].amount = proposal_detais.from[i].amount; + ctp.dsts[i].amount_to_provide = proposal_detais.from[i].amount; + ctp.dsts[i].addr.push_back(destination_addr); + ctp.dsts[i].asset_id = proposal_detais.from[i].asset_id; + } + // Here is an expected in return funds + for (size_t j = 0; j != proposal_detais.to.size(); j++, i++) + { + ctp.dsts[i].amount = proposal_detais.to[j].amount; + ctp.dsts[i].amount_to_provide = 0; + ctp.dsts[i].addr.push_back(m_account.get_public_address()); + ctp.dsts[i].asset_id = proposal_detais.to[j].asset_id; + } currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); ftp.tx_version = this->get_current_tx_version(); - prepare_transaction(ctp, ftp, tx); + prepare_transaction(ctp, ftp, template_tx); selected_transfers = ftp.selected_transfers; - finalize_transaction(ftp, tx, one_time_key, false); - + finalize_transaction(ftp, template_tx, one_time_key, false); + return true; } //---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 5239a39e..1a064a6a 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -44,6 +44,7 @@ #include "wallet_chain_shortener.h" #include "tor-connect/torlib/tor_lib_iface.h" #include "currency_core/pos_mining.h" +#include "view_iface.h" #define WALLET_DEFAULT_TX_SPENDABLE_AGE 10 From ae6feef3e580e8708c9ed93abe4a5625f9ea4714 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 28 Feb 2023 21:36:52 +0100 Subject: [PATCH 07/34] Functions definitions for mainwindow --- src/gui/qt-daemon/application/mainwindow.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/qt-daemon/application/mainwindow.h b/src/gui/qt-daemon/application/mainwindow.h index 37f1dc92..45306094 100644 --- a/src/gui/qt-daemon/application/mainwindow.h +++ b/src/gui/qt-daemon/application/mainwindow.h @@ -172,6 +172,9 @@ public: QString remove_custom_asset_id(const QString& param); QString get_wallet_info(const QString& param); + QString create_ionic_swap_proposal(const QString& param); + QString get_ionic_swap_proposal_info(const QString& param); + QString accept_ionic_swap_proposal(const QString& param); bool get_is_disabled_notifications(); bool set_is_disabled_notifications(const bool& param); From 0030f7fbf6b8f57ae0ef43fba7f2640a68b5f0dd Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 3 Mar 2023 18:17:16 +0100 Subject: [PATCH 08/34] Implemented basic code for validatiing ionic_swap --- src/gui/qt-daemon/application/mainwindow.cpp | 10 +++++-- src/wallet/wallet2.cpp | 19 +++++++++++++ src/wallet/wallets_manager.cpp | 30 ++++++++++++++++++++ src/wallet/wallets_manager.h | 1 + 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index 76e20a74..8cf48c4a 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -2168,14 +2168,20 @@ QString create_ionic_swap_proposal(const QString& param) LOG_API_TIMING(); PREPARE_ARG_FROM_JSON(view::create_ionic_swap_proposal_request, cispr); PREPARE_RESPONSE(view::api_response_t, ar); - ar.error_code = m_backend.create_ionic_swap_proposal(waid.wallet_id, cispr, ar.response_data); + ar.error_code = m_backend.create_ionic_swap_proposal(cispr.wallet_id, cispr, ar.response_data); return MAKE_RESPONSE(ar); CATCH_ENTRY_FAIL_API_RESPONCE(); } QString get_ionic_swap_proposal_info(const QString& param) { - + TRY_ENTRY(); + LOG_API_TIMING(); + PREPARE_ARG_FROM_JSON(view::api_request_t, tx_raw_hex); + PREPARE_RESPONSE(view::api_response_t, ar); + ar.error_code = m_backend.get_ionic_swap_proposal_info(tx_raw_hex.wallet_id, tx_raw_hex.req_data, ar.response_data); + return MAKE_RESPONSE(ar); + CATCH_ENTRY_FAIL_API_RESPONCE(); } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 71b62bd5..4bfed2ba 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4927,6 +4927,25 @@ bool wallet2::build_ionic_swap_template(const view::ionic_swap_proposal_info& pr return true; } //---------------------------------------------------------------------------------------------------- +bool wallet2::get_ionic_swap_proposal_info(std::string&raw_tx_template, ionic_swap_proposal_info& proposal) +{ + + currency::transaction tx; + bool r = parse_and_validate_tx_from_blob(tx_blob, tx); + THROW_IF_TRUE_WALLET_EX(!r, error::tx_parse_error, tx_blob); + + crypto::key_derivation derivation = AUTO_VAL_INIT(derivation); + std::vector outs; + uint64_t tx_money_got_in_outs = 0; + r = lookup_acc_outs(m_account.get_keys(), tx, outs, tx_money_got_in_outs, derivation); + THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "Failed to lookup_acc_outs for tx: " << get_transaction_hash(tx)); + for (const auto& o : outs) + { + + } + + +} //---------------------------------------------------------------------------------------------------- bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake_outputs_count, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money) { diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 6ed688fd..bec4cdea 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -865,6 +865,14 @@ std::string wallets_manager::create_ionic_swap_proposal(uint64_t wallet_id, cons } bool r = wo.w->get()->create_ionic_swap_proposal(proposal, dest_account); + if (!r) + { + return API_RETURN_CODE_FAIL; + } + else + { + return API_RETURN_CODE_OK; + } } catch (...) { @@ -875,6 +883,28 @@ std::string wallets_manager::create_ionic_swap_proposal(uint64_t wallet_id, cons return true; } +std::string get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_template_hex, ionic_swap_proposal_info& proposal) +{ + GET_WALLET_OPT_BY_ID(wallet_id, wo); + try { + std::string raw_tx_template; + bool r = epee::string_tools::parse_hexstr_to_binbuff(raw_tx_template_hex, raw_tx_template); + if (!r) + { + return API_RETURN_CODE_BAD_ARG; + } + + if (!wo.w->get()->get_ionic_swap_proposal_info(raw_tx_template, proposal)) + { + return API_RETURN_CODE_FAIL; + } + } + catch (...) + { + return API_RETURN_CODE_FAIL; + } + return API_RETURN_CODE_OK; +} std::string wallets_manager::get_my_offers(const bc_services::core_offers_filter& filter, std::list& offers) { diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index f88b024f..e465f3cf 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -137,6 +137,7 @@ public: std::string reset_wallet_password(uint64_t wallet_id, const std::string& pass); std::string is_wallet_password_valid(uint64_t wallet_id, const std::string& pass); std::string create_ionic_swap_proposal(uint64_t wallet_id, const view::create_ionic_swap_proposal_request& proposal, std::string& result_proposal_hex); + std::string get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_template, ionic_swap_proposal_info& proposal); std::string get_my_offers(const bc_services::core_offers_filter& filter, std::list& offers); std::string get_fav_offers(const std::list& hashes, const bc_services::core_offers_filter& filter, std::list& offers); std::string get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INFO::response& res); From 6e1fb500ebe110fc33669ed276e3f006a8884316 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 6 Mar 2023 22:47:06 +0100 Subject: [PATCH 09/34] Implemented function for decoding proposal details --- src/wallet/wallet2.cpp | 55 ++++++++++++++++++++++++++++++++++++++---- src/wallet/wallet2.h | 1 + 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 4bfed2ba..7a5892d9 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4924,27 +4924,72 @@ bool wallet2::build_ionic_swap_template(const view::ionic_swap_proposal_info& pr selected_transfers = ftp.selected_transfers; finalize_transaction(ftp, template_tx, one_time_key, false); + + add_transfers_to_expiration_list(selected_transfers, t.v, 0, currency::null_hash); return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::get_ionic_swap_proposal_info(std::string&raw_tx_template, ionic_swap_proposal_info& proposal) +bool wallet2::get_ionic_swap_proposal_info(std::string&raw_tx_template, view::ionic_swap_proposal_info& proposal) { - currency::transaction tx; - bool r = parse_and_validate_tx_from_blob(tx_blob, tx); - THROW_IF_TRUE_WALLET_EX(!r, error::tx_parse_error, tx_blob); + bool r = parse_and_validate_tx_from_blob(raw_tx_template, tx); + THROW_IF_TRUE_WALLET_EX(!r, error::tx_parse_error, raw_tx_template); crypto::key_derivation derivation = AUTO_VAL_INIT(derivation); std::vector outs; uint64_t tx_money_got_in_outs = 0; r = lookup_acc_outs(m_account.get_keys(), tx, outs, tx_money_got_in_outs, derivation); THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "Failed to lookup_acc_outs for tx: " << get_transaction_hash(tx)); + + std::unordered_map ammounts_to; + std::unordered_map ammounts_from; + std::vector third_party_outs; + size_t i = 0; for (const auto& o : outs) { - + ammounts_to[o.asset_id] += o.amount; + third_party_outs[i] = false; + i++; } + for (i = 0; i != tx.vout.size(); i++) + { + if (!third_party_outs[i]) + continue; + crypto::public_key asset_id = AUTO_VAL_INIT(asset_id); + uint64_t amount = 0; + //TODO decode output info + //get_amout_and_asset_id() + ammounts_from[asset_id] += amount; + } + + for (const auto& a : ammounts_to) + proposal.to.push_back(view::asset_funds{ a.first, a.second }); + + for (const auto& a : ammounts_from) + proposal.from.push_back(view::asset_funds{ a.first, a.second }); + + for (const auto&in : tx.vin) + { + if (in.type() != typeid(currency::txin_zc_input)) + return false; + size_t mx = boost::get(in).key_offsets.size() - 1; + if (proposal.mixins == 0 || proposal.mixins > mx) + { + proposal.mixins = mx; + } + } + + proposal.fee = currency::get_tx_fee(tx); + etc_tx_details_expiration_time t = AUTO_VAL_INIT(t); + if (!get_type_in_variant_container(tx.extra, t)) + { + return false; + } + + proposal.expiration_time = t.v; + return true; } //---------------------------------------------------------------------------------------------------- bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake_outputs_count, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 1a064a6a..731d6737 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -922,6 +922,7 @@ namespace tools currency::transaction& template_tx, std::vector& selected_transfers_for_template, crypto::secret_key& one_time_key); + bool get_ionic_swap_proposal_info(std::string& raw_tx_template, view::ionic_swap_proposal_info& proposal); private: // -------- t_transport_state_notifier ------------------------------------------------ From 8be2cc083f57e62e57b34e79e1bdeab5d9ab1eab Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 8 Mar 2023 21:19:59 +0100 Subject: [PATCH 10/34] Implemented accept ionic swap proposal(partially) --- src/gui/qt-daemon/application/mainwindow.cpp | 7 ++ src/wallet/wallet2.cpp | 97 ++++++++++++++++++-- src/wallet/wallet2.h | 12 ++- src/wallet/wallets_manager.cpp | 22 +++++ src/wallet/wallets_manager.h | 3 +- 5 files changed, 130 insertions(+), 11 deletions(-) diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index 8cf48c4a..03261af2 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -2187,6 +2187,13 @@ QString get_ionic_swap_proposal_info(const QString& param) QString accept_ionic_swap_proposal(const QString& param) { + TRY_ENTRY(); + LOG_API_TIMING(); + PREPARE_ARG_FROM_JSON(view::api_request_t, tx_raw_hex); + PREPARE_RESPONSE(view::api_response_t, ar); + ar.error_code = m_backend.accept_ionic_swap_proposal(tx_raw_hex.wallet_id, tx_raw_hex.req_data, ar.response_data); + return MAKE_RESPONSE(ar); + CATCH_ENTRY_FAIL_API_RESPONCE(); } QString MainWindow::backup_wallet_keys(const QString& param) { diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 7a5892d9..13db244b 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -907,7 +907,9 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept construct_tx_param construct_param = AUTO_VAL_INIT(construct_param); construct_param.fee = b_acceptance_fee; - currency::transaction tx = contr_it->second.proposal.tx_template; + mode_separate_context msc = AUTO_VAL_INIT(msc); + msc.tx_for_mode_separate = contr_it->second.proposal.tx_template; + currency::transaction& tx = msc.tx_for_mode_separate; crypto::secret_key one_time_key = contr_it->second.proposal.tx_onetime_secret_key; construct_param.crypt_address = m_account.get_public_address(); construct_param.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; @@ -965,7 +967,7 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept //build transaction currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); ftp.tx_version = this->get_current_tx_version(); - prepare_transaction(construct_param, ftp, tx); + prepare_transaction(construct_param, ftp, msc); mark_transfers_as_spent(ftp.selected_transfers, std::string("contract <") + epee::string_tools::pod_to_hex(contract_id) + "> has been accepted with tx <" + epee::string_tools::pod_to_hex(get_transaction_hash(tx)) + ">"); try @@ -4626,7 +4628,7 @@ void wallet2::build_escrow_template(const bc_services::contract_private_details& currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); ftp.tx_version = this->get_current_tx_version(); - prepare_transaction(ctp, ftp, tx); + prepare_transaction(ctp, ftp); selected_transfers = ftp.selected_transfers; @@ -4895,6 +4897,13 @@ bool wallet2::build_ionic_swap_template(const view::ionic_swap_proposal_info& pr crypto::secret_key& one_time_key) { construct_tx_param ctp = get_default_construct_tx_param(); + + ctp.fake_outputs_count = proposal_detais.mixins; + ctp.fee = 0; + ctp.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; + ctp.mark_tx_as_complete = false; + + etc_tx_details_expiration_time t = AUTO_VAL_INIT(t); t.v = proposal_detais.expiration_time; ctp.extra.push_back(t); @@ -4919,7 +4928,7 @@ bool wallet2::build_ionic_swap_template(const view::ionic_swap_proposal_info& pr currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); ftp.tx_version = this->get_current_tx_version(); - prepare_transaction(ctp, ftp, template_tx); + prepare_transaction(ctp, ftp); selected_transfers = ftp.selected_transfers; @@ -4929,12 +4938,16 @@ bool wallet2::build_ionic_swap_template(const view::ionic_swap_proposal_info& pr return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::get_ionic_swap_proposal_info(std::string&raw_tx_template, view::ionic_swap_proposal_info& proposal) +bool wallet2::get_ionic_swap_proposal_info(const std::string&raw_tx_template, view::ionic_swap_proposal_info& proposal) { currency::transaction tx; bool r = parse_and_validate_tx_from_blob(raw_tx_template, tx); THROW_IF_TRUE_WALLET_EX(!r, error::tx_parse_error, raw_tx_template); - + return get_ionic_swap_proposal_info(tx, proposal); +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::get_ionic_swap_proposal_info(const currency::transaction tx, view::ionic_swap_proposal_info& proposal) +{ crypto::key_derivation derivation = AUTO_VAL_INIT(derivation); std::vector outs; uint64_t tx_money_got_in_outs = 0; @@ -4992,6 +5005,74 @@ bool wallet2::get_ionic_swap_proposal_info(std::string&raw_tx_template, view::io return true; } //---------------------------------------------------------------------------------------------------- +bool wallet2::accept_ionic_swap_proposal(std::string&raw_tx_template, currency::transaction& result_tx) +{ + mode_separate_context msc = AUTO_VAL_INIT(msc); + + currency::transaction& tx = msc.tx_for_mode_separate; + bool r = parse_and_validate_tx_from_blob(raw_tx_template, tx); + THROW_IF_TRUE_WALLET_EX(!r, error::tx_parse_error, raw_tx_template); + + r = get_ionic_swap_proposal_info(tx, msc.proposal); + THROW_IF_TRUE_WALLET_EX(!r, error::wallet_internal_error, "Failed to get info from proposal"); + + std::unordered_map balances; + uint64_t mined = 0; + this->balance(balances, mined); + //validate balances needed + uint64_t native_amount_required = 0; + for (const auto& item : msc.proposal.to) + { + if (balances[item.asset_id].unlocked < item.amount) + { + return false; + } + if (item.asset_id == currency::null_pkey) + { + native_amount_required = item.amount; + } + } + + // balances is ok, check if fee is added to tx + uint64_t additional_fee = 0; + if (msc.proposal.fee < m_core_runtime_config.tx_default_fee) + { + additional_fee = m_core_runtime_config.tx_default_fee - msc.proposal.fee; + if (balances[currency::null_pkey].unlocked < additional_fee + native_amount_required) + { + return false; + } + } + + //everything is seemed to be ok + + construct_tx_param construct_param = get_default_construct_tx_param(); + construct_param.fee = additional_fee; + //crypto::secret_key one_time_key = contr_it->second.proposal.tx_onetime_secret_key; + construct_param.crypt_address = m_account.get_public_address(); + construct_param.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; + construct_param.mark_tx_as_complete = true; + + //build transaction + currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); + ftp.tx_version = this->get_current_tx_version(); + prepare_transaction(construct_param, ftp, msc); + mark_transfers_as_spent(ftp.selected_transfers, std::string("contract <") + epee::string_tools::pod_to_hex(contract_id) + "> has been accepted with tx <" + epee::string_tools::pod_to_hex(get_transaction_hash(tx)) + ">"); + + try + { + finalize_transaction(ftp, tx, one_time_key, true); + } + catch (...) + { + clear_transfers_from_flag(ftp.selected_transfers, WALLET_TRANSFER_DETAIL_FLAG_SPENT, std::string("exception in finalize_transaction, tx: ") + epee::string_tools::pod_to_hex(get_transaction_hash(tx))); + throw; + } + + + return true; +} +//---------------------------------------------------------------------------------------------------- bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake_outputs_count, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money) { prepare_free_transfers_cache(fake_outputs_count); @@ -5966,10 +6047,10 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money, } } //---------------------------------------------------------------------------------------------------- -void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const currency::transaction& tx_for_mode_separate /* = currency::transaction() */) +void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& mode_separatemode_separate) { TIME_MEASURE_START_MS(get_needed_money_time); - + const currency::transaction& tx_for_mode_separate = mode_separatemode_separate.tx_for_mode_separate; assets_selection_context needed_money_map = get_needed_money(ctp.fee, ctp.dsts); //@#@ need to do refactoring over this part to support hidden amounts and asset_id if (ctp.flags & TX_FLAG_SIGNATURE_MODE_SEPARATE && tx_for_mode_separate.vout.size() ) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 731d6737..49e430b7 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -297,6 +297,12 @@ namespace tools bool perform_packing = false; }; + struct mode_separate_context + { + currency::transaction tx_for_mode_separate; + view::ionic_swap_proposal_info proposal; + }; + struct selection_for_amount { @@ -884,7 +890,7 @@ namespace tools const std::list& get_expiration_entries() const { return m_money_expirations; }; bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) const; - void prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const currency::transaction& tx_for_mode_separate = currency::transaction()); + void prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& emode_separate = mode_separate_context()); void finalize_transaction(const currency::finalize_tx_param& ftp, currency::transaction& tx, crypto::secret_key& tx_key, bool broadcast_tx, bool store_tx_secret_key = true); void finalize_transaction(const currency::finalize_tx_param& ftp, currency::finalized_tx& result, bool broadcast_tx, bool store_tx_secret_key = true ); @@ -922,7 +928,9 @@ namespace tools currency::transaction& template_tx, std::vector& selected_transfers_for_template, crypto::secret_key& one_time_key); - bool get_ionic_swap_proposal_info(std::string& raw_tx_template, view::ionic_swap_proposal_info& proposal); + bool get_ionic_swap_proposal_info(const std::string&raw_tx_template, view::ionic_swap_proposal_info& proposal); + bool get_ionic_swap_proposal_info(const currency::transaction tx, view::ionic_swap_proposal_info& proposal); + bool accept_ionic_swap_proposal(std::string&raw_tx_template, currency::transaction& result_tx); private: // -------- t_transport_state_notifier ------------------------------------------------ diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index bec4cdea..21a7f8d0 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -906,6 +906,28 @@ std::string get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_ return API_RETURN_CODE_OK; } +std::string wallets_manager::accept_ionic_swap_proposal(uint64_t wallet_id, std::string&raw_tx_template, currency::transaction& result_tx) +{ + GET_WALLET_OPT_BY_ID(wallet_id, wo); + try { + std::string raw_tx_template; + bool r = epee::string_tools::parse_hexstr_to_binbuff(raw_tx_template_hex, raw_tx_template); + if (!r) + { + return API_RETURN_CODE_BAD_ARG; + } + + if (!wo.w->get()->accept_ionic_swap_proposal(raw_tx_template, result_tx)) + { + return API_RETURN_CODE_FAIL; + } + } + catch (...) + { + return API_RETURN_CODE_FAIL; + } + return API_RETURN_CODE_OK; +} std::string wallets_manager::get_my_offers(const bc_services::core_offers_filter& filter, std::list& offers) { if (m_remote_node_mode) diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index e465f3cf..d17cb437 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -137,7 +137,8 @@ public: std::string reset_wallet_password(uint64_t wallet_id, const std::string& pass); std::string is_wallet_password_valid(uint64_t wallet_id, const std::string& pass); std::string create_ionic_swap_proposal(uint64_t wallet_id, const view::create_ionic_swap_proposal_request& proposal, std::string& result_proposal_hex); - std::string get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_template, ionic_swap_proposal_info& proposal); + std::string get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_template_hex, ionic_swap_proposal_info& proposal); + std::string accept_ionic_swap_proposal(uint64_t wallet_id, std::string&raw_tx_template_hex, currency::transaction& result_tx); std::string get_my_offers(const bc_services::core_offers_filter& filter, std::list& offers); std::string get_fav_offers(const std::list& hashes, const bc_services::core_offers_filter& filter, std::list& offers); std::string get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INFO::response& res); From f0d5bc94cd28d3bebd49f90370d1b11cb6d48417 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 9 Mar 2023 19:49:40 +0100 Subject: [PATCH 11/34] Core tests for basic ionic swaps scenario: inital code --- src/wallet/wallet2.cpp | 6 ++- tests/core_tests/ionic_swap_tests.cpp | 55 +++++++++++++++++++++++++++ tests/core_tests/ionic_swap_tests.h | 15 ++++++++ tests/core_tests/zarcanum_test.cpp | 1 - tests/core_tests/zarcanum_test.h | 1 - 5 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 tests/core_tests/ionic_swap_tests.cpp create mode 100644 tests/core_tests/ionic_swap_tests.h diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 13db244b..f0cfa602 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5069,7 +5069,6 @@ bool wallet2::accept_ionic_swap_proposal(std::string&raw_tx_template, currency:: throw; } - return true; } //---------------------------------------------------------------------------------------------------- @@ -6056,7 +6055,10 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx if (ctp.flags & TX_FLAG_SIGNATURE_MODE_SEPARATE && tx_for_mode_separate.vout.size() ) { WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(get_tx_flags(tx_for_mode_separate) & TX_FLAG_SIGNATURE_MODE_SEPARATE, "tx_param.flags differs from tx.flags"); - needed_money_map[currency::null_hash].needed_amount += (currency::get_outs_money_amount(tx_for_mode_separate) - get_inputs_money_amount(tx_for_mode_separate)); + for (const auto& el : mode_separatemode_separate.proposal.to) + { + needed_money_map[el.asset_id].needed_amount += el.amount; + } } TIME_MEASURE_FINISH_MS(get_needed_money_time); diff --git a/tests/core_tests/ionic_swap_tests.cpp b/tests/core_tests/ionic_swap_tests.cpp new file mode 100644 index 00000000..a899ca44 --- /dev/null +++ b/tests/core_tests/ionic_swap_tests.cpp @@ -0,0 +1,55 @@ +// Copyright (c) 2014-2022 Zano Project +// Copyright (c) 2014-2018 The Louisdor Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "chaingen.h" +#include "ionic_swap_tests.h" +#include "wallet_test_core_proxy.h" + +#include "random_helper.h" +#include "tx_builder.h" + + +ionic_swap_basic_test::ionic_swap_basic_test() +{ + REGISTER_CALLBACK_METHOD(ionic_swap_basic_test, configure_core); + REGISTER_CALLBACK_METHOD(ionic_swap_basic_test, c1); + + m_hardforks.set_hardfork_height(1, 1); + m_hardforks.set_hardfork_height(2, 1); + m_hardforks.set_hardfork_height(3, 1); + m_hardforks.set_hardfork_height(4, 2); +} + +bool zarcanum_basic_test::generate(std::vector& events) const +{ + uint64_t ts = test_core_time::get_time(); + m_accounts.resize(TOTAL_ACCS_COUNT); + account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts); + account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts); + account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate(); bob_acc.set_createtime(ts); + //account_base& carol_acc = m_accounts[CAROL_ACC_IDX]; carol_acc.generate(); carol_acc.set_createtime(ts); + + MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts); + DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks + REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3); + + DO_CALLBACK(events, "c1"); + + return true; +} + +bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vector& events) +{ + bool r = false; + std::shared_ptr miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX); + std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX); + std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX); + + // check passing over the hardfork + CHECK_AND_ASSERT_MES(!c.get_blockchain_storage().is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM), false, "ZANO_HARDFORK_04_ZARCANUM is active"); + + return true; +} + diff --git a/tests/core_tests/ionic_swap_tests.h b/tests/core_tests/ionic_swap_tests.h new file mode 100644 index 00000000..389191ae --- /dev/null +++ b/tests/core_tests/ionic_swap_tests.h @@ -0,0 +1,15 @@ +// Copyright (c) 2014-2022 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 "chaingen.h" +#include "wallet_tests_basic.h" + + +struct ionic_swap_basic_test : public wallet_test +{ + ionic_swap_basic_test(); + bool generate(std::vector& events) const; + bool c1(currency::core& c, size_t ev_index, const std::vector& events); +}; + diff --git a/tests/core_tests/zarcanum_test.cpp b/tests/core_tests/zarcanum_test.cpp index 1d04d39a..3f1209af 100644 --- a/tests/core_tests/zarcanum_test.cpp +++ b/tests/core_tests/zarcanum_test.cpp @@ -1,5 +1,4 @@ // Copyright (c) 2014-2022 Zano Project -// Copyright (c) 2014-2018 The Louisdor Project // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/tests/core_tests/zarcanum_test.h b/tests/core_tests/zarcanum_test.h index 6b7e575b..4afa4eea 100644 --- a/tests/core_tests/zarcanum_test.h +++ b/tests/core_tests/zarcanum_test.h @@ -1,5 +1,4 @@ // Copyright (c) 2014-2022 Zano Project -// Copyright (c) 2014-2018 The Louisdor Project // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once From 8e43055140c8c96d3326a7d254eee300aaa5abc8 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 13 Mar 2023 22:14:39 +0100 Subject: [PATCH 12/34] Core tests for basic ionic swaps scenario: code for creating proposal --- src/wallet/wallet2.cpp | 3 +- src/wallet/wallet2.h | 2 +- tests/core_tests/ionic_swap_tests.cpp | 84 ++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index f0cfa602..90d4e988 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4879,7 +4879,8 @@ bool wallet2::check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& o } return false; } -bool wallet2::create_ionic_swap_proposal(uint64_t wallet_id, const view::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr) +//---------------------------------------------------------------------------------------------------- +bool wallet2::create_ionic_swap_proposal(const view::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr) { crypto::secret_key one_time_key = AUTO_VAL_INIT(one_time_key); std::vector selected_transfers_for_template; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 49e430b7..ddb69e2e 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -923,7 +923,7 @@ namespace tools bool check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id); // ionic swaps: - bool create_ionic_swap_proposal(uint64_t wallet_id, const view::ionic_swap_proposal_info& proposal, const currency::account_public_address& destination_addr); + bool create_ionic_swap_proposal(const view::ionic_swap_proposal_info& proposal, const currency::account_public_address& destination_addr, transaction& tx_template); bool build_ionic_swap_template(const view::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, currency::transaction& template_tx, std::vector& selected_transfers_for_template, diff --git a/tests/core_tests/ionic_swap_tests.cpp b/tests/core_tests/ionic_swap_tests.cpp index a899ca44..509badd8 100644 --- a/tests/core_tests/ionic_swap_tests.cpp +++ b/tests/core_tests/ionic_swap_tests.cpp @@ -10,6 +10,11 @@ #include "random_helper.h" #include "tx_builder.h" +#define AMOUNT_TO_TRANSFER_MULTIASSETS_BASIC (TESTS_DEFAULT_FEE) + +#define AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC 500000000000000000 + + ionic_swap_basic_test::ionic_swap_basic_test() { @@ -22,7 +27,7 @@ ionic_swap_basic_test::ionic_swap_basic_test() m_hardforks.set_hardfork_height(4, 2); } -bool zarcanum_basic_test::generate(std::vector& events) const +bool ionic_swap_basic_test::generate(std::vector& events) const { uint64_t ts = test_core_time::get_time(); m_accounts.resize(TOTAL_ACCS_COUNT); @@ -44,12 +49,85 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect { bool r = false; std::shared_ptr miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX); - std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX); - std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX); + miner_wlt->get_account().set_createtime(0); + + //std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX); + //std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX); // check passing over the hardfork CHECK_AND_ASSERT_MES(!c.get_blockchain_storage().is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM), false, "ZANO_HARDFORK_04_ZARCANUM is active"); + + account_base alice_acc; + alice_acc.generate(); + std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, alice_acc); + alice_wlt->get_account().set_createtime(0); + miner_wlt->refresh(); + + asset_descriptor_base adb = AUTO_VAL_INIT(adb); + adb.total_max_supply = 1000000000000000000; //1M coins + adb.full_name = "Test coins"; + adb.ticker = "TCT"; + adb.decimal_point = 12; + + std::vector destinations(2); + destinations[0].addr.push_back(miner_wlt->get_account().get_public_address()); + destinations[0].amount = AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC; + destinations[0].asset_id = currency::ffff_hash; + destinations[1].addr.push_back(alice_wlt->get_account().get_public_address()); + destinations[1].amount = AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC; + destinations[1].asset_id = currency::ffff_hash; + + LOG_PRINT_MAGENTA("destinations[0].asset_id:" << destinations[0].asset_id, LOG_LEVEL_0); + LOG_PRINT_MAGENTA("destinations[1].asset_id:" << destinations[1].asset_id, LOG_LEVEL_0); + LOG_PRINT_MAGENTA("currency::ffff_hash:" << currency::ffff_hash, LOG_LEVEL_0); + + currency::transaction tx = AUTO_VAL_INIT(tx); + crypto::hash asset_id = currency::null_hash; + miner_wlt->publish_new_asset(adb, destinations, tx, asset_id); + LOG_PRINT_L0("Published new asset: " << asset_id << ", tx_id: " << currency::get_transaction_hash(tx)); + + r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); + + + miner_wlt->refresh(); + alice_wlt->refresh(); + uint64_t mined = 0; + std::unordered_map balances; + miner_wlt->balance(balances, mined); + + auto it_asset = balances.find(asset_id); + auto it_native = balances.find(currency::null_hash); + + + CHECK_AND_ASSERT_MES(it_asset != balances.end() && it_native != balances.end(), false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_native->second.total == uint64_t(17517226)*COIN, false, "Failed to find needed asset in result balances"); + + + balances.clear(); + alice_wlt->balance(balances, mined); + + it_asset = balances.find(asset_id); + it_native = balances.find(currency::null_hash); + + CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_native == balances.end(), false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances"); + + //alice_wlt want to trade with miner_wlt, to exchange 10.0 TCT to 1.0 ZANO + view::ionic_swap_proposal_info proposal_details = AUTO_VAL_INIT(proposal_details); + proposal_details.expiration_time = alice_wlt->get_core_runtime_config().get_core_time() + 10 * 60; + proposal_details.fee = TESTS_DEFAULT_FEE; + proposal_details.mixins = 10; + proposal_details.from.push_back(view::asset_funds{ asset_id , 10 * COIN}); + proposal_details.to.push_back(view::asset_funds{ currency::null_pkey , 1 * COIN }); + + currency::transaction tx_template = AUTO_VAL_INIT(tx_template); + alice_wlt->create_ionic_swap_proposal(proposal_details, miner_wlt->get_account().get_public_address(), tx_template); + + return true; } From 83c5336004b648bcdb3f803a02d1b3d3140b19c8 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 16 Mar 2023 19:15:11 +0100 Subject: [PATCH 13/34] Core tests for basic ionic swaps scenario: draft for verification code --- src/wallet/wallet2.cpp | 20 ++++++++---- src/wallet/wallet2.h | 3 +- tests/core_tests/ionic_swap_tests.cpp | 46 +++++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 90d4e988..f6429fde 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4880,11 +4880,11 @@ bool wallet2::check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& o return false; } //---------------------------------------------------------------------------------------------------- -bool wallet2::create_ionic_swap_proposal(const view::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr) +bool wallet2::create_ionic_swap_proposal(const view::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr, transaction& tx_template) { crypto::secret_key one_time_key = AUTO_VAL_INIT(one_time_key); std::vector selected_transfers_for_template; - transaction tx_template; + build_ionic_swap_template(proposal_details, destination_addr, tx_template, selected_transfers_for_template, one_time_key); const uint32_t mask_to_mark_escrow_template_locked_transfers = WALLET_TRANSFER_DETAIL_FLAG_BLOCKED | WALLET_TRANSFER_DETAIL_FLAG_ESCROW_PROPOSAL_RESERVATION; @@ -5005,15 +5005,23 @@ bool wallet2::get_ionic_swap_proposal_info(const currency::transaction tx, view: proposal.expiration_time = t.v; return true; } + //---------------------------------------------------------------------------------------------------- -bool wallet2::accept_ionic_swap_proposal(std::string&raw_tx_template, currency::transaction& result_tx) +bool wallet2::accept_ionic_swap_proposal(const std::string& raw_tx_template, currency::transaction& result_tx) { - mode_separate_context msc = AUTO_VAL_INIT(msc); - - currency::transaction& tx = msc.tx_for_mode_separate; + currency::transaction tx; bool r = parse_and_validate_tx_from_blob(raw_tx_template, tx); THROW_IF_TRUE_WALLET_EX(!r, error::tx_parse_error, raw_tx_template); + return accept_ionic_swap_proposal(tx, result_tx); +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_template, currency::transaction& result_tx) +{ + mode_separate_context msc = AUTO_VAL_INIT(msc); + msc.tx_for_mode_separate = tx_template; + + r = get_ionic_swap_proposal_info(tx, msc.proposal); THROW_IF_TRUE_WALLET_EX(!r, error::wallet_internal_error, "Failed to get info from proposal"); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index ddb69e2e..a53ca4a0 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -930,7 +930,8 @@ namespace tools crypto::secret_key& one_time_key); bool get_ionic_swap_proposal_info(const std::string&raw_tx_template, view::ionic_swap_proposal_info& proposal); bool get_ionic_swap_proposal_info(const currency::transaction tx, view::ionic_swap_proposal_info& proposal); - bool accept_ionic_swap_proposal(std::string&raw_tx_template, currency::transaction& result_tx); + bool accept_ionic_swap_proposal(const std::string&raw_tx_template, currency::transaction& result_tx); + bool accept_ionic_swap_proposal(const currency::transaction& tx_template, currency::transaction& result_tx); private: // -------- t_transport_state_notifier ------------------------------------------------ diff --git a/tests/core_tests/ionic_swap_tests.cpp b/tests/core_tests/ionic_swap_tests.cpp index 509badd8..f2838e52 100644 --- a/tests/core_tests/ionic_swap_tests.cpp +++ b/tests/core_tests/ionic_swap_tests.cpp @@ -105,6 +105,7 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_native->second.total == uint64_t(17517226)*COIN, false, "Failed to find needed asset in result balances"); + uint64_t mined_balance = it_native->second.total; balances.clear(); alice_wlt->balance(balances, mined); @@ -116,17 +117,58 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect CHECK_AND_ASSERT_MES(it_native == balances.end(), false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances"); + const uint64_t assets_to_exchange = 10 * COIN; + const uint64_t native_tokens_to_exchange = 1 * COIN; + //alice_wlt want to trade with miner_wlt, to exchange 10.0 TCT to 1.0 ZANO view::ionic_swap_proposal_info proposal_details = AUTO_VAL_INIT(proposal_details); proposal_details.expiration_time = alice_wlt->get_core_runtime_config().get_core_time() + 10 * 60; proposal_details.fee = TESTS_DEFAULT_FEE; proposal_details.mixins = 10; - proposal_details.from.push_back(view::asset_funds{ asset_id , 10 * COIN}); - proposal_details.to.push_back(view::asset_funds{ currency::null_pkey , 1 * COIN }); + proposal_details.from.push_back(view::asset_funds{ asset_id , assets_to_exchange }); + proposal_details.to.push_back(view::asset_funds{ currency::null_pkey , native_tokens_to_exchange }); currency::transaction tx_template = AUTO_VAL_INIT(tx_template); alice_wlt->create_ionic_swap_proposal(proposal_details, miner_wlt->get_account().get_public_address(), tx_template); + view::ionic_swap_proposal_info proposal_decoded_info; + miner_wlt->get_ionic_swap_proposal_info(tx_template, proposal_decoded_info); + + //Validate proposal + if (proposal_decoded_info.from != proposal_details.from || proposal_decoded_info.to != proposal_details.to) + { + CHECK_AND_ASSERT_MES(false, false, "proposal actual and proposals decoded mismatch"); + } + + currency::transaction res_tx = AUTO_VAL_INIT(res_tx); + r = miner_wlt->accept_ionic_swap_proposal(tx_template, res_tx); + CHECK_AND_ASSERT_MES(r, false, "Failed to accept ionic proposal"); + + r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); + + miner_wlt->refresh(); + alice_wlt->refresh(); + + + balances.clear(); + alice_wlt->balance(balances, mined); + + it_asset = balances.find(asset_id); + it_native = balances.find(currency::null_hash); + + CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_native->second.total == native_tokens_to_exchange, false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC - assets_to_exchange, false, "Failed to find needed asset in result balances"); + + + balances.clear(); + miner_wlt->balance(balances, mined); + + CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_native->second.total == mined_balance - native_tokens_to_exchange, false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC + assets_to_exchange, false, "Failed to find needed asset in result balances"); + return true; } From f47e9977a5e6f5a8942a804526a375b6accb22d6 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 17 Mar 2023 19:55:32 +0100 Subject: [PATCH 14/34] Implemented generate_ionic_swap_proposal command in simplewallet --- src/simplewallet/simplewallet.cpp | 56 +++++++++++++++++++++++++++ src/simplewallet/simplewallet.h | 5 +++ tests/core_tests/ionic_swap_tests.cpp | 2 - 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index b93bafbb..d9160494 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -229,6 +229,10 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("add_custom_asset_id", boost::bind(&simple_wallet::add_custom_asset_id, this, _1), "Approve asset id to be recognized in the wallet and returned in balances"); m_cmd_binder.set_handler("remove_custom_asset_id", boost::bind(&simple_wallet::remove_custom_asset_id, this, _1), "Cancel previously made approval for asset id"); + m_cmd_binder.set_handler("generate_ionic_swap_proposal", boost::bind(&simple_wallet::generate_ionic_swap_proposal, this, _1), "generate_ionic_swap_proposal - Generates ionic_swap proposal with given conditions"); + m_cmd_binder.set_handler("get_ionic_swap_proposal_info", boost::bind(&simple_wallet::get_ionic_swap_proposal_info, this, _1), "get_ionic_swap_proposal_info - Extracts and display information from ionic_swap proposal raw data"); + m_cmd_binder.set_handler("accept_ionic_swap_proposal", boost::bind(&simple_wallet::accept_ionic_swap_proposal, this, _1), "accept_ionic_swap_proposal - Accept ionic_swap proposal and generates exchange transaction"); + } //---------------------------------------------------------------------------------------------------- simple_wallet::~simple_wallet() @@ -1849,6 +1853,58 @@ bool simple_wallet::add_custom_asset_id(const std::vector &args) } return true; } +//---------------------------------------------------------------------------------------------------- +bool simple_wallet::generate_ionic_swap_proposal(const std::vector &args) +{ + + if (args.size() != 2) + { + fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1"; + } + + view::ionic_swap_proposal_info proposal = AUTO_VAL_INIT(proposal); + bool r = epee::serialization::load_t_from_json_file(proposal, args[0]); + if (!r) + { + fail_msg_writer() << "Failed to load json file with asset specification: " << args[0]; + } + currency::account_public_address destination_addr = AUTO_VAL_INIT(destination_addr); + currency::payment_id_t integrated_payment_id; + if (!m_wallet->get_transfer_address(args[1], destination_addr, integrated_payment_id)) + { + fail_msg_writer() << "wrong address: " << args[1]; + return true; + } + if (integrated_payment_id.size()) + { + fail_msg_writer() << "Integrated addresses not supported yet"; + return true; + } + + transaction tx_template = AUTO_VAL_INIT(tx_template); + bool r = m_wallet->create_ionic_swap_proposal(proposal, destination_addr, tx_template); + if (!r) + { + fail_msg_writer() << "Failed to create ionic_swap proposal"; + return true; + } + else + { + success_msg_writer() << "Generated proposal: " << ENDL << epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(tx_template)); + } + return true; +} +//---------------------------------------------------------------------------------------------------- +bool simple_wallet::get_ionic_swap_proposal_info(const std::vector &args) +{ + +} +//---------------------------------------------------------------------------------------------------- +bool simple_wallet::accept_ionic_swap_proposal(const std::vector &args) +{ + +} + //---------------------------------------------------------------------------------------------------- bool simple_wallet::remove_custom_asset_id(const std::vector &args) { diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 823fee05..7ac24682 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -92,6 +92,11 @@ namespace currency bool add_custom_asset_id(const std::vector &args); bool remove_custom_asset_id(const std::vector &args); + //---------------------------------------------------------------------------------------------------- + bool generate_ionic_swap_proposal(const std::vector &args); + bool get_ionic_swap_proposal_info(const std::vector &args); + bool accept_ionic_swap_proposal(const std::vector &args); + bool validate_wrap_status(uint64_t amount); bool get_alias_from_daemon(const std::string& alias_name, currency::extra_alias_entry_base& ai); diff --git a/tests/core_tests/ionic_swap_tests.cpp b/tests/core_tests/ionic_swap_tests.cpp index f2838e52..c0206de7 100644 --- a/tests/core_tests/ionic_swap_tests.cpp +++ b/tests/core_tests/ionic_swap_tests.cpp @@ -168,8 +168,6 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_native->second.total == mined_balance - native_tokens_to_exchange, false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC + assets_to_exchange, false, "Failed to find needed asset in result balances"); - - return true; } From 94861608cffbcd8dbcbca028af162c5c9d971147 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 20 Mar 2023 20:11:23 +0100 Subject: [PATCH 15/34] Implemented accept_ionic_swap_proposal and get_ionic_swap_proposal_info command in simplewallet --- src/simplewallet/simplewallet.cpp | 48 ++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index d9160494..7d6e2096 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -229,7 +229,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("add_custom_asset_id", boost::bind(&simple_wallet::add_custom_asset_id, this, _1), "Approve asset id to be recognized in the wallet and returned in balances"); m_cmd_binder.set_handler("remove_custom_asset_id", boost::bind(&simple_wallet::remove_custom_asset_id, this, _1), "Cancel previously made approval for asset id"); - m_cmd_binder.set_handler("generate_ionic_swap_proposal", boost::bind(&simple_wallet::generate_ionic_swap_proposal, this, _1), "generate_ionic_swap_proposal - Generates ionic_swap proposal with given conditions"); + m_cmd_binder.set_handler("generate_ionic_swap_proposal", boost::bind(&simple_wallet::generate_ionic_swap_proposal, this, _1), "generate_ionic_swap_proposal - Generates ionic_swap proposal with given conditions"); m_cmd_binder.set_handler("get_ionic_swap_proposal_info", boost::bind(&simple_wallet::get_ionic_swap_proposal_info, this, _1), "get_ionic_swap_proposal_info - Extracts and display information from ionic_swap proposal raw data"); m_cmd_binder.set_handler("accept_ionic_swap_proposal", boost::bind(&simple_wallet::accept_ionic_swap_proposal, this, _1), "accept_ionic_swap_proposal - Accept ionic_swap proposal and generates exchange transaction"); @@ -1897,12 +1897,58 @@ bool simple_wallet::generate_ionic_swap_proposal(const std::vector //---------------------------------------------------------------------------------------------------- bool simple_wallet::get_ionic_swap_proposal_info(const std::vector &args) { + if (args.size() != 1) + { + fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1"; + } + std::string raw_tx_template; + bool r = epee::string_tools::parse_hexstr_to_binbuff(args[0], raw_tx_template); + if (!r) + { + fail_msg_writer() << "Failed to parse proposal hex to raw data"; + return true; + } + + view::ionic_swap_proposal_info proposal = AUTO_VAL_INIT(proposal); + if (!m_wallet->get_ionic_swap_proposal_info(raw_tx_template, proposal)) + { + fail_msg_writer() << "Failed to decode proposal info"; + return true; + } + std::string json_proposal = epee::serialization::store_t_to_json(proposal); + + + success_msg_writer() << "Proposal details: " << ENDL << json_proposal; + + return true; } //---------------------------------------------------------------------------------------------------- bool simple_wallet::accept_ionic_swap_proposal(const std::vector &args) { + if (args.size() != 1) + { + fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1"; + } + std::string raw_tx_template; + bool r = epee::string_tools::parse_hexstr_to_binbuff(args[0], raw_tx_template); + if (!r) + { + fail_msg_writer() << "Failed to parse proposal hex to raw data"; + return true; + } + + currency::transaction result_tx = AUTO_VAL_INIT(result_tx); + if (!m_wallet->accept_ionic_swap_proposal(raw_tx_template, result_tx)) + { + fail_msg_writer() << "Failed accept ionic_swap proposal"; + return true; + } + + success_msg_writer() << "Proposal accepted and executed, tx_id : " << currency::get_transaction_hash(result_tx); + + return true; } //---------------------------------------------------------------------------------------------------- From 2b9227c0f1faa75e1a4ca81fb2097adc6404351a Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 23 Mar 2023 19:24:23 +0100 Subject: [PATCH 16/34] Implemented basic code for ionic_swap rpc --- src/wallet/wallet_public_structs_defs.h | 68 +++++++++++++++++++++++++ src/wallet/wallet_rpc_server.cpp | 15 ++++++ src/wallet/wallet_rpc_server.h | 8 +++ 3 files changed, 91 insertions(+) diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 22da411d..1fe59a3a 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1178,6 +1178,74 @@ namespace wallet_public }; }; + struct COMMAND_IONIC_SWAP_GENERATE_PROPOSAL + { + struct request + { + view::ionic_swap_proposal_info proposal; + std::string destination_address; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(proposal) + KV_SERIALIZE(destination_address) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + std::string hex_raw_proposal; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(hex_raw_proposal) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO + { + struct request + { + std::string hex_raw_proposal; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(hex_raw_proposal) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + view::ionic_swap_proposal_info proposal; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(proposal) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL + { + struct request + { + std::string hex_raw_proposal; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(hex_raw_proposal) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + crypto::hash result_tx_id; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(result_tx_id) + END_KV_SERIALIZE_MAP() + }; + }; + + struct assets_whitelist { std::vector assets; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index fb804956..875138ed 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -926,6 +926,21 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_ionic_swap_generate_proposal(const wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_ionic_swap_get_proposal_info(const wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO& req, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_ionic_swap_accept_proposal(const wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + + } + //------------------------------------------------------------------------------------------------------------------------------ } // namespace tools diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 1edd325c..8db43937 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -73,6 +73,10 @@ namespace tools MAP_JON_RPC_WE("atomics_redeem_htlc", on_redeem_htlc, wallet_public::COMMAND_REDEEM_HTLC) MAP_JON_RPC_WE("atomics_check_htlc_redeemed", on_check_htlc_redeemed, wallet_public::COMMAND_CHECK_HTLC_REDEEMED) + //IONIC_SWAPS API + MAP_JON_RPC_WE("ionic_swap_generate_proposal", on_ionic_swap_generate_proposal, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL) + MAP_JON_RPC_WE("ionic_swap_get_proposal_info", on_ionic_swap_get_proposal_info, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO) + MAP_JON_RPC_WE("ionic_swap_accept_proposal", on_ionic_swap_accept_proposal, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL) END_JSON_RPC_MAP() END_URI_MAP2() @@ -114,6 +118,10 @@ namespace tools bool on_redeem_htlc(const wallet_public::COMMAND_REDEEM_HTLC::request& req, wallet_public::COMMAND_REDEEM_HTLC::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_check_htlc_redeemed(const wallet_public::COMMAND_CHECK_HTLC_REDEEMED::request& req, wallet_public::COMMAND_CHECK_HTLC_REDEEMED::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_ionic_swap_generate_proposal(const wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_ionic_swap_get_proposal_info(const wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO& req, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_ionic_swap_accept_proposal(const wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool handle_command_line(const boost::program_options::variables_map& vm); From 69647023e08efa666fda27df4bf7f372988e5a6c Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 24 Mar 2023 20:59:26 +0100 Subject: [PATCH 17/34] Implemented rpc calls for ionic_swaps --- src/wallet/wallet_rpc_server.cpp | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 875138ed..7001f4b7 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -928,17 +928,75 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_ionic_swap_generate_proposal(const wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx) { + currency::account_public_address destination_addr = AUTO_VAL_INIT(destination_addr); + currency::payment_id_t integrated_payment_id; + if (!m_wallet.get_transfer_address(req.destination_address, destination_addr, integrated_payment_id)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS"; + return false; + } + if (integrated_payment_id.size()) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS - integrated address is noit supported yet"; + return false; + } + currency::transaction tx_template = AUTO_VAL_INIT(tx_template); + bool r = m_wallet.create_ionic_swap_proposal(req.proposal, destination_addr, tx_template); + if (!r) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; + er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT - Error creating proposal"; + return false; + } + res.hex_raw_proposal = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(tx_template)); + return true; } //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_ionic_swap_get_proposal_info(const wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO& req, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx) { + std::string raw_tx_template; + bool r = epee::string_tools::parse_hexstr_to_binbuff(req.hex_raw_proposal, raw_tx_template); + if (!r) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; + er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT - failed to parse template from hex"; + return false; + } + if (!m_wallet.get_ionic_swap_proposal_info(raw_tx_template, res.proposal)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; + er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT - get_ionic_swap_proposal_info"; + return false; + } + return true; } //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_ionic_swap_accept_proposal(const wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx) { + std::string raw_tx_template; + bool r = epee::string_tools::parse_hexstr_to_binbuff(req.hex_raw_proposal, raw_tx_template); + if (!r) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; + er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT - failed to parse template from hex"; + return false; + } + + currency::transaction result_tx = AUTO_VAL_INIT(result_tx); + if (!m_wallet.accept_ionic_swap_proposal(raw_tx_template, result_tx)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; + er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT - failed to accept_ionic_swap_proposal()"; + return false; + } + + res.result_tx_id = currency::get_transaction_hash(result_tx); + return true; } //------------------------------------------------------------------------------------------------------------------------------ From 2ab206b6c106fc110b7e5dcf0ad76cf9693fafa9 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 27 Mar 2023 22:03:31 +0200 Subject: [PATCH 18/34] Multiwallet RPC API: initial code draft --- src/wallet/view_iface.h | 35 +----------- src/wallet/wallet2.h | 5 ++ src/wallet/wallet_public_structs_defs.h | 73 +++++++++++++++++++++++++ src/wallet/wallet_rpc_server.cpp | 28 +++++++++- src/wallet/wallet_rpc_server.h | 8 +++ 5 files changed, 114 insertions(+), 35 deletions(-) diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index 2773084b..caf4bad7 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -209,40 +209,9 @@ public: END_KV_SERIALIZE_MAP() }; - struct wallet_info - { - std::list balances; - uint64_t mined_total; - std::string address; - std::string view_sec_key; - std::string path; - bool is_auditable; - bool is_watch_only; + typedef wallet_public::wallet_info wallet_info; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(balances) - KV_SERIALIZE(mined_total) - KV_SERIALIZE(address) - KV_SERIALIZE(view_sec_key) - KV_SERIALIZE(path) - KV_SERIALIZE(is_auditable); - KV_SERIALIZE(is_watch_only); - END_KV_SERIALIZE_MAP() - }; - - - - struct wallet_entry_info - { - wallet_info wi; - uint64_t wallet_id; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(wi) - KV_SERIALIZE(wallet_id) - END_KV_SERIALIZE_MAP() - - }; + typedef wallet_public::wallet_entry_info wallet_entry_info; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index a53ca4a0..920a35b0 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -126,6 +126,10 @@ namespace tools virtual void on_transfer_canceled(const wallet_public::wallet_transfer_info& wti) {} virtual void on_message(message_severity /*severity*/, const std::string& /*m*/) {} virtual void on_tor_status_change(const std::string& state) {} + + //mw api + virtual void on_mw_get_wallets(std::vector& wallets) {} + virtual void on_mw_select_wallet(uint64_t wallet_id) {} }; struct tx_dust_policy @@ -546,6 +550,7 @@ namespace tools //i_wallet2_callback* callback() const { return m_wcallback; } //void callback(i_wallet2_callback* callback) { m_callback = callback; } void callback(std::shared_ptr callback) { m_wcallback = callback; m_do_rise_transfer = (callback != nullptr); } + i_wallet2_callback* get_callback() { return m_wcallback; } void set_do_rise_transfer(bool do_rise) { m_do_rise_transfer = do_rise; } bool has_related_alias_entry_unconfirmed(const currency::transaction& tx); diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 1fe59a3a..fb3a0d6a 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1246,6 +1246,79 @@ namespace wallet_public }; + struct wallet_info + { + std::list balances; + uint64_t mined_total; + std::string address; + std::string view_sec_key; + std::string path; + bool is_auditable; + bool is_watch_only; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(balances) + KV_SERIALIZE(mined_total) + KV_SERIALIZE(address) + KV_SERIALIZE(view_sec_key) + KV_SERIALIZE(path) + KV_SERIALIZE(is_auditable); + KV_SERIALIZE(is_watch_only); + END_KV_SERIALIZE_MAP() + }; + + + + struct wallet_entry_info + { + wallet_info wi; + uint64_t wallet_id; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(wi) + KV_SERIALIZE(wallet_id) + END_KV_SERIALIZE_MAP() + + }; + + struct COMMAND_MW_GET_WALLETS + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::vector wallets; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(wallets) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_MW_SELECT_WALLET + { + struct request + { + uint64_t wallet_id; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(wallet_id) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + }; + + struct assets_whitelist { std::vector assets; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 7001f4b7..d9822b23 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -999,6 +999,30 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - - + bool wallet_rpc_server::on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + i_wallet2_callback* pcallback = m_wallet.get_callback(); + if (!pcallback) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR"; + return false; + } + pcallback->on_mw_get_wallets(res.wallets); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + i_wallet2_callback* pcallback = m_wallet.get_callback(); + if (!pcallback) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR"; + return false; + } + pcallback->on_mw_select_wallet(req.wallet_id); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ } // namespace tools diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 8db43937..8c9c8a9d 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -77,6 +77,11 @@ namespace tools MAP_JON_RPC_WE("ionic_swap_generate_proposal", on_ionic_swap_generate_proposal, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL) MAP_JON_RPC_WE("ionic_swap_get_proposal_info", on_ionic_swap_get_proposal_info, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO) MAP_JON_RPC_WE("ionic_swap_accept_proposal", on_ionic_swap_accept_proposal, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL) + + //MULTIWALLET APIs + MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, wallet_public::COMMAND_MW_GET_WALLETS) + MAP_JON_RPC_WE("mw_select_wallet", on_mw_select_wallet, wallet_public::COMMAND_MW_SELECT_WALLET) + END_JSON_RPC_MAP() END_URI_MAP2() @@ -122,6 +127,9 @@ namespace tools bool on_ionic_swap_get_proposal_info(const wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO& req, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_ionic_swap_accept_proposal(const wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool handle_command_line(const boost::program_options::variables_map& vm); From 4ca3e2599546fadd258e70a8a2ddf7c00a91a944 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 29 Mar 2023 20:26:46 +0200 Subject: [PATCH 19/34] Multiwallet rpc server implementation: in work --- src/simplewallet/simplewallet.cpp | 11 +++ src/simplewallet/simplewallet.h | 2 + src/wallet/wallet2.h | 2 +- src/wallet/wallet_rpc_server.cpp | 154 ++++++++++++++++-------------- src/wallet/wallet_rpc_server.h | 6 +- src/wallet/wallets_manager.cpp | 24 +++++ src/wallet/wallets_manager.h | 5 + 7 files changed, 127 insertions(+), 77 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 7d6e2096..ec4b5b5d 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -695,6 +695,17 @@ void simple_wallet::on_tor_status_change(const std::string& state) message_writer(epee::log_space::console_color_yellow, true, std::string("[TOR]: ")) << human_message; } //---------------------------------------------------------------------------------------------------- +void simple_wallet::on_mw_get_wallets(std::vector& wallets) +{ + wallets.resize(1); + tools::get_wallet_info(*m_wallet, wallets[0].wi); +} +//---------------------------------------------------------------------------------------------------- +bool simple_wallet::on_mw_select_wallet(uint64_t wallet_id) +{ + return true; +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::refresh(const std::vector& args) { if (m_offline_mode) diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 7ac24682..2daee3de 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -111,6 +111,8 @@ namespace currency virtual void on_message(i_wallet2_callback::message_severity severity, const std::string& m) override; virtual void on_tor_status_change(const std::string& state) override; + virtual void on_mw_get_wallets(std::vector& wallets) override; + virtual bool on_mw_select_wallet(uint64_t wallet_id) override; //---------------------------------------------------------- friend class refresh_progress_reporter_t; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 920a35b0..5fdd93f4 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -129,7 +129,7 @@ namespace tools //mw api virtual void on_mw_get_wallets(std::vector& wallets) {} - virtual void on_mw_select_wallet(uint64_t wallet_id) {} + virtual bool on_mw_select_wallet(uint64_t wallet_id) {} }; struct tx_dust_policy diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index d9822b23..f9f5db77 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -57,7 +57,7 @@ namespace tools } //------------------------------------------------------------------------------------------------------------------------------ wallet_rpc_server::wallet_rpc_server(wallet2& w) - : m_wallet(w) + : m_pwallet(&w) , m_do_mint(false) , m_deaf(false) , m_last_wallet_store_height(0) @@ -79,7 +79,7 @@ namespace tools bool received_money = false, ok = false; std::atomic stop(false); LOG_PRINT_L2("wallet RPC idle: refreshing..."); - m_wallet.refresh(blocks_fetched, received_money, ok, stop); + m_pwallet->refresh(blocks_fetched, received_money, ok, stop); if (stop) { LOG_PRINT_L1("wallet RPC idle: refresh failed"); @@ -88,24 +88,24 @@ namespace tools bool has_related_alias_in_unconfirmed = false; LOG_PRINT_L2("wallet RPC idle: scanning tx pool..."); - m_wallet.scan_tx_pool(has_related_alias_in_unconfirmed); + m_pwallet->scan_tx_pool(has_related_alias_in_unconfirmed); if (m_do_mint) { LOG_PRINT_L2("wallet RPC idle: trying to do PoS iteration..."); - m_wallet.try_mint_pos(miner_address); + m_pwallet->try_mint_pos(miner_address); } //auto-store wallet in server mode, let's do it every 24-hour - if (m_wallet.get_top_block_height() < m_last_wallet_store_height) + if (m_pwallet->get_top_block_height() < m_last_wallet_store_height) { - LOG_ERROR("Unexpected m_last_wallet_store_height = " << m_last_wallet_store_height << " or " << m_wallet.get_top_block_height()); + LOG_ERROR("Unexpected m_last_wallet_store_height = " << m_last_wallet_store_height << " or " << m_pwallet->get_top_block_height()); } - else if (m_wallet.get_top_block_height() - m_last_wallet_store_height > CURRENCY_BLOCKS_PER_DAY) + else if (m_pwallet->get_top_block_height() - m_last_wallet_store_height > CURRENCY_BLOCKS_PER_DAY) { //store wallet - m_wallet.store(); - m_last_wallet_store_height = m_wallet.get_top_block_height(); + m_pwallet->store(); + m_last_wallet_store_height = m_pwallet->get_top_block_height(); } } catch (error::no_connection_to_daemon&) @@ -141,14 +141,14 @@ namespace tools if (command_line::has_arg(vm, arg_miner_text_info)) { - m_wallet.set_miner_text_info(command_line::get_arg(vm, arg_miner_text_info)); + m_pwallet->set_miner_text_info(command_line::get_arg(vm, arg_miner_text_info)); } return true; } //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::init(const boost::program_options::variables_map& vm) { - m_last_wallet_store_height = m_wallet.get_top_block_height(); + m_last_wallet_store_height = m_pwallet->get_top_block_height(); m_net_server.set_threads_prefix("RPC"); bool r = handle_command_line(vm); CHECK_AND_ASSERT_MES(r, false, "Failed to process command line in core_rpc_server"); @@ -186,10 +186,10 @@ namespace tools { try { - // res.balance = m_wallet.balance(); - // res.unlocked_balance = m_wallet.unlocked_balance(); + // res.balance = m_pwallet->balance(); + // res.unlocked_balance = m_pwallet->unlocked_balance(); uint64_t mined = 0; - m_wallet.balance(res.balances, mined); + m_pwallet->balance(res.balances, mined); for (auto it = res.balances.begin(); it != res.balances.end(); it++) { if (it->asset_info.asset_id == currency::null_hash) @@ -212,7 +212,7 @@ namespace tools { try { - res.address = m_wallet.get_account().get_public_address_str(); + res.address = m_pwallet->get_account().get_public_address_str(); } catch (std::exception& e) { @@ -226,17 +226,17 @@ namespace tools { try { - res.address = m_wallet.get_account().get_public_address_str(); - res.is_whatch_only = m_wallet.is_watch_only(); - res.path = epee::string_encoding::convert_to_ansii(m_wallet.get_wallet_path()); - res.transfers_count = m_wallet.get_recent_transfers_total_count(); - res.transfer_entries_count = m_wallet.get_transfer_entries_count(); + res.address = m_pwallet->get_account().get_public_address_str(); + res.is_whatch_only = m_pwallet->is_watch_only(); + res.path = epee::string_encoding::convert_to_ansii(m_pwallet->get_wallet_path()); + res.transfers_count = m_pwallet->get_recent_transfers_total_count(); + res.transfer_entries_count = m_pwallet->get_transfer_entries_count(); std::map distribution; - m_wallet.get_utxo_distribution(distribution); + m_pwallet->get_utxo_distribution(distribution); for (const auto& ent : distribution) res.utxo_distribution.push_back(currency::print_money_brief(ent.first) + ":" + std::to_string(ent.second)); - res.current_height = m_wallet.get_top_block_height(); + res.current_height = m_pwallet->get_top_block_height(); return true; } catch (std::exception& e) @@ -250,7 +250,7 @@ namespace tools { try { - res.seed_phrase = m_wallet.get_account().get_seed_phrase(req.seed_password); + res.seed_phrase = m_pwallet->get_account().get_seed_phrase(req.seed_password); return true; } catch (std::exception& e) @@ -271,21 +271,21 @@ namespace tools { if (req.update_provision_info) { - res.pi.balance = m_wallet.balance(res.pi.unlocked_balance); - res.pi.transfer_entries_count = m_wallet.get_transfer_entries_count(); - res.pi.transfers_count = m_wallet.get_recent_transfers_total_count(); - res.pi.curent_height = m_wallet.get_top_block_height(); + res.pi.balance = m_pwallet->balance(res.pi.unlocked_balance); + res.pi.transfer_entries_count = m_pwallet->get_transfer_entries_count(); + res.pi.transfers_count = m_pwallet->get_recent_transfers_total_count(); + res.pi.curent_height = m_pwallet->get_top_block_height(); } if (req.offset == 0 && !req.exclude_unconfirmed) - m_wallet.get_unconfirmed_transfers(res.transfers, req.exclude_mining_txs); + m_pwallet->get_unconfirmed_transfers(res.transfers, req.exclude_mining_txs); bool start_from_end = true; if (req.order == ORDER_FROM_BEGIN_TO_END) { start_from_end = false; } - m_wallet.get_recent_transfers_history(res.transfers, req.offset, req.count, res.total_transfers, res.last_item_index, req.exclude_mining_txs, start_from_end); + m_pwallet->get_recent_transfers_history(res.transfers, req.offset, req.count, res.total_transfers, res.last_item_index, req.exclude_mining_txs, start_from_end); return true; } @@ -299,10 +299,10 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_transfer(const wallet_public::COMMAND_RPC_TRANSFER::request& req, wallet_public::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx) { - if (req.fee < m_wallet.get_core_runtime_config().tx_pool_min_fee) + if (req.fee < m_pwallet->get_core_runtime_config().tx_pool_min_fee) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; - er.message = std::string("Given fee is too low: ") + epee::string_tools::num_to_string_fast(req.fee) + ", minimum is: " + epee::string_tools::num_to_string_fast(m_wallet.get_core_runtime_config().tx_pool_min_fee); + er.message = std::string("Given fee is too low: ") + epee::string_tools::num_to_string_fast(req.fee) + ", minimum is: " + epee::string_tools::num_to_string_fast(m_pwallet->get_core_runtime_config().tx_pool_min_fee); return false; } @@ -314,7 +314,7 @@ namespace tools return false; } - construct_tx_param ctp = m_wallet.get_default_construct_tx_param_inital(); + construct_tx_param ctp = m_pwallet->get_default_construct_tx_param_inital(); if (req.service_entries_permanent) { //put it to extra @@ -357,7 +357,7 @@ namespace tools wrap = true; //encrypt body with a special way } - else if(!m_wallet.get_transfer_address(it->address, de.addr.back(), embedded_payment_id)) + else if(!m_pwallet->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; @@ -396,7 +396,7 @@ namespace tools if (req.push_payer && !wrap) { - currency::create_and_add_tx_payer_to_container_from_address(extra, m_wallet.get_account().get_keys().account_address, m_wallet.get_top_block_height(), m_wallet.get_core_runtime_config()); + currency::create_and_add_tx_payer_to_container_from_address(extra, m_pwallet->get_account().get_keys().account_address, m_pwallet->get_top_block_height(), m_pwallet->get_core_runtime_config()); } if (!req.hide_receiver) @@ -404,7 +404,7 @@ namespace tools for (auto& d : dsts) { for (auto& a : d.addr) - currency::create_and_add_tx_receiver_to_container_from_address(extra, a, m_wallet.get_top_block_height(), m_wallet.get_core_runtime_config()); + currency::create_and_add_tx_receiver_to_container_from_address(extra, a, m_pwallet->get_top_block_height(), m_pwallet->get_core_runtime_config()); } } @@ -412,8 +412,8 @@ namespace tools std::string unsigned_tx_blob_str; ctp.fee = req.fee; ctp.fake_outputs_count = req.mixin; - m_wallet.transfer(ctp, result, true, &unsigned_tx_blob_str); - if (m_wallet.is_watch_only()) + m_pwallet->transfer(ctp, result, true, &unsigned_tx_blob_str); + if (m_pwallet->is_watch_only()) { res.tx_unsigned_hex = epee::string_tools::buff_to_hex_nodelimer(unsigned_tx_blob_str); // watch-only wallets could not sign and relay transactions // leave res.tx_hash empty, because tx hash will change after signing @@ -449,9 +449,9 @@ namespace tools bool wallet_rpc_server::on_store(const wallet_public::COMMAND_RPC_STORE::request& req, wallet_public::COMMAND_RPC_STORE::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_wallet.store(); + m_pwallet->store(); boost::system::error_code ec = AUTO_VAL_INIT(ec); - res.wallet_file_size = m_wallet.get_wallet_file_size(); + res.wallet_file_size = m_pwallet->get_wallet_file_size(); WALLET_RPC_CATCH_TRY_ENTRY(); return true; } @@ -468,7 +468,7 @@ namespace tools res.payments.clear(); std::list payment_list; - m_wallet.get_payments(payment_id, payment_list); + m_pwallet->get_payments(payment_id, payment_list); for (auto payment : payment_list) { if (payment.m_unlock_time && !req.allow_locked_transactions) @@ -505,7 +505,7 @@ namespace tools } std::list payment_list; - m_wallet.get_payments(payment_id, payment_list, req.min_block_height); + m_pwallet->get_payments(payment_id, payment_list, req.min_block_height); for (auto & payment : payment_list) { @@ -553,7 +553,7 @@ namespace tools crypto::generate_random_bytes(payment_id.size(), &payment_id.front()); } - res.integrated_address = currency::get_account_address_and_payment_id_as_str(m_wallet.get_account().get_public_address(), payment_id); + res.integrated_address = currency::get_account_address_and_payment_id_as_str(m_pwallet->get_account().get_public_address(), payment_id); res.payment_id = epee::string_tools::buff_to_hex_nodelimer(payment_id); return !res.integrated_address.empty(); @@ -587,7 +587,7 @@ namespace tools currency::account_public_address addr; currency::payment_id_t integrated_payment_id; - if (!m_wallet.get_transfer_address(req.address, addr, integrated_payment_id)) + if (!m_pwallet->get_transfer_address(req.address, addr, integrated_payment_id)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; er.message = std::string("Invalid address: ") + req.address; @@ -606,10 +606,10 @@ namespace tools payment_id = integrated_payment_id; } - if (req.fee < m_wallet.get_core_runtime_config().tx_pool_min_fee) + if (req.fee < m_pwallet->get_core_runtime_config().tx_pool_min_fee) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; - er.message = std::string("Given fee is too low: ") + epee::string_tools::num_to_string_fast(req.fee) + ", minimum is: " + epee::string_tools::num_to_string_fast(m_wallet.get_core_runtime_config().tx_pool_min_fee); + er.message = std::string("Given fee is too low: ") + epee::string_tools::num_to_string_fast(req.fee) + ", minimum is: " + epee::string_tools::num_to_string_fast(m_pwallet->get_core_runtime_config().tx_pool_min_fee); return false; } @@ -620,14 +620,14 @@ namespace tools uint64_t amount_total = 0, amount_swept = 0; std::string unsigned_tx_blob_str; - m_wallet.sweep_below(req.mixin, addr, req.amount, payment_id, req.fee, outs_total, amount_total, outs_swept, amount_swept, &tx, &unsigned_tx_blob_str); + m_pwallet->sweep_below(req.mixin, addr, req.amount, payment_id, req.fee, outs_total, amount_total, outs_swept, amount_swept, &tx, &unsigned_tx_blob_str); res.amount_swept = amount_swept; res.amount_total = amount_total; res.outs_swept = outs_swept; res.outs_total = outs_total; - if (m_wallet.is_watch_only()) + if (m_pwallet->is_watch_only()) { res.tx_unsigned_hex = epee::string_tools::buff_to_hex_nodelimer(unsigned_tx_blob_str); // watch-only wallets can't sign and relay transactions // leave res.tx_hash empty, because tx has will change after signing @@ -673,7 +673,7 @@ namespace tools return false; } std::string tx_signed_blob; - m_wallet.sign_transfer(tx_unsigned_blob, tx_signed_blob, tx); + m_pwallet->sign_transfer(tx_unsigned_blob, tx_signed_blob, tx); res.tx_signed_hex = epee::string_tools::buff_to_hex_nodelimer(tx_signed_blob); res.tx_hash = epee::string_tools::pod_to_hex(currency::get_transaction_hash(tx)); @@ -693,7 +693,7 @@ namespace tools WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction tx = AUTO_VAL_INIT(tx); - m_wallet.submit_transfer(tx_signed_blob, tx); + m_pwallet->submit_transfer(tx_signed_blob, tx); res.tx_hash = epee::string_tools::pod_to_hex(currency::get_transaction_hash(tx)); WALLET_RPC_CATCH_TRY_ENTRY(); @@ -705,7 +705,7 @@ namespace tools bool tx_id_specified = req.tx_id != currency::null_hash; // process confirmed txs - m_wallet.enumerate_transfers_history([&](const wallet_public::wallet_transfer_info& wti) -> bool { + m_pwallet->enumerate_transfers_history([&](const wallet_public::wallet_transfer_info& wti) -> bool { if (tx_id_specified) { @@ -741,7 +741,7 @@ namespace tools // process unconfirmed txs if (req.pool) { - m_wallet.enumerate_unconfirmed_transfers([&](const wallet_public::wallet_transfer_info& wti) -> bool { + m_pwallet->enumerate_unconfirmed_transfers([&](const wallet_public::wallet_transfer_info& wti) -> bool { if ((wti.is_income && req.in) || (!wti.is_income && req.out)) res.pool.push_back(wti); return true; // continue @@ -752,7 +752,7 @@ namespace tools } bool wallet_rpc_server::on_get_mining_history(const wallet_public::COMMAND_RPC_GET_MINING_HISTORY::request& req, wallet_public::COMMAND_RPC_GET_MINING_HISTORY::response& res, epee::json_rpc::error& er, connection_context& cntx) { - m_wallet.get_mining_history(res, req.v); + m_pwallet->get_mining_history(res, req.v); return true; } //------------------------------------------------------------------------------------------------------------------------------ @@ -775,7 +775,7 @@ namespace tools } currency::transaction tx = AUTO_VAL_INIT(tx); - m_wallet.request_alias_registration(ai, tx, m_wallet.get_default_fee(), 0, req.authority_key); + m_pwallet->request_alias_registration(ai, tx, m_pwallet->get_default_fee(), 0, req.authority_key); res.tx_id = get_transaction_hash(tx); return true; WALLET_RPC_CATCH_TRY_ENTRY(); @@ -786,7 +786,7 @@ namespace tools WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction tx = AUTO_VAL_INIT(tx); currency::transaction template_tx = AUTO_VAL_INIT(template_tx); - m_wallet.send_escrow_proposal(req, tx, template_tx); + m_pwallet->send_escrow_proposal(req, tx, template_tx); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -794,7 +794,7 @@ namespace tools bool wallet_rpc_server::on_contracts_accept_proposal(const wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_wallet.accept_proposal(req.contract_id, req.acceptance_fee); + m_pwallet->accept_proposal(req.contract_id, req.acceptance_fee); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -803,7 +803,7 @@ namespace tools { WALLET_RPC_BEGIN_TRY_ENTRY(); tools::wallet2::escrow_contracts_container ecc; - m_wallet.get_contracts(ecc); + m_pwallet->get_contracts(ecc); res.contracts.resize(ecc.size()); size_t i = 0; for (auto& c : ecc) @@ -819,7 +819,7 @@ namespace tools bool wallet_rpc_server::on_contracts_release(const wallet_public::COMMAND_CONTRACTS_RELEASE::request& req, wallet_public::COMMAND_CONTRACTS_RELEASE::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_wallet.finish_contract(req.contract_id, req.release_type); + m_pwallet->finish_contract(req.contract_id, req.release_type); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -827,7 +827,7 @@ namespace tools bool wallet_rpc_server::on_contracts_request_cancel(const wallet_public::COMMAND_CONTRACTS_REQUEST_CANCEL::request& req, wallet_public::COMMAND_CONTRACTS_REQUEST_CANCEL::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_wallet.request_cancel_contract(req.contract_id, req.fee, req.expiration_period); + m_pwallet->request_cancel_contract(req.contract_id, req.fee, req.expiration_period); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -835,7 +835,7 @@ namespace tools bool wallet_rpc_server::on_contracts_accept_cancel(const wallet_public::COMMAND_CONTRACTS_ACCEPT_CANCEL::request& req, wallet_public::COMMAND_CONTRACTS_ACCEPT_CANCEL::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_wallet.accept_cancel_contract(req.contract_id); + m_pwallet->accept_cancel_contract(req.contract_id); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -843,9 +843,9 @@ namespace tools bool wallet_rpc_server::on_marketplace_get_my_offers(const wallet_public::COMMAND_MARKETPLACE_GET_MY_OFFERS::request& req, wallet_public::COMMAND_MARKETPLACE_GET_MY_OFFERS::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_wallet.get_actual_offers(res.offers); + m_pwallet->get_actual_offers(res.offers); size_t offers_count_before_filtering = res.offers.size(); - bc_services::filter_offers_list(res.offers, req.filter, m_wallet.get_core_runtime_config().get_core_time()); + bc_services::filter_offers_list(res.offers, req.filter, m_pwallet->get_core_runtime_config().get_core_time()); LOG_PRINT("get_my_offers(): " << res.offers.size() << " offers returned (" << offers_count_before_filtering << " was before filter)", LOG_LEVEL_1); return true; WALLET_RPC_CATCH_TRY_ENTRY(); @@ -855,7 +855,7 @@ namespace tools { WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction res_tx = AUTO_VAL_INIT(res_tx); - m_wallet.push_offer(req.od, res_tx); + m_pwallet->push_offer(req.od, res_tx); res.tx_hash = string_tools::pod_to_hex(currency::get_transaction_hash(res_tx)); res.tx_blob_size = currency::get_object_blobsize(res_tx); @@ -868,7 +868,7 @@ namespace tools WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction res_tx = AUTO_VAL_INIT(res_tx); - m_wallet.update_offer_by_id(req.tx_id, req.no, req.od, res_tx); + m_pwallet->update_offer_by_id(req.tx_id, req.no, req.od, res_tx); res.tx_hash = string_tools::pod_to_hex(currency::get_transaction_hash(res_tx)); res.tx_blob_size = currency::get_object_blobsize(res_tx); @@ -880,7 +880,7 @@ namespace tools { WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction res_tx = AUTO_VAL_INIT(res_tx); - m_wallet.cancel_offer_by_id(req.tx_id, req.no, req.fee, res_tx); + m_pwallet->cancel_offer_by_id(req.tx_id, req.no, req.fee, res_tx); res.tx_hash = string_tools::pod_to_hex(currency::get_transaction_hash(res_tx)); res.tx_blob_size = currency::get_object_blobsize(res_tx); @@ -892,7 +892,7 @@ namespace tools { WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction tx = AUTO_VAL_INIT(tx); - m_wallet.create_htlc_proposal(req.amount, req.counterparty_address, req.lock_blocks_count, tx, req.htlc_hash, res.derived_origin_secret); + m_pwallet->create_htlc_proposal(req.amount, req.counterparty_address, req.lock_blocks_count, tx, req.htlc_hash, res.derived_origin_secret); res.result_tx_blob = currency::tx_to_blob(tx); res.result_tx_id = get_transaction_hash(tx); WALLET_RPC_CATCH_TRY_ENTRY(); @@ -902,7 +902,7 @@ namespace tools bool wallet_rpc_server::on_get_list_of_active_htlc(const wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC::request& req, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_wallet.get_list_of_active_htlc(res.htlcs, req.income_redeem_only); + m_pwallet->get_list_of_active_htlc(res.htlcs, req.income_redeem_only); WALLET_RPC_CATCH_TRY_ENTRY(); return true; } @@ -911,7 +911,7 @@ namespace tools { WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction tx = AUTO_VAL_INIT(tx); - m_wallet.redeem_htlc(req.tx_id, req.origin_secret, tx); + m_pwallet->redeem_htlc(req.tx_id, req.origin_secret, tx); res.result_tx_blob = currency::tx_to_blob(tx); res.result_tx_id = get_transaction_hash(tx); WALLET_RPC_CATCH_TRY_ENTRY(); @@ -921,7 +921,7 @@ namespace tools bool wallet_rpc_server::on_check_htlc_redeemed(const wallet_public::COMMAND_CHECK_HTLC_REDEEMED::request& req, wallet_public::COMMAND_CHECK_HTLC_REDEEMED::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_wallet.check_htlc_redeemed(req.htlc_tx_id, res.origin_secrete, res.redeem_tx_id); + m_pwallet->check_htlc_redeemed(req.htlc_tx_id, res.origin_secrete, res.redeem_tx_id); WALLET_RPC_CATCH_TRY_ENTRY(); return true; } @@ -930,7 +930,7 @@ namespace tools { currency::account_public_address destination_addr = AUTO_VAL_INIT(destination_addr); currency::payment_id_t integrated_payment_id; - if (!m_wallet.get_transfer_address(req.destination_address, destination_addr, integrated_payment_id)) + if (!m_pwallet->get_transfer_address(req.destination_address, destination_addr, integrated_payment_id)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; er.message = "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS"; @@ -944,7 +944,7 @@ namespace tools } currency::transaction tx_template = AUTO_VAL_INIT(tx_template); - bool r = m_wallet.create_ionic_swap_proposal(req.proposal, destination_addr, tx_template); + bool r = m_pwallet->create_ionic_swap_proposal(req.proposal, destination_addr, tx_template); if (!r) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; @@ -966,7 +966,7 @@ namespace tools return false; } - if (!m_wallet.get_ionic_swap_proposal_info(raw_tx_template, res.proposal)) + if (!m_pwallet->get_ionic_swap_proposal_info(raw_tx_template, res.proposal)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT - get_ionic_swap_proposal_info"; @@ -988,7 +988,7 @@ namespace tools } currency::transaction result_tx = AUTO_VAL_INIT(result_tx); - if (!m_wallet.accept_ionic_swap_proposal(raw_tx_template, result_tx)) + if (!m_pwallet->accept_ionic_swap_proposal(raw_tx_template, result_tx)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT - failed to accept_ionic_swap_proposal()"; @@ -1001,7 +1001,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx) { - i_wallet2_callback* pcallback = m_wallet.get_callback(); + i_wallet2_callback* pcallback = m_pwallet->get_callback(); if (!pcallback) { er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; @@ -1014,7 +1014,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx) { - i_wallet2_callback* pcallback = m_wallet.get_callback(); + i_wallet2_callback* pcallback = m_pwallet->get_callback(); if (!pcallback) { er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; @@ -1025,4 +1025,10 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::reset_active_wallet(wallet2& w) + { + m_pwallet = &w; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ } // namespace tools diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 8c9c8a9d..223e7497 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -129,12 +129,14 @@ namespace tools bool on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx); - + + + bool reset_active_wallet(wallet2& w); bool handle_command_line(const boost::program_options::variables_map& vm); private: - wallet2& m_wallet; + wallet2* m_pwallet; std::string m_port; std::string m_bind_ip; bool m_do_mint; diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 21a7f8d0..de0e07f8 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -2002,6 +2002,30 @@ void wallets_manager::on_tor_status_change(size_t wallet_id, const std::string& m_pview->update_tor_status(tsu); } +void wallets_manager::on_mw_get_wallets(std::vector& wallets) +{ + std::list opened_wallets; + this->get_opened_wallets(opened_wallets); + wallets.resize(opened_wallets.size()); + size_t i = 0; + for (const auto& item : opened_wallets) + { + wallets[i].wi = item.wi; + wallets[i].wallet_id = item.wallet_id; + i++; + } +} +bool wallets_manager::on_mw_select_wallet(uint64_t wallet_id) +{ + SHARED_CRITICAL_REGION_LOCAL(m_wallets_lock); + auto it = m_wallets.find(wallet_id); + if (it == m_wallets.end()) + return false; + auto& wo = it->second; + m_wallet_rpc_server.reset_active_wallet(wo.w); +} + + void wallets_manager::wallet_vs_options::worker_func() { LOG_PRINT_GREEN("[WALLET_HANDLER] Wallet handler thread started, addr: " << w->get()->get_account().get_public_address_str(), LOG_LEVEL_0); diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index d17cb437..ba73f431 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -193,6 +193,10 @@ private: virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti); virtual void on_tor_status_change(size_t wallet_id, const std::string& state); + virtual void on_mw_get_wallets(std::vector& wallets) override; + virtual bool on_mw_select_wallet(uint64_t wallet_id) override; + + //-------- std::thread m_main_worker_thread; @@ -224,6 +228,7 @@ private: currency::t_currency_protocol_handler m_cprotocol; nodetool::node_server > m_p2psrv; currency::core_rpc_server m_rpc_server; + tools::wallet_rpc_server m_wallet_rpc_server; //optional initialization #endif bool m_remote_node_mode; From ca7d50d9ff80d463d1c5e2b9ec18e153933a8528 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 30 Mar 2023 23:21:51 +0200 Subject: [PATCH 20/34] RPC server for UI: in work(need to overcome synchronization problem) --- src/simplewallet/simplewallet.h | 2 +- src/wallet/wallet_rpc_server.cpp | 155 ++++++++++++++++--------------- src/wallet/wallet_rpc_server.h | 4 +- 3 files changed, 83 insertions(+), 78 deletions(-) diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 2daee3de..e6924ca3 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -185,7 +185,7 @@ namespace currency epee::console_handlers_binder m_cmd_binder; - std::unique_ptr m_wallet; + std::shared_ptr m_wallet; net_utils::http::http_simple_client m_http_client; refresh_progress_reporter_t m_refresh_progress_reporter; }; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index f9f5db77..cf2b2d2a 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -56,13 +56,18 @@ namespace tools command_line::add_arg(desc, arg_deaf_mode); } //------------------------------------------------------------------------------------------------------------------------------ - wallet_rpc_server::wallet_rpc_server(wallet2& w) - : m_pwallet(&w) + wallet_rpc_server::wallet_rpc_server(std::shared_ptr wptr) + : m_pwallet(wptr) , m_do_mint(false) , m_deaf(false) , m_last_wallet_store_height(0) {} //------------------------------------------------------------------------------------------------------------------------------ + std::shared_ptr wallet_rpc_server::get_wallet() + { + return std::shared_ptr(m_pwallet); + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::run(bool do_mint, bool offline_mode, const currency::account_public_address& miner_address) { static const uint64_t wallet_rpc_idle_work_period_ms = 2000; @@ -79,7 +84,7 @@ namespace tools bool received_money = false, ok = false; std::atomic stop(false); LOG_PRINT_L2("wallet RPC idle: refreshing..."); - m_pwallet->refresh(blocks_fetched, received_money, ok, stop); + get_wallet()->refresh(blocks_fetched, received_money, ok, stop); if (stop) { LOG_PRINT_L1("wallet RPC idle: refresh failed"); @@ -88,24 +93,24 @@ namespace tools bool has_related_alias_in_unconfirmed = false; LOG_PRINT_L2("wallet RPC idle: scanning tx pool..."); - m_pwallet->scan_tx_pool(has_related_alias_in_unconfirmed); + get_wallet()->scan_tx_pool(has_related_alias_in_unconfirmed); if (m_do_mint) { LOG_PRINT_L2("wallet RPC idle: trying to do PoS iteration..."); - m_pwallet->try_mint_pos(miner_address); + get_wallet()->try_mint_pos(miner_address); } //auto-store wallet in server mode, let's do it every 24-hour - if (m_pwallet->get_top_block_height() < m_last_wallet_store_height) + if (get_wallet()->get_top_block_height() < m_last_wallet_store_height) { - LOG_ERROR("Unexpected m_last_wallet_store_height = " << m_last_wallet_store_height << " or " << m_pwallet->get_top_block_height()); + LOG_ERROR("Unexpected m_last_wallet_store_height = " << m_last_wallet_store_height << " or " << get_wallet()->get_top_block_height()); } - else if (m_pwallet->get_top_block_height() - m_last_wallet_store_height > CURRENCY_BLOCKS_PER_DAY) + else if (get_wallet()->get_top_block_height() - m_last_wallet_store_height > CURRENCY_BLOCKS_PER_DAY) { //store wallet - m_pwallet->store(); - m_last_wallet_store_height = m_pwallet->get_top_block_height(); + get_wallet()->store(); + m_last_wallet_store_height = get_wallet()->get_top_block_height(); } } catch (error::no_connection_to_daemon&) @@ -141,14 +146,14 @@ namespace tools if (command_line::has_arg(vm, arg_miner_text_info)) { - m_pwallet->set_miner_text_info(command_line::get_arg(vm, arg_miner_text_info)); + get_wallet()->set_miner_text_info(command_line::get_arg(vm, arg_miner_text_info)); } return true; } //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::init(const boost::program_options::variables_map& vm) { - m_last_wallet_store_height = m_pwallet->get_top_block_height(); + m_last_wallet_store_height = get_wallet()->get_top_block_height(); m_net_server.set_threads_prefix("RPC"); bool r = handle_command_line(vm); CHECK_AND_ASSERT_MES(r, false, "Failed to process command line in core_rpc_server"); @@ -186,10 +191,10 @@ namespace tools { try { - // res.balance = m_pwallet->balance(); - // res.unlocked_balance = m_pwallet->unlocked_balance(); + // res.balance = get_wallet()->balance(); + // res.unlocked_balance = get_wallet()->unlocked_balance(); uint64_t mined = 0; - m_pwallet->balance(res.balances, mined); + get_wallet()->balance(res.balances, mined); for (auto it = res.balances.begin(); it != res.balances.end(); it++) { if (it->asset_info.asset_id == currency::null_hash) @@ -212,7 +217,7 @@ namespace tools { try { - res.address = m_pwallet->get_account().get_public_address_str(); + res.address = get_wallet()->get_account().get_public_address_str(); } catch (std::exception& e) { @@ -226,17 +231,17 @@ namespace tools { try { - res.address = m_pwallet->get_account().get_public_address_str(); - res.is_whatch_only = m_pwallet->is_watch_only(); - res.path = epee::string_encoding::convert_to_ansii(m_pwallet->get_wallet_path()); - res.transfers_count = m_pwallet->get_recent_transfers_total_count(); - res.transfer_entries_count = m_pwallet->get_transfer_entries_count(); + res.address = get_wallet()->get_account().get_public_address_str(); + res.is_whatch_only = get_wallet()->is_watch_only(); + res.path = epee::string_encoding::convert_to_ansii(get_wallet()->get_wallet_path()); + res.transfers_count = get_wallet()->get_recent_transfers_total_count(); + res.transfer_entries_count = get_wallet()->get_transfer_entries_count(); std::map distribution; - m_pwallet->get_utxo_distribution(distribution); + get_wallet()->get_utxo_distribution(distribution); for (const auto& ent : distribution) res.utxo_distribution.push_back(currency::print_money_brief(ent.first) + ":" + std::to_string(ent.second)); - res.current_height = m_pwallet->get_top_block_height(); + res.current_height = get_wallet()->get_top_block_height(); return true; } catch (std::exception& e) @@ -250,7 +255,7 @@ namespace tools { try { - res.seed_phrase = m_pwallet->get_account().get_seed_phrase(req.seed_password); + res.seed_phrase = get_wallet()->get_account().get_seed_phrase(req.seed_password); return true; } catch (std::exception& e) @@ -271,21 +276,21 @@ namespace tools { if (req.update_provision_info) { - res.pi.balance = m_pwallet->balance(res.pi.unlocked_balance); - res.pi.transfer_entries_count = m_pwallet->get_transfer_entries_count(); - res.pi.transfers_count = m_pwallet->get_recent_transfers_total_count(); - res.pi.curent_height = m_pwallet->get_top_block_height(); + res.pi.balance = get_wallet()->balance(res.pi.unlocked_balance); + res.pi.transfer_entries_count = get_wallet()->get_transfer_entries_count(); + res.pi.transfers_count = get_wallet()->get_recent_transfers_total_count(); + res.pi.curent_height = get_wallet()->get_top_block_height(); } if (req.offset == 0 && !req.exclude_unconfirmed) - m_pwallet->get_unconfirmed_transfers(res.transfers, req.exclude_mining_txs); + get_wallet()->get_unconfirmed_transfers(res.transfers, req.exclude_mining_txs); bool start_from_end = true; if (req.order == ORDER_FROM_BEGIN_TO_END) { start_from_end = false; } - m_pwallet->get_recent_transfers_history(res.transfers, req.offset, req.count, res.total_transfers, res.last_item_index, req.exclude_mining_txs, start_from_end); + get_wallet()->get_recent_transfers_history(res.transfers, req.offset, req.count, res.total_transfers, res.last_item_index, req.exclude_mining_txs, start_from_end); return true; } @@ -299,10 +304,10 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_transfer(const wallet_public::COMMAND_RPC_TRANSFER::request& req, wallet_public::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx) { - if (req.fee < m_pwallet->get_core_runtime_config().tx_pool_min_fee) + if (req.fee < get_wallet()->get_core_runtime_config().tx_pool_min_fee) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; - er.message = std::string("Given fee is too low: ") + epee::string_tools::num_to_string_fast(req.fee) + ", minimum is: " + epee::string_tools::num_to_string_fast(m_pwallet->get_core_runtime_config().tx_pool_min_fee); + er.message = std::string("Given fee is too low: ") + epee::string_tools::num_to_string_fast(req.fee) + ", minimum is: " + epee::string_tools::num_to_string_fast(get_wallet()->get_core_runtime_config().tx_pool_min_fee); return false; } @@ -314,7 +319,7 @@ namespace tools return false; } - construct_tx_param ctp = m_pwallet->get_default_construct_tx_param_inital(); + construct_tx_param ctp = get_wallet()->get_default_construct_tx_param_inital(); if (req.service_entries_permanent) { //put it to extra @@ -357,7 +362,7 @@ namespace tools wrap = true; //encrypt body with a special way } - else if(!m_pwallet->get_transfer_address(it->address, de.addr.back(), embedded_payment_id)) + else if(!get_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; @@ -396,7 +401,7 @@ namespace tools if (req.push_payer && !wrap) { - currency::create_and_add_tx_payer_to_container_from_address(extra, m_pwallet->get_account().get_keys().account_address, m_pwallet->get_top_block_height(), m_pwallet->get_core_runtime_config()); + currency::create_and_add_tx_payer_to_container_from_address(extra, get_wallet()->get_account().get_keys().account_address, get_wallet()->get_top_block_height(), get_wallet()->get_core_runtime_config()); } if (!req.hide_receiver) @@ -404,7 +409,7 @@ namespace tools for (auto& d : dsts) { for (auto& a : d.addr) - currency::create_and_add_tx_receiver_to_container_from_address(extra, a, m_pwallet->get_top_block_height(), m_pwallet->get_core_runtime_config()); + currency::create_and_add_tx_receiver_to_container_from_address(extra, a, get_wallet()->get_top_block_height(), get_wallet()->get_core_runtime_config()); } } @@ -412,8 +417,8 @@ namespace tools std::string unsigned_tx_blob_str; ctp.fee = req.fee; ctp.fake_outputs_count = req.mixin; - m_pwallet->transfer(ctp, result, true, &unsigned_tx_blob_str); - if (m_pwallet->is_watch_only()) + get_wallet()->transfer(ctp, result, true, &unsigned_tx_blob_str); + if (get_wallet()->is_watch_only()) { res.tx_unsigned_hex = epee::string_tools::buff_to_hex_nodelimer(unsigned_tx_blob_str); // watch-only wallets could not sign and relay transactions // leave res.tx_hash empty, because tx hash will change after signing @@ -449,9 +454,9 @@ namespace tools bool wallet_rpc_server::on_store(const wallet_public::COMMAND_RPC_STORE::request& req, wallet_public::COMMAND_RPC_STORE::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_pwallet->store(); + get_wallet()->store(); boost::system::error_code ec = AUTO_VAL_INIT(ec); - res.wallet_file_size = m_pwallet->get_wallet_file_size(); + res.wallet_file_size = get_wallet()->get_wallet_file_size(); WALLET_RPC_CATCH_TRY_ENTRY(); return true; } @@ -468,7 +473,7 @@ namespace tools res.payments.clear(); std::list payment_list; - m_pwallet->get_payments(payment_id, payment_list); + get_wallet()->get_payments(payment_id, payment_list); for (auto payment : payment_list) { if (payment.m_unlock_time && !req.allow_locked_transactions) @@ -505,7 +510,7 @@ namespace tools } std::list payment_list; - m_pwallet->get_payments(payment_id, payment_list, req.min_block_height); + get_wallet()->get_payments(payment_id, payment_list, req.min_block_height); for (auto & payment : payment_list) { @@ -553,7 +558,7 @@ namespace tools crypto::generate_random_bytes(payment_id.size(), &payment_id.front()); } - res.integrated_address = currency::get_account_address_and_payment_id_as_str(m_pwallet->get_account().get_public_address(), payment_id); + res.integrated_address = currency::get_account_address_and_payment_id_as_str(get_wallet()->get_account().get_public_address(), payment_id); res.payment_id = epee::string_tools::buff_to_hex_nodelimer(payment_id); return !res.integrated_address.empty(); @@ -587,7 +592,7 @@ namespace tools currency::account_public_address addr; currency::payment_id_t integrated_payment_id; - if (!m_pwallet->get_transfer_address(req.address, addr, integrated_payment_id)) + if (!get_wallet()->get_transfer_address(req.address, addr, integrated_payment_id)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; er.message = std::string("Invalid address: ") + req.address; @@ -606,10 +611,10 @@ namespace tools payment_id = integrated_payment_id; } - if (req.fee < m_pwallet->get_core_runtime_config().tx_pool_min_fee) + if (req.fee < get_wallet()->get_core_runtime_config().tx_pool_min_fee) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; - er.message = std::string("Given fee is too low: ") + epee::string_tools::num_to_string_fast(req.fee) + ", minimum is: " + epee::string_tools::num_to_string_fast(m_pwallet->get_core_runtime_config().tx_pool_min_fee); + er.message = std::string("Given fee is too low: ") + epee::string_tools::num_to_string_fast(req.fee) + ", minimum is: " + epee::string_tools::num_to_string_fast(get_wallet()->get_core_runtime_config().tx_pool_min_fee); return false; } @@ -620,14 +625,14 @@ namespace tools uint64_t amount_total = 0, amount_swept = 0; std::string unsigned_tx_blob_str; - m_pwallet->sweep_below(req.mixin, addr, req.amount, payment_id, req.fee, outs_total, amount_total, outs_swept, amount_swept, &tx, &unsigned_tx_blob_str); + get_wallet()->sweep_below(req.mixin, addr, req.amount, payment_id, req.fee, outs_total, amount_total, outs_swept, amount_swept, &tx, &unsigned_tx_blob_str); res.amount_swept = amount_swept; res.amount_total = amount_total; res.outs_swept = outs_swept; res.outs_total = outs_total; - if (m_pwallet->is_watch_only()) + if (get_wallet()->is_watch_only()) { res.tx_unsigned_hex = epee::string_tools::buff_to_hex_nodelimer(unsigned_tx_blob_str); // watch-only wallets can't sign and relay transactions // leave res.tx_hash empty, because tx has will change after signing @@ -673,7 +678,7 @@ namespace tools return false; } std::string tx_signed_blob; - m_pwallet->sign_transfer(tx_unsigned_blob, tx_signed_blob, tx); + get_wallet()->sign_transfer(tx_unsigned_blob, tx_signed_blob, tx); res.tx_signed_hex = epee::string_tools::buff_to_hex_nodelimer(tx_signed_blob); res.tx_hash = epee::string_tools::pod_to_hex(currency::get_transaction_hash(tx)); @@ -693,7 +698,7 @@ namespace tools WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction tx = AUTO_VAL_INIT(tx); - m_pwallet->submit_transfer(tx_signed_blob, tx); + get_wallet()->submit_transfer(tx_signed_blob, tx); res.tx_hash = epee::string_tools::pod_to_hex(currency::get_transaction_hash(tx)); WALLET_RPC_CATCH_TRY_ENTRY(); @@ -705,7 +710,7 @@ namespace tools bool tx_id_specified = req.tx_id != currency::null_hash; // process confirmed txs - m_pwallet->enumerate_transfers_history([&](const wallet_public::wallet_transfer_info& wti) -> bool { + get_wallet()->enumerate_transfers_history([&](const wallet_public::wallet_transfer_info& wti) -> bool { if (tx_id_specified) { @@ -741,7 +746,7 @@ namespace tools // process unconfirmed txs if (req.pool) { - m_pwallet->enumerate_unconfirmed_transfers([&](const wallet_public::wallet_transfer_info& wti) -> bool { + get_wallet()->enumerate_unconfirmed_transfers([&](const wallet_public::wallet_transfer_info& wti) -> bool { if ((wti.is_income && req.in) || (!wti.is_income && req.out)) res.pool.push_back(wti); return true; // continue @@ -752,7 +757,7 @@ namespace tools } bool wallet_rpc_server::on_get_mining_history(const wallet_public::COMMAND_RPC_GET_MINING_HISTORY::request& req, wallet_public::COMMAND_RPC_GET_MINING_HISTORY::response& res, epee::json_rpc::error& er, connection_context& cntx) { - m_pwallet->get_mining_history(res, req.v); + get_wallet()->get_mining_history(res, req.v); return true; } //------------------------------------------------------------------------------------------------------------------------------ @@ -775,7 +780,7 @@ namespace tools } currency::transaction tx = AUTO_VAL_INIT(tx); - m_pwallet->request_alias_registration(ai, tx, m_pwallet->get_default_fee(), 0, req.authority_key); + get_wallet()->request_alias_registration(ai, tx, get_wallet()->get_default_fee(), 0, req.authority_key); res.tx_id = get_transaction_hash(tx); return true; WALLET_RPC_CATCH_TRY_ENTRY(); @@ -786,7 +791,7 @@ namespace tools WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction tx = AUTO_VAL_INIT(tx); currency::transaction template_tx = AUTO_VAL_INIT(template_tx); - m_pwallet->send_escrow_proposal(req, tx, template_tx); + get_wallet()->send_escrow_proposal(req, tx, template_tx); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -794,7 +799,7 @@ namespace tools bool wallet_rpc_server::on_contracts_accept_proposal(const wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_pwallet->accept_proposal(req.contract_id, req.acceptance_fee); + get_wallet()->accept_proposal(req.contract_id, req.acceptance_fee); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -803,7 +808,7 @@ namespace tools { WALLET_RPC_BEGIN_TRY_ENTRY(); tools::wallet2::escrow_contracts_container ecc; - m_pwallet->get_contracts(ecc); + get_wallet()->get_contracts(ecc); res.contracts.resize(ecc.size()); size_t i = 0; for (auto& c : ecc) @@ -819,7 +824,7 @@ namespace tools bool wallet_rpc_server::on_contracts_release(const wallet_public::COMMAND_CONTRACTS_RELEASE::request& req, wallet_public::COMMAND_CONTRACTS_RELEASE::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_pwallet->finish_contract(req.contract_id, req.release_type); + get_wallet()->finish_contract(req.contract_id, req.release_type); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -827,7 +832,7 @@ namespace tools bool wallet_rpc_server::on_contracts_request_cancel(const wallet_public::COMMAND_CONTRACTS_REQUEST_CANCEL::request& req, wallet_public::COMMAND_CONTRACTS_REQUEST_CANCEL::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_pwallet->request_cancel_contract(req.contract_id, req.fee, req.expiration_period); + get_wallet()->request_cancel_contract(req.contract_id, req.fee, req.expiration_period); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -835,7 +840,7 @@ namespace tools bool wallet_rpc_server::on_contracts_accept_cancel(const wallet_public::COMMAND_CONTRACTS_ACCEPT_CANCEL::request& req, wallet_public::COMMAND_CONTRACTS_ACCEPT_CANCEL::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_pwallet->accept_cancel_contract(req.contract_id); + get_wallet()->accept_cancel_contract(req.contract_id); return true; WALLET_RPC_CATCH_TRY_ENTRY(); } @@ -843,9 +848,9 @@ namespace tools bool wallet_rpc_server::on_marketplace_get_my_offers(const wallet_public::COMMAND_MARKETPLACE_GET_MY_OFFERS::request& req, wallet_public::COMMAND_MARKETPLACE_GET_MY_OFFERS::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_pwallet->get_actual_offers(res.offers); + get_wallet()->get_actual_offers(res.offers); size_t offers_count_before_filtering = res.offers.size(); - bc_services::filter_offers_list(res.offers, req.filter, m_pwallet->get_core_runtime_config().get_core_time()); + bc_services::filter_offers_list(res.offers, req.filter, get_wallet()->get_core_runtime_config().get_core_time()); LOG_PRINT("get_my_offers(): " << res.offers.size() << " offers returned (" << offers_count_before_filtering << " was before filter)", LOG_LEVEL_1); return true; WALLET_RPC_CATCH_TRY_ENTRY(); @@ -855,7 +860,7 @@ namespace tools { WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction res_tx = AUTO_VAL_INIT(res_tx); - m_pwallet->push_offer(req.od, res_tx); + get_wallet()->push_offer(req.od, res_tx); res.tx_hash = string_tools::pod_to_hex(currency::get_transaction_hash(res_tx)); res.tx_blob_size = currency::get_object_blobsize(res_tx); @@ -868,7 +873,7 @@ namespace tools WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction res_tx = AUTO_VAL_INIT(res_tx); - m_pwallet->update_offer_by_id(req.tx_id, req.no, req.od, res_tx); + get_wallet()->update_offer_by_id(req.tx_id, req.no, req.od, res_tx); res.tx_hash = string_tools::pod_to_hex(currency::get_transaction_hash(res_tx)); res.tx_blob_size = currency::get_object_blobsize(res_tx); @@ -880,7 +885,7 @@ namespace tools { WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction res_tx = AUTO_VAL_INIT(res_tx); - m_pwallet->cancel_offer_by_id(req.tx_id, req.no, req.fee, res_tx); + get_wallet()->cancel_offer_by_id(req.tx_id, req.no, req.fee, res_tx); res.tx_hash = string_tools::pod_to_hex(currency::get_transaction_hash(res_tx)); res.tx_blob_size = currency::get_object_blobsize(res_tx); @@ -892,7 +897,7 @@ namespace tools { WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction tx = AUTO_VAL_INIT(tx); - m_pwallet->create_htlc_proposal(req.amount, req.counterparty_address, req.lock_blocks_count, tx, req.htlc_hash, res.derived_origin_secret); + get_wallet()->create_htlc_proposal(req.amount, req.counterparty_address, req.lock_blocks_count, tx, req.htlc_hash, res.derived_origin_secret); res.result_tx_blob = currency::tx_to_blob(tx); res.result_tx_id = get_transaction_hash(tx); WALLET_RPC_CATCH_TRY_ENTRY(); @@ -902,7 +907,7 @@ namespace tools bool wallet_rpc_server::on_get_list_of_active_htlc(const wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC::request& req, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_pwallet->get_list_of_active_htlc(res.htlcs, req.income_redeem_only); + get_wallet()->get_list_of_active_htlc(res.htlcs, req.income_redeem_only); WALLET_RPC_CATCH_TRY_ENTRY(); return true; } @@ -911,7 +916,7 @@ namespace tools { WALLET_RPC_BEGIN_TRY_ENTRY(); currency::transaction tx = AUTO_VAL_INIT(tx); - m_pwallet->redeem_htlc(req.tx_id, req.origin_secret, tx); + get_wallet()->redeem_htlc(req.tx_id, req.origin_secret, tx); res.result_tx_blob = currency::tx_to_blob(tx); res.result_tx_id = get_transaction_hash(tx); WALLET_RPC_CATCH_TRY_ENTRY(); @@ -921,7 +926,7 @@ namespace tools bool wallet_rpc_server::on_check_htlc_redeemed(const wallet_public::COMMAND_CHECK_HTLC_REDEEMED::request& req, wallet_public::COMMAND_CHECK_HTLC_REDEEMED::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); - m_pwallet->check_htlc_redeemed(req.htlc_tx_id, res.origin_secrete, res.redeem_tx_id); + get_wallet()->check_htlc_redeemed(req.htlc_tx_id, res.origin_secrete, res.redeem_tx_id); WALLET_RPC_CATCH_TRY_ENTRY(); return true; } @@ -930,7 +935,7 @@ namespace tools { currency::account_public_address destination_addr = AUTO_VAL_INIT(destination_addr); currency::payment_id_t integrated_payment_id; - if (!m_pwallet->get_transfer_address(req.destination_address, destination_addr, integrated_payment_id)) + if (!get_wallet()->get_transfer_address(req.destination_address, destination_addr, integrated_payment_id)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; er.message = "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS"; @@ -944,7 +949,7 @@ namespace tools } currency::transaction tx_template = AUTO_VAL_INIT(tx_template); - bool r = m_pwallet->create_ionic_swap_proposal(req.proposal, destination_addr, tx_template); + bool r = get_wallet()->create_ionic_swap_proposal(req.proposal, destination_addr, tx_template); if (!r) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; @@ -966,7 +971,7 @@ namespace tools return false; } - if (!m_pwallet->get_ionic_swap_proposal_info(raw_tx_template, res.proposal)) + if (!get_wallet()->get_ionic_swap_proposal_info(raw_tx_template, res.proposal)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT - get_ionic_swap_proposal_info"; @@ -988,7 +993,7 @@ namespace tools } currency::transaction result_tx = AUTO_VAL_INIT(result_tx); - if (!m_pwallet->accept_ionic_swap_proposal(raw_tx_template, result_tx)) + if (!get_wallet()->accept_ionic_swap_proposal(raw_tx_template, result_tx)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT - failed to accept_ionic_swap_proposal()"; @@ -1001,7 +1006,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx) { - i_wallet2_callback* pcallback = m_pwallet->get_callback(); + i_wallet2_callback* pcallback = get_wallet()->get_callback(); if (!pcallback) { er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; @@ -1014,7 +1019,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx) { - i_wallet2_callback* pcallback = m_pwallet->get_callback(); + i_wallet2_callback* pcallback = get_wallet()->get_callback(); if (!pcallback) { er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 223e7497..e04b0d47 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -22,7 +22,7 @@ namespace tools public: typedef epee::net_utils::connection_context_base connection_context; - wallet_rpc_server(wallet2& cr); + wallet_rpc_server(std::shared_ptr wptr); const static command_line::arg_descriptor arg_rpc_bind_port; const static command_line::arg_descriptor arg_rpc_bind_ip; @@ -136,7 +136,7 @@ namespace tools bool handle_command_line(const boost::program_options::variables_map& vm); private: - wallet2* m_pwallet; + std::weak_ptr m_pwallet; std::string m_port; std::string m_bind_ip; bool m_do_mint; From dcf1b0adae95a0f92eae728f61e334e6eefdd016 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 3 Apr 2023 20:32:18 +0200 Subject: [PATCH 21/34] basic crypto functions exported from wallet --- src/wallet/wallet2.cpp | 29 +++++++++++++++++++++++++++++ src/wallet/wallet2.h | 7 +++++++ 2 files changed, 36 insertions(+) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index f6429fde..59930bf4 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5081,6 +5081,35 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat return true; } //---------------------------------------------------------------------------------------------------- + +// Signing and auth +bool wallet2::sign_buffer(const std::string& buff, crypto::signature& sig) +{ + crypto::hash h = crypto::cn_fast_hash(buff.data(), buff.size()); + crypto::generate_signature(h, m_account.get_public_address().spend_public_key, m_account.get_keys().spend_secret_key, sig); + return true; +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::validate_sign(const std::string& buff, const crypto::signature& sig, const crypto::public_key& pkey) +{ + crypto::hash h = crypto::cn_fast_hash(buff.data(), buff.size()); + return crypto::check_signature(h, sig, pkey); +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::encrypt_buffer(const std::string& buff, std::string& res_buff) +{ + res_buff = buff; + crypto::chacha_crypt(res_buff, m_account.get_keys().view_secret_key); + return true; +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::decrypt_buffer(const std::string& buff, std::string& res_buff) +{ + res_buff = buff; + crypto::chacha_crypt(res_buff, m_account.get_keys().view_secret_key); + return true; +} +//---------------------------------------------------------------------------------------------------- bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake_outputs_count, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money) { prepare_free_transfers_cache(fake_outputs_count); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 5fdd93f4..430d66de 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -937,6 +937,13 @@ namespace tools bool get_ionic_swap_proposal_info(const currency::transaction tx, view::ionic_swap_proposal_info& proposal); bool accept_ionic_swap_proposal(const std::string&raw_tx_template, currency::transaction& result_tx); bool accept_ionic_swap_proposal(const currency::transaction& tx_template, currency::transaction& result_tx); + + // Signing and auth + bool sign_buffer(const std::string& buff, crypto::signature& sig); + bool validate_sign(const std::string& buff, const crypto::signature& sig, const crypto::public_key& pkey); + bool encrypt_buffer(const std::string& buff, std::string& res_buff); + bool decrypt_buffer(const std::string& buff, std::string& res_buff); + private: // -------- t_transport_state_notifier ------------------------------------------------ From fed1df53f03af04b584816c0850e388cd6497fe6 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 5 Apr 2023 19:05:45 +0200 Subject: [PATCH 22/34] Implementd rpc for crypto api --- src/wallet/wallet_public_structs_defs.h | 89 +++++++++++++++++++++++++ src/wallet/wallet_rpc_server.cpp | 40 ++++++++++- src/wallet/wallet_rpc_server.h | 17 ++++- 3 files changed, 142 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index fb3a0d6a..3c7467bb 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1318,6 +1318,95 @@ namespace wallet_public }; }; + struct COMMAND_SIGN_MESSAGE + { + struct request + { + std::string buff; //base64 encoded data + + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(buff) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + crypto::signature sig; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(sig) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_VALIDATE_SIGNATURE + { + struct request + { + std::string buff; //base64 encoded data + crypto::signature sig; + crypto::public_key pkey; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(buff) + KV_SERIALIZE_POD_AS_HEX_STRING(sig) + KV_SERIALIZE_POD_AS_HEX_STRING(pkey) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_ENCRYPT_DATA + { + struct request + { + std::string buff; //base64 encoded data + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(buff) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + std::string res_buff; //base64 encoded encrypted data + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(res_buff) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_DECRYPT_DATA + { + struct request + { + std::string buff; //base64 encoded encrypted data + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(buff) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + std::string res_buff; //base64 encoded data + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(res_buff) + END_KV_SERIALIZE_MAP() + }; + }; + struct assets_whitelist { diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index cf2b2d2a..1bc0011d 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -1030,9 +1030,45 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::reset_active_wallet(wallet2& w) + bool on_sign_message(const wallet_public::COMMAND_SIGN_MESSAGE& req, wallet_public::COMMAND_SIGN_MESSAGE::response& res, epee::json_rpc::error& er, connection_context& cntx) { - m_pwallet = &w; + std::string buff = epee::string_encoding::base64_decode(req.buff); + get_wallet()->sign_buffer(buff, res.sig); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool on_validate_signature(const wallet_public::COMMAND_VALIDATE_SIGNATURE& req, wallet_public::COMMAND_VALIDATE_SIGNATURE::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + std::string buff = epee::string_encoding::base64_decode(req.buff); + bool r = get_wallet()->validate_sign(buff, req.sig, req.pkey); + if (!r) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; + er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT"; + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool on_encrypt_data(const wallet_public::COMMAND_ENCRYPT_DATA& req, wallet_public::COMMAND_ENCRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + std::string buff = epee::string_encoding::base64_decode(req.buff); + bool r = get_wallet()->encrypt_buffer(buff, res.res_buff); + res.res_buff = epee::string_encoding::base64_encode(res.res_buff); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool on_decrypt_data(const wallet_public::COMMAND_DECRYPT_DATA& req, wallet_public::COMMAND_DECRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + std::string buff = epee::string_encoding::base64_decode(req.buff); + bool r = get_wallet()->encrypt_buffer(buff, res.res_buff); + res.res_buff = epee::string_encoding::base64_encode(res.res_buff); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::reset_active_wallet(std::shared_ptr w) + { + m_pwallet = w; return true; } //------------------------------------------------------------------------------------------------------------------------------ diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index e04b0d47..8d853e2d 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -82,6 +82,11 @@ namespace tools MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, wallet_public::COMMAND_MW_GET_WALLETS) MAP_JON_RPC_WE("mw_select_wallet", on_mw_select_wallet, wallet_public::COMMAND_MW_SELECT_WALLET) + //basic crypto operations + MAP_JON_RPC_WE("sign_message", on_sign_message, wallet_public::COMMAND_SIGN_MESSAGE) + MAP_JON_RPC_WE("validate_signature", on_validate_signature, wallet_public::COMMAND_VALIDATE_SIGNATURE) + MAP_JON_RPC_WE("encrypt_data", on_encrypt_data, wallet_public::COMMAND_ENCRYPT_DATA) + MAP_JON_RPC_WE("decrypt_data", on_decrypt_data, wallet_public::COMMAND_DECRYPT_DATA) END_JSON_RPC_MAP() END_URI_MAP2() @@ -129,9 +134,17 @@ namespace tools bool on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx); + + bool on_sign_message(const wallet_public::COMMAND_SIGN_MESSAGE& req, wallet_public::COMMAND_SIGN_MESSAGE::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_validate_signature(const wallet_public::COMMAND_VALIDATE_SIGNATURE& req, wallet_public::COMMAND_VALIDATE_SIGNATURE::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_encrypt_data(const wallet_public::COMMAND_ENCRYPT_DATA& req, wallet_public::COMMAND_ENCRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_decrypt_data(const wallet_public::COMMAND_DECRYPT_DATA& req, wallet_public::COMMAND_DECRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx); + + + + std::shared_ptr get_wallet(); - - bool reset_active_wallet(wallet2& w); + bool reset_active_wallet(std::shared_ptr w); bool handle_command_line(const boost::program_options::variables_map& vm); From 3b7e0380644b509fb5f4b94d42909281947c64e4 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 7 Apr 2023 22:53:50 +0200 Subject: [PATCH 23/34] fixed multiple compilation problems --- src/simplewallet/simplewallet.cpp | 20 +++++---- src/simplewallet/simplewallet.h | 2 +- src/wallet/view_iface.h | 49 +++------------------- src/wallet/wallet2.cpp | 36 ++++++++-------- src/wallet/wallet2.h | 12 +++--- src/wallet/wallet_id_adapter.h | 14 +++++++ src/wallet/wallet_public_structs_defs.h | 56 ++++++++++++++++++++++--- src/wallet/wallet_rpc_server.cpp | 26 ++++++------ src/wallet/wallet_rpc_server.h | 24 +++++------ src/wallet/wallets_manager.cpp | 22 +++++----- src/wallet/wallets_manager.h | 7 ++-- 11 files changed, 146 insertions(+), 122 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index ec4b5b5d..6295b7d1 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -4,6 +4,10 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include +#if defined(WIN32) + #include +#endif #include #include #include @@ -22,11 +26,10 @@ #include "string_coding.h" #include "wallet/wrap_service.h" #include "common/general_purpose_commands_defs.h" -#include -#if defined(WIN32) -#include -#endif +#include "wallet/wallet_helpers.h" + + using namespace std; using namespace epee; @@ -695,7 +698,7 @@ void simple_wallet::on_tor_status_change(const std::string& state) message_writer(epee::log_space::console_color_yellow, true, std::string("[TOR]: ")) << human_message; } //---------------------------------------------------------------------------------------------------- -void simple_wallet::on_mw_get_wallets(std::vector& wallets) +void simple_wallet::on_mw_get_wallets(std::vector& wallets) { wallets.resize(1); tools::get_wallet_info(*m_wallet, wallets[0].wi); @@ -1893,7 +1896,7 @@ bool simple_wallet::generate_ionic_swap_proposal(const std::vector } transaction tx_template = AUTO_VAL_INIT(tx_template); - bool r = m_wallet->create_ionic_swap_proposal(proposal, destination_addr, tx_template); + r = m_wallet->create_ionic_swap_proposal(proposal, destination_addr, tx_template); if (!r) { fail_msg_writer() << "Failed to create ionic_swap proposal"; @@ -2352,7 +2355,8 @@ int main(int argc, char* argv[]) if (daemon_address.empty()) daemon_address = std::string("http://") + daemon_host + ":" + std::to_string(daemon_port); - tools::wallet2 wal; + std::shared_ptr wallet_ptr(new tools::wallet2()); + tools::wallet2& wal = *wallet_ptr; //try to open it while (true) { @@ -2408,7 +2412,7 @@ int main(int argc, char* argv[]) } } - tools::wallet_rpc_server wrpc(wal); + tools::wallet_rpc_server wrpc(wallet_ptr); bool r = wrpc.init(vm); CHECK_AND_ASSERT_MES(r, EXIT_FAILURE, "Failed to initialize wallet rpc server"); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index e6924ca3..01d637e4 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -111,7 +111,7 @@ namespace currency virtual void on_message(i_wallet2_callback::message_severity severity, const std::string& m) override; virtual void on_tor_status_change(const std::string& state) override; - virtual void on_mw_get_wallets(std::vector& wallets) override; + virtual void on_mw_get_wallets(std::vector& wallets) override; virtual bool on_mw_select_wallet(uint64_t wallet_id) override; //---------------------------------------------------------- diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index caf4bad7..faa7b341 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -209,9 +209,9 @@ public: END_KV_SERIALIZE_MAP() }; - typedef wallet_public::wallet_info wallet_info; + typedef tools::wallet_public::wallet_info wallet_info; - typedef wallet_public::wallet_entry_info wallet_entry_info; + typedef tools::wallet_public::wallet_entry_info wallet_entry_info; @@ -709,48 +709,9 @@ public: }; - struct asset_funds - { - crypto::public_key asset_id; - uint64_t amount; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(asset_id) - KV_SERIALIZE(amount) - END_KV_SERIALIZE_MAP() - }; - - struct ionic_swap_proposal_info - { - std::vector from; - std::vector to; - uint64_t mixins; - uint64_t fee; - uint64_t expiration_time; - - BEGIN_KV_SERIALIZE_MAP() - - KV_SERIALIZE(from) - KV_SERIALIZE(to) - KV_SERIALIZE(mixins) - KV_SERIALIZE(fee) - KV_SERIALIZE(expiration_time) - END_KV_SERIALIZE_MAP() - }; - - struct create_ionic_swap_proposal_request - { - uint64_t wallet_id; - ionic_swap_proposal_info proposal; - std::string destination_add; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(wallet_id) - KV_SERIALIZE(proposal) - KV_SERIALIZE(destination_add) - END_KV_SERIALIZE_MAP() - }; - + typedef tools::wallet_public::asset_funds asset_funds; + typedef tools::wallet_public::ionic_swap_proposal_info ionic_swap_proposal_info; + typedef tools::wallet_public::create_ionic_swap_proposal_request create_ionic_swap_proposal_request; struct address_validation_response { diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 59930bf4..b8ac7abb 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4880,7 +4880,7 @@ bool wallet2::check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& o return false; } //---------------------------------------------------------------------------------------------------- -bool wallet2::create_ionic_swap_proposal(const view::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr, transaction& tx_template) +bool wallet2::create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr, currency::transaction& tx_template) { crypto::secret_key one_time_key = AUTO_VAL_INIT(one_time_key); std::vector selected_transfers_for_template; @@ -4892,7 +4892,7 @@ bool wallet2::create_ionic_swap_proposal(const view::ionic_swap_proposal_info& p return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::build_ionic_swap_template(const view::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, +bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, currency::transaction& template_tx, std::vector& selected_transfers, crypto::secret_key& one_time_key) @@ -4939,7 +4939,7 @@ bool wallet2::build_ionic_swap_template(const view::ionic_swap_proposal_info& pr return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::get_ionic_swap_proposal_info(const std::string&raw_tx_template, view::ionic_swap_proposal_info& proposal) +bool wallet2::get_ionic_swap_proposal_info(const std::string&raw_tx_template, wallet_public::ionic_swap_proposal_info& proposal) { currency::transaction tx; bool r = parse_and_validate_tx_from_blob(raw_tx_template, tx); @@ -4947,16 +4947,16 @@ bool wallet2::get_ionic_swap_proposal_info(const std::string&raw_tx_template, vi return get_ionic_swap_proposal_info(tx, proposal); } //---------------------------------------------------------------------------------------------------- -bool wallet2::get_ionic_swap_proposal_info(const currency::transaction tx, view::ionic_swap_proposal_info& proposal) +bool wallet2::get_ionic_swap_proposal_info(const currency::transaction tx, wallet_public::ionic_swap_proposal_info& proposal) { crypto::key_derivation derivation = AUTO_VAL_INIT(derivation); std::vector outs; uint64_t tx_money_got_in_outs = 0; - r = lookup_acc_outs(m_account.get_keys(), tx, outs, tx_money_got_in_outs, derivation); + bool r = lookup_acc_outs(m_account.get_keys(), tx, outs, tx_money_got_in_outs, derivation); THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "Failed to lookup_acc_outs for tx: " << get_transaction_hash(tx)); - std::unordered_map ammounts_to; - std::unordered_map ammounts_from; + std::unordered_map ammounts_to; + std::unordered_map ammounts_from; std::vector third_party_outs; size_t i = 0; for (const auto& o : outs) @@ -4971,7 +4971,7 @@ bool wallet2::get_ionic_swap_proposal_info(const currency::transaction tx, view: if (!third_party_outs[i]) continue; - crypto::public_key asset_id = AUTO_VAL_INIT(asset_id); + crypto::hash asset_id = AUTO_VAL_INIT(asset_id); uint64_t amount = 0; //TODO decode output info //get_amout_and_asset_id() @@ -5022,10 +5022,10 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat msc.tx_for_mode_separate = tx_template; - r = get_ionic_swap_proposal_info(tx, msc.proposal); + bool r = get_ionic_swap_proposal_info(tx_template, msc.proposal); THROW_IF_TRUE_WALLET_EX(!r, error::wallet_internal_error, "Failed to get info from proposal"); - std::unordered_map balances; + std::unordered_map balances; uint64_t mined = 0; this->balance(balances, mined); //validate balances needed @@ -5036,7 +5036,7 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat { return false; } - if (item.asset_id == currency::null_pkey) + if (item.asset_id == currency::null_hash) { native_amount_required = item.amount; } @@ -5047,7 +5047,7 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat if (msc.proposal.fee < m_core_runtime_config.tx_default_fee) { additional_fee = m_core_runtime_config.tx_default_fee - msc.proposal.fee; - if (balances[currency::null_pkey].unlocked < additional_fee + native_amount_required) + if (balances[currency::null_hash].unlocked < additional_fee + native_amount_required) { return false; } @@ -5057,7 +5057,8 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat construct_tx_param construct_param = get_default_construct_tx_param(); construct_param.fee = additional_fee; - //crypto::secret_key one_time_key = contr_it->second.proposal.tx_onetime_secret_key; + + assert(0); crypto::secret_key one_time_key = currency::null_skey; //TODO: add transfer of secrete onetime key to proposal construct_param.crypt_address = m_account.get_public_address(); construct_param.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; construct_param.mark_tx_as_complete = true; @@ -5066,17 +5067,18 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); ftp.tx_version = this->get_current_tx_version(); prepare_transaction(construct_param, ftp, msc); - mark_transfers_as_spent(ftp.selected_transfers, std::string("contract <") + epee::string_tools::pod_to_hex(contract_id) + "> has been accepted with tx <" + epee::string_tools::pod_to_hex(get_transaction_hash(tx)) + ">"); try { - finalize_transaction(ftp, tx, one_time_key, true); + finalize_transaction(ftp, result_tx, one_time_key, true); } catch (...) { - clear_transfers_from_flag(ftp.selected_transfers, WALLET_TRANSFER_DETAIL_FLAG_SPENT, std::string("exception in finalize_transaction, tx: ") + epee::string_tools::pod_to_hex(get_transaction_hash(tx))); + clear_transfers_from_flag(ftp.selected_transfers, WALLET_TRANSFER_DETAIL_FLAG_SPENT, std::string("exception in finalize_transaction, tx: ") + epee::string_tools::pod_to_hex(get_transaction_hash(result_tx))); throw; } + mark_transfers_as_spent(ftp.selected_transfers, std::string("Proposal has been accepted with tx <" + epee::string_tools::pod_to_hex(get_transaction_hash(result_tx))) + ">"); + return true; } @@ -5093,7 +5095,7 @@ bool wallet2::sign_buffer(const std::string& buff, crypto::signature& sig) bool wallet2::validate_sign(const std::string& buff, const crypto::signature& sig, const crypto::public_key& pkey) { crypto::hash h = crypto::cn_fast_hash(buff.data(), buff.size()); - return crypto::check_signature(h, sig, pkey); + return crypto::check_signature(h, pkey, sig); } //---------------------------------------------------------------------------------------------------- bool wallet2::encrypt_buffer(const std::string& buff, std::string& res_buff) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 430d66de..5b9ac8c6 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -129,7 +129,7 @@ namespace tools //mw api virtual void on_mw_get_wallets(std::vector& wallets) {} - virtual bool on_mw_select_wallet(uint64_t wallet_id) {} + virtual bool on_mw_select_wallet(uint64_t wallet_id) { return true; } }; struct tx_dust_policy @@ -550,7 +550,7 @@ namespace tools //i_wallet2_callback* callback() const { return m_wcallback; } //void callback(i_wallet2_callback* callback) { m_callback = callback; } void callback(std::shared_ptr callback) { m_wcallback = callback; m_do_rise_transfer = (callback != nullptr); } - i_wallet2_callback* get_callback() { return m_wcallback; } + i_wallet2_callback* get_callback() { return m_wcallback.get(); } void set_do_rise_transfer(bool do_rise) { m_do_rise_transfer = do_rise; } bool has_related_alias_entry_unconfirmed(const currency::transaction& tx); @@ -928,13 +928,13 @@ namespace tools bool check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id); // ionic swaps: - bool create_ionic_swap_proposal(const view::ionic_swap_proposal_info& proposal, const currency::account_public_address& destination_addr, transaction& tx_template); - bool build_ionic_swap_template(const view::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, + bool create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal, const currency::account_public_address& destination_addr, currency::transaction& tx_template); + bool build_ionic_swap_template(const wallet_public::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, currency::transaction& template_tx, std::vector& selected_transfers_for_template, crypto::secret_key& one_time_key); - bool get_ionic_swap_proposal_info(const std::string&raw_tx_template, view::ionic_swap_proposal_info& proposal); - bool get_ionic_swap_proposal_info(const currency::transaction tx, view::ionic_swap_proposal_info& proposal); + bool get_ionic_swap_proposal_info(const std::string&raw_tx_template, wallet_public::ionic_swap_proposal_info& proposal); + bool get_ionic_swap_proposal_info(const currency::transaction tx, wallet_public::ionic_swap_proposal_info& proposal); bool accept_ionic_swap_proposal(const std::string&raw_tx_template, currency::transaction& result_tx); bool accept_ionic_swap_proposal(const currency::transaction& tx_template, currency::transaction& result_tx); diff --git a/src/wallet/wallet_id_adapter.h b/src/wallet/wallet_id_adapter.h index 4a4b0a8c..e31e2fab 100644 --- a/src/wallet/wallet_id_adapter.h +++ b/src/wallet/wallet_id_adapter.h @@ -17,6 +17,10 @@ public: virtual void on_sync_progress(size_t wallet_id, const uint64_t& /*percents*/) {} virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti) {} virtual void on_tor_status_change(size_t wallet_id, const std::string& state) {} + + virtual void on_mw_get_wallets(std::vector& wallets) {} + virtual bool on_mw_select_wallet(uint64_t wallet_id) { return true; } + }; struct i_wallet_to_i_backend_adapter: public tools::i_wallet2_callback @@ -45,6 +49,16 @@ struct i_wallet_to_i_backend_adapter: public tools::i_wallet2_callback m_pbackend->on_tor_status_change(m_wallet_id, state); } + virtual void on_mw_get_wallets(std::vector& wallets) + { + m_pbackend->on_mw_get_wallets(wallets); + } + virtual bool on_mw_select_wallet(uint64_t wallet_id) + { + return m_pbackend->on_mw_select_wallet(wallet_id); + } + + private: i_backend_wallet_callback* m_pbackend; size_t m_wallet_id; diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 3c7467bb..c1b03fd4 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1178,11 +1178,56 @@ namespace wallet_public }; }; + + + struct asset_funds + { + crypto::hash asset_id; + uint64_t amount; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(asset_id) + KV_SERIALIZE(amount) + END_KV_SERIALIZE_MAP() + }; + + struct ionic_swap_proposal_info + { + std::vector from; + std::vector to; + uint64_t mixins; + uint64_t fee; + uint64_t expiration_time; + + BEGIN_KV_SERIALIZE_MAP() + + KV_SERIALIZE(from) + KV_SERIALIZE(to) + KV_SERIALIZE(mixins) + KV_SERIALIZE(fee) + KV_SERIALIZE(expiration_time) + END_KV_SERIALIZE_MAP() + }; + + struct create_ionic_swap_proposal_request + { + uint64_t wallet_id; + ionic_swap_proposal_info proposal; + std::string destination_add; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(wallet_id) + KV_SERIALIZE(proposal) + KV_SERIALIZE(destination_add) + END_KV_SERIALIZE_MAP() + }; + + struct COMMAND_IONIC_SWAP_GENERATE_PROPOSAL { struct request { - view::ionic_swap_proposal_info proposal; + ionic_swap_proposal_info proposal; std::string destination_address; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(proposal) @@ -1215,7 +1260,7 @@ namespace wallet_public struct response { - view::ionic_swap_proposal_info proposal; + ionic_swap_proposal_info proposal; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(proposal) @@ -1291,7 +1336,7 @@ namespace wallet_public struct response { - std::vector wallets; + std::vector wallets; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(wallets) @@ -1373,11 +1418,10 @@ namespace wallet_public BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(buff) END_KV_SERIALIZE_MAP() - }; - + }; struct response - { + { std::string res_buff; //base64 encoded encrypted data BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(res_buff) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 1bc0011d..57121b3e 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -56,16 +56,16 @@ namespace tools command_line::add_arg(desc, arg_deaf_mode); } //------------------------------------------------------------------------------------------------------------------------------ - wallet_rpc_server::wallet_rpc_server(std::shared_ptr wptr) + wallet_rpc_server::wallet_rpc_server(std::shared_ptr wptr) : m_pwallet(wptr) , m_do_mint(false) , m_deaf(false) , m_last_wallet_store_height(0) {} //------------------------------------------------------------------------------------------------------------------------------ - std::shared_ptr wallet_rpc_server::get_wallet() + std::shared_ptr wallet_rpc_server::get_wallet() { - return std::shared_ptr(m_pwallet); + return std::shared_ptr(m_pwallet); } //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::run(bool do_mint, bool offline_mode, const currency::account_public_address& miner_address) @@ -931,7 +931,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_ionic_swap_generate_proposal(const wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx) + bool wallet_rpc_server::on_ionic_swap_generate_proposal(const wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::request& req, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx) { currency::account_public_address destination_addr = AUTO_VAL_INIT(destination_addr); currency::payment_id_t integrated_payment_id; @@ -960,7 +960,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_ionic_swap_get_proposal_info(const wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO& req, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx) + bool wallet_rpc_server::on_ionic_swap_get_proposal_info(const wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::request& req, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx) { std::string raw_tx_template; bool r = epee::string_tools::parse_hexstr_to_binbuff(req.hex_raw_proposal, raw_tx_template); @@ -980,7 +980,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_ionic_swap_accept_proposal(const wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx) + bool wallet_rpc_server::on_ionic_swap_accept_proposal(const wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::request& req, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx) { std::string raw_tx_template; @@ -1004,7 +1004,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx) + bool wallet_rpc_server::on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS::request& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx) { i_wallet2_callback* pcallback = get_wallet()->get_callback(); if (!pcallback) @@ -1017,7 +1017,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx) + bool wallet_rpc_server::on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET::request& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx) { i_wallet2_callback* pcallback = get_wallet()->get_callback(); if (!pcallback) @@ -1030,14 +1030,14 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool on_sign_message(const wallet_public::COMMAND_SIGN_MESSAGE& req, wallet_public::COMMAND_SIGN_MESSAGE::response& res, epee::json_rpc::error& er, connection_context& cntx) + bool wallet_rpc_server::on_sign_message(const wallet_public::COMMAND_SIGN_MESSAGE::request& req, wallet_public::COMMAND_SIGN_MESSAGE::response& res, epee::json_rpc::error& er, connection_context& cntx) { std::string buff = epee::string_encoding::base64_decode(req.buff); get_wallet()->sign_buffer(buff, res.sig); return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool on_validate_signature(const wallet_public::COMMAND_VALIDATE_SIGNATURE& req, wallet_public::COMMAND_VALIDATE_SIGNATURE::response& res, epee::json_rpc::error& er, connection_context& cntx) + bool wallet_rpc_server::on_validate_signature(const wallet_public::COMMAND_VALIDATE_SIGNATURE::request& req, wallet_public::COMMAND_VALIDATE_SIGNATURE::response& res, epee::json_rpc::error& er, connection_context& cntx) { std::string buff = epee::string_encoding::base64_decode(req.buff); bool r = get_wallet()->validate_sign(buff, req.sig, req.pkey); @@ -1050,7 +1050,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool on_encrypt_data(const wallet_public::COMMAND_ENCRYPT_DATA& req, wallet_public::COMMAND_ENCRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx) + bool wallet_rpc_server::on_encrypt_data(const wallet_public::COMMAND_ENCRYPT_DATA::request& req, wallet_public::COMMAND_ENCRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx) { std::string buff = epee::string_encoding::base64_decode(req.buff); bool r = get_wallet()->encrypt_buffer(buff, res.res_buff); @@ -1058,7 +1058,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool on_decrypt_data(const wallet_public::COMMAND_DECRYPT_DATA& req, wallet_public::COMMAND_DECRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx) + bool wallet_rpc_server::on_decrypt_data(const wallet_public::COMMAND_DECRYPT_DATA::request& req, wallet_public::COMMAND_DECRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx) { std::string buff = epee::string_encoding::base64_decode(req.buff); bool r = get_wallet()->encrypt_buffer(buff, res.res_buff); @@ -1066,7 +1066,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::reset_active_wallet(std::shared_ptr w) + bool wallet_rpc_server::reset_active_wallet(std::shared_ptr w) { m_pwallet = w; return true; diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 8d853e2d..b72c93de 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -22,7 +22,7 @@ namespace tools public: typedef epee::net_utils::connection_context_base connection_context; - wallet_rpc_server(std::shared_ptr wptr); + wallet_rpc_server(std::shared_ptr wptr); const static command_line::arg_descriptor arg_rpc_bind_port; const static command_line::arg_descriptor arg_rpc_bind_ip; @@ -128,23 +128,23 @@ namespace tools bool on_redeem_htlc(const wallet_public::COMMAND_REDEEM_HTLC::request& req, wallet_public::COMMAND_REDEEM_HTLC::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_check_htlc_redeemed(const wallet_public::COMMAND_CHECK_HTLC_REDEEMED::request& req, wallet_public::COMMAND_CHECK_HTLC_REDEEMED::response& res, epee::json_rpc::error& er, connection_context& cntx); - bool on_ionic_swap_generate_proposal(const wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx); - bool on_ionic_swap_get_proposal_info(const wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO& req, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx); - bool on_ionic_swap_accept_proposal(const wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL& req, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_ionic_swap_generate_proposal(const wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::request& req, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_ionic_swap_get_proposal_info(const wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::request& req, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_ionic_swap_accept_proposal(const wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::request& req, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx); - bool on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx); - bool on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS::request& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET::request& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx); - bool on_sign_message(const wallet_public::COMMAND_SIGN_MESSAGE& req, wallet_public::COMMAND_SIGN_MESSAGE::response& res, epee::json_rpc::error& er, connection_context& cntx); - bool on_validate_signature(const wallet_public::COMMAND_VALIDATE_SIGNATURE& req, wallet_public::COMMAND_VALIDATE_SIGNATURE::response& res, epee::json_rpc::error& er, connection_context& cntx); - bool on_encrypt_data(const wallet_public::COMMAND_ENCRYPT_DATA& req, wallet_public::COMMAND_ENCRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx); - bool on_decrypt_data(const wallet_public::COMMAND_DECRYPT_DATA& req, wallet_public::COMMAND_DECRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_sign_message(const wallet_public::COMMAND_SIGN_MESSAGE::request& req, wallet_public::COMMAND_SIGN_MESSAGE::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_validate_signature(const wallet_public::COMMAND_VALIDATE_SIGNATURE::request& req, wallet_public::COMMAND_VALIDATE_SIGNATURE::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_encrypt_data(const wallet_public::COMMAND_ENCRYPT_DATA::request& req, wallet_public::COMMAND_ENCRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_decrypt_data(const wallet_public::COMMAND_DECRYPT_DATA::request& req, wallet_public::COMMAND_DECRYPT_DATA::response& res, epee::json_rpc::error& er, connection_context& cntx); - std::shared_ptr get_wallet(); + std::shared_ptr get_wallet(); - bool reset_active_wallet(std::shared_ptr w); + bool reset_active_wallet(std::shared_ptr w); bool handle_command_line(const boost::program_options::variables_map& vm); diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index de0e07f8..d53f89a5 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -780,7 +780,7 @@ void wallets_manager::init_wallet_entry(wallet_vs_options& wo, uint64_t id) wo.m_pproxy_diagnostig_info = m_rpc_proxy->get_proxy_diagnostic_info(); wo.pview = m_pview; wo.has_related_alias_in_unconfirmed = false; - wo.rpc_wrapper.reset(new tools::wallet_rpc_server(*wo.w.unlocked_get().get())); + wo.rpc_wrapper.reset(new tools::wallet_rpc_server(wo.w.unlocked_get())); if (m_remote_node_mode) wo.core_conf = currency::get_default_core_runtime_config(); else @@ -854,23 +854,24 @@ std::string wallets_manager::get_fav_offers(const std::listget()->create_ionic_swap_proposal(proposal, dest_account); + currency::transaction tx_template = AUTO_VAL_INIT(tx_template); + bool r = wo.w->get()->create_ionic_swap_proposal(proposal.proposal, dest_account, tx_template); if (!r) { return API_RETURN_CODE_FAIL; } else { + result_proposal_hex = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(tx_template)); return API_RETURN_CODE_OK; } } @@ -879,11 +880,9 @@ std::string wallets_manager::create_ionic_swap_proposal(uint64_t wallet_id, cons return API_RETURN_CODE_FAIL; } return API_RETURN_CODE_OK; - - return true; } -std::string get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_template_hex, ionic_swap_proposal_info& proposal) +std::string wallets_manager::get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_template_hex, tools::wallet_public::ionic_swap_proposal_info& proposal) { GET_WALLET_OPT_BY_ID(wallet_id, wo); try { @@ -906,7 +905,7 @@ std::string get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_ return API_RETURN_CODE_OK; } -std::string wallets_manager::accept_ionic_swap_proposal(uint64_t wallet_id, std::string&raw_tx_template, currency::transaction& result_tx) +std::string wallets_manager::accept_ionic_swap_proposal(uint64_t wallet_id, std::string&raw_tx_template_hex, currency::transaction& result_tx) { GET_WALLET_OPT_BY_ID(wallet_id, wo); try { @@ -2002,7 +2001,7 @@ void wallets_manager::on_tor_status_change(size_t wallet_id, const std::string& m_pview->update_tor_status(tsu); } -void wallets_manager::on_mw_get_wallets(std::vector& wallets) +void wallets_manager::on_mw_get_wallets(std::vector& wallets) { std::list opened_wallets; this->get_opened_wallets(opened_wallets); @@ -2022,7 +2021,8 @@ bool wallets_manager::on_mw_select_wallet(uint64_t wallet_id) if (it == m_wallets.end()) return false; auto& wo = it->second; - m_wallet_rpc_server.reset_active_wallet(wo.w); + //m_wallet_rpc_server.reset_active_wallet(wo.w); + return false; } diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index ba73f431..1b4df43a 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -136,8 +136,8 @@ public: std::string backup_wallet(uint64_t wallet_id, const std::wstring& path); std::string reset_wallet_password(uint64_t wallet_id, const std::string& pass); std::string is_wallet_password_valid(uint64_t wallet_id, const std::string& pass); - std::string create_ionic_swap_proposal(uint64_t wallet_id, const view::create_ionic_swap_proposal_request& proposal, std::string& result_proposal_hex); - std::string get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_template_hex, ionic_swap_proposal_info& proposal); + std::string create_ionic_swap_proposal(uint64_t wallet_id, const tools::wallet_public::create_ionic_swap_proposal_request& proposal, std::string& result_proposal_hex); + std::string get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_template_hex, tools::wallet_public::ionic_swap_proposal_info& proposal); std::string accept_ionic_swap_proposal(uint64_t wallet_id, std::string&raw_tx_template_hex, currency::transaction& result_tx); std::string get_my_offers(const bc_services::core_offers_filter& filter, std::list& offers); std::string get_fav_offers(const std::list& hashes, const bc_services::core_offers_filter& filter, std::list& offers); @@ -193,7 +193,7 @@ private: virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti); virtual void on_tor_status_change(size_t wallet_id, const std::string& state); - virtual void on_mw_get_wallets(std::vector& wallets) override; + virtual void on_mw_get_wallets(std::vector& wallets) override; virtual bool on_mw_select_wallet(uint64_t wallet_id) override; //-------- @@ -228,7 +228,6 @@ private: currency::t_currency_protocol_handler m_cprotocol; nodetool::node_server > m_p2psrv; currency::core_rpc_server m_rpc_server; - tools::wallet_rpc_server m_wallet_rpc_server; //optional initialization #endif bool m_remote_node_mode; From 03f443cf4c8b53cbf07bdd5c1b9cb9ec57e987b6 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 11 Apr 2023 17:23:06 +0200 Subject: [PATCH 24/34] Fixed few complilation issues --- src/gui/qt-daemon/application/mainwindow.cpp | 12 ++++++------ src/wallet/view_iface.h | 2 +- src/wallet/wallet2.cpp | 12 ++++++------ src/wallet/wallet_public_structs_defs.h | 4 ++-- src/wallet/wallets_manager.cpp | 5 +++-- src/wallet/wallets_manager.h | 2 +- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index 03261af2..b61b4cce 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -2162,35 +2162,35 @@ QString MainWindow::get_wallet_info(const QString& param) return MAKE_RESPONSE(ar); CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString create_ionic_swap_proposal(const QString& param) +QString MainWindow::create_ionic_swap_proposal(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); PREPARE_ARG_FROM_JSON(view::create_ionic_swap_proposal_request, cispr); - PREPARE_RESPONSE(view::api_response_t, ar); + PREPARE_RESPONSE(std::string, ar); ar.error_code = m_backend.create_ionic_swap_proposal(cispr.wallet_id, cispr, ar.response_data); return MAKE_RESPONSE(ar); CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString get_ionic_swap_proposal_info(const QString& param) +QString MainWindow::get_ionic_swap_proposal_info(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); PREPARE_ARG_FROM_JSON(view::api_request_t, tx_raw_hex); - PREPARE_RESPONSE(view::api_response_t, ar); + PREPARE_RESPONSE(tools::wallet_public::ionic_swap_proposal_info, ar); ar.error_code = m_backend.get_ionic_swap_proposal_info(tx_raw_hex.wallet_id, tx_raw_hex.req_data, ar.response_data); return MAKE_RESPONSE(ar); CATCH_ENTRY_FAIL_API_RESPONCE(); } -QString accept_ionic_swap_proposal(const QString& param) +QString MainWindow::accept_ionic_swap_proposal(const QString& param) { TRY_ENTRY(); LOG_API_TIMING(); PREPARE_ARG_FROM_JSON(view::api_request_t, tx_raw_hex); - PREPARE_RESPONSE(view::api_response_t, ar); + PREPARE_RESPONSE(std::string, ar); ar.error_code = m_backend.accept_ionic_swap_proposal(tx_raw_hex.wallet_id, tx_raw_hex.req_data, ar.response_data); return MAKE_RESPONSE(ar); CATCH_ENTRY_FAIL_API_RESPONCE(); diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index de98cdfe..ebce8c5e 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -409,7 +409,7 @@ public: struct wallet_and_asset_id { uint64_t wallet_id = 0; - crypto::hash asset_id = currency::null_hash; + crypto::public_key asset_id = currency::null_pkey; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(wallet_id) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index dfbf9951..bb6f98bd 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5040,8 +5040,8 @@ bool wallet2::get_ionic_swap_proposal_info(const currency::transaction tx, walle bool r = lookup_acc_outs(m_account.get_keys(), tx, outs, tx_money_got_in_outs, derivation); THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "Failed to lookup_acc_outs for tx: " << get_transaction_hash(tx)); - std::unordered_map ammounts_to; - std::unordered_map ammounts_from; + std::unordered_map ammounts_to; + std::unordered_map ammounts_from; std::vector third_party_outs; size_t i = 0; for (const auto& o : outs) @@ -5060,7 +5060,7 @@ bool wallet2::get_ionic_swap_proposal_info(const currency::transaction tx, walle uint64_t amount = 0; //TODO decode output info //get_amout_and_asset_id() - ammounts_from[asset_id] += amount; + //ammounts_from[asset_id] += amount; } for (const auto& a : ammounts_to) @@ -5110,7 +5110,7 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat bool r = get_ionic_swap_proposal_info(tx_template, msc.proposal); THROW_IF_TRUE_WALLET_EX(!r, error::wallet_internal_error, "Failed to get info from proposal"); - std::unordered_map balances; + std::unordered_map balances; uint64_t mined = 0; this->balance(balances, mined); //validate balances needed @@ -5121,7 +5121,7 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat { return false; } - if (item.asset_id == currency::null_hash) + if (item.asset_id == currency::native_coin_asset_id) { native_amount_required = item.amount; } @@ -5132,7 +5132,7 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat if (msc.proposal.fee < m_core_runtime_config.tx_default_fee) { additional_fee = m_core_runtime_config.tx_default_fee - msc.proposal.fee; - if (balances[currency::null_hash].unlocked < additional_fee + native_amount_required) + if (balances[currency::native_coin_asset_id].unlocked < additional_fee + native_amount_required) { return false; } diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 485c2117..515fe5a4 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1183,11 +1183,11 @@ namespace wallet_public struct asset_funds { - crypto::hash asset_id; + crypto::public_key asset_id; uint64_t amount; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(asset_id) + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) KV_SERIALIZE(amount) END_KV_SERIALIZE_MAP() }; diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 53f20b24..5c2f7f1b 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -927,7 +927,7 @@ std::string wallets_manager::get_ionic_swap_proposal_info(uint64_t wallet_id, st return API_RETURN_CODE_OK; } -std::string wallets_manager::accept_ionic_swap_proposal(uint64_t wallet_id, std::string&raw_tx_template_hex, currency::transaction& result_tx) +std::string wallets_manager::accept_ionic_swap_proposal(uint64_t wallet_id, std::string&raw_tx_template_hex, std::string& result_raw_tx_hex) { GET_WALLET_OPT_BY_ID(wallet_id, wo); try { @@ -937,11 +937,12 @@ std::string wallets_manager::accept_ionic_swap_proposal(uint64_t wallet_id, std: { return API_RETURN_CODE_BAD_ARG; } - + currency::transaction result_tx = AUTO_VAL_INIT(result_tx); if (!wo.w->get()->accept_ionic_swap_proposal(raw_tx_template, result_tx)) { return API_RETURN_CODE_FAIL; } + result_raw_tx_hex = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(result_tx)); } catch (...) { diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index c2fac77f..b9542b2a 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -138,7 +138,7 @@ public: std::string is_wallet_password_valid(uint64_t wallet_id, const std::string& pass); std::string create_ionic_swap_proposal(uint64_t wallet_id, const tools::wallet_public::create_ionic_swap_proposal_request& proposal, std::string& result_proposal_hex); std::string get_ionic_swap_proposal_info(uint64_t wallet_id, std::string&raw_tx_template_hex, tools::wallet_public::ionic_swap_proposal_info& proposal); - std::string accept_ionic_swap_proposal(uint64_t wallet_id, std::string&raw_tx_template_hex, currency::transaction& result_tx); + std::string accept_ionic_swap_proposal(uint64_t wallet_id, std::string&raw_tx_template_hex, std::string& result_raw_tx); std::string get_my_offers(const bc_services::core_offers_filter& filter, std::list& offers); std::string get_fav_offers(const std::list& hashes, const bc_services::core_offers_filter& filter, std::list& offers); std::string get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INFO::response& res); From e30341163b7ecc6c300a97029e344b65e40c59f6 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 13 Apr 2023 20:07:43 +0200 Subject: [PATCH 25/34] Added intermediate information secure transfer between proposal and acceptance --- src/currency_core/currency_format_utils.cpp | 14 ++- src/currency_core/currency_format_utils.h | 3 + .../currency_format_utils_transactions.h | 70 +++++++------- src/wallet/wallet2.cpp | 95 ++++++++++++------- src/wallet/wallet2.h | 15 ++- src/wallet/wallet_public_structs_defs.h | 28 ++++++ src/wallet/wallets_manager.cpp | 6 +- 7 files changed, 146 insertions(+), 85 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 8f6efb01..5503b6ea 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1612,9 +1612,8 @@ namespace currency } //--------------------------------------------------------------- - void encrypt_attachments(transaction& tx, const account_keys& sender_keys, const account_public_address& destination_addr, const keypair& tx_random_key) + void encrypt_attachments(transaction& tx, const account_keys& sender_keys, const account_public_address& destination_addr, const keypair& tx_random_key, crypto::key_derivation& derivation) { - crypto::key_derivation derivation = AUTO_VAL_INIT(derivation); bool r = crypto::generate_key_derivation(destination_addr.view_public_key, tx_random_key.sec, derivation); CHECK_AND_ASSERT_MES(r, void(), "failed to generate_key_derivation"); bool was_attachment_crypted_entries = false; @@ -1645,6 +1644,12 @@ namespace currency } } //--------------------------------------------------------------- + void encrypt_attachments(transaction& tx, const account_keys& sender_keys, const account_public_address& destination_addr, const keypair& tx_random_key) + { + crypto::key_derivation derivation = AUTO_VAL_INIT(derivation); + return encrypt_attachments(tx, sender_keys, destination_addr, tx_random_key, derivation); + } + //--------------------------------------------------------------- void load_wallet_transfer_info_flags(tools::wallet_public::wallet_transfer_info& x) { x.is_service = currency::is_service_tx(x.tx); @@ -2052,7 +2057,7 @@ namespace currency //include offers if need tx.attachment = attachments; - encrypt_attachments(tx, sender_account_keys, crypt_destination_addr, txkey); + encrypt_attachments(tx, sender_account_keys, crypt_destination_addr, txkey, result.derivation); } else { @@ -2061,7 +2066,8 @@ namespace currency CHECK_AND_ASSERT_MES(txkey.pub != null_pkey && txkey.sec != null_skey, false, "In append mode both public and secret keys must be provided"); //separately encrypt attachments without putting extra - crypto::key_derivation derivation = get_encryption_key_derivation(true, tx, sender_account_keys); + result.derivation = get_encryption_key_derivation(true, tx, sender_account_keys); + crypto::key_derivation& derivation = result.derivation; CHECK_AND_ASSERT_MES(derivation != null_derivation, false, "failed to generate_key_derivation"); bool was_attachment_crypted_entries = false; std::vector extra_local = extra; diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 2994ca13..e79a1d50 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -183,6 +183,7 @@ namespace currency finalize_tx_param ftp; std::string htlc_origin; std::vector> outs_key_images; // pairs (out_index, key_image) for each change output + crypto::key_derivation derivation; BEGIN_SERIALIZE_OBJECT() FIELD(tx) @@ -190,6 +191,7 @@ namespace currency FIELD(ftp) FIELD(htlc_origin) FIELD(outs_key_images) + FIELD(derivation) END_SERIALIZE() }; @@ -338,6 +340,7 @@ namespace currency bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t current_blockchain_size, uint64_t current_time); crypto::key_derivation get_encryption_key_derivation(bool is_income, const transaction& tx, const account_keys& acc_keys); bool decrypt_payload_items(bool is_income, const transaction& tx, const account_keys& acc_keys, std::vector& decrypted_items); + void encrypt_attachments(transaction& tx, const account_keys& sender_keys, const account_public_address& destination_addr, const keypair& tx_random_key, crypto::key_derivation& derivation); void encrypt_attachments(transaction& tx, const account_keys& sender_keys, const account_public_address& destination_addr, const keypair& tx_random_key); bool is_derivation_used_to_encrypt(const transaction& tx, const crypto::key_derivation& derivation); bool is_address_like_wrapped(const std::string& addr); diff --git a/src/currency_core/currency_format_utils_transactions.h b/src/currency_core/currency_format_utils_transactions.h index 4b7aeeb7..30cb7589 100644 --- a/src/currency_core/currency_format_utils_transactions.h +++ b/src/currency_core/currency_format_utils_transactions.h @@ -264,44 +264,46 @@ namespace currency // consider redesign, some data may possibly be excluded from kv serialization -- sowle BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(asset_ids); - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(blinded_asset_ids); - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(amount_commitments); - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(asset_id_blinding_masks); - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(amounts); - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(amount_blinding_masks); - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(pseudo_outs_blinded_asset_ids); - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(pseudo_outs_plus_real_out_blinding_masks); - KV_SERIALIZE_CONTAINER_POD_AS_BLOB(real_zc_ins_asset_ids); - KV_SERIALIZE_POD_AS_HEX_STRING(pseudo_out_amount_commitments_sum); - KV_SERIALIZE_POD_AS_HEX_STRING(pseudo_out_amount_blinding_masks_sum); - KV_SERIALIZE_POD_AS_HEX_STRING(real_in_asset_id_blinding_mask_x_amount_sum); - KV_SERIALIZE_POD_AS_HEX_STRING(amount_commitments_sum); - KV_SERIALIZE_POD_AS_HEX_STRING(amount_blinding_masks_sum); - KV_SERIALIZE_POD_AS_HEX_STRING(asset_id_blinding_mask_x_amount_sum); - KV_SERIALIZE_POD_AS_HEX_STRING(ao_asset_id); - KV_SERIALIZE_POD_AS_HEX_STRING(ao_asset_id_pt); - KV_SERIALIZE_POD_AS_HEX_STRING(ao_amount_commitment); - KV_SERIALIZE_POD_AS_HEX_STRING(ao_amount_blinding_mask); + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(asset_ids) + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(blinded_asset_ids) + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(amount_commitments) + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(asset_id_blinding_masks) + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(amounts) + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(amount_blinding_masks) + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(pseudo_outs_blinded_asset_ids) + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(pseudo_outs_plus_real_out_blinding_masks) + KV_SERIALIZE_CONTAINER_POD_AS_BLOB(real_zc_ins_asset_ids) + KV_SERIALIZE_POD_AS_HEX_STRING(pseudo_out_amount_commitments_sum) + KV_SERIALIZE_POD_AS_HEX_STRING(pseudo_out_amount_blinding_masks_sum) + KV_SERIALIZE_POD_AS_HEX_STRING(real_in_asset_id_blinding_mask_x_amount_sum) + KV_SERIALIZE_POD_AS_HEX_STRING(amount_commitments_sum) + KV_SERIALIZE_POD_AS_HEX_STRING(amount_blinding_masks_sum) + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id_blinding_mask_x_amount_sum) + KV_SERIALIZE_POD_AS_HEX_STRING(ao_asset_id) + KV_SERIALIZE_POD_AS_HEX_STRING(ao_asset_id_pt) + KV_SERIALIZE_POD_AS_HEX_STRING(ao_amount_commitment) + KV_SERIALIZE_POD_AS_HEX_STRING(ao_amount_blinding_mask) END_KV_SERIALIZE_MAP() // solely for consolidated txs, asset opration fields are not serialized BEGIN_SERIALIZE_OBJECT() - FIELD(asset_ids); - FIELD(blinded_asset_ids); - FIELD(amount_commitments); - FIELD((std::vector&)(asset_id_blinding_masks)); - FIELD((std::vector&)(amounts)); - FIELD((std::vector&)(amount_blinding_masks)); - FIELD(pseudo_outs_blinded_asset_ids); - FIELD((std::vector&)(pseudo_outs_plus_real_out_blinding_masks)); - FIELD(real_zc_ins_asset_ids); - FIELD(pseudo_out_amount_commitments_sum); - FIELD(pseudo_out_amount_blinding_masks_sum); - FIELD(real_in_asset_id_blinding_mask_x_amount_sum); - FIELD(amount_commitments_sum); - FIELD(amount_blinding_masks_sum); - FIELD(asset_id_blinding_mask_x_amount_sum); + VERSION() + CURRENT_VERSION(0) + FIELD(asset_ids) + FIELD(blinded_asset_ids) + FIELD(amount_commitments) + FIELD((std::vector&)(asset_id_blinding_masks)) + FIELD((std::vector&)(amounts)) + FIELD((std::vector&)(amount_blinding_masks)) + FIELD(pseudo_outs_blinded_asset_ids) + FIELD((std::vector&)(pseudo_outs_plus_real_out_blinding_masks)) + FIELD(real_zc_ins_asset_ids) + FIELD(pseudo_out_amount_commitments_sum) + FIELD(pseudo_out_amount_blinding_masks_sum) + FIELD(real_in_asset_id_blinding_mask_x_amount_sum) + FIELD(amount_commitments_sum) + FIELD(amount_blinding_masks_sum) + FIELD(asset_id_blinding_mask_x_amount_sum) // no asset operation fields here //ao_asset_id diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 7de9eeb8..d6e49151 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4967,12 +4967,11 @@ bool wallet2::check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& o return false; } //---------------------------------------------------------------------------------------------------- -bool wallet2::create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr, currency::transaction& tx_template) +bool wallet2::create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr, ionic_swap_proposal& proposal) { - crypto::secret_key one_time_key = AUTO_VAL_INIT(one_time_key); std::vector selected_transfers_for_template; - build_ionic_swap_template(proposal_details, destination_addr, tx_template, selected_transfers_for_template, one_time_key); + build_ionic_swap_template(proposal_details, destination_addr, proposal, selected_transfers_for_template); const uint32_t mask_to_mark_escrow_template_locked_transfers = WALLET_TRANSFER_DETAIL_FLAG_BLOCKED | WALLET_TRANSFER_DETAIL_FLAG_ESCROW_PROPOSAL_RESERVATION; mark_transfers_with_flag(selected_transfers_for_template, mask_to_mark_escrow_template_locked_transfers, "preparing ionic_swap"); @@ -4980,10 +4979,10 @@ bool wallet2::create_ionic_swap_proposal(const wallet_public::ionic_swap_proposa } //---------------------------------------------------------------------------------------------------- bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, - currency::transaction& template_tx, - std::vector& selected_transfers, - crypto::secret_key& one_time_key) + ionic_swap_proposal& proposal, + std::vector& selected_transfers) { + ionic_swap_proposal& proposal.tx_template; construct_tx_param ctp = get_default_construct_tx_param(); ctp.fake_outputs_count = proposal_detais.mixins; @@ -5019,29 +5018,54 @@ bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal prepare_transaction(ctp, ftp); selected_transfers = ftp.selected_transfers; + currency::finalized_tx finalize_result = AUTO_VAL_INIT(finalize_result); + finalize_transaction(ftp, finalize_result, false); + add_transfers_to_expiration_list(selected_transfers, finalize_result, 0, currency::null_hash); - finalize_transaction(ftp, template_tx, one_time_key, false); - - add_transfers_to_expiration_list(selected_transfers, t.v, 0, currency::null_hash); + //wrap it all + proposal.tx_template = finalize_result.tx; + ionic_swap_proposal_context ispc = AUTO_VAL_INIT(ispc); + ispc.gen_context = finalize_result.ftp.gen_context; + ispc.one_time_skey = finalize_result.one_time_key; + std::string proposal_context_blob = t_serializable_object_to_blob(ispc); + proposal.encrypted_context = crypto::chacha_crypt(proposal_context_blob, finalize_result.derivation); return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::get_ionic_swap_proposal_info(const std::string&raw_tx_template, wallet_public::ionic_swap_proposal_info& proposal) +bool wallet2::get_ionic_swap_proposal_info(const std::string&raw_proposal, wallet_public::ionic_swap_proposal_info& proposal_info) { - currency::transaction tx; - bool r = parse_and_validate_tx_from_blob(raw_tx_template, tx); - THROW_IF_TRUE_WALLET_EX(!r, error::tx_parse_error, raw_tx_template); - return get_ionic_swap_proposal_info(tx, proposal); + wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); + bool r = t_unserializable_object_from_blob(raw_proposal, proposal); + THROW_IF_TRUE_WALLET_EX(!r, error::wallet_internal_error, "Failed to parse proposal"); + return get_ionic_swap_proposal_info(proposal, proposal_info); } //---------------------------------------------------------------------------------------------------- -bool wallet2::get_ionic_swap_proposal_info(const currency::transaction tx, wallet_public::ionic_swap_proposal_info& proposal) +bool wallet2::get_ionic_swap_proposal_info(const wallet_public::ionic_swap_proposal& proposal, wallet_public::ionic_swap_proposal_info& proposal_info) { + wallet_public::ionic_swap_proposal_context ionic_context = AUTO_VAL_INIT(ionic_context); + return get_ionic_swap_proposal_info(proposal, proposal_info, ionic_context); +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::get_ionic_swap_proposal_info(const wallet_public::ionic_swap_proposal& proposal, wallet_public::ionic_swap_proposal_info& proposal_info, wallet_public::ionic_swap_proposal_context& ionic_context) +{ + const transaction& tx = proposal.tx_template; crypto::key_derivation derivation = AUTO_VAL_INIT(derivation); std::vector outs; uint64_t tx_money_got_in_outs = 0; bool r = lookup_acc_outs(m_account.get_keys(), tx, outs, tx_money_got_in_outs, derivation); THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "Failed to lookup_acc_outs for tx: " << get_transaction_hash(tx)); + if (!outs.size()) + { + return false; + } + + //decrypt context + std::string decrypted_raw_context = crypto::chacha_crypt(proposal.encrypted_context, derivation); + r = t_unserializable_object_from_blob(ionic_context, decrypted_raw_context); + THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "Failed to unserialize decrypted ionic_context"); + + std::unordered_map ammounts_to; std::unordered_map ammounts_from; std::vector third_party_outs; @@ -5066,50 +5090,50 @@ bool wallet2::get_ionic_swap_proposal_info(const currency::transaction tx, walle } for (const auto& a : ammounts_to) - proposal.to.push_back(view::asset_funds{ a.first, a.second }); + proposal_info.to.push_back(view::asset_funds{ a.first, a.second }); for (const auto& a : ammounts_from) - proposal.from.push_back(view::asset_funds{ a.first, a.second }); + proposal_info.from.push_back(view::asset_funds{ a.first, a.second }); for (const auto&in : tx.vin) { if (in.type() != typeid(currency::txin_zc_input)) return false; size_t mx = boost::get(in).key_offsets.size() - 1; - if (proposal.mixins == 0 || proposal.mixins > mx) + if (proposal_info.mixins == 0 || proposal_info.mixins > mx) { - proposal.mixins = mx; + proposal_info.mixins = mx; } } - proposal.fee = currency::get_tx_fee(tx); + proposal_info.fee = currency::get_tx_fee(tx); etc_tx_details_expiration_time t = AUTO_VAL_INIT(t); if (!get_type_in_variant_container(tx.extra, t)) { return false; } - proposal.expiration_time = t.v; + proposal_info.expiration_time = t.v; return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::accept_ionic_swap_proposal(const std::string& raw_tx_template, currency::transaction& result_tx) +bool wallet2::accept_ionic_swap_proposal(const std::string& raw_proposal, currency::transaction& result_tx) { - currency::transaction tx; - bool r = parse_and_validate_tx_from_blob(raw_tx_template, tx); - THROW_IF_TRUE_WALLET_EX(!r, error::tx_parse_error, raw_tx_template); + const wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); + bool r = parse_and_validate_tx_from_blob(raw_proposal, proposal); + THROW_IF_TRUE_WALLET_EX(!r, error::wallet_internal_error, "Failed to parse proposal info"); - return accept_ionic_swap_proposal(tx, result_tx); + return accept_ionic_swap_proposal(proposal, result_tx); } //---------------------------------------------------------------------------------------------------- -bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_template, currency::transaction& result_tx) +bool wallet2::accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposal& proposal, currency::transaction& result_tx) { mode_separate_context msc = AUTO_VAL_INIT(msc); msc.tx_for_mode_separate = tx_template; - - bool r = get_ionic_swap_proposal_info(tx_template, msc.proposal); + wallet_public::ionic_swap_proposal_context ionic_context = AUTO_VAL_INIT(ionic_context); + bool r = get_ionic_swap_proposal_info(proposal, msc.proposal_info, ionic_context); THROW_IF_TRUE_WALLET_EX(!r, error::wallet_internal_error, "Failed to get info from proposal"); std::unordered_map balances; @@ -5117,7 +5141,7 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat this->balance(balances, mined); //validate balances needed uint64_t native_amount_required = 0; - for (const auto& item : msc.proposal.to) + for (const auto& item : msc.proposal_info.to) { if (balances[item.asset_id].unlocked < item.amount) { @@ -5131,9 +5155,9 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat // balances is ok, check if fee is added to tx uint64_t additional_fee = 0; - if (msc.proposal.fee < m_core_runtime_config.tx_default_fee) + if (msc.proposal_info.fee < m_core_runtime_config.tx_default_fee) { - additional_fee = m_core_runtime_config.tx_default_fee - msc.proposal.fee; + additional_fee = m_core_runtime_config.tx_default_fee - msc.proposal_info.fee; if (balances[currency::native_coin_asset_id].unlocked < additional_fee + native_amount_required) { return false; @@ -5145,7 +5169,7 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat construct_tx_param construct_param = get_default_construct_tx_param(); construct_param.fee = additional_fee; - assert(0); crypto::secret_key one_time_key = currency::null_skey; //TODO: add transfer of secrete onetime key to proposal + assert(0); crypto::secret_key one_time_key = ionic_context.one_time_skey; construct_param.crypt_address = m_account.get_public_address(); construct_param.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; construct_param.mark_tx_as_complete = true; @@ -5153,6 +5177,7 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat //build transaction currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); ftp.tx_version = this->get_current_tx_version(); + ftp.gen_context = ionic_context.gen_context; prepare_transaction(construct_param, ftp, msc); try @@ -5165,8 +5190,6 @@ bool wallet2::accept_ionic_swap_proposal(const currency::transaction& tx_templat throw; } mark_transfers_as_spent(ftp.selected_transfers, std::string("Proposal has been accepted with tx <" + epee::string_tools::pod_to_hex(get_transaction_hash(result_tx))) + ">"); - - return true; } //---------------------------------------------------------------------------------------------------- @@ -6197,7 +6220,7 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx if (ctp.flags & TX_FLAG_SIGNATURE_MODE_SEPARATE && tx_for_mode_separate.vout.size() ) { WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(get_tx_flags(tx_for_mode_separate) & TX_FLAG_SIGNATURE_MODE_SEPARATE, "tx_param.flags differs from tx.flags"); - for (const auto& el : mode_separatemode_separate.proposal.to) + for (const auto& el : mode_separatemode_separate.proposal_info.to) { needed_money_map[el.asset_id].needed_amount += el.amount; } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 804f9eb7..82c6a19f 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -949,15 +949,16 @@ namespace tools bool check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id); // ionic swaps: - bool create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal, const currency::account_public_address& destination_addr, currency::transaction& tx_template); + bool create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal, const currency::account_public_address& destination_addr, ionic_swap_proposal& proposal); bool build_ionic_swap_template(const wallet_public::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, - currency::transaction& template_tx, + ionic_swap_proposal& proposal, std::vector& selected_transfers_for_template, crypto::secret_key& one_time_key); - bool get_ionic_swap_proposal_info(const std::string&raw_tx_template, wallet_public::ionic_swap_proposal_info& proposal); - bool get_ionic_swap_proposal_info(const currency::transaction tx, wallet_public::ionic_swap_proposal_info& proposal); - bool accept_ionic_swap_proposal(const std::string&raw_tx_template, currency::transaction& result_tx); - bool accept_ionic_swap_proposal(const currency::transaction& tx_template, currency::transaction& result_tx); + bool get_ionic_swap_proposal_info(const std::string&raw_proposal, wallet_public::ionic_swap_proposal_info& proposal_info); + bool get_ionic_swap_proposal_info(const wallet_public::ionic_swap_proposal& proposal, wallet_public::ionic_swap_proposal_info& proposal_info); + bool get_ionic_swap_proposal_info(const wallet_public::ionic_swap_proposal& proposal, wallet_public::ionic_swap_proposal_info& proposal_info, wallet_public::ionic_swap_proposal_context& ionic_context); + bool accept_ionic_swap_proposal(const std::string& raw_proposal, currency::transaction& result_tx); + bool accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposal& proposal, currency::transaction& result_tx); // Signing and auth bool sign_buffer(const std::string& buff, crypto::signature& sig); @@ -970,8 +971,6 @@ private: // -------- t_transport_state_notifier ------------------------------------------------ virtual void notify_state_change(const std::string& state_code, const std::string& details = std::string()); // ------------------------------------------------------------------------------------ - - void add_transfers_to_expiration_list(const std::vector& selected_transfers, uint64_t expiration, uint64_t change_amount, const crypto::hash& related_tx_id); void remove_transfer_from_expiration_list(uint64_t transfer_index); void load_keys(const std::string& keys_file_name, const std::string& password, uint64_t file_signature, keys_file_data& kf_data); diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 515fe5a4..c7e2123a 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1210,6 +1210,34 @@ namespace wallet_public END_KV_SERIALIZE_MAP() }; + + struct ionic_swap_proposal_context + { + currency::tx_generation_context gen_context; + crypto::secret_key one_time_skey; + + BEGIN_SERIALIZE_OBJECT() + VERSION() + CURRENT_VERSION(0) + FIELD(gen_context) + FIELD(one_time_skey) + END_SERIALIZE() + }; + + struct ionic_swap_proposal + { + currency::transaction tx_template; + std::string encrypted_context; //ionic_swap_proposal_context encrypted with derivation + + + BEGIN_SERIALIZE_OBJECT() + VERSION() + CURRENT_VERSION(0) + FIELD(tx_template) + FIELD(encrypted_context) + END_SERIALIZE() + }; + struct create_ionic_swap_proposal_request { uint64_t wallet_id; diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 5c2f7f1b..72e2e663 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -885,15 +885,15 @@ std::string wallets_manager::create_ionic_swap_proposal(uint64_t wallet_id, cons { return API_RETURN_CODE_BAD_ARG; } - currency::transaction tx_template = AUTO_VAL_INIT(tx_template); - bool r = wo.w->get()->create_ionic_swap_proposal(proposal.proposal, dest_account, tx_template); + tools::wallet_public ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); + bool r = wo.w->get()->create_ionic_swap_proposal(proposal.proposal, dest_account, proposal); if (!r) { return API_RETURN_CODE_FAIL; } else { - result_proposal_hex = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(tx_template)); + result_proposal_hex = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(proposal)); return API_RETURN_CODE_OK; } } From 9859361e36832b4b3977d7004843b29e2150e4d8 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 17 Apr 2023 19:35:55 +0200 Subject: [PATCH 26/34] Multiple fixes over ionic_swap --- .../currency_format_utils_transactions.cpp | 9 +++++ .../currency_format_utils_transactions.h | 4 +- src/serialization/serialization.h | 4 +- src/wallet/wallet2.cpp | 39 +++++++++++-------- src/wallet/wallet2.h | 9 ++--- src/wallet/wallet_public_structs_defs.h | 1 + 6 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/currency_core/currency_format_utils_transactions.cpp b/src/currency_core/currency_format_utils_transactions.cpp index e7071e0c..95bb4cdd 100644 --- a/src/currency_core/currency_format_utils_transactions.cpp +++ b/src/currency_core/currency_format_utils_transactions.cpp @@ -397,5 +397,14 @@ namespace currency CATCH_ENTRY2(std::vector{}); } //--------------------------------------------------------------- + bool validate_tx_output_details_againt_tx_generation_context(const transaction& tx, const tx_generation_context& gen_context, const crypto::secret_key& onet_time_key) + { + //TODO: Implement this function before mainnet +#ifdef TESTNET + return true; +#else + return false; +#endif + } } \ 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 index 30cb7589..2137054b 100644 --- a/src/currency_core/currency_format_utils_transactions.h +++ b/src/currency_core/currency_format_utils_transactions.h @@ -201,7 +201,7 @@ namespace currency bool tx_to_blob(const transaction& b, blobdata& b_blob); bool read_keyimages_from_tx(const transaction& tx, std::list& kil); bool validate_inputs_sorting(const transaction& tx); - bool is_asset_emitting_transaction(const transaction& tx, asset_descriptor_operation* p_ado = nullptr); + bool is_asset_emitting_transaction(const transaction& tx, asset_descriptor_operation* p_ado = nullptr); std::vector prepare_outputs_entries_for_key_offsets(const std::vector& outputs, size_t old_real_index, size_t& new_real_index) noexcept; @@ -313,4 +313,6 @@ namespace currency END_SERIALIZE() }; // struct tx_generation_context + bool validate_tx_output_details_againt_tx_generation_context(const transaction& tx, const tx_generation_context& gen_context, const crypto::secret_key& onet_time_key); + } // namespace currency diff --git a/src/serialization/serialization.h b/src/serialization/serialization.h index 5b5383b1..d2e8d029 100644 --- a/src/serialization/serialization.h +++ b/src/serialization/serialization.h @@ -63,8 +63,8 @@ inline bool do_serialize(Archive &ar, T &v) #define BEGIN_SERIALIZE() \ template class Archive> bool do_serialize(Archive &_ser_ar) {uint8_t s_current_version ATTRIBUTE_UNUSED = 0; uint8_t s_version ATTRIBUTE_UNUSED = 0; #define BEGIN_SERIALIZE_OBJECT() \ - template class Archive> bool do_serialize(Archive &_ser_ar) { _ser_ar.begin_object(); bool _ser_res = do_serialize_object(_ser_ar); _ser_ar.end_object(); return _ser_res; } \ - template class Archive> bool do_serialize_object(Archive &_ser_ar){ + template class Archive> bool do_serialize(Archive &_ser_ar) {_ser_ar.begin_object(); bool _ser_res = do_serialize_object(_ser_ar); _ser_ar.end_object(); return _ser_res; } \ + template class Archive> bool do_serialize_object(Archive &_ser_ar){ uint8_t s_current_version ATTRIBUTE_UNUSED = 0; uint8_t s_version ATTRIBUTE_UNUSED = 0; #define PREPARE_CUSTOM_VECTOR_SERIALIZATION(size, vec) ::serialization::detail::prepare_custom_vector_serialization(size, vec, typename Archive::is_saving()) #define END_SERIALIZE() return true;} diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index d6e49151..1fab53bc 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4967,7 +4967,7 @@ bool wallet2::check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& o return false; } //---------------------------------------------------------------------------------------------------- -bool wallet2::create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr, ionic_swap_proposal& proposal) +bool wallet2::create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr, wallet_public::ionic_swap_proposal& proposal) { std::vector selected_transfers_for_template; @@ -4979,10 +4979,9 @@ bool wallet2::create_ionic_swap_proposal(const wallet_public::ionic_swap_proposa } //---------------------------------------------------------------------------------------------------- bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, - ionic_swap_proposal& proposal, + wallet_public::ionic_swap_proposal& proposal, std::vector& selected_transfers) { - ionic_swap_proposal& proposal.tx_template; construct_tx_param ctp = get_default_construct_tx_param(); ctp.fake_outputs_count = proposal_detais.mixins; @@ -5020,11 +5019,11 @@ bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal selected_transfers = ftp.selected_transfers; currency::finalized_tx finalize_result = AUTO_VAL_INIT(finalize_result); finalize_transaction(ftp, finalize_result, false); - add_transfers_to_expiration_list(selected_transfers, finalize_result, 0, currency::null_hash); + add_transfers_to_expiration_list(selected_transfers, proposal_detais.expiration_time, 0, currency::null_hash); //wrap it all proposal.tx_template = finalize_result.tx; - ionic_swap_proposal_context ispc = AUTO_VAL_INIT(ispc); + wallet_public::ionic_swap_proposal_context ispc = AUTO_VAL_INIT(ispc); ispc.gen_context = finalize_result.ftp.gen_context; ispc.one_time_skey = finalize_result.one_time_key; std::string proposal_context_blob = t_serializable_object_to_blob(ispc); @@ -5035,7 +5034,7 @@ bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal bool wallet2::get_ionic_swap_proposal_info(const std::string&raw_proposal, wallet_public::ionic_swap_proposal_info& proposal_info) { wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); - bool r = t_unserializable_object_from_blob(raw_proposal, proposal); + bool r = t_unserializable_object_from_blob(proposal, raw_proposal); THROW_IF_TRUE_WALLET_EX(!r, error::wallet_internal_error, "Failed to parse proposal"); return get_ionic_swap_proposal_info(proposal, proposal_info); } @@ -5065,6 +5064,8 @@ bool wallet2::get_ionic_swap_proposal_info(const wallet_public::ionic_swap_propo r = t_unserializable_object_from_blob(ionic_context, decrypted_raw_context); THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "Failed to unserialize decrypted ionic_context"); + r = validate_tx_output_details_againt_tx_generation_context(tx, ionic_context.gen_context, ionic_context.one_time_skey); + THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "Failed to validate decrypted ionic_context"); std::unordered_map ammounts_to; std::unordered_map ammounts_from; @@ -5072,21 +5073,27 @@ bool wallet2::get_ionic_swap_proposal_info(const wallet_public::ionic_swap_propo size_t i = 0; for (const auto& o : outs) { + THROW_IF_FALSE_WALLET_INT_ERR_EX(ionic_context.gen_context.asset_ids.size() > i, "Tx gen context has mismatch with tx(asset_ids) "); + THROW_IF_FALSE_WALLET_INT_ERR_EX(ionic_context.gen_context.asset_ids[i].to_public_key() == o.asset_id, "Tx gen context has mismatch with tx(asset_id != asset_id) "); + THROW_IF_FALSE_WALLET_INT_ERR_EX(ionic_context.gen_context.amounts[i].m_u64[0] == o.amount, "Tx gen context has mismatch with tx(amount != amount)"); + ammounts_to[o.asset_id] += o.amount; third_party_outs[i] = false; i++; } + //validate outputs against decrypted tx generation context for (i = 0; i != tx.vout.size(); i++) { - if (!third_party_outs[i]) - continue; - crypto::hash asset_id = AUTO_VAL_INIT(asset_id); - uint64_t amount = 0; - //TODO decode output info - //get_amout_and_asset_id() - //ammounts_from[asset_id] += amount; + if (!third_party_outs[i]) + { + continue; + } + + crypto::public_key asset_id = ionic_context.gen_context.asset_ids[i].to_public_key(); + uint64_t amount = ionic_context.gen_context.amounts[i].m_u64[0]; + ammounts_from[asset_id] += amount; } for (const auto& a : ammounts_to) @@ -5120,8 +5127,8 @@ bool wallet2::get_ionic_swap_proposal_info(const wallet_public::ionic_swap_propo //---------------------------------------------------------------------------------------------------- bool wallet2::accept_ionic_swap_proposal(const std::string& raw_proposal, currency::transaction& result_tx) { - const wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); - bool r = parse_and_validate_tx_from_blob(raw_proposal, proposal); + wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); + bool r = t_unserializable_object_from_blob(proposal, raw_proposal); THROW_IF_TRUE_WALLET_EX(!r, error::wallet_internal_error, "Failed to parse proposal info"); return accept_ionic_swap_proposal(proposal, result_tx); @@ -5130,7 +5137,7 @@ bool wallet2::accept_ionic_swap_proposal(const std::string& raw_proposal, curren bool wallet2::accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposal& proposal, currency::transaction& result_tx) { mode_separate_context msc = AUTO_VAL_INIT(msc); - msc.tx_for_mode_separate = tx_template; + msc.tx_for_mode_separate = proposal.tx_template; wallet_public::ionic_swap_proposal_context ionic_context = AUTO_VAL_INIT(ionic_context); bool r = get_ionic_swap_proposal_info(proposal, msc.proposal_info, ionic_context); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 82c6a19f..80a665ae 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -305,7 +305,7 @@ namespace tools struct mode_separate_context { currency::transaction tx_for_mode_separate; - view::ionic_swap_proposal_info proposal; + view::ionic_swap_proposal_info proposal_info; }; @@ -949,11 +949,10 @@ namespace tools bool check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id); // ionic swaps: - bool create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal, const currency::account_public_address& destination_addr, ionic_swap_proposal& proposal); + bool create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr, wallet_public::ionic_swap_proposal& proposal); bool build_ionic_swap_template(const wallet_public::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr, - ionic_swap_proposal& proposal, - std::vector& selected_transfers_for_template, - crypto::secret_key& one_time_key); + wallet_public::ionic_swap_proposal& proposal, + std::vector& selected_transfers_for_template); bool get_ionic_swap_proposal_info(const std::string&raw_proposal, wallet_public::ionic_swap_proposal_info& proposal_info); bool get_ionic_swap_proposal_info(const wallet_public::ionic_swap_proposal& proposal, wallet_public::ionic_swap_proposal_info& proposal_info); bool get_ionic_swap_proposal_info(const wallet_public::ionic_swap_proposal& proposal, wallet_public::ionic_swap_proposal_info& proposal_info, wallet_public::ionic_swap_proposal_context& ionic_context); diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index c7e2123a..06dd7832 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1208,6 +1208,7 @@ namespace wallet_public KV_SERIALIZE(fee) KV_SERIALIZE(expiration_time) END_KV_SERIALIZE_MAP() + }; From ac4a62a5c980c0fda5fe9ef695b9f54b3790380a Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 17 Apr 2023 23:04:30 +0200 Subject: [PATCH 27/34] fixed API for explorer --- src/currency_core/blockchain_storage.cpp | 76 ++++++ src/currency_core/blockchain_storage.h | 2 + src/currency_core/currency_format_utils.cpp | 249 -------------------- src/currency_core/currency_format_utils.h | 212 ++++++++++++++++- src/currency_core/tx_pool.cpp | 6 +- 5 files changed, 291 insertions(+), 254 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index be5a1417..46fc7e06 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -5150,6 +5150,82 @@ std::shared_ptr blockchain_storage::find_key_imag return std::shared_ptr(); } +//--------------------------------------------------------------- +bool blockchain_storage::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) const +{ + //tei.blob = tx_ptr->tx + tei.id = epee::string_tools::pod_to_hex(h); + if (!tei.blob_size) + tei.blob_size = get_object_blobsize(tx); + + tei.fee = get_tx_fee(tx); + tei.pub_key = epee::string_tools::pod_to_hex(get_tx_pub_key_from_extra(tx)); + tei.timestamp = timestamp; + tei.amount = get_outs_money_amount(tx); + + if (is_short) + return true; + + fill_tx_rpc_inputs(tei, tx); + fill_tx_rpc_outputs(tei, tx, ptce); + fill_tx_rpc_payload_items(tei.extra, tx.extra); + fill_tx_rpc_payload_items(tei.attachments, tx.attachment); + return true; +} +//------------------------------------------------------------------ +bool blockchain_storage::fill_tx_rpc_inputs(tx_rpc_extended_info& tei, const transaction& tx) const +{ + //handle inputs + for (auto in : tx.vin) + { + tei.ins.push_back(tx_in_rpc_entry()); + if (in.type() == typeid(txin_gen)) + { + tei.ins.back().amount = 0; + } + else if (in.type() == typeid(txin_to_key) || in.type() == typeid(txin_htlc)) + { + //TODO: add htlc info + const txin_to_key& tk = get_to_key_input_from_txin_v(in); + tei.ins.back().amount = tk.amount; + tei.ins.back().kimage_or_ms_id = epee::string_tools::pod_to_hex(tk.k_image); + std::vector absolute_offsets = relative_output_offsets_to_absolute(tk.key_offsets); + for (auto& ao : absolute_offsets) + { + tei.ins.back().global_indexes.push_back(0); + if (ao.type() == typeid(uint64_t)) + { + tei.ins.back().global_indexes.back() = boost::get(ao); + } + else if (ao.type() == typeid(ref_by_id)) + { + //disable for the reset at the moment + auto tx_ptr = get_tx_chain_entry(boost::get(ao).tx_id); + if (!tx_ptr || tx_ptr->m_global_output_indexes.size() <= boost::get(ao).n) + { + tei.ins.back().global_indexes.back() = std::numeric_limits::max(); + return false; + } + tei.ins.back().global_indexes.back() = tx_ptr->m_global_output_indexes[boost::get(ao).n]; + } + } + if (in.type() == typeid(txin_htlc)) + { + tei.ins.back().htlc_origin = epee::string_tools::buff_to_hex_nodelimer(boost::get(in).hltc_origin); + } + //tk.etc_details -> visualize it may be later + } + else if (in.type() == typeid(txin_multisig)) + { + txin_multisig& tms = boost::get(in); + tei.ins.back().amount = tms.amount; + tei.ins.back().kimage_or_ms_id = epee::string_tools::pod_to_hex(tms.multisig_out_id); + if (tx.signatures.size() >= tei.ins.size()) + tei.ins.back().multisig_count = tx.signatures[tei.ins.size() - 1].size(); + } + } + return true; +} //------------------------------------------------------------------ bool blockchain_storage::prune_aged_alt_blocks() { diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index e5791569..f9dfa437 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -334,6 +334,8 @@ namespace currency // returns true as soon as the hardfork is active for the NEXT upcoming block (not for the top block in the blockchain storage) bool is_hardfork_active(size_t hardfork_id) const; + bool fill_tx_rpc_inputs(tx_rpc_extended_info& tei, const transaction& tx) const; + 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) const; wide_difficulty_type block_difficulty(size_t i)const; bool forecast_difficulty(std::vector> &out_height_2_diff_vector, bool pos) const; diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 3324ca55..98dcf722 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -3570,235 +3570,7 @@ namespace currency return cnt; } - struct rpc_tx_payload_handler : public boost::static_visitor - { - tx_extra_rpc_entry& tv; - rpc_tx_payload_handler(tx_extra_rpc_entry& t) : tv(t) - {} - bool operator()(const tx_service_attachment& ee) - { - tv.type = "service"; - tv.short_view = ee.service_id + ":" + ee.instruction; - if (ee.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY) - tv.short_view += "(encrypted)"; - else - { - std::string deflated_buff; - const std::string* pfinalbuff = &ee.body; - if (ee.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY) - { - bool r = epee::zlib_helper::unpack(ee.body, deflated_buff); - CHECK_AND_ASSERT_MES(r, false, "Failed to unpack"); - pfinalbuff = &deflated_buff; - } - if (ee.service_id == BC_PAYMENT_ID_SERVICE_ID || ee.service_id == BC_OFFERS_SERVICE_ID) - tv.details_view = *pfinalbuff; - else - tv.details_view = "BINARY DATA"; - } - return true; - } - bool operator()(const tx_crypto_checksum& ee) - { - tv.type = "crypto_checksum"; - tv.short_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash); - tv.details_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash) + "\n" - + "encrypted_key_derivation: " + epee::string_tools::pod_to_hex(ee.encrypted_key_derivation); - - return true; - } - bool operator()(const etc_tx_time& ee) - { - tv.type = "pos_time"; - tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); - return true; - } - bool operator()(const etc_tx_details_unlock_time& ee) - { - tv.type = "unlock_time"; - if (ee.v < CURRENCY_MAX_BLOCK_NUMBER) - tv.short_view = std::string("height: ") + std::to_string(ee.v); - else - tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); - - return true; - } - bool operator()(const etc_tx_details_unlock_time2& ee) - { - tv.type = "unlock_time"; - std::stringstream ss; - ss << "["; - for (auto v : ee.unlock_time_array) - { - ss << " " << v; - } - ss << "]"; - tv.short_view = ss.str(); - - return true; - } - bool operator()(const etc_tx_details_expiration_time& ee) - { - tv.type = "expiration_time"; - if (ee.v < CURRENCY_MAX_BLOCK_NUMBER) - tv.short_view = std::string("height: ") + std::to_string(ee.v); - else - tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); - - return true; - } - bool operator()(const etc_tx_details_flags& ee) - { - tv.type = "details_flags"; - tv.short_view = epee::string_tools::pod_to_hex(ee.v); - return true; - } - bool operator()(const crypto::public_key& ee) - { - tv.type = "pub_key"; - tv.short_view = epee::string_tools::pod_to_hex(ee); - return true; - } - bool operator()(const extra_attachment_info& ee) - { - tv.type = "attachment_info"; - tv.short_view = std::to_string(ee.sz) + " bytes"; - tv.details_view = currency::obj_to_json_str(ee); - return true; - } - bool operator()(const extra_alias_entry& ee) - { - tv.type = "alias_info"; - tv.short_view = ee.m_alias + "-->" + get_account_address_as_str(ee.m_address); - tv.details_view = currency::obj_to_json_str(ee); - - return true; - } - bool operator()(const extra_alias_entry_old& ee) - { - return operator()(static_cast(ee)); - } - bool operator()(const extra_user_data& ee) - { - tv.type = "user_data"; - tv.short_view = std::to_string(ee.buff.size()) + " bytes"; - tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee.buff); - - return true; - } - bool operator()(const extra_padding& ee) - { - tv.type = "extra_padding"; - tv.short_view = std::to_string(ee.buff.size()) + " bytes"; - if (!ee.buff.empty()) - tv.details_view = epee::string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast(&ee.buff[0]), ee.buff.size())); - - return true; - } - bool operator()(const tx_comment& ee) - { - tv.type = "comment"; - tv.short_view = std::to_string(ee.comment.size()) + " bytes(encrypted)"; - tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee.comment); - - return true; - } - bool operator()(const tx_payer& ee) - { - //const tx_payer& ee = boost::get(extra); - tv.type = "payer"; - tv.short_view = "(encrypted)"; - - return true; - } - bool operator()(const tx_payer_old&) - { - tv.type = "payer_old"; - tv.short_view = "(encrypted)"; - - return true; - } - bool operator()(const tx_receiver& ee) - { - //const tx_payer& ee = boost::get(extra); - tv.type = "receiver"; - tv.short_view = "(encrypted)"; - - return true; - } - bool operator()(const tx_receiver_old& ee) - { - tv.type = "receiver_old"; - tv.short_view = "(encrypted)"; - - return true; - } - bool operator()(const tx_derivation_hint& ee) - { - tv.type = "derivation_hint"; - tv.short_view = std::to_string(ee.msg.size()) + " bytes"; - tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee.msg); - - return true; - } - bool operator()(const std::string& ee) - { - tv.type = "string"; - tv.short_view = std::to_string(ee.size()) + " bytes"; - tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee); - - return true; - } - bool operator()(const etc_tx_flags16_t& dh) - { - tv.type = "FLAGS16"; - tv.short_view = epee::string_tools::pod_to_hex(dh); - tv.details_view = epee::string_tools::pod_to_hex(dh); - - return true; - } - bool operator()(const zarcanum_tx_data_v1& ztxd) - { - tv.type = "zarcanum_tx_data_v1"; - tv.short_view = "fee = " + print_money_brief(ztxd.fee); - tv.details_view = tv.short_view; - return true; - } - bool operator()(const zc_outs_range_proof& rp) - { - tv.type = "zc_outs_range_proof"; - // TODO @#@# - //tv.short_view = "outputs_count = " + std::to_string(rp.outputs_count); - return true; - } - bool operator()(const zc_balance_proof& bp) - { - tv.type = "zc_balance_proof"; - return true; - } - template - bool operator()(const t_type& t_t) - { - tv.type = typeid(t_t).name(); - return true; - } - }; - //------------------------------------------------------------------ - template - bool fill_tx_rpc_payload_items(std::vector& target_vector, const t_container& tc) - { - //handle extra - for (auto& extra : tc) - { - target_vector.push_back(tx_extra_rpc_entry()); - tx_extra_rpc_entry& tv = target_vector.back(); - - rpc_tx_payload_handler vstr(tv); - boost::apply_visitor(vstr, extra); - } - return true; - } //------------------------------------------------------------------ bool fill_tx_rpc_outputs(tx_rpc_extended_info& tei, const transaction& tx, const transaction_chain_entry* ptce) { @@ -3919,28 +3691,7 @@ namespace currency pei_rpc.penalty = (pei_rpc.base_reward + pei_rpc.total_fee) - pei_rpc.summary_reward; return true; } - //--------------------------------------------------------------- - 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) - { - //tei.blob = tx_ptr->tx - tei.id = epee::string_tools::pod_to_hex(h); - if(!tei.blob_size) - tei.blob_size = get_object_blobsize(tx); - tei.fee = get_tx_fee(tx); - tei.pub_key = epee::string_tools::pod_to_hex(get_tx_pub_key_from_extra(tx)); - tei.timestamp = timestamp; - tei.amount = get_outs_money_amount(tx); - - if (is_short) - return true; - - fill_tx_rpc_inputs(tei, tx); - fill_tx_rpc_outputs(tei, tx, ptce); - fill_tx_rpc_payload_items(tei.extra, tx.extra); - fill_tx_rpc_payload_items(tei.attachments, tx.attachment); - return true; - } //------------------------------------------------------------------ void append_per_block_increments_for_tx(const transaction& tx, std::unordered_map& gindices) { diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 8ccf34d5..4b9008a4 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -29,6 +29,9 @@ #include "currency_format_utils_transactions.h" #include "core_runtime_config.h" #include "wallet/wallet_public_structs_defs.h" +#include "bc_attachments_helpers.h" +#include "bc_payments_id_service.h" +#include "bc_offers_service_basic.h" // ------ get_tx_type_definition ------------- @@ -417,8 +420,7 @@ namespace currency update_alias_rpc_details alias_info_to_rpc_update_alias_info(const currency::extra_alias_entry& ai, const std::string& old_address); size_t get_service_attachments_count_in_tx(const transaction& tx); bool fill_tx_rpc_outputs(tx_rpc_extended_info& tei, const transaction& tx, const transaction_chain_entry* ptce); - bool fill_tx_rpc_inputs(tx_rpc_extended_info& tei, const transaction& tx); - 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, bool use_password); @@ -894,5 +896,211 @@ namespace currency const difficulties& b_diff ); + struct rpc_tx_payload_handler : public boost::static_visitor + { + tx_extra_rpc_entry& tv; + rpc_tx_payload_handler(tx_extra_rpc_entry& t) : tv(t) + {} + + bool operator()(const tx_service_attachment& ee) + { + tv.type = "service"; + tv.short_view = ee.service_id + ":" + ee.instruction; + if (ee.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY) + tv.short_view += "(encrypted)"; + else + { + std::string deflated_buff; + const std::string* pfinalbuff = &ee.body; + if (ee.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY) + { + bool r = epee::zlib_helper::unpack(ee.body, deflated_buff); + CHECK_AND_ASSERT_MES(r, false, "Failed to unpack"); + pfinalbuff = &deflated_buff; + } + if (ee.service_id == BC_PAYMENT_ID_SERVICE_ID || ee.service_id == BC_OFFERS_SERVICE_ID) + tv.datails_view = *pfinalbuff; + else + tv.datails_view = "BINARY DATA"; + } + return true; + } + bool operator()(const tx_crypto_checksum& ee) + { + tv.type = "crypto_checksum"; + tv.short_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash); + tv.datails_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash) + "\n" + + "encrypted_key_derivation: " + epee::string_tools::pod_to_hex(ee.encrypted_key_derivation); + + return true; + } + bool operator()(const etc_tx_time& ee) + { + tv.type = "pos_time"; + tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); + return true; + } + bool operator()(const etc_tx_details_unlock_time& ee) + { + tv.type = "unlock_time"; + if (ee.v < CURRENCY_MAX_BLOCK_NUMBER) + tv.short_view = std::string("height: ") + std::to_string(ee.v); + else + tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); + + return true; + } + bool operator()(const etc_tx_details_unlock_time2& ee) + { + tv.type = "unlock_time"; + std::stringstream ss; + ss << "["; + for (auto v : ee.unlock_time_array) + { + ss << " " << v; + } + ss << "]"; + tv.short_view = ss.str(); + + return true; + } + bool operator()(const etc_tx_details_expiration_time& ee) + { + tv.type = "expiration_time"; + if (ee.v < CURRENCY_MAX_BLOCK_NUMBER) + tv.short_view = std::string("height: ") + std::to_string(ee.v); + else + tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); + + return true; + } + bool operator()(const etc_tx_details_flags& ee) + { + tv.type = "details_flags"; + tv.short_view = epee::string_tools::pod_to_hex(ee.v); + return true; + } + bool operator()(const crypto::public_key& ee) + { + tv.type = "pub_key"; + tv.short_view = epee::string_tools::pod_to_hex(ee); + return true; + } + bool operator()(const extra_attachment_info& ee) + { + tv.type = "attachment_info"; + tv.short_view = std::to_string(ee.sz) + " bytes"; + tv.datails_view = currency::obj_to_json_str(ee); + return true; + } + bool operator()(const extra_alias_entry& ee) + { + tv.type = "alias_info"; + tv.short_view = ee.m_alias + "-->" + get_account_address_as_str(ee.m_address); + tv.datails_view = currency::obj_to_json_str(ee); + + return true; + } + bool operator()(const extra_alias_entry_old& ee) + { + return operator()(static_cast(ee)); + } + bool operator()(const extra_user_data& ee) + { + tv.type = "user_data"; + tv.short_view = std::to_string(ee.buff.size()) + " bytes"; + tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee.buff); + + return true; + } + bool operator()(const extra_padding& ee) + { + tv.type = "extra_padding"; + tv.short_view = std::to_string(ee.buff.size()) + " bytes"; + if (!ee.buff.empty()) + tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast(&ee.buff[0]), ee.buff.size())); + + return true; + } + bool operator()(const tx_comment& ee) + { + tv.type = "comment"; + tv.short_view = std::to_string(ee.comment.size()) + " bytes(encrypted)"; + tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee.comment); + + return true; + } + bool operator()(const tx_payer& ee) + { + //const tx_payer& ee = boost::get(extra); + tv.type = "payer"; + tv.short_view = "(encrypted)"; + + return true; + } + bool operator()(const tx_payer_old&) + { + tv.type = "payer_old"; + tv.short_view = "(encrypted)"; + + return true; + } + bool operator()(const tx_receiver& ee) + { + //const tx_payer& ee = boost::get(extra); + tv.type = "receiver"; + tv.short_view = "(encrypted)"; + + return true; + } + bool operator()(const tx_receiver_old& ee) + { + tv.type = "receiver_old"; + tv.short_view = "(encrypted)"; + + return true; + } + bool operator()(const tx_derivation_hint& ee) + { + tv.type = "derivation_hint"; + tv.short_view = std::to_string(ee.msg.size()) + " bytes"; + tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee.msg); + + return true; + } + bool operator()(const std::string& ee) + { + tv.type = "string"; + tv.short_view = std::to_string(ee.size()) + " bytes"; + tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee); + + return true; + } + bool operator()(const etc_tx_flags16_t& dh) + { + tv.type = "FLAGS16"; + tv.short_view = epee::string_tools::pod_to_hex(dh); + tv.datails_view = epee::string_tools::pod_to_hex(dh); + + return true; + } + }; + //------------------------------------------------------------------ + + + template + bool fill_tx_rpc_payload_items(std::vector& target_vector, const t_container& tc) + { + //handle extra + for (auto& extra : tc) + { + target_vector.push_back(tx_extra_rpc_entry()); + tx_extra_rpc_entry& tv = target_vector.back(); + + rpc_tx_payload_handler vstr(tv); + boost::apply_visitor(vstr, extra); + } + return true; + } } // namespace currency diff --git a/src/currency_core/tx_pool.cpp b/src/currency_core/tx_pool.cpp index 61e5a449..8fcca00f 100644 --- a/src/currency_core/tx_pool.cpp +++ b/src/currency_core/tx_pool.cpp @@ -516,7 +516,7 @@ namespace currency txs.push_back(tx_rpc_extended_info()); tx_rpc_extended_info& trei = txs.back(); trei.blob_size = tx_entry.blob_size; - fill_tx_rpc_details(trei, tx_entry.tx, nullptr, h, tx_entry.receive_time, true); + m_blockchain.fill_tx_rpc_details(trei, tx_entry.tx, nullptr, h, tx_entry.receive_time, true); return true; }); @@ -568,7 +568,7 @@ namespace currency txs.push_back(tx_rpc_extended_info()); tx_rpc_extended_info& trei = txs.back(); trei.blob_size = ptei->blob_size; - fill_tx_rpc_details(trei, ptei->tx, nullptr, id, ptei->receive_time, false); + m_blockchain.fill_tx_rpc_details(trei, ptei->tx, nullptr, id, ptei->receive_time, false); } return true; } @@ -605,7 +605,7 @@ namespace currency if (!ptei) return false; - fill_tx_rpc_details(trei, ptei->tx, nullptr, id, ptei->receive_time, false); + m_blockchain.fill_tx_rpc_details(trei, ptei->tx, nullptr, id, ptei->receive_time, false); return true; } //--------------------------------------------------------------------------------- From 44e22b611d4969fde10a70d6514ec74574e708b1 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 18 Apr 2023 16:55:00 +0200 Subject: [PATCH 28/34] Multiple fixes here and there, mostly fixing compilation problems --- src/currency_core/currency_basic.h | 4 +-- src/currency_core/currency_format_utils.cpp | 2 +- src/simplewallet/simplewallet.cpp | 2 +- src/wallet/wallet2.cpp | 4 +-- src/wallet/wallet_public_structs_defs.h | 9 +++-- src/wallet/wallet_rpc_server.cpp | 6 ++-- src/wallet/wallets_manager.cpp | 8 ++--- tests/core_tests/hard_fork_2.cpp | 6 ++-- tests/core_tests/ionic_swap_tests.cpp | 36 +++++++++---------- .../isolate_auditable_and_proof.cpp | 2 +- tests/core_tests/multiassets_test.cpp | 6 ++-- tests/core_tests/multisig_wallet_tests.cpp | 5 +-- tests/core_tests/wallet_rpc_tests.cpp | 6 ++-- 13 files changed, 51 insertions(+), 45 deletions(-) diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index e64155c0..b86d5e70 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -56,8 +56,8 @@ namespace currency const static crypto::key_derivation null_derivation = AUTO_VAL_INIT(null_derivation); const static crypto::hash gdefault_genesis = epee::string_tools::hex_to_pod("CC608F59F8080E2FBFE3C8C80EB6E6A953D47CF2D6AEBD345BADA3A1CAB99852"); - const static crypto::hash ffff_hash = epee::string_tools::hex_to_pod("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - const static crypto::public_key ffff_pkey = epee::string_tools::hex_to_pod("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // TODO @#@# consider getting rid of this + //const static crypto::hash ffff_hash = epee::string_tools::hex_to_pod("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + //const static crypto::public_key ffff_pkey = epee::string_tools::hex_to_pod("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // TODO @#@# consider getting rid of this // TODO: rewtire the following to a normal aggregate initialization once we move to C++17 -- sowle const static crypto::public_key native_coin_asset_id = reinterpret_cast(static_cast(crypto::ec_scalar{'\xd6', '\x32', '\x9b', '\x5b', '\x1f', '\x7c', '\x08', '\x05', '\xb5', '\xc3', '\x45', '\xf4', '\x95', '\x75', '\x54', '\x00', '\x2a', '\x2f', '\x55', '\x78', '\x45', '\xf6', '\x4d', '\x76', '\x45', '\xda', '\xe0', '\xe0', '\x51', '\xa6', '\x49', '\x8a'})); // == crypto::c_point_H, checked in crypto_constants diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 98dcf722..cfe34b18 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -2241,7 +2241,7 @@ namespace currency uint64_t amount_of_emitted_asset = 0; for (auto& item : shuffled_dsts) { - if (item.asset_id == currency::ffff_pkey) + if (item.asset_id == currency::null_pkey) { item.asset_id = gen_context.ao_asset_id; // set calculated asset_id to the asset's outputs, if this asset is being emitted within this tx amount_of_emitted_asset += item.amount; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index de38d89a..d23a3ea1 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1819,7 +1819,7 @@ bool simple_wallet::deploy_new_asset(const std::vector &args) tx_destination_entry td = AUTO_VAL_INIT(td); td.addr.push_back(m_wallet->get_account().get_public_address()); td.amount = adb.current_supply; - td.asset_id = currency::ffff_pkey; + td.asset_id = currency::null_pkey; std::vector destinations; destinations.push_back(td); currency::transaction result_tx = AUTO_VAL_INIT(result_tx); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 58db3195..ac4838f6 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5535,7 +5535,7 @@ assets_selection_context wallet2::get_needed_money(uint64_t fee, const std::vect amounts_map[currency::native_coin_asset_id].needed_amount = fee; for(auto& dt : dsts) { - if(dt.asset_id == currency::ffff_pkey) + if(dt.asset_id == currency::null_pkey) continue; //this destination for emmition only THROW_IF_TRUE_WALLET_EX(0 == dt.amount, error::zero_destination); @@ -6181,7 +6181,7 @@ void wallet2::prepare_tx_destinations(const assets_selection_context& needed_mon { // special case for asset minting destinations for (auto& dst : dsts) - if (dst.asset_id == currency::ffff_pkey) + if (dst.asset_id == currency::null_pkey) final_destinations.emplace_back(dst.amount, dst.addr, dst.asset_id); // if there's not ehough destinations items (i.e. outputs), split the last one diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 06dd7832..bdba4ff4 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1192,6 +1192,7 @@ namespace wallet_public END_KV_SERIALIZE_MAP() }; + struct ionic_swap_proposal_info { std::vector from; @@ -1242,12 +1243,12 @@ namespace wallet_public struct create_ionic_swap_proposal_request { uint64_t wallet_id; - ionic_swap_proposal_info proposal; + ionic_swap_proposal_info proposal_info; std::string destination_add; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(wallet_id) - KV_SERIALIZE(proposal) + KV_SERIALIZE(proposal_info) KV_SERIALIZE(destination_add) END_KV_SERIALIZE_MAP() }; @@ -1515,6 +1516,10 @@ namespace wallet_public } } + bool operator==(const asset_funds& lhs, const asset_funds& rhs) + { + return lhs.amount == rhs.amount && lhs.asset_id == rhs.asset_id; + } } // namespace wallet_rpc } // namespace tools diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index b151972e..e9b156cd 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -948,15 +948,15 @@ namespace tools return false; } - currency::transaction tx_template = AUTO_VAL_INIT(tx_template); - bool r = get_wallet()->create_ionic_swap_proposal(req.proposal, destination_addr, tx_template); + wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); + bool r = get_wallet()->create_ionic_swap_proposal(req.proposal, destination_addr, proposal); if (!r) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; er.message = "WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT - Error creating proposal"; return false; } - res.hex_raw_proposal = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(tx_template)); + res.hex_raw_proposal = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(proposal)); return true; } //------------------------------------------------------------------------------------------------------------------------------ diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 72e2e663..d8159122 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -876,17 +876,17 @@ std::string wallets_manager::get_fav_offers(const std::listget()->create_ionic_swap_proposal(proposal.proposal, dest_account, proposal); + tools::wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); + bool r = wo.w->get()->create_ionic_swap_proposal(proposal_req.proposal_info, dest_account, proposal); if (!r) { return API_RETURN_CODE_FAIL; diff --git a/tests/core_tests/hard_fork_2.cpp b/tests/core_tests/hard_fork_2.cpp index fc6a96cd..72b21bea 100644 --- a/tests/core_tests/hard_fork_2.cpp +++ b/tests/core_tests/hard_fork_2.cpp @@ -81,7 +81,7 @@ bool hard_fork_2_tx_payer_in_wallet::c1(currency::core& c, size_t ev_index, cons CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt, MK_TEST_COINS(12)), false, ""); // wallet RPC server - tools::wallet_rpc_server miner_wlt_rpc(*miner_wlt); + tools::wallet_rpc_server miner_wlt_rpc(miner_wlt); epee::json_rpc::error je; tools::wallet_rpc_server::connection_context ctx; @@ -161,7 +161,7 @@ bool hard_fork_2_tx_payer_in_wallet::c1(currency::core& c, size_t ev_index, cons bob_wlt->callback(std::make_shared()); // clear callback // Before HF2: Bob (auditable address) -> Alice with payer info requested (should NOT put tx_payer or tx_payer_old) - tools::wallet_rpc_server bob_wlt_rpc(*bob_wlt); + tools::wallet_rpc_server bob_wlt_rpc(bob_wlt); tools::wallet_public::COMMAND_RPC_TRANSFER::request req_c = AUTO_VAL_INIT(req_c); req_c.destinations.push_back(tools::wallet_public::transfer_destination{ MK_TEST_COINS(1), m_accounts[ALICE_ACC_IDX].get_public_address_str() }); req_c.fee = TESTS_DEFAULT_FEE; @@ -328,7 +328,7 @@ bool hard_fork_2_tx_receiver_in_wallet::c1(currency::core& c, size_t ev_index, c CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt, 0), false, ""); // wallet RPC server - tools::wallet_rpc_server alice_wlt_rpc(*alice_wlt); + tools::wallet_rpc_server alice_wlt_rpc(alice_wlt); epee::json_rpc::error je; tools::wallet_rpc_server::connection_context ctx; diff --git a/tests/core_tests/ionic_swap_tests.cpp b/tests/core_tests/ionic_swap_tests.cpp index c0206de7..17361503 100644 --- a/tests/core_tests/ionic_swap_tests.cpp +++ b/tests/core_tests/ionic_swap_tests.cpp @@ -31,9 +31,9 @@ bool ionic_swap_basic_test::generate(std::vector& events) cons { uint64_t ts = test_core_time::get_time(); m_accounts.resize(TOTAL_ACCS_COUNT); - account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts); - account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts); - account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate(); bob_acc.set_createtime(ts); + currency::account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts); + currency::account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts); + currency::account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate(); bob_acc.set_createtime(ts); //account_base& carol_acc = m_accounts[CAROL_ACC_IDX]; carol_acc.generate(); carol_acc.set_createtime(ts); MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts); @@ -45,7 +45,7 @@ bool ionic_swap_basic_test::generate(std::vector& events) cons return true; } -bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vector& events) +bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::vector& events) { bool r = false; std::shared_ptr miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX); @@ -58,13 +58,13 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect CHECK_AND_ASSERT_MES(!c.get_blockchain_storage().is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM), false, "ZANO_HARDFORK_04_ZARCANUM is active"); - account_base alice_acc; + currency::account_base alice_acc; alice_acc.generate(); std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, alice_acc); alice_wlt->get_account().set_createtime(0); miner_wlt->refresh(); - asset_descriptor_base adb = AUTO_VAL_INIT(adb); + currency::asset_descriptor_base adb = AUTO_VAL_INIT(adb); adb.total_max_supply = 1000000000000000000; //1M coins adb.full_name = "Test coins"; adb.ticker = "TCT"; @@ -73,17 +73,17 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect std::vector destinations(2); destinations[0].addr.push_back(miner_wlt->get_account().get_public_address()); destinations[0].amount = AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC; - destinations[0].asset_id = currency::ffff_hash; + destinations[0].asset_id = currency::null_pkey; destinations[1].addr.push_back(alice_wlt->get_account().get_public_address()); destinations[1].amount = AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC; - destinations[1].asset_id = currency::ffff_hash; + destinations[1].asset_id = currency::null_pkey; LOG_PRINT_MAGENTA("destinations[0].asset_id:" << destinations[0].asset_id, LOG_LEVEL_0); LOG_PRINT_MAGENTA("destinations[1].asset_id:" << destinations[1].asset_id, LOG_LEVEL_0); - LOG_PRINT_MAGENTA("currency::ffff_hash:" << currency::ffff_hash, LOG_LEVEL_0); + LOG_PRINT_MAGENTA("currency::null_pkey:" << currency::null_pkey, LOG_LEVEL_0); currency::transaction tx = AUTO_VAL_INIT(tx); - crypto::hash asset_id = currency::null_hash; + crypto::public_key asset_id = currency::null_pkey; miner_wlt->publish_new_asset(adb, destinations, tx, asset_id); LOG_PRINT_L0("Published new asset: " << asset_id << ", tx_id: " << currency::get_transaction_hash(tx)); @@ -94,11 +94,11 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect miner_wlt->refresh(); alice_wlt->refresh(); uint64_t mined = 0; - std::unordered_map balances; + std::unordered_map balances; miner_wlt->balance(balances, mined); auto it_asset = balances.find(asset_id); - auto it_native = balances.find(currency::null_hash); + auto it_native = balances.find(currency::native_coin_asset_id); CHECK_AND_ASSERT_MES(it_asset != balances.end() && it_native != balances.end(), false, "Failed to find needed asset in result balances"); @@ -111,7 +111,7 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect alice_wlt->balance(balances, mined); it_asset = balances.find(asset_id); - it_native = balances.find(currency::null_hash); + it_native = balances.find(currency::native_coin_asset_id); CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_native == balances.end(), false, "Failed to find needed asset in result balances"); @@ -128,11 +128,11 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect proposal_details.from.push_back(view::asset_funds{ asset_id , assets_to_exchange }); proposal_details.to.push_back(view::asset_funds{ currency::null_pkey , native_tokens_to_exchange }); - currency::transaction tx_template = AUTO_VAL_INIT(tx_template); - alice_wlt->create_ionic_swap_proposal(proposal_details, miner_wlt->get_account().get_public_address(), tx_template); + tools::wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); + alice_wlt->create_ionic_swap_proposal(proposal_details, miner_wlt->get_account().get_public_address(), proposal); view::ionic_swap_proposal_info proposal_decoded_info; - miner_wlt->get_ionic_swap_proposal_info(tx_template, proposal_decoded_info); + miner_wlt->get_ionic_swap_proposal_info(proposal, proposal_decoded_info); //Validate proposal if (proposal_decoded_info.from != proposal_details.from || proposal_decoded_info.to != proposal_details.to) @@ -141,7 +141,7 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect } currency::transaction res_tx = AUTO_VAL_INIT(res_tx); - r = miner_wlt->accept_ionic_swap_proposal(tx_template, res_tx); + r = miner_wlt->accept_ionic_swap_proposal(proposal, res_tx); CHECK_AND_ASSERT_MES(r, false, "Failed to accept ionic proposal"); r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); @@ -155,7 +155,7 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect alice_wlt->balance(balances, mined); it_asset = balances.find(asset_id); - it_native = balances.find(currency::null_hash); + it_native = balances.find(currency::native_coin_asset_id); CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_native->second.total == native_tokens_to_exchange, false, "Failed to find needed asset in result balances"); diff --git a/tests/core_tests/isolate_auditable_and_proof.cpp b/tests/core_tests/isolate_auditable_and_proof.cpp index 2bf086f5..d079a022 100644 --- a/tests/core_tests/isolate_auditable_and_proof.cpp +++ b/tests/core_tests/isolate_auditable_and_proof.cpp @@ -111,7 +111,7 @@ bool isolate_auditable_and_proof::c1(currency::core& c, size_t ev_index, const s epee::json_rpc::error je; tools::wallet_rpc_server::connection_context ctx; - tools::wallet_rpc_server miner_wlt_rpc(*auditable_test_instance); + tools::wallet_rpc_server miner_wlt_rpc(auditable_test_instance); tools::wallet_public::COMMAND_RPC_GET_RECENT_TXS_AND_INFO::request req = AUTO_VAL_INIT(req); tools::wallet_public::COMMAND_RPC_GET_RECENT_TXS_AND_INFO::response res = AUTO_VAL_INIT(res); req.count = 100; diff --git a/tests/core_tests/multiassets_test.cpp b/tests/core_tests/multiassets_test.cpp index 06beb95a..64b861d0 100644 --- a/tests/core_tests/multiassets_test.cpp +++ b/tests/core_tests/multiassets_test.cpp @@ -70,14 +70,14 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v std::vector destinations(2); destinations[0].addr.push_back(miner_wlt->get_account().get_public_address()); destinations[0].amount = AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC; - destinations[0].asset_id = currency::ffff_pkey; + destinations[0].asset_id = currency::null_pkey; destinations[1].addr.push_back(alice_wlt->get_account().get_public_address()); destinations[1].amount = AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC; - destinations[1].asset_id = currency::ffff_pkey; + destinations[1].asset_id = currency::null_pkey; LOG_PRINT_MAGENTA("destinations[0].asset_id:" << destinations[0].asset_id, LOG_LEVEL_0); LOG_PRINT_MAGENTA("destinations[1].asset_id:" << destinations[1].asset_id, LOG_LEVEL_0); - LOG_PRINT_MAGENTA("currency::ffff_pkey: " << currency::ffff_pkey, LOG_LEVEL_0); + LOG_PRINT_MAGENTA("currency::null_pkey: " << currency::null_pkey, LOG_LEVEL_0); currency::transaction tx = AUTO_VAL_INIT(tx); crypto::public_key asset_id = currency::null_pkey; diff --git a/tests/core_tests/multisig_wallet_tests.cpp b/tests/core_tests/multisig_wallet_tests.cpp index ec2abfaa..acf4d959 100644 --- a/tests/core_tests/multisig_wallet_tests.cpp +++ b/tests/core_tests/multisig_wallet_tests.cpp @@ -66,8 +66,9 @@ void transfer_multisig(tools::wallet2& w, ftp.tx_version = tx_version; - - w.prepare_transaction(ctp, ftp, tx); + tools::mode_separate_context emode_separate = AUTO_VAL_INIT(emode_separate); + emode_separate.tx_for_mode_separate = tx; + w.prepare_transaction(ctp, ftp, emode_separate); crypto::secret_key sk = AUTO_VAL_INIT(sk); w.finalize_transaction(ftp, tx, sk, false); diff --git a/tests/core_tests/wallet_rpc_tests.cpp b/tests/core_tests/wallet_rpc_tests.cpp index ec867687..4db60da5 100644 --- a/tests/core_tests/wallet_rpc_tests.cpp +++ b/tests/core_tests/wallet_rpc_tests.cpp @@ -28,7 +28,7 @@ bool wallet_rpc_integrated_address::generate(std::vector& even CREATE_TEST_WALLET(miner_wlt, miner_acc, blk_0); // wallet RPC server - tools::wallet_rpc_server miner_wlt_rpc(*miner_wlt); + tools::wallet_rpc_server miner_wlt_rpc(miner_wlt); epee::json_rpc::error je; tools::wallet_rpc_server::connection_context ctx; @@ -110,7 +110,7 @@ bool wallet_rpc_integrated_address_transfer::c1(currency::core& c, size_t ev_ind std::string alice_integrated_address = get_account_address_and_payment_id_as_str(m_accounts[ALICE_ACC_IDX].get_public_address(), payment_id); // wallet RPC server - tools::wallet_rpc_server miner_wlt_rpc(*miner_wlt); + tools::wallet_rpc_server miner_wlt_rpc(miner_wlt); epee::json_rpc::error je; tools::wallet_rpc_server::connection_context ctx; @@ -226,7 +226,7 @@ bool wallet_rpc_transfer::c1(currency::core& c, size_t ev_index, const std::vect miner_wlt->refresh(); // wallet RPC server - tools::wallet_rpc_server miner_wlt_rpc(*miner_wlt); + tools::wallet_rpc_server miner_wlt_rpc(miner_wlt); epee::json_rpc::error je; tools::wallet_rpc_server::connection_context ctx; From aa8d3207a438e940d5af0f34c66c8cda3aee1733 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 18 Apr 2023 20:07:33 +0200 Subject: [PATCH 29/34] minor fixes over TX_FLAG_SIGNATURE_MODE_SEPARATE --- src/currency_core/blockchain_storage.cpp | 32 ++++++++------ src/currency_core/currency_format_utils.cpp | 3 +- src/currency_core/currency_format_utils.h | 47 ++++++++++++++++----- src/wallet/wallet_public_structs_defs.h | 2 +- tests/core_tests/chaingen_main.cpp | 1 + tests/core_tests/chaingen_tests_list.h | 1 + tests/core_tests/ionic_swap_tests.cpp | 17 +++++--- 7 files changed, 70 insertions(+), 33 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 46fc7e06..836474ac 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -5175,27 +5175,29 @@ bool blockchain_storage::fill_tx_rpc_details(tx_rpc_extended_info& tei, const tr //------------------------------------------------------------------ bool blockchain_storage::fill_tx_rpc_inputs(tx_rpc_extended_info& tei, const transaction& tx) const { + //handle inputs for (auto in : tx.vin) { tei.ins.push_back(tx_in_rpc_entry()); + tx_in_rpc_entry& entry_to_fill = tei.ins.back(); if (in.type() == typeid(txin_gen)) { - tei.ins.back().amount = 0; + entry_to_fill.amount = 0; } - else if (in.type() == typeid(txin_to_key) || in.type() == typeid(txin_htlc)) + else if (in.type() == typeid(txin_to_key) || in.type() == typeid(txin_htlc) || in.type() == typeid(txin_zc_input)) { //TODO: add htlc info - const txin_to_key& tk = get_to_key_input_from_txin_v(in); - tei.ins.back().amount = tk.amount; - tei.ins.back().kimage_or_ms_id = epee::string_tools::pod_to_hex(tk.k_image); - std::vector absolute_offsets = relative_output_offsets_to_absolute(tk.key_offsets); + entry_to_fill.amount = get_amount_from_variant(in); + entry_to_fill.kimage_or_ms_id = epee::string_tools::pod_to_hex(get_key_image_from_txin_v(in)); + const std::vector& key_offsets = get_key_offsets_from_txin_v(in); + std::vector absolute_offsets = relative_output_offsets_to_absolute(key_offsets); for (auto& ao : absolute_offsets) { - tei.ins.back().global_indexes.push_back(0); + entry_to_fill.global_indexes.push_back(0); if (ao.type() == typeid(uint64_t)) { - tei.ins.back().global_indexes.back() = boost::get(ao); + entry_to_fill.global_indexes.back() = boost::get(ao); } else if (ao.type() == typeid(ref_by_id)) { @@ -5211,17 +5213,21 @@ bool blockchain_storage::fill_tx_rpc_inputs(tx_rpc_extended_info& tei, const tra } if (in.type() == typeid(txin_htlc)) { - tei.ins.back().htlc_origin = epee::string_tools::buff_to_hex_nodelimer(boost::get(in).hltc_origin); + entry_to_fill.htlc_origin = epee::string_tools::buff_to_hex_nodelimer(boost::get(in).hltc_origin); } //tk.etc_details -> visualize it may be later } else if (in.type() == typeid(txin_multisig)) { txin_multisig& tms = boost::get(in); - tei.ins.back().amount = tms.amount; - tei.ins.back().kimage_or_ms_id = epee::string_tools::pod_to_hex(tms.multisig_out_id); - if (tx.signatures.size() >= tei.ins.size()) - tei.ins.back().multisig_count = tx.signatures[tei.ins.size() - 1].size(); + entry_to_fill.amount = tms.amount; + entry_to_fill.kimage_or_ms_id = epee::string_tools::pod_to_hex(tms.multisig_out_id); + if (tx.signatures.size() >= tei.ins.size() && + tx.signatures[tei.ins.size() - 1].type() == typeid(NLSAG_sig)) + { + entry_to_fill.multisig_count = boost::get(tx.signatures[tei.ins.size() - 1]).s.size(); + } + } } return true; diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index cfe34b18..58f3eb27 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -2383,7 +2383,8 @@ namespace currency // // proofs (transaction-wise, not pre-input) // - if (tx.version > TRANSACTION_VERSION_PRE_HF4) + if (tx.version > TRANSACTION_VERSION_PRE_HF4 && + (append_mode || (flags & TX_FLAG_SIGNATURE_MODE_SEPARATE) == 0)) { // asset surjection proof currency::zc_asset_surjection_proof asp{}; diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 4b9008a4..5179e0f2 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -919,9 +919,9 @@ namespace currency pfinalbuff = &deflated_buff; } if (ee.service_id == BC_PAYMENT_ID_SERVICE_ID || ee.service_id == BC_OFFERS_SERVICE_ID) - tv.datails_view = *pfinalbuff; + tv.details_view = *pfinalbuff; else - tv.datails_view = "BINARY DATA"; + tv.details_view = "BINARY DATA"; } return true; } @@ -929,7 +929,7 @@ namespace currency { tv.type = "crypto_checksum"; tv.short_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash); - tv.datails_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash) + "\n" + tv.details_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash) + "\n" + "encrypted_key_derivation: " + epee::string_tools::pod_to_hex(ee.encrypted_key_derivation); return true; @@ -990,14 +990,14 @@ namespace currency { tv.type = "attachment_info"; tv.short_view = std::to_string(ee.sz) + " bytes"; - tv.datails_view = currency::obj_to_json_str(ee); + tv.details_view = currency::obj_to_json_str(ee); return true; } bool operator()(const extra_alias_entry& ee) { tv.type = "alias_info"; tv.short_view = ee.m_alias + "-->" + get_account_address_as_str(ee.m_address); - tv.datails_view = currency::obj_to_json_str(ee); + tv.details_view = currency::obj_to_json_str(ee); return true; } @@ -1009,7 +1009,7 @@ namespace currency { tv.type = "user_data"; tv.short_view = std::to_string(ee.buff.size()) + " bytes"; - tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee.buff); + tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee.buff); return true; } @@ -1018,7 +1018,7 @@ namespace currency tv.type = "extra_padding"; tv.short_view = std::to_string(ee.buff.size()) + " bytes"; if (!ee.buff.empty()) - tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast(&ee.buff[0]), ee.buff.size())); + tv.details_view = epee::string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast(&ee.buff[0]), ee.buff.size())); return true; } @@ -1026,7 +1026,7 @@ namespace currency { tv.type = "comment"; tv.short_view = std::to_string(ee.comment.size()) + " bytes(encrypted)"; - tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee.comment); + tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee.comment); return true; } @@ -1064,7 +1064,7 @@ namespace currency { tv.type = "derivation_hint"; tv.short_view = std::to_string(ee.msg.size()) + " bytes"; - tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee.msg); + tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee.msg); return true; } @@ -1072,7 +1072,7 @@ namespace currency { tv.type = "string"; tv.short_view = std::to_string(ee.size()) + " bytes"; - tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee); + tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee); return true; } @@ -1080,10 +1080,35 @@ namespace currency { tv.type = "FLAGS16"; tv.short_view = epee::string_tools::pod_to_hex(dh); - tv.datails_view = epee::string_tools::pod_to_hex(dh); + tv.details_view = epee::string_tools::pod_to_hex(dh); return true; } + bool operator()(const zarcanum_tx_data_v1& ztxd) + { + tv.type = "zarcanum_tx_data_v1"; + tv.short_view = "fee = " + print_money_brief(ztxd.fee); + tv.details_view = tv.short_view; + return true; + } + bool operator()(const zc_outs_range_proof& rp) + { + tv.type = "zc_outs_range_proof"; + // TODO @#@# + //tv.short_view = "outputs_count = " + std::to_string(rp.outputs_count); + return true; + } + bool operator()(const zc_balance_proof& bp) + { + tv.type = "zc_balance_proof"; + return true; + } + template + bool operator()(const t_type& t_t) + { + tv.type = typeid(t_t).name(); + return true; + } }; //------------------------------------------------------------------ diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index bdba4ff4..411413cf 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1516,7 +1516,7 @@ namespace wallet_public } } - bool operator==(const asset_funds& lhs, const asset_funds& rhs) + inline bool operator==(const asset_funds& lhs, const asset_funds& rhs) { return lhs.amount == rhs.amount && lhs.asset_id == rhs.asset_id; } diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index eda3300f..7e0c0169 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1085,6 +1085,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(zarcanum_basic_test); GENERATE_AND_PLAY(multiassets_basic_test); + GENERATE_AND_PLAY(ionic_swap_basic_test); GENERATE_AND_PLAY(zarcanum_test_n_inputs_validation); GENERATE_AND_PLAY(zarcanum_gen_time_balance); GENERATE_AND_PLAY(zarcanum_txs_with_big_shuffled_decoy_set_shuffled); diff --git a/tests/core_tests/chaingen_tests_list.h b/tests/core_tests/chaingen_tests_list.h index cf3fbb7d..a44af329 100644 --- a/tests/core_tests/chaingen_tests_list.h +++ b/tests/core_tests/chaingen_tests_list.h @@ -42,3 +42,4 @@ #include "isolate_auditable_and_proof.h" #include "zarcanum_test.h" #include "multiassets_test.h" +#include "ionic_swap_tests.h" diff --git a/tests/core_tests/ionic_swap_tests.cpp b/tests/core_tests/ionic_swap_tests.cpp index 17361503..c7aa91a6 100644 --- a/tests/core_tests/ionic_swap_tests.cpp +++ b/tests/core_tests/ionic_swap_tests.cpp @@ -55,7 +55,7 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve //std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX); // check passing over the hardfork - CHECK_AND_ASSERT_MES(!c.get_blockchain_storage().is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM), false, "ZANO_HARDFORK_04_ZARCANUM is active"); + CHECK_AND_ASSERT_MES(c.get_blockchain_storage().is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM), false, "ZANO_HARDFORK_04_ZARCANUM is active"); currency::account_base alice_acc; @@ -87,6 +87,9 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve miner_wlt->publish_new_asset(adb, destinations, tx, asset_id); LOG_PRINT_L0("Published new asset: " << asset_id << ", tx_id: " << currency::get_transaction_hash(tx)); + currency::transaction res_tx = AUTO_VAL_INIT(res_tx); + miner_wlt->transfer(COIN, alice_wlt->get_account().get_public_address(), res_tx); + r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); @@ -103,7 +106,7 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve CHECK_AND_ASSERT_MES(it_asset != balances.end() && it_native != balances.end(), false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances"); - CHECK_AND_ASSERT_MES(it_native->second.total == uint64_t(17517226)*COIN, false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_native->second.total == uint64_t(17517226)*COIN - COIN, false, "Failed to find needed asset in result balances"); uint64_t mined_balance = it_native->second.total; @@ -113,8 +116,8 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve it_asset = balances.find(asset_id); it_native = balances.find(currency::native_coin_asset_id); - CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances"); - CHECK_AND_ASSERT_MES(it_native == balances.end(), false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_asset != balances.end() && it_native != balances.end(), false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_native->second.total == COIN, false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances"); const uint64_t assets_to_exchange = 10 * COIN; @@ -126,7 +129,7 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve proposal_details.fee = TESTS_DEFAULT_FEE; proposal_details.mixins = 10; proposal_details.from.push_back(view::asset_funds{ asset_id , assets_to_exchange }); - proposal_details.to.push_back(view::asset_funds{ currency::null_pkey , native_tokens_to_exchange }); + proposal_details.to.push_back(view::asset_funds{ currency::native_coin_asset_id , native_tokens_to_exchange }); tools::wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); alice_wlt->create_ionic_swap_proposal(proposal_details, miner_wlt->get_account().get_public_address(), proposal); @@ -140,8 +143,8 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve CHECK_AND_ASSERT_MES(false, false, "proposal actual and proposals decoded mismatch"); } - currency::transaction res_tx = AUTO_VAL_INIT(res_tx); - r = miner_wlt->accept_ionic_swap_proposal(proposal, res_tx); + currency::transaction res_tx2 = AUTO_VAL_INIT(res_tx2); + r = miner_wlt->accept_ionic_swap_proposal(proposal, res_tx2); CHECK_AND_ASSERT_MES(r, false, "Failed to accept ionic proposal"); r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); From 4acb2bae032494fb2fffefa63a56b71786a73462 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 20 Apr 2023 22:08:20 +0200 Subject: [PATCH 30/34] multiple fixes over ionic_swap proposal --- src/currency_core/currency_format_utils.cpp | 30 ++-- src/currency_core/currency_format_utils.h | 3 + .../currency_format_utils_transactions.h | 15 +- src/wallet/wallet2.cpp | 147 +++++++++++++----- src/wallet/wallet_public_structs_defs.h | 12 +- tests/core_tests/ionic_swap_tests.cpp | 27 +++- tests/core_tests/ionic_swap_tests.h | 5 +- 7 files changed, 175 insertions(+), 64 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 58f3eb27..b06448cd 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -406,7 +406,7 @@ namespace currency tx_destination_entry de = AUTO_VAL_INIT(de); de.addr.push_back(miner_address); de.amount = a; - de.explicit_native_asset_id = true; // don't use asset id blinding as it's obvious which asset it is + de.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id; // don't use asset id blinding as it's obvious which asset it is if (pe.stake_unlock_time && pe.stake_unlock_time > height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW) { //this means that block is creating after hardfork_1 and unlock_time is needed to set for every destination separately @@ -421,7 +421,7 @@ namespace currency if (pe.stake_unlock_time && pe.stake_unlock_time > height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW) stake_lock_time = pe.stake_unlock_time; destinations.push_back(tx_destination_entry(pe.amount, stakeholder_address, stake_lock_time)); - destinations.back().explicit_native_asset_id = true; // don't use asset id blinding as it's obvious which asset it is + destinations.back().flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id; // don't use asset id blinding as it's obvious which asset it is } CHECK_AND_ASSERT_MES(destinations.size() <= CURRENCY_TX_MAX_ALLOWED_OUTS || height == 0, false, "Too many outs (" << destinations.size() << ")! Miner tx can't be constructed."); @@ -1143,8 +1143,8 @@ namespace currency blinded_asset_id = crypto::point_t(de.asset_id) + asset_blinding_mask * crypto::c_point_X; out.blinded_asset_id = (crypto::c_scalar_1div8 * blinded_asset_id).to_public_key(); // T = 1/8 * (H_asset + s * X) - CHECK_AND_ASSERT_MES(!de.explicit_native_asset_id || de.asset_id == currency::native_coin_asset_id, false, "explicit_native_asset_id may be used only with native asset id"); - asset_blinding_mask = de.explicit_native_asset_id ? 0 : crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_ASSET_BLINDING_MASK, h); // f = Hs(domain_sep, d, i) + CHECK_AND_ASSERT_MES(!de.flags & tx_destination_entry_flags::tdef_explicit_native_asset_id || de.asset_id == currency::native_coin_asset_id, false, "explicit_native_asset_id may be used only with native asset id"); + asset_blinding_mask = de.flags & tx_destination_entry_flags::tdef_explicit_native_asset_id ? 0 : crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_ASSET_BLINDING_MASK, h); // f = Hs(domain_sep, d, i) amount_commitment = de.amount * blinded_asset_id + amount_blinding_mask * crypto::c_point_G; out.amount_commitment = (crypto::c_scalar_1div8 * amount_commitment).to_public_key(); // E = 1/8 * e * T + 1/8 * y * G @@ -1163,8 +1163,8 @@ namespace currency crypto::scalar_t amount_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_AMOUNT_MASK, h); out.encrypted_amount = de.amount ^ amount_mask.m_u64[0]; - CHECK_AND_ASSERT_MES(!de.explicit_native_asset_id || de.asset_id == currency::native_coin_asset_id, false, "explicit_native_asset_id may be used only with native asset id"); - asset_blinding_mask = de.explicit_native_asset_id ? 0 : crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_ASSET_BLINDING_MASK, h); // f = Hs(domain_sep, d, i) + CHECK_AND_ASSERT_MES(!de.flags & tx_destination_entry_flags::tdef_explicit_native_asset_id || de.asset_id == currency::native_coin_asset_id, false, "explicit_native_asset_id may be used only with native asset id"); + asset_blinding_mask = de.flags & tx_destination_entry_flags::tdef_explicit_native_asset_id ? 0 : crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_ASSET_BLINDING_MASK, h); // f = Hs(domain_sep, d, i) blinded_asset_id = crypto::point_t(de.asset_id) + asset_blinding_mask * crypto::c_point_X; out.blinded_asset_id = (crypto::c_scalar_1div8 * blinded_asset_id).to_public_key(); // T = 1/8 * (H_asset + s * X) @@ -2271,7 +2271,7 @@ namespace currency { tx_destination_entry& dst_entr = shuffled_dsts[j]; if (all_inputs_are_obviously_native_coins && gen_context.ao_asset_id == currency::null_pkey) - dst_entr.explicit_native_asset_id = true; // all inputs are obviously native coins -- all outputs must have explicit asset ids (unless there's an asset emission) + dst_entr.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id; // all inputs are obviously native coins -- all outputs must have explicit asset ids (unless there's an asset emission) CHECK_AND_ASSERT_MES(dst_entr.amount > 0, false, "Destination with wrong amount: " << dst_entr.amount); // <<-- TODO @#@# consider removing this check r = construct_tx_out(dst_entr, txkey.sec, output_index, tx, deriv_cache, sender_account_keys, @@ -2317,8 +2317,16 @@ namespace currency std::sort(tx.vin.begin() + input_starter_index, tx.vin.end(), less_txin_v); // add explicit fee info - r = add_tx_fee_amount_to_extra(tx, native_coins_input_sum - native_coins_output_sum); - CHECK_AND_ASSERT_MES(r, false, "add_tx_fee_amount_to_extra failed"); + uint64_t fee_to_declare = native_coins_input_sum - native_coins_output_sum; + if (flags & TX_FLAG_SIGNATURE_MODE_SEPARATE) + { + fee_to_declare = ftp.mode_separate_fee; + } + if (fee_to_declare) + { + r = add_tx_fee_amount_to_extra(tx, fee_to_declare); + CHECK_AND_ASSERT_MES(r, false, "add_tx_fee_amount_to_extra failed"); + } } // attachments container should be sealed by now @@ -2357,10 +2365,9 @@ namespace currency for (size_t i_ = 0; i_ != sources.size(); i_++) { size_t i_mapped = inputs_mapping[i_]; - const tx_source_entry& source_entry = sources[i_mapped]; crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, i_ + input_starter_index, tx_prefix_hash); - CHECK_AND_ASSERT_MES(tx_hash_for_signature != null_hash, false, "prepare_prefix_hash_for_sign failed"); + CHECK_AND_ASSERT_MES(tx_hash_for_signature != null_hash, false, "prepare_prefix_hash_for_sign failed"); std::stringstream ss_ring_s; if (source_entry.is_zc()) @@ -2369,6 +2376,7 @@ namespace currency // blinding_masks_sum is supposed to be sum(mask of all tx output) - sum(masks of all pseudo out commitments) r = generate_ZC_sig(tx_hash_for_signature, i_ + input_starter_index, source_entry, in_contexts[i_mapped], sender_account_keys, flags, gen_context, tx, i_ + 1 == sources.size()); CHECK_AND_ASSERT_MES(r, false, "generate_ZC_sigs failed"); + gen_context.input_amounts[i_ + input_starter_index] = source_entry.amount; } else { diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 5179e0f2..195e1cb3 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -142,6 +142,7 @@ namespace currency struct finalize_tx_param { + uint64_t unlock_time; std::vector extra; std::vector attachments; @@ -156,6 +157,7 @@ namespace currency uint64_t expiration_time; crypto::public_key spend_pub_key; // only for validations uint64_t tx_version; + uint64_t mode_separate_fee = 0; tx_generation_context gen_context{}; // solely for consolidated txs @@ -174,6 +176,7 @@ namespace currency FIELD(expiration_time) FIELD(spend_pub_key) FIELD(tx_version) + FIELD(mode_separate_fee) if (flags & TX_FLAG_SIGNATURE_MODE_SEPARATE) FIELD(gen_context); END_SERIALIZE() diff --git a/src/currency_core/currency_format_utils_transactions.h b/src/currency_core/currency_format_utils_transactions.h index 2137054b..24600d5f 100644 --- a/src/currency_core/currency_format_utils_transactions.h +++ b/src/currency_core/currency_format_utils_transactions.h @@ -94,6 +94,13 @@ namespace currency }; + enum tx_destination_entry_flags + { + tdef_none = 0, + tdef_explicit_native_asset_id = 0x0001, + tdef_explicit_amount_to_provide = 0x0002 + }; + struct tx_destination_entry { uint64_t amount = 0; // money @@ -103,7 +110,7 @@ namespace currency uint64_t unlock_time = 0; destination_option_htlc_out htlc_options; // htlc options crypto::public_key asset_id = currency::native_coin_asset_id; // not blinded, not premultiplied - bool explicit_native_asset_id = false; + uint64_t flags = 0; // set of flags (see tx_destination_entry_flags) tx_destination_entry() = default; tx_destination_entry(uint64_t a, const account_public_address& ad) : amount(a), addr(1, ad) {} @@ -123,7 +130,7 @@ namespace currency FIELD(unlock_time) FIELD(htlc_options) FIELD(asset_id) - FIELD(explicit_native_asset_id) + FIELD(flags) END_SERIALIZE() }; //--------------------------------------------------------------- @@ -218,6 +225,7 @@ namespace currency asset_id_blinding_masks.resize(outs_count); amounts.resize(outs_count); amount_blinding_masks.resize(outs_count); + input_amounts.resize(zc_ins_count); } // TODO @#@# reconsider this check -- sowle @@ -245,6 +253,7 @@ namespace currency std::vector pseudo_outs_blinded_asset_ids; // generate_asset_surjection_proof crypto::scalar_vec_t pseudo_outs_plus_real_out_blinding_masks; // r_pi + r'_j // generate_asset_surjection_proof std::vector real_zc_ins_asset_ids; // H_i // generate_asset_surjection_proof + std::vector input_amounts; // all inputs, including non ZC // common data: inputs crypto::point_t pseudo_out_amount_commitments_sum = crypto::c_point_0; // generate_tx_balance_proof generate_ZC_sig @@ -273,6 +282,7 @@ namespace currency KV_SERIALIZE_CONTAINER_POD_AS_BLOB(pseudo_outs_blinded_asset_ids) KV_SERIALIZE_CONTAINER_POD_AS_BLOB(pseudo_outs_plus_real_out_blinding_masks) KV_SERIALIZE_CONTAINER_POD_AS_BLOB(real_zc_ins_asset_ids) + KV_SERIALIZE(input_amounts) KV_SERIALIZE_POD_AS_HEX_STRING(pseudo_out_amount_commitments_sum) KV_SERIALIZE_POD_AS_HEX_STRING(pseudo_out_amount_blinding_masks_sum) KV_SERIALIZE_POD_AS_HEX_STRING(real_in_asset_id_blinding_mask_x_amount_sum) @@ -298,6 +308,7 @@ namespace currency FIELD(pseudo_outs_blinded_asset_ids) FIELD((std::vector&)(pseudo_outs_plus_real_out_blinding_masks)) FIELD(real_zc_ins_asset_ids) + FIELD(input_amounts) FIELD(pseudo_out_amount_commitments_sum) FIELD(pseudo_out_amount_blinding_masks_sum) FIELD(real_in_asset_id_blinding_mask_x_amount_sum) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ac4838f6..06eac0ae 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5011,34 +5011,38 @@ bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal construct_tx_param ctp = get_default_construct_tx_param(); ctp.fake_outputs_count = proposal_detais.mixins; - ctp.fee = 0; + ctp.fee = proposal_detais.fee_paid_by_a; ctp.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; ctp.mark_tx_as_complete = false; + ctp.crypt_address = destination_addr; etc_tx_details_expiration_time t = AUTO_VAL_INIT(t); t.v = proposal_detais.expiration_time; ctp.extra.push_back(t); - ctp.dsts.resize(proposal_detais.from.size() + proposal_detais.to.size()); + ctp.dsts.resize(proposal_detais.to_bob.size() + proposal_detais.to_alice.size()); size_t i = 0; // Here is an proposed for exchange funds - for (; i != proposal_detais.from.size(); i++) + for (; i != proposal_detais.to_bob.size(); i++) { - ctp.dsts[i].amount = proposal_detais.from[i].amount; - ctp.dsts[i].amount_to_provide = proposal_detais.from[i].amount; + ctp.dsts[i].amount = proposal_detais.to_bob[i].amount; + ctp.dsts[i].amount_to_provide = proposal_detais.to_bob[i].amount; + ctp.dsts[i].flags |= tx_destination_entry_flags::tdef_explicit_amount_to_provide; ctp.dsts[i].addr.push_back(destination_addr); - ctp.dsts[i].asset_id = proposal_detais.from[i].asset_id; + ctp.dsts[i].asset_id = proposal_detais.to_bob[i].asset_id; } // Here is an expected in return funds - for (size_t j = 0; j != proposal_detais.to.size(); j++, i++) + for (size_t j = 0; j != proposal_detais.to_alice.size(); j++, i++) { - ctp.dsts[i].amount = proposal_detais.to[j].amount; + ctp.dsts[i].amount = proposal_detais.to_alice[j].amount; ctp.dsts[i].amount_to_provide = 0; + ctp.dsts[i].flags |= tx_destination_entry_flags::tdef_explicit_amount_to_provide; ctp.dsts[i].addr.push_back(m_account.get_public_address()); - ctp.dsts[i].asset_id = proposal_detais.to[j].asset_id; + ctp.dsts[i].asset_id = proposal_detais.to_alice[j].asset_id; } currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); + ftp.mode_separate_fee = ctp.fee; ftp.tx_version = this->get_current_tx_version(); prepare_transaction(ctp, ftp); @@ -5053,7 +5057,7 @@ bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal ispc.gen_context = finalize_result.ftp.gen_context; ispc.one_time_skey = finalize_result.one_time_key; std::string proposal_context_blob = t_serializable_object_to_blob(ispc); - proposal.encrypted_context = crypto::chacha_crypt(proposal_context_blob, finalize_result.derivation); + proposal.encrypted_context = crypto::chacha_crypt(static_cast(proposal_context_blob), finalize_result.derivation); return true; } //---------------------------------------------------------------------------------------------------- @@ -5093,53 +5097,115 @@ bool wallet2::get_ionic_swap_proposal_info(const wallet_public::ionic_swap_propo r = validate_tx_output_details_againt_tx_generation_context(tx, ionic_context.gen_context, ionic_context.one_time_skey); THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "Failed to validate decrypted ionic_context"); - std::unordered_map ammounts_to; - std::unordered_map ammounts_from; - std::vector third_party_outs; - size_t i = 0; + std::unordered_map amounts_provided_by_a; + + std::unordered_map ammounts_to_a; //amounts to Alice (the one who created proposal), should be NOT funded + std::unordered_map ammounts_to_b; //amounts to Bob (the one who received proposal), should BE funded + std::vector bob_outs; + bob_outs.resize(proposal.tx_template.vout.size()); + for (const auto& o : outs) { - THROW_IF_FALSE_WALLET_INT_ERR_EX(ionic_context.gen_context.asset_ids.size() > i, "Tx gen context has mismatch with tx(asset_ids) "); - THROW_IF_FALSE_WALLET_INT_ERR_EX(ionic_context.gen_context.asset_ids[i].to_public_key() == o.asset_id, "Tx gen context has mismatch with tx(asset_id != asset_id) "); - THROW_IF_FALSE_WALLET_INT_ERR_EX(ionic_context.gen_context.amounts[i].m_u64[0] == o.amount, "Tx gen context has mismatch with tx(amount != amount)"); + THROW_IF_FALSE_WALLET_INT_ERR_EX(ionic_context.gen_context.asset_ids.size() > o.index, "Tx gen context has mismatch with tx(asset_ids) "); + THROW_IF_FALSE_WALLET_INT_ERR_EX(ionic_context.gen_context.asset_ids[o.index].to_public_key() == o.asset_id, "Tx gen context has mismatch with tx(asset_id != asset_id) "); + THROW_IF_FALSE_WALLET_INT_ERR_EX(ionic_context.gen_context.amounts[o.index].m_u64[0] == o.amount, "Tx gen context has mismatch with tx(amount != amount)"); - ammounts_to[o.asset_id] += o.amount; - third_party_outs[i] = false; - i++; + ammounts_to_b[o.asset_id] += o.amount; + bob_outs[o.index] = true; } - + size_t i = 0; //validate outputs against decrypted tx generation context for (i = 0; i != tx.vout.size(); i++) { - if (!third_party_outs[i]) + if (bob_outs[i]) { continue; } crypto::public_key asset_id = ionic_context.gen_context.asset_ids[i].to_public_key(); uint64_t amount = ionic_context.gen_context.amounts[i].m_u64[0]; - ammounts_from[asset_id] += amount; + ammounts_to_a[asset_id] += amount; } - for (const auto& a : ammounts_to) - proposal_info.to.push_back(view::asset_funds{ a.first, a.second }); - - for (const auto& a : ammounts_from) - proposal_info.from.push_back(view::asset_funds{ a.first, a.second }); - - for (const auto&in : tx.vin) + //read amounts already provided by third party + size_t zc_current_index = 0; //some inputs might be old ones, so it's asset id assumed as native and there is no entry for it in real_zc_ins_asset_ids + //THROW_IF_FALSE_WALLET_INT_ERR_EX(ionic_context.gen_context.input_amounts.size() == tx.vin.size(), "Tx gen context has mismatch with tx(amount != amount)"); + for (i = 0; i != tx.vin.size(); i++) { - if (in.type() != typeid(currency::txin_zc_input)) + size_t mx = 0; + uint64_t amount = 0; + crypto::public_key in_asset_id = currency::native_coin_asset_id; + if (tx.vin[i].type() == typeid(txin_zc_input)) + { + in_asset_id = ionic_context.gen_context.real_zc_ins_asset_ids[zc_current_index].to_public_key(); + amount = ionic_context.gen_context.input_amounts[zc_current_index]; + zc_current_index++; + mx = boost::get(tx.vin[i]).key_offsets.size() - 1; + } + else if (tx.vin[i].type() == typeid(txin_to_key)) + { + amount = boost::get(tx.vin[i]).amount; + mx = boost::get(tx.vin[i]).key_offsets.size() - 1; + } + else + { + WLT_LOG_RED("Unexpected type of input in ionic_swap tx: " << tx.vin[i].type().name(), LOG_LEVEL_0); return false; - size_t mx = boost::get(in).key_offsets.size() - 1; + } + amounts_provided_by_a[in_asset_id] += amount; + if (proposal_info.mixins == 0 || proposal_info.mixins > mx) { proposal_info.mixins = mx; } + } - proposal_info.fee = currency::get_tx_fee(tx); + //this might be 0, if Alice don't want to pay fee herself + proposal_info.fee_paid_by_a = currency::get_tx_fee(tx); + if (proposal_info.fee_paid_by_a) + { + THROW_IF_FALSE_WALLET_INT_ERR_EX(amounts_provided_by_a[currency::native_coin_asset_id] >= proposal_info.fee_paid_by_a, "Fee mentioned as specified but not provided by A"); + amounts_provided_by_a[currency::native_coin_asset_id] -= proposal_info.fee_paid_by_a; + } + + //proposal_info.fee = currency::get_tx_fee(tx); + //need to make sure that funds for Bob properly funded + for (const auto& a : ammounts_to_b) + { + uint64_t amount_sent_back_to_alice = ammounts_to_a[a.first]; + + if (amounts_provided_by_a[a.first] < (a.second + amount_sent_back_to_alice) ) + { + WLT_LOG_RED("Amount[" << a.first << "] provided by Alice(" << amounts_provided_by_a[a.first] << ") is less then transfered to Bob(" << a.second <<")", LOG_LEVEL_0); + return false; + } + amounts_provided_by_a[a.first] -= (amount_sent_back_to_alice + a.second); + proposal_info.to_bob.push_back(view::asset_funds{ a.first, a.second }); + //clean accounted assets + ammounts_to_a.erase(ammounts_to_a.find(a.first)); + if (amounts_provided_by_a[a.first] > 0) + { + WLT_LOG_RED("Amount[" << a.first << "] provided by Alice has unused leftovers: " << amounts_provided_by_a[a.first], LOG_LEVEL_0); + return false; + } + } + + //need to see what Alice actually expect in return + for (const auto& a : ammounts_to_a) + { + //now amount provided by A should be less or equal to what we have in a.second + if (amounts_provided_by_a[a.first] > a.second) + { + //could be fee + WLT_LOG_RED("Amount[" << a.first << "] provided by Alice has unused leftovers: " << amounts_provided_by_a[a.first], LOG_LEVEL_0); + return false; + } + + proposal_info.to_alice.push_back(view::asset_funds{ a.first, a.second - amounts_provided_by_a[a.first] }); + } + etc_tx_details_expiration_time t = AUTO_VAL_INIT(t); if (!get_type_in_variant_container(tx.extra, t)) { @@ -5174,7 +5240,7 @@ bool wallet2::accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposa this->balance(balances, mined); //validate balances needed uint64_t native_amount_required = 0; - for (const auto& item : msc.proposal_info.to) + for (const auto& item : msc.proposal_info.to_alice) { if (balances[item.asset_id].unlocked < item.amount) { @@ -5188,9 +5254,9 @@ bool wallet2::accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposa // balances is ok, check if fee is added to tx uint64_t additional_fee = 0; - if (msc.proposal_info.fee < m_core_runtime_config.tx_default_fee) + if (msc.proposal_info.fee_paid_by_a < m_core_runtime_config.tx_default_fee) { - additional_fee = m_core_runtime_config.tx_default_fee - msc.proposal_info.fee; + additional_fee = m_core_runtime_config.tx_default_fee - msc.proposal_info.fee_paid_by_a; if (balances[currency::native_coin_asset_id].unlocked < additional_fee + native_amount_required) { return false; @@ -5540,11 +5606,16 @@ assets_selection_context wallet2::get_needed_money(uint64_t fee, const std::vect THROW_IF_TRUE_WALLET_EX(0 == dt.amount, error::zero_destination); uint64_t money_to_add = dt.amount; - if (dt.amount_to_provide) + if (dt.amount_to_provide || dt.flags & tx_destination_entry_flags::tdef_explicit_amount_to_provide) money_to_add = dt.amount_to_provide; amounts_map[dt.asset_id].needed_amount += money_to_add; THROW_IF_TRUE_WALLET_EX(amounts_map[dt.asset_id].needed_amount < money_to_add, error::tx_sum_overflow, dsts, fee); + //clean up empty entries + if (amounts_map[dt.asset_id].needed_amount == 0) + { + amounts_map.erase(amounts_map.find(dt.asset_id)); + } } return std::move(amounts_map); } @@ -6253,7 +6324,7 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx if (ctp.flags & TX_FLAG_SIGNATURE_MODE_SEPARATE && tx_for_mode_separate.vout.size() ) { WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(get_tx_flags(tx_for_mode_separate) & TX_FLAG_SIGNATURE_MODE_SEPARATE, "tx_param.flags differs from tx.flags"); - for (const auto& el : mode_separatemode_separate.proposal_info.to) + for (const auto& el : mode_separatemode_separate.proposal_info.to_alice) { needed_money_map[el.asset_id].needed_amount += el.amount; } diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 411413cf..75539c96 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1195,18 +1195,18 @@ namespace wallet_public struct ionic_swap_proposal_info { - std::vector from; - std::vector to; + std::vector to_bob; //assets that funded by side that making proposal(Alice) and addressed to receiver of proposal (Bob) + std::vector to_alice; //assets expected to be funded by the side that receiving proposal (Bob) and addressed to Alice uint64_t mixins; - uint64_t fee; + uint64_t fee_paid_by_a; uint64_t expiration_time; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(from) - KV_SERIALIZE(to) + KV_SERIALIZE(to_bob) + KV_SERIALIZE(to_alice) KV_SERIALIZE(mixins) - KV_SERIALIZE(fee) + KV_SERIALIZE(fee_paid_by_a) KV_SERIALIZE(expiration_time) END_KV_SERIALIZE_MAP() diff --git a/tests/core_tests/ionic_swap_tests.cpp b/tests/core_tests/ionic_swap_tests.cpp index c7aa91a6..0fe5f725 100644 --- a/tests/core_tests/ionic_swap_tests.cpp +++ b/tests/core_tests/ionic_swap_tests.cpp @@ -29,7 +29,12 @@ ionic_swap_basic_test::ionic_swap_basic_test() bool ionic_swap_basic_test::generate(std::vector& events) const { - uint64_t ts = test_core_time::get_time(); + // NOTE: This test is made deterministic to be able to correctly set up checkpoint. + random_state_test_restorer::reset_random(); // random generator's state was previously stored, will be restore on dtor (see also m_random_state_test_restorer) + uint64_t ts = 1450000000; + test_core_time::adjust(ts); + + ts = test_core_time::get_time(); m_accounts.resize(TOTAL_ACCS_COUNT); currency::account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts); currency::account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts); @@ -126,19 +131,23 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve //alice_wlt want to trade with miner_wlt, to exchange 10.0 TCT to 1.0 ZANO view::ionic_swap_proposal_info proposal_details = AUTO_VAL_INIT(proposal_details); proposal_details.expiration_time = alice_wlt->get_core_runtime_config().get_core_time() + 10 * 60; - proposal_details.fee = TESTS_DEFAULT_FEE; + proposal_details.fee_paid_by_a = TESTS_DEFAULT_FEE; proposal_details.mixins = 10; - proposal_details.from.push_back(view::asset_funds{ asset_id , assets_to_exchange }); - proposal_details.to.push_back(view::asset_funds{ currency::native_coin_asset_id , native_tokens_to_exchange }); + proposal_details.to_bob.push_back(view::asset_funds{ asset_id , assets_to_exchange }); + proposal_details.to_alice.push_back(view::asset_funds{ currency::native_coin_asset_id , native_tokens_to_exchange }); tools::wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); alice_wlt->create_ionic_swap_proposal(proposal_details, miner_wlt->get_account().get_public_address(), proposal); - view::ionic_swap_proposal_info proposal_decoded_info; + view::ionic_swap_proposal_info proposal_decoded_info = AUTO_VAL_INIT(proposal_decoded_info); miner_wlt->get_ionic_swap_proposal_info(proposal, proposal_decoded_info); //Validate proposal - if (proposal_decoded_info.from != proposal_details.from || proposal_decoded_info.to != proposal_details.to) + if (proposal_decoded_info.to_bob != proposal_details.to_bob + || proposal_decoded_info.to_alice != proposal_details.to_alice + || proposal_decoded_info.fee_paid_by_a != proposal_details.fee_paid_by_a + || proposal_decoded_info.mixins != proposal_details.mixins + ) { CHECK_AND_ASSERT_MES(false, false, "proposal actual and proposals decoded mismatch"); } @@ -171,6 +180,12 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_native->second.total == mined_balance - native_tokens_to_exchange, false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC + assets_to_exchange, false, "Failed to find needed asset in result balances"); + + + //TODO: + // add fee paid by bob scenario + // add transfer of tokens without native coins + // different fail combination return true; } diff --git a/tests/core_tests/ionic_swap_tests.h b/tests/core_tests/ionic_swap_tests.h index 389191ae..576c796c 100644 --- a/tests/core_tests/ionic_swap_tests.h +++ b/tests/core_tests/ionic_swap_tests.h @@ -4,12 +4,15 @@ #pragma once #include "chaingen.h" #include "wallet_tests_basic.h" - +#include "random_helper.h" struct ionic_swap_basic_test : public wallet_test { ionic_swap_basic_test(); bool generate(std::vector& events) const; bool c1(currency::core& c, size_t ev_index, const std::vector& events); + +private: + random_state_test_restorer m_random_state_test_restorer; }; From 09215f8923e8a31f9e310f657efe53fffe6792f6 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 21 Apr 2023 17:33:56 +0200 Subject: [PATCH 31/34] Fixes over TX_FLAG_SIGNATURE_MODE_SEPARATE and ionic swaps --- src/currency_core/currency_format_utils.cpp | 68 +++++++++++++-------- src/wallet/wallet2.cpp | 3 +- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index b06448cd..8d5f0b37 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1549,13 +1549,6 @@ namespace currency crypto::key_derivation get_encryption_key_derivation(bool is_income, const transaction& tx, const account_keys& acc_keys) { crypto::key_derivation derivation = null_derivation; - tx_crypto_checksum crypto_info = AUTO_VAL_INIT(crypto_info); - if (!get_type_in_variant_container(tx.extra, crypto_info) && !get_type_in_variant_container(tx.attachment, crypto_info)) - { - //no crypt info in tx - return null_derivation; - } - if (is_income) { crypto::public_key tx_pub_key = currency::get_tx_pub_key_from_extra(tx); @@ -1563,18 +1556,25 @@ namespace currency bool r = crypto::generate_key_derivation(tx_pub_key, acc_keys.view_secret_key, derivation); CHECK_AND_ASSERT_MES(r, null_derivation, "failed to generate_key_derivation"); LOG_PRINT_GREEN("DECRYPTING ON KEY: " << epee::string_tools::pod_to_hex(derivation) << ", key derived from destination addr: " << currency::get_account_address_as_str(acc_keys.account_address), LOG_LEVEL_0); + return derivation; } else { + tx_crypto_checksum crypto_info = AUTO_VAL_INIT(crypto_info); + if (!get_type_in_variant_container(tx.extra, crypto_info) && !get_type_in_variant_container(tx.attachment, crypto_info)) + { + //no crypt info in tx + return null_derivation; + } + derivation = crypto_info.encrypted_key_derivation; crypto::chacha_crypt(derivation, acc_keys.spend_secret_key); LOG_PRINT_GREEN("DECRYPTING ON KEY: " << epee::string_tools::pod_to_hex(derivation) << ", key decrypted from sender address: " << currency::get_account_address_as_str(acc_keys.account_address), LOG_LEVEL_0); + //validate derivation we here. Yoda style + crypto::hash hash_for_check_sum = crypto::cn_fast_hash(&derivation, sizeof(derivation)); + CHECK_AND_ASSERT_MES(*(uint32_t*)&hash_for_check_sum == crypto_info.derivation_hash, null_derivation, "Derivation hash missmatched in tx id " << currency::get_transaction_hash(tx)); + return derivation; } - - //validate derivation we here. Yoda style - crypto::hash hash_for_check_sum = crypto::cn_fast_hash(&derivation, sizeof(derivation)); - CHECK_AND_ASSERT_MES(*(uint32_t*)&hash_for_check_sum == crypto_info.derivation_hash, null_derivation, "Derivation hash missmatched in tx id " << currency::get_transaction_hash(tx)); - return derivation; } //--------------------------------------------------------------- template @@ -2027,7 +2027,8 @@ namespace currency append_mode = true; keypair txkey = AUTO_VAL_INIT(txkey); - + size_t zc_inputs_count = 0; + bool has_non_zc_inputs = false; if (!append_mode) { @@ -2082,6 +2083,17 @@ namespace currency tx.attachment.insert(tx.attachment.end(), attachments_local.begin(), attachments_local.end()); tx.extra.insert(tx.extra.end(), extra_local.begin(), extra_local.end()); + + for (const auto in : tx.vin) + { + if (in.type() == typeid(txin_zc_input)) + { + zc_inputs_count++; + } + else { + has_non_zc_inputs = true; + } + } } @@ -2094,7 +2106,6 @@ namespace currency size_t current_index = 0; inputs_mapping.resize(sources.size()); size_t input_starter_index = tx.vin.size(); - size_t zc_inputs_count = 0; bool all_inputs_are_obviously_native_coins = true; for (const tx_source_entry& src_entr : sources) { @@ -2113,6 +2124,7 @@ namespace currency input_multisig.multisig_out_id = src_entr.multisig_id; input_multisig.sigs_count = src_entr.ms_sigs_count; tx.vin.push_back(input_multisig); + has_non_zc_inputs = true; } else if (src_entr.htlc_origin.size()) { @@ -2147,6 +2159,7 @@ namespace currency input_to_key.key_offsets.push_back(src_entr.outputs.front().out_reference); tx.vin.push_back(input_to_key); + has_non_zc_inputs = true; } else { @@ -2189,6 +2202,7 @@ namespace currency input_to_key.k_image = img; input_to_key.key_offsets = std::move(key_offsets); tx.vin.push_back(input_to_key); + has_non_zc_inputs = true; } } @@ -2209,15 +2223,15 @@ namespace currency } } } - bool has_non_zc_inputs = zc_inputs_count != sources.size(); // TODO @#@# reconsider this for consilidated txs + // // OUTs // std::vector shuffled_dsts(destinations); - size_t outputs_to_be_constructed = shuffled_dsts.size(); + //size_t outputs_to_be_constructed = shuffled_dsts.size(); tx_generation_context& gen_context = result.ftp.gen_context; - gen_context.resize(zc_inputs_count, outputs_to_be_constructed); + gen_context.resize(zc_inputs_count, tx.vout.size() + shuffled_dsts.size()); // ASSET oprations handling if (tx.version > TRANSACTION_VERSION_PRE_HF4) @@ -2265,24 +2279,24 @@ namespace currency // construct outputs uint64_t native_coins_output_sum = 0; size_t output_index = tx.vout.size(); // in case of append mode we need to start output indexing from the last one + 1 - uint64_t range_proof_start_index = output_index; + uint64_t range_proof_start_index = 0; std::set deriv_cache; - for(size_t j = 0; j < outputs_to_be_constructed; ++j, ++output_index) + for(size_t destination_index = 0; destination_index < shuffled_dsts.size(); ++destination_index, ++output_index) { - tx_destination_entry& dst_entr = shuffled_dsts[j]; + tx_destination_entry& dst_entr = shuffled_dsts[destination_index]; if (all_inputs_are_obviously_native_coins && gen_context.ao_asset_id == currency::null_pkey) dst_entr.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id; // all inputs are obviously native coins -- all outputs must have explicit asset ids (unless there's an asset emission) CHECK_AND_ASSERT_MES(dst_entr.amount > 0, false, "Destination with wrong amount: " << dst_entr.amount); // <<-- TODO @#@# consider removing this check r = construct_tx_out(dst_entr, txkey.sec, output_index, tx, deriv_cache, sender_account_keys, - gen_context.asset_id_blinding_masks[j], gen_context.amount_blinding_masks[j], - gen_context.blinded_asset_ids[j], gen_context.amount_commitments[j], result, tx_outs_attr); + gen_context.asset_id_blinding_masks[output_index], gen_context.amount_blinding_masks[output_index], + gen_context.blinded_asset_ids[output_index], gen_context.amount_commitments[output_index], result, tx_outs_attr); CHECK_AND_ASSERT_MES(r, false, "Failed to construct tx out"); - gen_context.amounts[j] = dst_entr.amount; - gen_context.asset_ids[j] = crypto::point_t(dst_entr.asset_id); - gen_context.asset_id_blinding_mask_x_amount_sum += gen_context.asset_id_blinding_masks[j] * dst_entr.amount; - gen_context.amount_blinding_masks_sum += gen_context.amount_blinding_masks[j]; - gen_context.amount_commitments_sum += gen_context.amount_commitments[j]; + gen_context.amounts[output_index] = dst_entr.amount; + gen_context.asset_ids[output_index] = crypto::point_t(dst_entr.asset_id); + gen_context.asset_id_blinding_mask_x_amount_sum += gen_context.asset_id_blinding_masks[output_index] * dst_entr.amount; + gen_context.amount_blinding_masks_sum += gen_context.amount_blinding_masks[output_index]; + gen_context.amount_commitments_sum += gen_context.amount_commitments[output_index]; if (dst_entr.is_native_coin()) native_coins_output_sum += dst_entr.amount; } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 06eac0ae..e57a0b0b 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5230,6 +5230,7 @@ bool wallet2::accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposa { mode_separate_context msc = AUTO_VAL_INIT(msc); msc.tx_for_mode_separate = proposal.tx_template; + result_tx = msc.tx_for_mode_separate; wallet_public::ionic_swap_proposal_context ionic_context = AUTO_VAL_INIT(ionic_context); bool r = get_ionic_swap_proposal_info(proposal, msc.proposal_info, ionic_context); @@ -5268,7 +5269,7 @@ bool wallet2::accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposa construct_tx_param construct_param = get_default_construct_tx_param(); construct_param.fee = additional_fee; - assert(0); crypto::secret_key one_time_key = ionic_context.one_time_skey; + crypto::secret_key one_time_key = ionic_context.one_time_skey; construct_param.crypt_address = m_account.get_public_address(); construct_param.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; construct_param.mark_tx_as_complete = true; From 9f6436ea08ee1dc39b51a242ad7957faa4eb32d2 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 25 Apr 2023 00:16:13 +0200 Subject: [PATCH 32/34] Final fixes for ionic_swap_basic_test - first time test worked!!!!! --- src/common/error_codes.h | 3 +- src/currency_core/currency_format_utils.cpp | 8 +- .../currency_format_utils_transactions.h | 8 +- src/wallet/wallet2.cpp | 79 +++++++++++++++++-- src/wallet/wallet2.h | 20 ++++- src/wallet/wallet_errors.h | 11 +++ tests/core_tests/ionic_swap_tests.cpp | 38 ++++++--- 7 files changed, 139 insertions(+), 28 deletions(-) diff --git a/src/common/error_codes.h b/src/common/error_codes.h index 7b77fec3..313a9aad 100644 --- a/src/common/error_codes.h +++ b/src/common/error_codes.h @@ -40,4 +40,5 @@ #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 +#define API_RETURN_CODE_WRAP "WRAP" +#define API_RETURN_CODE_MISSING_ZC_INPUTS "MISSING_ZC_INPUTS" \ No newline at end of file diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 8d5f0b37..c323d7d5 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -2096,7 +2096,7 @@ namespace currency } } - + size_t thirdparty_zc_inputs_count = zc_inputs_count; // // INs // @@ -2284,7 +2284,7 @@ namespace currency for(size_t destination_index = 0; destination_index < shuffled_dsts.size(); ++destination_index, ++output_index) { tx_destination_entry& dst_entr = shuffled_dsts[destination_index]; - if (all_inputs_are_obviously_native_coins && gen_context.ao_asset_id == currency::null_pkey) + if (!append_mode && all_inputs_are_obviously_native_coins && gen_context.ao_asset_id == currency::null_pkey) dst_entr.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id; // all inputs are obviously native coins -- all outputs must have explicit asset ids (unless there's an asset emission) CHECK_AND_ASSERT_MES(dst_entr.amount > 0, false, "Destination with wrong amount: " << dst_entr.amount); // <<-- TODO @#@# consider removing this check @@ -2376,6 +2376,7 @@ namespace currency // ring signatures (per-input proofs) r = false; + size_t curren_zc_index = thirdparty_zc_inputs_count; for (size_t i_ = 0; i_ != sources.size(); i_++) { size_t i_mapped = inputs_mapping[i_]; @@ -2390,7 +2391,8 @@ namespace currency // blinding_masks_sum is supposed to be sum(mask of all tx output) - sum(masks of all pseudo out commitments) r = generate_ZC_sig(tx_hash_for_signature, i_ + input_starter_index, source_entry, in_contexts[i_mapped], sender_account_keys, flags, gen_context, tx, i_ + 1 == sources.size()); CHECK_AND_ASSERT_MES(r, false, "generate_ZC_sigs failed"); - gen_context.input_amounts[i_ + input_starter_index] = source_entry.amount; + gen_context.zc_input_amounts[curren_zc_index] = source_entry.amount; + curren_zc_index++; } else { diff --git a/src/currency_core/currency_format_utils_transactions.h b/src/currency_core/currency_format_utils_transactions.h index 24600d5f..e4f16d1f 100644 --- a/src/currency_core/currency_format_utils_transactions.h +++ b/src/currency_core/currency_format_utils_transactions.h @@ -225,7 +225,7 @@ namespace currency asset_id_blinding_masks.resize(outs_count); amounts.resize(outs_count); amount_blinding_masks.resize(outs_count); - input_amounts.resize(zc_ins_count); + zc_input_amounts.resize(zc_ins_count); } // TODO @#@# reconsider this check -- sowle @@ -253,7 +253,7 @@ namespace currency std::vector pseudo_outs_blinded_asset_ids; // generate_asset_surjection_proof crypto::scalar_vec_t pseudo_outs_plus_real_out_blinding_masks; // r_pi + r'_j // generate_asset_surjection_proof std::vector real_zc_ins_asset_ids; // H_i // generate_asset_surjection_proof - std::vector input_amounts; // all inputs, including non ZC + std::vector zc_input_amounts; // ZC only input amounts // common data: inputs crypto::point_t pseudo_out_amount_commitments_sum = crypto::c_point_0; // generate_tx_balance_proof generate_ZC_sig @@ -282,7 +282,7 @@ namespace currency KV_SERIALIZE_CONTAINER_POD_AS_BLOB(pseudo_outs_blinded_asset_ids) KV_SERIALIZE_CONTAINER_POD_AS_BLOB(pseudo_outs_plus_real_out_blinding_masks) KV_SERIALIZE_CONTAINER_POD_AS_BLOB(real_zc_ins_asset_ids) - KV_SERIALIZE(input_amounts) + KV_SERIALIZE(zc_input_amounts) KV_SERIALIZE_POD_AS_HEX_STRING(pseudo_out_amount_commitments_sum) KV_SERIALIZE_POD_AS_HEX_STRING(pseudo_out_amount_blinding_masks_sum) KV_SERIALIZE_POD_AS_HEX_STRING(real_in_asset_id_blinding_mask_x_amount_sum) @@ -308,7 +308,7 @@ namespace currency FIELD(pseudo_outs_blinded_asset_ids) FIELD((std::vector&)(pseudo_outs_plus_real_out_blinding_masks)) FIELD(real_zc_ins_asset_ids) - FIELD(input_amounts) + FIELD(zc_input_amounts) FIELD(pseudo_out_amount_commitments_sum) FIELD(pseudo_out_amount_blinding_masks_sum) FIELD(real_in_asset_id_blinding_mask_x_amount_sum) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index e57a0b0b..54226571 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -42,6 +42,8 @@ using namespace epee; using namespace currency; +#define SET_CONTEXT_OBJ_FOR_SCOPE(name, obj) m_current_context.name = &obj; \ + auto COMBINE(auto_scope_var_, __LINE__) = epee::misc_utils::create_scope_leave_handler([&]() { m_current_context.name = nullptr; }); #define MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES (100*1024*1024) // 100 MB @@ -5139,7 +5141,7 @@ bool wallet2::get_ionic_swap_proposal_info(const wallet_public::ionic_swap_propo if (tx.vin[i].type() == typeid(txin_zc_input)) { in_asset_id = ionic_context.gen_context.real_zc_ins_asset_ids[zc_current_index].to_public_key(); - amount = ionic_context.gen_context.input_amounts[zc_current_index]; + amount = ionic_context.gen_context.zc_input_amounts[zc_current_index]; zc_current_index++; mx = boost::get(tx.vin[i]).key_offsets.size() - 1; } @@ -5280,6 +5282,8 @@ bool wallet2::accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposa ftp.gen_context = ionic_context.gen_context; prepare_transaction(construct_param, ftp, msc); + + try { finalize_transaction(ftp, result_tx, one_time_key, true); @@ -5895,6 +5899,38 @@ bool wallet2::get_actual_offers(std::list& offers return true; } //---------------------------------------------------------------------------------------------------- +bool wallet2::expand_selection_with_zc_input(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector& selected_indexes) +{ + + free_amounts_cache_type& found_free_amounts = m_found_free_amounts[currency::native_coin_asset_id]; + auto& asset_needed_money_item = needed_money_map[currency::native_coin_asset_id]; + //need to add ZC input + for (auto it = found_free_amounts.begin(); it != found_free_amounts.end(); it++) + { + for (auto it_in_amount = it->second.begin(); it_in_amount != it->second.end(); it_in_amount++) + { + if (!m_transfers[*it_in_amount].is_zc()) + { + continue; + } + + if (is_transfer_ready_to_go(m_transfers[*it->second.begin()], fake_outputs_count)) + { + asset_needed_money_item.found_amount += it->first; + selected_indexes.push_back(*it_in_amount); + it->second.erase(it_in_amount); + if (!it->second.size()) + { + found_free_amounts.erase(it); + } + return true; + } + } + } + WLT_THROW_IF_FALSE_WALLET_EX_MES(false , error::no_zc_inputs, "Missing ZC inputs for TX_FLAG_SIGNATURE_MODE_SEPARATE operation"); + return true; +} +//---------------------------------------------------------------------------------------------------- bool wallet2::select_indices_for_transfer(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector& selected_indexes) { bool res = true; @@ -5906,6 +5942,24 @@ bool wallet2::select_indices_for_transfer(assets_selection_context& needed_money item.second.found_amount = select_indices_for_transfer(selected_indexes, asset_cashe_it->second, item.second.needed_amount, fake_outputs_count); WLT_THROW_IF_FALSE_WALLET_EX_MES(item.second.found_amount >= item.second.needed_amount, error::not_enough_money, "", item.second.found_amount, item.second.needed_amount, 0, item.first); } + if (m_current_context.pconstruct_tx_param && m_current_context.pconstruct_tx_param->need_at_least_1_zc) + { + bool found_zc_input = false; + for (auto i : selected_indexes) + { + if (m_transfers[i].is_zc()) + { + found_zc_input = true; + break; + } + } + if (!found_zc_input) + { + expand_selection_with_zc_input(needed_money_map, fake_outputs_count, selected_indexes); + } + } + + return res; } //---------------------------------------------------------------------------------------------------- @@ -5913,6 +5967,7 @@ uint64_t wallet2::select_indices_for_transfer(std::vector& selected_in { WLT_LOG_GREEN("Selecting indices for transfer of " << print_money_brief(needed_money) << " with " << fake_outputs_count << " fake outs, found_free_amounts.size()=" << found_free_amounts.size() << "...", LOG_LEVEL_0); uint64_t found_money = 0; + //uint64_t found_zc_input = false; std::string selected_amounts_str; while (found_money < needed_money && found_free_amounts.size()) { @@ -5934,6 +5989,7 @@ uint64_t wallet2::select_indices_for_transfer(std::vector& selected_in found_free_amounts.erase(it); } + WLT_LOG_GREEN("Found " << print_money_brief(found_money) << " as " << selected_indexes.size() << " out(s): " << selected_amounts_str << ", found_free_amounts.size()=" << found_free_amounts.size(), LOG_LEVEL_0); return found_money; } @@ -6057,11 +6113,16 @@ bool wallet2::read_money_transfer2_details_from_tx(const transaction& tx, const else if (i.type() == typeid(currency::txin_zc_input)) { const currency::txin_zc_input& in_zc = boost::get(i); - auto it = m_key_images.find(in_zc.k_image); //should we panic if image not found? - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it != m_key_images.end(), "[read_money_transfer2_details_from_tx]Unknown key image in tx: " << get_transaction_hash(tx)); - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it->second < m_transfers.size(), "[read_money_transfer2_details_from_tx]Index out of range for key image in tx: " << get_transaction_hash(tx)); - wtd.spn.push_back(m_transfers[it->second].amount()); + //@zoidberg: nope! + if (m_key_images.count(in_zc.k_image)) + { + auto it = m_key_images.find(in_zc.k_image); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it != m_key_images.end(), "[read_money_transfer2_details_from_tx]Unknown key image in tx: " << get_transaction_hash(tx)); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it->second < m_transfers.size(), "[read_money_transfer2_details_from_tx]Index out of range for key image in tx: " << get_transaction_hash(tx)); + wtd.spn.push_back(m_transfers[it->second].amount()); + } + } } return true; @@ -6314,14 +6375,19 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money, //---------------------------------------------------------------------------------------------------- void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& mode_separatemode_separate) { + + SET_CONTEXT_OBJ_FOR_SCOPE(pconstruct_tx_param, ctp); + SET_CONTEXT_OBJ_FOR_SCOPE(pfinalize_tx_param, ftp); + SET_CONTEXT_OBJ_FOR_SCOPE(pmode_separate_context, mode_separatemode_separate); + TIME_MEASURE_START_MS(get_needed_money_time); + const currency::transaction& tx_for_mode_separate = mode_separatemode_separate.tx_for_mode_separate; assets_selection_context needed_money_map = get_needed_money(ctp.fee, ctp.dsts); // // TODO @#@# need to do refactoring over this part to support hidden amounts and asset_id // - if (ctp.flags & TX_FLAG_SIGNATURE_MODE_SEPARATE && tx_for_mode_separate.vout.size() ) { WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(get_tx_flags(tx_for_mode_separate) & TX_FLAG_SIGNATURE_MODE_SEPARATE, "tx_param.flags differs from tx.flags"); @@ -6329,6 +6395,7 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx { needed_money_map[el.asset_id].needed_amount += el.amount; } + ctp.need_at_least_1_zc = true; } TIME_MEASURE_FINISH_MS(get_needed_money_time); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 4bbe3302..b09fd5e8 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -300,6 +300,7 @@ namespace tools uint8_t tx_outs_attr = 0; bool shuffle = false; bool perform_packing = false; + bool need_at_least_1_zc = false; }; struct mode_separate_context @@ -469,6 +470,21 @@ namespace tools crypto::hash related_tx_id = currency::null_hash; // tx id which caused money lock, if any (ex: escrow proposal transport tx) }; + /* + This might be not the best solution so far, but after discussion with @sowle we came up to conclusion + that passing great variety of arguments through the long call stack of different member functions of the wallet will + only complicate codebase and make it harder to understand. + current_operation_context will keep pointers to some useful data, and every function that use it, should + make sure(!!!) that pointer got nulled before pointed object got destroyed, likely by using SET_CONTEXT_OBJ_FOR_SCOPE macro + + */ + struct current_operation_context + { + construct_tx_param* pconstruct_tx_param = nullptr; + currency::finalize_tx_param* pfinalize_tx_param = nullptr; + const mode_separate_context* pmode_separate_context = nullptr; + }; + typedef std::unordered_multimap payment_container; @@ -1109,7 +1125,7 @@ private: bool is_in_hardfork_zone(uint64_t hardfork_index) const; uint8_t out_get_mixin_attr(const currency::tx_out_v& out_t); const crypto::public_key& out_get_pub_key(const currency::tx_out_v& out_t, std::list& htlc_info_list); - + bool expand_selection_with_zc_input(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector& selected_indexes); void push_alias_info_to_extra_according_to_hf_status(const currency::extra_alias_entry& ai, std::vector& extra); void remove_transfer_from_amount_gindex_map(uint64_t tid); @@ -1174,6 +1190,8 @@ private: mutable uint64_t m_current_wallet_file_size; bool m_use_deffered_global_outputs; bool m_disable_tor_relay; + + mutable current_operation_context m_current_context; //this needed to access wallets state in coretests, for creating abnormal blocks and tranmsactions friend class test_generator; diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index 3d118c92..9e8426c0 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -380,6 +380,17 @@ namespace tools uint64_t m_fee; crypto::public_key m_asset_id; }; + + struct no_zc_inputs : public transfer_error + { + no_zc_inputs(const std::string& /*v*/): transfer_error(std::string(""), API_RETURN_CODE_MISSING_ZC_INPUTS) + {} + + virtual const char* what() const noexcept + { + return API_RETURN_CODE_MISSING_ZC_INPUTS; + } + }; //---------------------------------------------------------------------------------------------------- struct not_enough_outs_to_mix : public transfer_error { diff --git a/tests/core_tests/ionic_swap_tests.cpp b/tests/core_tests/ionic_swap_tests.cpp index 0fe5f725..013176d2 100644 --- a/tests/core_tests/ionic_swap_tests.cpp +++ b/tests/core_tests/ionic_swap_tests.cpp @@ -67,6 +67,14 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve alice_acc.generate(); std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, alice_acc); alice_wlt->get_account().set_createtime(0); + + + currency::account_base bob_acc; + bob_acc.generate(); + std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, bob_acc); + bob_wlt->get_account().set_createtime(0); + + miner_wlt->refresh(); currency::asset_descriptor_base adb = AUTO_VAL_INIT(adb); @@ -76,7 +84,7 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve adb.decimal_point = 12; std::vector destinations(2); - destinations[0].addr.push_back(miner_wlt->get_account().get_public_address()); + destinations[0].addr.push_back(bob_wlt->get_account().get_public_address()); destinations[0].amount = AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC; destinations[0].asset_id = currency::null_pkey; destinations[1].addr.push_back(alice_wlt->get_account().get_public_address()); @@ -94,16 +102,17 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve currency::transaction res_tx = AUTO_VAL_INIT(res_tx); miner_wlt->transfer(COIN, alice_wlt->get_account().get_public_address(), res_tx); + miner_wlt->transfer(COIN, bob_wlt->get_account().get_public_address(), res_tx); r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); - miner_wlt->refresh(); + bob_wlt->refresh(); alice_wlt->refresh(); uint64_t mined = 0; std::unordered_map balances; - miner_wlt->balance(balances, mined); + bob_wlt->balance(balances, mined); auto it_asset = balances.find(asset_id); auto it_native = balances.find(currency::native_coin_asset_id); @@ -111,7 +120,7 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve CHECK_AND_ASSERT_MES(it_asset != balances.end() && it_native != balances.end(), false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances"); - CHECK_AND_ASSERT_MES(it_native->second.total == uint64_t(17517226)*COIN - COIN, false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_native->second.total == COIN, false, "Failed to find needed asset in result balances"); uint64_t mined_balance = it_native->second.total; @@ -126,9 +135,9 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances"); const uint64_t assets_to_exchange = 10 * COIN; - const uint64_t native_tokens_to_exchange = 1 * COIN; + const uint64_t native_tokens_to_exchange = COIN/2; - //alice_wlt want to trade with miner_wlt, to exchange 10.0 TCT to 1.0 ZANO + //alice_wlt want to trade with bob_wlt, to exchange 10.0 TCT to 1.0 ZANO view::ionic_swap_proposal_info proposal_details = AUTO_VAL_INIT(proposal_details); proposal_details.expiration_time = alice_wlt->get_core_runtime_config().get_core_time() + 10 * 60; proposal_details.fee_paid_by_a = TESTS_DEFAULT_FEE; @@ -137,10 +146,10 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve proposal_details.to_alice.push_back(view::asset_funds{ currency::native_coin_asset_id , native_tokens_to_exchange }); tools::wallet_public::ionic_swap_proposal proposal = AUTO_VAL_INIT(proposal); - alice_wlt->create_ionic_swap_proposal(proposal_details, miner_wlt->get_account().get_public_address(), proposal); + alice_wlt->create_ionic_swap_proposal(proposal_details, bob_wlt->get_account().get_public_address(), proposal); view::ionic_swap_proposal_info proposal_decoded_info = AUTO_VAL_INIT(proposal_decoded_info); - miner_wlt->get_ionic_swap_proposal_info(proposal, proposal_decoded_info); + bob_wlt->get_ionic_swap_proposal_info(proposal, proposal_decoded_info); //Validate proposal if (proposal_decoded_info.to_bob != proposal_details.to_bob @@ -153,13 +162,13 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve } currency::transaction res_tx2 = AUTO_VAL_INIT(res_tx2); - r = miner_wlt->accept_ionic_swap_proposal(proposal, res_tx2); + r = bob_wlt->accept_ionic_swap_proposal(proposal, res_tx2); CHECK_AND_ASSERT_MES(r, false, "Failed to accept ionic proposal"); r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); - miner_wlt->refresh(); + bob_wlt->refresh(); alice_wlt->refresh(); @@ -170,15 +179,18 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve it_native = balances.find(currency::native_coin_asset_id); CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances"); - CHECK_AND_ASSERT_MES(it_native->second.total == native_tokens_to_exchange, false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_native->second.total == native_tokens_to_exchange + COIN - TESTS_DEFAULT_FEE, false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC - assets_to_exchange, false, "Failed to find needed asset in result balances"); balances.clear(); - miner_wlt->balance(balances, mined); + bob_wlt->balance(balances, mined); + it_asset = balances.find(asset_id); + it_native = balances.find(currency::native_coin_asset_id); + CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances"); - CHECK_AND_ASSERT_MES(it_native->second.total == mined_balance - native_tokens_to_exchange, false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_native->second.total == COIN - native_tokens_to_exchange, false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC + assets_to_exchange, false, "Failed to find needed asset in result balances"); From 4cfb62575bd0543363a73385ecb646aa279dd843 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 26 Apr 2023 00:24:29 +0200 Subject: [PATCH 33/34] fixed bug in atomic swaps(discovered by core_tests) --- src/wallet/wallet2.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 54226571..5da66730 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6410,15 +6410,15 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx { //htlc //@#@ need to do refactoring over this part to support hidden amounts and asset_id - prepare_tx_sources_htlc(ctp.htlc_tx_id, ctp.htlc_origin, ftp.sources, needed_money_map[currency::null_pkey].found_amount); + prepare_tx_sources_htlc(ctp.htlc_tx_id, ctp.htlc_origin, ftp.sources, needed_money_map[currency::native_coin_asset_id].found_amount); WLT_THROW_IF_FALSE_WITH_CODE(ctp.dsts.size() == 1, "htlc: unexpected ctp.dsts.size() =" << ctp.dsts.size(), API_RETURN_CODE_INTERNAL_ERROR); - WLT_THROW_IF_FALSE_WITH_CODE(needed_money_map[currency::null_pkey].found_amount > ctp.fee, + WLT_THROW_IF_FALSE_WITH_CODE(needed_money_map[currency::native_coin_asset_id].found_amount > ctp.fee, "htlc: found money less then fee", API_RETURN_CODE_INTERNAL_ERROR); //fill amount - ctp.dsts.begin()->amount = needed_money_map[currency::null_pkey].found_amount - ctp.fee; + ctp.dsts.begin()->amount = needed_money_map[currency::native_coin_asset_id].found_amount - ctp.fee; } else if (ctp.multisig_id != currency::null_hash) From 64a043a18fd61c2c2020c5234887ce090a0c5ad0 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 26 Apr 2023 23:59:33 +0200 Subject: [PATCH 34/34] fixed few bugs related to aliases registration and block versions --- src/currency_core/blockchain_storage.cpp | 10 +--------- src/currency_core/currency_format_utils.cpp | 2 +- tests/core_tests/chaingen.cpp | 7 ++++--- tests/core_tests/chaingen.h | 2 ++ 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 836474ac..e601b888 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -6409,15 +6409,7 @@ bool blockchain_storage::prevalidate_block(const block& bl) return true; } - // HF3 - if ( m_core_runtime_config.is_hardfork_active_for_height(3, block_height) && - !m_core_runtime_config.is_hardfork_active_for_height(4, block_height)) - { - CHECK_AND_ASSERT_MES(bl.major_version == HF3_BLOCK_MAJOR_VERSION, false, "HF3, incorrect block major version: " << (int)bl.major_version); - } - - - //after hard_fork3 + // >= HF3 if (bl.major_version > CURRENT_BLOCK_MAJOR_VERSION) { LOG_ERROR("prevalidation failed for block " << get_block_hash(bl) << ": major block version " << static_cast(bl.major_version) << " is incorrect, " << CURRENT_BLOCK_MAJOR_VERSION << " is expected" << ENDL diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index c323d7d5..c5a82881 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -3533,7 +3533,7 @@ namespace currency } if (p_amount_burnt) *p_amount_burnt = sum_of_bare_outs_burnt; - return sum_of_bare_outs_burnt == amount; + return sum_of_bare_outs_burnt >= amount; } // post HF-4 txs diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 5ff7a81c..8822e469 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -2228,7 +2228,10 @@ bool shuffle_source_entries(std::vector& sources) //------------------------------------------------------------------------------ - +test_chain_unit_base::test_chain_unit_base() +{ + m_hardforks = get_default_core_runtime_config().hard_forks; // set default hardforks for tests (will be overriden by test if necessary) +} void test_chain_unit_base::register_callback(const std::string& cb_name, verify_callback cb) { m_callbacks[cb_name] = cb; @@ -2286,8 +2289,6 @@ test_chain_unit_enchanced::test_chain_unit_enchanced() REGISTER_CALLBACK_METHOD(test_chain_unit_enchanced, check_offers_count); REGISTER_CALLBACK_METHOD(test_chain_unit_enchanced, check_hardfork_active); REGISTER_CALLBACK_METHOD(test_chain_unit_enchanced, check_hardfork_inactive); - - m_hardforks = get_default_core_runtime_config().hard_forks; // set default hardforks for tests (will be overriden by test if necessary) } bool test_chain_unit_enchanced::configure_core(currency::core& c, size_t ev_index, const std::vector& events) diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 4662a530..a6222192 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -230,6 +230,8 @@ class test_generator; class test_chain_unit_base { public: + test_chain_unit_base(); + typedef boost::function &events)> verify_callback; typedef std::map callbacks_map;