Merge pull request #6214
054b4c7
protocol: request txpool contents when synced (moneromooo-monero)
This commit is contained in:
commit
096e2135dd
@ -1935,6 +1935,12 @@ namespace cryptonote
|
||||
{
|
||||
m_blockchain_storage.flush_invalid_blocks();
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_txpool_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes)
|
||||
{
|
||||
return m_mempool.get_complement(hashes, txes);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::update_blockchain_pruning()
|
||||
{
|
||||
return m_blockchain_storage.update_blockchain_pruning();
|
||||
|
@ -854,6 +854,15 @@ namespace cryptonote
|
||||
*/
|
||||
void flush_invalid_blocks();
|
||||
|
||||
/**
|
||||
* @brief returns the set of transactions in the txpool which are not in the argument
|
||||
*
|
||||
* @param hashes hashes of transactions to exclude from the result
|
||||
*
|
||||
* @return true iff success, false otherwise
|
||||
*/
|
||||
bool get_txpool_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -576,6 +576,39 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::get_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
|
||||
m_blockchain.for_all_txpool_txes([this, &hashes, &txes](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata*) {
|
||||
const auto relay_method = meta.get_relay_method();
|
||||
if (relay_method != relay_method::block && relay_method != relay_method::fluff)
|
||||
return true;
|
||||
const auto i = std::find(hashes.begin(), hashes.end(), txid);
|
||||
if (i == hashes.end())
|
||||
{
|
||||
cryptonote::blobdata bd;
|
||||
try
|
||||
{
|
||||
if (!m_blockchain.get_txpool_tx_blob(txid, bd, cryptonote::relay_category::broadcasted))
|
||||
{
|
||||
MERROR("Failed to get blob for txpool transaction " << txid);
|
||||
return true;
|
||||
}
|
||||
txes.emplace_back(std::move(bd));
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
MERROR("Failed to get blob for txpool transaction " << txid << ": " << e.what());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, false);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
void tx_memory_pool::on_idle()
|
||||
{
|
||||
m_remove_stuck_tx_interval.do_call([this](){return remove_stuck_transactions();});
|
||||
|
@ -441,6 +441,11 @@ namespace cryptonote
|
||||
*/
|
||||
bool get_transaction_info(const crypto::hash &txid, tx_details &td) const;
|
||||
|
||||
/**
|
||||
* @brief get transactions not in the passed set
|
||||
*/
|
||||
bool get_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -354,4 +354,22 @@ namespace cryptonote
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
struct NOTIFY_GET_TXPOOL_COMPLEMENT
|
||||
{
|
||||
const static int ID = BC_COMMANDS_POOL_BASE + 10;
|
||||
|
||||
struct request_t
|
||||
{
|
||||
std::vector<crypto::hash> hashes;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(hashes)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ namespace cryptonote
|
||||
HANDLE_NOTIFY_T2(NOTIFY_RESPONSE_CHAIN_ENTRY, &cryptonote_protocol_handler::handle_response_chain_entry)
|
||||
HANDLE_NOTIFY_T2(NOTIFY_NEW_FLUFFY_BLOCK, &cryptonote_protocol_handler::handle_notify_new_fluffy_block)
|
||||
HANDLE_NOTIFY_T2(NOTIFY_REQUEST_FLUFFY_MISSING_TX, &cryptonote_protocol_handler::handle_request_fluffy_missing_tx)
|
||||
HANDLE_NOTIFY_T2(NOTIFY_GET_TXPOOL_COMPLEMENT, &cryptonote_protocol_handler::handle_notify_get_txpool_complement)
|
||||
END_INVOKE_MAP2()
|
||||
|
||||
bool on_idle();
|
||||
@ -124,6 +125,7 @@ namespace cryptonote
|
||||
int handle_response_chain_entry(int command, NOTIFY_RESPONSE_CHAIN_ENTRY::request& arg, cryptonote_connection_context& context);
|
||||
int handle_notify_new_fluffy_block(int command, NOTIFY_NEW_FLUFFY_BLOCK::request& arg, cryptonote_connection_context& context);
|
||||
int handle_request_fluffy_missing_tx(int command, NOTIFY_REQUEST_FLUFFY_MISSING_TX::request& arg, cryptonote_connection_context& context);
|
||||
int handle_notify_get_txpool_complement(int command, NOTIFY_GET_TXPOOL_COMPLEMENT::request& arg, cryptonote_connection_context& context);
|
||||
|
||||
//----------------- i_bc_protocol_layout ---------------------------------------
|
||||
virtual bool relay_block(NOTIFY_NEW_BLOCK::request& arg, cryptonote_connection_context& exclude_context);
|
||||
@ -144,6 +146,7 @@ namespace cryptonote
|
||||
int try_add_next_blocks(cryptonote_connection_context &context);
|
||||
void notify_new_stripe(cryptonote_connection_context &context, uint32_t stripe);
|
||||
void skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const;
|
||||
bool request_txpool_complement(cryptonote_connection_context &context);
|
||||
|
||||
t_core& m_core;
|
||||
|
||||
@ -153,6 +156,7 @@ namespace cryptonote
|
||||
std::atomic<bool> m_synchronized;
|
||||
std::atomic<bool> m_stopping;
|
||||
std::atomic<bool> m_no_sync;
|
||||
std::atomic<bool> m_ask_for_txpool_complement;
|
||||
boost::mutex m_sync_lock;
|
||||
block_queue m_block_queue;
|
||||
epee::math_helper::once_a_time_seconds<30> m_idle_peer_kicker;
|
||||
|
@ -83,6 +83,7 @@ namespace cryptonote
|
||||
m_p2p(p_net_layout),
|
||||
m_syncronized_connections_count(0),
|
||||
m_synchronized(offline),
|
||||
m_ask_for_txpool_complement(true),
|
||||
m_stopping(false),
|
||||
m_no_sync(false)
|
||||
|
||||
@ -879,6 +880,34 @@ namespace cryptonote
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
int t_cryptonote_protocol_handler<t_core>::handle_notify_get_txpool_complement(int command, NOTIFY_GET_TXPOOL_COMPLEMENT::request& arg, cryptonote_connection_context& context)
|
||||
{
|
||||
MLOG_P2P_MESSAGE("Received NOTIFY_GET_TXPOOL_COMPLEMENT (" << arg.hashes.size() << " txes)");
|
||||
|
||||
std::vector<std::pair<cryptonote::blobdata, block>> local_blocks;
|
||||
std::vector<cryptonote::blobdata> local_txs;
|
||||
|
||||
std::vector<cryptonote::blobdata> txes;
|
||||
if (!m_core.get_txpool_complement(arg.hashes, txes))
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("failed to get txpool complement");
|
||||
return 1;
|
||||
}
|
||||
|
||||
NOTIFY_NEW_TRANSACTIONS::request new_txes;
|
||||
new_txes.txs = std::move(txes);
|
||||
|
||||
MLOG_P2P_MESSAGE
|
||||
(
|
||||
"-->>NOTIFY_NEW_TRANSACTIONS: "
|
||||
<< ", txs.size()=" << new_txes.txs.size()
|
||||
);
|
||||
|
||||
post_notify<NOTIFY_NEW_TRANSACTIONS>(new_txes, context);
|
||||
return 1;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
int t_cryptonote_protocol_handler<t_core>::handle_notify_new_transactions(int command, NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& context)
|
||||
{
|
||||
MLOG_P2P_MESSAGE("Received NOTIFY_NEW_TRANSACTIONS (" << arg.txs.size() << " txes)");
|
||||
@ -2195,6 +2224,27 @@ skip:
|
||||
}
|
||||
m_core.safesyncmode(true);
|
||||
m_p2p->clear_used_stripe_peers();
|
||||
|
||||
// ask for txpool complement from any suitable node if we did not yet
|
||||
val_expected = true;
|
||||
if (m_ask_for_txpool_complement.compare_exchange_strong(val_expected, false))
|
||||
{
|
||||
m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool
|
||||
{
|
||||
if(context.m_state < cryptonote_connection_context::state_synchronizing)
|
||||
{
|
||||
MDEBUG(context << "not ready, ignoring");
|
||||
return true;
|
||||
}
|
||||
if (!request_txpool_complement(context))
|
||||
{
|
||||
MERROR(context << "Failed to request txpool complement");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
@ -2348,6 +2398,21 @@ skip:
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
bool t_cryptonote_protocol_handler<t_core>::request_txpool_complement(cryptonote_connection_context &context)
|
||||
{
|
||||
NOTIFY_GET_TXPOOL_COMPLEMENT::request r = {};
|
||||
if (!m_core.get_pool_transaction_hashes(r.hashes, false))
|
||||
{
|
||||
MERROR("Failed to get txpool hashes");
|
||||
return false;
|
||||
}
|
||||
MLOG_P2P_MESSAGE("-->>NOTIFY_GET_TXPOOL_COMPLEMENT: hashes.size()=" << r.hashes.size() );
|
||||
post_notify<NOTIFY_GET_TXPOOL_COMPLEMENT>(r, context);
|
||||
MLOG_PEER_STATE("requesting txpool complement");
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
std::string t_cryptonote_protocol_handler<t_core>::get_peers_overview() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
@ -2457,7 +2522,10 @@ skip:
|
||||
MINFO("Target height decreasing from " << previous_target << " to " << target);
|
||||
m_core.set_target_blockchain_height(target);
|
||||
if (target == 0 && context.m_state > cryptonote_connection_context::state_before_handshake && !m_stopping)
|
||||
{
|
||||
MCWARNING("global", "monerod is now disconnected from the network");
|
||||
m_ask_for_txpool_complement = true;
|
||||
}
|
||||
}
|
||||
|
||||
m_block_queue.flush_spans(context.m_connection_id, false);
|
||||
|
@ -109,5 +109,7 @@ namespace tests
|
||||
bool pad_transactions() const { return false; }
|
||||
uint32_t get_blockchain_pruning_seed() const { return 0; }
|
||||
bool prune_blockchain(uint32_t pruning_seed) const { return true; }
|
||||
bool get_txpool_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) { return false; }
|
||||
bool get_pool_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes = true) const { return false; }
|
||||
};
|
||||
}
|
||||
|
@ -90,6 +90,8 @@ public:
|
||||
bool prune_blockchain(uint32_t pruning_seed = 0) { return true; }
|
||||
bool is_within_compiled_block_hash_area(uint64_t height) const { return false; }
|
||||
bool has_block_weights(uint64_t height, uint64_t nblocks) const { return false; }
|
||||
bool get_txpool_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) { return false; }
|
||||
bool get_pool_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes = true) const { return false; }
|
||||
void stop() {}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user