From 26ef578f08341eb2019e5c1b37491deaf3cd6efb Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 14 Aug 2023 22:32:52 +0200 Subject: [PATCH] fixed at least currency_format_utils.cpp --- src/currency_core/currency_format_utils.cpp | 73 ++++++----- src/currency_core/currency_format_utils.h | 4 +- src/wallet/wallet2.cpp | 137 +++++++++++++++++--- src/wallet/wallet2.h | 54 +++++++- tests/core_tests/multiassets_test.cpp | 10 ++ 5 files changed, 226 insertions(+), 52 deletions(-) diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 2c812068..e59e5b3b 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -581,9 +581,9 @@ namespace currency CHECK_AND_ASSERT_MES(context.ado.opt_amount_commitment.has_value(), false, "opt_amount_commitment is absent"); CHECK_AND_ASSERT_MES(aop.opt_amount_commitment_g_proof.has_value(), false, "opt_amount_commitment_g_proof is absent"); crypto::point_t A = is_burn ? - crypto::point_t(context.ado.opt_amount_commitment.get()).modify_mul8() + context.amount * asset_id_pt + crypto::point_t(context.ado.opt_amount_commitment.get()).modify_mul8() + context.amout_to_validate * context.asset_id_pt : - crypto::point_t(context.ado.opt_amount_commitment.get()).modify_mul8() - context.amount * asset_id_pt + crypto::point_t(context.ado.opt_amount_commitment.get()).modify_mul8() - context.amout_to_validate * context.asset_id_pt ; bool r = crypto::check_signature(context.tx_id, A.to_public_key(), aop.opt_amount_commitment_g_proof.get()); @@ -2079,16 +2079,21 @@ namespace currency p_result_point->to_public_key(*p_result_pub_key); } - bool construct_tx_handle_ado(const account_keys& sender_account_keys, const finalize_tx_param& ftp, asset_descriptor_operation* pado, tx_generation_context& gen_context) + bool construct_tx_handle_ado(const account_keys& sender_account_keys, + const finalize_tx_param& ftp, + asset_descriptor_operation& ado, + tx_generation_context& gen_context, + const crypto::secret_key& one_time_tx_secret_key, + std::vector& shuffled_dsts) { - if (pado->operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER) + if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER) { - //CHECK_AND_ASSERT_MES(pado->operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER, false, "unsupported asset operation: " << (int)pado->operation_type); + //CHECK_AND_ASSERT_MES(ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER, false, "unsupported asset operation: " << (int)ado.operation_type); crypto::secret_key asset_control_key{}; - bool r = derive_key_pair_from_key_pair(sender_account_keys.account_address.spend_public_key, one_time_tx_secret_key, asset_control_key, pado->descriptor.owner, CRYPTO_HDS_ASSET_CONTROL_KEY); + bool r = derive_key_pair_from_key_pair(sender_account_keys.account_address.spend_public_key, one_time_tx_secret_key, asset_control_key, ado.descriptor.owner, CRYPTO_HDS_ASSET_CONTROL_KEY); CHECK_AND_ASSERT_MES(r, false, "derive_key_pair_from_key_pair failed"); - calculate_asset_id(pado->descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id); + calculate_asset_id(ado.descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id); // calculate amount blinding mask gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, asset_control_key); @@ -2103,23 +2108,23 @@ namespace currency amount_of_emitted_asset += item.amount; } } - pado->descriptor.current_supply = amount_of_emitted_asset; // TODO: consider setting current_supply beforehand, not setting it hear in ad-hoc manner -- sowle + ado.descriptor.current_supply = amount_of_emitted_asset; // TODO: consider setting current_supply beforehand, not setting it hear in ad-hoc manner -- sowle gen_context.ao_amount_commitment = amount_of_emitted_asset * gen_context.ao_asset_id_pt + gen_context.ao_amount_blinding_mask * crypto::c_point_G; - pado->opt_amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key(); + ado.opt_amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key(); } else { - if (pado->operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT) + if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT) { - //bool r = derive_key_pair_from_key_pair(sender_account_keys.account_address.spend_public_key, one_time_tx_secret_key, asset_control_key, pado->descriptor.owner, CRYPTO_HDS_ASSET_CONTROL_KEY); + //bool r = derive_key_pair_from_key_pair(sender_account_keys.account_address.spend_public_key, one_time_tx_secret_key, asset_control_key, ado.descriptor.owner, CRYPTO_HDS_ASSET_CONTROL_KEY); //CHECK_AND_ASSERT_MES(r, false, "derive_key_pair_from_key_pair failed"); - //calculate_asset_id(pado->descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id); - CHECK_AND_ASSERT_MES(pado->opt_asset_id, false, "pado->opt_asset_id is not found at pado->operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE"); + //calculate_asset_id(ado.descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id); + CHECK_AND_ASSERT_MES(ado.opt_asset_id, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE"); - gen_context.ao_asset_id = *pado->opt_asset_id; + gen_context.ao_asset_id = *ado.opt_asset_id; gen_context.ao_asset_id_pt.from_public_key(gen_context.ao_asset_id); // calculate amount blinding mask gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, ftp.asset_control_key); @@ -2133,52 +2138,60 @@ namespace currency amount_of_emitted_asset += item.amount; } } - pado->descriptor.current_supply += amount_of_emitted_asset; // TODO: consider setting current_supply beforehand, not setting it hear in ad-hoc manner -- sowle + ado.descriptor.current_supply += amount_of_emitted_asset; // TODO: consider setting current_supply beforehand, not setting it hear in ad-hoc manner -- sowle gen_context.ao_amount_commitment = amount_of_emitted_asset * gen_context.ao_asset_id_pt + gen_context.ao_amount_blinding_mask * crypto::c_point_G; - pado->opt_amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key(); + ado.opt_amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key(); } - else if (pado->operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE) + else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE) { - CHECK_AND_ASSERT_MES(pado->opt_asset_id, false, "pado->opt_asset_id is not found at pado->operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE"); - CHECK_AND_ASSERT_MES(pado->opt_proof, false, "pado->opt_asset_id is not found at pado->operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE"); - CHECK_AND_ASSERT_MES(!pado->opt_amount_commitment, false, "pado->opt_asset_id is not found at pado->operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE"); + CHECK_AND_ASSERT_MES(ado.opt_asset_id, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE"); + CHECK_AND_ASSERT_MES(ado.opt_proof, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE"); + CHECK_AND_ASSERT_MES(!ado.opt_amount_commitment, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE"); //fields that not supposed to be changed? } - else if (pado->operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN) + else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN) { - //calculate_asset_id(pado->descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id); - CHECK_AND_ASSERT_MES(pado->opt_asset_id, false, "pado->opt_asset_id is not found at pado->operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE"); + //calculate_asset_id(ado.descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id); + CHECK_AND_ASSERT_MES(ado.opt_asset_id, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE"); - gen_context.ao_asset_id = *pado->opt_asset_id; + gen_context.ao_asset_id = *ado.opt_asset_id; gen_context.ao_asset_id_pt.from_public_key(gen_context.ao_asset_id); // calculate amount blinding mask gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, ftp.asset_control_key); // set correct asset_id to the corresponding destination entries uint64_t amount_of_burned_assets = 0; - for (auto& item : ftp.sources) + for (auto& item: ftp.sources) { if (item.asset_id == gen_context.ao_asset_id) { amount_of_burned_assets += item.amount; } } - pado->descriptor.current_supply -= amount_of_burned_assets; // TODO: consider setting current_supply beforehand, not setting it hear in ad-hoc manner -- sowle + for (auto& item : ftp.prepared_destinations) + { + if (item.asset_id == gen_context.ao_asset_id ) + { + CHECK_AND_ASSERT_THROW_MES(amount_of_burned_assets >= item.amount, "Failed to find burn amount, failed condition: amount_of_burned_assets(" << amount_of_burned_assets << ") >= item.amount("<< item.amount << ")"); + amount_of_burned_assets -= item.amount; + } + } + ado.descriptor.current_supply -= amount_of_burned_assets; // TODO: consider setting current_supply beforehand, not setting it hear in ad-hoc manner -- sowle gen_context.ao_amount_commitment = amount_of_burned_assets * gen_context.ao_asset_id_pt + gen_context.ao_amount_blinding_mask * crypto::c_point_G; - pado->opt_amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key(); + ado.opt_amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key(); } //seal it with owners signature crypto::signature sig = currency::null_sig; crypto::public_key pub_k = currency::null_pkey; crypto::secret_key_to_public_key(ftp.asset_control_key, pub_k); - crypto::generate_signature(get_signature_hash_for_asset_operation(ado), ftp.asset_control_key, sig); - pado->opt_proof = sig; + crypto::generate_signature(get_signature_hash_for_asset_operation(ado), pub_k, ftp.asset_control_key, sig); + ado.opt_proof = sig; } return true; } @@ -2436,7 +2449,7 @@ namespace currency pado = get_type_in_variant_container(tx.extra); if (pado) { - bool r = construct_tx_handle_ado(sender_account_keys, ftp, pado, gen_context); + bool r = construct_tx_handle_ado(sender_account_keys, ftp, *pado, gen_context, one_time_tx_secret_key, shuffled_dsts); CHECK_AND_ASSERT_MES(r, false, "Failed to construct_tx_handle_ado()"); } } diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 412f31d8..355c85a9 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -158,7 +158,8 @@ namespace currency crypto::public_key spend_pub_key; // only for validations uint64_t tx_version; uint64_t mode_separate_fee = 0; - crypto::secret_key asset_control_key = currency::null_pkey; + crypto::secret_key asset_control_key = currency::null_skey; + tx_generation_context gen_context{}; // solely for consolidated txs @@ -178,6 +179,7 @@ namespace currency FIELD(spend_pub_key) FIELD(tx_version) FIELD(mode_separate_fee) + FIELD(asset_control_key) if (flags & TX_FLAG_SIGNATURE_MODE_SEPARATE) FIELD(gen_context); END_SERIALIZE() diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 9bdb27cc..ff6b4f81 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -416,7 +416,7 @@ const crypto::public_key& wallet2::out_get_pub_key(const currency::tx_out_v& out } } //---------------------------------------------------------------------------------------------------- -void wallet2::process_ado_in_new_transaction(const asset_descriptor_operation& ado) +void wallet2::process_ado_in_new_transaction(const asset_descriptor_operation& ado, uint64_t height) { do { @@ -443,7 +443,7 @@ void wallet2::process_ado_in_new_transaction(const asset_descriptor_operation& a WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(m_own_asset_descriptors.count(asset_id) == 0, "asset with asset_id " << asset_id << " has already been registered in the wallet as own asset"); wallet_own_asset_context& asset_context = m_own_asset_descriptors[asset_id]; asset_context.asset_descriptor = ado.descriptor; - asset_context.height = height; + //asset_context.height = height; std::stringstream ss; ss << "New Asset Registered:" << ENDL << "asset id: " << asset_id @@ -453,17 +453,38 @@ void wallet2::process_ado_in_new_transaction(const asset_descriptor_operation& a << 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; + + add_rollback_event(height, asset_register_event{ asset_id }); WLT_LOG_MAGENTA(ss.str(), LOG_LEVEL_0); if (m_wcallback) m_wcallback->on_message(i_wallet2_callback::ms_yellow, ss.str()); } - else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE) + else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE || ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT || ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN) { - if (ado.opt_asset_id) + WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(ado.opt_asset_id, "ASSET_DESCRIPTOR_OPERATION_UPDATE with empty opt_asset_id"); + auto it = m_own_asset_descriptors.find(*ado.opt_asset_id); + WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(it != m_own_asset_descriptors.end(), "asset with asset_id " << *ado.opt_asset_id << " not found during ASSET_DESCRIPTOR_OPERATION_UPDATE"); + if (it->second.asset_descriptor.owner != ado.descriptor.owner) + { + //ownership of the asset had been transfered + add_rollback_event(height, asset_unown_event{ it->first, it->second }); + m_own_asset_descriptors.erase(it); + } + else + { + //asset had been updated + add_rollback_event(height, asset_update_event{ it->first, it->second }); + it->second.asset_descriptor = ado.descriptor; + } } } while (false); } - +//---------------------------------------------------------------------------------------------------- +void wallet2::add_rollback_event(uint64_t h, const wallet_event_t& ev) +{ + m_rollback_events.emplace_back(h, ev); +} +//---------------------------------------------------------------------------------------------------- void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t height, const currency::block& b, const std::vector* pglobal_indexes) { //check for transaction spends @@ -852,7 +873,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t asset_descriptor_operation ado = AUTO_VAL_INIT(ado); if (get_type_in_variant_container(tx.extra, ado)) { - process_ado_in_new_transaction(ado); + process_ado_in_new_transaction(ado, height); } } @@ -2750,17 +2771,41 @@ void wallet2::detach_blockchain(uint64_t including_height) } //asset descriptors - for (auto it = m_own_asset_descriptors.begin(); it != m_own_asset_descriptors.end(); ) - { - if (including_height <= it->second.height) - it = m_own_asset_descriptors.erase(it); - else - ++it; - } + handle_rollback_events(including_height); WLT_LOG_L0("Detached blockchain on height " << including_height << ", transfers detached " << transfers_detached << ", blocks detached " << blocks_detached); } //---------------------------------------------------------------------------------------------------- +void wallet2::operator()(const asset_register_event& e) +{ + auto it = m_own_asset_descriptors.find(e.asset_id); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it != m_own_asset_descriptors.end(), "asset_id " << e.asset_id << "not found during rolling asset_register_event"); + m_own_asset_descriptors.erase(it); +} +void wallet2::operator()(const asset_update_event& e) +{ + auto it = m_own_asset_descriptors.find(e.asset_id); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it != m_own_asset_descriptors.end(), "asset_id " << e.asset_id << "not found during rolling asset_update_event"); + it->second = e.own_context; +} +void wallet2::operator()(const asset_unown_event& e) +{ + auto it = m_own_asset_descriptors.find(e.asset_id); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it == m_own_asset_descriptors.end(), "asset_id " << e.asset_id << "unexpectedly found during rolling asset_unown_event"); + m_own_asset_descriptors[e.asset_id] = e.own_context; +} +//---------------------------------------------------------------------------------------------------- +void wallet2::handle_rollback_events(uint64_t including_height) +{ + while (m_rollback_events.size() && m_rollback_events.back().first >= including_height) + { + boost::apply_visitor(*this, m_rollback_events.back()); + m_rollback_events.pop_back(); + } +} +//---------------------------------------------------------------------------------------------------- + +m_rollback_events bool wallet2::deinit() { m_wcallback.reset(); @@ -4673,7 +4718,53 @@ void wallet2::emmit_asset(const crypto::public_key asset_id, std::vectorsecond.control_key; + ctp.asset_deploy_control_key = own_asset_entry_it->second.control_key; + + finalized_tx ft = AUTO_VAL_INIT(ft); + this->transfer(ctp, ft, true, nullptr); + result_tx = ft.tx; +} +//---------------------------------------------------------------------------------------------------- +void wallet2::update_asset(const crypto::public_key asset_id, const asset_descriptor_base new_descriptor, currency::transaction& result_tx) +{ + 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"); + + asset_descriptor_operation asset_emmit_info = AUTO_VAL_INIT(asset_emmit_info); + asset_emmit_info.descriptor = new_descriptor; + asset_emmit_info.operation_type = ASSET_DESCRIPTOR_OPERATION_UPDATE; + asset_emmit_info.asset_id = asset_id; + construct_tx_param ctp = get_default_construct_tx_param(); + ctp.extra.push_back(asset_reg_info); + ctp.need_at_least_1_zc = true; + ctp.asset_deploy_control_key = own_asset_entry_it->second.control_key; + + finalized_tx ft = AUTO_VAL_INIT(ft); + this->transfer(ctp, ft, true, nullptr); + result_tx = ft.tx; +} +//---------------------------------------------------------------------------------------------------- +void wallet2::burn_asset(const crypto::public_key asset_id, uint64_t amount_to_burn, currency::transaction& result_tx) +{ + 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"); + + asset_descriptor_operation asset_emmit_info = AUTO_VAL_INIT(asset_emmit_info); + asset_emmit_info.descriptor = own_asset_entry_it->second.asset_descriptor; + + CHECK_AND_ASSERT_THROW_MES(asset_emmit_info.descriptor.current_supply > amount_to_burn, "Wrong amount to burn (current_supply" << asset_emmit_info.descriptor.current_supply << " is less then " << amount_to_burn << ")"); + + currency::tx_destination_entry dst_to_burn = AUTO_VAL_INIT(dst_to_burn); + dst_to_burn.amount = amount_to_burn; + dst_to_burn.asset_id = asset_id; + + asset_emmit_info.operation_type = ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN; + asset_emmit_info.asset_id = asset_id; + construct_tx_param ctp = get_default_construct_tx_param(); + ctp.extra.push_back(asset_reg_info); + ctp.need_at_least_1_zc = true; + ctp.asset_deploy_control_key = own_asset_entry_it->second.control_key; + ctp.dsts.push_back(dst_to_burn); finalized_tx ft = AUTO_VAL_INIT(ft); this->transfer(ctp, ft, true, nullptr); @@ -6499,6 +6590,19 @@ void wallet2::prepare_tx_destinations(const assets_selection_context& needed_mon 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); } + + //exclude destinations that supposed to be burned (for ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN) + for (size_t i = 0; i < final_destinations.size(); ) + { + if (final_destinations[i].addr.size() == 0) + { + final_destinations.erase(final_destinations.begin() + i); + } + else + { + i++; + } + } } } //---------------------------------------------------------------------------------------------------- @@ -6554,7 +6658,7 @@ bool wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx const currency::transaction& tx_for_mode_separate = msc.tx_for_mode_separate; assets_selection_context needed_money_map = get_needed_money(ctp.fee, ctp.dsts); - ftp.asset_control_key = ctp.control_key; + ftp.asset_control_key = ctp.asset_deploy_control_key; // // TODO @#@# need to do refactoring over this part to support hidden amounts and asset_id // @@ -6569,7 +6673,7 @@ bool wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx if (msc.escrow) needed_money_map[currency::native_coin_asset_id].needed_amount += (currency::get_outs_money_amount(tx_for_mode_separate) - get_inputs_money_amount(tx_for_mode_separate)); - } + }else if(ctp.) TIME_MEASURE_FINISH_MS(get_needed_money_time); //uint64_t found_money = 0; @@ -6850,6 +6954,7 @@ void wallet2::transfer(construct_tx_param& ctp, TIME_MEASURE_START(prepare_transaction_time); currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp); + ftp.p_construct_tx_param = &ctp; ftp.tx_version = this->get_current_tx_version(); if (!prepare_transaction(ctp, ftp)) { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index f4170ebc..ca80e841 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -292,7 +292,7 @@ namespace tools bool shuffle = false; bool create_utxo_defragmentation_tx = false; bool need_at_least_1_zc = false; - crypto::secret_key control_key = currency::null_pkey; + crypto::secret_key asset_deploy_control_key = currency::null_pkey; }; struct mode_separate_context @@ -311,7 +311,7 @@ namespace tools }; typedef std::unordered_map assets_selection_context; - class wallet2: public tools::tor::t_transport_state_notifier + class wallet2: public tools::tor::t_transport_state_notifier, public boost::static_visitor { wallet2(const wallet2&) = delete; public: @@ -597,12 +597,12 @@ namespace tools { currency::asset_descriptor_base asset_descriptor; crypto::secret_key control_key; - uint64_t height = 0; + //uint64_t height = 0; BEGIN_BOOST_SERIALIZATION() BOOST_SERIALIZE(asset_descriptor) BOOST_SERIALIZE(control_key) - BOOST_SERIALIZE(height) + //BOOST_SERIALIZE(height) END_BOOST_SERIALIZATION() }; @@ -1002,11 +1002,17 @@ private: // -------- t_transport_state_notifier ------------------------------------------------ virtual void notify_state_change(const std::string& state_code, const std::string& details = std::string()); + //---------- m_rollback_events visitor ------------------------------------------------ + void operator()(const asset_register_event& e); + void operator()(const asset_update_event& e); + void operator()(const asset_unown_event& e); + + void add_rollback_event(uint64_t h, const wallet_event_t& ev); // ------------------------------------------------------------------------------------ void add_transfers_to_expiration_list(const std::vector& selected_transfers, const std::vector& received, uint64_t expiration, const crypto::hash& related_tx_id); void remove_transfer_from_expiration_list(uint64_t transfer_index); void load_keys(const std::string& keys_file_name, const std::string& password, uint64_t file_signature, keys_file_data& kf_data); - void process_ado_in_new_transaction(const asset_descriptor_operation& ado); + void process_ado_in_new_transaction(const asset_descriptor_operation& ado, uint64_t height); void process_new_transaction(const currency::transaction& tx, uint64_t height, const currency::block& b, const std::vector* pglobal_indexes); void fetch_tx_global_indixes(const currency::transaction& tx, std::vector& goutputs_indexes); void fetch_tx_global_indixes(const std::list>& txs, std::vector>& goutputs_indexes); @@ -1204,6 +1210,44 @@ private: mutable current_operation_context m_current_context; //this needed to access wallets state in coretests, for creating abnormal blocks and tranmsactions friend class test_generator; + + + //general rollback mechanism + struct asset_register_event + { + crypto::public_key asset_id = currency::null_pkey; + BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(asset_id) + END_BOOST_SERIALIZATION() + + }; + + struct asset_update_event + { + crypto::public_key asset_id = currency::null_pkey; + wallet_own_asset_context own_context; + + BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(asset_id) + BOOST_SERIALIZE(own_context) + END_BOOST_SERIALIZATION() + }; + + struct asset_unown_event + { + crypto::public_key asset_id = currency::null_pkey; + wallet_own_asset_context own_context; + + BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(asset_id) + BOOST_SERIALIZE(own_context) + END_BOOST_SERIALIZATION() + }; + + typedef boost::variant wallet_event_t; + + std::list> m_rollback_events; + }; // class wallet2 diff --git a/tests/core_tests/multiassets_test.cpp b/tests/core_tests/multiassets_test.cpp index 92383f61..3747ce39 100644 --- a/tests/core_tests/multiassets_test.cpp +++ b/tests/core_tests/multiassets_test.cpp @@ -134,7 +134,17 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v return true; } + asset_descriptor_base asset_info = AUTO_VAL_INIT(asset_info); + /* + adb.total_max_supply = 1000000000000000000; //1M coins + adb.full_name = "Test coins"; + adb.ticker = "TCT"; + adb.decimal_point = 12 + */ + bool r = c.get_blockchain_storage().get_asset_info(asset_id); + CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info"); + CHECK_AND_ASSERT_MES(asset_info.current_supply = AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC*2, false, "Failed to find needed asset in result balances"); return true; }