From ac4a62a5c980c0fda5fe9ef695b9f54b3790380a Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Mon, 17 Apr 2023 23:04:30 +0200 Subject: [PATCH] fixed API for explorer --- src/currency_core/blockchain_storage.cpp | 76 ++++++ src/currency_core/blockchain_storage.h | 2 + src/currency_core/currency_format_utils.cpp | 249 -------------------- src/currency_core/currency_format_utils.h | 212 ++++++++++++++++- src/currency_core/tx_pool.cpp | 6 +- 5 files changed, 291 insertions(+), 254 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index be5a1417..46fc7e06 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -5150,6 +5150,82 @@ std::shared_ptr blockchain_storage::find_key_imag return std::shared_ptr(); } +//--------------------------------------------------------------- +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); + + tei.fee = get_tx_fee(tx); + tei.pub_key = epee::string_tools::pod_to_hex(get_tx_pub_key_from_extra(tx)); + tei.timestamp = timestamp; + tei.amount = get_outs_money_amount(tx); + + if (is_short) + return true; + + fill_tx_rpc_inputs(tei, tx); + 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); + return true; +} +//------------------------------------------------------------------ +bool blockchain_storage::fill_tx_rpc_inputs(tx_rpc_extended_info& tei, const transaction& tx) const +{ + //handle inputs + for (auto in : tx.vin) + { + tei.ins.push_back(tx_in_rpc_entry()); + if (in.type() == typeid(txin_gen)) + { + tei.ins.back().amount = 0; + } + else if (in.type() == typeid(txin_to_key) || in.type() == typeid(txin_htlc)) + { + //TODO: add htlc info + const txin_to_key& tk = get_to_key_input_from_txin_v(in); + tei.ins.back().amount = tk.amount; + tei.ins.back().kimage_or_ms_id = epee::string_tools::pod_to_hex(tk.k_image); + std::vector absolute_offsets = relative_output_offsets_to_absolute(tk.key_offsets); + for (auto& ao : absolute_offsets) + { + tei.ins.back().global_indexes.push_back(0); + if (ao.type() == typeid(uint64_t)) + { + tei.ins.back().global_indexes.back() = boost::get(ao); + } + else if (ao.type() == typeid(ref_by_id)) + { + //disable for the reset at the moment + auto tx_ptr = get_tx_chain_entry(boost::get(ao).tx_id); + if (!tx_ptr || tx_ptr->m_global_output_indexes.size() <= boost::get(ao).n) + { + tei.ins.back().global_indexes.back() = std::numeric_limits::max(); + return false; + } + tei.ins.back().global_indexes.back() = tx_ptr->m_global_output_indexes[boost::get(ao).n]; + } + } + if (in.type() == typeid(txin_htlc)) + { + tei.ins.back().htlc_origin = epee::string_tools::buff_to_hex_nodelimer(boost::get(in).hltc_origin); + } + //tk.etc_details -> visualize it may be later + } + else if (in.type() == typeid(txin_multisig)) + { + txin_multisig& tms = boost::get(in); + tei.ins.back().amount = tms.amount; + tei.ins.back().kimage_or_ms_id = epee::string_tools::pod_to_hex(tms.multisig_out_id); + if (tx.signatures.size() >= tei.ins.size()) + tei.ins.back().multisig_count = tx.signatures[tei.ins.size() - 1].size(); + } + } + return true; +} //------------------------------------------------------------------ bool blockchain_storage::prune_aged_alt_blocks() { diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index e5791569..f9dfa437 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -334,6 +334,8 @@ namespace currency // returns true as soon as the hardfork is active for the NEXT upcoming block (not for the top block in the blockchain storage) bool is_hardfork_active(size_t hardfork_id) const; + bool fill_tx_rpc_inputs(tx_rpc_extended_info& tei, const transaction& tx) const; + bool 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 = false) const; wide_difficulty_type block_difficulty(size_t i)const; bool forecast_difficulty(std::vector> &out_height_2_diff_vector, bool pos) const; diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 3324ca55..98dcf722 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -3570,235 +3570,7 @@ namespace currency return cnt; } - struct rpc_tx_payload_handler : public boost::static_visitor - { - tx_extra_rpc_entry& tv; - rpc_tx_payload_handler(tx_extra_rpc_entry& t) : tv(t) - {} - bool operator()(const tx_service_attachment& ee) - { - tv.type = "service"; - tv.short_view = ee.service_id + ":" + ee.instruction; - if (ee.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY) - tv.short_view += "(encrypted)"; - else - { - std::string deflated_buff; - const std::string* pfinalbuff = &ee.body; - if (ee.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY) - { - bool r = epee::zlib_helper::unpack(ee.body, deflated_buff); - CHECK_AND_ASSERT_MES(r, false, "Failed to unpack"); - pfinalbuff = &deflated_buff; - } - if (ee.service_id == BC_PAYMENT_ID_SERVICE_ID || ee.service_id == BC_OFFERS_SERVICE_ID) - tv.details_view = *pfinalbuff; - else - tv.details_view = "BINARY DATA"; - } - return true; - } - bool operator()(const tx_crypto_checksum& ee) - { - tv.type = "crypto_checksum"; - tv.short_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash); - tv.details_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash) + "\n" - + "encrypted_key_derivation: " + epee::string_tools::pod_to_hex(ee.encrypted_key_derivation); - - return true; - } - bool operator()(const etc_tx_time& ee) - { - tv.type = "pos_time"; - tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); - return true; - } - bool operator()(const etc_tx_details_unlock_time& ee) - { - tv.type = "unlock_time"; - if (ee.v < CURRENCY_MAX_BLOCK_NUMBER) - tv.short_view = std::string("height: ") + std::to_string(ee.v); - else - tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); - - return true; - } - bool operator()(const etc_tx_details_unlock_time2& ee) - { - tv.type = "unlock_time"; - std::stringstream ss; - ss << "["; - for (auto v : ee.unlock_time_array) - { - ss << " " << v; - } - ss << "]"; - tv.short_view = ss.str(); - - return true; - } - bool operator()(const etc_tx_details_expiration_time& ee) - { - tv.type = "expiration_time"; - if (ee.v < CURRENCY_MAX_BLOCK_NUMBER) - tv.short_view = std::string("height: ") + std::to_string(ee.v); - else - tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); - - return true; - } - bool operator()(const etc_tx_details_flags& ee) - { - tv.type = "details_flags"; - tv.short_view = epee::string_tools::pod_to_hex(ee.v); - return true; - } - bool operator()(const crypto::public_key& ee) - { - tv.type = "pub_key"; - tv.short_view = epee::string_tools::pod_to_hex(ee); - return true; - } - bool operator()(const extra_attachment_info& ee) - { - tv.type = "attachment_info"; - tv.short_view = std::to_string(ee.sz) + " bytes"; - tv.details_view = currency::obj_to_json_str(ee); - return true; - } - bool operator()(const extra_alias_entry& ee) - { - tv.type = "alias_info"; - tv.short_view = ee.m_alias + "-->" + get_account_address_as_str(ee.m_address); - tv.details_view = currency::obj_to_json_str(ee); - - return true; - } - bool operator()(const extra_alias_entry_old& ee) - { - return operator()(static_cast(ee)); - } - bool operator()(const extra_user_data& ee) - { - tv.type = "user_data"; - tv.short_view = std::to_string(ee.buff.size()) + " bytes"; - tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee.buff); - - return true; - } - bool operator()(const extra_padding& ee) - { - tv.type = "extra_padding"; - tv.short_view = std::to_string(ee.buff.size()) + " bytes"; - if (!ee.buff.empty()) - tv.details_view = epee::string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast(&ee.buff[0]), ee.buff.size())); - - return true; - } - bool operator()(const tx_comment& ee) - { - tv.type = "comment"; - tv.short_view = std::to_string(ee.comment.size()) + " bytes(encrypted)"; - tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee.comment); - - return true; - } - bool operator()(const tx_payer& ee) - { - //const tx_payer& ee = boost::get(extra); - tv.type = "payer"; - tv.short_view = "(encrypted)"; - - return true; - } - bool operator()(const tx_payer_old&) - { - tv.type = "payer_old"; - tv.short_view = "(encrypted)"; - - return true; - } - bool operator()(const tx_receiver& ee) - { - //const tx_payer& ee = boost::get(extra); - tv.type = "receiver"; - tv.short_view = "(encrypted)"; - - return true; - } - bool operator()(const tx_receiver_old& ee) - { - tv.type = "receiver_old"; - tv.short_view = "(encrypted)"; - - return true; - } - bool operator()(const tx_derivation_hint& ee) - { - tv.type = "derivation_hint"; - tv.short_view = std::to_string(ee.msg.size()) + " bytes"; - tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee.msg); - - return true; - } - bool operator()(const std::string& ee) - { - tv.type = "string"; - tv.short_view = std::to_string(ee.size()) + " bytes"; - tv.details_view = epee::string_tools::buff_to_hex_nodelimer(ee); - - return true; - } - bool operator()(const etc_tx_flags16_t& dh) - { - tv.type = "FLAGS16"; - tv.short_view = epee::string_tools::pod_to_hex(dh); - tv.details_view = epee::string_tools::pod_to_hex(dh); - - return true; - } - bool operator()(const zarcanum_tx_data_v1& ztxd) - { - tv.type = "zarcanum_tx_data_v1"; - tv.short_view = "fee = " + print_money_brief(ztxd.fee); - tv.details_view = tv.short_view; - return true; - } - bool operator()(const zc_outs_range_proof& rp) - { - tv.type = "zc_outs_range_proof"; - // TODO @#@# - //tv.short_view = "outputs_count = " + std::to_string(rp.outputs_count); - return true; - } - bool operator()(const zc_balance_proof& bp) - { - tv.type = "zc_balance_proof"; - return true; - } - template - bool operator()(const t_type& t_t) - { - tv.type = typeid(t_t).name(); - return true; - } - }; - //------------------------------------------------------------------ - template - bool fill_tx_rpc_payload_items(std::vector& target_vector, const t_container& tc) - { - //handle extra - for (auto& extra : tc) - { - target_vector.push_back(tx_extra_rpc_entry()); - tx_extra_rpc_entry& tv = target_vector.back(); - - rpc_tx_payload_handler vstr(tv); - boost::apply_visitor(vstr, extra); - } - return true; - } //------------------------------------------------------------------ bool fill_tx_rpc_outputs(tx_rpc_extended_info& tei, const transaction& tx, const transaction_chain_entry* ptce) { @@ -3919,28 +3691,7 @@ namespace currency pei_rpc.penalty = (pei_rpc.base_reward + pei_rpc.total_fee) - pei_rpc.summary_reward; return true; } - //--------------------------------------------------------------- - bool 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) - { - //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); - tei.fee = get_tx_fee(tx); - tei.pub_key = epee::string_tools::pod_to_hex(get_tx_pub_key_from_extra(tx)); - tei.timestamp = timestamp; - tei.amount = get_outs_money_amount(tx); - - if (is_short) - return true; - - fill_tx_rpc_inputs(tei, tx); - 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); - return true; - } //------------------------------------------------------------------ void append_per_block_increments_for_tx(const transaction& tx, std::unordered_map& gindices) { diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 8ccf34d5..4b9008a4 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -29,6 +29,9 @@ #include "currency_format_utils_transactions.h" #include "core_runtime_config.h" #include "wallet/wallet_public_structs_defs.h" +#include "bc_attachments_helpers.h" +#include "bc_payments_id_service.h" +#include "bc_offers_service_basic.h" // ------ get_tx_type_definition ------------- @@ -417,8 +420,7 @@ namespace currency update_alias_rpc_details alias_info_to_rpc_update_alias_info(const currency::extra_alias_entry& ai, const std::string& old_address); size_t get_service_attachments_count_in_tx(const transaction& tx); bool fill_tx_rpc_outputs(tx_rpc_extended_info& tei, const transaction& tx, const transaction_chain_entry* ptce); - bool fill_tx_rpc_inputs(tx_rpc_extended_info& tei, const transaction& tx); - bool 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 = false); + bool fill_block_rpc_details(block_rpc_extended_info& pei_rpc, const block_extended_info& bei_chain, const crypto::hash& h); void append_per_block_increments_for_tx(const transaction& tx, std::unordered_map& gindices); std::string get_word_from_timstamp(uint64_t timestamp, bool use_password); @@ -894,5 +896,211 @@ namespace currency const difficulties& b_diff ); + struct rpc_tx_payload_handler : public boost::static_visitor + { + tx_extra_rpc_entry& tv; + rpc_tx_payload_handler(tx_extra_rpc_entry& t) : tv(t) + {} + + bool operator()(const tx_service_attachment& ee) + { + tv.type = "service"; + tv.short_view = ee.service_id + ":" + ee.instruction; + if (ee.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY) + tv.short_view += "(encrypted)"; + else + { + std::string deflated_buff; + const std::string* pfinalbuff = &ee.body; + if (ee.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY) + { + bool r = epee::zlib_helper::unpack(ee.body, deflated_buff); + CHECK_AND_ASSERT_MES(r, false, "Failed to unpack"); + pfinalbuff = &deflated_buff; + } + if (ee.service_id == BC_PAYMENT_ID_SERVICE_ID || ee.service_id == BC_OFFERS_SERVICE_ID) + tv.datails_view = *pfinalbuff; + else + tv.datails_view = "BINARY DATA"; + } + return true; + } + bool operator()(const tx_crypto_checksum& ee) + { + tv.type = "crypto_checksum"; + tv.short_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash); + tv.datails_view = std::string("derivation_hash: ") + epee::string_tools::pod_to_hex(ee.derivation_hash) + "\n" + + "encrypted_key_derivation: " + epee::string_tools::pod_to_hex(ee.encrypted_key_derivation); + + return true; + } + bool operator()(const etc_tx_time& ee) + { + tv.type = "pos_time"; + tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); + return true; + } + bool operator()(const etc_tx_details_unlock_time& ee) + { + tv.type = "unlock_time"; + if (ee.v < CURRENCY_MAX_BLOCK_NUMBER) + tv.short_view = std::string("height: ") + std::to_string(ee.v); + else + tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); + + return true; + } + bool operator()(const etc_tx_details_unlock_time2& ee) + { + tv.type = "unlock_time"; + std::stringstream ss; + ss << "["; + for (auto v : ee.unlock_time_array) + { + ss << " " << v; + } + ss << "]"; + tv.short_view = ss.str(); + + return true; + } + bool operator()(const etc_tx_details_expiration_time& ee) + { + tv.type = "expiration_time"; + if (ee.v < CURRENCY_MAX_BLOCK_NUMBER) + tv.short_view = std::string("height: ") + std::to_string(ee.v); + else + tv.short_view = std::string("timestamp: ") + std::to_string(ee.v) + " " + epee::misc_utils::get_internet_time_str(ee.v); + + return true; + } + bool operator()(const etc_tx_details_flags& ee) + { + tv.type = "details_flags"; + tv.short_view = epee::string_tools::pod_to_hex(ee.v); + return true; + } + bool operator()(const crypto::public_key& ee) + { + tv.type = "pub_key"; + tv.short_view = epee::string_tools::pod_to_hex(ee); + return true; + } + bool operator()(const extra_attachment_info& ee) + { + tv.type = "attachment_info"; + tv.short_view = std::to_string(ee.sz) + " bytes"; + tv.datails_view = currency::obj_to_json_str(ee); + return true; + } + bool operator()(const extra_alias_entry& ee) + { + tv.type = "alias_info"; + tv.short_view = ee.m_alias + "-->" + get_account_address_as_str(ee.m_address); + tv.datails_view = currency::obj_to_json_str(ee); + + return true; + } + bool operator()(const extra_alias_entry_old& ee) + { + return operator()(static_cast(ee)); + } + bool operator()(const extra_user_data& ee) + { + tv.type = "user_data"; + tv.short_view = std::to_string(ee.buff.size()) + " bytes"; + tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee.buff); + + return true; + } + bool operator()(const extra_padding& ee) + { + tv.type = "extra_padding"; + tv.short_view = std::to_string(ee.buff.size()) + " bytes"; + if (!ee.buff.empty()) + tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast(&ee.buff[0]), ee.buff.size())); + + return true; + } + bool operator()(const tx_comment& ee) + { + tv.type = "comment"; + tv.short_view = std::to_string(ee.comment.size()) + " bytes(encrypted)"; + tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee.comment); + + return true; + } + bool operator()(const tx_payer& ee) + { + //const tx_payer& ee = boost::get(extra); + tv.type = "payer"; + tv.short_view = "(encrypted)"; + + return true; + } + bool operator()(const tx_payer_old&) + { + tv.type = "payer_old"; + tv.short_view = "(encrypted)"; + + return true; + } + bool operator()(const tx_receiver& ee) + { + //const tx_payer& ee = boost::get(extra); + tv.type = "receiver"; + tv.short_view = "(encrypted)"; + + return true; + } + bool operator()(const tx_receiver_old& ee) + { + tv.type = "receiver_old"; + tv.short_view = "(encrypted)"; + + return true; + } + bool operator()(const tx_derivation_hint& ee) + { + tv.type = "derivation_hint"; + tv.short_view = std::to_string(ee.msg.size()) + " bytes"; + tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee.msg); + + return true; + } + bool operator()(const std::string& ee) + { + tv.type = "string"; + tv.short_view = std::to_string(ee.size()) + " bytes"; + tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee); + + return true; + } + bool operator()(const etc_tx_flags16_t& dh) + { + tv.type = "FLAGS16"; + tv.short_view = epee::string_tools::pod_to_hex(dh); + tv.datails_view = epee::string_tools::pod_to_hex(dh); + + return true; + } + }; + //------------------------------------------------------------------ + + + template + bool fill_tx_rpc_payload_items(std::vector& target_vector, const t_container& tc) + { + //handle extra + for (auto& extra : tc) + { + target_vector.push_back(tx_extra_rpc_entry()); + tx_extra_rpc_entry& tv = target_vector.back(); + + rpc_tx_payload_handler vstr(tv); + boost::apply_visitor(vstr, extra); + } + return true; + } } // namespace currency diff --git a/src/currency_core/tx_pool.cpp b/src/currency_core/tx_pool.cpp index 61e5a449..8fcca00f 100644 --- a/src/currency_core/tx_pool.cpp +++ b/src/currency_core/tx_pool.cpp @@ -516,7 +516,7 @@ namespace currency txs.push_back(tx_rpc_extended_info()); tx_rpc_extended_info& trei = txs.back(); trei.blob_size = tx_entry.blob_size; - fill_tx_rpc_details(trei, tx_entry.tx, nullptr, h, tx_entry.receive_time, true); + m_blockchain.fill_tx_rpc_details(trei, tx_entry.tx, nullptr, h, tx_entry.receive_time, true); return true; }); @@ -568,7 +568,7 @@ namespace currency txs.push_back(tx_rpc_extended_info()); tx_rpc_extended_info& trei = txs.back(); trei.blob_size = ptei->blob_size; - fill_tx_rpc_details(trei, ptei->tx, nullptr, id, ptei->receive_time, false); + m_blockchain.fill_tx_rpc_details(trei, ptei->tx, nullptr, id, ptei->receive_time, false); } return true; } @@ -605,7 +605,7 @@ namespace currency if (!ptei) return false; - fill_tx_rpc_details(trei, ptei->tx, nullptr, id, ptei->receive_time, false); + m_blockchain.fill_tx_rpc_details(trei, ptei->tx, nullptr, id, ptei->receive_time, false); return true; } //---------------------------------------------------------------------------------