Skip to content

Commit

Permalink
Merge pull request monero-project#4047
Browse files Browse the repository at this point in the history
41b4bf9 tx_pool: cache check_tx_inputs results (moneromooo-monero)
  • Loading branch information
luigi1111 committed Jul 19, 2018
2 parents 94ed562 + 41b4bf9 commit 5cade94
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
33 changes: 28 additions & 5 deletions src/cryptonote_core/tx_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ namespace cryptonote
crypto::hash max_used_block_id = null_hash;
uint64_t max_used_block_height = 0;
cryptonote::txpool_tx_meta_t meta;
bool ch_inp_res = m_blockchain.check_tx_inputs(tx, max_used_block_height, max_used_block_id, tvc, kept_by_block);
bool ch_inp_res = check_tx_inputs([&tx]()->cryptonote::transaction&{ return tx; }, id, max_used_block_height, max_used_block_id, tvc, kept_by_block);
if(!ch_inp_res)
{
// if the transaction was valid before (kept_by_block), then it
Expand Down Expand Up @@ -893,11 +893,15 @@ namespace cryptonote
//---------------------------------------------------------------------------------
bool tx_memory_pool::on_blockchain_inc(uint64_t new_block_height, const crypto::hash& top_block_id)
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
m_input_cache.clear();
return true;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::on_blockchain_dec(uint64_t new_block_height, const crypto::hash& top_block_id)
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
m_input_cache.clear();
return true;
}
//---------------------------------------------------------------------------------
Expand Down Expand Up @@ -937,7 +941,26 @@ namespace cryptonote
m_transactions_lock.unlock();
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::is_transaction_ready_to_go(txpool_tx_meta_t& txd, const cryptonote::blobdata &txblob, transaction &tx) const
bool tx_memory_pool::check_tx_inputs(const std::function<cryptonote::transaction&(void)> &get_tx, const crypto::hash &txid, uint64_t &max_used_block_height, crypto::hash &max_used_block_id, tx_verification_context &tvc, bool kept_by_block) const
{
if (!kept_by_block)
{
const std::unordered_map<crypto::hash, std::tuple<bool, tx_verification_context, uint64_t, crypto::hash>>::const_iterator i = m_input_cache.find(txid);
if (i != m_input_cache.end())
{
max_used_block_height = std::get<2>(i->second);
max_used_block_id = std::get<3>(i->second);
tvc = std::get<1>(i->second);
return std::get<0>(i->second);
}
}
bool ret = m_blockchain.check_tx_inputs(get_tx(), max_used_block_height, max_used_block_id, tvc, kept_by_block);
if (!kept_by_block)
m_input_cache.insert(std::make_pair(txid, std::make_tuple(ret, tvc, max_used_block_height, max_used_block_id)));
return ret;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const
{
struct transction_parser
{
Expand Down Expand Up @@ -966,7 +989,7 @@ namespace cryptonote
return false;//we already sure that this tx is broken for this height

tx_verification_context tvc;
if(!m_blockchain.check_tx_inputs(lazy_tx(), txd.max_used_block_height, txd.max_used_block_id, tvc))
if(!check_tx_inputs([&lazy_tx]()->cryptonote::transaction&{ return lazy_tx(); }, txid, txd.max_used_block_height, txd.max_used_block_id, tvc))
{
txd.last_failed_height = m_blockchain.get_current_blockchain_height()-1;
txd.last_failed_id = m_blockchain.get_block_id_by_height(txd.last_failed_height);
Expand All @@ -983,7 +1006,7 @@ namespace cryptonote
return false;
//check ring signature again, it is possible (with very small chance) that this transaction become again valid
tx_verification_context tvc;
if(!m_blockchain.check_tx_inputs(lazy_tx(), txd.max_used_block_height, txd.max_used_block_id, tvc))
if(!check_tx_inputs([&lazy_tx]()->cryptonote::transaction&{ return lazy_tx(); }, txid, txd.max_used_block_height, txd.max_used_block_id, tvc))
{
txd.last_failed_height = m_blockchain.get_current_blockchain_height()-1;
txd.last_failed_id = m_blockchain.get_block_id_by_height(txd.last_failed_height);
Expand Down Expand Up @@ -1176,7 +1199,7 @@ namespace cryptonote
bool ready = false;
try
{
ready = is_transaction_ready_to_go(meta, txblob, tx);
ready = is_transaction_ready_to_go(meta, sorted_it->second, txblob, tx);
}
catch (const std::exception &e)
{
Expand Down
8 changes: 7 additions & 1 deletion src/cryptonote_core/tx_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,12 +499,13 @@ namespace cryptonote
* @brief check if a transaction is a valid candidate for inclusion in a block
*
* @param txd the transaction to check (and info about it)
* @param txid the txid of the transaction to check
* @param txblob the transaction blob to check
* @param tx the parsed transaction, if successful
*
* @return true if the transaction is good to go, otherwise false
*/
bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const cryptonote::blobdata &txblob, transaction &tx) const;
bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const;

/**
* @brief mark all transactions double spending the one passed
Expand Down Expand Up @@ -557,6 +558,9 @@ namespace cryptonote
*/
sorted_tx_container::iterator find_tx_in_sorted_container(const crypto::hash& id) const;

//! cache/call Blockchain::check_tx_inputs results
bool check_tx_inputs(const std::function<cryptonote::transaction&(void)> &get_tx, const crypto::hash &txid, uint64_t &max_used_block_height, crypto::hash &max_used_block_id, tx_verification_context &tvc, bool kept_by_block = false) const;

//! transactions which are unlikely to be included in blocks
/*! These transactions are kept in RAM in case they *are* included
* in a block eventually, but this container is not saved to disk.
Expand All @@ -567,6 +571,8 @@ namespace cryptonote

size_t m_txpool_max_size;
size_t m_txpool_size;

mutable std::unordered_map<crypto::hash, std::tuple<bool, tx_verification_context, uint64_t, crypto::hash>> m_input_cache;
};
}

Expand Down

0 comments on commit 5cade94

Please sign in to comment.