diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index da380010..eb90f017 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2289,6 +2289,17 @@ uint64_t wallet2::balance() const void wallet2::get_transfers(wallet2::transfer_container& incoming_transfers) const { incoming_transfers = m_transfers; +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::generate_packing_transaction_if_needed(transaction& tx) +{ + 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() < WALLET_POS_MINT_PACKING_SIZE) + return false; + + + } //---------------------------------------------------------------------------------------------------- std::string wallet2::get_transfers_str(bool include_spent /*= true*/, bool include_unspent /*= true*/) const @@ -3424,11 +3435,41 @@ void wallet2::send_escrow_proposal(const bc_services::contract_private_details& print_tx_sent_message(tx, "(from multisig)", fee); } //---------------------------------------------------------------------------------------------------- +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() < WALLET_POS_MINT_PACKING_SIZE) + return false; + + uint64_t found_money = 0; + for (auto set_it = it->second.begin(); set_it != it->second.end(); it++) + { + if (is_transfer_ready_to_go(m_transfers[*set_it], fake_outputs_count)) + { + found_money += it->first; + selected_indicies.push_back(*set_it); + WLT_LOG_L2("Selected index: " << *set_it << ", transfer_details: " << ENDL << epee::serialization::store_t_to_json(m_transfers[*set_it])); + } + it->second.erase(it->second.begin()); + if (!it->second.size()) + found_free_amounts.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) { found_money = select_transfers(needed_money, fake_outputs_count, dust_threshold, selected_indicies); THROW_IF_FALSE_WALLET_EX_MES(found_money >= needed_money, error::not_enough_money, "wallet_dump: " << ENDL << dump_trunsfers(false), found_money, needed_money, 0); - + return prepare_tx_sources(fake_outputs_count, sources, selected_indicies, found_money); +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector& sources, std::vector& selected_indicies, uint64_t& found_money) +{ typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry; typedef currency::tx_source_entry::output_entry tx_output_entry; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index e1fd1d63..bb989655 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -42,6 +42,8 @@ #define WALLET_DEFAULT_TX_SPENDABLE_AGE 10 #define WALLET_POS_MINT_CHECK_HEIGHT_INTERVAL 1 +#define WALLET_POS_MINT_PACKING_SIZE 100 + #undef LOG_DEFAULT_CHANNEL #define LOG_DEFAULT_CHANNEL "wallet" ENABLE_CHANNEL_BY_DEFAULT("wallet"); @@ -256,6 +258,7 @@ namespace tools currency::account_public_address crypt_address; uint8_t tx_outs_attr; bool shuffle; + bool perform_packing; }; struct finalize_tx_param @@ -784,7 +787,9 @@ private: 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(crypto::hash multisig_id, 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); uint64_t get_needed_money(uint64_t fee, const std::vector& dsts); void prepare_tx_destinations(uint64_t needed_money, uint64_t found_money, @@ -842,7 +847,7 @@ private: void exception_handler() const; uint64_t get_minimum_allowed_fee_for_contract(const crypto::hash& ms_id); void check_for_free_space_and_throw_if_it_lacks(const std::wstring& path, uint64_t exact_size_needed_if_known = UINT64_MAX); - + bool generate_packing_transaction_if_needed(transaction& tx); currency::account_base m_account;