From b827779c7ce138316fe396f8b16f4b01d5d4fa5e Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 6 Jun 2023 23:05:53 +0200 Subject: [PATCH] deep refactoring of recent_transfers structure against confidential assets - still pretty much all broken --- src/currency_core/currency_config.h | 4 +- src/currency_core/currency_format_utils.cpp | 18 +- src/currency_core/currency_format_utils.h | 6 +- src/wallet/wallet2.cpp | 257 ++++++++++++-------- src/wallet/wallet2.h | 76 ++++-- src/wallet/wallet_id_adapter.h | 6 +- src/wallet/wallet_public_structs_defs.h | 27 +- tests/core_tests/atomic_tests.cpp | 2 +- tests/core_tests/escrow_wallet_tests.cpp | 2 +- tests/core_tests/hard_fork_2.cpp | 10 +- tests/core_tests/wallet_tests.cpp | 8 +- tests/core_tests/wallet_tests.h | 2 +- tests/core_tests/wallet_tests_basic.h | 6 +- 13 files changed, 260 insertions(+), 164 deletions(-) diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index de929b98..f1ec0dfc 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -236,9 +236,9 @@ #define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin" #ifndef TESTNET -#define WALLET_FILE_SERIALIZATION_VERSION 155 +#define WALLET_FILE_SERIALIZATION_VERSION 160 #else -#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+71) +#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+72) #endif #define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 4504aa14..1a048254 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -2889,12 +2889,12 @@ namespace currency return true; } //--------------------------------------------------------------- - bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation) + bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector& outs, crypto::key_derivation& derivation) { crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx); if (null_pkey == tx_pub_key) return false; - return lookup_acc_outs(acc, tx, get_tx_pub_key_from_extra(tx), outs, sum_of_native_outs, derivation); + return lookup_acc_outs(acc, tx, get_tx_pub_key_from_extra(tx), outs, derivation); } //--------------------------------------------------------------- bool check_tx_derivation_hint(const transaction& tx, const crypto::key_derivation& derivation) @@ -2922,7 +2922,7 @@ namespace currency return false; } //--------------------------------------------------------------- - bool lookup_acc_outs_genesis(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector& outs, uint64_t& money_transfered, crypto::key_derivation& derivation) + bool lookup_acc_outs_genesis(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector& outs, crypto::key_derivation& derivation) { uint64_t offset = 0; bool r = get_account_genesis_offset_by_address(get_account_address_as_str(acc.account_address), offset); @@ -2943,22 +2943,21 @@ namespace currency return true; } //--------------------------------------------------------------- - bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation) + bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector& outs, crypto::key_derivation& derivation) { std::list htlc_info_list; - return lookup_acc_outs(acc, tx, tx_pub_key, outs, sum_of_native_outs, derivation, htlc_info_list); + return lookup_acc_outs(acc, tx, tx_pub_key, outs, derivation, htlc_info_list); } //--------------------------------------------------------------- - bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation, std::list& htlc_info_list) + bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector& outs, crypto::key_derivation& derivation, std::list& htlc_info_list) { - sum_of_native_outs = 0; bool r = generate_key_derivation(tx_pub_key, acc.view_secret_key, derivation); CHECK_AND_ASSERT_MES(r, false, "unable to generate derivation from tx_pub = " << tx_pub_key << " * view_sec, invalid tx_pub?"); if (is_coinbase(tx) && get_block_height(tx) == 0 && tx_pub_key == ggenesis_tx_pub_key) { //genesis coinbase - return lookup_acc_outs_genesis(acc, tx, tx_pub_key, outs, sum_of_native_outs, derivation); + return lookup_acc_outs_genesis(acc, tx, tx_pub_key, outs, derivation); } if (!check_tx_derivation_hint(tx, derivation)) @@ -2975,7 +2974,6 @@ namespace currency if (is_out_to_acc(acc.account_address, t, derivation, output_index)) { outs.emplace_back(output_index, o.amount); - sum_of_native_outs += o.amount; } VARIANT_CASE_CONST(txout_multisig, t) if (is_out_to_acc(acc.account_address, t, derivation, output_index)) @@ -3016,8 +3014,6 @@ namespace currency crypto::point_t asset_id_pt = crypto::point_t(zo.blinded_asset_id).modify_mul8() - asset_id_blinding_mask * crypto::c_point_X; crypto::public_key asset_id = asset_id_pt.to_public_key(); outs.emplace_back(output_index, amount, amount_blinding_mask, asset_id_blinding_mask, asset_id); - if (asset_id == currency::native_coin_asset_id) - sum_of_native_outs += amount; } } VARIANT_SWITCH_END(); diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 0d8ebaf5..cbe82cc4 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -331,9 +331,9 @@ namespace currency bool is_out_to_acc(const account_public_address& addr, const txout_to_key& out_key, const crypto::key_derivation& derivation, size_t output_index); bool is_out_to_acc(const account_public_address& addr, const txout_multisig& out_multisig, const crypto::key_derivation& derivation, size_t output_index); bool is_out_to_acc(const account_public_address& addr, const tx_out_zarcanum& zo, const crypto::key_derivation& derivation, size_t output_index, uint64_t& decoded_amount, crypto::public_key& decoded_asset_id, crypto::scalar_t& amount_blinding_mask, crypto::scalar_t& asset_id_blinding_mask); - bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation); - bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation, std::list& htlc_info_list); - bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation); + bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector& outs, crypto::key_derivation& derivation); + bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector& outs, crypto::key_derivation& derivation, std::list& htlc_info_list); + bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector& outs, crypto::key_derivation& derivation); bool get_tx_fee(const transaction& tx, uint64_t & fee); uint64_t get_tx_fee(const transaction& tx); bool derive_ephemeral_key_helper(const account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, keypair& in_ephemeral); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 05fe16f5..ccf87cd0 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -431,11 +431,10 @@ const crypto::public_key& wallet2::out_get_pub_key(const currency::tx_out_v& out //---------------------------------------------------------------------------------------------------- void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t height, const currency::block& b, const std::vector* pglobal_indexes) { - std::vector recipients, remote_aliases; - process_unconfirmed(tx, recipients, remote_aliases); - //check for transaction spends - process_transaction_context ptc = AUTO_VAL_INIT(ptc); + process_transaction_context ptc(tx); + + process_unconfirmed(tx, ptc.recipients, ptc.remote_aliases); // check all outputs for spending (compare key images) ptc.coin_base_tx = is_coinbase(tx, ptc.is_pos_coinbase); @@ -443,6 +442,8 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t ptc.is_derived_from_coinbase = !ptc.is_pos_coinbase; ptc.height = height; + + for(auto& in : tx.vin) { ptc.sub_i = 0; @@ -464,7 +465,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t { it->second.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_SPENT; it->second.m_spent_height = height; - WLT_LOG_L0("Spent multisig out: " << multisig_id << ", amount: " << print_money(currency::get_amount_from_variant(in)) << ", with tx: " << get_transaction_hash(tx) << ", at height " << height); + WLT_LOG_L0("Spent multisig out: " << multisig_id << ", amount: " << print_money(currency::get_amount_from_variant(in)) << ", with tx: " << ptc.tx_hash() << ", at height " << height); ptc.mtd.spent_indices.push_back(ptc.i); } } @@ -494,7 +495,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t m_transfers[it->second].m_spent_height = height; transfer_details_extra_option_htlc_info& tdeohi = get_or_add_field_to_variant_vector(td.varian_options); tdeohi.origin = in_htlc.hltc_origin; - tdeohi.redeem_tx_id = get_transaction_hash(tx); + tdeohi.redeem_tx_id = ptc.tx_hash(); } } VARIANT_SWITCH_END(); @@ -509,7 +510,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t uint64_t max_out_unlock_time = 0; std::vector outs; - uint64_t sum_of_native_outs = 0; // TODO: @#@# correctly calculate tx_money_got_in_outs for post-HF4 + //uint64_t sum_of_native_outs = 0; // TODO: @#@# correctly calculate tx_money_got_in_outs for post-HF4 crypto::public_key tx_pub_key = null_pkey; bool r = parse_and_validate_tx_extra(tx, tx_pub_key); THROW_IF_TRUE_WALLET_EX(!r, error::tx_extra_parse_error, tx); @@ -517,7 +518,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t //check for transaction income crypto::key_derivation derivation = AUTO_VAL_INIT(derivation); std::list htlc_info_list; - r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, sum_of_native_outs, derivation, htlc_info_list); + r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, derivation, htlc_info_list); THROW_IF_TRUE_WALLET_EX(!r, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys()); if (!outs.empty()) @@ -605,17 +606,17 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it->second < m_transfers.size(), "m_key_images entry has wrong m_transfers index, it->second: " << it->second << ", m_transfers.size(): " << m_transfers.size()); const transfer_details& local_td = m_transfers[it->second]; std::stringstream ss; - ss << "tx " << get_transaction_hash(tx) << " @ block " << height << " has output #" << o << " with key image " << ki << " that has already been seen in output #" << + ss << "tx " << ptc.tx_hash() << " @ block " << height << " has output #" << o << " with key image " << ki << " that has already been seen in output #" << local_td.m_internal_output_index << " in tx " << get_transaction_hash(local_td.m_ptx_wallet_info->m_tx) << " @ block " << local_td.m_spent_height << ". This output can't ever be spent and will be skipped."; WLT_LOG_YELLOW(ss.str(), LOG_LEVEL_0); if (m_wcallback) m_wcallback->on_message(i_wallet2_callback::ms_yellow, ss.str()); - if (out.is_native_coin()) - { - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(sum_of_native_outs >= out.amount, "sum_of_native_outs: " << sum_of_native_outs << ", out.amount:" << out.amount); - sum_of_native_outs -= out.amount; - } + //if (out.is_native_coin()) + //{ + //WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(sum_of_native_outs >= out.amount, "sum_of_native_outs: " << sum_of_native_outs << ", out.amount:" << out.amount); + //sum_of_native_outs -= out.amount; + //} continue; // skip the output } } @@ -624,16 +625,16 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t out_get_mixin_attr(out_v) != CURRENCY_TO_KEY_OUT_FORCED_NO_MIX) { std::stringstream ss; - ss << "output #" << o << " from tx " << get_transaction_hash(tx) << " with amount " << print_money_brief(outs[i_in_outs].amount) + ss << "output #" << o << " from tx " << ptc.tx_hash() << " with amount " << print_money_brief(outs[i_in_outs].amount) << " is targeted to this auditable wallet and has INCORRECT mix_attr = " << (uint64_t)out_get_mixin_attr(out_v) << ". Output is IGNORED."; WLT_LOG_RED(ss.str(), LOG_LEVEL_0); if (m_wcallback) m_wcallback->on_message(i_wallet2_callback::ms_red, ss.str()); - if (out.is_native_coin()) - { - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(sum_of_native_outs >= out.amount, "sum_of_native_outs: " << sum_of_native_outs << ", out.amount:" << out.amount); - sum_of_native_outs -= out.amount; - } + //if (out.is_native_coin()) + //{ + //WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(sum_of_native_outs >= out.amount, "sum_of_native_outs: " << sum_of_native_outs << ", out.amount:" << out.amount); + //sum_of_native_outs -= out.amount; + //} continue; // skip the output } @@ -693,7 +694,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t //active htlc auto amount_gindex_pair = std::make_pair(td.m_amount, td.m_global_output_index); m_active_htlcs[amount_gindex_pair] = transfer_index; - m_active_htlcs_txid[get_transaction_hash(tx)] = transfer_index; + m_active_htlcs_txid[ptc.tx_hash()] = transfer_index; //add payer to extra options currency::tx_payer payer = AUTO_VAL_INIT(payer); if (het.is_wallet_owns_redeem) @@ -712,11 +713,15 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t } } + else + { + ptc.total_balance_change[td.get_asset_id()] += td.amount(); + add_transfer_to_transfers_cache(td.m_amount, transfer_index, td.get_asset_id()); + } + if (td.m_key_image != currency::null_ki) m_key_images[td.m_key_image] = transfer_index; - add_transfer_to_transfers_cache(td.m_amount, transfer_index, td.get_asset_id()); - if (is_watch_only() && is_auditable()) { WLT_CHECK_AND_ASSERT_MES_NO_RET(td.m_global_output_index != WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED, "td.m_global_output_index != WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED validation failed"); @@ -732,17 +737,17 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t { if (td.is_native_coin()) { - WLT_LOG_L0("Received native coins, transfer #" << transfer_index << ", amount: " << print_money_brief(td.amount()) << (out_type_zc ? " (hidden)" : "") << ", with tx: " << get_transaction_hash(tx) << ", at height " << height); + WLT_LOG_L0("Received native coins, transfer #" << transfer_index << ", amount: " << print_money_brief(td.amount()) << (out_type_zc ? " (hidden)" : "") << ", with tx: " << ptc.tx_hash() << ", at height " << height); } else { // TODO @#@# output asset's ticker/name - WLT_LOG_L0("Received asset " << print16(td.get_asset_id()) << ", transfer #" << transfer_index << ", amount: " << print_money_brief(td.amount()) << (out_type_zc ? " (hidden)" : "") << ", with tx: " << get_transaction_hash(tx) << ", at height " << height); + WLT_LOG_L0("Received asset " << print16(td.get_asset_id()) << ", transfer #" << transfer_index << ", amount: " << print_money_brief(td.amount()) << (out_type_zc ? " (hidden)" : "") << ", with tx: " << ptc.tx_hash() << ", at height " << height); } } else if (out_type_htlc) { - WLT_LOG_L0("Detected HTLC[" << (td.m_flags&WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM ? "REDEEM" : "REFUND") << "], transfer #" << transfer_index << ", amount: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx) << ", at height " << height); + WLT_LOG_L0("Detected HTLC[" << (td.m_flags&WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM ? "REDEEM" : "REFUND") << "], transfer #" << transfer_index << ", amount: " << print_money(td.amount()) << ", with tx: " << ptc.tx_hash() << ", at height " << height); } } else if (out_type_multisig) @@ -753,37 +758,60 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t tdb.m_ptx_wallet_info = pwallet_info; tdb.m_internal_output_index = o; tdb.m_amount = outs[i_in_outs].amount; - WLT_LOG_L0("Received multisig, multisig out id: " << multisig_id << ", amount: " << tdb.amount() << ", with tx: " << get_transaction_hash(tx)); + WLT_LOG_L0("Received multisig, multisig out id: " << multisig_id << ", amount: " << tdb.amount() << ", with tx: " << ptc.tx_hash()); } else { - WLT_LOG_YELLOW("Unexpected output type: " << out_v.type().name() << ", out index: " << o << " in tx " << get_transaction_hash(tx), LOG_LEVEL_0); + WLT_LOG_YELLOW("Unexpected output type: " << out_v.type().name() << ", out index: " << o << " in tx " << ptc.tx_hash(), LOG_LEVEL_0); } } } } - std::string payment_id; - if (sum_of_native_outs != 0 && get_payment_id_from_tx(tx.attachment, payment_id)) - { - // TODO @#@# this code takes care only of native coins - // we need to add assets support - uint64_t received = (ptc.sum_of_own_native_inputs < sum_of_native_outs) ? sum_of_native_outs - ptc.sum_of_own_native_inputs : 0; - if (0 < received && payment_id.size()) + //do final calculations + bool has_in_transfers = false; + bool has_out_transfers = false; + for (const auto& bce : ptc.total_balance_change) + { + if (bce.second > 0) { - payment_details payment; - payment.m_tx_hash = currency::get_transaction_hash(tx); - payment.m_amount = received; - payment.m_block_height = height; - payment.m_unlock_time = max_out_unlock_time; - m_payments.emplace(payment_id, payment); - WLT_LOG_L2("Payment found, id (hex): " << epee::string_tools::buff_to_hex_nodelimer(payment_id) << ", tx: " << payment.m_tx_hash << ", amount: " << print_money_brief(payment.m_amount)); + has_in_transfers = true; + } + else if (bce.second < 0) + { + has_out_transfers = true; } } + + std::string payment_id; + if (has_in_transfers && get_payment_id_from_tx(tx.attachment, payment_id) && payment_id.size()) + { + payment_details payment; + payment.m_tx_hash = ptc.tx_hash(); + payment.m_amount = 0; + payment.m_block_height = height; + payment.m_unlock_time = max_out_unlock_time; + + for (const auto& bce : ptc.total_balance_change) + { + if (bce.second > 0) + { + if (bce.first == currency::native_coin_asset_id) + { + payment.m_amount = static_cast(bce.second); + }else + { + payment.subtransfers.push_back(payment_details_subtransfer{ bce.first, static_cast(bce.second)}); + } + } + } + m_payments.emplace(payment_id, payment); + WLT_LOG_L2("Payment found, id (hex): " << epee::string_tools::buff_to_hex_nodelimer(payment_id) << ", tx: " << payment.m_tx_hash << ", amount: " << print_money_brief(payment.m_amount) << "subtransfers = " << payment.subtransfers.size()); + } - if (ptc.sum_of_own_native_inputs) + if (ptc.spent_own_native_inputs) { //check if there are asset_registration that belong to this wallet asset_descriptor_operation ado = AUTO_VAL_INIT(ado); @@ -797,13 +825,13 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t if (!r) { //not critical error, continue to work - LOG_ERROR("Failed to derive_key_pair_from_key_pair for asset_descriptor_operation in tx " << get_transaction_hash(tx)); + LOG_ERROR("Failed to derive_key_pair_from_key_pair for asset_descriptor_operation in tx " << ptc.tx_hash()); }else { if (self_check != ado.descriptor.owner) { //still not critical error - LOG_ERROR("Public key from asset_descriptor_operation(" << ado.descriptor.owner << ") not much with derived public key(" << self_check << "), for tx" << get_transaction_hash(tx)); + LOG_ERROR("Public key from asset_descriptor_operation(" << ado.descriptor.owner << ") not much with derived public key(" << self_check << "), for tx" << ptc.tx_hash()); } else { @@ -831,6 +859,13 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t } } + if (has_in_transfers || has_out_transfers) + { + ptc.timestamp = get_block_datetime(b); + handle_money(b, ptc); + } + + /* if (ptc.sum_of_own_native_inputs) {//this actually is transfer transaction, notify about spend if (ptc.sum_of_own_native_inputs > sum_of_native_outs) @@ -841,7 +876,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t {//strange transfer, seems that in one transaction have transfers from different wallets. if (!is_coinbase(tx)) { - WLT_LOG_RED("Unusual transaction " << currency::get_transaction_hash(tx) << ", sum_of_native_inputs: " << ptc.sum_of_own_native_inputs << ", sum_of_native_outs: " << sum_of_native_outs, LOG_LEVEL_0); + WLT_LOG_RED("Unusual transaction " << ptc.tx_hash() << ", sum_of_native_inputs: " << ptc.sum_of_own_native_inputs << ", sum_of_native_outs: " << sum_of_native_outs, LOG_LEVEL_0); } handle_money_received2(b, tx, (sum_of_native_outs - (ptc.sum_of_own_native_inputs - get_tx_fee(tx))), ptc.mtd); } @@ -854,7 +889,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t } else if (currency::is_derivation_used_to_encrypt(tx, derivation)) { - //transaction doesn't transfer actually money, bud bring some information + //transaction doesn't transfer actually money, but bring some information handle_money_received2(b, tx, 0, ptc.mtd); } else if (ptc.mtd.spent_indices.size()) @@ -862,7 +897,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t // multisig spend detected handle_money_spent2(b, tx, 0, ptc.mtd, recipients, remote_aliases); } - } + }*/ } //---------------------------------------------------------------------------------------------------- void wallet2::prepare_wti_decrypted_attachments(wallet_public::wallet_transfer_info& wti, const std::vector& decrypted_att) @@ -883,11 +918,10 @@ void wallet2::prepare_wti_decrypted_attachments(wallet_public::wallet_transfer_i } } - - if (wti.is_income) + if (wti.is_income_mode_encryption()) { account_public_address sender_address = AUTO_VAL_INIT(sender_address); - wti.show_sender = handle_2_alternative_types_in_variant_container(decrypted_att, [&](const tx_payer& p) { sender_address = p.acc_addr; return false; /* <- continue? */ } ); + wti.show_sender = handle_2_alternative_types_in_variant_container(decrypted_att, [&](const tx_payer& p) { sender_address = p.acc_addr; return false; /* <- continue? */ }); if (wti.show_sender) wti.remote_addresses.push_back(currency::get_account_address_as_str(sender_address)); } @@ -902,7 +936,7 @@ void wallet2::prepare_wti_decrypted_attachments(wallet_public::wallet_transfer_i else addr_str = currency::get_account_address_and_payment_id_as_str(p.acc_addr, wti.payment_id); // show integrated address if there's a payment id provided wti.remote_addresses.push_back(addr_str); - LOG_PRINT_YELLOW("prepare_wti_decrypted_attachments, income=false, wti.amount = " << print_money_brief(wti.amount) << ", rem. addr = " << addr_str, LOG_LEVEL_0); + LOG_PRINT_YELLOW("prepare_wti_decrypted_attachments, income=false, rem. addr = " << addr_str, LOG_LEVEL_0); return true; // continue iterating through the container }); } @@ -1226,11 +1260,10 @@ bool wallet2::handle_proposal(wallet_public::wallet_transfer_info& wti, const bc //scan outputs to figure out amount of change in escrow 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(), prop.tx_template, outs, tx_money_got_in_outs, derivation); + bool r = lookup_acc_outs(m_account.get_keys(), prop.tx_template, outs, derivation); THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "Failed to lookup_acc_outs for tx: " << get_transaction_hash(prop.tx_template)); - add_transfers_to_expiration_list(found_transfers, ed.expiration_time, tx_money_got_in_outs, wti.tx_hash); + add_transfers_to_expiration_list(found_transfers, ed.expiration_time, wti.tx_hash); WLT_LOG_GREEN("Locked " << found_transfers.size() << " transfers due to proposal " << ms_id, LOG_LEVEL_0); } @@ -1255,7 +1288,8 @@ bool wallet2::handle_release_contract(wallet_public::wallet_transfer_info& wti, else if (release_instruction == BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_BURN) { change_contract_state(it->second, wallet_public::escrow_contract_details_basic::contract_released_burned, ms_id, wti); - wti.amount = it->second.private_detailes.amount_to_pay + it->second.private_detailes.amount_a_pledge + it->second.private_detailes.amount_b_pledge; + WLT_CHECK_AND_ASSERT_MES(wti.subtransfers.size(), false, "Unexpected subtransfers size"); //TODO: subject for refactoring + wti.subtransfers.back().amount = it->second.private_detailes.amount_to_pay + it->second.private_detailes.amount_a_pledge + it->second.private_detailes.amount_b_pledge; if (!it->second.is_a) { wti.fee = currency::get_tx_fee(wti.tx); @@ -1312,7 +1346,8 @@ bool wallet2::handle_contract(wallet_public::wallet_transfer_info& wti, const bc //in code which know escrow protocol, and we know that fee paid by B(seller) if (ed.is_a) { - wti.amount += wti.fee; + WLT_CHECK_AND_ASSERT_MES(wti.subtransfers.size(), false, "Unexpected subtransfers size"); //TODO: subject for refactoring + wti.subtransfers.back().amount += wti.fee; wti.fee = 0; } @@ -1413,19 +1448,19 @@ bool wallet2::process_contract_info(wallet_public::wallet_transfer_info& wti, co return true; } //----------------------------------------------------------------------------------------------------- -void wallet2::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) +void wallet2::prepare_wti(wallet_public::wallet_transfer_info& wti, const process_transaction_context& tx_process_context) { PROFILE_FUNC("wallet2::prepare_wti"); - wti.tx = tx; - wti.amount = amount; - wti.height = height; - fill_transfer_details(tx, td, wti.td); - wti.unlock_time = get_max_unlock_time_from_receive_indices(tx, td); - wti.timestamp = timestamp; + wti.tx = tx_process_context.tx; + + wti.height = tx_process_context.height; + fill_transfer_details(tx_process_context.tx, tx_process_context.mtd, wti.td); + wti.unlock_time = get_max_unlock_time_from_receive_indices(tx_process_context.tx, tx_process_context.mtd); + wti.timestamp = tx_process_context.timestamp; wti.tx_blob_size = static_cast(currency::get_object_blobsize(wti.tx)); - wti.tx_hash = currency::get_transaction_hash(tx); + wti.tx_hash = tx_process_context.tx_hash(); load_wallet_transfer_info_flags(wti); - bc_services::extract_market_instructions(wti.marketplace_entries, tx.attachment); + bc_services::extract_market_instructions(wti.marketplace_entries, wti.tx.attachment); // escrow transactions, which are built with TX_FLAG_SIGNATURE_MODE_SEPARATE flag actually encrypt attachments // with buyer as a sender, and seller as receiver, despite the fact that for both sides transaction seen as outgoing @@ -1433,19 +1468,20 @@ void wallet2::prepare_wti(wallet_public::wallet_transfer_info& wti, uint64_t hei //we check if spent_indices have zero then input do not belong to this account, which means that we are seller for this //escrow, and decryption should be processed as income flag - bool decrypt_attachment_as_income = wti.is_income; + //let's assume that the one who pays for tx fee is sender of tx + bool decrypt_attachment_as_income = !(tx_process_context.total_balance_change.count(currency::native_coin_asset_id) && tx_process_context.total_balance_change.at(currency::native_coin_asset_id) < 0 ); std::vector decrypted_att; - if (wti.tx_type == GUI_TX_TYPE_ESCROW_TRANSFER && std::find(td.spent_indices.begin(), td.spent_indices.end(), 0) == td.spent_indices.end()) + if (wti.tx_type == GUI_TX_TYPE_ESCROW_TRANSFER && std::find(tx_process_context.mtd.spent_indices.begin(), tx_process_context.mtd.spent_indices.end(), 0) == tx_process_context.mtd.spent_indices.end()) decrypt_attachment_as_income = true; - decrypt_payload_items(decrypt_attachment_as_income, tx, m_account.get_keys(), decrypted_att); - if ((is_watch_only() && !wti.is_income)|| (height > 638000 && !have_type_in_variant_container(decrypted_att))) + decrypt_payload_items(decrypt_attachment_as_income, wti.tx, m_account.get_keys(), decrypted_att); + if ((is_watch_only() && !decrypt_attachment_as_income)|| (height > 638000 && !have_type_in_variant_container(decrypted_att))) { remove_field_of_type_from_extra(decrypted_att); remove_field_of_type_from_extra(decrypted_att); } - if (is_watch_only() && !wti.is_income) + if (is_watch_only() && !decrypt_attachment_as_income) { remove_field_of_type_from_extra(decrypted_att); } @@ -1453,19 +1489,6 @@ void wallet2::prepare_wti(wallet_public::wallet_transfer_info& wti, uint64_t hei process_contract_info(wti, decrypted_att); } //---------------------------------------------------------------------------------------------------- -void wallet2::handle_money_received2(const currency::block& b, const currency::transaction& tx, uint64_t amount, const money_transfer2_details& td) -{ - //decrypt attachments - m_transfer_history.push_back(AUTO_VAL_INIT(wallet_public::wallet_transfer_info())); - wallet_public::wallet_transfer_info& wti = m_transfer_history.back(); - wti.is_income = true; - // TODO @#@# this function is only able to handle native coins atm, consider changing -- sowle - wti.asset_id = native_coin_asset_id; - prepare_wti(wti, get_block_height(b), get_block_datetime(b), tx, amount, td); - WLT_LOG_L1("[MONEY RECEIVED]: " << epee::serialization::store_t_to_json(wti)); - rise_on_transfer2(wti); -} -//---------------------------------------------------------------------------------------------------- void wallet2::rise_on_transfer2(const wallet_public::wallet_transfer_info& wti) { PROFILE_FUNC("wallet2::rise_on_transfer2"); @@ -1475,22 +1498,11 @@ void wallet2::rise_on_transfer2(const wallet_public::wallet_transfer_info& wti) uint64_t mined_balance = 0; this->balance(balances, mined_balance); m_wcallback->on_transfer2(wti, balances, mined_balance); - - // TODO @#@# bad design, CZ we need to redesign balance() functions regarding getting mined and unlocked balances for the native coin - uint64_t unlocked_balance = 0, native_balance = 0; - for (auto& el : balances) - { - if (el.asset_info.asset_id == currency::native_coin_asset_id) - { - native_balance = el.total; - unlocked_balance = el.unlocked; - break; - } - } // second call for legacy callback handlers - m_wcallback->on_transfer2(wti, native_balance, unlocked_balance, mined_balance); + m_wcallback->on_transfer2(wti, balances, mined_balance); } //---------------------------------------------------------------------------------------------------- +/* void wallet2::handle_money_spent2(const currency::block& b, const currency::transaction& in_tx, uint64_t amount, @@ -1509,6 +1521,54 @@ void wallet2::handle_money_spent2(const currency::block& b, rise_on_transfer2(wti); } //---------------------------------------------------------------------------------------------------- +void wallet2::handle_money_received2(const currency::block& b, const currency::transaction& tx, uint64_t amount, const money_transfer2_details& td) +{ + //decrypt attachments + m_transfer_history.push_back(AUTO_VAL_INIT(wallet_public::wallet_transfer_info())); + wallet_public::wallet_transfer_info& wti = m_transfer_history.back(); + wti.is_income = true; + // TODO @#@# this function is only able to handle native coins atm, consider changing -- sowle + wti.asset_id = native_coin_asset_id; + prepare_wti(wti, get_block_height(b), get_block_datetime(b), tx, amount, td); + WLT_LOG_L1("[MONEY RECEIVED]: " << epee::serialization::store_t_to_json(wti)); + rise_on_transfer2(wti); +} +*/ +//---------------------------------------------------------------------------------------------------- +void wallet2::handle_money(const currency::block& b, const process_transaction_context& tx_process_context) +{ + m_transfer_history.push_back(AUTO_VAL_INIT(wallet_public::wallet_transfer_info())); + wallet_public::wallet_transfer_info& wti = m_transfer_history.back(); + wti.remote_addresses = tx_process_context.recipients; + wti.remote_aliases = tx_process_context.remote_aliases; + for (const auto bce : tx_process_context.total_balance_change) + { + wallet_sub_transfer_info wsti = AUTO_VAL_INIT(wsti); + wsti.asset_id = bce.first; + if (bce.second == 0) + { + continue; + } + else if (bce.second > 0) + { + //in transfer + wsti.is_income = true; + wsti.amount = static_cast(bce.second); + } + else + { + //out transfer + wsti.is_income = false; + wsti.amount = static_cast(bce.second * (-1)); + } + wti.push_back(wsti); + } + + prepare_wti(wti, tx_process_context); + WLT_LOG_L1("[MONEY SPENT]: " << epee::serialization::store_t_to_json(wti)); + rise_on_transfer2(wti); +} +//---------------------------------------------------------------------------------------------------- void wallet2::process_unconfirmed(const currency::transaction& tx, std::vector& recipients, std::vector& remote_aliases) { auto unconf_it = m_unconfirmed_txs.find(get_transaction_hash(tx)); @@ -4799,7 +4859,7 @@ void wallet2::build_escrow_template(const bc_services::contract_private_details& finalize_transaction(ftp, tx, one_time_key, false); } //---------------------------------------------------------------------------------------------------- -void wallet2::add_transfers_to_expiration_list(const std::vector& selected_transfers, uint64_t expiration, uint64_t change_amount, const crypto::hash& related_tx_id) +void wallet2::add_transfers_to_expiration_list(const std::vector& selected_transfers, uint64_t expiration, const crypto::hash& related_tx_id) { // check all elements in selected_transfers for being already mentioned in m_money_expirations std::vector selected_transfers_local; @@ -4821,7 +4881,6 @@ void wallet2::add_transfers_to_expiration_list(const std::vector& sele m_money_expirations.push_back(AUTO_VAL_INIT(expiration_entry_info())); m_money_expirations.back().expiration_time = expiration; m_money_expirations.back().selected_transfers = selected_transfers_local; - m_money_expirations.back().change_amount = change_amount; m_money_expirations.back().related_tx_id = related_tx_id; std::stringstream ss; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 0e800111..f8f13b3d 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -120,7 +120,6 @@ namespace tools virtual ~i_wallet2_callback() = default; virtual void on_new_block(uint64_t /*height*/, const currency::block& /*block*/) {} - virtual void on_transfer2(const wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) {} // this one is left for compatibility, one day we need to get rid of it virtual void on_transfer2(const wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) {} virtual void on_pos_block_found(const currency::block& /*block*/) {} virtual void on_sync_progress(const uint64_t& /*percents*/) {} @@ -438,12 +437,32 @@ namespace tools }; + struct payment_details_subtransfer + { + crypto::public_key asset_id = currency::null_pkey; + uint64_t amount = 0; + + BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(asset_id) + BOOST_SERIALIZE(amount) + END_BOOST_SERIALIZATION() + }; + struct payment_details { crypto::hash m_tx_hash = currency::null_hash; - uint64_t m_amount = 0; + uint64_t m_amount = 0; // native coins amount uint64_t m_block_height = 0; uint64_t m_unlock_time = 0; + std::vector subtransfers; //subtransfers added for confidential asset only, native amount should be stored in m_amount (for space saving) + + BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(m_tx_hash) + BOOST_SERIALIZE(m_amount) + BOOST_SERIALIZE(m_block_height) + BOOST_SERIALIZE(m_unlock_time) + BOOST_SERIALIZE(subtransfers) + END_BOOST_SERIALIZATION() }; struct mining_context : public currency::pos_mining_context @@ -466,7 +485,6 @@ namespace tools struct expiration_entry_info { std::vector selected_transfers; - uint64_t change_amount = 0; uint64_t expiration_time = 0; crypto::hash related_tx_id = currency::null_hash; // tx id which caused money lock, if any (ex: escrow proposal transport tx) }; @@ -533,7 +551,9 @@ namespace tools struct process_transaction_context { - uint64_t sum_of_own_native_inputs = 0; // old-fashioned bare inputs or ZC inputs referring to native coin asset_id + process_transaction_context(const currency::transaction& t) : tx(t) {} + const currency::transaction& tx; + bool spent_own_native_inputs = false; // check all outputs for spending (compare key images) money_transfer2_details mtd; bool is_pos_coinbase = false; @@ -543,6 +563,21 @@ namespace tools size_t i = 0; size_t sub_i = 0; uint64_t height = 0; + uint64_t timestamp = 0; + std::map total_balance_change; + std::vector recipients; + std::vector remote_aliases; + + const crypto::hash& tx_hash() const + { + if (tx_hash_ == currency::null_hash) + { + tx_hash_ = get_transaction_hash(tx); + } + return tx_hash_; + } + private: + mutable crypto::hash tx_hash_ = currency::null_hash; }; @@ -988,7 +1023,7 @@ 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 add_transfers_to_expiration_list(const std::vector& selected_transfers, uint64_t expiration, 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); void process_new_transaction(const currency::transaction& tx, uint64_t height, const currency::block& b, const std::vector* pglobal_indexes); @@ -1015,18 +1050,11 @@ private: const std::vector& splitted_dsts); 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); - void prepare_wti_decrypted_attachments(wallet_public::wallet_transfer_info& wti, const std::vector& decrypted_att); - void handle_money_received2(const currency::block& b, - const currency::transaction& tx, - uint64_t amount, - const money_transfer2_details& td); - void handle_money_spent2(const currency::block& b, - const currency::transaction& in_tx, - uint64_t amount, - const money_transfer2_details& td, - const std::vector& recipients, - const std::vector& recipients_aliases); + void prepare_wti(wallet_public::wallet_transfer_info& wti, const process_transaction_context& tx_process_context); + void prepare_wti_decrypted_attachments(wallet_public::wallet_transfer_info& wti, const std::vector& decrypted_att); + void handle_money(const currency::block& b, const process_transaction_context& tx_process_context); + + void handle_pulled_blocks(size_t& blocks_added, std::atomic& stop, currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& blocks); std::string get_alias_for_address(const std::string& addr); @@ -1267,15 +1295,6 @@ namespace boost a & x.is_wallet_owns_redeem; a & x.transfer_index; } - - template - inline void serialize(Archive& a, tools::wallet2::payment_details& x, const boost::serialization::version_type ver) - { - a & x.m_tx_hash; - a & x.m_amount; - a & x.m_block_height; - a & x.m_unlock_time; - } template inline void serialize(Archive& a, tools::wallet_public::wallet_transfer_info_details& x, const boost::serialization::version_type ver) @@ -1350,8 +1369,11 @@ namespace tools if (tr_index != UINT64_MAX) { transfer_details& td = m_transfers[tr_index]; + ptc.total_balance_change[td.get_asset_id()] -= td.amount(); if (td.is_native_coin()) - ptc.sum_of_own_native_inputs += td.m_amount; + { + ptc.spent_own_native_inputs = true; + } uint32_t flags_before = td.m_flags; td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_SPENT; td.m_spent_height = ptc.height; diff --git a/src/wallet/wallet_id_adapter.h b/src/wallet/wallet_id_adapter.h index e31e2fab..e794795f 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, uint64_t balance, uint64_t unlocked_balance, 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,8 +32,8 @@ 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, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) { - m_pbackend->on_transfer2(m_wallet_id, wti, balance, unlocked_balance, 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) { m_pbackend->on_pos_block_found(m_wallet_id, wti); diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 03f6b6b7..35e841f9 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -91,20 +91,22 @@ namespace wallet_public struct wallet_sub_transfer_info { - std::vector remote_addresses; //optional - std::vector remote_aliases; //optional, describe only if there only one remote address uint64_t amount; bool is_income; crypto::public_key asset_id; // not blinded, not premultiplied by 1/8 BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(remote_addresses) - KV_SERIALIZE(remote_aliases) KV_SERIALIZE(amount) KV_SERIALIZE(is_income) KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) END_KV_SERIALIZE_MAP() + BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(amount) + BOOST_SERIALIZE(is_income) + BOOST_SERIALIZE(asset_id) + END_BOOST_SERIALIZATION() + }; struct wallet_transfer_info @@ -122,6 +124,9 @@ namespace wallet_public uint64_t tx_type; wallet_transfer_info_details td; std::vector service_entries; + std::vector remote_addresses; //optional + std::vector remote_aliases; //optional, describe only if there only one remote address + std::vector subtransfers; //not included in streaming serialization @@ -154,6 +159,8 @@ namespace wallet_public KV_SERIALIZE(contract) KV_SERIALIZE(service_entries) KV_SERIALIZE(transfer_internal_index) + KV_SERIALIZE(remote_addresses) + KV_SERIALIZE(remote_aliases) KV_SERIALIZE(subtransfers) END_KV_SERIALIZE_MAP() @@ -178,8 +185,20 @@ namespace wallet_public BOOST_SERIALIZE(contract) BOOST_SERIALIZE(service_entries) BOOST_SERIALIZE(transfer_internal_index) + BOOST_SERIALIZE(remote_addresses) + BOOST_SERIALIZE(remote_aliases) BOOST_SERIALIZE(subtransfers) END_BOOST_SERIALIZATION() + + bool is_income_mode_encryption() + { + for (const auto& st : subtransfers) + { + if (st.asset_id == currency::native_coin_asset_id) + return st.is_income; + } + return true; + } }; struct asset_balance_entry_base diff --git a/tests/core_tests/atomic_tests.cpp b/tests/core_tests/atomic_tests.cpp index a6176fc1..41382a51 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, uint64_t balance, uint64_t unlocked_balance, 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/escrow_wallet_tests.cpp b/tests/core_tests/escrow_wallet_tests.cpp index 5b013f5d..6cee1610 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, uint64_t balance, uint64_t unlocked_balance, 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 72b21bea..8f434d2b 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, uint64_t balance, uint64_t unlocked_balance, 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, uint64_t balance, uint64_t unlocked_balance, 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, uint64_t balance, uint64_t unlocked_balance, 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, uint64_t balance, uint64_t unlocked_balance, 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, uint64_t balance, uint64_t unlocked_balance, 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/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index 8abd0ecf..dc2f58f0 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -1586,7 +1586,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, uint64_t balance, uint64_t unlocked_balance, 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 { @@ -1819,7 +1819,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, uint64_t balance, uint64_t unlocked_balance, 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; } @@ -3295,7 +3295,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, uint64_t balance, uint64_t unlocked_balance, 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)); @@ -3444,7 +3444,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, uint64_t balance, uint64_t unlocked_balance, 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 eb54960b..251ff43b 100644 --- a/tests/core_tests/wallet_tests.h +++ b/tests/core_tests/wallet_tests.h @@ -111,7 +111,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, uint64_t balance, uint64_t unlocked_balance, 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 425c81f6..c40ebad4 100644 --- a/tests/core_tests/wallet_tests_basic.h +++ b/tests/core_tests/wallet_tests_basic.h @@ -60,7 +60,7 @@ 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, uint64_t balance, uint64_t unlocked_balance, 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_called = true; m_result = false; @@ -92,9 +92,9 @@ struct wallet_callback_balance_checker : public tools::i_wallet2_callback struct wlt_lambda_on_transfer2_wrapper : public tools::i_wallet2_callback { - typedef std::function 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, uint64_t balance, uint64_t unlocked_balance, 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); }