Skip to content

Commit 8fef32e

Browse files
committed
Merge pull request #7292
ba3c627 Command max_bytes moved from dynamic map to static switch (Lee Clagett)
2 parents 7f1a83b + ba3c627 commit 8fef32e

File tree

8 files changed

+115
-48
lines changed

8 files changed

+115
-48
lines changed

src/cryptonote_basic/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ endif()
3838

3939
set(cryptonote_basic_sources
4040
account.cpp
41+
connection_context.cpp
4142
cryptonote_basic_impl.cpp
4243
cryptonote_format_utils.cpp
4344
difficulty.cpp
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright (c) 2020, The Monero Project
2+
//
3+
// All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without modification, are
6+
// permitted provided that the following conditions are met:
7+
//
8+
// 1. Redistributions of source code must retain the above copyright notice, this list of
9+
// conditions and the following disclaimer.
10+
//
11+
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12+
// of conditions and the following disclaimer in the documentation and/or other
13+
// materials provided with the distribution.
14+
//
15+
// 3. Neither the name of the copyright holder nor the names of its contributors may be
16+
// used to endorse or promote products derived from this software without specific
17+
// prior written permission.
18+
//
19+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20+
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21+
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22+
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26+
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27+
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
29+
#include "connection_context.h"
30+
31+
#include "cryptonote_protocol/cryptonote_protocol_defs.h"
32+
#include "p2p/p2p_protocol_defs.h"
33+
34+
namespace cryptonote
35+
{
36+
std::size_t cryptonote_connection_context::get_max_bytes(const int command) noexcept
37+
{
38+
switch (command)
39+
{
40+
case nodetool::COMMAND_HANDSHAKE_T<cryptonote::CORE_SYNC_DATA>::ID:
41+
return 65536;
42+
case nodetool::COMMAND_TIMED_SYNC_T<cryptonote::CORE_SYNC_DATA>::ID:
43+
return 65536;
44+
case nodetool::COMMAND_PING::ID:
45+
return 4096;
46+
case nodetool::COMMAND_REQUEST_SUPPORT_FLAGS::ID:
47+
return 4096;
48+
case cryptonote::NOTIFY_NEW_BLOCK::ID:
49+
return 1024 * 1024 * 128; // 128 MB (max packet is a bit less than 100 MB though)
50+
case cryptonote::NOTIFY_NEW_TRANSACTIONS::ID:
51+
return 1024 * 1024 * 128; // 128 MB (max packet is a bit less than 100 MB though)
52+
case cryptonote::NOTIFY_REQUEST_GET_OBJECTS::ID:
53+
return 1024 * 1024 * 2; // 2 MB
54+
case cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::ID:
55+
return 1024 * 1024 * 128; // 128 MB (max packet is a bit less than 100 MB though)
56+
case cryptonote::NOTIFY_REQUEST_CHAIN::ID:
57+
return 512 * 1024; // 512 kB
58+
case cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::ID:
59+
return 1024 * 1024 * 4; // 4 MB
60+
case cryptonote::NOTIFY_NEW_FLUFFY_BLOCK::ID:
61+
return 1024 * 1024 * 4; // 4 MB, but it does not includes transaction data
62+
case cryptonote::NOTIFY_REQUEST_FLUFFY_MISSING_TX::ID:
63+
return 1024 * 1024; // 1 MB
64+
case cryptonote::NOTIFY_GET_TXPOOL_COMPLEMENT::ID:
65+
return 1024 * 1024 * 4; // 4 MB
66+
default:
67+
break;
68+
};
69+
return std::numeric_limits<size_t>::max();
70+
}
71+
} // cryptonote

src/cryptonote_basic/connection_context.h

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939

4040
namespace cryptonote
4141
{
42-
4342
struct cryptonote_connection_context: public epee::net_utils::connection_context_base
4443
{
4544
cryptonote_connection_context(): m_state(state_before_handshake), m_remote_blockchain_height(0), m_last_response_height(0),
@@ -56,28 +55,11 @@ namespace cryptonote
5655
state_normal
5756
};
5857

58+
static constexpr int handshake_command() noexcept { return 1001; }
5959
bool handshake_complete() const noexcept { return m_state != state_before_handshake; }
6060

61-
void set_max_bytes(int command, size_t bytes) {
62-
const auto i = std::lower_bound(m_max_bytes.begin(), m_max_bytes.end(), std::make_pair(command, bytes), [](const std::pair<int, size_t> &e0, const std::pair<int, size_t> &e1){
63-
return e0.first < e1.first;
64-
});
65-
if (i == m_max_bytes.end())
66-
m_max_bytes.push_back(std::make_pair(command, bytes));
67-
else if (i->first == command)
68-
i->second = bytes;
69-
else
70-
m_max_bytes.insert(i, std::make_pair(command, bytes));
71-
}
72-
size_t get_max_bytes(int command) const {
73-
const auto i = std::lower_bound(m_max_bytes.begin(), m_max_bytes.end(), std::make_pair(command, 0), [](const std::pair<int, size_t> &e0, const std::pair<int, size_t> &e1){
74-
return e0.first < e1.first;
75-
});
76-
if (i == m_max_bytes.end() || i->first != command)
77-
return std::numeric_limits<size_t>::max();
78-
else
79-
return i->second;
80-
}
61+
//! \return Maximum number of bytes permissible for `command`.
62+
static size_t get_max_bytes(int command) noexcept;
8163

8264
state m_state;
8365
std::vector<std::pair<crypto::hash, uint64_t>> m_needed_objects;
@@ -95,7 +77,6 @@ namespace cryptonote
9577
int m_expect_response;
9678
uint64_t m_expect_height;
9779
size_t m_num_requested;
98-
std::vector<std::pair<int, size_t>> m_max_bytes;
9980
};
10081

10182
inline std::string get_protocol_state_string(cryptonote_connection_context::state s)

src/cryptonote_protocol/cryptonote_protocol_handler.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ namespace cryptonote
109109
std::list<connection_info> get_connections();
110110
const block_queue &get_block_queue() const { return m_block_queue; }
111111
void stop();
112-
void on_connection_new(cryptonote_connection_context &context);
113112
void on_connection_close(cryptonote_connection_context &context);
114113
void set_max_out_peers(unsigned int max) { m_max_out_peers = max; }
115114
bool no_sync() const { return m_no_sync; }

src/cryptonote_protocol/cryptonote_protocol_handler.inl

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,25 +2878,6 @@ skip:
28782878
}
28792879
//------------------------------------------------------------------------------------------------------------------------
28802880
template<class t_core>
2881-
void t_cryptonote_protocol_handler<t_core>::on_connection_new(cryptonote_connection_context &context)
2882-
{
2883-
context.set_max_bytes(nodetool::COMMAND_HANDSHAKE_T<cryptonote::CORE_SYNC_DATA>::ID, 65536);
2884-
context.set_max_bytes(nodetool::COMMAND_TIMED_SYNC_T<cryptonote::CORE_SYNC_DATA>::ID, 65536);
2885-
context.set_max_bytes(nodetool::COMMAND_PING::ID, 4096);
2886-
context.set_max_bytes(nodetool::COMMAND_REQUEST_SUPPORT_FLAGS::ID, 4096);
2887-
2888-
context.set_max_bytes(cryptonote::NOTIFY_NEW_BLOCK::ID, 1024 * 1024 * 128); // 128 MB (max packet is a bit less than 100 MB though)
2889-
context.set_max_bytes(cryptonote::NOTIFY_NEW_TRANSACTIONS::ID, 1024 * 1024 * 128); // 128 MB (max packet is a bit less than 100 MB though)
2890-
context.set_max_bytes(cryptonote::NOTIFY_REQUEST_GET_OBJECTS::ID, 1024 * 1024 * 2); // 2 MB
2891-
context.set_max_bytes(cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::ID, 1024 * 1024 * 128); // 128 MB (max packet is a bit less than 100 MB though)
2892-
context.set_max_bytes(cryptonote::NOTIFY_REQUEST_CHAIN::ID, 512 * 1024); // 512 kB
2893-
context.set_max_bytes(cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::ID, 1024 * 1024 * 4); // 4 MB
2894-
context.set_max_bytes(cryptonote::NOTIFY_NEW_FLUFFY_BLOCK::ID, 1024 * 1024 * 4); // 4 MB, but it does not includes transaction data
2895-
context.set_max_bytes(cryptonote::NOTIFY_REQUEST_FLUFFY_MISSING_TX::ID, 1024 * 1024); // 1 MB
2896-
context.set_max_bytes(cryptonote::NOTIFY_GET_TXPOOL_COMPLEMENT::ID, 1024 * 1024 * 4); // 4 MB
2897-
}
2898-
//------------------------------------------------------------------------------------------------------------------------
2899-
template<class t_core>
29002881
void t_cryptonote_protocol_handler<t_core>::on_connection_close(cryptonote_connection_context &context)
29012882
{
29022883
uint64_t target = 0;

src/p2p/net_node.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ namespace nodetool
118118
m_in_timedsync(false)
119119
{}
120120

121-
static constexpr int handshake_command() noexcept { return 1001; }
122-
123121
std::vector<cryptonote::blobdata> fluff_txs;
124122
std::chrono::steady_clock::time_point flush_time;
125123
peerid_type peer_id;

src/p2p/net_node.inl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2639,7 +2639,6 @@ namespace nodetool
26392639
void node_server<t_payload_net_handler>::on_connection_new(p2p_connection_context& context)
26402640
{
26412641
MINFO("["<< epee::net_utils::print_connection_context(context) << "] NEW CONNECTION");
2642-
m_payload_handler.on_connection_new(context);
26432642
}
26442643
//-----------------------------------------------------------------------------------
26452644
template<class t_payload_net_handler>

tests/unit_tests/levin.cpp

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,12 @@ namespace
183183
}
184184

