From c69ef90249c8d1724dd283b17955644c556a533f Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 14 Apr 2023 04:51:33 +0200 Subject: [PATCH] check_native_coins_amount_burnt_in_outs() instead of get_amount_for_zero_pubkeys() which is now deprecated, some coretests adapted and have been debugged --- src/currency_core/blockchain_storage.cpp | 25 ++++++-------- src/currency_core/currency_format_utils.cpp | 36 +++++++++++++++++++++ src/currency_core/currency_format_utils.h | 3 +- tests/core_tests/chaingen.cpp | 2 +- tests/core_tests/chaingen_helpers.h | 18 ++++++----- tests/core_tests/wallet_tests.cpp | 6 ++-- 6 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index f2598dd3..be5a1417 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3857,17 +3857,12 @@ i_core_event_handler* blockchain_storage::get_event_handler() const //------------------------------------------------------------------ uint64_t blockchain_storage::validate_alias_reward(const transaction& tx, const std::string& alias) const { - - //validate alias coast uint64_t fee_for_alias = get_alias_coast(alias); - - //validate the price had been paid - uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx); - - CHECK_AND_ASSERT_MES(found_alias_reward >= fee_for_alias, false, "registration of alias '" - << alias << "' goes with a reward of " << print_money(found_alias_reward) << " which is less than expected: " << print_money(fee_for_alias) - <<"(fee median: " << get_tx_fee_median() << ")" - << ", tx: " << get_transaction_hash(tx)); + uint64_t burnt_amount = 0; + CHECK_AND_ASSERT_MES(check_native_coins_amount_burnt_in_outs(tx, fee_for_alias, &burnt_amount), false, + "registration of alias '" << alias << "' failed due to incorrect reward; expected reward: " << print_money_brief(fee_for_alias) + << "; burnt amount: " << (tx.version <= TRANSACTION_VERSION_PRE_HF4 ? print_money_brief(burnt_amount) : std::string("hidden")) + << "; tx: " << get_transaction_hash(tx)); return true; } @@ -4332,12 +4327,12 @@ bool blockchain_storage::validate_all_aliases_for_new_median_mode() uint64_t fee_for_alias = get_alias_coast_from_fee(tei.m_alias.m_alias, median_fee); //validate the price had been paid - uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx_ptr->tx); - if (found_alias_reward < fee_for_alias) + uint64_t burnt_amount = 0; + if (!check_native_coins_amount_burnt_in_outs(tx_ptr->tx, fee_for_alias, &burnt_amount)) { - LOG_PRINT_RED_L0("[" << i << "]Found collision on alias: " << tei.m_alias.m_alias - << ", expected fee: " << print_money(fee_for_alias) << "(median:" << print_money(median_fee) << ")" - <<" found reward: " << print_money(found_alias_reward) <<". tx_id: " << tx_id); + LOG_PRINT_RED_L0("[" << i << "]Detected collision on alias: " << tei.m_alias.m_alias + << ", expected fee: " << print_money_brief(fee_for_alias) << " (median: " << print_money_brief(median_fee) << ")" + << " found reward: " << (tx_ptr->tx.version <= TRANSACTION_VERSION_PRE_HF4 ? print_money_brief(burnt_amount) : std::string("hidden")) << "; tx_id: " << tx_id); } } } diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 0a500bbb..b36eaeaa 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -3484,6 +3484,42 @@ namespace currency return true; } //--------------------------------------------------------------- + bool check_native_coins_amount_burnt_in_outs(const transaction& tx, const uint64_t amount, uint64_t* p_amount_burnt /* = nullptr */) + { + if (tx.version <= TRANSACTION_VERSION_PRE_HF4) + { + uint64_t sum_of_bare_outs_burnt = 0; + for (const auto& out : tx.vout) + { + VARIANT_SWITCH_BEGIN(out); + VARIANT_CASE_CONST(tx_out_bare, out) + if (out.target.type() != typeid(txout_to_key)) + continue; + const txout_to_key& o = boost::get(out.target); + if (o.key == null_pkey) + sum_of_bare_outs_burnt += out.amount; + VARIANT_SWITCH_END(); + } + if (p_amount_burnt) + *p_amount_burnt = sum_of_bare_outs_burnt; + return sum_of_bare_outs_burnt == amount; + } + + // post HF-4 txs + // assuming: zero out pubkey, explicit asset_id, zero amount blinding mask + crypto::point_t sum_of_amount_commitments = crypto::c_point_0; + for (const auto& out : tx.vout) + { + VARIANT_SWITCH_BEGIN(out); + VARIANT_CASE_CONST(tx_out_zarcanum, out_zc) + if (out_zc.stealth_address == null_pkey && out_zc.blinded_asset_id == native_coin_asset_id_1div8) + sum_of_amount_commitments += crypto::point_t(out_zc.amount_commitment).modify_mul8(); + VARIANT_SWITCH_END(); + } + return sum_of_amount_commitments == amount * native_coin_asset_id_pt; + } + //--------------------------------------------------------------- + // DEPRECATED, don't use -- sowle uint64_t get_amount_for_zero_pubkeys(const transaction& tx) { uint64_t found_alias_reward = 0; diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index f028340b..a025c43b 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -396,7 +396,8 @@ namespace currency bool is_service_tx(const transaction& tx); bool does_tx_have_only_mixin_inputs(const transaction& tx); bool is_showing_sender_addres(const transaction& tx); - uint64_t get_amount_for_zero_pubkeys(const transaction& tx); + bool check_native_coins_amount_burnt_in_outs(const transaction& tx, const uint64_t amount, uint64_t* p_amount_burnt = nullptr); + [[deprecated("Use check_native_coins_amount_burnt_in_outs instead")]] uint64_t get_amount_for_zero_pubkeys(const transaction& tx); //std::string get_comment_from_tx(const transaction& tx); std::string print_stake_kernel_info(const stake_kernel& sk); std::string dump_ring_sig_data(const crypto::hash& hash_for_sig, const crypto::key_image& k_image, const std::vector& output_keys_ptrs, const std::vector& sig); diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 6b80f9cd..5ff7a81c 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -1842,7 +1842,7 @@ bool check_balance_via_wallet(const tools::wallet2& w, const char* account_name, bool r = true; -#define _CHECK_BAL(v) if (!(expected_##v == INVALID_BALANCE_VAL || v == expected_##v)) { r = false; LOG_PRINT_RED_L0("invalid " #v " balance, expected: " << print_money(expected_##v)); } +#define _CHECK_BAL(v) if (!(expected_##v == INVALID_BALANCE_VAL || v == expected_##v)) { r = false; LOG_PRINT_RED_L0("invalid " #v " balance, expected: " << print_money_brief(expected_##v)); } _CHECK_BAL(unlocked) _CHECK_BAL(awaiting_in) _CHECK_BAL(awaiting_out) diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h index 83d5da23..8d43323c 100644 --- a/tests/core_tests/chaingen_helpers.h +++ b/tests/core_tests/chaingen_helpers.h @@ -288,14 +288,17 @@ inline bool put_alias_via_tx_to_list(const currency::hard_forks_descriptor& hf, currency::account_keys& ak = const_cast(reward_acc.get_keys()); currency::get_aliases_reward_account(ak.account_address, ak.view_secret_key); - uint64_t fee_median = generator.get_last_n_blocks_fee_median(get_block_hash(head_block)); - uint64_t reward = currency::get_alias_coast_from_fee(ae.m_alias, fee_median); + uint64_t alias_reward = 0; + if (get_block_height(head_block) < ALIAS_MEDIAN_RECALC_INTERWAL) + alias_reward = get_alias_coast_from_fee(ae.m_alias, ALIAS_VERY_INITAL_COAST); // don't ask why + else + LOCAL_ASSERT(false); // not implemented yet, see also all the mess around blockchain_storage::get_tx_fee_median(), get_tx_fee_median_effective_index() etc. MAKE_TX_MIX_LIST_EXTRA_MIX_ATTR(events, tx_set, miner_acc, reward_acc, - reward, + alias_reward, 0, head_block, CURRENCY_TO_KEY_OUT_RELAXED, @@ -303,12 +306,11 @@ inline bool put_alias_via_tx_to_list(const currency::hard_forks_descriptor& hf, std::vector()); - uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx_set.back()); - if (found_alias_reward != reward) + uint64_t burnt_amount = 0; + if (!check_native_coins_amount_burnt_in_outs(tx_set.back(), alias_reward, &burnt_amount)) { - LOCAL_ASSERT(false); - CHECK_AND_ASSERT_MES(false, false, "wrong transaction constructed, first input value not match alias amount or account"); - return false; + CHECK_AND_ASSERT_MES(false, false, "alias reward was not found, expected: " << print_money_brief(alias_reward) + << "; burnt: " << (tx_set.back().version <= TRANSACTION_VERSION_PRE_HF4 ? print_money_brief(burnt_amount) : "hidden") << "; tx: " << get_transaction_hash(tx_set.back())); } return true; diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index a1744253..8abd0ecf 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -1670,8 +1670,7 @@ bool gen_wallet_alias_and_unconfirmed_txs::c1(currency::core& c, size_t ev_index std::vector stub_events_vec; MAKE_TEST_WALLET_TX_EXTRA(stub_events_vec, tx, bob_wlt, alias_reward, null_account, std::vector({ ai })); - uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx); - CHECK_AND_ASSERT_MES(found_alias_reward == alias_reward, false, "Generated tx has invalid alias reward"); + CHECK_AND_ASSERT_MES(check_native_coins_amount_burnt_in_outs(tx, alias_reward), false, "Generated tx has invalid alias reward"); bool has_relates_alias_in_unconfirmed = false; bob_wlt->scan_tx_pool(has_relates_alias_in_unconfirmed); @@ -1707,8 +1706,7 @@ bool gen_wallet_alias_and_unconfirmed_txs::c2(currency::core& c, size_t ev_index std::vector stub_events_vec; MAKE_TEST_WALLET_TX_EXTRA(stub_events_vec, tx, bob_wlt, alias_reward, null_account, std::vector({ ai })); - uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx); - CHECK_AND_ASSERT_MES(found_alias_reward == alias_reward, false, "Generated tx has invalid alias reward"); + CHECK_AND_ASSERT_MES(check_native_coins_amount_burnt_in_outs(tx, alias_reward), false, "Generated tx has invalid alias reward"); bool has_relates_alias_in_unconfirmed = false; bob_wlt->scan_tx_pool(has_relates_alias_in_unconfirmed);