diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index aefd7a0e..ba711c66 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -59,6 +59,7 @@ using namespace currency; #define BLOCKCHAIN_STORAGE_CONTAINER_ADDR_TO_ALIAS "addr_to_alias" #define BLOCKCHAIN_STORAGE_CONTAINER_TX_FEE_MEDIAN "median_fee2" #define BLOCKCHAIN_STORAGE_CONTAINER_GINDEX_INCS "gindex_increments" +#define BLOCKCHAIN_STORAGE_CONTAINER_ASSETS "assets" #define BLOCKCHAIN_STORAGE_OPTIONS_ID_CURRENT_BLOCK_CUMUL_SZ_LIMIT 0 #define BLOCKCHAIN_STORAGE_OPTIONS_ID_CURRENT_PRUNED_RS_HEIGHT 1 @@ -95,6 +96,7 @@ blockchain_storage::blockchain_storage(tx_memory_pool& tx_pool) :m_db(nullptr, m m_db_multisig_outs(m_db), m_db_solo_options(m_db), m_db_aliases(m_db), + m_db_assets(m_db), m_db_addr_to_alias(m_db), m_read_lock(m_rw_lock), m_db_current_block_cumul_sz_limit(BLOCKCHAIN_STORAGE_OPTIONS_ID_CURRENT_BLOCK_CUMUL_SZ_LIMIT, m_db_solo_options), @@ -297,6 +299,7 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro m_db_multisig_outs.set_cache_size(cache_size); m_db_solo_options.set_cache_size(cache_size); m_db_aliases.set_cache_size(cache_size); + m_db_assets.set_cache_size(cache_size); m_db_addr_to_alias.set_cache_size(cache_size); } @@ -414,6 +417,7 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro m_db_multisig_outs.deinit(); m_db_solo_options.deinit(); m_db_aliases.deinit(); + m_db_assets.deinit(); m_db_addr_to_alias.deinit(); m_db_per_block_gindex_incs.deinit(); m_db.close(); @@ -660,6 +664,7 @@ bool blockchain_storage::clear() m_db_outputs.clear(); m_db_multisig_outs.clear(); m_db_aliases.clear(); + m_db_assets.clear(); m_db_addr_to_alias.clear(); m_db_per_block_gindex_incs.clear(); m_pos_targetdata_cache.clear(); @@ -1546,6 +1551,7 @@ void blockchain_storage::reset_db_cache() const m_db_solo_options.clear_cache(); m_db_multisig_outs.clear_cache(); m_db_aliases.clear_cache(); + m_db_assets.clear_cache(); m_db_addr_to_alias.clear_cache(); } @@ -2953,6 +2959,7 @@ void blockchain_storage::print_db_cache_perfeormance_data() const DB_CONTAINER_PERF_DATA_ENTRY(m_db_multisig_outs) << ENDL DB_CONTAINER_PERF_DATA_ENTRY(m_db_solo_options) << ENDL DB_CONTAINER_PERF_DATA_ENTRY(m_db_aliases) << ENDL + DB_CONTAINER_PERF_DATA_ENTRY(m_db_assets) << ENDL DB_CONTAINER_PERF_DATA_ENTRY(m_db_addr_to_alias) << ENDL //DB_CONTAINER_PERF_DATA_ENTRY(m_db_per_block_gindex_incs) << ENDL //DB_CONTAINER_PERF_DATA_ENTRY(m_tx_fee_median) << ENDL @@ -3518,6 +3525,27 @@ uint64_t blockchain_storage::get_aliases_count() const return m_db_aliases.size(); } //------------------------------------------------------------------ +bool blockchain_storage::get_asset_info(const crypto::hash& asset_id, asset_descriptor_base& info)const +{ + CRITICAL_REGION_LOCAL(m_read_lock); + auto as_ptr = m_db_assets.find(asset_id); + if (as_ptr) + { + if (as_ptr->size()) + { + info = as_ptr->back(); + return true; + } + } + return false; +} +//------------------------------------------------------------------ +uint64_t blockchain_storage::get_assets_count() const +{ + CRITICAL_REGION_LOCAL(m_read_lock); + return m_db_assets.size(); +} +//------------------------------------------------------------------ std::string blockchain_storage::get_alias_by_address(const account_public_address& addr)const { auto alias_ptr = m_db_addr_to_alias.find(addr); @@ -3700,6 +3728,49 @@ bool blockchain_storage::put_alias_info(const transaction & tx, extra_alias_entr return true; } //------------------------------------------------------------------ +bool blockchain_storage::pop_asset_info(const crypto::hash& asset_id) +{ + CRITICAL_REGION_LOCAL(m_read_lock); + + auto asset_history_ptr = m_db_assets.find(asset_id); + CHECK_AND_ASSERT_MES(asset_history_ptr && asset_history_ptr->size(), false, "empty name list in pop_asset_info"); + + assets_container::t_value_type local_asset_hist = *asset_history_ptr; + local_asset_hist.pop_back(); + if (local_asset_hist.size()) + m_db_aliases.set(asset_id, local_asset_hist); + else + m_db_aliases.erase(asset_id); + + LOG_PRINT_MAGENTA("[ASSET_POP]: " << asset_id << ": " << (!local_asset_hist.empty() ? "(prev)" : "(erased)"), LOG_LEVEL_1); + return true; +} +//------------------------------------------------------------------ +bool blockchain_storage::put_asset_info(const transaction & tx, asset_descriptor_operation & ado) +{ + CRITICAL_REGION_LOCAL(m_read_lock); + if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER) + { + crypto::hash asset_id = get_asset_id_from_descriptor(ado.descriptor); + auto asset_history_ptr = m_db_aliases.find(asset_id); + CHECK_AND_ASSERT_MES(!asset_history_ptr, false, "Asset id already existing"); + assets_container::t_value_type local_asset_history = AUTO_VAL_INIT(local_asset_history); + local_asset_history.push_back(ado.descriptor); + m_db_assets.set(asset_id, local_asset_history); + LOG_PRINT_MAGENTA("[ASSET_REGISTERED]: " << asset_id << ": " << ado.descriptor.full_name, LOG_LEVEL_1); + //TODO: + //rise_core_event(CORE_EVENT_ADD_ASSET, alias_info_to_rpc_alias_info(ai)); + + } + else + { + //TODO: implement other operations + CHECK_AND_ASSERT_THROW(false, "not implemented yet"); + } + + return true; +} +//------------------------------------------------------------------ void blockchain_storage::set_event_handler(i_core_event_handler* event_handler) const { if (event_handler == nullptr) diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 15d027bb..92ab3049 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -288,6 +288,8 @@ namespace currency uint64_t get_aliases_count()const; uint64_t get_block_h_older_then(uint64_t timestamp) const; bool validate_tx_service_attachmens_in_services(const tx_service_attachment& a, size_t i, const transaction& tx)const; + bool get_asset_info(const crypto::hash& asset_id, asset_descriptor_base& info)const; + uint64_t get_assets_count() const; bool check_tx_input(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase)const; bool check_tx_input(const transaction& tx, size_t in_index, const txin_multisig& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height)const; bool check_tx_input(const transaction& tx, size_t in_index, const txin_htlc& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height)const; @@ -486,6 +488,9 @@ namespace currency typedef tools::db::cached_key_value_accessor multisig_outs_container;// ms out id => ms_output_entry typedef tools::db::cached_key_value_accessor solo_options_container; typedef tools::db::basic_key_value_accessor per_block_gindex_increments_container; // height => [(amount, gindex_increment), ...] + + typedef tools::db::cached_key_value_accessor, true, false> assets_container; + //----------------------------------------- @@ -527,6 +532,7 @@ namespace currency address_to_aliases_container m_db_addr_to_alias; per_block_gindex_increments_container m_db_per_block_gindex_incs; + assets_container m_db_assets; @@ -645,6 +651,8 @@ namespace currency bool unprocess_blockchain_tx_attachments(const transaction& tx, uint64_t h, uint64_t timestamp); bool pop_alias_info(const extra_alias_entry& ai); bool put_alias_info(const transaction& tx, extra_alias_entry& ai); + bool pop_asset_info(const crypto::hash& asset_id); + bool put_asset_info(const transaction & tx, asset_descriptor_operation & ado); void fill_addr_to_alias_dict(); //bool resync_spent_tx_flags(); bool prune_ring_signatures_and_attachments_if_need(); diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index 074d0dd3..ae103568 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -725,15 +725,17 @@ namespace currency struct asset_descriptor_operation { - uint8_t operation_type = ASSET_DESCRIPTOR_OPERATION_UNDEFINED; - std::vector proof; - asset_descriptor_base descriptor; + uint8_t operation_type = ASSET_DESCRIPTOR_OPERATION_UNDEFINED; + std::vector proof; + asset_descriptor_base descriptor; + std::vector asset_id; //questionable regarding form of optional fields BEGIN_VERSIONED_SERIALIZE() FIELD(operation_type) FIELD(proof) FIELD(descriptor) + FIELD(asset_id) END_SERIALIZE() diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 90bd203a..e69415d0 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1797,9 +1797,8 @@ namespace currency tx.extra.insert(tx.extra.end(), extra_local.begin(), extra_local.end()); } -// //first: separate zarcanum inputs and regular one - //std::vector zc_sources; - //std::vector NLSAG_sources; + + uint64_t summary_inputs_money = 0; crypto::hash asset_id_for_destinations = currency::null_hash; if (tx.version > TRANSACTION_VERSION_PRE_HF4) @@ -1812,6 +1811,8 @@ namespace currency CHECK_AND_ASSERT_MES(r, false, "Failed to derive_public_key_from_tx_and_account_pub_key()"); //also assign this asset id to destinations asset_id_for_destinations = get_asset_id_from_descriptor(ado.descriptor); + //TODO: temporary + summary_inputs_money += ado.descriptor.current_supply; } } @@ -1824,7 +1825,6 @@ namespace currency size_t current_index = 0; inputs_mapping.resize(sources.size()); size_t input_starter_index = tx.vin.size(); - uint64_t summary_inputs_money = 0; //fill inputs NLSAG and Zarcanum for (const tx_source_entry& src_entr : sources) { @@ -2055,8 +2055,6 @@ namespace currency if (tx.attachment.size()) add_attachments_info_to_extra(tx.extra, tx.attachment); } - - // // generate ring signatures // diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index b5f535ba..17e5e251 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -288,6 +288,7 @@ namespace currency uint64_t get_tx_version(uint64_t h, const hard_forks_descriptor& hfd); bool construct_tx(const account_keys& sender_account_keys, const finalize_tx_param& param, finalized_tx& result); + crypto::hash get_asset_id_from_descriptor(const asset_descriptor_base& adb); bool sign_multisig_input_in_tx(currency::transaction& tx, size_t ms_input_index, const currency::account_keys& keys, const currency::transaction& source_tx, bool *p_is_input_fully_signed = nullptr); diff --git a/src/currency_core/dispatch_core_events.h b/src/currency_core/dispatch_core_events.h index dadff8b1..19d3df40 100644 --- a/src/currency_core/dispatch_core_events.h +++ b/src/currency_core/dispatch_core_events.h @@ -17,6 +17,7 @@ #define CORE_EVENT_ADD_ALIAS "CORE_EVENT_ADD_ALIAS" #define CORE_EVENT_UPDATE_ALIAS "CORE_EVENT_UPDATE_ALIAS" #define CORE_EVENT_BLOCK_ADDED "CORE_EVENT_BLOCK_ADDED" +#define CORE_EVENT_ADD_ASSET "CORE_EVENT_ADD_ASSET" namespace currency