From 438dd74166c0c2edd5208fa094362db5a57a4087 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 26 Apr 2023 22:49:31 +0200 Subject: [PATCH 1/6] coretests: fixed construct_tx_to_key for boundary condition handling for tx_version at the next block height --- tests/core_tests/chaingen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 5ff7a81c..32ba7264 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -1653,7 +1653,8 @@ bool construct_tx_to_key(const currency::hard_forks_descriptor& hf, if (!fill_tx_sources(sources, events, blk_head, from.get_keys(), spending_amount, nmix, check_for_spends, check_for_unlocktime, use_ref_by_id)) return false; - uint64_t tx_version = currency::get_tx_version(get_block_height(blk_head), hf); + uint64_t tx_expected_block_height = get_block_height(blk_head) + 1; + uint64_t tx_version = currency::get_tx_version(tx_expected_block_height, hf); boost::multiprecision::int128_t change = get_sources_total_amount(sources); change -= spending_amount; if (change < 0) From 0fcfe2e54085c2611ed779ec97d5b8962a27bc20 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 28 Apr 2023 20:07:35 +0200 Subject: [PATCH 2/6] wallet2: various fixes for escrow --- src/wallet/wallet2.cpp | 17 +++++++++++------ src/wallet/wallet2.h | 1 + 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5da66730..374ed25f 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -937,6 +937,7 @@ 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; mode_separate_context msc = AUTO_VAL_INIT(msc); + msc.escrow = true; 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; @@ -5275,6 +5276,7 @@ bool wallet2::accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposa construct_param.crypt_address = m_account.get_public_address(); construct_param.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE; construct_param.mark_tx_as_complete = true; + construct_param.need_at_least_1_zc = true; //build transaction currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); @@ -6373,16 +6375,16 @@ 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) +void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& msc) { 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); + SET_CONTEXT_OBJ_FOR_SCOPE(pmode_separate_context, msc); TIME_MEASURE_START_MS(get_needed_money_time); - const currency::transaction& tx_for_mode_separate = mode_separatemode_separate.tx_for_mode_separate; + const currency::transaction& tx_for_mode_separate = msc.tx_for_mode_separate; assets_selection_context needed_money_map = get_needed_money(ctp.fee, ctp.dsts); // @@ -6391,11 +6393,14 @@ 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_alice) + if (ftp.tx_version > TRANSACTION_VERSION_PRE_HF4) { + for (const auto& el : msc.proposal_info.to_alice) needed_money_map[el.asset_id].needed_amount += el.amount; } - ctp.need_at_least_1_zc = true; + + if (msc.escrow) + needed_money_map[currency::native_coin_asset_id].needed_amount += (currency::get_outs_money_amount(tx_for_mode_separate) - get_inputs_money_amount(tx_for_mode_separate)); } TIME_MEASURE_FINISH_MS(get_needed_money_time); @@ -6425,7 +6430,7 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx { //multisig //@#@ need to do refactoring over this part to support hidden amounts and asset_id - prepare_tx_sources(ctp.multisig_id, ftp.sources, needed_money_map[currency::null_pkey].found_amount); + prepare_tx_sources(ctp.multisig_id, ftp.sources, needed_money_map[currency::native_coin_asset_id].found_amount); } else { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index b09fd5e8..4242e451 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -307,6 +307,7 @@ namespace tools { currency::transaction tx_for_mode_separate; view::ionic_swap_proposal_info proposal_info; + bool escrow = false; }; From 1a698a72b23d0ed174aa01c1f5dc16a2c5c93537 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 28 Apr 2023 21:51:28 +0200 Subject: [PATCH 3/6] a rare case in get_est_height_from_date fixed (credits go to @crypto_zoidberg) --- src/currency_core/blockchain_storage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index e601b888..d6defdf4 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3264,7 +3264,7 @@ bool blockchain_storage::get_est_height_from_date(uint64_t date, uint64_t& res_h //we moved too much forward current_height_boundary = calculated_estimated_height; - CHECK_AND_ASSERT_MES(current_height_boundary > current_low_boundary, true, + CHECK_AND_ASSERT_MES(current_height_boundary >= current_low_boundary, true, "Internal error: current_hight_boundary(" << current_height_boundary << ") > current_low_boundary("<< current_low_boundary << ")"); uint64_t offset = (current_height_boundary - current_low_boundary)/2; if (offset <= 2) @@ -3282,7 +3282,7 @@ bool blockchain_storage::get_est_height_from_date(uint64_t date, uint64_t& res_h { //we too much in past current_low_boundary = calculated_estimated_height; - CHECK_AND_ASSERT_MES(current_height_boundary > current_low_boundary, true, + CHECK_AND_ASSERT_MES(current_height_boundary >= current_low_boundary, true, "Internal error: current_hight_boundary(" << current_height_boundary << ") > current_low_boundary(" << current_low_boundary << ")"); uint64_t offset = (current_height_boundary - current_low_boundary) / 2; if (offset <= 2) From 6de38385e250ad9022d9febf25140f267ed84ad5 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 28 Apr 2023 21:58:18 +0200 Subject: [PATCH 4/6] gcc warning fixed --- tests/core_tests/chaingen_helpers.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h index 8d43323c..dc3af1bf 100644 --- a/tests/core_tests/chaingen_helpers.h +++ b/tests/core_tests/chaingen_helpers.h @@ -5,6 +5,7 @@ #pragma once #include "currency_core/currency_core.h" +#include "curency_core/currency_format_utils.h" #include "currency_core/miner.h" #include "wallet/wallet2.h" #include "test_core_time.h" From ba2e7d4d15ccb141f21dd25bf4d50fc5d92901ad Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 28 Apr 2023 22:19:07 +0200 Subject: [PATCH 5/6] typo fixed --- tests/core_tests/chaingen_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h index dc3af1bf..a9537274 100644 --- a/tests/core_tests/chaingen_helpers.h +++ b/tests/core_tests/chaingen_helpers.h @@ -5,7 +5,7 @@ #pragma once #include "currency_core/currency_core.h" -#include "curency_core/currency_format_utils.h" +#include "currency_core/currency_format_utils.h" #include "currency_core/miner.h" #include "wallet/wallet2.h" #include "test_core_time.h" From 9efa8f7a6ff154a63be69921ee9c6d4821288587 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 1 May 2023 13:34:37 +0200 Subject: [PATCH 6/6] wallet2::add_sent_unconfirmed_tx partially fixed for assets, read_money_transfer2_details_from_tx removed --- src/wallet/wallet2.cpp | 96 ++++++++++++++++++++---------------------- src/wallet/wallet2.h | 3 -- 2 files changed, 45 insertions(+), 54 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 374ed25f..2741dfcc 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3249,6 +3249,7 @@ bool wallet2::balance(std::list& balances, u auto it_local = m_whitelisted_assets.find(item.first); if(it_local == m_whitelisted_assets.end()) { + WLT_LOG_YELLOW("WARNING: unknown asset " << item.first << " found and skipped; it's NOT included in balance", LOG_LEVEL_0); continue; } else @@ -6090,46 +6091,6 @@ bool wallet2::select_transfers(assets_selection_context& needed_money_map, size_ return select_indices_for_transfer(needed_money_map, fake_outputs_count, selected_indicies); } //---------------------------------------------------------------------------------------------------- -bool wallet2::read_money_transfer2_details_from_tx(const transaction& tx, const std::vector& splitted_dsts, - wallet_public::wallet_transfer_info_details& wtd) -{ - PROFILE_FUNC("wallet2::read_money_transfer2_details_from_tx"); - for (auto& d : splitted_dsts) - { - if (d.addr.size() && d.addr.back().spend_public_key == m_account.get_keys().account_address.spend_public_key && - d.addr.back().view_public_key == m_account.get_keys().account_address.view_public_key) - wtd.rcv.push_back(d.amount); - } - - //scan key images - for (auto& i : tx.vin) - { - if (i.type() == typeid(currency::txin_to_key)) - { - const currency::txin_to_key& in_to_key = boost::get(i); - if (m_key_images.count(in_to_key.k_image)) - { - wtd.spn.push_back(in_to_key.amount); - } - } - else if (i.type() == typeid(currency::txin_zc_input)) - { - const currency::txin_zc_input& in_zc = boost::get(i); - //should we panic if image not found? - //@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; -} -//---------------------------------------------------------------------------------------------------- void wallet2::add_sent_unconfirmed_tx(const currency::transaction& tx, const std::vector& recipients, const std::vector& selected_indicies, @@ -6144,17 +6105,50 @@ void wallet2::add_sent_unconfirmed_tx(const currency::transaction& tx, unconfirmed_wti.remote_aliases.push_back(get_alias_for_address(addr)); unconfirmed_wti.is_income = false; unconfirmed_wti.selected_indicies = selected_indicies; - /*TODO: add selected_indicies to read_money_transfer2_details_from_tx in case of performance problems*/ - read_money_transfer2_details_from_tx(tx, splitted_dsts, unconfirmed_wti.td); - - uint64_t change_amount = 0; - uint64_t inputs_amount = 0; - for (auto i : unconfirmed_wti.td.rcv) - change_amount += i; - for (auto i : unconfirmed_wti.td.spn) - inputs_amount += i; + unconfirmed_wti.asset_id = null_pkey; - prepare_wti(unconfirmed_wti, 0, m_core_runtime_config.get_core_time(), tx, inputs_amount - (change_amount + get_tx_fee(tx)), money_transfer2_details()); + uint64_t native_coin_change_amount = 0; + uint64_t native_coin_inputs_amount = 0; + + // TODO @#@# potential issue: one tx may have different asset_id's in INs or OUTs + // but only one asset_id is associated with a transfer atm + // possible solution: make a transfer item for each asset_id in tx -- sowle + for (auto& d : splitted_dsts) + { + if (d.addr.size() && + d.addr.back().spend_public_key == m_account.get_keys().account_address.spend_public_key && + d.addr.back().view_public_key == m_account.get_keys().account_address.view_public_key) + { + unconfirmed_wti.td.rcv.push_back(d.amount); + WLT_CHECK_AND_ASSERT_MES(unconfirmed_wti.asset_id == null_pkey || unconfirmed_wti.asset_id == d.asset_id, (void)0, "TODO: BAD case with asset_id"); + unconfirmed_wti.asset_id = d.asset_id; + if (d.asset_id == native_coin_asset_id) + native_coin_change_amount += d.amount; + } + } + + //scan key images + for (auto& i : tx.vin) + { + crypto::key_image ki{}; + if (get_key_image_from_txin_v(i, ki)) + { + if (m_key_images.count(ki)) + { + auto it = m_key_images.find(ki); + 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)); + unconfirmed_wti.td.spn.push_back(m_transfers[it->second].amount()); + + WLT_CHECK_AND_ASSERT_MES(unconfirmed_wti.asset_id == null_pkey || unconfirmed_wti.asset_id == m_transfers[it->second].get_asset_id(), (void)0, "TODO: BAD case with asset_id"); + unconfirmed_wti.asset_id = m_transfers[it->second].get_asset_id(); + if (unconfirmed_wti.asset_id == native_coin_asset_id) + native_coin_inputs_amount += m_transfers[it->second].amount(); + } + } + } + + prepare_wti(unconfirmed_wti, 0, m_core_runtime_config.get_core_time(), tx, native_coin_inputs_amount - (native_coin_change_amount + get_tx_fee(tx)), money_transfer2_details()); rise_on_transfer2(unconfirmed_wti); } //---------------------------------------------------------------------------------------------------- @@ -6396,7 +6390,7 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx if (ftp.tx_version > TRANSACTION_VERSION_PRE_HF4) { for (const auto& el : msc.proposal_info.to_alice) - needed_money_map[el.asset_id].needed_amount += el.amount; + needed_money_map[el.asset_id].needed_amount += el.amount; } if (msc.escrow) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 4242e451..4406be40 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1011,9 +1011,6 @@ private: const std::vector& recipients, const std::vector& selected_indicies, const std::vector& splitted_dsts); - bool read_money_transfer2_details_from_tx(const currency::transaction& tx, - const std::vector& splitted_dsts, - wallet_public::wallet_transfer_info_details& wtd); void update_current_tx_limit(); void prepare_wti(wallet_public::wallet_transfer_info& wti, uint64_t height, uint64_t timestamp, const currency::transaction& tx, uint64_t amount, const money_transfer2_details& td);