185185
//\return Number of messages processed
186-
std::size_t process_send_queue()
186+
std::size_t process_send_queue(const bool valid = true)
187187
{
188188
std::size_t count = 0;
189189
for ( ; !endpoint_.send_queue_.empty(); ++count, endpoint_.send_queue_.pop_front())
190190
{
191-
// invalid messages shoudn't be possible in this test;
192-
EXPECT_TRUE(handler_.handle_recv(endpoint_.send_queue_.front().data(), endpoint_.send_queue_.front().size()));
191+
EXPECT_EQ(valid, handler_.handle_recv(endpoint_.send_queue_.front().data(), endpoint_.send_queue_.front().size()));
193192
}
194193
return count;
195194
}
@@ -239,6 +238,13 @@ namespace
239238
return {connection, std::move(request)};
240239
}
241240

241+
static received_message get_raw_message(std::deque<received_message>& queue)
242+
{
243+
received_message out{std::move(queue.front())};
244+
queue.pop_front();
245+
return out;
246+
}
247+
242248
virtual int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, cryptonote::levin::detail::p2p_context& context) override final
243249
{
244250
buff_out.clear();
@@ -295,6 +301,11 @@ namespace
295301
{
296302
return get_message<T>(notified_);
297303
}
304+
305+
received_message get_raw_notification()
306+
{
307+
return get_raw_message(notified_);
308+
}
298309
};
299310

