From d933a221540ca7d7a61903d8bad5c588684aba29 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 28 Mar 2024 13:29:00 +0100 Subject: [PATCH 1/9] wallet: set_pos_utxo_count_limits_for_defragmentation_tx() added, coretests: packing_outputs_on_pos_minting_wallet, pos_minting_tx_packing fixed --- src/wallet/wallet2.cpp | 14 ++++++-------- src/wallet/wallet2.h | 3 +-- tests/core_tests/pos_validation.cpp | 2 +- tests/core_tests/wallet_tests.cpp | 12 ++++-------- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 1264781e..b76b9717 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -174,15 +174,13 @@ bool wallet2::set_core_proxy(const std::shared_ptr& 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; } //---------------------------------------------------------------------------------------------------- std::shared_ptr wallet2::get_core_proxy() diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 05863a18..b0c55331 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -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& get_own_assets() const { return m_own_asset_descriptors; } bool set_core_proxy(const std::shared_ptr& 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 get_core_proxy(); diff --git a/tests/core_tests/pos_validation.cpp b/tests/core_tests/pos_validation.cpp index 0106b050..4f444e69 100644 --- a/tests/core_tests/pos_validation.cpp +++ b/tests/core_tests/pos_validation.cpp @@ -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(); diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index 0be2a9bd..bfadc1fb 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -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()); From 4d6aa1a4f9c555a2d2b6b0975af451d60a51f2ad Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 28 Mar 2024 13:32:26 +0100 Subject: [PATCH 2/9] wallet: minor fixes (logging) --- src/wallet/wallet2.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index b76b9717..5de4c730 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -428,7 +428,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 }); @@ -464,7 +464,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 }); @@ -495,7 +495,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); From 312d500a36c0ccfc3e53b435efb2b46f11872ac3 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 28 Mar 2024 19:22:20 +0100 Subject: [PATCH 3/9] fixed problem with decoy selection algo --- src/wallet/wallet2.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5de4c730..bac76141 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6250,6 +6250,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))) { @@ -6260,11 +6266,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); } From b0c92e28dd7f6b05b5b00f3563eb88f3db6caf5d Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 28 Mar 2024 21:19:57 +0100 Subject: [PATCH 4/9] added more logs for generate_unique_reversed_distribution --- src/wallet/decoy_selection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/decoy_selection.cpp b/src/wallet/decoy_selection.cpp index 7a3c8d01..e9d24446 100644 --- a/src/wallet/decoy_selection.cpp +++ b/src/wallet/decoy_selection.cpp @@ -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; From a45e42e0a54db72539557930209a29677252fdf5 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 29 Mar 2024 14:31:00 +0100 Subject: [PATCH 5/9] handle ethash epoch context allocation errors by triggering an immediate stop via the critical error handler --- src/currency_core/basic_pow_helpers.cpp | 6 +- src/currency_core/blockchain_storage.cpp | 7 +- src/currency_core/currency_core.cpp | 212 ++++++++++++++--------- 3 files changed, 137 insertions(+), 88 deletions(-) diff --git a/src/currency_core/basic_pow_helpers.cpp b/src/currency_core/basic_pow_helpers.cpp index ddb87912..b7ee80ca 100644 --- a/src/currency_core/basic_pow_helpers.cpp +++ b/src/currency_core/basic_pow_helpers.cpp @@ -66,7 +66,11 @@ namespace currency init_ethash_log_if_necessary(); int epoch = ethash_height_to_epoch(height); std::shared_ptr p_context = progpow::get_global_epoch_context_full(static_cast(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(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)); diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 0e6c923c..eb6d0fb3 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -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; diff --git a/src/currency_core/currency_core.cpp b/src/currency_core/currency_core.cpp index 7658f4da..1c15498b 100644 --- a/src/currency_core/currency_core.cpp +++ b/src/currency_core/currency_core.cpp @@ -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(); - 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(); + 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); + m_miner.pause(); + misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([this]() + { + 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; + //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); - 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); + uint64_t time_pack_txs_ms = 0, time_relay_ms = 0; - 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(); - 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 missed_txs; - std::list 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)) + if (p_verification_result->m_verification_failed || !p_verification_result->m_added_to_main_chain) { - 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; + 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(); + 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 missed_txs; + std::list 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)); + 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_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); - } + time_relay_ms = epee::misc_utils::get_tick_count(); + m_pprotocol->relay_block(arg, exclude_context); + TIME_MEASURE_FINISH_MS(time_relay_ms); + } - 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_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; + 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; + } } //----------------------------------------------------------------------------------------------- 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; - } + uint64_t h = m_blockchain_storage.get_top_block_height(); + if (m_stop_after_height != 0 && h >= m_stop_after_height) + { + 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) + bool r = m_blockchain_storage.add_new_block(b, bvc); + if (r && bvc.m_added_to_main_chain) { - 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) + uint64_t h = get_block_height(b); + if (h > 0) { - LOG_PRINT_GREEN("Hardfork " << hardfork_id_for_curr_block << " has been activated after the block at height " << h, LOG_LEVEL_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; + 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) From 01c60fa07ed135f69e2d4387dc6ba4c5ac2e4d82 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 29 Mar 2024 15:53:51 +0100 Subject: [PATCH 6/9] simplewallet: --pos-mining-defrag CLI option added --- src/currency_core/currency_format_utils.cpp | 1 + src/simplewallet/simplewallet.cpp | 68 ++++++++++++++------- src/wallet/wallet2.cpp | 10 ++- 3 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 8eb17e2d..32b43656 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -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_; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index ed51ef76..7bdb3ef7 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -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 arg_wallet_file ("wallet-file", "Use wallet ", ""); - const command_line::arg_descriptor arg_generate_new_wallet ("generate-new-wallet", "Generate new wallet and save it to or
.wallet by default", ""); - const command_line::arg_descriptor arg_generate_new_auditable_wallet ("generate-new-auditable-wallet", "Generate new auditable wallet and store it to ", ""); - const command_line::arg_descriptor arg_daemon_address ("daemon-address", "Use daemon instance at :", ""); - const command_line::arg_descriptor arg_daemon_host ("daemon-host", "Use daemon instance at host instead of localhost", ""); - const command_line::arg_descriptor arg_password ("password", "Wallet password"); - const command_line::arg_descriptor arg_dont_refresh ( "no-refresh", "Do not refresh after load"); - const command_line::arg_descriptor arg_dont_set_date ( "no-set-creation-date", "Do not set wallet creation date", false); - const command_line::arg_descriptor arg_daemon_port ("daemon-port", "Use daemon instance at port instead of default", 0); - //const command_line::arg_descriptor arg_log_level ("set-log", ""); - const command_line::arg_descriptor arg_do_pos_mining ( "do-pos-mining", "Do PoS mining", false); - const command_line::arg_descriptor 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 arg_restore_wallet ( "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to ", "" ); - const command_line::arg_descriptor arg_offline_mode ( "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)"); - const command_line::arg_descriptor arg_scan_for_wallet ( "scan-for-wallet", ""); - const command_line::arg_descriptor arg_addr_to_compare ( "addr-to-compare", ""); - const command_line::arg_descriptor arg_disable_tor_relay ( "disable-tor-relay", "Disable TOR relay", false); - const command_line::arg_descriptor arg_set_timeout("set-timeout", "Set timeout for the wallet"); - const command_line::arg_descriptor arg_voting_config_file("voting-config-file", "Set voting config instead of getting if from daemon", ""); - const command_line::arg_descriptor arg_no_password_confirmations("no-password-confirmation", "Enable/Disable password confirmation for transactions", false); + const command_line::arg_descriptor arg_wallet_file ("wallet-file", "Use wallet ", ""); + const command_line::arg_descriptor arg_generate_new_wallet ("generate-new-wallet", "Generate new wallet and save it to or
.wallet by default", ""); + const command_line::arg_descriptor arg_generate_new_auditable_wallet ("generate-new-auditable-wallet", "Generate new auditable wallet and store it to ", ""); + const command_line::arg_descriptor arg_daemon_address ("daemon-address", "Use daemon instance at :", ""); + const command_line::arg_descriptor arg_daemon_host ("daemon-host", "Use daemon instance at host instead of localhost", ""); + const command_line::arg_descriptor arg_password ("password", "Wallet password"); + const command_line::arg_descriptor arg_dont_refresh ( "no-refresh", "Do not refresh after load"); + const command_line::arg_descriptor arg_dont_set_date ( "no-set-creation-date", "Do not set wallet creation date", false); + const command_line::arg_descriptor arg_daemon_port ("daemon-port", "Use daemon instance at port instead of default", 0); + const command_line::arg_descriptor arg_do_pos_mining ( "do-pos-mining", "Do PoS mining", false); + const command_line::arg_descriptor 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 arg_pos_mining_defrag ( "pos-mining-defrag", " 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 arg_restore_wallet ( "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to ", "" ); + const command_line::arg_descriptor arg_offline_mode ( "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)"); + const command_line::arg_descriptor arg_scan_for_wallet ( "scan-for-wallet", ""); + const command_line::arg_descriptor arg_addr_to_compare ( "addr-to-compare", ""); + const command_line::arg_descriptor arg_disable_tor_relay ( "disable-tor-relay", "Disable TOR relay", false); + const command_line::arg_descriptor arg_set_timeout("set-timeout", "Set timeout for the wallet"); + const command_line::arg_descriptor arg_voting_config_file("voting-config-file", "Set voting config instead of getting if from daemon", ""); + const command_line::arg_descriptor arg_no_password_confirmations("no-password-confirmation", "Enable/Disable password confirmation for transactions", false); const command_line::arg_descriptor< std::vector > 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 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); + } + } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index bac76141..0cadb402 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -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 @@ -181,6 +177,8 @@ void wallet2::set_defragmentation_tx_settings(bool enabled, uint64_t min_outs, u 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; + 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"))); } //---------------------------------------------------------------------------------------------------- std::shared_ptr wallet2::get_core_proxy() From 950c80a108261afa976a50cdc61b6e53abf47905 Mon Sep 17 00:00:00 2001 From: zano build machine Date: Fri, 29 Mar 2024 17:54:22 +0300 Subject: [PATCH 7/9] === build number: 290 -> 291 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index fc6d8a54..1a64a14d 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -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 291 #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 "]" From 16be157addfb86a79f846633bb60f43014bf6e63 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 29 Mar 2024 16:31:12 +0100 Subject: [PATCH 8/9] simplewallet: fixed typo + logs --- src/simplewallet/simplewallet.cpp | 2 +- src/wallet/wallet2.cpp | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 7bdb3ef7..97418e35 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2867,7 +2867,7 @@ int main(int argc, char* argv[]) { std::vector 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); + 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]); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 0cadb402..fe7efa42 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -177,8 +177,15 @@ void wallet2::set_defragmentation_tx_settings(bool enabled, uint64_t min_outs, u 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; - 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"))); + 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 wallet2::get_core_proxy() From c375d6fa1050d03c941291a11b5cde354862dd5d Mon Sep 17 00:00:00 2001 From: zano build machine Date: Fri, 29 Mar 2024 18:31:42 +0300 Subject: [PATCH 9/9] === build number: 291 -> 292 === --- src/version.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h.in b/src/version.h.in index 1a64a14d..3a89fbcd 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,6 @@ #define PROJECT_REVISION "0" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 291 +#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 "]"