1
0
Fork 0
forked from lthn/blockchain

wallet2::prepare_tx_destinations() fixed to correctly support assets + minor logging improvements

This commit is contained in:
sowle 2022-12-03 21:12:31 +01:00
parent dac549f0b6
commit 528a46f4ed
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
3 changed files with 45 additions and 37 deletions

View file

@ -1988,7 +1988,7 @@ namespace currency
{
if (summary_outs_money > summary_inputs_money)
{
LOG_ERROR("Transaction inputs money (" << summary_inputs_money << ") less than outputs money (" << summary_outs_money << ")");
LOG_ERROR("Transaction inputs money (" << print_money_brief(summary_inputs_money) << ") is less than outputs money (" << print_money_brief(summary_outs_money) << ")");
return false;
}
}

View file

@ -5742,6 +5742,9 @@ void wallet2::print_source_entry(std::stringstream& output, const currency::tx_s
<< ", real_output: " << src.real_output
<< ", real_output_in_tx_index: " << src.real_output_in_tx_index
<< ", indexes: " << ss.str();
if (src.asset_id != currency::null_hash)
output << ", asset_id: " << print16(src.asset_id);
}
//----------------------------------------------------------------------------------------------------
bool wallet2::get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) const
@ -5769,15 +5772,25 @@ void wallet2::prepare_tx_destinations(const assets_selection_context& needed_mon
prepare_tx_destinations(el.second.needed_amount, el.second.found_amount, destination_split_strategy_id, dust_policy, dsts, final_destinations, el.first);
}
if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM) && final_destinations.size() < CURRENCY_TX_MIN_ALLOWED_OUTS)
if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM))
{
// special case for asset minting destinations
for (auto& dst : dsts)
if (dst.asset_id == currency::ffff_hash)
final_destinations.emplace_back(dst.amount, dst.addr, dst.asset_id);
// 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();
decompose_amount_randomly(de.amount, [&](uint64_t amount){ de.amount = amount; final_destinations.push_back(de); }, items_to_be_added);
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.size() > 0 && final_destinations.size() < CURRENCY_TX_MIN_ALLOWED_OUTS)
{
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);
}
}
}
//----------------------------------------------------------------------------------------------------
@ -5790,41 +5803,25 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money,
{
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(found_money >= needed_money, "needed_money==" << needed_money << " < found_money==" << found_money);
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;
}
if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM))
{
// TODO: consider allowing to set them somewhere
size_t min_number_of_outputs = CURRENCY_TX_MIN_ALLOWED_OUTS;
size_t num_digits_to_keep = CURRENCY_TX_OUTS_RND_SPLIT_DIGITS_TO_KEEP;
for(auto& dst : dsts)
{
decompose_amount_randomly(dst.amount, [&](uint64_t a){ final_destinations.emplace_back(a, dst.addr, dst.asset_id); }, min_number_of_outputs, num_digits_to_keep);
}
if (change_dts.amount > 0)
{
if (final_destinations.size() >= min_number_of_outputs - 1)
final_destinations.emplace_back(std::move(change_dts)); // don't split the change if there's enough outs
else
decompose_amount_randomly(change_dts.amount, [&](uint64_t a){ final_destinations.emplace_back(a, change_dts.addr, change_dts.asset_id); }, min_number_of_outputs, num_digits_to_keep);
if (dst.asset_id == asset_id)
final_destinations.emplace_back(dst.amount, dst.addr, dst.asset_id);
}
if (found_money > needed_money)
final_destinations.emplace_back(found_money - needed_money, m_account.get_public_address(), asset_id); // returning back the change
}
else
{
// pre-HF4
if (asset_id != currency::null_hash)
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(asset_id != currency::null_hash, "assets are not allowed prior to HF4");
currency::tx_destination_entry change_dts = AUTO_VAL_INIT(change_dts);
if (needed_money < found_money)
{
if (change_dts.amount)
{
final_destinations.push_back(change_dts);
}
return;
change_dts.addr.push_back(m_account.get_keys().account_address);
change_dts.amount = found_money - needed_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_destinations, dust, WALLET_MAX_ALLOWED_OUTPUT_AMOUNT);
@ -5833,7 +5830,7 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money,
if (0 != dust && !dust_policy.add_to_fee)
{
final_destinations.emplace_back(dust, dust_policy.addr_for_dust, asset_id);
final_destinations.emplace_back(dust, dust_policy.addr_for_dust);
}
}
}

View file

@ -438,8 +438,19 @@ namespace tools
for (size_t i = 0; i < m_sources.size(); ++i)
{
const currency::tx_source_entry& src = m_sources[i];
ss << "\n source " << i << ":";
ss << "\n amount: " << currency::print_money(src.amount);
ss << "\n " << i << ": ";
ss << " amount: " << std::setw(21) << currency::print_money(src.amount);
ss << src.is_zarcanum() ? " ZC " : " old ";
ss << " asset_id: " << src.asset_id;
for (size_t j = 0; j < src.outputs.size(); ++j)
{
const currency::tx_source_entry::output_entry& out = src.outputs[j];
if (out.out_reference.type() == typeid(uint64_t))
ss << "\n ref #" << j << ": " << boost::get<uint64_t>(out.out_reference);
else
ss << "\n ref #" << j << ": ref by id";
}
// It's not good, if logs will contain such much data
//ss << "\n real_output: " << src.real_output;
//ss << "\n real_output_in_tx_index: " << src.real_output_in_tx_index;
@ -462,7 +473,7 @@ namespace tools
{
ss << currency::get_account_address_as_str(a) << ";";
}
ss << " anount: " << currency::print_money(dst.amount);
ss << " amount: " << std::setw(21) << currency::print_money(dst.amount);
ss << " asset_id: " << dst.asset_id;
}