From 7bfa59fd7e84b05c418cbae9ed32584e984b4f75 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Fri, 25 Aug 2023 22:40:20 +0200 Subject: [PATCH] full test for assets operations ready and passes --- contrib/epee/include/misc_language.h | 12 +++ src/currency_core/blockchain_storage.cpp | 8 ++ src/currency_core/currency_format_utils.cpp | 16 ++++ src/currency_core/currency_format_utils.h | 2 + src/wallet/wallet2.cpp | 18 +++- src/wallet/wallet_debug_events_definitions.h | 6 ++ tests/core_tests/multiassets_test.cpp | 89 +++++++++++++++++++- 7 files changed, 146 insertions(+), 5 deletions(-) diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/misc_language.h index 7d370a72..0044788a 100644 --- a/contrib/epee/include/misc_language.h +++ b/contrib/epee/include/misc_language.h @@ -484,6 +484,18 @@ namespace misc_utils m_callbacks[ti] = cb_entry; } + template + void UNSUBSCRIBE_DEBUG_EVENT() + { + std::type_index ti = typeid(param_t); + auto it = m_callbacks.find(ti); + if (it != m_callbacks.end()) + { + m_callbacks.erase(it); + } + } + + template void RAISE_DEBUG_EVENT(param_t& p) { diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index a442aca2..9759d519 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3873,17 +3873,25 @@ bool blockchain_storage::put_asset_info(const transaction& tx, const crypto::has { //check that total current_supply haven't changed CHECK_AND_ASSERT_MES(ado.descriptor.current_supply == avc.asset_op_history->back().descriptor.current_supply, false, "update operation actually try to change emission, failed"); + CHECK_AND_ASSERT_MES(validate_ado_update_allowed(ado.descriptor, avc.asset_op_history->back().descriptor), false, "update operation trying to change fields that not supposed to be changed, failed"); + need_to_validate_balance_proof = false; } else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT) { CHECK_AND_ASSERT_MES(ado.descriptor.current_supply > avc.asset_op_history->back().descriptor.current_supply, false, "emmit operation not increasing emission, failed"); + CHECK_AND_ASSERT_MES(validate_ado_update_allowed(ado.descriptor, avc.asset_op_history->back().descriptor), false, "emmit operation not allow to update fields"); + CHECK_AND_ASSERT_MES(ado.descriptor.meta_info == avc.asset_op_history->back().descriptor.meta_info, false, "emmit operation not not allow to update meta info"); avc.amout_to_validate = ado.descriptor.current_supply - avc.asset_op_history->back().descriptor.current_supply; } else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN) { CHECK_AND_ASSERT_MES(ado.descriptor.current_supply < avc.asset_op_history->back().descriptor.current_supply, false, "burn operation not decreasing emission, failed"); + CHECK_AND_ASSERT_MES(validate_ado_update_allowed(ado.descriptor, avc.asset_op_history->back().descriptor), false, "burn operation not allow to update fields"); + CHECK_AND_ASSERT_MES(ado.descriptor.meta_info == avc.asset_op_history->back().descriptor.meta_info, false, "burn operation not not allow to update meta info"); + avc.amout_to_validate = avc.asset_op_history->back().descriptor.current_supply - ado.descriptor.current_supply; + } else { diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 9c96d119..331ac86d 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1116,6 +1116,20 @@ namespace currency return origin_blob; } //--------------------------------------------------------------- + bool validate_ado_update_allowed(const asset_descriptor_base& a, const asset_descriptor_base& b) + { + if (a.total_max_supply != b.total_max_supply) return false; + //if (a.current_supply != b.current_supply) return false; + if (a.decimal_point != b.decimal_point) return false; + if (a.ticker != b.ticker) return false; + if (a.full_name != b.full_name) return false; + //a.meta_info; + if (a.owner != b.owner) return false; + if (a.hidden_supply != b.hidden_supply) return false; + + return true; + } + //--------------------------------------------------------------- crypto::hash get_signature_hash_for_asset_operation(const asset_descriptor_operation& ado) { asset_descriptor_operation ado_local = ado; @@ -2190,6 +2204,8 @@ namespace currency ado.opt_amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key(); } + if (ftp.pevents_dispatcher) ftp.pevents_dispatcher->RAISE_DEBUG_EVENT(wde_construct_tx_handle_asset_descriptor_operation_before_seal{ &ado }); + //seal it with owners signature crypto::signature sig = currency::null_sig; crypto::public_key pub_k = currency::null_pkey; diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index f21819aa..cfae779f 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -446,6 +446,8 @@ namespace currency std::string get_word_from_timstamp(uint64_t timestamp, bool use_password); uint64_t get_timstamp_from_word(std::string word, bool& password_used); std::string generate_origin_for_htlc(const txout_htlc& htlc, const account_keys& acc_keys); + bool validate_ado_update_allowed(const asset_descriptor_base& a, const asset_descriptor_base& b); + void normalize_asset_operation_for_hashing(asset_descriptor_operation& op); crypto::hash get_signature_hash_for_asset_operation(const asset_descriptor_operation& ado); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index d1b50fcc..71ecc3e6 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4723,9 +4723,14 @@ void wallet2::emmit_asset(const crypto::public_key asset_id, std::vectorcall_COMMAND_RPC_GET_ASSET_INFO(req, rsp); + CHECK_AND_ASSERT_THROW_MES(r, "Failed to call_COMMAND_RPC_GET_ASSET_INFO"); + asset_descriptor_operation asset_emmit_info = AUTO_VAL_INIT(asset_emmit_info); - asset_emmit_info.descriptor = own_asset_entry_it->second.asset_descriptor; + asset_emmit_info.descriptor = rsp.asset_descriptor; asset_emmit_info.operation_type = ASSET_DESCRIPTOR_OPERATION_EMMIT; asset_emmit_info.opt_asset_id = asset_id; construct_tx_param ctp = get_default_construct_tx_param(); @@ -4762,9 +4767,16 @@ void wallet2::burn_asset(const crypto::public_key asset_id, uint64_t amount_to_b { auto own_asset_entry_it = m_own_asset_descriptors.find(asset_id); CHECK_AND_ASSERT_THROW_MES(own_asset_entry_it != m_own_asset_descriptors.end(), "Failed find asset_id " << asset_id << " in own assets list"); + COMMAND_RPC_GET_ASSET_INFO::request req; + req.asset_id = asset_id; + COMMAND_RPC_GET_ASSET_INFO::response rsp; + bool r = m_core_proxy->call_COMMAND_RPC_GET_ASSET_INFO(req, rsp); + CHECK_AND_ASSERT_THROW_MES(r, "Failed to call_COMMAND_RPC_GET_ASSET_INFO"); + + asset_descriptor_operation asset_burn_info = AUTO_VAL_INIT(asset_burn_info); - asset_burn_info.descriptor = own_asset_entry_it->second.asset_descriptor; + asset_burn_info.descriptor = rsp.asset_descriptor; CHECK_AND_ASSERT_THROW_MES(asset_burn_info.descriptor.current_supply > amount_to_burn, "Wrong amount to burn (current_supply" << asset_burn_info.descriptor.current_supply << " is less then " << amount_to_burn << ")"); diff --git a/src/wallet/wallet_debug_events_definitions.h b/src/wallet/wallet_debug_events_definitions.h index 68c6fc4b..c9845a9b 100644 --- a/src/wallet/wallet_debug_events_definitions.h +++ b/src/wallet/wallet_debug_events_definitions.h @@ -13,3 +13,9 @@ struct wde_construct_tx_handle_asset_descriptor_operation }; +//Wallet Debug Events +struct wde_construct_tx_handle_asset_descriptor_operation_before_seal +{ + currency::asset_descriptor_operation* pado; +}; + diff --git a/tests/core_tests/multiassets_test.cpp b/tests/core_tests/multiassets_test.cpp index 733f6d62..ed11c80e 100644 --- a/tests/core_tests/multiassets_test.cpp +++ b/tests/core_tests/multiassets_test.cpp @@ -252,6 +252,8 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); CHECK_AND_ASSERT_MES(asset_info4.current_supply == asset_info3.current_supply - last_miner_balance, false, "Failed to find needed asset in result balances"); + + //------------------- tests that trying to break stuff ------------------- //tests that trying to break stuff miner_wlt->get_debug_events_dispatcher().SUBSCIRBE_DEBUG_EVENT([&](wde_construct_tx_handle_asset_descriptor_operation& o) { @@ -259,12 +261,95 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v o.pado->opt_proof = s; }); - //test update function + + //test update function with broken ownership + r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info); + CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); + asset_info.meta_info = "{\"some2\": \"info2\"}"; miner_wlt->update_asset(asset_id, asset_info, tx); r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 2); + CHECK_AND_ASSERT_MES(!r, false, "Test failed, broken ownership passed"); + c.get_tx_pool().purge_transactions(); + miner_wlt->refresh(); - + miner_wlt->get_debug_events_dispatcher().UNSUBSCRIBE_DEBUG_EVENT(); + + //------------------- tests that trying to break stuff ------------------- + //test update function with not allowed fields + r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info); + CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); + + asset_info.ticker = "XXX"; + miner_wlt->update_asset(asset_id, asset_info, tx); + r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 2); + CHECK_AND_ASSERT_MES(!r, false, "Test failed, broken ownership passed"); + c.get_tx_pool().purge_transactions(); + + //------------------- tests that trying to break stuff ------------------- + //test update function with not allowed fields + r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info); + CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); + + asset_info.full_name = "XXX"; + miner_wlt->update_asset(asset_id, asset_info, tx); + r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 2); + CHECK_AND_ASSERT_MES(!r, false, "Test failed, broken ownership passed"); + c.get_tx_pool().purge_transactions(); + miner_wlt->refresh(); + + //------------------- tests that trying to break stuff ------------------- + r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info); + CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); + + asset_info.decimal_point = 3; + miner_wlt->update_asset(asset_id, asset_info, tx); + r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 2); + CHECK_AND_ASSERT_MES(!r, false, "Test failed, broken ownership passed"); + c.get_tx_pool().purge_transactions(); + miner_wlt->refresh(); + + //------------------- tests that trying to break stuff ------------------- + r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info); + CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); + + currency::keypair kp = currency::keypair::generate(); + + asset_info.owner = kp.pub; + miner_wlt->update_asset(asset_id, asset_info, tx); + r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 2); + CHECK_AND_ASSERT_MES(!r, false, "Test failed, broken ownership passed"); + c.get_tx_pool().purge_transactions(); + miner_wlt->refresh(); + + //------------------- tests that trying to break stuff ------------------- + miner_wlt->get_debug_events_dispatcher().SUBSCIRBE_DEBUG_EVENT([&](wde_construct_tx_handle_asset_descriptor_operation_before_seal& o) + { + o.pado->descriptor.current_supply += 1000000; + }); + //test emmit function but re-adjust current_supply to wrong amount + miner_wlt->emmit_asset(asset_id, destinations, tx); + r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + CHECK_AND_ASSERT_MES(!r, false, "mine_next_pow_blocks_in_playtime failed"); + c.get_tx_pool().purge_transactions(); + miner_wlt->refresh(); + + //------------------- tests that trying to break stuff ------------------- + //test burn that burn more then tx has + miner_wlt->get_debug_events_dispatcher().UNSUBSCRIBE_DEBUG_EVENT(); + + miner_wlt->get_debug_events_dispatcher().SUBSCIRBE_DEBUG_EVENT([&](wde_construct_tx_handle_asset_descriptor_operation_before_seal& o) + { + o.pado->descriptor.current_supply -= 1000000; + }); + + miner_wlt->burn_asset(asset_id, 10000000000000, tx); + r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + CHECK_AND_ASSERT_MES(!r, false, "mine_next_pow_blocks_in_playtime failed"); + c.get_tx_pool().purge_transactions(); + miner_wlt->refresh(); + + // return true; }