1
0
Fork 0
forked from lthn/blockchain

Merge branch 'release2'

This commit is contained in:
sowle 2024-03-29 17:09:26 +01:00
commit e928d03ec7
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
11 changed files with 227 additions and 151 deletions

View file

@ -66,7 +66,11 @@ namespace currency
init_ethash_log_if_necessary();
int epoch = ethash_height_to_epoch(height);
std::shared_ptr<ethash::epoch_context_full> p_context = progpow::get_global_epoch_context_full(static_cast<int>(epoch));
CHECK_AND_ASSERT_THROW_MES(p_context, "progpow::get_global_epoch_context_full returned null");
if (!p_context)
{
LOG_ERROR("fatal error: get_global_epoch_context_full failed, throwing bad_alloc...");
throw std::bad_alloc();
}
auto res_eth = progpow::hash(*p_context, static_cast<int>(height), *(ethash::hash256*)&block_header_hash, nonce);
crypto::hash result = currency::null_hash;
memcpy(&result.data, &res_eth.final_hash, sizeof(res_eth.final_hash));

View file

@ -6941,7 +6941,12 @@ bool blockchain_storage::add_new_block(const block& bl, block_verification_conte
if (m_event_handler) m_event_handler->on_complete_events();
return res;
}
}
catch (const std::bad_alloc&)
{
// failed memory allocation is critical; this is supposed to be handled by the called (assuming immediate stop)
throw;
}
catch (const std::exception& ex)
{
bvc.m_verification_failed = true;

View file

@ -415,82 +415,102 @@ namespace currency
//-----------------------------------------------------------------------------------------------
bool core::handle_block_found(const block& b, block_verification_context* p_verification_result, bool need_update_miner_block_template)
{
TIME_MEASURE_START_MS(time_total_ms);
block_verification_context bvc = boost::value_initialized<block_verification_context>();
if (!p_verification_result)
p_verification_result = &bvc;
m_miner.pause();
misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([this]()
try
{
m_miner.resume();
});
TIME_MEASURE_START_MS(time_total_ms);
block_verification_context bvc = boost::value_initialized<block_verification_context>();
if (!p_verification_result)
p_verification_result = &bvc;
TIME_MEASURE_START_MS(time_add_new_block_ms);
m_blockchain_storage.add_new_block(b, *p_verification_result);
TIME_MEASURE_FINISH_MS(time_add_new_block_ms);
//anyway - update miner template
TIME_MEASURE_START_MS(time_update_block_template_ms);
if (need_update_miner_block_template)
update_miner_block_template();
TIME_MEASURE_FINISH_MS(time_update_block_template_ms);
uint64_t time_pack_txs_ms = 0, time_relay_ms = 0;
if (p_verification_result->m_verification_failed || !p_verification_result->m_added_to_main_chain)
{
LOG_PRINT2("failed_mined_blocks.log", "verification_failed: " << p_verification_result->m_verification_failed << ", added_to_main_chain: " << p_verification_result->m_added_to_main_chain << ENDL <<
currency::obj_to_json_str(b), LOG_LEVEL_0);
}
CHECK_AND_ASSERT_MES(!p_verification_result->m_verification_failed, false, "mined block has failed to pass verification: id " << get_block_hash(b) << " @ height " << get_block_height(b) << " prev_id: " << b.prev_id);
if(p_verification_result->m_added_to_main_chain)
{
time_pack_txs_ms = epee::misc_utils::get_tick_count();
currency_connection_context exclude_context = boost::value_initialized<currency_connection_context>();
NOTIFY_NEW_BLOCK::request arg = AUTO_VAL_INIT(arg);
arg.hop = 0;
arg.current_blockchain_height = m_blockchain_storage.get_current_blockchain_size();
std::list<crypto::hash> missed_txs;
std::list<transaction> txs;
m_blockchain_storage.get_transactions(b.tx_hashes, txs, missed_txs);
if(missed_txs.size() && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b))
m_miner.pause();
misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([this]()
{
LOG_PRINT_L0("Block found (id " << get_block_hash(b) << " @ height " << get_block_height(b) << ") but it seems that reorganize just happened after that, do not relay this block");
return true;
m_miner.resume();
});
TIME_MEASURE_START_MS(time_add_new_block_ms);
m_blockchain_storage.add_new_block(b, *p_verification_result);
TIME_MEASURE_FINISH_MS(time_add_new_block_ms);
//anyway - update miner template
TIME_MEASURE_START_MS(time_update_block_template_ms);
if (need_update_miner_block_template)
update_miner_block_template();
TIME_MEASURE_FINISH_MS(time_update_block_template_ms);
uint64_t time_pack_txs_ms = 0, time_relay_ms = 0;
if (p_verification_result->m_verification_failed || !p_verification_result->m_added_to_main_chain)
{
LOG_PRINT2("failed_mined_blocks.log", "verification_failed: " << p_verification_result->m_verification_failed << ", added_to_main_chain: " << p_verification_result->m_added_to_main_chain << ENDL <<
currency::obj_to_json_str(b), LOG_LEVEL_0);
}
if (txs.size() != b.tx_hashes.size() || missed_txs.size() != 0)
CHECK_AND_ASSERT_MES(!p_verification_result->m_verification_failed, false, "mined block has failed to pass verification: id " << get_block_hash(b) << " @ height " << get_block_height(b) << " prev_id: " << b.prev_id);
if(p_verification_result->m_added_to_main_chain)
{
std::stringstream ss;
ss << "txs:" << ENDL;
for (auto& t : txs)
ss << get_transaction_hash(t) << ENDL;
ss << "missed txs:" << ENDL;
for (auto& tx_id : missed_txs)
ss << tx_id << ENDL;
LOG_ERROR("can't find some transactions in found block: " << get_block_hash(b) << ", txs.size()=" << txs.size()
<< ", b.tx_hashes.size()=" << b.tx_hashes.size() << ", missed_txs.size()=" << missed_txs.size() << ENDL << ss.str());
return false;
time_pack_txs_ms = epee::misc_utils::get_tick_count();
currency_connection_context exclude_context = boost::value_initialized<currency_connection_context>();
NOTIFY_NEW_BLOCK::request arg = AUTO_VAL_INIT(arg);
arg.hop = 0;
arg.current_blockchain_height = m_blockchain_storage.get_current_blockchain_size();
std::list<crypto::hash> missed_txs;
std::list<transaction> txs;
m_blockchain_storage.get_transactions(b.tx_hashes, txs, missed_txs);
if(missed_txs.size() && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b))
{
LOG_PRINT_L0("Block found (id " << get_block_hash(b) << " @ height " << get_block_height(b) << ") but it seems that reorganize just happened after that, do not relay this block");
return true;
}
if (txs.size() != b.tx_hashes.size() || missed_txs.size() != 0)
{
std::stringstream ss;
ss << "txs:" << ENDL;
for (auto& t : txs)
ss << get_transaction_hash(t) << ENDL;
ss << "missed txs:" << ENDL;
for (auto& tx_id : missed_txs)
ss << tx_id << ENDL;
LOG_ERROR("can't find some transactions in found block: " << get_block_hash(b) << ", txs.size()=" << txs.size()
<< ", b.tx_hashes.size()=" << b.tx_hashes.size() << ", missed_txs.size()=" << missed_txs.size() << ENDL << ss.str());
return false;
}
block_to_blob(b, arg.b.block);
//pack transactions
for(auto& tx : txs)
arg.b.txs.push_back(t_serializable_object_to_blob(tx));
TIME_MEASURE_FINISH_MS(time_pack_txs_ms);
time_relay_ms = epee::misc_utils::get_tick_count();
m_pprotocol->relay_block(arg, exclude_context);
TIME_MEASURE_FINISH_MS(time_relay_ms);
}
block_to_blob(b, arg.b.block);
//pack transactions
for(auto& tx : txs)
arg.b.txs.push_back(t_serializable_object_to_blob(tx));
TIME_MEASURE_FINISH_MS(time_total_ms);
LOG_PRINT_L2("handle_block_found timings (ms): total: " << time_total_ms << ", add new block: " << time_add_new_block_ms << ", update template: " << time_update_block_template_ms << ", pack txs: " << time_pack_txs_ms << ", relay: " << time_relay_ms);
TIME_MEASURE_FINISH_MS(time_pack_txs_ms);
time_relay_ms = epee::misc_utils::get_tick_count();
m_pprotocol->relay_block(arg, exclude_context);
TIME_MEASURE_FINISH_MS(time_relay_ms);
return p_verification_result->m_added_to_main_chain;
}
catch(std::bad_alloc&)
{
LOG_ERROR("bad_alloc in core::handle_block_found(), requesting immediate stop...");
if (m_critical_error_handler)
m_critical_error_handler->on_immediate_stop_requested();
return false;
}
catch(std::exception& e)
{
LOG_ERROR("caught exception in core::handle_block_found(): " << e.what());
return false;
}
catch(...)
{
LOG_ERROR("caught unknown exception in core::handle_block_found()");
return false;
}
TIME_MEASURE_FINISH_MS(time_total_ms);
LOG_PRINT_L2("handle_block_found timings (ms): total: " << time_total_ms << ", add new block: " << time_add_new_block_ms << ", update template: " << time_update_block_template_ms << ", pack txs: " << time_pack_txs_ms << ", relay: " << time_relay_ms);
return p_verification_result->m_added_to_main_chain;
}
//-----------------------------------------------------------------------------------------------
bool core::handle_block_found(const block& b, block_verification_context* p_verification_result /* = nullptr */)
@ -509,39 +529,59 @@ namespace currency
//-----------------------------------------------------------------------------------------------
bool core::add_new_block(const block& b, block_verification_context& bvc)
{
uint64_t h = m_blockchain_storage.get_top_block_height();
if (m_stop_after_height != 0 && h >= m_stop_after_height)
try
{
LOG_PRINT_YELLOW("Blockchain top block height is " << h << ", the daemon will now stop as requested", LOG_LEVEL_0);
if (m_critical_error_handler)
return m_critical_error_handler->on_immediate_stop_requested();
return false;
}
bool r = m_blockchain_storage.add_new_block(b, bvc);
if (r && bvc.m_added_to_main_chain)
{
uint64_t h = get_block_height(b);
if (h > 0)
uint64_t h = m_blockchain_storage.get_top_block_height();
if (m_stop_after_height != 0 && h >= m_stop_after_height)
{
auto& crc = m_blockchain_storage.get_core_runtime_config();
size_t hardfork_id_for_prev_block = crc.hard_forks.get_the_most_recent_hardfork_id_for_height(h);
size_t hardfork_id_for_curr_block = crc.hard_forks.get_the_most_recent_hardfork_id_for_height(h + 1);
if (hardfork_id_for_prev_block != hardfork_id_for_curr_block)
{
LOG_PRINT_GREEN("Hardfork " << hardfork_id_for_curr_block << " has been activated after the block at height " << h, LOG_LEVEL_0);
}
}
if (h == m_stop_after_height)
{
LOG_PRINT_YELLOW("Reached block " << h << ", the daemon will now stop as requested", LOG_LEVEL_0);
LOG_PRINT_YELLOW("Blockchain top block height is " << h << ", the daemon will now stop as requested", LOG_LEVEL_0);
if (m_critical_error_handler)
return m_critical_error_handler->on_immediate_stop_requested();
return false;
}
bool r = m_blockchain_storage.add_new_block(b, bvc);
if (r && bvc.m_added_to_main_chain)
{
uint64_t h = get_block_height(b);
if (h > 0)
{
auto& crc = m_blockchain_storage.get_core_runtime_config();
size_t hardfork_id_for_prev_block = crc.hard_forks.get_the_most_recent_hardfork_id_for_height(h);
size_t hardfork_id_for_curr_block = crc.hard_forks.get_the_most_recent_hardfork_id_for_height(h + 1);
if (hardfork_id_for_prev_block != hardfork_id_for_curr_block)
{
LOG_PRINT_GREEN("Hardfork " << hardfork_id_for_curr_block << " has been activated after the block at height " << h, LOG_LEVEL_0);
}
}
if (h == m_stop_after_height)
{
LOG_PRINT_YELLOW("Reached block " << h << ", the daemon will now stop as requested", LOG_LEVEL_0);
if (m_critical_error_handler)
return m_critical_error_handler->on_immediate_stop_requested();
return false;
}
}
return r;
}
catch(std::bad_alloc&)
{
LOG_ERROR("bad_alloc in core::add_new_block(), requesting immediate stop...");
if (m_critical_error_handler)
m_critical_error_handler->on_immediate_stop_requested();
return false;
}
catch(std::exception& e)
{
LOG_ERROR("caught exception in core::add_new_block(): " << e.what());
return false;
}
catch(...)
{
LOG_ERROR("caught unknown exception in core::add_new_block()");
return false;
}
return r;
}
//-----------------------------------------------------------------------------------------------
bool core::parse_block(const blobdata& block_blob, block& b, block_verification_context& bvc)

