Skip to content

Commit

Permalink
Merge pull request #1115 from AntelopeIO/GH-1101-p2p-no-blocks
Browse files Browse the repository at this point in the history
P2P: Add p2p-listen-endpoint :trx & :blk support
  • Loading branch information
heifner authored Jan 27, 2025
2 parents f15440e + ee00bd8 commit 10a0ecb
Show file tree
Hide file tree
Showing 7 changed files with 682 additions and 96 deletions.
4 changes: 2 additions & 2 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5852,8 +5852,8 @@ void controller::validate_tapos( const transaction& trx )const { try {

//Verify TaPoS block summary has correct ID prefix, and that this block's time is not past the expiration
EOS_ASSERT(trx.verify_reference_block(tapos_block_summary.block_id), invalid_ref_block_exception,
"Transaction's reference block did not match. Is this transaction from a different fork?",
("tapos_summary", tapos_block_summary));
"Transaction's reference block ${rb} did not match ${bs}. Is this transaction from a different fork?",
("rb", trx.ref_block_num)("bs", tapos_block_summary.block_id));
} FC_CAPTURE_AND_RETHROW() }

void controller::validate_db_available_size() const {
Expand Down
92 changes: 76 additions & 16 deletions plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,89 @@ namespace detail {
return block_sync_rate_limit;
}

/// @return host, port, remainder
inline std::tuple<std::string, std::string, std::string> split_host_port_remainder(const std::string& peer_add, bool should_throw) {
using std::string;
// host:port[:trx|:blk][:<rate>]
if (peer_add.empty()) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception, "Address specification is empty" );
return {};
}

auto colon_count = std::count(peer_add.begin(), peer_add.end(), ':');
string::size_type end_bracket = 0;
if (peer_add[0] == '[') {
end_bracket = peer_add.find(']');
if (end_bracket == string::npos) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
"Invalid address specification ${a}, IPv6 no closing square bracket", ("a", peer_add) );
return {};
}
} else if (colon_count >= 7) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
"Invalid address specification ${a}; IPv6 addresses must be enclosed in square brackets.", ("a", peer_add));
return {};

} else if (colon_count < 1 || colon_count > 3) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
"Invalid address specification ${a}; unexpected number of colons.", ("a", peer_add));
return {};
}
string::size_type colon = peer_add.find(':', end_bracket+1);
if (colon == string::npos) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
"Invalid address specification ${a}; missing port specification.", ("a", peer_add));
return {};
}
if (end_bracket != 0 && end_bracket+1 != colon) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
"Invalid address specification ${a}; unexpected character after ']'.", ("a", peer_add));
return {};
}
string::size_type colon2 = peer_add.find(':', colon + 1);
string host = peer_add.substr( 0, colon );
string port = peer_add.substr( colon + 1, colon2 == string::npos ? string::npos : colon2 - (colon + 1));
string remainder = colon2 == string::npos ? "" : peer_add.substr( colon2 + 1 );
return {std::move(host), std::move(port), std::move(remainder)};
}

} // namespace detail

/// @return host, port, type. returns empty on invalid peer_add, does not throw
inline std::tuple<std::string, std::string, std::string> split_host_port_type(const std::string& peer_add) {

using std::string;
// host:port[:trx|:blk][:<rate>] // rate is discarded
if (peer_add.empty()) return {};

constexpr bool should_throw = false;
auto [host, port, remainder] = detail::split_host_port_remainder(peer_add, should_throw);
if (host.empty() || port.empty()) return {};

std::string type;
if (remainder.starts_with("blk") || remainder.starts_with("trx")) {
type = remainder.substr(0, 3);
}

return {std::move(host), std::move(port), std::move(type)};
}

/// @return listen address and block sync rate limit (in bytes/sec) of address string
/// @throws chain::plugin_config_exception on invalid address
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);
}
constexpr bool should_throw = true;
auto [host, port, remainder] = detail::split_host_port_remainder(address, should_throw);
EOS_ASSERT(!host.empty() && !port.empty(), chain::plugin_config_exception,
"Invalid address specification ${a}; host or port missing.", ("a", address));
auto listen_addr = host + ":" + port;
auto limit = remainder;
auto last_colon_location = remainder.rfind(':');
if (last_colon_location != std::string::npos) {
limit = std::string(remainder, last_colon_location+1);
}
auto block_sync_rate_limit = detail::parse_connection_rate_limit(limit);

return {listen_addr, block_sync_rate_limit};
return {std::move(listen_addr), block_sync_rate_limit};
}

} // namespace eosio::net_utils
Loading

0 comments on commit 10a0ecb

Please sign in to comment.