From 6b2831e52514e2f639dacc6e5041b4a8a733fb95 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 25 Nov 2022 23:01:45 +0100 Subject: [PATCH 01/10] wallet: sweep_below adapted for HF4 --- src/simplewallet/simplewallet.cpp | 4 +- src/wallet/wallet2.cpp | 100 ++++++++++++++++++++---------- src/wallet/wallet2.h | 2 +- src/wallet/wallet_rpc_server.cpp | 3 +- 4 files changed, 70 insertions(+), 39 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 7f4ab1b0..9537390a 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1822,9 +1822,7 @@ bool simple_wallet::sweep_below(const std::vector &args) uint64_t amount_total = 0, amount_swept = 0; currency::transaction result_tx = AUTO_VAL_INIT(result_tx); std::string filename = "zano_tx_unsigned"; - m_wallet->sweep_below(fake_outs_count, addr, amount, payment_id, fee, outs_total, amount_total, outs_swept, &result_tx, &filename); - if (!get_inputs_money_amount(result_tx, amount_swept)) - LOG_ERROR("get_inputs_money_amount failed, tx: " << obj_to_json_str(result_tx)); + m_wallet->sweep_below(fake_outs_count, addr, amount, payment_id, fee, outs_total, amount_total, outs_swept, amount_swept, &result_tx, &filename); success_msg_writer(false) << outs_swept << " outputs (" << print_money_brief(amount_swept) << " coins) of " << outs_total << " total (" << print_money_brief(amount_total) << ") below the specified limit of " << print_money_brief(amount) << " were successfully swept"; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 9764eab0..59a48fa1 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -499,7 +499,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t uint64_t max_out_unlock_time = 0; std::vector outs; - uint64_t tx_money_got_in_outs = 0; + uint64_t tx_money_got_in_outs = 0; // TODO: @#@# correctly calculate tx_money_got_in_outs for post-HF4 crypto::public_key tx_pub_key = null_pkey; bool r = parse_and_validate_tx_extra(tx, tx_pub_key); THROW_IF_TRUE_WALLET_EX(!r, error::tx_extra_parse_error, tx); @@ -4981,7 +4981,6 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vectorm_tx.vout[td.m_internal_output_index]); VARIANT_CASE_CONST(tx_out_bare, o) { @@ -5762,8 +5761,10 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money, detail::split_strategy_id_t destination_split_strategy_id, const tx_dust_policy& dust_policy, const std::vector& dsts, - std::vector& final_detinations, const crypto::hash& asset_id) + std::vector& final_destinations, const crypto::hash& asset_id) { + 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) { @@ -5771,25 +5772,44 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money, change_dts.amount = found_money - needed_money; change_dts.asset_id = asset_id; } - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(found_money >= needed_money, "needed_money==" << needed_money << " < found_money==" << found_money); - if (asset_id != currency::null_hash) + + if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM)) { - if (change_dts.amount) + // 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) { - final_detinations.push_back(change_dts); + 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); } - return; } - - uint64_t dust = 0; - bool r = detail::apply_split_strategy_by_id(destination_split_strategy_id, dsts, change_dts, dust_policy.dust_threshold, final_detinations, dust, WALLET_MAX_ALLOWED_OUTPUT_AMOUNT); - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "invalid split strategy id: " << destination_split_strategy_id); - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(dust_policy.dust_threshold >= dust, "invalid dust value: dust = " << dust << ", dust_threshold = " << dust_policy.dust_threshold); - - if (0 != dust && !dust_policy.add_to_fee) + else { - final_detinations.push_back(currency::tx_destination_entry(dust, dust_policy.addr_for_dust)); - final_detinations.back().asset_id = asset_id; + // pre-HF4 + if (asset_id != currency::null_hash) + { + if (change_dts.amount) + { + final_destinations.push_back(change_dts); + } + return; + } + 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); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "invalid split strategy id: " << destination_split_strategy_id); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(dust_policy.dust_threshold >= dust, "invalid dust value: dust = " << dust << ", dust_threshold = " << dust_policy.dust_threshold); + + if (0 != dust && !dust_policy.add_to_fee) + { + final_destinations.emplace_back(dust, dust_policy.addr_for_dust, asset_id); + } } } //---------------------------------------------------------------------------------------------------- @@ -6114,7 +6134,7 @@ void wallet2::transfer(construct_tx_param& ctp, } //---------------------------------------------------------------------------------------------------- void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public_address& destination_addr, uint64_t threshold_amount, const currency::payment_id_t& payment_id, - uint64_t fee, size_t& outs_total, uint64_t& amount_total, size_t& outs_swept, currency::transaction* p_result_tx /* = nullptr */, std::string* p_filename_or_unsigned_tx_blob_str /* = nullptr */) + uint64_t fee, size_t& outs_total, uint64_t& amount_total, size_t& outs_swept, uint64_t& amount_swept, currency::transaction* p_result_tx /* = nullptr */, std::string* p_filename_or_unsigned_tx_blob_str /* = nullptr */) { static const size_t estimated_bytes_per_input = 78; const size_t estimated_max_inputs = static_cast(CURRENCY_MAX_TRANSACTION_BLOB_SIZE / (estimated_bytes_per_input * (fake_outs_count + 1.5))); // estimated number of maximum tx inputs under the tx size limit @@ -6124,6 +6144,7 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public outs_total = 0; amount_total = 0; outs_swept = 0; + amount_swept = 0; std::vector selected_transfers; selected_transfers.reserve(m_transfers.size()); @@ -6158,10 +6179,11 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public if (fake_outs_count > 0) { COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req = AUTO_VAL_INIT(req); + req.height_upper_limit = m_last_pow_block_h; req.use_forced_mix_outs = false; req.decoys_count = fake_outs_count + 1; for (uint64_t i : selected_transfers) - req.amounts.push_back(m_transfers[i].amount()); + req.amounts.push_back(m_transfers[i].is_zc() ? 0 : m_transfers[i].m_amount); r = m_core_proxy->call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS(req, rpc_get_random_outs_resp); @@ -6228,16 +6250,14 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public { if (td.m_global_output_index == daemon_oe.global_amount_index) continue; - tx_output_entry oe = AUTO_VAL_INIT(oe); - oe.out_reference = daemon_oe.global_amount_index; - oe.stealth_address = daemon_oe.stealth_address; - src.outputs.push_back(oe); + src.outputs.emplace_back(daemon_oe.global_amount_index, daemon_oe.stealth_address, daemon_oe.concealing_point, daemon_oe.amount_commitment); if (src.outputs.size() >= fake_outs_count) break; } } // insert real output into src.outputs + // TODO: bad design, we need to get rid of code duplicates below -- sowle auto it_to_insert = std::find_if(src.outputs.begin(), src.outputs.end(), [&](const tx_output_entry& a) { if (a.out_reference.type().hash_code() == typeid(uint64_t).hash_code()) @@ -6245,17 +6265,32 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public return false; // TODO: implement deterministics real output placement in case there're ref_by_id outs }); tx_output_entry real_oe = AUTO_VAL_INIT(real_oe); - real_oe.out_reference = td.m_global_output_index; - //@#@ - if(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type() != typeid(tx_out_bare)) - continue; - const tx_out_bare& out_b = boost::get(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]); - real_oe.stealth_address = boost::get(out_b.target).key; - auto inserted_it = src.outputs.insert(it_to_insert, real_oe); + txout_ref_v out_reference = td.m_global_output_index; // TODO: use ref_by_id when neccessary + std::vector::iterator interted_it = src.outputs.end(); + VARIANT_SWITCH_BEGIN(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]); + VARIANT_CASE_CONST(tx_out_bare, o) + { + VARIANT_SWITCH_BEGIN(o.target); + VARIANT_CASE_CONST(txout_to_key, o) + interted_it = src.outputs.emplace(it_to_insert, out_reference, o.key); + VARIANT_CASE_CONST(txout_htlc, htlc) + interted_it = src.outputs.emplace(it_to_insert, out_reference, htlc.pkey_refund); + VARIANT_CASE_OTHER() + { + WLT_THROW_IF_FALSE_WITH_CODE(false, + "Internal error: unexpected type of target: " << o.target.type().name(), + API_RETURN_CODE_INTERNAL_ERROR); + } + VARIANT_SWITCH_END(); + } + VARIANT_CASE_CONST(tx_out_zarcanum, o); + interted_it = src.outputs.emplace(it_to_insert, out_reference, o.stealth_address, o.concealing_point, o.amount_commitment); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_opt_blinding_mask, "m_opt_blinding_mask is null, transfer index: " << tr_index << ", amount: " << print_money_brief(td.amount())); + src.real_out_amount_blinding_mask = *td.m_opt_blinding_mask; + VARIANT_SWITCH_END(); src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_ptx_wallet_info->m_tx); - src.real_output = inserted_it - src.outputs.begin(); + src.real_output = interted_it - src.outputs.begin(); src.real_output_in_tx_index = td.m_internal_output_index; - //detail::print_source_entry(src); } if (amount_swept <= fee) @@ -6284,7 +6319,6 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public }; size_t st_index_upper_boundary = std::min(selected_transfers.size(), estimated_max_inputs); - uint64_t amount_swept = 0; try_construct_result_t res = try_construct_tx(st_index_upper_boundary, ftp, amount_swept); WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(res != rc_too_few_outputs, st_index_upper_boundary << " biggest unspent outputs have total amount of " << print_money_brief(amount_swept) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index b3e3ca38..737e8beb 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -714,7 +714,7 @@ namespace tools void submit_transfer_files(const std::string& signed_tx_file, currency::transaction& tx); void sweep_below(size_t fake_outs_count, const currency::account_public_address& destination_addr, uint64_t threshold_amount, const currency::payment_id_t& payment_id, - uint64_t fee, size_t& outs_total, uint64_t& amount_total, size_t& outs_swept, currency::transaction* p_result_tx = nullptr, std::string* p_filename_or_unsigned_tx_blob_str = nullptr); + uint64_t fee, size_t& outs_total, uint64_t& amount_total, size_t& outs_swept, uint64_t& amount_swept, currency::transaction* p_result_tx = nullptr, std::string* p_filename_or_unsigned_tx_blob_str = nullptr); bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id); inline uint64_t get_blockchain_current_size() const { diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index e2c953a5..fb804956 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -620,9 +620,8 @@ namespace tools uint64_t amount_total = 0, amount_swept = 0; std::string unsigned_tx_blob_str; - m_wallet.sweep_below(req.mixin, addr, req.amount, payment_id, req.fee, outs_total, amount_total, outs_swept, &tx, &unsigned_tx_blob_str); + m_wallet.sweep_below(req.mixin, addr, req.amount, payment_id, req.fee, outs_total, amount_total, outs_swept, amount_swept, &tx, &unsigned_tx_blob_str); - get_inputs_money_amount(tx, amount_swept); res.amount_swept = amount_swept; res.amount_total = amount_total; res.outs_swept = outs_swept; From e1acf907db8481cf43d625b3c8cb4917d2896b5d Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 28 Nov 2022 21:15:49 +0100 Subject: [PATCH 02/10] wallet2::is_transfer_able_to_go() adapted for HF4 --- src/wallet/wallet2.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 59a48fa1..a3b5884f 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5468,23 +5468,25 @@ bool wallet2::is_transfer_able_to_go(const transfer_details& td, uint64_t fake_o { if (!td.is_spendable()) return false; - VARIANT_SWITCH_BEGIN(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]); - VARIANT_CASE_CONST(tx_out_bare, o); + + const tx_out_v &out_v = td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]; + + uint8_t mix_attr = CURRENCY_TO_KEY_OUT_RELAXED; + if (get_mix_attr_from_tx_out_v(out_v, mix_attr)) { + if (!currency::is_mixattr_applicable_for_fake_outs_counter(mix_attr, fake_outputs_count)) + return false; + } + + VARIANT_SWITCH_BEGIN(out_v); + VARIANT_CASE_CONST(tx_out_bare, o); if (o.target.type() == typeid(txout_htlc)) { if (fake_outputs_count != 0) return false; } - else - { - if (!currency::is_mixattr_applicable_for_fake_outs_counter(boost::get(o.target).mix_attr, fake_outputs_count)) - return false; - } - } - VARIANT_CASE_CONST(tx_out_zarcanum, o); - //@#@ VARIANT_SWITCH_END(); + return true; } //---------------------------------------------------------------------------------------------------- From 2b98842f8dcd61b9f052451fc782773d47ce6aa7 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 28 Nov 2022 21:17:59 +0100 Subject: [PATCH 03/10] stratum: handle_method_eth_submitHashrate now supports parameter of any length (should be helpful for odd miners) --- src/stratum/stratum_server.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/stratum/stratum_server.cpp b/src/stratum/stratum_server.cpp index 8ec41088..f100efef 100644 --- a/src/stratum/stratum_server.cpp +++ b/src/stratum/stratum_server.cpp @@ -951,14 +951,14 @@ namespace bool r = params_array != nullptr && ps.get_next_value(params_array, rate_submit_id_str); CHECK_AND_ASSERT_MES(r, false, "Incorrect parameters"); - struct { uint64_t low, high; } rate_128 = { 0 }; - CHECK_AND_ASSERT_MES(pod_from_net_format_reverse(rate_str, rate_128, true), false, "Can't parse rate from " << rate_str); - CHECK_AND_ASSERT_MES(rate_128.high == 0, false, "rate overflow, rate str: " << rate_str); + struct { uint64_t low, high, higher, highest; } rate_256 = { 0 }; // this will allow any length of data from 64 to 256 bits (helpful for odd miners) + CHECK_AND_ASSERT_MES(pod_from_net_format_reverse(rate_str, rate_256, true), false, "Can't parse rate from " << rate_str); + CHECK_AND_ASSERT_MES(rate_256.high == 0 && rate_256.higher == 0 && rate_256.highest == 0, false, "rate overflow, rate str: " << rate_str); crypto::hash rate_submit_id = null_hash; CHECK_AND_ASSERT_MES(pod_from_net_format(rate_submit_id_str, rate_submit_id), false, "Can't parse rate_submit_id from " << rate_submit_id_str); - m_last_reported_hashrate = rate_128.low; - return m_config.handle_submit_hashrate(this, rate_128.low, rate_submit_id); + m_last_reported_hashrate = rate_256.low; + return m_config.handle_submit_hashrate(this, rate_256.low, rate_submit_id); } bool handle_method_eth_submitWork(const jsonrpc_id_t& id, epee::serialization::portable_storage& ps, epee::serialization::portable_storage::hsection params_section) From 139f2a5ae44334a5fa959f5707523025f79e502d Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 30 Nov 2022 19:58:20 +0100 Subject: [PATCH 04/10] wallet: minor log improvement --- src/currency_core/pos_mining.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/currency_core/pos_mining.cpp b/src/currency_core/pos_mining.cpp index 8ecc7af4..e0096ea3 100644 --- a/src/currency_core/pos_mining.cpp +++ b/src/currency_core/pos_mining.cpp @@ -72,8 +72,8 @@ namespace currency << "kernel info: " << ENDL << print_stake_kernel_info(this->sk) << "kernel_hash: " << this->kernel_hash << ENDL - << "lhs: " << lhs << ENDL - << "rhs: " << rhs + << "lhs: " << crypto::scalar_t(lhs) << ENDL + << "rhs: " << crypto::scalar_t(rhs) , LOG_LEVEL_0); } From dac549f0b610525f50b7395d9002708b0824f70a Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 2 Dec 2022 18:14:19 +0100 Subject: [PATCH 05/10] minor improvements and compilation fixes --- src/connectivity_tool/conn_tool.cpp | 2 +- src/currency_core/pos_mining.cpp | 9 +++++++-- tests/functional_tests/difficulty_analysis.cpp | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/connectivity_tool/conn_tool.cpp b/src/connectivity_tool/conn_tool.cpp index f4daeacc..b4364d04 100644 --- a/src/connectivity_tool/conn_tool.cpp +++ b/src/connectivity_tool/conn_tool.cpp @@ -408,7 +408,7 @@ bool generate_genesis(const std::string& path_config, uint64_t premine_split_amo ss.str(""); ss.clear(); std::cout << ENDL << "PROOF PHRASE: " << gcp.proof_string << ENDL; - construct_miner_tx(0, 0, 0, 0, 0, destinations, bl.miner_tx, TRANSACTION_VERSION_PRE_HF4, gcp.proof_string, CURRENCY_MINER_TX_MAX_OUTS); + // construct_miner_tx(0, 0, 0, 0, 0, destinations, bl.miner_tx, TRANSACTION_VERSION_PRE_HF4, gcp.proof_string, CURRENCY_MINER_TX_MAX_OUTS); <-- temporarily commented out; this overload needs to be re-implemented -- sowle currency::blobdata txb = tx_to_blob(bl.miner_tx); //self validate block diff --git a/src/currency_core/pos_mining.cpp b/src/currency_core/pos_mining.cpp index e0096ea3..a2b6237b 100644 --- a/src/currency_core/pos_mining.cpp +++ b/src/currency_core/pos_mining.cpp @@ -67,13 +67,18 @@ namespace currency if (found) { found = true; + const boost::multiprecision::uint256_t d_mp = lhs / (crypto::c_zarcanum_z_coeff_mp * this->stake_amount) + 1; + const boost::multiprecision::uint256_t ba = d_mp * crypto::c_zarcanum_z_coeff_mp * this->stake_amount - lhs; + const boost::multiprecision::uint256_t l_div_z_D = this->z_l_div_z_D / crypto::c_zarcanum_z_coeff_mp; LOG_PRINT_GREEN("Found Zarcanum kernel: amount: " << currency::print_money_brief(this->stake_amount) << /* ", gindex: " << td.m_global_output_index << */ ENDL << "difficulty: " << this->basic_diff << ENDL << "kernel info: " << ENDL << print_stake_kernel_info(this->sk) << "kernel_hash: " << this->kernel_hash << ENDL - << "lhs: " << crypto::scalar_t(lhs) << ENDL - << "rhs: " << crypto::scalar_t(rhs) + << "lhs: 0x" << crypto::scalar_t(lhs).to_string_as_hex_number() << " = 0x" << std::hex << d_mp << " * 2^64 * " << this->stake_amount << " - 0x" << std::hex << ba << ENDL + << "rhs: 0x" << crypto::scalar_t(rhs).to_string_as_hex_number() << ENDL + << "d: 0x" << std::hex << d_mp << ENDL + << "l / floor(z * D): 0x" << std::hex << l_div_z_D , LOG_LEVEL_0); } diff --git a/tests/functional_tests/difficulty_analysis.cpp b/tests/functional_tests/difficulty_analysis.cpp index 0af4d4d8..3df52f21 100644 --- a/tests/functional_tests/difficulty_analysis.cpp +++ b/tests/functional_tests/difficulty_analysis.cpp @@ -306,7 +306,7 @@ void run_emulation(const std::string& path) perform_simulation_for_function(timestamp_to_hashrate, current_index, blocks, result_blocks, \ [&](std::vector& timestamps, std::vector& cumulative_difficulties, size_t target_seconds) \ { \ - return func_name(timestamps, cumulative_difficulties, target_seconds); \ + return func_name(timestamps, cumulative_difficulties, target_seconds, DIFFICULTY_POW_STARTER); \ }); \ current_index+=2; From 528a46f4ed05ebe62af5eacfcd32e9e529a81ced Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 3 Dec 2022 21:12:31 +0100 Subject: [PATCH 06/10] wallet2::prepare_tx_destinations() fixed to correctly support assets + minor logging improvements --- src/currency_core/currency_format_utils.cpp | 2 +- src/wallet/wallet2.cpp | 63 ++++++++++----------- src/wallet/wallet_errors.h | 17 +++++- 3 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 9adeb482..dc37bb07 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -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; } } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index bb7cd199..898d4921 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -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); } } } diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index e45eafb6..635f4617 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -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(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; } From 2de573e2c342c3335228c123b8c02aa027d0a95d Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 3 Dec 2022 21:31:41 +0100 Subject: [PATCH 07/10] gcc warning fix --- src/wallet/wallet_errors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index 635f4617..973c5e95 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -440,7 +440,7 @@ namespace tools const currency::tx_source_entry& src = m_sources[i]; ss << "\n " << i << ": "; ss << " amount: " << std::setw(21) << currency::print_money(src.amount); - ss << src.is_zarcanum() ? " ZC " : " old "; + ss << (src.is_zarcanum() ? " ZC " : " old "); ss << " asset_id: " << src.asset_id; for (size_t j = 0; j < src.outputs.size(); ++j) { From a8be7c327d7a2cc3be3b9adc4375d452e3f27a21 Mon Sep 17 00:00:00 2001 From: sowle Date: Sun, 4 Dec 2022 15:20:09 +0100 Subject: [PATCH 08/10] fix for a typo --- src/wallet/wallet2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 898d4921..538db3c4 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5816,7 +5816,7 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money, else { // pre-HF4 - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(asset_id != currency::null_hash, "assets are not allowed prior to HF4"); + 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) { From aca0388c3e372c58c4daf8bcddebedd53f327118 Mon Sep 17 00:00:00 2001 From: sowle Date: Sun, 4 Dec 2022 15:25:19 +0100 Subject: [PATCH 09/10] don't use deprecated boost/bind.hpp and placeholders in global namespace --- contrib/epee/include/net/http_server_impl_base.h | 2 +- src/common/ntp.cpp | 4 ++-- src/p2p/net_node.h | 2 +- src/rpc/core_rpc_server.cpp | 2 +- src/simplewallet/simplewallet.cpp | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contrib/epee/include/net/http_server_impl_base.h b/contrib/epee/include/net/http_server_impl_base.h index c02475c3..417deab4 100644 --- a/contrib/epee/include/net/http_server_impl_base.h +++ b/contrib/epee/include/net/http_server_impl_base.h @@ -31,7 +31,7 @@ #include -#include +#include #include "net/http_server_cp2.h" #include "net/http_server_handlers_map2.h" diff --git a/src/common/ntp.cpp b/src/common/ntp.cpp index db55610a..0b50e9be 100644 --- a/src/common/ntp.cpp +++ b/src/common/ntp.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Zano Project +// Copyright (c) 2019-2022 Zano Project // Note: class udp_blocking_client is a slightly modified version of an example // taken from https://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/timeouts/blocking_udp_client.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 5c0fb12e..9ec3cc17 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -6,7 +6,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 19a73be6..249cda11 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1242,4 +1242,4 @@ namespace currency #undef LOG_DEFAULT_CHANNEL -#define LOG_DEFAULT_CHANNEL NULL \ No newline at end of file +#define LOG_DEFAULT_CHANNEL NULL diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 858a4e0c..b4886ee6 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -223,9 +223,9 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this,ph::_1), "sign_transfer - sign unsigned tx from a watch-only wallet"); m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this,ph::_1), "submit_transfer - broadcast signed tx"); m_cmd_binder.set_handler("export_history", boost::bind(&simple_wallet::submit_transfer, this,ph::_1), "Export transaction history in CSV file"); - m_cmd_binder.set_handler("tor_enable", boost::bind(&simple_wallet::tor_enable, this, _1), "Enable relaying transactions over TOR network(enabled by default)"); - m_cmd_binder.set_handler("tor_disable", boost::bind(&simple_wallet::tor_disable, this, _1), "Enable relaying transactions over TOR network(enabled by default)"); - m_cmd_binder.set_handler("deploy_new_asset", boost::bind(&simple_wallet::deploy_new_asset, this, _1), "Deploys new asset in the network, with current wallet as a maintainer"); + m_cmd_binder.set_handler("tor_enable", boost::bind(&simple_wallet::tor_enable, this, ph::_1), "Enable relaying transactions over TOR network(enabled by default)"); + m_cmd_binder.set_handler("tor_disable", boost::bind(&simple_wallet::tor_disable, this, ph::_1), "Enable relaying transactions over TOR network(enabled by default)"); + m_cmd_binder.set_handler("deploy_new_asset", boost::bind(&simple_wallet::deploy_new_asset, this, ph::_1), "Deploys new asset in the network, with current wallet as a maintainer"); } //---------------------------------------------------------------------------------------------------- From 4c7d6e9724f59a2a77fcabd0274019640c3d7114 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 5 Dec 2022 14:42:23 +0100 Subject: [PATCH 10/10] tor-connect module updated --- contrib/tor-connect | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/tor-connect b/contrib/tor-connect index 13f47143..486a46e9 160000 --- a/contrib/tor-connect +++ b/contrib/tor-connect @@ -1 +1 @@ -Subproject commit 13f47143c0dcb8c12cfa293efc9d6d57ad3d1e37 +Subproject commit 486a46e927449a5827cf3cb69731bc0e3811b46a