aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_protocol/cryptonote_protocol_handler.inl
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_protocol/cryptonote_protocol_handler.inl')
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl96
1 files changed, 79 insertions, 17 deletions
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index 61a211094..9d52935f1 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -2,7 +2,7 @@
/// @author rfree (current maintainer/user in monero.cc project - most of code is from CryptoNote)
/// @brief This is the original cryptonote protocol network-events handler, modified by us
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
@@ -226,7 +226,7 @@ namespace cryptonote
cnx.host = cntxt.m_remote_address.host_str();
cnx.ip = "";
cnx.port = "";
- if (cntxt.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::ID)
+ if (cntxt.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
{
cnx.ip = cnx.host;
cnx.port = std::to_string(cntxt.m_remote_address.as<epee::net_utils::ipv4_network_address>().port());
@@ -268,6 +268,7 @@ namespace cryptonote
cnx.current_upload = cntxt.m_current_speed_up / 1024;
cnx.connection_id = epee::string_tools::pod_to_hex(cntxt.m_connection_id);
+ cnx.ssl = cntxt.m_ssl;
cnx.height = cntxt.m_remote_blockchain_height;
cnx.pruning_seed = cntxt.m_pruning_seed;
@@ -333,6 +334,13 @@ namespace cryptonote
return true;
}
+ // No chain synchronization over hidden networks (tor, i2p, etc.)
+ if(context.m_remote_address.get_zone() != epee::net_utils::zone::public_)
+ {
+ context.m_state = cryptonote_connection_context::state_normal;
+ return true;
+ }
+
if (hshd.current_height > target)
{
/* As I don't know if accessing hshd from core could be a good practice,
@@ -410,7 +418,14 @@ namespace cryptonote
m_core.pause_mine();
std::vector<block_complete_entry> blocks;
blocks.push_back(arg.b);
- m_core.prepare_handle_incoming_blocks(blocks);
+ std::vector<block> pblocks;
+ if (!m_core.prepare_handle_incoming_blocks(blocks, pblocks))
+ {
+ LOG_PRINT_CCONTEXT_L1("Block verification failed: prepare_handle_incoming_blocks failed, dropping connection");
+ drop_connection(context, false, false);
+ m_core.resume_mine();
+ return 1;
+ }
for(auto tx_blob_it = arg.b.txs.begin(); tx_blob_it!=arg.b.txs.end();tx_blob_it++)
{
cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
@@ -426,7 +441,7 @@ namespace cryptonote
}
block_verification_context bvc = boost::value_initialized<block_verification_context>();
- m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block
+ m_core.handle_incoming_block(arg.b.block, pblocks.empty() ? NULL : &pblocks[0], bvc); // got block from handle_notify_new_block
if (!m_core.cleanup_handle_incoming_blocks(true))
{
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
@@ -689,10 +704,16 @@ namespace cryptonote
std::vector<block_complete_entry> blocks;
blocks.push_back(b);
- m_core.prepare_handle_incoming_blocks(blocks);
+ std::vector<block> pblocks;
+ if (!m_core.prepare_handle_incoming_blocks(blocks, pblocks))
+ {
+ LOG_PRINT_CCONTEXT_L0("Failure in prepare_handle_incoming_blocks");
+ m_core.resume_mine();
+ return 1;
+ }
block_verification_context bvc = boost::value_initialized<block_verification_context>();
- m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block
+ m_core.handle_incoming_block(arg.b.block, pblocks.empty() ? NULL : &pblocks[0], bvc); // got block from handle_notify_new_block
if (!m_core.cleanup_handle_incoming_blocks(true))
{
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
@@ -1166,10 +1187,21 @@ namespace cryptonote
}
}
- m_core.prepare_handle_incoming_blocks(blocks);
+ std::vector<block> pblocks;
+ if (!m_core.prepare_handle_incoming_blocks(blocks, pblocks))
+ {
+ LOG_ERROR_CCONTEXT("Failure in prepare_handle_incoming_blocks");
+ return 1;
+ }
+ if (!pblocks.empty() && pblocks.size() != blocks.size())
+ {
+ m_core.cleanup_handle_incoming_blocks();
+ LOG_ERROR_CCONTEXT("Internal error: blocks.size() != block_entry.txs.size()");
+ return 1;
+ }
uint64_t block_process_time_full = 0, transactions_process_time_full = 0;
- size_t num_txs = 0;
+ size_t num_txs = 0, blockidx = 0;
for(const block_complete_entry& block_entry: blocks)
{
if (m_stopping)
@@ -1221,7 +1253,7 @@ namespace cryptonote
TIME_MEASURE_START(block_process_time);
block_verification_context bvc = boost::value_initialized<block_verification_context>();
- m_core.handle_incoming_block(block_entry.block, bvc, false); // <--- process block
+ m_core.handle_incoming_block(block_entry.block, pblocks.empty() ? NULL : &pblocks[blockidx], bvc, false); // <--- process block
if(bvc.m_verifivation_failed)
{
@@ -1264,6 +1296,7 @@ namespace cryptonote
TIME_MEASURE_FINISH(block_process_time);
block_process_time_full += block_process_time;
+ ++blockidx;
} // each download block
@@ -2058,20 +2091,20 @@ skip:
fluffy_arg.b.txs = fluffy_txs;
// sort peers between fluffy ones and others
- std::list<boost::uuids::uuid> fullConnections, fluffyConnections;
+ std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> fullConnections, fluffyConnections;
m_p2p->for_each_connection([this, &exclude_context, &fullConnections, &fluffyConnections](connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)
{
- if (peer_id && exclude_context.m_connection_id != context.m_connection_id)
+ if (peer_id && exclude_context.m_connection_id != context.m_connection_id && context.m_remote_address.get_zone() == epee::net_utils::zone::public_)
{
if(m_core.fluffy_blocks_enabled() && (support_flags & P2P_SUPPORT_FLAG_FLUFFY_BLOCKS))
{
LOG_DEBUG_CC(context, "PEER SUPPORTS FLUFFY BLOCKS - RELAYING THIN/COMPACT WHATEVER BLOCK");
- fluffyConnections.push_back(context.m_connection_id);
+ fluffyConnections.push_back({context.m_remote_address.get_zone(), context.m_connection_id});
}
else
{
LOG_DEBUG_CC(context, "PEER DOESN'T SUPPORT FLUFFY BLOCKS - RELAYING FULL BLOCK");
- fullConnections.push_back(context.m_connection_id);
+ fullConnections.push_back({context.m_remote_address.get_zone(), context.m_connection_id});
}
}
return true;
@@ -2082,13 +2115,13 @@ skip:
{
std::string fluffyBlob;
epee::serialization::store_t_to_binary(fluffy_arg, fluffyBlob);
- m_p2p->relay_notify_to_list(NOTIFY_NEW_FLUFFY_BLOCK::ID, epee::strspan<uint8_t>(fluffyBlob), fluffyConnections);
+ m_p2p->relay_notify_to_list(NOTIFY_NEW_FLUFFY_BLOCK::ID, epee::strspan<uint8_t>(fluffyBlob), std::move(fluffyConnections));
}
if (!fullConnections.empty())
{
std::string fullBlob;
epee::serialization::store_t_to_binary(arg, fullBlob);
- m_p2p->relay_notify_to_list(NOTIFY_NEW_BLOCK::ID, epee::strspan<uint8_t>(fullBlob), fullConnections);
+ m_p2p->relay_notify_to_list(NOTIFY_NEW_BLOCK::ID, epee::strspan<uint8_t>(fullBlob), std::move(fullConnections));
}
return true;
@@ -2097,8 +2130,14 @@ skip:
template<class t_core>
bool t_cryptonote_protocol_handler<t_core>::relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& exclude_context)
{
+ const bool hide_tx_broadcast =
+ 1 < m_p2p->get_zone_count() && exclude_context.m_remote_address.get_zone() == epee::net_utils::zone::invalid;
+
+ if (hide_tx_broadcast)
+ MDEBUG("Attempting to conceal origin of tx via anonymity network connection(s)");
+
// no check for success, so tell core they're relayed unconditionally
- const bool pad_transactions = m_core.pad_transactions();
+ const bool pad_transactions = m_core.pad_transactions() || hide_tx_broadcast;
size_t bytes = pad_transactions ? 9 /* header */ + 4 /* 1 + 'txs' */ + tools::get_varint_data(arg.txs.size()).size() : 0;
for(auto tx_blob_it = arg.txs.begin(); tx_blob_it!=arg.txs.end(); ++tx_blob_it)
{
@@ -2131,7 +2170,30 @@ skip:
// if the size of _ moved enough, we might lose byte in size encoding, we don't care
}
- return relay_post_notify<NOTIFY_NEW_TRANSACTIONS>(arg, exclude_context);
+ std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> connections;
+ m_p2p->for_each_connection([hide_tx_broadcast, &exclude_context, &connections](connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)
+ {
+ const epee::net_utils::zone current_zone = context.m_remote_address.get_zone();
+ const bool broadcast_to_peer =
+ peer_id &&
+ (hide_tx_broadcast != bool(current_zone == epee::net_utils::zone::public_)) &&
+ exclude_context.m_connection_id != context.m_connection_id;
+
+ if (broadcast_to_peer)
+ connections.push_back({current_zone, context.m_connection_id});
+
+ return true;
+ });
+
+ if (connections.empty())
+ MERROR("Transaction not relayed - no" << (hide_tx_broadcast ? " privacy": "") << " peers available");
+ else
+ {
+ std::string fullBlob;
+ epee::serialization::store_t_to_binary(arg, fullBlob);
+ m_p2p->relay_notify_to_list(NOTIFY_NEW_TRANSACTIONS::ID, epee::strspan<uint8_t>(fullBlob), std::move(connections));
+ }
+ return true;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>