Skip to content

Commit

Permalink
Merge pull request #269
Browse files Browse the repository at this point in the history
641d824 Keep memory pool consistent when stuck tx removed (warptangent)
b76857f Add mempool output to daemon via command and RPC (warptangent)
  • Loading branch information
fluffypony committed May 6, 2015
2 parents 9598a39 + 641d824 commit 8005a0c
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 17 deletions.
5 changes: 5 additions & 0 deletions src/cryptonote_core/cryptonote_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,11 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
bool core::get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos) const
{
return m_mempool.get_transactions_and_spent_keys_info(tx_infos, key_image_infos);
}
//-----------------------------------------------------------------------------------------------
bool core::get_short_chain_history(std::list<crypto::hash>& ids)
{
return m_blockchain_storage.get_short_chain_history(ids);
Expand Down
1 change: 1 addition & 0 deletions src/cryptonote_core/cryptonote_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ namespace cryptonote
void set_enforce_dns_checkpoints(bool enforce_dns);

bool get_pool_transactions(std::list<transaction>& txs);
bool get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos) const;
size_t get_pool_transactions_count();
size_t get_blockchain_total_transactions();
//bool get_outs(uint64_t amount, std::list<crypto::public_key>& pkeys);
Expand Down
35 changes: 35 additions & 0 deletions src/cryptonote_core/tx_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ namespace cryptonote
(tx_age > CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME && it->second.kept_by_block) )
{
LOG_PRINT_L1("Tx " << it->first << " removed from tx pool due to outdated, age: " << tx_age );
remove_transaction_keyimages(it->second.tx);
m_transactions.erase(it++);
}else
++it;
Expand All @@ -276,6 +277,40 @@ namespace cryptonote
BOOST_FOREACH(const auto& tx_vt, m_transactions)
txs.push_back(tx_vt.second.tx);
}
//------------------------------------------------------------------
bool tx_memory_pool::get_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos) const
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
for (const auto& tx_vt : m_transactions)
{
tx_info txi;
const tx_details& txd = tx_vt.second;
txi.id_hash = epee::string_tools::pod_to_hex(tx_vt.first);
txi.tx_json = obj_to_json_str(*const_cast<transaction*>(&txd.tx));
txi.blob_size = txd.blob_size;
txi.fee = txd.fee;
txi.kept_by_block = txd.kept_by_block;
txi.max_used_block_height = txd.max_used_block_height;
txi.max_used_block_id_hash = epee::string_tools::pod_to_hex(txd.max_used_block_id);
txi.last_failed_height = txd.last_failed_height;
txi.last_failed_id_hash = epee::string_tools::pod_to_hex(txd.last_failed_id);
txi.receive_time = txd.receive_time;
tx_infos.push_back(txi);
}

for (const key_images_container::value_type& kee : m_spent_key_images) {
const crypto::key_image& k_image = kee.first;
const std::unordered_set<crypto::hash>& kei_image_set = kee.second;
spent_key_image_info ki;
ki.id_hash = epee::string_tools::pod_to_hex(k_image);
for (const crypto::hash& tx_id_hash : kei_image_set)
{
ki.txs_hashes.push_back(epee::string_tools::pod_to_hex(tx_id_hash));
}
key_image_infos.push_back(ki);
}
return true;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::get_transaction(const crypto::hash& id, transaction& tx) const
{
Expand Down
2 changes: 2 additions & 0 deletions src/cryptonote_core/tx_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "cryptonote_basic_impl.h"
#include "verification_context.h"
#include "crypto/hash.h"
#include "rpc/core_rpc_server_commands_defs.h"

namespace cryptonote
{
Expand Down Expand Up @@ -81,6 +82,7 @@ namespace cryptonote
bool deinit();
bool fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee);
void get_transactions(std::list<transaction>& txs) const;
bool get_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos) const;
bool get_transaction(const crypto::hash& h, transaction& tx) const;
size_t get_transactions_count() const;
std::string print_pool(bool short_format) const;
Expand Down
63 changes: 50 additions & 13 deletions src/daemon/rpc_command_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,20 +523,58 @@ bool t_rpc_command_executor::print_transaction_pool_long() {
}
}

