Skip to content

Commit

Permalink
Merge pull request #1908 from AntelopeIO/net-cleanup-main
Browse files Browse the repository at this point in the history
[5.0 -> main] Test: net_plugin test cleanup
  • Loading branch information
heifner authored Nov 15, 2023
2 parents a997831 + f8001a2 commit 40cc421
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace eosio::auto_bp_peering {

template <typename Derived, typename Connection>
class bp_connection_manager {
#ifdef BOOST_TEST_MODULE
#ifdef BOOST_TEST
public:
#endif

Expand Down
67 changes: 67 additions & 0 deletions plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#pragma once

#include <eosio/chain/exceptions.hpp>

#include <string>
#include <sstream>
#include <regex>

namespace eosio::net_utils {

namespace detail {

inline static const std::map<std::string, size_t> prefix_multipliers{
{"",1},{"K",pow(10,3)},{"M",pow(10,6)},{"G",pow(10, 9)},{"T",pow(10, 12)},
{"Ki",pow(2,10)},{"Mi",pow(2,20)},{"Gi",pow(2,30)},{"Ti",pow(2,40)}
};

inline size_t parse_connection_rate_limit( const std::string& limit_str) {
std::istringstream in(limit_str);
double limit{0};
in >> limit;
EOS_ASSERT(limit >= 0.0, chain::plugin_config_exception, "block sync rate limit must not be negative: ${limit}", ("limit", limit_str));
size_t block_sync_rate_limit = 0;
if( limit > 0.0 ) {
std::string units;
in >> units;
std::regex units_regex{"([KMGT]?[i]?)B/s"};
std::smatch units_match;
std::regex_match(units, units_match, units_regex);
if( units.length() > 0 ) {
EOS_ASSERT(units_match.size() == 2, chain::plugin_config_exception, "invalid block sync rate limit specification: ${limit}", ("limit", units));
try {
block_sync_rate_limit = boost::numeric_cast<size_t>(limit * prefix_multipliers.at(units_match[1].str()));
} catch (boost::numeric::bad_numeric_cast&) {
EOS_THROW(chain::plugin_config_exception, "block sync rate limit specification overflowed: ${limit}", ("limit", limit_str));
}
}
}
return block_sync_rate_limit;
}

} // namespace detail

/// @return listen address and block sync rate limit (in bytes/sec) of address string
inline std::tuple<std::string, size_t> parse_listen_address( const std::string& address ) {
auto listen_addr = address;
auto limit = std::string("0");
auto last_colon_location = address.rfind(':');
if( auto right_bracket_location = address.find(']'); right_bracket_location != address.npos ) {
if( std::count(address.begin()+right_bracket_location, address.end(), ':') > 1 ) {
listen_addr = std::string(address, 0, last_colon_location);
limit = std::string(address, last_colon_location+1);
}
} else {
if( auto colon_count = std::count(address.begin(), address.end(), ':'); colon_count > 1 ) {
EOS_ASSERT( colon_count <= 2, chain::plugin_config_exception,
"Invalid address specification ${addr}; IPv6 addresses must be enclosed in square brackets.", ("addr", address));
listen_addr = std::string(address, 0, last_colon_location);
limit = std::string(address, last_colon_location+1);
}
}
auto block_sync_rate_limit = detail::parse_connection_rate_limit(limit);

return {listen_addr, block_sync_rate_limit};
}

} // namespace eosio::net_utils
56 changes: 3 additions & 53 deletions plugins/net_plugin/net_plugin.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <eosio/net_plugin/net_plugin.hpp>
#include <eosio/net_plugin/protocol.hpp>
#include <eosio/net_plugin/net_utils.hpp>
#include <eosio/net_plugin/auto_bp_peering.hpp>
#include <eosio/chain/types.hpp>
#include <eosio/chain/controller.hpp>
Expand Down Expand Up @@ -517,10 +518,6 @@ namespace eosio {
std::function<void()> increment_dropped_trxs;

private:
inline static const std::map<std::string, size_t> prefix_multipliers{
{"",1},{"K",pow(10,3)},{"M",pow(10,6)},{"G",pow(10, 9)},{"T",pow(10, 12)},
{"Ki",pow(2,10)},{"Mi",pow(2,20)},{"Gi",pow(2,30)},{"Ti",pow(2,40)}
};
alignas(hardware_destructive_interference_size)
mutable fc::mutex chain_info_mtx; // protects chain_info_t
chain_info_t chain_info GUARDED_BY(chain_info_mtx);
Expand Down Expand Up @@ -575,8 +572,6 @@ namespace eosio {

constexpr static uint16_t to_protocol_version(uint16_t v);

std::tuple<std::string, size_t> parse_listen_address(const std::string& peer) const;
size_t parse_connection_rate_limit(const string& limit_str) const;
void plugin_initialize(const variables_map& options);
void plugin_startup();
void plugin_shutdown();
Expand Down Expand Up @@ -4104,52 +4099,6 @@ namespace eosio {
return fc::json::from_string(s).as<T>();
}

std::tuple<std::string, size_t> net_plugin_impl::parse_listen_address( const std::string& address ) const {
auto listen_addr = address;
auto limit = string("0");
auto last_colon_location = address.rfind(':');
if( auto right_bracket_location = address.find(']'); right_bracket_location != address.npos ) {
if( std::count(address.begin()+right_bracket_location, address.end(), ':') > 1 ) {
listen_addr = std::string(address, 0, last_colon_location);
limit = std::string(address, last_colon_location+1);
}
} else {
if( auto colon_count = std::count(address.begin(), address.end(), ':'); colon_count > 1 ) {
EOS_ASSERT( colon_count <= 2, plugin_config_exception, "Invalid address specification ${addr}; IPv6 addresses must be enclosed in square brackets.", ("addr", address));
listen_addr = std::string(address, 0, last_colon_location);
limit = std::string(address, last_colon_location+1);
}
}
auto block_sync_rate_limit = parse_connection_rate_limit(limit);

return {listen_addr, block_sync_rate_limit};
}

size_t net_plugin_impl::parse_connection_rate_limit( const std::string& limit_str) const {
std::istringstream in(limit_str);
double limit{0};
in >> limit;
EOS_ASSERT(limit >= 0.0, plugin_config_exception, "block sync rate limit must not be negative: ${limit}", ("limit", limit_str));
size_t block_sync_rate_limit = 0;
if( limit > 0.0 ) {
std::string units;
in >> units;
std::regex units_regex{"([KMGT]?[i]?)B/s"};
std::smatch units_match;
std::regex_match(units, units_match, units_regex);
if( units.length() > 0 ) {
EOS_ASSERT(units_match.size() == 2, plugin_config_exception, "invalid block sync rate limit specification: ${limit}", ("limit", units));
try {
block_sync_rate_limit = boost::numeric_cast<size_t>(limit * prefix_multipliers.at(units_match[1].str()));
fc_ilog( logger, "setting block_sync_rate_limit to ${limit} megabytes per second", ("limit", double(block_sync_rate_limit)/1000000));
} catch (boost::numeric::bad_numeric_cast&) {
EOS_THROW(plugin_config_exception, "block sync rate limit specification overflowed: ${limit}", ("limit", limit_str));
}
}
}
return block_sync_rate_limit;
}

void net_plugin_impl::plugin_initialize( const variables_map& options ) {
try {
fc_ilog( logger, "Initialize net plugin" );
Expand Down Expand Up @@ -4365,7 +4314,8 @@ namespace eosio {
std::string extra_listening_log_info =
", max clients is " + std::to_string(my->connections.get_max_client_count());

auto [listen_addr, block_sync_rate_limit] = my->parse_listen_address(address);
auto [listen_addr, block_sync_rate_limit] = net_utils::parse_listen_address(address);
fc_ilog( logger, "setting block_sync_rate_limit to ${limit} megabytes per second", ("limit", double(block_sync_rate_limit)/1000000));

fc::create_listener<tcp>(
my->thread_pool.get_executor(), logger, accept_timeout, listen_addr, extra_listening_log_info,
Expand Down
23 changes: 7 additions & 16 deletions plugins/net_plugin/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@

add_executable(auto_bp_peering_unittest auto_bp_peering_unittest.cpp)

target_link_libraries(auto_bp_peering_unittest eosio_chain)

target_include_directories(auto_bp_peering_unittest PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include" )

add_test(auto_bp_peering_unittest auto_bp_peering_unittest)

add_executable(rate_limit_parse_unittest rate_limit_parse_unittest.cpp)

target_link_libraries(rate_limit_parse_unittest net_plugin)

target_include_directories(rate_limit_parse_unittest PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include")

add_test(rate_limit_parse_unittest rate_limit_parse_unittest)
add_executable( test_net_plugin
auto_bp_peering_unittest.cpp
rate_limit_parse_unittest.cpp
main.cpp
)
target_link_libraries( test_net_plugin net_plugin eosio_testing eosio_chain_wrap )
add_test(NAME test_net_plugin COMMAND plugins/net_plugin/tests/test_net_plugin WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
3 changes: 1 addition & 2 deletions plugins/net_plugin/tests/auto_bp_peering_unittest.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#define BOOST_TEST_MODULE auto_bp_peering
#include <boost/test/included/unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include <eosio/net_plugin/auto_bp_peering.hpp>

struct mock_connection {
Expand Down
2 changes: 2 additions & 0 deletions plugins/net_plugin/tests/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#define BOOST_TEST_MODULE net_plugin
#include <boost/test/included/unit_test.hpp>
28 changes: 13 additions & 15 deletions plugins/net_plugin/tests/rate_limit_parse_unittest.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#define BOOST_TEST_MODULE rate_limit_parsing
#include <boost/test/included/unit_test.hpp>
#include "../net_plugin.cpp"
#include <boost/test/unit_test.hpp>
#include <eosio/net_plugin/net_utils.hpp>

BOOST_AUTO_TEST_CASE(test_parse_rate_limit) {
eosio::net_plugin_impl plugin_impl;
std::vector<std::string> p2p_addresses = {
"0.0.0.0:9876"
, "0.0.0.0:9776:0"
Expand All @@ -18,37 +16,37 @@ BOOST_AUTO_TEST_CASE(test_parse_rate_limit) {
, "0.0.0.0:9877:999999999999999999999999999TiB/s"
};
size_t which = 0;
auto [listen_addr, block_sync_rate_limit] = plugin_impl.parse_listen_address(p2p_addresses[which++]);
auto [listen_addr, block_sync_rate_limit] = eosio::net_utils::parse_listen_address(p2p_addresses[which++]);
BOOST_CHECK_EQUAL(listen_addr, "0.0.0.0:9876");
BOOST_CHECK_EQUAL(block_sync_rate_limit, 0u);
std::tie(listen_addr, block_sync_rate_limit) = plugin_impl.parse_listen_address(p2p_addresses[which++]);
std::tie(listen_addr, block_sync_rate_limit) = eosio::net_utils::parse_listen_address(p2p_addresses[which++]);
BOOST_CHECK_EQUAL(listen_addr, "0.0.0.0:9776");
BOOST_CHECK_EQUAL(block_sync_rate_limit, 0u);
std::tie(listen_addr, block_sync_rate_limit) = plugin_impl.parse_listen_address(p2p_addresses[which++]);
std::tie(listen_addr, block_sync_rate_limit) = eosio::net_utils::parse_listen_address(p2p_addresses[which++]);
BOOST_CHECK_EQUAL(listen_addr, "0.0.0.0:9877");
BOOST_CHECK_EQUAL(block_sync_rate_limit, 640000u);
std::tie(listen_addr, block_sync_rate_limit) = plugin_impl.parse_listen_address(p2p_addresses[which++]);
std::tie(listen_addr, block_sync_rate_limit) = eosio::net_utils::parse_listen_address(p2p_addresses[which++]);
BOOST_CHECK_EQUAL(listen_addr, "192.168.0.1:9878");
BOOST_CHECK_EQUAL(block_sync_rate_limit, 20971520u);
std::tie(listen_addr, block_sync_rate_limit) = plugin_impl.parse_listen_address(p2p_addresses[which++]);
std::tie(listen_addr, block_sync_rate_limit) = eosio::net_utils::parse_listen_address(p2p_addresses[which++]);
BOOST_CHECK_EQUAL(listen_addr, "localhost:9879");
BOOST_CHECK_EQUAL(block_sync_rate_limit, 500u);
std::tie(listen_addr, block_sync_rate_limit) = plugin_impl.parse_listen_address(p2p_addresses[which++]);
std::tie(listen_addr, block_sync_rate_limit) = eosio::net_utils::parse_listen_address(p2p_addresses[which++]);
BOOST_CHECK_EQUAL(listen_addr, "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:9876");
BOOST_CHECK_EQUAL(block_sync_rate_limit, 250000u);
std::tie(listen_addr, block_sync_rate_limit) = plugin_impl.parse_listen_address(p2p_addresses[which++]);
std::tie(listen_addr, block_sync_rate_limit) = eosio::net_utils::parse_listen_address(p2p_addresses[which++]);
BOOST_CHECK_EQUAL(listen_addr, "[::1]:9876");
BOOST_CHECK_EQUAL(block_sync_rate_limit, 250000u);
BOOST_CHECK_EXCEPTION(plugin_impl.parse_listen_address(p2p_addresses[which++]), eosio::chain::plugin_config_exception,
BOOST_CHECK_EXCEPTION(eosio::net_utils::parse_listen_address(p2p_addresses[which++]), eosio::chain::plugin_config_exception,
[](const eosio::chain::plugin_config_exception& e)
{return std::strstr(e.top_message().c_str(), "IPv6 addresses must be enclosed in square brackets");});
BOOST_CHECK_EXCEPTION(plugin_impl.parse_listen_address(p2p_addresses[which++]), eosio::chain::plugin_config_exception,
BOOST_CHECK_EXCEPTION(eosio::net_utils::parse_listen_address(p2p_addresses[which++]), eosio::chain::plugin_config_exception,
[](const eosio::chain::plugin_config_exception& e)
{return std::strstr(e.top_message().c_str(), "block sync rate limit must not be negative");});
BOOST_CHECK_EXCEPTION(plugin_impl.parse_listen_address(p2p_addresses[which++]), eosio::chain::plugin_config_exception,
BOOST_CHECK_EXCEPTION(eosio::net_utils::parse_listen_address(p2p_addresses[which++]), eosio::chain::plugin_config_exception,
[](const eosio::chain::plugin_config_exception& e)
{return std::strstr(e.top_message().c_str(), "invalid block sync rate limit specification");});
BOOST_CHECK_EXCEPTION(plugin_impl.parse_listen_address(p2p_addresses[which++]), eosio::chain::plugin_config_exception,
BOOST_CHECK_EXCEPTION(eosio::net_utils::parse_listen_address(p2p_addresses[which++]), eosio::chain::plugin_config_exception,
[](const eosio::chain::plugin_config_exception& e)
{return std::strstr(e.top_message().c_str(), "block sync rate limit specification overflowed");});
}

0 comments on commit 40cc421

Please sign in to comment.