1
0
Fork 0
forked from lthn/blockchain

wallet: fixed creation of redundant zero-amount outputs in ionic-swap transactions

This commit is contained in:
sowle 2023-10-23 17:12:43 +02:00
parent c974f65a30
commit 4a5586efad
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
2 changed files with 28 additions and 21 deletions

View file

@ -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<currency::tx_destination_entry>& dsts,
uint8_t tx_flags,
std::vector<currency::tx_destination_entry>& final_destinations)
{
@ -6611,7 +6612,7 @@ void wallet2::prepare_tx_destinations(const assets_selection_context& needed_mon
std::unordered_set<crypto::public_key> 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<currency::tx_destination_entry>& dsts,
std::vector<currency::tx_destination_entry>& final_destinations, const crypto::public_key& asset_id)
const crypto::public_key& asset_id,
std::vector<currency::tx_destination_entry>& 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<detail::split_strategy_id_t>(ctp.split_strategy_id), ctp.dust_policy, ctp.dsts, ftp.prepared_destinations);
prepare_tx_destinations(needed_money_map, static_cast<detail::split_strategy_id_t>(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<currency::tx_destination_entry> 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);

View file

@ -1110,13 +1110,15 @@ private:
detail::split_strategy_id_t destination_split_strategy_id,
const tx_dust_policy& dust_policy,
const std::vector<currency::tx_destination_entry>& dsts,
uint8_t tx_flags,
std::vector<currency::tx_destination_entry>& 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<currency::tx_destination_entry>& dsts,
std::vector<currency::tx_destination_entry>& final_detinations, const crypto::public_key& asset_id);
const crypto::public_key& asset_id,
std::vector<currency::tx_destination_entry>& final_detinations);
bool handle_contract(wallet_public::wallet_transfer_info& wti, const bc_services::contract_private_details& cntr, const std::vector<currency::payload_items_v>& 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<currency::payload_items_v>& decrypted_attach);