Merge pull request #269
641d824
Keep memory pool consistent when stuck tx removed (warptangent)b76857f
Add mempool output to daemon via command and RPC (warptangent)
This commit is contained in:
commit
8005a0c7a1
7 changed files with 108 additions and 17 deletions
|
@ -658,6 +658,11 @@ namespace cryptonote
|
||||||
return true;
|
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)
|
bool core::get_short_chain_history(std::list<crypto::hash>& ids)
|
||||||
{
|
{
|
||||||
return m_blockchain_storage.get_short_chain_history(ids);
|
return m_blockchain_storage.get_short_chain_history(ids);
|
||||||
|
|
|
@ -108,6 +108,7 @@ namespace cryptonote
|
||||||
void set_enforce_dns_checkpoints(bool enforce_dns);
|
void set_enforce_dns_checkpoints(bool enforce_dns);
|
||||||
|
|
||||||
bool get_pool_transactions(std::list<transaction>& txs);
|
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_pool_transactions_count();
|
||||||
size_t get_blockchain_total_transactions();
|
size_t get_blockchain_total_transactions();
|
||||||
//bool get_outs(uint64_t amount, std::list<crypto::public_key>& pkeys);
|
//bool get_outs(uint64_t amount, std::list<crypto::public_key>& pkeys);
|
||||||
|
|
|
@ -257,6 +257,7 @@ namespace cryptonote
|
||||||
(tx_age > CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME && it->second.kept_by_block) )
|
(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 );
|
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++);
|
m_transactions.erase(it++);
|
||||||
}else
|
}else
|
||||||
++it;
|
++it;
|
||||||
|
@ -276,6 +277,40 @@ namespace cryptonote
|
||||||
BOOST_FOREACH(const auto& tx_vt, m_transactions)
|
BOOST_FOREACH(const auto& tx_vt, m_transactions)
|
||||||
txs.push_back(tx_vt.second.tx);
|
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
|
bool tx_memory_pool::get_transaction(const crypto::hash& id, transaction& tx) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "cryptonote_basic_impl.h"
|
#include "cryptonote_basic_impl.h"
|
||||||
#include "verification_context.h"
|
#include "verification_context.h"
|
||||||
#include "crypto/hash.h"
|
#include "crypto/hash.h"
|
||||||
|
#include "rpc/core_rpc_server_commands_defs.h"
|
||||||
|
|
||||||
namespace cryptonote
|
namespace cryptonote
|
||||||
{
|
{
|
||||||
|
@ -81,6 +82,7 @@ namespace cryptonote
|
||||||
bool deinit();
|
bool deinit();
|
||||||
bool fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee);
|
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;
|
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;
|
bool get_transaction(const crypto::hash& h, transaction& tx) const;
|
||||||
size_t get_transactions_count() const;
|
size_t get_transactions_count() const;
|
||||||
std::string print_pool(bool short_format) const;
|
std::string print_pool(bool short_format) const;
|
||||||
|
|
|
@ -523,21 +523,59 @@ 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;
|
tools::msg_writer() << "Pool is empty" << std::endl;
|
||||||
}
|
}
|
||||||
|
if (! res.transactions.empty())
|
||||||
|
{
|
||||||
|
tools::msg_writer() << "Transactions: ";
|
||||||
for (auto & tx_info : res.transactions)
|
for (auto & tx_info : res.transactions)
|
||||||
{
|
{
|
||||||
tools::msg_writer() << "id: " << tx_info.id_hash << std::endl
|
tools::msg_writer() << "id: " << tx_info.id_hash << std::endl
|
||||||
|
<< tx_info.tx_json << std::endl
|
||||||
<< "blob_size: " << tx_info.blob_size << std::endl
|
<< "blob_size: " << tx_info.blob_size << std::endl
|
||||||
<< "fee: " << tx_info.fee << std::endl
|
<< "fee: " << cryptonote::print_money(tx_info.fee) << std::endl
|
||||||
<< "kept_by_block: " << tx_info.kept_by_block << 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_height: " << tx_info.max_used_block_height << std::endl
|
||||||
<< "max_used_block_id: " << tx_info.max_used_block_id_hash << 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_height: " << tx_info.last_failed_height << std::endl
|
||||||
<< "last_failed_id: " << tx_info.last_failed_id_hash << 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -571,10 +609,9 @@ bool t_rpc_command_executor::print_transaction_pool_short() {
|
||||||
for (auto & tx_info : res.transactions)
|
for (auto & tx_info : res.transactions)
|
||||||
{
|
{
|
||||||
tools::msg_writer() << "id: " << tx_info.id_hash << std::endl
|
tools::msg_writer() << "id: " << tx_info.id_hash << std::endl
|
||||||
<< tx_info.tx_json << std::endl
|
|
||||||
<< "blob_size: " << tx_info.blob_size << std::endl
|
<< "blob_size: " << tx_info.blob_size << std::endl
|
||||||
<< "fee: " << tx_info.fee << std::endl
|
<< "fee: " << cryptonote::print_money(tx_info.fee) << std::endl
|
||||||
<< "kept_by_block: " << tx_info.kept_by_block << 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_height: " << tx_info.max_used_block_height << std::endl
|
||||||
<< "max_used_block_id: " << tx_info.max_used_block_id_hash << 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_height: " << tx_info.last_failed_height << std::endl
|
||||||
|
|
|
@ -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)
|
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();
|
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;
|
res.status = CORE_RPC_STATUS_OK;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -620,6 +620,17 @@ namespace cryptonote
|
||||||
END_KV_SERIALIZE_MAP()
|
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 COMMAND_RPC_GET_TRANSACTION_POOL
|
||||||
{
|
{
|
||||||
struct request
|
struct request
|
||||||
|
@ -632,10 +643,12 @@ namespace cryptonote
|
||||||
{
|
{
|
||||||
std::string status;
|
std::string status;
|
||||||
std::vector<tx_info> transactions;
|
std::vector<tx_info> transactions;
|
||||||
|
std::vector<spent_key_image_info> spent_key_images;
|
||||||
|
|
||||||
BEGIN_KV_SERIALIZE_MAP()
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
KV_SERIALIZE(status)
|
KV_SERIALIZE(status)
|
||||||
KV_SERIALIZE(transactions)
|
KV_SERIALIZE(transactions)
|
||||||
|
KV_SERIALIZE(spent_key_images)
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue