From c2fa96883525e627e3ab0a2034bd708a9bf696dd Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 26 Mar 2024 19:55:34 +0100 Subject: [PATCH] daemon: 1) print_asset_info command added; 2) print_tx greatly improved; 3) fill_tx_rpc_details() now fills blob and object_in_json fields and use base64 encoding --- src/currency_core/blockchain_storage.cpp | 15 ++- src/currency_core/blockchain_storage.h | 1 + src/daemon/daemon_commands_handler.h | 150 +++++++++++++++++------ src/rpc/core_rpc_server_commands_defs.h | 4 +- 4 files changed, 127 insertions(+), 43 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index c5f26e11..6e781c68 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3780,6 +3780,17 @@ uint64_t blockchain_storage::get_aliases_count() const return m_db_aliases.size(); } //------------------------------------------------------------------ +bool blockchain_storage::get_asset_history(const crypto::public_key& asset_id, std::list& result) const +{ + CRITICAL_REGION_LOCAL(m_read_lock); + auto as_ptr = m_db_assets.find(asset_id); + if (!as_ptr) + return false; + + result = *as_ptr; + return true; +} +//------------------------------------------------------------------ bool blockchain_storage::get_asset_info(const crypto::public_key& asset_id, asset_descriptor_base& result) const { CRITICAL_REGION_LOCAL(m_read_lock); @@ -5443,7 +5454,6 @@ std::shared_ptr blockchain_storage::find_key_imag //--------------------------------------------------------------- bool blockchain_storage::fill_tx_rpc_details(tx_rpc_extended_info& tei, const transaction& tx, const transaction_chain_entry* ptce, const crypto::hash& h, uint64_t timestamp, bool is_short) const { - //tei.blob = tx_ptr->tx tei.id = epee::string_tools::pod_to_hex(h); if (!tei.blob_size) tei.blob_size = get_object_blobsize(tx); @@ -5460,6 +5470,9 @@ bool blockchain_storage::fill_tx_rpc_details(tx_rpc_extended_info& tei, const tr fill_tx_rpc_outputs(tei, tx, ptce); fill_tx_rpc_payload_items(tei.extra, tx.extra); fill_tx_rpc_payload_items(tei.attachments, tx.attachment); + + tei.blob = t_serializable_object_to_blob(tx); + tei.object_in_json = obj_to_json_str(tx); return true; } //------------------------------------------------------------------ diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index c59bdcd0..eb9c017a 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -299,6 +299,7 @@ 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_history(const crypto::public_key& asset_id, std::list& result) const; bool get_asset_info(const crypto::public_key& 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; diff --git a/src/daemon/daemon_commands_handler.h b/src/daemon/daemon_commands_handler.h index 7e395584..8f2aa24a 100644 --- a/src/daemon/daemon_commands_handler.h +++ b/src/daemon/daemon_commands_handler.h @@ -47,6 +47,7 @@ public: m_cmd_binder.set_handler("print_block_info", boost::bind(&daemon_commands_handler::print_block_info, this, ph::_1), "Print block info, print_block | "); m_cmd_binder.set_handler("print_tx_prun_info", boost::bind(&daemon_commands_handler::print_tx_prun_info, this, ph::_1), "Print tx prunning info"); m_cmd_binder.set_handler("print_tx", boost::bind(&daemon_commands_handler::print_tx, this, ph::_1), "Print transaction, print_tx "); + m_cmd_binder.set_handler("print_asset_info", boost::bind(&daemon_commands_handler::print_asset_info, this, ph::_1), "Print information about the given asset by its id"); m_cmd_binder.set_handler("start_mining", boost::bind(&daemon_commands_handler::start_mining, this, ph::_1), "Start mining for specified address, start_mining [threads=1]"); m_cmd_binder.set_handler("stop_mining", boost::bind(&daemon_commands_handler::stop_mining, this, ph::_1), "Stop mining"); m_cmd_binder.set_handler("print_pool", boost::bind(&daemon_commands_handler::print_pool, this, ph::_1), "Print transaction pool (long format)"); @@ -688,7 +689,7 @@ private: { if (args.empty()) { - std::cout << "expected: print_tx " << std::endl; + std::cout << "usage: print_tx " << std::endl; return true; } @@ -696,55 +697,74 @@ private: crypto::hash tx_hash; if (!parse_hash256(str_hash, tx_hash)) { + LOG_PRINT_RED_L0("invalid tx hash was given"); return true; } - // std::vector tx_ids; - // tx_ids.push_back(tx_hash); - // std::list txs; - // std::list missed_ids; - // m_srv.get_payload_object().get_core().get_transactions(tx_ids, txs, missed_ids); - - currency::transaction_chain_entry tx_entry = AUTO_VAL_INIT(tx_entry); - - if (!m_srv.get_payload_object().get_core().get_blockchain_storage().get_tx_chain_entry(tx_hash, tx_entry)) + currency::tx_rpc_extended_info tx_rpc_ei{}; + currency::core& core = m_srv.get_payload_object().get_core(); + if (core.get_blockchain_storage().get_tx_rpc_details(tx_hash, tx_rpc_ei, 0, false)) { - LOG_PRINT_RED("transaction wasn't found: " << tx_hash, LOG_LEVEL_0); + // pass } - currency::block_extended_info bei = AUTO_VAL_INIT(bei); - m_srv.get_payload_object().get_core().get_blockchain_storage().get_block_extended_info_by_height(tx_entry.m_keeper_block_height, bei); - uint64_t timestamp = bei.bl.timestamp; - - const currency::transaction& tx = tx_entry.tx; - std::stringstream ss; - - ss << "------------------------------------------------------" - << ENDL << "tx_id: " << tx_hash - << ENDL << "keeper_block: " << tx_entry.m_keeper_block_height << ", timestamp (" << timestamp << ") " << epee::misc_utils::get_internet_time_str(timestamp) - << ENDL << currency::obj_to_json_str(tx) - << ENDL << "------------------------------------------------------" - << ENDL << epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(tx)) - << ENDL << "------------------------------------------------------"; - - - ss << "ATTACHMENTS: " << ENDL; - for (auto at : tx.attachment) + else if (core.get_tx_pool().get_transaction_details(tx_hash, tx_rpc_ei)) { - if (at.type() == typeid(currency::tx_service_attachment)) - { - const currency::tx_service_attachment& sa = boost::get(at); - ss << "++++++++++++++++++++++++++++++++ " << ENDL; - ss << "[SERVICE_ATTACHMENT]: ID = \'" << sa.service_id << "\', INSTRUCTION: \'" << sa.instruction << "\'" << ENDL; + // pass + } + else + { + LOG_PRINT_RED("transaction " << tx_hash << " was not found in either the blockchain or the pool", LOG_LEVEL_0); + return true; + } - if (!(sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY)) + std::stringstream ss; + ss << ENDL << + "----------------------TX-HEX--------------------------" << ENDL << + epee::string_tools::buff_to_hex_nodelimer(tx_rpc_ei.blob) << ENDL << + "------------------END-OF-TX-HEX-----------------------" << ENDL; + + ss << ENDL << + "tx " << tx_hash << " "; + + if (tx_rpc_ei.keeper_block == -1) + { + ss << "has been in the transaction pool for " << epee::misc_utils::get_time_interval_string(core.get_blockchain_storage().get_core_runtime_config().get_core_time() - tx_rpc_ei.timestamp) << + ", added " << epee::misc_utils::get_internet_time_str(tx_rpc_ei.timestamp) << ", ts: " << tx_rpc_ei.timestamp << ", blob size: " << tx_rpc_ei.blob_size << ENDL; + } + else + { + ss << "was added to block @ " << tx_rpc_ei.keeper_block << ", block time: " << epee::misc_utils::get_internet_time_str(tx_rpc_ei.timestamp) << ", ts: " << tx_rpc_ei.timestamp << ", blob size: " << tx_rpc_ei.blob_size << ENDL; + } + + ss << ENDL << + "-----------------------JSON---------------------------" << ENDL << + tx_rpc_ei.object_in_json << ENDL << + "--------------------END-OF-JSON-----------------------" << ENDL; + + currency::transaction tx{}; + CHECK_AND_ASSERT_MES(currency::parse_and_validate_tx_from_blob(tx_rpc_ei.blob, tx), true, "parse_and_validate_tx_from_blob failed"); + + if (!tx.attachment.empty()) + { + ss << "ATTACHMENTS: " << ENDL; + for (auto at : tx.attachment) + { + if (at.type() == typeid(currency::tx_service_attachment)) { - std::string body = sa.body; - if (sa.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY) + const currency::tx_service_attachment& sa = boost::get(at); + ss << "++++++++++++++++++++++++++++++++ " << ENDL; + ss << "[SERVICE_ATTACHMENT]: ID = \'" << sa.service_id << "\', INSTRUCTION: \'" << sa.instruction << "\'" << ENDL; + + if (!(sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY)) { - bool r = epee::zlib_helper::unpack(sa.body, body); - CHECK_AND_ASSERT_MES(r, false, "Failed to unpack"); + std::string body = sa.body; + if (sa.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY) + { + bool r = epee::zlib_helper::unpack(sa.body, body); + CHECK_AND_ASSERT_MES(r, false, "Failed to unpack"); + } + ss << "BODY: " << body << ENDL; } - ss << "BODY: " << body << ENDL; } } } @@ -753,6 +773,56 @@ private: return true; } //-------------------------------------------------------------------------------- + bool print_asset_info(const std::vector& args) + { + if (args.empty()) + { + std::cout << "usage: print_asset_info " << std::endl; + return true; + } + + const std::string& str_asset_id = args.front(); + crypto::public_key asset_id{}; + crypto::point_t asset_id_pt{}; + if (!crypto::parse_tpod_from_hex_string(str_asset_id, asset_id) || !asset_id_pt.from_public_key(asset_id)) + { + LOG_PRINT_RED_L0("invalid asset id was given"); + return true; + } + + currency::core& core = m_srv.get_payload_object().get_core(); + + std::list asset_history; + if (!core.get_blockchain_storage().get_asset_history(asset_id, asset_history)) + { + LOG_PRINT_RED_L0("asset id doesn't present in the blockchain"); + return true; + } + + std::stringstream ss; + ss << ENDL << + "history for asset " << asset_id << ":" << ENDL; + + size_t idx = 0; + for(auto& aop: asset_history) + { + ss << "[" << std::setw(2) << idx << "] operation: " << currency::get_asset_operation_type_string(aop.operation_type) << " (" << (int)aop.operation_type << ")" << ENDL << + " ticker: \"" << aop.descriptor.ticker << "\"" << ENDL << + " full name: \"" << aop.descriptor.full_name << "\"" << ENDL << + " meta info: \"" << aop.descriptor.meta_info << "\"" << ENDL << + " current supply: " << currency::print_money_brief(aop.descriptor.current_supply, aop.descriptor.decimal_point) << ENDL << + " max supply: " << currency::print_money_brief(aop.descriptor.total_max_supply, aop.descriptor.decimal_point) << ENDL << + " decimal point: " << (int)aop.descriptor.decimal_point << ENDL << + " owner * 1/8: " << aop.descriptor.owner << ENDL << + " amount cmt * 1/8: " << aop.amount_commitment << ENDL << + " hidden supply: " << (aop.descriptor.hidden_supply ? "yes" : "no") << ENDL << + ""; + } + + LOG_PRINT_L0(ss.str()); + return true; + } + //-------------------------------------------------------------------------------- bool print_tx_outputs_usage(const std::vector& args) { if (args.empty()) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index df0b699e..ce931d9d 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -1344,7 +1344,7 @@ namespace currency std::string object_in_json; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(blob) + KV_SERIALIZE_BLOB_AS_BASE64_STRING(blob) KV_SERIALIZE(blob_size) KV_SERIALIZE(timestamp) KV_SERIALIZE(keeper_block) @@ -1356,7 +1356,7 @@ namespace currency KV_SERIALIZE(ins) KV_SERIALIZE(extra) KV_SERIALIZE(attachments) - KV_SERIALIZE(object_in_json) + KV_SERIALIZE_BLOB_AS_BASE64_STRING(object_in_json) END_KV_SERIALIZE_MAP() };