1
0
Fork 0
forked from lthn/blockchain

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

This commit is contained in:
sowle 2024-03-26 19:55:34 +01:00
parent 6740a0df28
commit c2fa968835
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
4 changed files with 127 additions and 43 deletions

View file

@ -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<asset_descriptor_operation>& 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<const transaction_chain_entry> 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;
}
//------------------------------------------------------------------

View file

@ -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<asset_descriptor_operation>& 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;

View file

@ -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 <block_hash> | <block_height>");
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 <transaction_hash>");
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 <addr> [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 <transaction hash>" << std::endl;
std::cout << "usage: print_tx <transaction hash>" << 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<crypto::hash> tx_ids;
// tx_ids.push_back(tx_hash);
// std::list<currency::transaction> txs;
// std::list<crypto::hash> 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<currency::tx_service_attachment>(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<currency::tx_service_attachment>(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<std::string>& args)
{
if (args.empty())
{
std::cout << "usage: print_asset_info <asset_id>" << 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<currency::asset_descriptor_operation> 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<std::string>& args)
{
if (args.empty())

View file

@ -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()
};