diff options
Diffstat (limited to 'src/cryptonote_protocol/cryptonote_protocol_handler.inl')
-rw-r--r-- | src/cryptonote_protocol/cryptonote_protocol_handler.inl | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 5ba637c2f..999ec5650 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -1210,6 +1210,7 @@ skip: bool t_cryptonote_protocol_handler<t_core>::on_idle() { m_idle_peer_kicker.do_call(boost::bind(&t_cryptonote_protocol_handler<t_core>::kick_idle_peers, this)); + m_standby_checker.do_call(boost::bind(&t_cryptonote_protocol_handler<t_core>::check_standby_peers, this)); return m_core.on_idle(); } //------------------------------------------------------------------------------------------------------------------------ @@ -1245,6 +1246,22 @@ skip: } //------------------------------------------------------------------------------------------------------------------------ template<class t_core> + bool t_cryptonote_protocol_handler<t_core>::check_standby_peers() + { + 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_standby) + { + LOG_PRINT_CCONTEXT_L2("requesting callback"); + ++context.m_callback_request_count; + m_p2p->request_callback(context); + } + return true; + }); + return true; + } + //------------------------------------------------------------------------------------------------------------------------ + template<class t_core> int t_cryptonote_protocol_handler<t_core>::handle_request_chain(int command, NOTIFY_REQUEST_CHAIN::request& arg, cryptonote_connection_context& context) { MLOG_P2P_MESSAGE("Received NOTIFY_REQUEST_CHAIN (" << arg.block_ids.size() << " blocks"); @@ -1338,14 +1355,13 @@ skip: bool start_from_current_chain = false; if (!force_next_span) { - bool first = true; - while (1) + do { size_t nblocks = m_block_queue.get_num_filled_spans(); size_t size = m_block_queue.get_data_size(); if (nblocks < BLOCK_QUEUE_NBLOCKS_THRESHOLD || size < BLOCK_QUEUE_SIZE_THRESHOLD) { - if (!first) + if (context.m_state != cryptonote_connection_context::state_standby) { LOG_DEBUG_CC(context, "Block queue is " << nblocks << " and " << size << ", resuming"); } @@ -1368,10 +1384,9 @@ skip: break; } - if (first) + if (context.m_state != cryptonote_connection_context::state_standby) { LOG_DEBUG_CC(context, "Block queue is " << nblocks << " and " << size << ", pausing"); - first = false; context.m_state = cryptonote_connection_context::state_standby; } @@ -1385,13 +1400,8 @@ skip: return true; } - for (size_t n = 0; n < 50; ++n) - { - if (m_stopping) - return true; - boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); - } - } + return true; + } while(0); context.m_state = cryptonote_connection_context::state_synchronizing; } @@ -1726,8 +1736,39 @@ skip: bool t_cryptonote_protocol_handler<t_core>::relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& exclude_context) { // no check for success, so tell core they're relayed unconditionally + const bool pad_transactions = m_core.pad_transactions(); + 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) + { m_core.on_transaction_relayed(*tx_blob_it); + if (pad_transactions) + bytes += tools::get_varint_data(tx_blob_it->size()).size() + tx_blob_it->size(); + } + + if (pad_transactions) + { + // stuff some dummy bytes in to stay safe from traffic volume analysis + static constexpr size_t granularity = 1024; + size_t padding = granularity - bytes % granularity; + const size_t overhead = 2 /* 1 + '_' */ + tools::get_varint_data(padding).size(); + if (overhead > padding) + padding = 0; + else + padding -= overhead; + arg._ = std::string(padding, ' '); + + std::string arg_buff; + epee::serialization::store_t_to_binary(arg, arg_buff); + + // we probably lowballed the payload size a bit, so added a but too much. Fix this now. + size_t remove = arg_buff.size() % granularity; + if (remove > arg._.size()) + arg._.clear(); + else + arg._.resize(arg._.size() - remove); + // 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); } //------------------------------------------------------------------------------------------------------------------------ |