diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 20c36019..ded83250 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6600,6 +6600,7 @@ void wallet2::prepare_tx_destinations(const assets_selection_context& needed_mon detail::split_strategy_id_t destination_split_strategy_id, const tx_dust_policy& dust_policy, const std::vector& dsts, + uint8_t tx_flags, std::vector& final_destinations) { @@ -6611,7 +6612,7 @@ void wallet2::prepare_tx_destinations(const assets_selection_context& needed_mon std::unordered_set processed_assets; for (auto& el: needed_money_map) { - prepare_tx_destinations(el.second.needed_amount, el.second.found_amount, destination_split_strategy_id, dust_policy, dsts, final_destinations, el.first); + prepare_tx_destinations(el.second.needed_amount, el.second.found_amount, destination_split_strategy_id, dust_policy, dsts, el.first, final_destinations); processed_assets.insert(el.first); } @@ -6635,23 +6636,26 @@ void wallet2::prepare_tx_destinations(const assets_selection_context& needed_mon } } - if (final_destinations.empty()) + if (!(tx_flags & TX_FLAG_SIGNATURE_MODE_SEPARATE)) { - // if there's no destinations -- make CURRENCY_TX_MIN_ALLOWED_OUTS empty destinations - for(size_t i = 0; i < CURRENCY_TX_MIN_ALLOWED_OUTS; ++i) - final_destinations.emplace_back(0, m_account.get_public_address()); - } - else if (final_destinations.size() < CURRENCY_TX_MIN_ALLOWED_OUTS) - { - // if there's not ehough destinations items (i.e. outputs), split the last one - tx_destination_entry de = final_destinations.back(); - final_destinations.pop_back(); - size_t items_to_be_added = CURRENCY_TX_MIN_ALLOWED_OUTS - final_destinations.size(); - // TODO: consider allowing to set them somewhere - size_t num_digits_to_keep = CURRENCY_TX_OUTS_RND_SPLIT_DIGITS_TO_KEEP; - decompose_amount_randomly(de.amount, [&](uint64_t amount){ de.amount = amount; final_destinations.push_back(de); }, items_to_be_added, num_digits_to_keep); - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(final_destinations.size() == CURRENCY_TX_MIN_ALLOWED_OUTS, - "can't get necessary number of outputs using decompose_amount_randomly(), got " << final_destinations.size() << " while mininum is " << CURRENCY_TX_MIN_ALLOWED_OUTS); + if (final_destinations.empty()) + { + // if there's no destinations -- make CURRENCY_TX_MIN_ALLOWED_OUTS empty destinations + for(size_t i = 0; i < CURRENCY_TX_MIN_ALLOWED_OUTS; ++i) + final_destinations.emplace_back(0, m_account.get_public_address()); + } + else if (final_destinations.size() < CURRENCY_TX_MIN_ALLOWED_OUTS) + { + // if there's not ehough destinations items (i.e. outputs), split the last one + tx_destination_entry de = final_destinations.back(); + final_destinations.pop_back(); + size_t items_to_be_added = CURRENCY_TX_MIN_ALLOWED_OUTS - final_destinations.size(); + // TODO: consider allowing to set them somewhere + size_t num_digits_to_keep = CURRENCY_TX_OUTS_RND_SPLIT_DIGITS_TO_KEEP; + decompose_amount_randomly(de.amount, [&](uint64_t amount){ de.amount = amount; final_destinations.push_back(de); }, items_to_be_added, num_digits_to_keep); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(final_destinations.size() == CURRENCY_TX_MIN_ALLOWED_OUTS, + "can't get necessary number of outputs using decompose_amount_randomly(), got " << final_destinations.size() << " while mininum is " << CURRENCY_TX_MIN_ALLOWED_OUTS); + } } } } @@ -6661,7 +6665,8 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money, detail::split_strategy_id_t destination_split_strategy_id, const tx_dust_policy& dust_policy, const std::vector& dsts, - std::vector& final_destinations, const crypto::public_key& asset_id) + const crypto::public_key& asset_id, + std::vector& final_destinations) { WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(found_money >= needed_money, "needed_money==" << needed_money << " < found_money==" << found_money); @@ -6767,7 +6772,7 @@ bool wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx TIME_MEASURE_FINISH_MS(prepare_tx_sources_time); TIME_MEASURE_START_MS(prepare_tx_destinations_time); - prepare_tx_destinations(needed_money_map, 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, ctp.flags, ftp.prepared_destinations); TIME_MEASURE_FINISH_MS(prepare_tx_destinations_time); @@ -7219,7 +7224,7 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public assets_selection_context needed_money_map; needed_money_map[currency::native_coin_asset_id] = {}; std::vector dsts({ tx_destination_entry(amount_swept - fee, destination_addr) }); - prepare_tx_destinations(needed_money_map, get_current_split_strategy(), tools::tx_dust_policy(), dsts, ftp.prepared_destinations); + prepare_tx_destinations(needed_money_map, get_current_split_strategy(), tools::tx_dust_policy(), ftp.prepared_destinations, ftp.flags, dsts); 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 cd32ca48..5c3a08f6 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1110,13 +1110,15 @@ private: detail::split_strategy_id_t destination_split_strategy_id, const tx_dust_policy& dust_policy, const std::vector& dsts, + uint8_t tx_flags, std::vector& final_destinations); 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, const crypto::public_key& asset_id); + const crypto::public_key& asset_id, + std::vector& final_detinations); 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);