diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 2609fc13e..fdbb25bde 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -502,6 +502,11 @@ namespace cryptonote return m_mempool.print_pool(short_format); } //----------------------------------------------------------------------------------------------- + void core::each_transaction(std::function callback) + { + m_mempool.each_transaction(callback); + } + //----------------------------------------------------------------------------------------------- bool core::update_miner_block_template() { m_miner.on_block_chain_update(); diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 1f1b6eec6..b9f2da1e7 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -88,6 +88,8 @@ namespace cryptonote void print_blockchain(uint64_t start_index, uint64_t end_index); void print_blockchain_index(); std::string print_pool(bool short_format); + void each_transaction(std::function callback); + void print_blockchain_outs(const std::string& file); void on_synchronized(); diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index ce1bc1ad2..6e66f0351 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -374,6 +374,16 @@ namespace cryptonote return ss.str(); } //--------------------------------------------------------------------------------- + void tx_memory_pool::each_transaction(std::function callback) + { + CRITICAL_REGION_LOCAL(m_transactions_lock); + BOOST_FOREACH(transactions_container::value_type& txe, m_transactions) + { + tx_details& details = txe.second; + callback(details); + } + } + //--------------------------------------------------------------------------------- bool tx_memory_pool::fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee) { // Warning: This function takes already_generated_ diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 649af41a3..0fc4c6803 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,21 @@ namespace cryptonote { public: tx_memory_pool(blockchain_storage& bchs); + + struct tx_details + { + transaction tx; + size_t blob_size; + uint64_t fee; + crypto::hash max_used_block_id; + uint64_t max_used_block_height; + bool kept_by_block; + // + uint64_t last_failed_height; + crypto::hash last_failed_id; + time_t receive_time; + }; + bool add_tx(const transaction &tx, const crypto::hash &id, size_t blob_size, tx_verification_context& tvc, bool keeped_by_block); bool add_tx(const transaction &tx, tx_verification_context& tvc, bool keeped_by_block); //gets tx and remove it from pool @@ -57,6 +73,7 @@ namespace cryptonote bool have_key_images(const std::unordered_set& kic, const transaction& tx); bool append_key_images(std::unordered_set& kic, const transaction& tx); std::string print_pool(bool short_format); + void each_transaction(std::function callback); /*bool flush_pool(const std::strig& folder); bool inflate_pool(const std::strig& folder);*/ @@ -73,20 +90,6 @@ namespace cryptonote a & m_spent_key_images; } - struct tx_details - { - transaction tx; - size_t blob_size; - uint64_t fee; - crypto::hash max_used_block_id; - uint64_t max_used_block_height; - bool kept_by_block; - // - uint64_t last_failed_height; - crypto::hash last_failed_id; - time_t receive_time; - }; - private: bool remove_stuck_transactions(); bool is_transaction_ready_to_go(tx_details& txd); diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index b15c8d6b0..d4631edba 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -346,6 +346,7 @@ namespace cryptonote return false; } } + //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_set_log_level(const COMMAND_RPC_SET_LOG_LEVEL::request& req, COMMAND_RPC_SET_LOG_LEVEL::response& res, connection_context& cntx) { if (req.level < LOG_LEVEL_MIN || req.level > LOG_LEVEL_MAX) @@ -360,6 +361,25 @@ namespace cryptonote } } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res, connection_context& cntx) + { + CHECK_CORE_BUSY(); + m_core.each_transaction([&res](tx_memory_pool::tx_details & details) { + res.transactions.emplace_back( + obj_to_json_str(details.tx) + , details.blob_size + , details.fee + , details.max_used_block_id + , details.max_used_block_height + , details.kept_by_block + , details.last_failed_height + , details.last_failed_id + , details.receive_time + ); + }); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res, connection_context& cntx) { CHECK_CORE_BUSY(); diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index eda29f7d8..2167f9b3a 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -49,6 +49,7 @@ namespace cryptonote MAP_URI_AUTO_JON2("/get_peer_list", on_get_peer_list, COMMAND_RPC_GET_PEER_LIST) MAP_URI_AUTO_JON2("/set_log_hash_rate", on_set_log_hash_rate, COMMAND_RPC_SET_LOG_HASH_RATE) MAP_URI_AUTO_JON2("/set_log_level", on_set_log_level, COMMAND_RPC_SET_LOG_LEVEL) + MAP_URI_AUTO_JON2("/get_transaction_pool", on_get_transaction_pool, COMMAND_RPC_GET_TRANSACTION_POOL) BEGIN_JSON_RPC_MAP("/json_rpc") MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT) MAP_JON_RPC_WE("on_getblockhash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH) @@ -74,6 +75,7 @@ namespace cryptonote bool on_get_peer_list(const COMMAND_RPC_GET_PEER_LIST::request& req, COMMAND_RPC_GET_PEER_LIST::response& res, connection_context& cntx); bool on_set_log_hash_rate(const COMMAND_RPC_SET_LOG_HASH_RATE::request& req, COMMAND_RPC_SET_LOG_HASH_RATE::response& res, connection_context& cntx); bool on_set_log_level(const COMMAND_RPC_SET_LOG_LEVEL::request& req, COMMAND_RPC_SET_LOG_LEVEL::response& res, connection_context& cntx); + bool on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res, connection_context& cntx); //json_rpc bool on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res, connection_context& cntx); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 2048e087f..35ab84eb7 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -559,5 +559,66 @@ namespace cryptonote END_KV_SERIALIZE_MAP() }; }; + + struct tx_info + { + std::string tx_json; + size_t blob_size; + uint64_t fee; + crypto::hash max_used_block_id; + uint64_t max_used_block_height; + bool kept_by_block; + uint64_t last_failed_height; + crypto::hash last_failed_id; + time_t receive_time; + + tx_info() = default; + + tx_info(std::string tx_json, size_t blob_size, uint64_t fee + , crypto::hash max_used_block_id, uint64_t max_used_block_height + , bool kept_by_block, uint64_t last_failed_height + , crypto::hash last_failed_id, time_t receive_time + ) + : tx_json(std::move(tx_json)) + , blob_size(blob_size) + , fee(fee) + , max_used_block_id(std::move(max_used_block_id)) + , kept_by_block(kept_by_block) + , last_failed_height(last_failed_height) + , last_failed_id(std::move(last_failed_id)) + , receive_time(receive_time) + {} + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_json) + KV_SERIALIZE(blob_size) + KV_SERIALIZE(fee) + KV_SERIALIZE_VAL_POD_AS_BLOB(max_used_block_id) + KV_SERIALIZE(max_used_block_height) + KV_SERIALIZE(kept_by_block) + KV_SERIALIZE(last_failed_height) + KV_SERIALIZE_VAL_POD_AS_BLOB(last_failed_id) + KV_SERIALIZE(receive_time) + END_KV_SERIALIZE_MAP() + }; + + struct COMMAND_RPC_GET_TRANSACTION_POOL + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + std::vector transactions; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(transactions) + END_KV_SERIALIZE_MAP() + }; + }; }