daemon: include nonce to txid map in print_pool

This commit is contained in:
Crypto City 2020-10-16 18:24:50 +00:00
parent 110e1d227e
commit cb353a875d
8 changed files with 78 additions and 17 deletions

View File

@ -1811,9 +1811,9 @@ namespace cryptonote
return spent.front();
}
//-----------------------------------------------------------------------------------------------
bool core::get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, bool include_sensitive_data) const
bool core::get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, std::vector<used_nonce_info> &used_nonces, bool include_sensitive_data) const
{
return m_mempool.get_transactions_and_spent_keys_info(tx_infos, key_image_infos, include_sensitive_data);
return m_mempool.get_transactions_and_spent_keys_info(tx_infos, key_image_infos, used_nonces, include_sensitive_data);
}
//-----------------------------------------------------------------------------------------------
bool core::get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos) const

View File

@ -506,7 +506,7 @@ namespace cryptonote
*
* @note see tx_memory_pool::get_pool_transactions_and_spent_keys_info
*/
bool get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, bool include_sensitive_txes = false) const;
bool get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, std::vector<used_nonce_info> &used_nonces, bool include_sensitive_txes = false) const;
/**
* @copydoc tx_memory_pool::get_pool_for_rpc

View File

@ -1665,7 +1665,7 @@ if (m_blockchain.get_db().height() > 10500)
}
//------------------------------------------------------------------
//TODO: investigate whether boolean return is appropriate
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, bool include_sensitive_data) const
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, std::vector<used_nonce_info> &used_nonces, bool include_sensitive_data) const
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
@ -1673,7 +1673,8 @@ if (m_blockchain.get_db().height() > 10500)
const size_t count = m_blockchain.get_txpool_tx_count(include_sensitive_data);
tx_infos.reserve(count);
key_image_infos.reserve(count);
m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos, include_sensitive_data](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){
used_nonces.reserve(count);
m_blockchain.for_all_txpool_txes([&tx_infos, include_sensitive_data](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){
tx_info txi;
txi.id_hash = epee::string_tools::pod_to_hex(txid);
txi.tx_blob = *bd;
@ -1728,6 +1729,21 @@ if (m_blockchain.get_db().height() > 10500)
if (!ki.txs_hashes.empty())
key_image_infos.push_back(std::move(ki));
}
for (const cc_nonces_container::value_type& enn : m_used_cc_nonces) {
const uint64_t nonce = enn.first;
const std::unordered_set<crypto::hash>& used_nonce_set = enn.second;
used_nonce_info ni;
ni.nonce = nonce;
for (const crypto::hash& tx_id_hash : used_nonce_set)
{
if (m_blockchain.txpool_tx_matches_category(tx_id_hash, category))
ni.txs_hashes.push_back(epee::string_tools::pod_to_hex(tx_id_hash));
}
// Only return key images for which we have at least one tx that we can show for them
if (!ni.txs_hashes.empty())
used_nonces.push_back(std::move(ni));
}
return true;
}
//---------------------------------------------------------------------------------

View File

@ -283,12 +283,13 @@ namespace cryptonote
*
* @param tx_infos return-by-reference the transactions' information
* @param key_image_infos return-by-reference the spent key images' information
* @param used_nonces return-by-reference the used nonces' information
* @param include_sensitive_data return stempool, anonymity-pool, and unrelayed
* txes and fields that are sensitive to the node privacy
*
* @return true
*/
bool get_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, bool include_sensitive_data = false) const;
bool get_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, std::vector<used_nonce_info> &used_nonces, bool include_sensitive_data = false) const;
/**
* @brief get information about all transactions and key images in the pool

View File

@ -1187,10 +1187,6 @@ bool t_rpc_command_executor::print_transaction_pool_long() {
<< "cc_nonce: " << tx_info.cc_nonce << " (" << (void*)tx_info.cc_nonce << ")" << std::endl
<< "cc_parent: " << tx_info.cc_parent << " (" << (void*)tx_info.cc_parent << ")" << 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())
{
@ -1221,6 +1217,35 @@ bool t_rpc_command_executor::print_transaction_pool_long() {
tools::msg_writer() << "WARNING: Inconsistent pool state - no transactions";
}
}
if (! res.used_nonces.empty())
{
tools::msg_writer() << ""; // one newline
tools::msg_writer() << "Used nonces: ";
for (const cryptonote::used_nonce_info& ninfo : res.used_nonces)
{
tools::msg_writer() << "nonce: " << ninfo.nonce;
if (ninfo.txs_hashes.size() == 1)
{
tools::msg_writer() << " tx: " << ninfo.txs_hashes[0];
}
else if (ninfo.txs_hashes.size() == 0)
{
tools::msg_writer() << " WARNING: used nonce has no txs associated";
}
else
{
tools::msg_writer() << " NOTE: nonce for multiple txs: " << ninfo.txs_hashes.size();
for (const std::string& tx_id : ninfo.txs_hashes)
{
tools::msg_writer() << " tx: " << tx_id;
}
}
}
if (res.transactions.empty())
{
tools::msg_writer() << "WARNING: Inconsistent pool state - no transactions";
}
}
return true;
}

View File

@ -876,7 +876,8 @@ namespace cryptonote
{
std::vector<tx_info> pool_tx_info;
std::vector<spent_key_image_info> pool_key_image_info;
bool r = m_core.get_pool_transactions_and_spent_keys_info(pool_tx_info, pool_key_image_info, !request_has_rpc_origin || !restricted);
std::vector<used_nonce_info> pool_used_onnce_info;
bool r = m_core.get_pool_transactions_and_spent_keys_info(pool_tx_info, pool_key_image_info, pool_used_onnce_info, !request_has_rpc_origin || !restricted);
if(r)
{
// sort to match original request
@ -1130,7 +1131,8 @@ namespace cryptonote
// check the pool too
std::vector<cryptonote::tx_info> txs;
std::vector<cryptonote::spent_key_image_info> ki;
r = m_core.get_pool_transactions_and_spent_keys_info(txs, ki, !request_has_rpc_origin || !restricted);
std::vector<cryptonote::used_nonce_info> nonces;
r = m_core.get_pool_transactions_and_spent_keys_info(txs, ki, nonces, !request_has_rpc_origin || !restricted);
if(!r)
{
res.status = "Failed";
@ -1592,7 +1594,7 @@ namespace cryptonote
if (n_txes > 0)
{
CHECK_PAYMENT_SAME_TS(req, res, n_txes * COST_PER_TX);
m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, allow_sensitive);
m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, res.used_nonces, allow_sensitive);
for (tx_info& txi : res.transactions)
txi.tx_blob = epee::string_tools::buff_to_hex_nodelimer(txi.tx_blob);
}

View File

@ -1545,6 +1545,17 @@ namespace cryptonote
END_KV_SERIALIZE_MAP()
};
struct used_nonce_info
{
uint64_t nonce;
std::vector<std::string> txs_hashes;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(nonce)
KV_SERIALIZE(txs_hashes)
END_KV_SERIALIZE_MAP()
};
struct COMMAND_RPC_GET_TRANSACTION_POOL
{
struct request_t: public rpc_access_request_base
@ -1559,11 +1570,13 @@ namespace cryptonote
{
std::vector<tx_info> transactions;
std::vector<spent_key_image_info> spent_key_images;
std::vector<used_nonce_info> used_nonces;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_PARENT(rpc_access_response_base)
KV_SERIALIZE(transactions)
KV_SERIALIZE(spent_key_images)
KV_SERIALIZE(used_nonces)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;

View File

@ -68,7 +68,8 @@ bool txpool_base::check_txpool_spent_keys(cryptonote::core& c, size_t /*ev_index
{
std::vector<cryptonote::tx_info> infos{};
std::vector<cryptonote::spent_key_image_info> key_images{};
if (!c.get_pool_transactions_and_spent_keys_info(infos, key_images) || infos.size() != m_broadcasted_tx_count || key_images.size() != m_broadcasted_tx_count)
std::vector<cryptonote::used_nonce_info> used_nonces{};
if (!c.get_pool_transactions_and_spent_keys_info(infos, key_images, used_nonces) || infos.size() != m_broadcasted_tx_count || key_images.size() != m_broadcasted_tx_count)
{
MERROR("Failed broadcasted spent keys retrieval - Expected Broadcasted Count: " << m_broadcasted_tx_count << " Actual Info Count: " << infos.size() << " Actual Key Image Count: " << key_images.size());
return false;
@ -76,7 +77,8 @@ bool txpool_base::check_txpool_spent_keys(cryptonote::core& c, size_t /*ev_index
infos.clear();
key_images.clear();
if (!c.get_pool_transactions_and_spent_keys_info(infos, key_images, false) || infos.size() != m_broadcasted_tx_count || key_images.size() != m_broadcasted_tx_count)
used_nonces.clear();
if (!c.get_pool_transactions_and_spent_keys_info(infos, key_images, used_nonces, false) || infos.size() != m_broadcasted_tx_count || key_images.size() != m_broadcasted_tx_count)
{
MERROR("Failed broadcasted spent keys retrieval - Expected Broadcasted Count: " << m_broadcasted_tx_count << " Actual Info Count: " << infos.size() << " Actual Key Image Count: " << key_images.size());
return false;
@ -84,7 +86,8 @@ bool txpool_base::check_txpool_spent_keys(cryptonote::core& c, size_t /*ev_index
infos.clear();
key_images.clear();
if (!c.get_pool_transactions_and_spent_keys_info(infos, key_images, true) || infos.size() != m_all_tx_count || key_images.size() != m_all_tx_count)
used_nonces.clear();
if (!c.get_pool_transactions_and_spent_keys_info(infos, key_images, used_nonces, true) || infos.size() != m_all_tx_count || key_images.size() != m_all_tx_count)
{
MERROR("Failed all spent keys retrieval - Expected All Count: " << m_all_tx_count << " Actual Info Count: " << infos.size() << " Actual Key Image Count: " << key_images.size());
return false;
@ -248,7 +251,8 @@ bool txpool_double_spend_base::check_changed(cryptonote::core& c, const size_t e
{
std::vector<cryptonote::tx_info> infos{};
std::vector<cryptonote::spent_key_image_info> key_images{};
if (!c.get_pool_transactions_and_spent_keys_info(infos, key_images, true) || infos.size() != m_all_hashes.size())
std::vector<cryptonote::used_nonce_info> used_nonces{};
if (!c.get_pool_transactions_and_spent_keys_info(infos, key_images, used_nonces, true) || infos.size() != m_all_hashes.size())
{
MERROR("Unable to retrieve all txpool metadata");
return false;