1
0
Fork 0
forked from lthn/blockchain

wallet: minor refactoring around generate_utxo_defragmentation_transaction_if_needed; coretests packing_outputs_on_pos_minting_wallet and pos_minting_tx_packing fixed

This commit is contained in:
sowle 2023-06-12 20:37:26 +02:00
parent 2955b2c231
commit dbb2712119
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
6 changed files with 31 additions and 22 deletions

View file

@ -12,7 +12,6 @@
#define API_RETURN_CODE_INTERNAL_ERROR "INTERNAL_ERROR"
#define API_RETURN_CODE_NOT_ENOUGH_MONEY "NOT_ENOUGH_MONEY"
#define API_RETURN_CODE_NOT_ENOUGH_OUTPUTS_FOR_MIXING "NOT_ENOUGH_OUTPUTS_FOR_MIXING"
#define API_RETURN_CODE_NOT_ENOUGH_OUTPUTS_FOR_OPERATION "NOT_ENOUGH_OUTPUTS_FOR_OPERATION"
#define API_RETURN_CODE_INTERNAL_ERROR_QUE_FULL "INTERNAL_ERROR_QUE_FULL"
#define API_RETURN_CODE_BAD_ARG "BAD_ARG"
#define API_RETURN_CODE_BAD_ARG_EMPTY_DESTINATIONS "BAD_ARG_EMPTY_DESTINATIONS"

View file

@ -190,6 +190,7 @@ namespace currency
std::string htlc_origin;
std::vector<serializable_pair<uint64_t, crypto::key_image>> outs_key_images; // pairs (out_index, key_image) for each change output
crypto::key_derivation derivation;
bool was_not_prepared = false; // true if tx was not prepared/created for some good reason (e.g. not enough outs for UTXO defragmentation tx). Because we decided not to throw exceptions for non-error cases. -- sowle
BEGIN_SERIALIZE_OBJECT()
FIELD(tx)
@ -198,6 +199,7 @@ namespace currency
FIELD(htlc_origin)
FIELD(outs_key_images)
FIELD(derivation)
FIELD(was_not_prepared)
END_SERIALIZE()
};

View file

@ -209,9 +209,15 @@ bool wallet2::set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy)
return true;
}
//----------------------------------------------------------------------------------------------------
void wallet2::set_pos_min_utxo_count_for_defragmentation_tx(uint64_t new_size)
void wallet2::set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs)
{
m_min_utxo_count_for_defragmentation_tx = new_size;
m_min_utxo_count_for_defragmentation_tx = min_outs;
m_max_utxo_count_for_defragmentation_tx = max_outs;
}
//----------------------------------------------------------------------------------------------------
void wallet2::set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count)
{
m_decoys_count_for_defragmentation_tx = decoys_count;
}
//----------------------------------------------------------------------------------------------------
std::shared_ptr<i_core_proxy> wallet2::get_core_proxy()
@ -3373,19 +3379,14 @@ bool wallet2::generate_utxo_defragmentation_transaction_if_needed(currency::tran
{
construct_tx_param ctp = get_default_construct_tx_param();
ctp.create_utxo_defragmentation_tx = true;
try
{
transfer(ctp, tx, false, nullptr);
}
catch(error::wallet_error& we)
{
if (we.error_code() == API_RETURN_CODE_NOT_ENOUGH_OUTPUTS_FOR_OPERATION)
return false;
WLT_LOG_ERROR("generate_utxo_defragmentation_transaction_if_needed: transfer failed with: " << we.what());
//} <-- this brace is inside CATCH_ENTRY2
CATCH_ENTRY2(false);
finalized_tx ftp{};
transfer(ctp, ftp, false, nullptr);
if (ftp.was_not_prepared)
return false; // no such UTXO were found, not an error
tx = ftp.tx;
return true;
}
//----------------------------------------------------------------------------------------------------
@ -6419,7 +6420,7 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money,
}
}
//----------------------------------------------------------------------------------------------------
void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& msc)
bool wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& msc)
{
SET_CONTEXT_OBJ_FOR_SCOPE(pconstruct_tx_param, ctp);
@ -6454,7 +6455,7 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx
if (ctp.create_utxo_defragmentation_tx)
{
if (!prepare_tx_sources_for_defragmentation_tx(ftp.sources, ftp.selected_transfers, needed_money_map[currency::native_coin_asset_id].found_amount))
throw error::wallet_error(LOCATION_STR, "", API_RETURN_CODE_NOT_ENOUGH_OUTPUTS_FOR_OPERATION);
return false;
}
else if (ctp.htlc_tx_id != currency::null_hash)
{
@ -6510,6 +6511,7 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx
<< ", construct_tx_time: " << construct_tx_time << " ms"
<< ", sign_ms_input_time: " << sign_ms_input_time << " ms",
LOG_LEVEL_0);*/
return true;
}
//----------------------------------------------------------------------------------------------------
void wallet2::finalize_transaction(const currency::finalize_tx_param& ftp, currency::transaction& tx, crypto::secret_key& tx_key, bool broadcast_tx, bool store_tx_secret_key /* = true */)
@ -6718,7 +6720,11 @@ void wallet2::transfer(construct_tx_param& ctp,
TIME_MEASURE_START(prepare_transaction_time);
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.tx_version = this->get_current_tx_version();
prepare_transaction(ctp, ftp);
if (prepare_transaction(ctp, ftp))
{
result.was_not_prepared = true;
return;
}
TIME_MEASURE_FINISH(prepare_transaction_time);
if (m_watch_only)

View file

@ -607,7 +607,8 @@ namespace tools
void deploy_new_asset(const currency::asset_descriptor_base& asset_info, const std::vector<currency::tx_destination_entry>& destinations, currency::transaction& result_tx, crypto::public_key& new_asset_id);
bool set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy);
void set_pos_min_utxo_count_for_defragmentation_tx(uint64_t new_size);
void set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs); // don't create UTXO defrag. tx if there are less than 'min_outs' outs; don't put more than 'max_outs' outs
void set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count);
void set_minimum_height(uint64_t h);
std::shared_ptr<i_core_proxy> get_core_proxy();
uint64_t balance() const;
@ -931,7 +932,7 @@ namespace tools
const std::list<expiration_entry_info>& get_expiration_entries() const { return m_money_expirations; };
bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) const;
void prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& emode_separate = mode_separate_context());
bool prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& emode_separate = mode_separate_context());
void finalize_transaction(const currency::finalize_tx_param& ftp, currency::transaction& tx, crypto::secret_key& tx_key, bool broadcast_tx, bool store_tx_secret_key = true);
void finalize_transaction(const currency::finalize_tx_param& ftp, currency::finalized_tx& result, bool broadcast_tx, bool store_tx_secret_key = true );

View file

@ -1085,7 +1085,7 @@ bool pos_minting_tx_packing::c1(currency::core& c, size_t ev_index, const std::v
m_alice_start_amount + CURRENCY_BLOCK_REWARD * m_pos_mint_packing_size // unlocked
), false, "");
alice_wlt->set_pos_min_utxo_count_for_defragmentation_tx(m_pos_mint_packing_size);
alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(m_pos_mint_packing_size + 1, m_pos_mint_packing_size + 1); // +1 because previous implementation () had an error with this limit
// no coinbase tx outputs should be packed
r = alice_wlt->try_mint_pos();

View file

@ -3402,7 +3402,8 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde
miner_wlt->refresh(blocks_fetched, received_money, atomic_false);
CHECK_AND_ASSERT_MES(blocks_fetched == CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5, false, "Incorrect numbers of blocks fetched");
miner_wlt->set_pos_min_utxo_count_for_defragmentation_tx(4);
miner_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(5, 5);
miner_wlt->set_pos_decoys_count_for_defragmentation_tx(0);
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*miner_wlt.get(), "miner_wlt", m_premine_amount + m_mined_amount, uint64_max, uint64_max, 0, 0), false, "");
miner_wlt->try_mint_pos();