From ff0d32fa20bc38c4dd7688c1aa5ceb1fa5bf6066 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sat, 17 Sep 2022 22:52:26 +0200 Subject: [PATCH 1/5] transfer refactoring - inital code --- .../currency_format_utils_transactions.h | 21 ++++---- src/wallet/wallet2.cpp | 12 +++-- src/wallet/wallet2.h | 49 +------------------ 3 files changed, 19 insertions(+), 63 deletions(-) diff --git a/src/currency_core/currency_format_utils_transactions.h b/src/currency_core/currency_format_utils_transactions.h index d678cc38..ce24c2cd 100644 --- a/src/currency_core/currency_format_utils_transactions.h +++ b/src/currency_core/currency_format_utils_transactions.h @@ -76,8 +76,8 @@ namespace currency //if this struct is present, then creating htlc out, expiration -> number of blocks that htlc proposal is active struct destination_option_htlc_out { - uint64_t expiration; - crypto::hash htlc_hash; + uint64_t expiration = 0; + crypto::hash htlc_hash = crypto::null_hash; BEGIN_SERIALIZE_OBJECT() FIELD(expiration) @@ -90,16 +90,17 @@ namespace currency { uint64_t amount; //money std::list addr; //destination address, in case of 1 address - txout_to_key, in case of more - txout_multisig - size_t minimum_sigs; //if txout_multisig: minimum signatures that are required to spend this output (minimum_sigs <= addr.size()) IF txout_to_key - not used - uint64_t amount_to_provide; //amount money that provided by initial creator of tx, used with partially created transactions - uint64_t unlock_time; - destination_option_htlc_out htlc_options; //htlc options + size_t minimum_sigs = 0; //if txout_multisig: minimum signatures that are required to spend this output (minimum_sigs <= addr.size()) IF txout_to_key - not used + uint64_t amount_to_provide = 0; //amount money that provided by initial creator of tx, used with partially created transactions + uint64_t unlock_time = 0; + destination_option_htlc_out htlc_options; //htlc options + crypto::hash asset_id = crypto::null_hash; - tx_destination_entry() : amount(0), minimum_sigs(0), amount_to_provide(0), unlock_time(0), htlc_options(destination_option_htlc_out()){} - tx_destination_entry(uint64_t a, const account_public_address& ad) : amount(a), addr(1, ad), minimum_sigs(0), amount_to_provide(0), unlock_time(0), htlc_options(destination_option_htlc_out()) {} - tx_destination_entry(uint64_t a, const account_public_address& ad, uint64_t ut) : amount(a), addr(1, ad), minimum_sigs(0), amount_to_provide(0), unlock_time(ut), htlc_options(destination_option_htlc_out()) {} - tx_destination_entry(uint64_t a, const std::list& addr) : amount(a), addr(addr), minimum_sigs(addr.size()), amount_to_provide(0), unlock_time(0), htlc_options(destination_option_htlc_out()) {} + tx_destination_entry() = default; + tx_destination_entry(uint64_t a, const account_public_address& ad) : amount(a), addr(1, ad) {} + tx_destination_entry(uint64_t a, const account_public_address& ad, uint64_t ut) : amount(a), addr(1, ad), unlock_time(ut) {} + tx_destination_entry(uint64_t a, const std::list& addr) : amount(a), addr(addr), minimum_sigs(addr.size()) {} BEGIN_SERIALIZE_OBJECT() FIELD(amount) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 83e62a3d..93aedc1e 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4894,9 +4894,10 @@ bool wallet2::prepare_tx_sources_htlc(crypto::hash htlc_tx_id, const std::string } //---------------------------------------------------------------------------------------------------------------- -uint64_t wallet2::get_needed_money(uint64_t fee, const std::vector& dsts) +std::unordered_map&& wallet2::get_needed_money(uint64_t fee, const std::vector& dsts) { - uint64_t needed_money = fee; + std::unordered_map amounts_map; + amounts_map[currency::null_hash] = fee; BOOST_FOREACH(auto& dt, dsts) { THROW_IF_TRUE_WALLET_EX(0 == dt.amount, error::zero_destination); @@ -4904,10 +4905,10 @@ uint64_t wallet2::get_needed_money(uint64_t fee, const std::vector needed_money_map; + uint64_t needed_money_map = get_needed_money(ctp.fee, ctp.dsts); 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"); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 277336a2..ffdf536b 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -295,53 +295,6 @@ namespace tools bool perform_packing = false; }; -// struct currency::finalize_tx_param -// { -// uint64_t unlock_time; -// std::vector extra; -// std::vector attachments; -// currency::account_public_address crypt_address; -// uint8_t tx_outs_attr; -// bool shuffle; -// uint8_t flags; -// crypto::hash multisig_id; -// std::vector sources; -// std::vector selected_transfers; -// std::vector prepared_destinations; -// -// crypto::public_key spend_pub_key; // only for validations -// -// BEGIN_SERIALIZE_OBJECT() -// FIELD(unlock_time) -// FIELD(extra) -// FIELD(attachments) -// FIELD(crypt_address) -// FIELD(tx_outs_attr) -// FIELD(shuffle) -// FIELD(flags) -// FIELD(multisig_id) -// FIELD(sources) -// FIELD(selected_transfers) -// FIELD(prepared_destinations) -// FIELD(spend_pub_key) -// END_SERIALIZE() -// }; -// -// struct currency::finalized_tx -// { -// currency::transaction tx; -// crypto::secret_key one_time_key; -// currency::finalize_tx_param ftp; -// std::vector> outs_key_images; // pairs (out_index, key_image) for each change output -// -// BEGIN_SERIALIZE_OBJECT() -// FIELD(tx) -// FIELD(one_time_key) -// FIELD(ftp) -// FIELD(outs_key_images) -// END_SERIALIZE() -// }; - class wallet2: public tools::tor::t_transport_state_notifier { @@ -1002,7 +955,7 @@ private: bool prepare_tx_sources_htlc(crypto::hash htlc_tx_id, const std::string& origin, std::vector& sources, uint64_t& found_money); bool 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); void prefetch_global_indicies_if_needed(std::vector& selected_indicies); - uint64_t get_needed_money(uint64_t fee, const std::vector& dsts); + std::unordered_map&& get_needed_money(uint64_t fee, const std::vector& dsts); void prepare_tx_destinations(uint64_t needed_money, uint64_t found_money, detail::split_strategy_id_t destination_split_strategy_id, From 7c4d8a41e8d2099a31970df4f7618201dfb5a7bf Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 20 Sep 2022 22:01:52 +0200 Subject: [PATCH 2/5] massive changes over adding asset id to primary operations to wallet --- src/currency_core/currency_basic.h | 16 +- src/currency_core/currency_format_utils.cpp | 18 +- .../currency_format_utils_transactions.h | 23 +-- src/gui/qt-daemon/application/mainwindow.cpp | 2 + src/gui/qt-daemon/application/mainwindow.h | 2 +- src/wallet/wallet2.cpp | 161 ++++++++++++------ src/wallet/wallet2.h | 31 +++- src/wallet/wallet_errors.h | 2 +- 8 files changed, 179 insertions(+), 76 deletions(-) diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index f7cb6271..c0dbfd52 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -207,7 +207,7 @@ namespace currency }; - typedef boost::variant txin_etc_details_v; + typedef boost::variant txin_etc_details_v; struct referring_input @@ -372,6 +372,17 @@ namespace currency END_BOOST_SERIALIZATION() }; + //!!!!this is temporary struct!!! + //needed only to hold asset_id of input/output while zarcanum extension being developed + struct open_asset_id + { + crypto::hash asset_id; + BEGIN_SERIALIZE_OBJECT() + FIELD(asset_id) // referring_input + END_SERIALIZE() + }; + + typedef boost::variant txout_etc_details_v; struct tx_out_zarcanum { @@ -386,6 +397,7 @@ namespace currency crypto::public_key amount_commitment; // premultiplied by 1/8 uint64_t encrypted_amount; uint8_t mix_attr; + std::vector etc_details; //crypto::public_key token_masked_generator; BEGIN_SERIALIZE_OBJECT() @@ -1063,7 +1075,7 @@ SET_VARIANT_TAGS(currency::void_sig, 44, "void_sig"); SET_VARIANT_TAGS(currency::zarcanum_outs_range_proof, 45, "zarcanum_outs_range_proof"); SET_VARIANT_TAGS(currency::zc_balance_proof, 46, "zc_balance_proof"); - +SET_VARIANT_TAGS(open_asset_id, 47, "asset_id"); diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 7671652a..142d12eb 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -882,6 +882,14 @@ namespace currency // TODO @#@# implement multisig support tx_out_zarcanum out = AUTO_VAL_INIT(out); + //@#@ + //TODO: TEMPORARY + if (de.asset_id != currency::null_hash) + { + out.etc_details.push_back(txout_etc_details_v{ de.asset_id }); + } + //@#@ + const account_public_address& apa = de.addr.front(); if (apa.spend_public_key == null_pkey && apa.view_public_key == null_pkey) { @@ -1881,8 +1889,13 @@ namespace currency txin_zc_input zc_in = AUTO_VAL_INIT(zc_in); zc_in.k_image = img; zc_in.key_offsets = std::move(key_offsets); + //TEMPORARY + if (src_entr.asset_id != currency::null_hash) + { + zc_in.etc_details.push_back(open_asset_id{ src_entr.asset_id }); + } tx.vin.push_back(zc_in); - //zc_sources.push_back(&src_entr); + } else { @@ -1906,6 +1919,9 @@ namespace currency if (shuffle) std::sort(shuffled_dsts.begin(), shuffled_dsts.end(), [](const tx_destination_entry& de1, const tx_destination_entry& de2) { return de1.amount < de2.amount; }); + + // TODO: consider "Shuffle" inputs + uint64_t summary_outs_money = 0; //fill outputs size_t output_index = tx.vout.size(); // in case of append mode we need to start output indexing from the last one + 1 diff --git a/src/currency_core/currency_format_utils_transactions.h b/src/currency_core/currency_format_utils_transactions.h index ce24c2cd..8cb2892a 100644 --- a/src/currency_core/currency_format_utils_transactions.h +++ b/src/currency_core/currency_format_utils_transactions.h @@ -41,17 +41,18 @@ namespace currency //typedef serializable_pair output_entry; // txout_ref_v is either global output index or ref_by_id; public_key - is output's stealth address std::vector outputs; - uint64_t real_output; //index in outputs vector of real output_entry - crypto::public_key real_out_tx_key; //real output's transaction's public key - crypto::scalar_t real_out_amount_blinding_mask; //blinding mask of real out's amount committment (only for zarcanum inputs, otherwise must be 0) - size_t real_output_in_tx_index; //index in transaction outputs vector - uint64_t amount; //money - uint64_t transfer_index; //money - crypto::hash multisig_id; //if txin_multisig: multisig output id - size_t ms_sigs_count; //if txin_multisig: must be equal to output's minimum_sigs - size_t ms_keys_count; //if txin_multisig: must be equal to size of output's keys container - bool separately_signed_tx_complete; //for separately signed tx only: denotes the last source entry in complete tx to explicitly mark the final step of tx creation - std::string htlc_origin; //for htlc, specify origin + uint64_t real_output = 0; //index in outputs vector of real output_entry + crypto::public_key real_out_tx_key = currency::null_pkey; //real output's transaction's public key + crypto::scalar_t real_out_amount_blinding_mask; //blinding mask of real out's amount committment (only for zarcanum inputs, otherwise must be 0) + size_t real_output_in_tx_index = 0; //index in transaction outputs vector + uint64_t amount = 0; //money + uint64_t transfer_index = 0; //index in m_transfers + crypto::hash multisig_id = currency::null_hash; //if txin_multisig: multisig output id + size_t ms_sigs_count = 0; //if txin_multisig: must be equal to output's minimum_sigs + size_t ms_keys_count = 0; //if txin_multisig: must be equal to size of output's keys container + bool separately_signed_tx_complete = false; //for separately signed tx only: denotes the last source entry in complete tx to explicitly mark the final step of tx creation + std::string htlc_origin; //for htlc, specify origin + crypto::hash asset_id = currency::null_hash; //asset id bool is_multisig() const { return ms_sigs_count > 0; } bool is_zarcanum() const { return !real_out_amount_blinding_mask.is_zero(); } diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index 77e558cb..dcb5f2b6 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -2184,6 +2184,7 @@ QString MainWindow::toggle_autostart(const QString& param) return MAKE_RESPONSE(default_ar); CATCH_ENTRY_FAIL_API_RESPONCE(); } +/* QString MainWindow::check_available_sources(const QString& param) { TRY_ENTRY(); @@ -2192,6 +2193,7 @@ QString MainWindow::check_available_sources(const QString& param) return m_backend.check_available_sources(sources.wallet_id, sources.req_data).c_str(); CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); } +*/ QString MainWindow::open_url_in_browser(const QString& param) { diff --git a/src/gui/qt-daemon/application/mainwindow.h b/src/gui/qt-daemon/application/mainwindow.h index f01dbe93..98a3d03b 100644 --- a/src/gui/qt-daemon/application/mainwindow.h +++ b/src/gui/qt-daemon/application/mainwindow.h @@ -173,7 +173,7 @@ public: bool set_is_disabled_notifications(const bool& param); QString export_wallet_history(const QString& param); QString get_log_file(); - QString check_available_sources(const QString& param); + //QString check_available_sources(const QString& param); QString open_url_in_browser(const QString& param); void trayIconActivated(QSystemTrayIcon::ActivationReason reason); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 93aedc1e..8b28744f 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -695,7 +695,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t 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); + add_transfer_to_transfers_cache(td.m_amount, transfer_index, td.get_asset_id()); if (is_watch_only() && is_auditable()) { @@ -865,7 +865,7 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept 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.split_strategy_id = detail::ssi_digit; + construct_param.split_strategy_id = get_current_split_strategy(); //little hack for now, we add multisig_entry before transaction actually get to blockchain //to let prepare_transaction (which is called from build_escrow_release_templates) work correct @@ -876,7 +876,7 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept transfer_details_base& tdb = m_multisig_transfers[contract_id]; //create once instance of tx for all entries std::shared_ptr pwallet_info(new transaction_wallet_info()); - pwallet_info->m_tx = tx;; + pwallet_info->m_tx = tx; pwallet_info->m_block_height = 0; pwallet_info->m_block_timestamp = 0; tdb.m_ptx_wallet_info = pwallet_info; @@ -1050,7 +1050,7 @@ void wallet2::request_cancel_contract(const crypto::hash& contract_id, uint64_t tsa.flags |= TX_SERVICE_ATTACHMENT_ENCRYPT_BODY; construct_param.extra.push_back(tsa); construct_param.crypt_address = contr_it->second.private_detailes.b_addr; - construct_param.split_strategy_id = detail::ssi_digit; + construct_param.split_strategy_id = get_current_split_strategy(); currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); ftp.tx_version = this->get_current_tx_version(); @@ -1822,6 +1822,14 @@ void wallet2::refresh(std::atomic& stop) refresh(n, f, stop); } //---------------------------------------------------------------------------------------------------- +split_strategy_id_t wallet2::get_current_split_strategy() +{ + if (is_need_to_split_outputs()) + return tools::detail::ssi_digit; + else + return tools::detail::ssi_void; +} +// void wallet2::transfer(uint64_t amount, const currency::account_public_address& acc, currency::transaction& result_tx) { std::vector extra; @@ -1831,7 +1839,7 @@ void wallet2::transfer(uint64_t amount, const currency::account_public_address& dst.resize(1); dst.back().addr.push_back(acc); dst.back().amount = amount; - this->transfer(dst, 0, 0, TX_DEFAULT_FEE, extra, attachments, tools::detail::ssi_digit, tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), result_tx); + this->transfer(dst, 0, 0, TX_DEFAULT_FEE, extra, attachments, get_current_split_strategy(), tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), result_tx); } //---------------------------------------------------------------------------------------------------- void wallet2::transfer(uint64_t amount, const currency::account_public_address& acc) @@ -3074,8 +3082,8 @@ void wallet2::get_transfers(wallet2::transfer_container& incoming_transfers) con bool wallet2::generate_packing_transaction_if_needed(currency::transaction& tx, uint64_t fake_outputs_number) { prepare_free_transfers_cache(0); - auto it = m_found_free_amounts.find(CURRENCY_BLOCK_REWARD); - if (it == m_found_free_amounts.end() || it->second.size() <= m_pos_mint_packing_size) + auto it = m_found_free_amounts[currency::null_hash].find(CURRENCY_BLOCK_REWARD); + if (it == m_found_free_amounts[currency::null_hash].end() || it->second.size() <= m_pos_mint_packing_size) return false; //let's check if we have at least WALLET_POS_MINT_PACKING_SIZE transactions which is ready to go @@ -3227,12 +3235,16 @@ void wallet2::sign_transfer_files(const std::string& tx_sources_file, const std: //---------------------------------------------------------------------------------------------------- bool wallet2::get_utxo_distribution(std::map& distribution) { + //TODO@#@ + /* prepare_free_transfers_cache(0); for (auto ent : m_found_free_amounts) { distribution[ent.first] = ent.second.size(); } - return true; + */ + + return false; } //---------------------------------------------------------------------------------------------------- void wallet2::submit_transfer(const std::string& signed_tx_blob, currency::transaction& tx) @@ -3968,7 +3980,7 @@ void wallet2::push_offer(const bc_services::offer_details_ex& od, currency::tran bc_services::put_offer_into_attachment(static_cast(od), attachments); destinations.push_back(tx_dest); - transfer(destinations, 0, 0, od.fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx); + transfer(destinations, 0, 0, od.fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx); } //---------------------------------------------------------------------------------------------------- const transaction& wallet2::get_transaction_by_id(const crypto::hash& tx_hash) @@ -3998,7 +4010,7 @@ void wallet2::cancel_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, uin crypto::generate_signature(crypto::cn_fast_hash(sig_blob.data(), sig_blob.size()), ephemeral.pub, ephemeral.sec, co.sig); bc_services::put_offer_into_attachment(co, attachments); - transfer(std::vector(), 0, 0, fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx); + transfer(std::vector(), 0, 0, fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx); } //---------------------------------------------------------------------------------------------------- void wallet2::update_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, const bc_services::offer_details_ex& od, currency::transaction& res_tx) @@ -4024,7 +4036,7 @@ void wallet2::update_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, con bc_services::put_offer_into_attachment(uo, attachments); destinations.push_back(tx_dest); - transfer(destinations, 0, 0, od.fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx); + transfer(destinations, 0, 0, od.fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx); } //---------------------------------------------------------------------------------------------------- void wallet2::push_alias_info_to_extra_according_to_hf_status(const currency::extra_alias_entry& ai, std::vector& extra) @@ -4104,7 +4116,7 @@ void wallet2::request_alias_registration(currency::extra_alias_entry& ai, curren tx_dest_alias_reward.amount = reward; destinations.push_back(tx_dest_alias_reward); - transfer(destinations, 0, 0, fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx, CURRENCY_TO_KEY_OUT_RELAXED, false); + transfer(destinations, 0, 0, fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx, CURRENCY_TO_KEY_OUT_RELAXED, false); } //---------------------------------------------------------------------------------------------------- void wallet2::request_alias_update(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward) @@ -4129,11 +4141,12 @@ void wallet2::request_alias_update(currency::extra_alias_entry& ai, currency::tr push_alias_info_to_extra_according_to_hf_status(ai, extra); - transfer(destinations, 0, 0, fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx, CURRENCY_TO_KEY_OUT_RELAXED, false); + transfer(destinations, 0, 0, fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx, CURRENCY_TO_KEY_OUT_RELAXED, false); } //---------------------------------------------------------------------------------------------------- bool wallet2::check_available_sources(std::list& amounts) { + /* std::list > holds; amounts.sort(); bool res = true; @@ -4159,6 +4172,8 @@ bool wallet2::check_available_sources(std::list& amounts) WLT_LOG_MAGENTA("[CHECK_AVAILABLE_SOURCES]: " << amounts << " res: " << res << ENDL <<" holds: " << holds, LOG_LEVEL_0); return res; + */ + return false; } //---------------------------------------------------------------------------------------------------- std::string get_random_rext(size_t len) @@ -4246,7 +4261,7 @@ void wallet2::build_escrow_release_templates(crypto::hash multisig_id, construct_tx_param construct_params = AUTO_VAL_INIT(construct_params); construct_params.fee = fee; construct_params.multisig_id = multisig_id; - construct_params.split_strategy_id = detail::ssi_digit; + construct_params.split_strategy_id = get_current_split_strategy(); construct_params.dsts.resize(2); //0 - addr_a //1 - addr_b @@ -4310,7 +4325,7 @@ void wallet2::build_escrow_cancel_template(crypto::hash multisig_id, ftp.tx_version = this->get_current_tx_version(); construct_params.fee = it->second.amount() - (ecrow_details.amount_a_pledge + ecrow_details.amount_to_pay + ecrow_details.amount_b_pledge); construct_params.multisig_id = multisig_id; - construct_params.split_strategy_id = detail::ssi_digit; + construct_params.split_strategy_id = get_current_split_strategy(); construct_params.dsts.resize(2); //0 - addr_a //1 - addr_b @@ -4360,7 +4375,7 @@ void wallet2::build_escrow_template(const bc_services::contract_private_details& ctp.mark_tx_as_complete = false; ctp.multisig_id = currency::null_hash; ctp.shuffle = true; - ctp.split_strategy_id = detail::ssi_digit; + ctp.split_strategy_id = get_current_split_strategy(); ctp.tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED; ctp.unlock_time = unlock_time; @@ -4518,7 +4533,7 @@ void wallet2::send_escrow_proposal(const bc_services::contract_private_details& ctp.fake_outputs_count = fake_outputs_count; ctp.fee = fee; ctp.shuffle = true; - ctp.split_strategy_id = detail::ssi_digit; + ctp.split_strategy_id = get_current_split_strategy(); ctp.tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED; ctp.unlock_time = unlock_time; @@ -4646,8 +4661,8 @@ bool wallet2::check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& o 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); - auto it = m_found_free_amounts.find(CURRENCY_BLOCK_REWARD); - if (it == m_found_free_amounts.end() || it->second.size() < m_pos_mint_packing_size) + auto it = m_found_free_amounts[currency::null_hash].find(CURRENCY_BLOCK_REWARD); + if (it == m_found_free_amounts[currency::null_hash].end() || it->second.size() < m_pos_mint_packing_size) return false; for (auto set_it = it->second.begin(); set_it != it->second.end() && selected_indicies.size() <= m_pos_mint_packing_size; ) @@ -4664,16 +4679,17 @@ bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake set_it++; } if (!it->second.size()) - m_found_free_amounts.erase(it); + m_found_free_amounts[currency::null_hash].erase(it); return prepare_tx_sources(fake_outputs_count, sources, selected_indicies, found_money); } //---------------------------------------------------------------------------------------------------- -bool wallet2::prepare_tx_sources(uint64_t needed_money, size_t fake_outputs_count, uint64_t dust_threshold, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money) +bool wallet2::prepare_tx_sources(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust_threshold, std::vector& sources, std::vector& selected_indicies) { - found_money = select_transfers(needed_money, fake_outputs_count, dust_threshold, selected_indicies); - WLT_THROW_IF_FALSE_WALLET_EX_MES(found_money >= needed_money, error::not_enough_money, "", found_money, needed_money, 0); - return prepare_tx_sources(fake_outputs_count, sources, selected_indicies, found_money); + bool r = select_transfers(needed_money_map, fake_outputs_count, dust_threshold, selected_indicies); + if (!r) + return r; + return prepare_tx_sources(fake_outputs_count, sources, selected_indicies); } //---------------------------------------------------------------------------------------------------- void wallet2::prefetch_global_indicies_if_needed(std::vector& selected_indicies) @@ -4702,7 +4718,7 @@ void wallet2::prefetch_global_indicies_if_needed(std::vector& selected } } //---------------------------------------------------------------------------------------------------- -bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money) +bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector& sources, const std::vector& selected_indicies) { typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry; typedef currency::tx_source_entry::output_entry tx_output_entry; @@ -4754,6 +4770,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector&& wallet2::get_needed_money(uint64_t fee, const std::vector& dsts) +assets_selection_context&& wallet2::get_needed_money(uint64_t fee, const std::vector& dsts) { - std::unordered_map amounts_map; - amounts_map[currency::null_hash] = fee; + assets_selection_context amounts_map; + amounts_map[currency::null_hash].needed_amount = fee; BOOST_FOREACH(auto& dt, dsts) { THROW_IF_TRUE_WALLET_EX(0 == dt.amount, error::zero_destination); @@ -4905,8 +4922,8 @@ std::unordered_map&& wallet2::get_needed_money(uint64_t if (dt.amount_to_provide) money_to_add = dt.amount_to_provide; - amounts_map[dt.asset_id] += money_to_add; - THROW_IF_TRUE_WALLET_EX(needed_money < money_to_add, error::tx_sum_overflow, dsts, fee); + 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); } return amounts_map; } @@ -5185,6 +5202,20 @@ bool wallet2::get_actual_offers(std::list& offers 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; + // + for (auto& item : needed_money_map) + { + auto asset_cashe_it = m_found_free_amounts.find(item.first); + WLT_THROW_IF_FALSE_WALLET_EX_MES(asset_cashe_it != m_found_free_amounts.end(), error::not_enough_money, "", item.second.found_money, item.second.needed_money, 0, item.first); + item.second.found_money = select_indices_for_transfer(selected_indexes, asset_cashe_it->second, item.second.needed_money, fake_outputs_count); + WLT_THROW_IF_FALSE_WALLET_EX_MES(item.second.found_money >= item.second.needed_money, error::not_enough_money, "", item.second.found_money, item.second.needed_money, 0, item.first); + } + return res; +} +//---------------------------------------------------------------------------------------------------- uint64_t wallet2::select_indices_for_transfer(std::vector& selected_indexes, free_amounts_cache_type& found_free_amounts, uint64_t needed_money, uint64_t fake_outputs_count) { 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); @@ -5277,7 +5308,7 @@ bool wallet2::prepare_free_transfers_cache(uint64_t fake_outputs_count) if (is_transfer_able_to_go(td, fake_outputs_count)) { //@#@ - m_found_free_amounts[td.amount()].insert(i); + m_found_free_amounts[td.get_asset_id()][td.amount()].insert(i); count++; } } @@ -5292,18 +5323,18 @@ void wallet2::add_transfers_to_transfers_cache(const std::vector& inde { //@#@ for (auto i : indexs) - add_transfer_to_transfers_cache(boost::get(m_transfers[i].m_ptx_wallet_info->m_tx.vout[m_transfers[i].m_internal_output_index]).amount , i); + add_transfer_to_transfers_cache(m_transfers[i].amount(), i, m_transfers[i].get_asset_id()); } //---------------------------------------------------------------------------------------------------- -void wallet2::add_transfer_to_transfers_cache(uint64_t amount, uint64_t index) +void wallet2::add_transfer_to_transfers_cache(uint64_t amount, uint64_t index, const crypto::hash& asset_id) { - m_found_free_amounts[amount].insert(index); + m_found_free_amounts[asset_id][amount].insert(index); } //---------------------------------------------------------------------------------------------------- -uint64_t wallet2::select_transfers(uint64_t needed_money, size_t fake_outputs_count, uint64_t dust, std::vector& selected_indicies) +bool wallet2::select_transfers(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust, std::vector& selected_indicies) { prepare_free_transfers_cache(fake_outputs_count); - return select_indices_for_transfer(selected_indicies, m_found_free_amounts, needed_money, fake_outputs_count); + 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, @@ -5400,7 +5431,7 @@ void wallet2::transfer(const std::vector& dsts, const std::vector& attachments, currency::transaction& tx) { - transfer(dsts, fake_outputs_count, unlock_time, fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), tx); + transfer(dsts, fake_outputs_count, unlock_time, fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), tx); } //---------------------------------------------------------------------------------------------------- void wallet2::transfer(const std::vector& dsts, size_t fake_outputs_count, @@ -5499,21 +5530,43 @@ bool wallet2::get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) c return true; } //---------------------------------------------------------------------------------------------------- +bool wallet2::is_need_to_split_outputs() +{ + if (this->m_core_runtime_config.hard_forks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, this->get_blockchain_current_size())) + return false; + else + return true; +} +//---------------------------------------------------------------------------------------------------- +void wallet2::prepare_tx_destinations(const assets_selection_context& needed_money_map, + detail::split_strategy_id_t destination_split_strategy_id, + const tx_dust_policy& dust_policy, + const std::vector& dsts, + std::vector& final_detinations) +{ + for (auto& el: needed_money_map) + { + prepare_tx_destinations(el.second.needed_money, el.second.found_money, destination_split_strategy_id, dust_policy, dsts, final_detinations, el.first); + } +} +//---------------------------------------------------------------------------------------------------- void wallet2::prepare_tx_destinations(uint64_t needed_money, uint64_t found_money, detail::split_strategy_id_t destination_split_strategy_id, const tx_dust_policy& dust_policy, const std::vector& dsts, - std::vector& final_detinations) + std::vector& final_detinations, const crypto::hash& asset_id) { currency::tx_destination_entry change_dts = AUTO_VAL_INIT(change_dts); if (needed_money < found_money) { change_dts.addr.push_back(m_account.get_keys().account_address); change_dts.amount = found_money - needed_money; + change_dts.asset_id = asset_id; } WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(found_money >= needed_money, "needed_money==" << needed_money << " < found_money==" << found_money); + uint64_t dust = 0; bool r = detail::apply_split_strategy_by_id(destination_split_strategy_id, dsts, change_dts, dust_policy.dust_threshold, final_detinations, dust, WALLET_MAX_ALLOWED_OUTPUT_AMOUNT); WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "invalid split strategy id: " << destination_split_strategy_id); @@ -5531,56 +5584,60 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money, if (0 != dust && !dust_policy.add_to_fee) { final_detinations.push_back(currency::tx_destination_entry(dust, dust_policy.addr_for_dust)); + final_detinations.back().asset_id = asset_id; } } //---------------------------------------------------------------------------------------------------- void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const currency::transaction& tx_for_mode_separate /* = currency::transaction() */) { TIME_MEASURE_START_MS(get_needed_money_time); - std::unordered_map needed_money_map; - uint64_t needed_money_map = get_needed_money(ctp.fee, ctp.dsts); - if (ctp.flags & TX_FLAG_SIGNATURE_MODE_SEPARATE && tx_for_mode_separate.vout.size()) + + 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() ) { 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 += (currency::get_outs_money_amount(tx_for_mode_separate) - get_inputs_money_amount(tx_for_mode_separate)); + 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)); } TIME_MEASURE_FINISH_MS(get_needed_money_time); - uint64_t found_money = 0; + //uint64_t found_money = 0; TIME_MEASURE_START_MS(prepare_tx_sources_time); if (ctp.perform_packing) { - prepare_tx_sources_for_packing(WALLET_DEFAULT_POS_MINT_PACKING_SIZE, 0, ftp.sources, ftp.selected_transfers, found_money); + prepare_tx_sources_for_packing(WALLET_DEFAULT_POS_MINT_PACKING_SIZE, 0, ftp.sources, ftp.selected_transfers, needed_money_map[currency::null_hash].found_money); } else if (ctp.htlc_tx_id != currency::null_hash) { //htlc - prepare_tx_sources_htlc(ctp.htlc_tx_id, ctp.htlc_origin, ftp.sources, found_money); + //@#@ 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_hash].found_money); 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(found_money > ctp.fee, + WLT_THROW_IF_FALSE_WITH_CODE(needed_money_map[currency::null_hash].found_money > ctp.fee, "htlc: found money less then fee", API_RETURN_CODE_INTERNAL_ERROR); //fill amount - ctp.dsts.begin()->amount = found_money - ctp.fee; + ctp.dsts.begin()->amount = needed_money_map[currency::null_hash].found_money - ctp.fee; } else if (ctp.multisig_id != currency::null_hash) { //multisig - prepare_tx_sources(ctp.multisig_id, ftp.sources, found_money); + //@#@ 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_hash].found_money); } else { //regular tx - prepare_tx_sources(needed_money, ctp.fake_outputs_count, ctp.dust_policy.dust_threshold, ftp.sources, ftp.selected_transfers, found_money); + prepare_tx_sources(needed_money_map, ctp.fake_outputs_count, ctp.dust_policy.dust_threshold, ftp.sources, ftp.selected_transfers); } TIME_MEASURE_FINISH_MS(prepare_tx_sources_time); TIME_MEASURE_START_MS(prepare_tx_destinations_time); - prepare_tx_destinations(needed_money, found_money, static_cast(ctp.split_strategy_id), ctp.dust_policy, ctp.dsts, ftp.prepared_destinations); + prepare_tx_destinations(needed_money_map, static_cast(ctp.split_strategy_id), ctp.dust_policy, ctp.dsts, ftp.prepared_destinations); TIME_MEASURE_FINISH_MS(prepare_tx_destinations_time); if (ctp.mark_tx_as_complete && !ftp.sources.empty()) @@ -5718,7 +5775,7 @@ construct_tx_param wallet2::get_default_construct_tx_param_inital() ctp.fee = m_core_runtime_config.tx_default_fee; ctp.dust_policy = tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD); - ctp.split_strategy_id = tools::detail::ssi_digit; + ctp.split_strategy_id = get_current_split_strategy(); ctp.tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED; ctp.shuffle = 0; return ctp; @@ -6001,7 +6058,7 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public // try to construct a transaction std::vector dsts({ tx_destination_entry(amount_swept - fee, destination_addr) }); - prepare_tx_destinations(0, 0, detail::ssi_digit, tools::tx_dust_policy(), dsts, ftp.prepared_destinations); + prepare_tx_destinations(0, 0, get_current_split_strategy(), tools::tx_dust_policy(), dsts, ftp.prepared_destinations); currency::transaction tx = AUTO_VAL_INIT(tx); crypto::secret_key tx_key = AUTO_VAL_INIT(tx_key); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index ffdf536b..d9eec410 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -296,6 +296,14 @@ namespace tools }; + struct selection_for_amount + { + uint64_t needed_amount = 0; + uint64_t found_money = 0; + //std::vector selected_indicies; + }; + typedef std::unordered_map assets_selection_context; + class wallet2: public tools::tor::t_transport_state_notifier { wallet2(const wallet2&) = delete; @@ -446,6 +454,7 @@ namespace tools typedef std::unordered_map multisig_transfer_container; typedef std::unordered_map escrow_contracts_container; typedef std::map > free_amounts_cache_type; + typedef std::unordered_map free_assets_amounts_cache_type; typedef std::unordered_map, uint64_t> amount_gindex_to_transfer_id_container; // maps [amount; gindex] -> tid @@ -800,6 +809,7 @@ namespace tools bool is_transfer_ready_to_go(const transfer_details& td, uint64_t fake_outputs_count); bool is_transfer_able_to_go(const transfer_details& td, uint64_t fake_outputs_count); uint64_t select_indices_for_transfer(std::vector& ind, free_amounts_cache_type& found_free_amounts, uint64_t needed_money, uint64_t fake_outputs_count); + bool select_indices_for_transfer(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector& selected_indexes); //PoS //synchronous version of function @@ -912,9 +922,9 @@ private: currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& unserialized); void pull_blocks(size_t& blocks_added, std::atomic& stop); bool prepare_free_transfers_cache(uint64_t fake_outputs_count); - uint64_t select_transfers(uint64_t needed_money, size_t fake_outputs_count, uint64_t dust, std::vector& selected_indicies); + bool select_transfers(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust, std::vector& selected_indicies); void add_transfers_to_transfers_cache(const std::vector& indexs); - void add_transfer_to_transfers_cache(uint64_t amount, uint64_t index); + void add_transfer_to_transfers_cache(uint64_t amount, uint64_t index, const crypto::hash& asset_id = currency::null_hash); bool prepare_file_names(const std::wstring& file_path); void process_unconfirmed(const currency::transaction& tx, std::vector& recipients, std::vector& recipients_aliases); void add_sent_unconfirmed_tx(const currency::transaction& tx, @@ -949,19 +959,24 @@ private: void rise_on_transfer2(const wallet_public::wallet_transfer_info& wti); void process_genesis_if_needed(const currency::block& genesis); bool build_escrow_proposal(bc_services::contract_private_details& ecrow_details, uint64_t fee, uint64_t unlock_time, currency::tx_service_attachment& att, std::vector& selected_indicies); - bool prepare_tx_sources(uint64_t needed_money, size_t fake_outputs_count, uint64_t dust_threshold, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money); - bool prepare_tx_sources(size_t fake_outputs_count, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money); + bool prepare_tx_sources(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust_threshold, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money); + bool prepare_tx_sources(size_t fake_outputs_count, std::vector& sources, const std::vector& selected_indicies); bool prepare_tx_sources(crypto::hash multisig_id, std::vector& sources, uint64_t& found_money); bool prepare_tx_sources_htlc(crypto::hash htlc_tx_id, const std::string& origin, std::vector& sources, uint64_t& found_money); bool 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); void prefetch_global_indicies_if_needed(std::vector& selected_indicies); - std::unordered_map&& get_needed_money(uint64_t fee, const std::vector& dsts); + assets_selection_context&& get_needed_money(uint64_t fee, const std::vector& dsts); + void prepare_tx_destinations(const assets_selection_context& needed_money_map, + detail::split_strategy_id_t destination_split_strategy_id, + const tx_dust_policy& dust_policy, + const std::vector& dsts, + std::vector& final_detinations); void prepare_tx_destinations(uint64_t needed_money, uint64_t found_money, detail::split_strategy_id_t destination_split_strategy_id, const tx_dust_policy& dust_policy, const std::vector& dsts, - std::vector& final_detinations); + std::vector& final_detinations, const crypto::hash& assed_id); bool handle_contract(wallet_public::wallet_transfer_info& wti, const bc_services::contract_private_details& cntr, const std::vector& decrypted_attach); bool handle_release_contract(wallet_public::wallet_transfer_info& wti, const std::string& release_instruction); bool handle_cancel_proposal(wallet_public::wallet_transfer_info& wti, const bc_services::escrow_cancel_templates_body& ectb, const std::vector& decrypted_attach); @@ -970,7 +985,7 @@ private: uint64_t get_current_tx_version(); void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const wallet_public::wallet_transfer_info& wti) const; void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const std::string& reason = "internal intention") const; - + bool is_need_to_split_outputs(); template bool process_input_t(const input_t& in_t, wallet2::process_transaction_context& ptc, const currency::transaction& tx); @@ -1083,7 +1098,7 @@ private: std::list m_money_expirations; //optimization for big wallets and batch tx - free_amounts_cache_type m_found_free_amounts; + free_assets_amounts_cache_type m_found_free_amounts; uint64_t m_fake_outputs_count; std::string m_miner_text_info; diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index a5de826d..8c820551 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -349,7 +349,7 @@ namespace tools //---------------------------------------------------------------------------------------------------- struct not_enough_money : public transfer_error { - not_enough_money(std::string&& loc, uint64_t availbable, uint64_t tx_amount, uint64_t fee) + not_enough_money(std::string&& loc, uint64_t availbable, uint64_t tx_amount, uint64_t fee, const crypto::hash& assset_id) : transfer_error(std::move(loc), "NOT_ENOUGH_MONEY") , m_available(availbable) , m_tx_amount(tx_amount) From d573dd53fd3f6374ceddf83a134a3a94a9d2f872 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 21 Sep 2022 14:50:29 +0200 Subject: [PATCH 3/5] assigning asset id from tx --- src/currency_core/currency_format_utils.cpp | 5 +++++ src/currency_core/currency_format_utils.h | 1 + src/wallet/wallet2.cpp | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 142d12eb..ec547e25 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -2594,6 +2594,11 @@ namespace currency if (is_out_to_acc(acc, zo, derivation, output_index, amount, blinding_mask)) { outs.emplace_back(output_index, amount, blinding_mask); + open_asset_id v = AUTO_VAL_INIT(v); + if (get_type_in_variant_container(zo.etc_details, v)) + { + outs.back().asset_id = v.asset_id; + } money_transfered += amount; } VARIANT_SWITCH_END(); diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index c020c2dd..0e0da357 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -211,6 +211,7 @@ namespace currency size_t index = SIZE_MAX; uint64_t amount = 0; crypto::scalar_t blinding_mask = 0; + crypto::hash asset_id = currency::null_hash; }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 8b28744f..88f01620 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -626,6 +626,10 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t td.m_ptx_wallet_info = pwallet_info; td.m_internal_output_index = o; td.m_key_image = ki; + if (outs[i_in_outs].asset_id != currency::null_hash) + { + td.m_asset_id.reset(new crypto::hash(outs[i_in_outs].asset_id)); + } td.m_amount = outs[i_in_outs].amount; if (m_use_deffered_global_outputs) { From 1aa6a37b0860fbbdd31dc5caa3b23e0f6aa88b3e Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 21 Sep 2022 22:35:24 +0200 Subject: [PATCH 4/5] compilation errors fixed for wallet.cpp --- src/currency_core/currency_basic.h | 26 +++++++++------- .../currency_format_utils_transactions.h | 4 +-- src/wallet/wallet2.cpp | 30 +++++++++---------- src/wallet/wallet2.h | 9 +++--- 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index c0dbfd52..375dd6e6 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -206,6 +206,20 @@ namespace currency uint32_t n_extras; }; + //!!!!this is temporary struct!!! + //needed only to hold asset_id of input/output while zarcanum extension being developed + struct open_asset_id + { + crypto::hash asset_id; + BEGIN_SERIALIZE_OBJECT() + FIELD(asset_id) // referring_input + END_SERIALIZE() + + BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(asset_id) + END_BOOST_SERIALIZATION() + }; + typedef boost::variant txin_etc_details_v; @@ -372,16 +386,6 @@ namespace currency END_BOOST_SERIALIZATION() }; - //!!!!this is temporary struct!!! - //needed only to hold asset_id of input/output while zarcanum extension being developed - struct open_asset_id - { - crypto::hash asset_id; - BEGIN_SERIALIZE_OBJECT() - FIELD(asset_id) // referring_input - END_SERIALIZE() - }; - typedef boost::variant txout_etc_details_v; struct tx_out_zarcanum @@ -1075,7 +1079,7 @@ SET_VARIANT_TAGS(currency::void_sig, 44, "void_sig"); SET_VARIANT_TAGS(currency::zarcanum_outs_range_proof, 45, "zarcanum_outs_range_proof"); SET_VARIANT_TAGS(currency::zc_balance_proof, 46, "zc_balance_proof"); -SET_VARIANT_TAGS(open_asset_id, 47, "asset_id"); +SET_VARIANT_TAGS(currency::open_asset_id, 47, "asset_id"); diff --git a/src/currency_core/currency_format_utils_transactions.h b/src/currency_core/currency_format_utils_transactions.h index 8cb2892a..0c8a9e8c 100644 --- a/src/currency_core/currency_format_utils_transactions.h +++ b/src/currency_core/currency_format_utils_transactions.h @@ -78,7 +78,7 @@ namespace currency struct destination_option_htlc_out { uint64_t expiration = 0; - crypto::hash htlc_hash = crypto::null_hash; + crypto::hash htlc_hash = currency::null_hash; BEGIN_SERIALIZE_OBJECT() FIELD(expiration) @@ -95,7 +95,7 @@ namespace currency uint64_t amount_to_provide = 0; //amount money that provided by initial creator of tx, used with partially created transactions uint64_t unlock_time = 0; destination_option_htlc_out htlc_options; //htlc options - crypto::hash asset_id = crypto::null_hash; + crypto::hash asset_id = currency::null_hash; tx_destination_entry() = default; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 88f01620..4aa78072 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1826,7 +1826,7 @@ void wallet2::refresh(std::atomic& stop) refresh(n, f, stop); } //---------------------------------------------------------------------------------------------------- -split_strategy_id_t wallet2::get_current_split_strategy() +detail::split_strategy_id_t wallet2::get_current_split_strategy() { if (is_need_to_split_outputs()) return tools::detail::ssi_digit; @@ -4685,7 +4685,7 @@ bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake if (!it->second.size()) m_found_free_amounts[currency::null_hash].erase(it); - return prepare_tx_sources(fake_outputs_count, sources, selected_indicies, found_money); + return prepare_tx_sources(fake_outputs_count, sources, selected_indicies); } //---------------------------------------------------------------------------------------------------- bool wallet2::prepare_tx_sources(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust_threshold, std::vector& sources, std::vector& selected_indicies) @@ -4696,7 +4696,7 @@ bool wallet2::prepare_tx_sources(assets_selection_context& needed_money_map, siz return prepare_tx_sources(fake_outputs_count, sources, selected_indicies); } //---------------------------------------------------------------------------------------------------- -void wallet2::prefetch_global_indicies_if_needed(std::vector& selected_indicies) +void wallet2::prefetch_global_indicies_if_needed(const std::vector& selected_indicies) { std::list> txs; std::list indices_that_requested_global_indicies; @@ -4915,7 +4915,7 @@ bool wallet2::prepare_tx_sources_htlc(crypto::hash htlc_tx_id, const std::string } //---------------------------------------------------------------------------------------------------------------- -assets_selection_context&& wallet2::get_needed_money(uint64_t fee, const std::vector& dsts) +assets_selection_context wallet2::get_needed_money(uint64_t fee, const std::vector& dsts) { assets_selection_context amounts_map; amounts_map[currency::null_hash].needed_amount = fee; @@ -4929,7 +4929,7 @@ assets_selection_context&& wallet2::get_needed_money(uint64_t fee, const std::ve 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); } - return amounts_map; + return std::move(amounts_map); } //---------------------------------------------------------------------------------------------------------------- void wallet2::set_disable_tor_relay(bool disable) @@ -5213,9 +5213,9 @@ bool wallet2::select_indices_for_transfer(assets_selection_context& needed_money for (auto& item : needed_money_map) { auto asset_cashe_it = m_found_free_amounts.find(item.first); - WLT_THROW_IF_FALSE_WALLET_EX_MES(asset_cashe_it != m_found_free_amounts.end(), error::not_enough_money, "", item.second.found_money, item.second.needed_money, 0, item.first); - item.second.found_money = select_indices_for_transfer(selected_indexes, asset_cashe_it->second, item.second.needed_money, fake_outputs_count); - WLT_THROW_IF_FALSE_WALLET_EX_MES(item.second.found_money >= item.second.needed_money, error::not_enough_money, "", item.second.found_money, item.second.needed_money, 0, item.first); + WLT_THROW_IF_FALSE_WALLET_EX_MES(asset_cashe_it != m_found_free_amounts.end(), error::not_enough_money, "", item.second.found_amount, item.second.needed_amount, 0, item.first); + 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); } return res; } @@ -5550,7 +5550,7 @@ void wallet2::prepare_tx_destinations(const assets_selection_context& needed_mon { for (auto& el: needed_money_map) { - prepare_tx_destinations(el.second.needed_money, el.second.found_money, destination_split_strategy_id, dust_policy, dsts, final_detinations, el.first); + prepare_tx_destinations(el.second.needed_amount, el.second.found_amount, destination_split_strategy_id, dust_policy, dsts, final_detinations, el.first); } } //---------------------------------------------------------------------------------------------------- @@ -5610,28 +5610,28 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx TIME_MEASURE_START_MS(prepare_tx_sources_time); if (ctp.perform_packing) { - prepare_tx_sources_for_packing(WALLET_DEFAULT_POS_MINT_PACKING_SIZE, 0, ftp.sources, ftp.selected_transfers, needed_money_map[currency::null_hash].found_money); + prepare_tx_sources_for_packing(WALLET_DEFAULT_POS_MINT_PACKING_SIZE, 0, ftp.sources, ftp.selected_transfers, needed_money_map[currency::null_hash].found_amount); } else if (ctp.htlc_tx_id != currency::null_hash) { //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_hash].found_money); + prepare_tx_sources_htlc(ctp.htlc_tx_id, ctp.htlc_origin, ftp.sources, needed_money_map[currency::null_hash].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_hash].found_money > ctp.fee, + WLT_THROW_IF_FALSE_WITH_CODE(needed_money_map[currency::null_hash].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_hash].found_money - ctp.fee; + ctp.dsts.begin()->amount = needed_money_map[currency::null_hash].found_amount - ctp.fee; } else if (ctp.multisig_id != currency::null_hash) { //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_hash].found_money); + prepare_tx_sources(ctp.multisig_id, ftp.sources, needed_money_map[currency::null_hash].found_amount); } else { @@ -6062,7 +6062,7 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public // try to construct a transaction std::vector dsts({ tx_destination_entry(amount_swept - fee, destination_addr) }); - prepare_tx_destinations(0, 0, get_current_split_strategy(), tools::tx_dust_policy(), dsts, ftp.prepared_destinations); + prepare_tx_destinations(0, 0, get_current_split_strategy(), tools::tx_dust_policy(), dsts, ftp.prepared_destinations, currency::null_hash); currency::transaction tx = AUTO_VAL_INIT(tx); crypto::secret_key tx_key = AUTO_VAL_INIT(tx_key); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index d9eec410..f75b1e98 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -299,7 +299,7 @@ namespace tools struct selection_for_amount { uint64_t needed_amount = 0; - uint64_t found_money = 0; + uint64_t found_amount = 0; //std::vector selected_indicies; }; typedef std::unordered_map assets_selection_context; @@ -959,13 +959,13 @@ private: void rise_on_transfer2(const wallet_public::wallet_transfer_info& wti); void process_genesis_if_needed(const currency::block& genesis); bool build_escrow_proposal(bc_services::contract_private_details& ecrow_details, uint64_t fee, uint64_t unlock_time, currency::tx_service_attachment& att, std::vector& selected_indicies); - bool prepare_tx_sources(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust_threshold, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money); + bool prepare_tx_sources(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust_threshold, std::vector& sources, std::vector& selected_indicies); bool prepare_tx_sources(size_t fake_outputs_count, std::vector& sources, const std::vector& selected_indicies); bool prepare_tx_sources(crypto::hash multisig_id, std::vector& sources, uint64_t& found_money); bool prepare_tx_sources_htlc(crypto::hash htlc_tx_id, const std::string& origin, std::vector& sources, uint64_t& found_money); bool 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); - void prefetch_global_indicies_if_needed(std::vector& selected_indicies); - assets_selection_context&& get_needed_money(uint64_t fee, const std::vector& dsts); + void prefetch_global_indicies_if_needed(const std::vector& selected_indicies); + assets_selection_context get_needed_money(uint64_t fee, const std::vector& dsts); void prepare_tx_destinations(const assets_selection_context& needed_money_map, detail::split_strategy_id_t destination_split_strategy_id, const tx_dust_policy& dust_policy, @@ -1050,6 +1050,7 @@ private: 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); uint64_t get_alias_cost(const std::string& alias); + detail::split_strategy_id_t get_current_split_strategy(); static void wti_to_csv_entry(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index); static void wti_to_txt_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index); From 2ba139ebaff1ca83d1fbf4def434e0f7406d2bed Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 22 Sep 2022 19:29:18 +0200 Subject: [PATCH 5/5] fixed wrong variant type --- src/currency_core/currency_format_utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index ec547e25..3292ab8c 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -886,7 +886,7 @@ namespace currency //TODO: TEMPORARY if (de.asset_id != currency::null_hash) { - out.etc_details.push_back(txout_etc_details_v{ de.asset_id }); + out.etc_details.push_back(open_asset_id{ de.asset_id }); } //@#@