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.inl312
1 files changed, 257 insertions, 55 deletions
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index 2754eb73c..1cf66521f 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -1,3 +1,7 @@
+/// @file
+/// @author rfree (current maintainer/user in monero.cc project - most of code is from CryptoNote)
+/// @brief This is the orginal cryptonote protocol network-events handler, modified by us
+
// Copyright (c) 2014-2015, The Monero Project
//
// All rights reserved.
@@ -28,14 +32,28 @@
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+// (may contain code and/or modifications by other developers)
+// developer rfree: this code is caller of our new network code, and is modded; e.g. for rate limiting
+
#include <boost/interprocess/detail/atomic.hpp>
#include <list>
#include "cryptonote_core/cryptonote_format_utils.h"
#include "profile_tools.h"
+#include "../../contrib/otshell_utils/utils.hpp"
+#include "../../src/p2p/network_throttle-detail.hpp"
+#include "../../src/p2p/data_logger.hpp"
+using namespace nOT::nUtils;
+
namespace cryptonote
{
+
+// static
+// template<class t_core> std::ofstream t_cryptonote_protocol_handler<t_core>::m_logreq("logreq.txt"); // static
+
+
+
//-----------------------------------------------------------------------------------------------------------------------
template<class t_core>
t_cryptonote_protocol_handler<t_core>::t_cryptonote_protocol_handler(t_core& rcore, nodetool::i_p2p_endpoint<connection_context>* p_net_layout):m_core(rcore),
@@ -99,24 +117,66 @@ namespace cryptonote
void t_cryptonote_protocol_handler<t_core>::log_connections()
{
std::stringstream ss;
+ ss.precision(1);
+
+ double down_sum = 0.0;
+ double down_curr_sum = 0.0;
+ double up_sum = 0.0;
+ double up_curr_sum = 0.0;
- ss << std::setw(25) << std::left << "Remote Host"
+ ss << std::setw(30) << std::left << "Remote Host"
<< std::setw(20) << "Peer id"
- << std::setw(25) << "Recv/Sent (inactive,sec)"
+ << std::setw(30) << "Recv/Sent (inactive,sec)"
<< std::setw(25) << "State"
- << std::setw(20) << "Livetime(seconds)" << ENDL;
-
+ << std::setw(20) << "Livetime(sec)"
+ << std::setw(12) << "Down (kB/s)"
+ << std::setw(14) << "Down(now)"
+ << std::setw(10) << "Up (kB/s)"
+ << std::setw(13) << "Up(now)"
+ << ENDL;
+
+ uint32_t ip;
m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id)
{
- ss << std::setw(25) << std::left << std::string(cntxt.m_is_income ? " [INC]":"[OUT]") +
- epee::string_tools::get_ip_string_from_int32(cntxt.m_remote_ip) + ":" + std::to_string(cntxt.m_remote_port)
+ bool local_ip = false;
+ ip = ntohl(cntxt.m_remote_ip);
+ // TODO: local ip in calss A, B
+ if (ip > 3232235520 && ip < 3232301055) // 192.168.x.x
+ local_ip = true;
+ auto connection_time = time(NULL) - cntxt.m_started;
+ ss << std::setw(30) << std::left << std::string(cntxt.m_is_income ? " [INC]":"[OUT]") +
+ epee::string_tools::get_ip_string_from_int32(cntxt.m_remote_ip) + ":" + std::to_string(cntxt.m_remote_port)
<< std::setw(20) << std::hex << peer_id
- << std::setw(25) << std::to_string(cntxt.m_recv_cnt)+ "(" + std::to_string(time(NULL) - cntxt.m_last_recv) + ")" + "/" + std::to_string(cntxt.m_send_cnt) + "(" + std::to_string(time(NULL) - cntxt.m_last_send) + ")"
+ << std::setw(30) << std::to_string(cntxt.m_recv_cnt)+ "(" + std::to_string(time(NULL) - cntxt.m_last_recv) + ")" + "/" + std::to_string(cntxt.m_send_cnt) + "(" + std::to_string(time(NULL) - cntxt.m_last_send) + ")"
<< std::setw(25) << get_protocol_state_string(cntxt.m_state)
- << std::setw(20) << std::to_string(time(NULL) - cntxt.m_started) << ENDL;
+ << std::setw(20) << std::to_string(time(NULL) - cntxt.m_started)
+ << std::setw(12) << std::fixed << (connection_time == 0 ? 0.0 : cntxt.m_recv_cnt / connection_time / 1024)
+ << std::setw(14) << std::fixed << cntxt.m_current_speed_down / 1024
+ << std::setw(10) << std::fixed << (connection_time == 0 ? 0.0 : cntxt.m_send_cnt / connection_time / 1024)
+ << std::setw(13) << std::fixed << cntxt.m_current_speed_up / 1024
+ << (local_ip ? "[LAN]" : "")
+ << std::left << (ip == LOCALHOST_INT ? "[LOCALHOST]" : "") // 127.0.0.1
+ << ENDL;
+
+ if (connection_time > 1)
+ {
+ down_sum += (cntxt.m_recv_cnt / connection_time / 1024);
+ up_sum += (cntxt.m_send_cnt / connection_time / 1024);
+ }
+
+ down_curr_sum += (cntxt.m_current_speed_down / 1024);
+ up_curr_sum += (cntxt.m_current_speed_up / 1024);
+
return true;
});
- LOG_PRINT_L0("Connections: " << ENDL << ss.str());
+ ss << ENDL
+ << std::setw(125) << " "
+ << std::setw(12) << down_sum
+ << std::setw(14) << down_curr_sum
+ << std::setw(10) << up_sum
+ << std::setw(13) << up_curr_sum
+ << ENDL;
+ LOG_PRINT_L0("Connections: " << ENDL << ss.str());
}
//------------------------------------------------------------------------------------------------------------------------
// Returns a list of connection_info objects describing each open p2p connection
@@ -150,6 +210,42 @@ namespace cryptonote
cnx.live_time = timestamp - cntxt.m_started;
+ uint32_t ip;
+ ip = ntohl(cntxt.m_remote_ip);
+ if (ip == LOCALHOST_INT)
+ {
+ cnx.localhost = true;
+ }
+ else
+ {
+ cnx.localhost = false;
+ }
+
+ if (ip > 3232235520 && ip < 3232301055) // 192.168.x.x
+ {
+ cnx.local_ip = true;
+ }
+ else
+ {
+ cnx.local_ip = false;
+ }
+
+ auto connection_time = time(NULL) - cntxt.m_started;
+ if (connection_time == 0)
+ {
+ cnx.avg_download = 0;
+ cnx.avg_upload = 0;
+ }
+
+ else
+ {
+ cnx.avg_download = cntxt.m_recv_cnt / connection_time / 1024;
+ cnx.avg_upload = cntxt.m_send_cnt / connection_time / 1024;
+ }
+
+ cnx.current_download = cntxt.m_current_speed_down / 1024;
+ cnx.current_upload = cntxt.m_current_speed_up / 1024;
+
connections.push_back(cnx);
return true;
@@ -234,11 +330,11 @@ namespace cryptonote
block_verification_context bvc = boost::value_initialized<block_verification_context>();
m_core.pause_mine();
- m_core.handle_incoming_block(arg.b.block, bvc);
+ m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block
m_core.resume_mine();
if(bvc.m_verifivation_failed)
{
- LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
+ LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
m_p2p->drop_connection(context);
return 1;
}
@@ -304,13 +400,70 @@ namespace cryptonote
LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" << rsp.blocks.size() << ", txs.size()=" << rsp.txs.size()
<< ", rsp.m_current_blockchain_height=" << rsp.current_blockchain_height << ", missed_ids.size()=" << rsp.missed_ids.size());
post_notify<NOTIFY_RESPONSE_GET_OBJECTS>(rsp, context);
+ //handler_response_blocks_now(sizeof(rsp)); // XXX
+ //handler_response_blocks_now(200);
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
+
+
+ template<class t_core>
+ double t_cryptonote_protocol_handler<t_core>::get_avg_block_size() {
+ // return m_core.get_blockchain_storage().get_avg_block_size(count); // this does not count too well the actuall network-size of data we need to download
+
+ CRITICAL_REGION_LOCAL(m_buffer_mutex);
+ double avg = 0;
+ if (m_avg_buffer.size() == 0) {
+ _warn("m_avg_buffer.size() == 0");
+ return 500;
+ }
+
+ const bool dbg_poke_lock = 0; // debug: try to trigger an error by poking around with locks. TODO: configure option
+ long int dbg_repeat=0;
+ do {
+ for (auto element : m_avg_buffer) avg += element;
+ } while(dbg_poke_lock && (dbg_repeat++)<100000); // in debug/poke mode, repeat this calculation to trigger hidden locking error if there is one
+ return avg / m_avg_buffer.size();
+ }
+
+
template<class t_core>
int t_cryptonote_protocol_handler<t_core>::handle_response_get_objects(int command, NOTIFY_RESPONSE_GET_OBJECTS::request& arg, cryptonote_connection_context& context)
{
LOG_PRINT_CCONTEXT_L2("NOTIFY_RESPONSE_GET_OBJECTS");
+
+ // calculate size of request - mainly for logging/debug
+ size_t size = 0;
+ for (auto element : arg.txs) size += element.size();
+
+ for (auto element : arg.blocks) {
+ size += element.block.size();
+ for (auto tx : element.txs)
+ size += tx.size();
+ }
+
+ for (auto element : arg.missed_ids)
+ size += sizeof(element.data);
+
+ size += sizeof(arg.current_blockchain_height);
+ {
+ CRITICAL_REGION_LOCAL(m_buffer_mutex);
+ m_avg_buffer.push_back(size);
+
+ const bool dbg_poke_lock = 0; // debug: try to trigger an error by poking around with locks. TODO: configure option
+ long int dbg_repeat=0;
+ do {
+ m_avg_buffer.push_back(666); // a test value
+ m_avg_buffer.erase_end(1);
+ } while(dbg_poke_lock && (dbg_repeat++)<100000); // in debug/poke mode, repeat this calculation to trigger hidden locking error if there is one
+ }
+ /*using namespace boost::chrono;
+ auto point = steady_clock::now();
+ auto time_from_epoh = point.time_since_epoch();
+ auto sec = duration_cast< seconds >( time_from_epoh ).count();*/
+
+ //epee::net_utils::network_throttle_manager::get_global_throttle_inreq().logger_handle_net("log/dr-monero/net/req-all.data", sec, get_avg_block_size());
+
if(context.m_last_response_height > arg.current_blockchain_height)
{
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_HAVE_OBJECTS: arg.m_current_blockchain_height=" << arg.current_blockchain_height
@@ -373,53 +526,67 @@ namespace cryptonote
return 1;
}
+
{
m_core.pause_mine();
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler(
boost::bind(&t_core::resume_mine, &m_core));
- BOOST_FOREACH(const block_complete_entry& block_entry, arg.blocks)
- {
- //process transactions
- TIME_MEASURE_START(transactions_process_time);
- BOOST_FOREACH(auto& tx_blob, block_entry.txs)
- {
- tx_verification_context tvc = AUTO_VAL_INIT(tvc);
- m_core.handle_incoming_tx(tx_blob, tvc, true);
- if(tvc.m_verifivation_failed)
- {
- LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_OBJECTS, \r\ntx_id = "
- << epee::string_tools::pod_to_hex(get_blob_hash(tx_blob)) << ", dropping connection");
- m_p2p->drop_connection(context);
- return 1;
- }
- }
- TIME_MEASURE_FINISH(transactions_process_time);
-
- //process block
- 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);
-
- if(bvc.m_verifivation_failed)
- {
- LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
- m_p2p->drop_connection(context);
- return 1;
- }
- if(bvc.m_marked_as_orphaned)
- {
- LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection");
- m_p2p->drop_connection(context);
- return 1;
- }
-
- TIME_MEASURE_FINISH(block_process_time);
- LOG_PRINT_CCONTEXT_L2("Block process time: " << block_process_time + transactions_process_time << "(" << transactions_process_time << "/" << block_process_time << ")ms");
- }
+ LOG_PRINT_CCONTEXT_YELLOW( "Got NEW BLOCKS inside of " << __FUNCTION__ << ": size: " << arg.blocks.size() , LOG_LEVEL_0);
+
+ if (m_core.get_test_drop_download() && m_core.get_test_drop_download_height()) { // DISCARD BLOCKS for testing
+
+
+ BOOST_FOREACH(const block_complete_entry& block_entry, arg.blocks)
+ {
+ // process transactions
+ TIME_MEASURE_START(transactions_process_time);
+ BOOST_FOREACH(auto& tx_blob, block_entry.txs)
+ {
+ tx_verification_context tvc = AUTO_VAL_INIT(tvc);
+ m_core.handle_incoming_tx(tx_blob, tvc, true);
+ if(tvc.m_verifivation_failed)
+ {
+ LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_OBJECTS, \r\ntx_id = "
+ << epee::string_tools::pod_to_hex(get_blob_hash(tx_blob)) << ", dropping connection");
+ m_p2p->drop_connection(context);
+ return 1;
+ }
+ }
+ TIME_MEASURE_FINISH(transactions_process_time);
+
+ // process block
+
+ 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
+
+ if(bvc.m_verifivation_failed)
+ {
+ LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
+ m_p2p->drop_connection(context);
+ return 1;
+ }
+ if(bvc.m_marked_as_orphaned)
+ {
+ LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection");
+ m_p2p->drop_connection(context);
+ return 1;
+ }
+
+ TIME_MEASURE_FINISH(block_process_time);
+ LOG_PRINT_CCONTEXT_L2("Block process time: " << block_process_time + transactions_process_time << "(" << transactions_process_time << "/" << block_process_time << ")ms");
+
+ epee::net_utils::data_logger::get_instance().add_data("calc_time", block_process_time + transactions_process_time);
+ epee::net_utils::data_logger::get_instance().add_data("block_processing", 1);
+
+ } // each download block
+
+ } // if not DISCARD BLOCK
+
+
}
-
request_missing_objects(context, true);
return 1;
}
@@ -448,6 +615,15 @@ namespace cryptonote
template<class t_core>
bool t_cryptonote_protocol_handler<t_core>::request_missing_objects(cryptonote_connection_context& context, bool check_having_blocks)
{
+ //if (!m_one_request == false)
+ //return true;
+ m_one_request = false;
+ // save request size to log (dr monero)
+ /*using namespace boost::chrono;
+ auto point = steady_clock::now();
+ auto time_from_epoh = point.time_since_epoch();
+ auto sec = duration_cast< seconds >( time_from_epoh ).count();*/
+
if(context.m_needed_objects.size())
{
//we know objects that we need, request this objects
@@ -455,6 +631,8 @@ namespace cryptonote
size_t count = 0;
auto it = context.m_needed_objects.begin();
+ size_t count_limit = BLOCKS_SYNCHRONIZING_DEFAULT_COUNT;
+ _note_c("net/req-calc" , "Setting count_limit: " << count_limit);
while(it != context.m_needed_objects.end() && count < BLOCKS_SYNCHRONIZING_DEFAULT_COUNT)
{
if( !(check_having_blocks && m_core.have_block(*it)))
@@ -465,14 +643,24 @@ namespace cryptonote
}
context.m_needed_objects.erase(it++);
}
- LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_REQUEST_GET_OBJECTS: blocks.size()=" << req.blocks.size() << ", txs.size()=" << req.txs.size());
+ LOG_PRINT_CCONTEXT_L0("-->>NOTIFY_REQUEST_GET_OBJECTS: blocks.size()=" << req.blocks.size() << ", txs.size()=" << req.txs.size()
+ << "requested blocks count=" << count << " / " << count_limit);
+ //epee::net_utils::network_throttle_manager::get_global_throttle_inreq().logger_handle_net("log/dr-monero/net/req-all.data", sec, get_avg_block_size());
+
post_notify<NOTIFY_REQUEST_GET_OBJECTS>(req, context);
}else if(context.m_last_response_height < context.m_remote_blockchain_height-1)
{//we have to fetch more objects ids, request blockchain entry
NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>();
m_core.get_short_chain_history(r.block_ids);
- LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() );
+ handler_request_blocks_history( r.block_ids ); // change the limit(?), sleep(?)
+
+ //std::string blob; // for calculate size of request
+ //epee::serialization::store_t_to_binary(r, blob);
+ //epee::net_utils::network_throttle_manager::get_global_throttle_inreq().logger_handle_net("log/dr-monero/net/req-all.data", sec, get_avg_block_size());
+ LOG_PRINT_CCONTEXT_L0("r = " << 200);
+
+ LOG_PRINT_CCONTEXT_L0("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() );
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
}else
{
@@ -575,4 +763,18 @@ namespace cryptonote
{
return relay_post_notify<NOTIFY_NEW_TRANSACTIONS>(arg, exclude_context);
}
-}
+
+ /// @deprecated
+ template<class t_core> std::ofstream& t_cryptonote_protocol_handler<t_core>::get_logreq() const {
+ static std::ofstream * logreq=NULL;
+ if (!logreq) {
+ LOG_PRINT_RED("LOG OPENED",LOG_LEVEL_0);
+ logreq = new std::ofstream("logreq.txt"); // leak mem (singleton)
+ *logreq << "Opened log" << std::endl;
+ }
+ LOG_PRINT_YELLOW("LOG USED",LOG_LEVEL_0);
+ (*logreq) << "log used" << std::endl;
+ return *logreq;
+ }
+
+} // namespace