if (res.transactions.empty())
if (res.transactions.empty() && res.spent_key_images.empty())
{
tools::msg_writer() << "Pool is empty" << std::endl;
}
for (auto & tx_info : res.transactions)
if (! res.transactions.empty())
{
tools::msg_writer() << "id: " << tx_info.id_hash << std::endl
<< "blob_size: " << tx_info.blob_size << std::endl
<< "fee: " << tx_info.fee << std::endl
<< "kept_by_block: " << tx_info.kept_by_block << std::endl
<< "max_used_block_height: " << tx_info.max_used_block_height << std::endl
<< "max_used_block_id: " << tx_info.max_used_block_id_hash << std::endl
<< "last_failed_height: " << tx_info.last_failed_height << std::endl
<< "last_failed_id: " << tx_info.last_failed_id_hash << std::endl;
tools::msg_writer() << "Transactions: ";
for (auto & tx_info : res.transactions)
{
tools::msg_writer() << "id: " << tx_info.id_hash << std::endl
<< tx_info.tx_json << std::endl
<< "blob_size: " << tx_info.blob_size << std::endl
<< "fee: " << cryptonote::print_money(tx_info.fee) << std::endl
<< "kept_by_block: " << (tx_info.kept_by_block ? 'T' : 'F') << std::endl
<< "max_used_block_height: " << tx_info.max_used_block_height << std::endl
<< "max_used_block_id: " << tx_info.max_used_block_id_hash << std::endl
<< "last_failed_height: " << tx_info.last_failed_height << std::endl
<< "last_failed_id: " << tx_info.last_failed_id_hash << std::endl;
}
if (res.spent_key_images.empty())
{
tools::msg_writer() << "WARNING: Inconsistent pool state - no spent key images";
}
}
if (! res.spent_key_images.empty())
{
tools::msg_writer() << ""; // one newline
tools::msg_writer() << "Spent key images: ";
for (const cryptonote::spent_key_image_info& kinfo : res.spent_key_images)
{
tools::msg_writer() << "key image: " << kinfo.id_hash;
if (kinfo.txs_hashes.size() == 1)
{
tools::msg_writer() << " tx: " << kinfo.txs_hashes[0];
}
else if (kinfo.txs_hashes.size() == 0)
{
tools::msg_writer() << " WARNING: spent key image has no txs associated";
}
else
{
tools::msg_writer() << " NOTE: key image for multiple txs: " << kinfo.txs_hashes.size();
for (const std::string& tx_id : kinfo.txs_hashes)
{
tools::msg_writer() << " tx: " << tx_id;
}
}
}
if (res.transactions.empty())
{
tools::msg_writer() << "WARNING: Inconsistent pool state - no transactions";
}
}

return true;
Expand Down Expand Up @@ -571,10 +609,9 @@ bool t_rpc_command_executor::print_transaction_pool_short() {
for (auto & tx_info : res.transactions)
{
tools::msg_writer() << "id: " << tx_info.id_hash << std::endl
<< tx_info.tx_json << std::endl
<< "blob_size: " << tx_info.blob_size << std::endl
<< "fee: " << tx_info.fee << std::endl
<< "kept_by_block: " << tx_info.kept_by_block << std::endl
<< "fee: " << cryptonote::print_money(tx_info.fee) << std::endl
<< "kept_by_block: " << (tx_info.kept_by_block ? 'T' : 'F') << std::endl
<< "max_used_block_height: " << tx_info.max_used_block_height << std::endl
<< "max_used_block_id: " << tx_info.max_used_block_id_hash << std::endl
<< "last_failed_height: " << tx_info.last_failed_height << std::endl
Expand Down
4 changes: 1 addition & 3 deletions src/rpc/core_rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,8 @@ 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)
{
/*
CHECK_CORE_BUSY();
res.transactions = m_core.transaction_pool_info();
*/
m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images);
res.status = CORE_RPC_STATUS_OK;
return true;
}
Expand Down
15 changes: 14 additions & 1 deletion src/rpc/core_rpc_server_commands_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,18 @@ namespace cryptonote
KV_SERIALIZE(receive_time)
END_KV_SERIALIZE_MAP()
};


struct spent_key_image_info
{
std::string id_hash;
std::vector<std::string> txs_hashes;

BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(id_hash)
KV_SERIALIZE(txs_hashes)
END_KV_SERIALIZE_MAP()
};

struct COMMAND_RPC_GET_TRANSACTION_POOL
{
struct request
Expand All @@ -632,10 +643,12 @@ namespace cryptonote
{
std::string status;
std::vector<tx_info> transactions;
std::vector<spent_key_image_info> spent_key_images;

BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
KV_SERIALIZE(transactions)
KV_SERIALIZE(spent_key_images)
END_KV_SERIALIZE_MAP()
};
};
Expand Down

0 comments on commit 8005a0c

Please sign in to comment.