diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 7303fb06..d1606992 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1664,10 +1664,10 @@ namespace currency txin_htlc htlc_in = AUTO_VAL_INIT(htlc_in); x.tx_type = get_tx_type_ex(x.tx, htlc_out, htlc_in); - if(x.tx_type == GUI_TX_TYPE_HTLC_DEPOSIT && x.is_income == true) + if(x.tx_type == GUI_TX_TYPE_HTLC_DEPOSIT && !x.has_outgoing_entries()) { //need to override amount - x.amount = htlc_out.amount; + x.get_native_income_amount() = htlc_out.amount; } } @@ -2941,7 +2941,6 @@ namespace currency if (is_out_to_acc(acc.account_address, boost::get(o.target), derivation, offset)) { outs.emplace_back(offset, o.amount); - money_transfered += o.amount; } return true; } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 8d3914c4..3a693184 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6224,12 +6224,6 @@ void wallet2::add_sent_unconfirmed_tx(const currency::transaction& tx, unconfirmed_wti.selected_indicies = selected_indicies; - - // 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 - // RE: TODO - discuss with @sowl -- zoidberg - // check all inputs for spending (compare key images) //scan key images for (auto& i : tx.vin) diff --git a/src/wallet/wallet2_escrow.cpp b/src/wallet/wallet2_escrow.cpp index 12c46142..2efab94c 100644 --- a/src/wallet/wallet2_escrow.cpp +++ b/src/wallet/wallet2_escrow.cpp @@ -55,7 +55,7 @@ bool wallet2::validate_escrow_proposal(const wallet_public::wallet_transfer_info // (2/5) extra decrypted_items.clear(); - bool r = decrypt_payload_items(wti.is_income, prop.tx_template, m_account.get_keys(), decrypted_items); + bool r = decrypt_payload_items(wti.is_income_mode_encryption(), prop.tx_template, m_account.get_keys(), decrypted_items); LOC_CHK(r, "failed to decrypt payload items in proposal tx"); currency::tx_service_attachment tsa = AUTO_VAL_INIT(tsa); diff --git a/src/wallet/wallet_id_adapter.h b/src/wallet/wallet_id_adapter.h index e794795f..73b3627b 100644 --- a/src/wallet/wallet_id_adapter.h +++ b/src/wallet/wallet_id_adapter.h @@ -12,7 +12,7 @@ class i_backend_wallet_callback { public: virtual void on_new_block(size_t wallet_id, uint64_t /*height*/, const currency::block& /*block*/) {} - virtual void on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) {} + virtual void on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) {} virtual void on_pos_block_found(size_t wallet_id, const currency::block& /*block*/) {} 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) {} @@ -32,7 +32,7 @@ struct i_wallet_to_i_backend_adapter: public tools::i_wallet2_callback virtual void on_new_block(uint64_t height, const currency::block& block) { m_pbackend->on_new_block(m_wallet_id, height, block); } - virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) { + virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) { m_pbackend->on_transfer2(m_wallet_id, wti, balances, total_mined); } virtual void on_pos_block_found(const currency::block& wti) { diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index effc3b8d..23529d13 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -91,9 +91,9 @@ namespace wallet_public struct wallet_sub_transfer_info { - uint64_t amount; - bool is_income; - crypto::public_key asset_id; // not blinded, not premultiplied by 1/8 + uint64_t amount = 0; + bool is_income = false; + crypto::public_key asset_id = currency::native_coin_asset_id; // not blinded, not premultiplied by 1/8 BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(amount) @@ -210,6 +210,24 @@ namespace wallet_public } return 0; } + uint64_t& get_native_income_amount() + { + for (auto& st : subtransfers) + { + if (st.asset_id == currency::native_coin_asset_id) + if (st.is_income) + { + return st.amount; + } + else + { + throw std::runtime_error("Unexpected wallet_transfer_info: native is not income type"); + } + } + subtransfers.push_back(wallet_sub_transfer_info()); + subtransfers.back().is_income = true; + return subtransfers.back().amount; + } }; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 6ea7b2e4..87f90a0c 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -688,10 +688,11 @@ namespace tools } } - if (wti.is_income && req.in) + bool has_outgoing = wti.has_outgoing_entries(); + if (!has_outgoing && req.in) res.in.push_back(wti); - if (!wti.is_income && req.out) + if (has_outgoing && req.out) res.out.push_back(wti); return true; // continue @@ -701,7 +702,7 @@ namespace tools if (req.pool) { w.get_wallet()->enumerate_unconfirmed_transfers([&](const wallet_public::wallet_transfer_info& wti) -> bool { - if ((wti.is_income && req.in) || (!wti.is_income && req.out)) + if ((!wti.has_outgoing_entries() && req.in) || (wti.has_outgoing_entries() && req.out)) res.pool.push_back(wti); return true; // continue }); diff --git a/tests/core_tests/atomic_tests.cpp b/tests/core_tests/atomic_tests.cpp index 41382a51..f04d984a 100644 --- a/tests/core_tests/atomic_tests.cpp +++ b/tests/core_tests/atomic_tests.cpp @@ -24,7 +24,7 @@ using namespace currency; struct wallet_tests_callback_handler : public tools::i_wallet2_callback { - virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) + virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) { all_wtis.push_back(wti); } diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h index b95613af..82208abd 100644 --- a/tests/core_tests/chaingen_helpers.h +++ b/tests/core_tests/chaingen_helpers.h @@ -316,3 +316,22 @@ inline bool put_alias_via_tx_to_list(const currency::hard_forks_descriptor& hf, return true; } + +//--------------------------------------------------------------- +namespace currency +{ + //this lookup_acc_outs overload is mostly for backward compatibility for tests, ineffective from performance perspective, should not be used in wallet + inline bool lookup_acc_outs(const currency::account_keys& acc, const currency::transaction& tx, std::vector& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation) + { + sum_of_native_outs = 0; + bool res = currency::lookup_acc_outs(acc, tx, outs, derivation); + for (const auto& o : outs) + { + if (o.asset_id == currency::native_coin_asset_id) + { + sum_of_native_outs += o.amount; + } + } + return res; + } +} diff --git a/tests/core_tests/escrow_wallet_tests.cpp b/tests/core_tests/escrow_wallet_tests.cpp index 6cee1610..49521201 100644 --- a/tests/core_tests/escrow_wallet_tests.cpp +++ b/tests/core_tests/escrow_wallet_tests.cpp @@ -17,7 +17,7 @@ using namespace currency; struct wallet_tests_callback_handler : public tools::i_wallet2_callback { - virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) + virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) { all_wtis.push_back(wti); } diff --git a/tests/core_tests/hard_fork_2.cpp b/tests/core_tests/hard_fork_2.cpp index 8f434d2b..3f5b3c83 100644 --- a/tests/core_tests/hard_fork_2.cpp +++ b/tests/core_tests/hard_fork_2.cpp @@ -140,7 +140,7 @@ bool hard_fork_2_tx_payer_in_wallet::c1(currency::core& c, size_t ev_index, cons size_t callback_counter = 0; std::shared_ptr l(new wlt_lambda_on_transfer2_wrapper( - [&](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { + [&](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { CHECK_AND_ASSERT_THROW_MES(wti.show_sender, "show_sender is false"); CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.size() == 1, "incorrect wti.remote_addresses.size() = " << wti.remote_addresses.size()); CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.front() == m_accounts[MINER_ACC_IDX].get_public_address_str(), "wti.remote_addresses.front is incorrect"); @@ -234,7 +234,7 @@ bool hard_fork_2_tx_payer_in_wallet::c1(currency::core& c, size_t ev_index, cons CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); std::shared_ptr l2(new wlt_lambda_on_transfer2_wrapper( - [&](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { + [&](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { CHECK_AND_ASSERT_THROW_MES(wti.amount == MK_TEST_COINS(2), "incorrect wti.amount = " << print_money_brief(wti.amount)); CHECK_AND_ASSERT_THROW_MES(wti.show_sender, "show_sender is false"); CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.size() == 1, "incorrect wti.remote_addresses.size() = " << wti.remote_addresses.size()); @@ -367,7 +367,7 @@ bool hard_fork_2_tx_receiver_in_wallet::c1(currency::core& c, size_t ev_index, c CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); std::shared_ptr l(new wlt_lambda_on_transfer2_wrapper( - [&](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { + [&](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { CHECK_AND_ASSERT_THROW_MES(!wti.is_income, "wti.is_income is " << wti.is_income); CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.size() == 2, "incorrect wti.remote_addresses.size() = " << wti.remote_addresses.size()); CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.front() == m_accounts[MINER_ACC_IDX].get_public_address_str(), "wti.remote_addresses.front is incorrect"); @@ -409,7 +409,7 @@ bool hard_fork_2_tx_receiver_in_wallet::c1(currency::core& c, size_t ev_index, c CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); std::shared_ptr l2(new wlt_lambda_on_transfer2_wrapper( - [&](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { + [&](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { CHECK_AND_ASSERT_THROW_MES(!wti.is_income, "wti.is_income is " << wti.is_income); CHECK_AND_ASSERT_THROW_MES(wti.amount == MK_TEST_COINS(4), "incorrect wti.amount = " << print_money_brief(wti.amount)); CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.size() == 2, "incorrect wti.remote_addresses.size() = " << wti.remote_addresses.size()); @@ -1003,7 +1003,7 @@ bool hard_fork_2_awo_wallets_basic_test::c1(currency::core& c, size bool callback_called = false; std::shared_ptr l(new wlt_lambda_on_transfer2_wrapper( - [&callback_called](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { + [&callback_called](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { callback_called = true; return true; } diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp index cd8643ca..150ec14a 100644 --- a/tests/core_tests/transaction_tests.cpp +++ b/tests/core_tests/transaction_tests.cpp @@ -10,7 +10,7 @@ #include "currency_core/account.h" #include "currency_core/currency_format_utils.h" #include "misc_language.h" - +#include "chaingen_helpers.h" using namespace currency; diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index 929b8d50..306b01d0 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -1598,7 +1598,7 @@ bool gen_wallet_decrypted_attachments::generate(std::vector& e return true; } -void gen_wallet_decrypted_attachments::on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) +void gen_wallet_decrypted_attachments::on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) { m_on_transfer2_called = true; //try { @@ -1831,7 +1831,7 @@ bool gen_wallet_alias_via_special_wallet_funcs::c1(currency::core& c, size_t ev_ uint64_t biggest_alias_reward = get_alias_coast_from_fee("a", TESTS_DEFAULT_FEE); std::shared_ptr l(new wlt_lambda_on_transfer2_wrapper( - [biggest_alias_reward](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { + [biggest_alias_reward](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { return std::count(wti.remote_aliases.begin(), wti.remote_aliases.end(), "minerminer") == 1 && wti.amount == biggest_alias_reward; } @@ -3307,7 +3307,7 @@ bool wallet_unconfimed_tx_balance::c1(currency::core& c, size_t ev_index, const bool callback_is_ok = false; // this callback will ba called from within wallet2::transfer() below std::shared_ptr l(new wlt_lambda_on_transfer2_wrapper( - [&callback_is_ok](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool + [&callback_is_ok](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { CHECK_AND_ASSERT_MES(balance == MK_TEST_COINS(70), false, "invalid balance: " << print_money_brief(balance)); CHECK_AND_ASSERT_MES(unlocked_balance == MK_TEST_COINS(50), false, "invalid unlocked_balance: " << print_money_brief(unlocked_balance)); @@ -3457,7 +3457,7 @@ bool wallet_sending_to_integrated_address::c1(currency::core& c, size_t ev_index bool callback_succeded = false; std::shared_ptr l(new wlt_lambda_on_transfer2_wrapper( - [&](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { + [&](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool { LOG_PRINT_YELLOW("on_transfer: " << print_money_brief(wti.amount) << " pid len: " << wti.payment_id.size() << " remote addr: " << (wti.remote_addresses.size() > 0 ? wti.remote_addresses[0] : ""), LOG_LEVEL_0); if (wti.payment_id.empty()) return true; // skip another outputs diff --git a/tests/core_tests/wallet_tests.h b/tests/core_tests/wallet_tests.h index b5368fb1..08720808 100644 --- a/tests/core_tests/wallet_tests.h +++ b/tests/core_tests/wallet_tests.h @@ -110,7 +110,7 @@ struct gen_wallet_decrypted_attachments : public wallet_test, virtual public too bool generate(std::vector& events) const; // intrface tools::i_wallet2_callback - virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) override; + virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) override; private: mutable bool m_on_transfer2_called; diff --git a/tests/core_tests/wallet_tests_basic.h b/tests/core_tests/wallet_tests_basic.h index ef044c48..6fc66a99 100644 --- a/tests/core_tests/wallet_tests_basic.h +++ b/tests/core_tests/wallet_tests_basic.h @@ -48,6 +48,17 @@ protected: std::shared_ptr m_core_proxy; }; + +const tools::wallet_public::asset_balance_entry get_native_balance_entry(const std::list& balances) +{ + for (const auto& b : balances) + { + if (b.asset_info.asset_id == currency::native_coin_asset_id) + return b; + } + return tools::wallet_public::asset_balance_entry(); +} + // wallet callback helper to check balance in wallet callbacks // see escrow_balance test for usage example struct wallet_callback_balance_checker : public tools::i_wallet2_callback @@ -62,8 +73,12 @@ struct wallet_callback_balance_checker : public tools::i_wallet2_callback m_called = false; } - virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) override + virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) override { + tools::wallet_public::asset_balance_entry native_balance = get_native_balance_entry(balances); + uint64_t balance = native_balance.total; + uint64_t unlocked_balance = native_balance.unlocked; + m_called = true; m_result = false; CHECK_AND_ASSERT_MES(m_balance == UINT64_MAX || balance == m_balance, (void)(0), m_label << " balance is incorrect: " << currency::print_money_brief(balance) << ", expected: " << currency::print_money_brief(m_balance)); @@ -94,11 +109,11 @@ struct wallet_callback_balance_checker : public tools::i_wallet2_callback struct wlt_lambda_on_transfer2_wrapper : public tools::i_wallet2_callback { - typedef std::function&, uint64_t)> Func; + typedef std::function&, uint64_t)> Func; wlt_lambda_on_transfer2_wrapper(Func callback) : m_result(false), m_callback(callback) {} - virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) override + virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) override { - m_result = m_callback(wti, balance, unlocked_balance, total_mined); + m_result = m_callback(wti, balances, total_mined); } bool m_result; Func m_callback;