View file

@ -756,6 +756,7 @@ namespace currency
}
}
//---------------------------------------------------------------
// TODO: reverse order of arguments
bool parse_amount(uint64_t& amount, const std::string& str_amount_)
{
std::string str_amount = str_amount_;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2023 Zano Project
// Copyright (c) 2014-2024 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
@ -118,29 +118,32 @@ namespace ph = boost::placeholders;
#define CONFIRM_WITH_PASSWORD() if(!check_password_for_operation()) return true;
#define DEFAULT_WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX 3
#define DEFAULT_WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX 10
namespace
{
const command_line::arg_descriptor<std::string> arg_wallet_file ("wallet-file", "Use wallet <arg>", "");
const command_line::arg_descriptor<std::string> arg_generate_new_wallet ("generate-new-wallet", "Generate new wallet and save it to <arg> or <address>.wallet by default", "");
const command_line::arg_descriptor<std::string> arg_generate_new_auditable_wallet ("generate-new-auditable-wallet", "Generate new auditable wallet and store it to <arg>", "");
const command_line::arg_descriptor<std::string> arg_daemon_address ("daemon-address", "Use daemon instance at <host>:<port>", "");
const command_line::arg_descriptor<std::string> arg_daemon_host ("daemon-host", "Use daemon instance at host <arg> instead of localhost", "");
const command_line::arg_descriptor<std::string> arg_password ("password", "Wallet password");
const command_line::arg_descriptor<bool> arg_dont_refresh ( "no-refresh", "Do not refresh after load");
const command_line::arg_descriptor<bool> arg_dont_set_date ( "no-set-creation-date", "Do not set wallet creation date", false);
const command_line::arg_descriptor<int> arg_daemon_port ("daemon-port", "Use daemon instance at port <arg> instead of default", 0);
//const command_line::arg_descriptor<uint32_t> arg_log_level ("set-log", "");
const command_line::arg_descriptor<bool> arg_do_pos_mining ( "do-pos-mining", "Do PoS mining", false);
const command_line::arg_descriptor<std::string> arg_pos_mining_reward_address ( "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" );
const command_line::arg_descriptor<std::string> arg_restore_wallet ( "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to <arg>", "" );
const command_line::arg_descriptor<bool> arg_offline_mode ( "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)");
const command_line::arg_descriptor<std::string> arg_scan_for_wallet ( "scan-for-wallet", "");
const command_line::arg_descriptor<std::string> arg_addr_to_compare ( "addr-to-compare", "");
const command_line::arg_descriptor<bool> arg_disable_tor_relay ( "disable-tor-relay", "Disable TOR relay", false);
const command_line::arg_descriptor<unsigned int> arg_set_timeout("set-timeout", "Set timeout for the wallet");
const command_line::arg_descriptor<std::string> arg_voting_config_file("voting-config-file", "Set voting config instead of getting if from daemon", "");
const command_line::arg_descriptor<bool> arg_no_password_confirmations("no-password-confirmation", "Enable/Disable password confirmation for transactions", false);
const command_line::arg_descriptor<std::string> arg_wallet_file ("wallet-file", "Use wallet <arg>", "");
const command_line::arg_descriptor<std::string> arg_generate_new_wallet ("generate-new-wallet", "Generate new wallet and save it to <arg> or <address>.wallet by default", "");
const command_line::arg_descriptor<std::string> arg_generate_new_auditable_wallet ("generate-new-auditable-wallet", "Generate new auditable wallet and store it to <arg>", "");
const command_line::arg_descriptor<std::string> arg_daemon_address ("daemon-address", "Use daemon instance at <host>:<port>", "");
const command_line::arg_descriptor<std::string> arg_daemon_host ("daemon-host", "Use daemon instance at host <arg> instead of localhost", "");
const command_line::arg_descriptor<std::string> arg_password ("password", "Wallet password");
const command_line::arg_descriptor<bool> arg_dont_refresh ( "no-refresh", "Do not refresh after load");
const command_line::arg_descriptor<bool> arg_dont_set_date ( "no-set-creation-date", "Do not set wallet creation date", false);
const command_line::arg_descriptor<int> arg_daemon_port ("daemon-port", "Use daemon instance at port <arg> instead of default", 0);
const command_line::arg_descriptor<bool> arg_do_pos_mining ( "do-pos-mining", "Do PoS mining", false);
const command_line::arg_descriptor<std::string> arg_pos_mining_reward_address ( "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" );
const command_line::arg_descriptor<std::string> arg_pos_mining_defrag ( "pos-mining-defrag", "<min_outs_cnt,max_outs_cnt,amount_limit> Generate defragmentation tx for small outputs each time a PoS block is found. Default params: " STR(DEFAULT_WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) "," STR(DEFAULT_WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX) ",1.0", "" );
const command_line::arg_descriptor<std::string> arg_restore_wallet ( "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to <arg>", "" );
const command_line::arg_descriptor<bool> arg_offline_mode ( "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)");
const command_line::arg_descriptor<std::string> arg_scan_for_wallet ( "scan-for-wallet", "");
const command_line::arg_descriptor<std::string> arg_addr_to_compare ( "addr-to-compare", "");
const command_line::arg_descriptor<bool> arg_disable_tor_relay ( "disable-tor-relay", "Disable TOR relay", false);
const command_line::arg_descriptor<unsigned int> arg_set_timeout("set-timeout", "Set timeout for the wallet");
const command_line::arg_descriptor<std::string> arg_voting_config_file("voting-config-file", "Set voting config instead of getting if from daemon", "");
const command_line::arg_descriptor<bool> arg_no_password_confirmations("no-password-confirmation", "Enable/Disable password confirmation for transactions", false);
const command_line::arg_descriptor< std::vector<std::string> > arg_command ("command", "");
@ -2665,6 +2668,7 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_params, arg_dont_set_date);
command_line::add_arg(desc_params, arg_do_pos_mining);
command_line::add_arg(desc_params, arg_pos_mining_reward_address);
command_line::add_arg(desc_params, arg_pos_mining_defrag);
command_line::add_arg(desc_params, arg_restore_wallet);
command_line::add_arg(desc_params, arg_offline_mode);
command_line::add_arg(desc_params, command_line::arg_log_file);
@ -2850,6 +2854,28 @@ int main(int argc, char* argv[])
LOG_PRINT_YELLOW("PoS reward will be sent to another address: " << arg_pos_mining_reward_address_str, LOG_LEVEL_0);
}
}
if (command_line::has_arg(vm, arg_pos_mining_defrag))
{
std::string arg_pos_mining_defrag_str = command_line::get_arg(vm, arg_pos_mining_defrag);
if (arg_pos_mining_defrag_str.empty())
{
// enable with default params
wal.set_defragmentation_tx_settings(true, DEFAULT_WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX, DEFAULT_WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX, COIN);
}
else
{
std::vector<std::string> params;
boost::split(params, arg_pos_mining_defrag_str, boost::is_any_of(",;"), boost::token_compress_on);
CHECK_AND_ASSERT_MES(params.size() == 3, EXIT_FAILURE, "incorrect number of params given: " << arg_pos_mining_defrag_str);
int64_t outs_min = 0, outs_max = 0;
uint64_t max_amount = 0;
CHECK_AND_ASSERT_MES(epee::string_tools::string_to_num_fast(params[0], outs_min) && outs_min > 0 && outs_min < 256, EXIT_FAILURE, "incorrect param: " << params[0]);
CHECK_AND_ASSERT_MES(epee::string_tools::string_to_num_fast(params[1], outs_max) && outs_max > 0 && outs_max < 256, EXIT_FAILURE, "incorrect param: " << params[1]);
CHECK_AND_ASSERT_MES(currency::parse_amount(max_amount, params[2]), EXIT_FAILURE, "incorrect param: " << params[2]);
wal.set_defragmentation_tx_settings(true, outs_min, outs_max, max_amount);
}
}