300311
class levin_notify : public ::testing::Test
@@ -323,6 +334,8 @@ namespace
323334
EXPECT_EQ(0u, events_.relayed_method_size());
324335
}
325336

337+
cryptonote::levin::connections& get_connections() noexcept { return *connections_; }
338+
326339
void add_connection(const bool is_incoming)
327340
{
328341
contexts_.emplace_back(io_service_, *connections_, random_generator_, is_incoming);
@@ -2141,3 +2154,27 @@ TEST_F(levin_notify, noise_stem)
21412154
}
21422155
}
21432156
}
2157+
2158+
TEST_F(levin_notify, command_max_bytes)
2159+
{
2160+
static constexpr int ping_command = nodetool::COMMAND_PING::ID;
2161+
2162+
add_connection(true);
2163+
2164+
std::string bytes(4096, 'h');
2165+
2166+
EXPECT_EQ(1, get_connections().notify(ping_command, epee::strspan<std::uint8_t>(bytes), contexts_.front().get_id()));
2167+
EXPECT_EQ(1u, contexts_.front().process_send_queue(true));
2168+
EXPECT_EQ(1u, receiver_.notified_size());
2169+
2170+
const received_message msg = receiver_.get_raw_notification();
2171+
EXPECT_EQ(ping_command, msg.command);
2172+
EXPECT_EQ(contexts_.front().get_id(), msg.connection);
2173+
EXPECT_EQ(bytes, msg.payload);
2174+
2175+
bytes.push_back('e');
2176+
2177+
EXPECT_EQ(1, get_connections().notify(ping_command, epee::strspan<std::uint8_t>(bytes), contexts_.front().get_id()));
2178+
EXPECT_EQ(1u, contexts_.front().process_send_queue(false));
2179+
EXPECT_EQ(0u, receiver_.notified_size());
2180+
}

0 commit comments

Comments
 (0)