View file

@ -8,6 +8,6 @@
#define PROJECT_REVISION "0"
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
#define PROJECT_VERSION_BUILD_NO 290
#define PROJECT_VERSION_BUILD_NO 292
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"

View file

@ -89,7 +89,7 @@ void decoy_selection_generator::generate_unique_reversed_distribution(uint64_t c
{
if (count + set_to_extend.size() > m_max)
{
throw std::runtime_error("generate_distribution_set with unexpected count");
throw std::runtime_error(std::string("generate_distribution_set with unexpected count=") + std::to_string(count) + ", set_to_extend.size() = " + std::to_string(set_to_extend.size()) + ", m_max: " + std::to_string(m_max));
}
size_t attempt_count = 0;

View file

@ -56,10 +56,6 @@ using namespace currency;
#define MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES (100*1024*1024) // 100 MB
#define WALLET_DEFAULT_DECOYS_COUNT_FOR_DEFRAGMENTATION_TX 10 // TODO @#@# change to default decoy set number
#define WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX 3 // TODO: @#@# consider descreasing to mimic normal tx
#define WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX 10 // TODO: @#@# consider descreasing to mimic normal tx
#define WALLET_TX_MAX_ALLOWED_FEE (COIN * 100)
#define WALLET_FETCH_RANDOM_OUTS_SIZE 200
@ -83,8 +79,8 @@ namespace tools
, m_required_decoys_count(CURRENCY_DEFAULT_DECOY_SET_SIZE)
, m_defragmentation_tx_enabled(false)
, m_max_allowed_output_amount_for_defragmentation_tx(CURRENCY_BLOCK_REWARD)
, m_min_utxo_count_for_defragmentation_tx(WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX)
, m_max_utxo_count_for_defragmentation_tx(WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX)
, m_min_utxo_count_for_defragmentation_tx(0)
, m_max_utxo_count_for_defragmentation_tx(0)
, m_decoys_count_for_defragmentation_tx(SIZE_MAX)
, m_use_deffered_global_outputs(false)
#ifdef DISABLE_TOR
@ -174,15 +170,22 @@ bool wallet2::set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy)
return true;
}
//----------------------------------------------------------------------------------------------------
void wallet2::set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs)
void wallet2::set_defragmentation_tx_settings(bool enabled, uint64_t min_outs, uint64_t max_outs, uint64_t max_allowed_amount, size_t decoys_count)
{
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;
m_defragmentation_tx_enabled = enabled;
m_min_utxo_count_for_defragmentation_tx = min_outs;
m_max_utxo_count_for_defragmentation_tx = max_outs;
m_max_allowed_output_amount_for_defragmentation_tx = max_allowed_amount;
m_decoys_count_for_defragmentation_tx = decoys_count;
if (enabled)
{
WLT_LOG_L0("Defragmentation tx creation is enabled, settings: min outs: " << min_outs << ", max outs: " << max_outs << ", max amount: " << print_money_brief(max_allowed_amount) <<
", decoys: " << (decoys_count != SIZE_MAX ? epee::string_tools::num_to_string_fast(decoys_count) : std::string("default")));
}
else
{
WLT_LOG_L0("Defragmentation tx creation is disabled");
}
}
//----------------------------------------------------------------------------------------------------
std::shared_ptr<i_core_proxy> wallet2::get_core_proxy()
@ -430,7 +433,7 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op
<< ENDL << "Ticker: " << asset_context.asset_descriptor.ticker
<< ENDL << "Total Max Supply: " << print_asset_money(asset_context.asset_descriptor.total_max_supply, asset_context.asset_descriptor.decimal_point)
<< ENDL << "Current Supply: " << print_asset_money(asset_context.asset_descriptor.current_supply, asset_context.asset_descriptor.decimal_point)
<< ENDL << "Decimal Point: " << asset_context.asset_descriptor.decimal_point;
<< ENDL << "Decimal Point: " << (int)asset_context.asset_descriptor.decimal_point;
add_rollback_event(ptc.height, asset_register_event{ asset_id });
@ -466,7 +469,7 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op
<< ENDL << "Ticker: " << ado.descriptor.ticker
<< ENDL << "Total Max Supply: " << print_asset_money(ado.descriptor.total_max_supply, ado.descriptor.decimal_point)
<< ENDL << "Current Supply: " << print_asset_money(ado.descriptor.current_supply, ado.descriptor.decimal_point)
<< ENDL << "Decimal Point: " << ado.descriptor.decimal_point;
<< ENDL << "Decimal Point: " << (int)ado.descriptor.decimal_point;
add_rollback_event(ptc.height, asset_register_event{ asset_id });
@ -497,7 +500,7 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op
<< ENDL << "Ticker: " << ado.descriptor.ticker
<< ENDL << "Total Max Supply: " << print_asset_money(ado.descriptor.total_max_supply, ado.descriptor.decimal_point)
<< ENDL << "Current Supply: " << print_asset_money(ado.descriptor.current_supply, ado.descriptor.decimal_point)
<< ENDL << "Decimal Point: " << ado.descriptor.decimal_point;
<< ENDL << "Decimal Point: " << (int)ado.descriptor.decimal_point;
add_rollback_event(ptc.height, asset_register_event{ asset_id });
WLT_LOG_MAGENTA(ss.str(), LOG_LEVEL_0);
@ -6252,6 +6255,12 @@ void wallet2::select_decoys(currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS
{
out_entry entry = extract_random_from_container(amount_entry.outs);
//
if (entry.global_amount_index == own_g_index)
{
continue;
}
//skip auditable
if ((entry.flags & (RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_NOT_ALLOWED)))
{
@ -6262,11 +6271,7 @@ void wallet2::select_decoys(currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS
coinbases.push_back(entry);
continue;
}
//
if (entry.global_amount_index == own_g_index)
{
continue;
}
local_outs.push_back(entry);
}

View file

@ -402,8 +402,7 @@ namespace tools
bool daemon_get_asset_info(const crypto::public_key& asset_id, currency::asset_descriptor_base& adb);
const std::unordered_map<crypto::public_key, wallet_own_asset_context>& get_own_assets() const { return m_own_asset_descriptors; }
bool set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy);
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_defragmentation_tx_settings(bool enabled, uint64_t min_outs, uint64_t max_outs, uint64_t max_allowed_amount = CURRENCY_BLOCK_REWARD, size_t decoys_count = SIZE_MAX);
void set_pos_required_decoys_count(size_t v) { m_required_decoys_count = v; }
void set_minimum_height(uint64_t h);
std::shared_ptr<i_core_proxy> get_core_proxy();

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_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
alice_wlt->set_defragmentation_tx_settings(true, 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

@ -3440,8 +3440,7 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde
// 1. Try to defragment the same UTXO that is used for staking
// (Bob has two: one UTXO is for staking, other is being defragmented)
bob_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(1, 10);
bob_wlt->set_pos_decoys_count_for_defragmentation_tx(0);
bob_wlt->set_defragmentation_tx_settings(true, 1, 10, CURRENCY_BLOCK_REWARD, 0);
bob_wlt->try_mint_pos();
CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 3, false, "Incorrect blockchain height:" << c.get_current_blockchain_size());
@ -3453,8 +3452,7 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde
// 2. Try to mine a PoS block and defragment some of UTXO
alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(2, 2);
alice_wlt->set_pos_decoys_count_for_defragmentation_tx(0);
alice_wlt->set_defragmentation_tx_settings(true, 2, 2, CURRENCY_BLOCK_REWARD, 0);
alice_wlt->try_mint_pos();
CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 4, false, "Incorrect blockchain height:" << c.get_current_blockchain_size());
@ -3467,8 +3465,7 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde
// 3. Try to mine a PoS block and defragment with huge decoy set. Make sure block is mined successfully without a defragmentation tx
// Alice has one UTXO
alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(1, 1);
alice_wlt->set_pos_decoys_count_for_defragmentation_tx(80);
alice_wlt->set_defragmentation_tx_settings(true, 1, 1, CURRENCY_BLOCK_REWARD, 80);
alice_wlt->try_mint_pos();
CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 5, false, "Incorrect blockchain height:" << c.get_current_blockchain_size());
@ -3480,8 +3477,7 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde
// 4. Finally mine a PoS and defragment the last one unlocked UTXO
alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(1, 1);
alice_wlt->set_pos_decoys_count_for_defragmentation_tx(0);
alice_wlt->set_defragmentation_tx_settings(true, 1, 1, CURRENCY_BLOCK_REWARD, 0);
alice_wlt->try_mint_pos();
CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 6, false, "Incorrect blockchain height:" << c.get_current_blockchain_size());