1#include <xrpld/overlay/detail/OverlayImpl.h>
3#include <xrpld/app/misc/ValidatorList.h>
4#include <xrpld/app/misc/ValidatorSite.h>
5#include <xrpld/overlay/Cluster.h>
6#include <xrpld/overlay/detail/ConnectAttempt.h>
7#include <xrpld/overlay/detail/Handshake.h>
8#include <xrpld/overlay/detail/PeerImp.h>
9#include <xrpld/overlay/detail/ProtocolVersion.h>
10#include <xrpld/overlay/detail/TrafficCount.h>
11#include <xrpld/overlay/detail/Tuning.h>
12#include <xrpld/peerfinder/PeerfinderManager.h>
13#include <xrpld/rpc/ServerHandler.h>
14#include <xrpld/rpc/handlers/admin/status/GetCounts.h>
15#include <xrpld/rpc/json_body.h>
17#include <xrpl/basics/Log.h>
18#include <xrpl/basics/Resolver.h>
19#include <xrpl/basics/Slice.h>
20#include <xrpl/basics/base64.h>
21#include <xrpl/basics/base_uint.h>
22#include <xrpl/basics/chrono.h>
23#include <xrpl/basics/contract.h>
24#include <xrpl/basics/make_SSLContext.h>
25#include <xrpl/basics/random.h>
26#include <xrpl/basics/strHex.h>
27#include <xrpl/beast/core/LexicalCast.h>
28#include <xrpl/beast/insight/Collector.h>
29#include <xrpl/beast/net/IPAddress.h>
30#include <xrpl/beast/net/IPAddressConversion.h>
31#include <xrpl/beast/net/IPEndpoint.h>
32#include <xrpl/beast/rfc2616.h>
33#include <xrpl/beast/utility/PropertyStream.h>
34#include <xrpl/beast/utility/WrappedSink.h>
35#include <xrpl/beast/utility/instrumentation.h>
36#include <xrpl/config/BasicConfig.h>
37#include <xrpl/config/Constants.h>
38#include <xrpl/core/HashRouter.h>
39#include <xrpl/json/json_value.h>
40#include <xrpl/peerfinder/Config.h>
41#include <xrpl/peerfinder/Slot.h>
42#include <xrpl/peerfinder/make_Manager.h>
43#include <xrpl/protocol/BuildInfo.h>
44#include <xrpl/protocol/STTx.h>
45#include <xrpl/protocol/Serializer.h>
46#include <xrpl/protocol/SystemParameters.h>
47#include <xrpl/protocol/jss.h>
48#include <xrpl/resource/Fees.h>
49#include <xrpl/resource/ResourceManager.h>
50#include <xrpl/server/Handoff.h>
51#include <xrpl/server/Manifest.h>
52#include <xrpl/server/NetworkOPs.h>
53#include <xrpl/server/SimpleWriter.h>
54#include <xrpl/server/Wallet.h>
55#include <xrpl/server/Writer.h>
57#include <boost/algorithm/string/predicate.hpp>
58#include <boost/asio/bind_executor.hpp>
59#include <boost/asio/dispatch.hpp>
60#include <boost/asio/error.hpp>
61#include <boost/asio/executor_work_guard.hpp>
62#include <boost/asio/io_context.hpp>
63#include <boost/asio/ip/address.hpp>
64#include <boost/asio/post.hpp>
65#include <boost/asio/strand.hpp>
66#include <boost/beast/http/empty_body.hpp>
67#include <boost/beast/http/field.hpp>
68#include <boost/beast/http/status.hpp>
69#include <boost/lexical_cast.hpp>
70#include <boost/lexical_cast/bad_lexical_cast.hpp>
71#include <boost/lexical_cast/try_lexical_convert.hpp>
102static constexpr auto kUnl = (1 << 3);
136 boost::asio::bind_executor(
146 if (ec && ec != boost::asio::error::operation_aborted)
148 JLOG(
overlay_.journal_.error()) <<
"on_timer: " << ec.message();
153 overlay_.peerFinder_->oncePerSecond();
156 if (
overlay_.app_.config().txReduceRelayEnable)
173 boost::asio::io_context& ioContext,
189 app_.getJournal(
"PeerFinder"),
194 ,
slots_(app, *this, app.config())
198 [counts = traffic_.getCounts(), collector]() {
201 for (
auto const& pair : counts)
202 ret.
emplace(pair.first, TrafficGauges(pair.second.name, collector));
218 auto peerJournal =
app_.getJournal(
"Peer");
228 handoff.
moved =
true;
230 JLOG(journal.
debug()) <<
"Peer connection upgrade from " << remoteEndpoint;
233 auto const localEndpoint(streamPtr->next_layer().socket().local_endpoint(ec));
236 JLOG(journal.
debug()) << remoteEndpoint <<
" failed: " << ec.message();
242 if (consumer.disconnect(journal))
245 auto const [slot, result] =
peerFinder_->newInboundSlot(
252 handoff.
moved =
false;
253 JLOG(journal.
debug()) <<
"Peer " << remoteEndpoint <<
" refused, " <<
to_string(result);
262 return boost::iequals(s,
"peer");
265 handoff.
moved =
false;
273 if (!negotiatedVersion)
276 handoff.
moved =
false;
278 slot, request, remoteEndpoint.address(),
"Unable to agree on a protocol version");
287 handoff.
moved =
false;
289 makeErrorResponse(slot, request, remoteEndpoint.address(),
"Incorrect security cookie");
301 remoteEndpoint.address(),
304 consumer.setPublicKey(publicKey);
309 bool const reserved =
static_cast<bool>(
app_.getCluster().member(publicKey)) ||
310 app_.getPeerReservations().contains(publicKey);
311 auto const result =
peerFinder_->activate(slot, publicKey, reserved);
312 if (result != peer_finder::Result::Success)
315 JLOG(journal.
debug())
316 <<
"Peer " << remoteEndpoint <<
" redirected, " <<
to_string(result);
317 handoff.
moved =
false;
332 std::move(streamPtr),
340 auto const result =
peers_.emplace(peer->slot(), peer);
341 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::onHandoff : peer is inserted");
344 list_.emplace(peer.get(), peer);
348 handoff.
moved =
true;
353 JLOG(journal.
debug()) <<
"Peer " << remoteEndpoint <<
" fails handshake (" << e.
what()
357 handoff.
moved =
false;
372 return !versions.empty();
389 boost::beast::http::response<JsonBody> msg;
390 msg.version(request.version());
391 msg.result(boost::beast::http::status::service_unavailable);
395 ostr << remoteAddress;
396 msg.insert(
"Remote-Address", ostr.
str());
398 msg.insert(
"Content-Type",
"application/json");
399 msg.insert(boost::beast::http::field::connection,
"close");
404 ips.
append(_.address.toString());
406 msg.prepare_payload();
417 boost::beast::http::response<boost::beast::http::empty_body> msg;
418 msg.version(request.version());
419 msg.result(boost::beast::http::status::bad_request);
420 msg.reason(
"Bad Request (" + text +
")");
422 msg.insert(
"Remote-Address", remoteAddress.to_string());
423 msg.insert(boost::beast::http::field::connection,
"close");
424 msg.prepare_payload();
433 XRPL_ASSERT(
work_,
"xrpl::OverlayImpl::connect : work is set");
438 JLOG(
journal_.info()) <<
"Over resource limit: " << remoteEndpoint;
445 JLOG(
journal_.debug()) <<
"Connect: No slot for " << remoteEndpoint <<
": "
458 app_.getJournal(
"Peer"),
462 list_.emplace(p.get(), p);
478 auto const result =
peers_.emplace(peer->slot(), peer);
479 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::addActive : peer is inserted");
484 auto const result =
ids_.emplace(
486 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::addActive : peer ID is inserted");
492 JLOG(journal.
debug()) <<
"activated";
504 auto const iter =
peers_.find(slot);
505 XRPL_ASSERT(iter !=
peers_.end(),
"xrpl::OverlayImpl::remove : valid input");
515 app_.getValidationPublicKey().has_value(),
524 auto bootstrapIps =
app_.config().ips.empty() ?
app_.config().ipsFixed :
app_.config().ips;
528 if (bootstrapIps.empty())
531 bootstrapIps.emplace_back(
"r.ripple.com 51235");
534 bootstrapIps.emplace_back(
"sahyadri.isrdc.in 51235");
537 bootstrapIps.emplace_back(
"hubs.xrpkuwait.com 51235");
540 bootstrapIps.emplace_back(
"hub.xrpl-commons.org 51235");
548 for (
auto const& addr : addresses)
550 if (addr.port() == 0)
566 if (!
app_.config().standalone() && !
app_.config().ipsFixed.empty())
569 app_.config().ipsFixed,
571 std::vector<beast::ip::Endpoint> ips;
572 ips.reserve(addresses.size());
574 for (auto& addr : addresses)
576 if (addr.port() == 0)
578 ips.emplace_back(addr.address(), kDefaultPeerPort);
582 ips.emplace_back(addr);
592 list_.emplace(timer.get(), timer);
603 cond_.wait(lock, [
this] {
return list_.empty(); });
618 auto const stats =
traffic_.getCounts();
619 for (
auto const& pair : stats)
622 item[
"category"] = pair.second.name;
624 item[
"messages_in"] =
std::to_string(pair.second.messagesIn.load());
626 item[
"messages_out"] =
std::to_string(pair.second.messagesOut.load());
646 auto const result(
ids_.emplace(
648 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::activate : peer ID is inserted");
652 JLOG(journal.
debug()) <<
"activated";
655 XRPL_ASSERT(
size(),
"xrpl::OverlayImpl::activate : nonzero peers");
670 auto const& journal = from->pJournal();
677 auto const total =
static_cast<std::size_t>(m->list_size());
679 bool skippedUntrusted =
false;
681 protocol::TMManifests
relay;
685 auto& s = m->list().Get(i).stobject();
689 auto const serialized = mo->serialized;
693 bool const isTrusted =
app_.getValidators().listed(mo->masterKey);
700 if (untrusted >= maxUntrusted)
702 skippedUntrusted =
true;
708 auto const result =
app_.getValidatorManifests().applyManifest(
721 "xrpl::OverlayImpl::onManifests : manifest "
722 "deserialization succeeded");
724 app_.getOPs().pubManifest(*mo);
727 relay.add_list()->set_stobject(s);
733 auto db =
app_.getWalletDB().checkoutDb();
740 JLOG(journal.debug()) <<
"Malformed manifest #" << i + 1 <<
": " <<
strHex(s);
745 if (skippedUntrusted)
751 JLOG(journal.warn()) <<
"Manifests: message had " << total
752 <<
" entries; processed all trusted plus the first " << maxUntrusted
756 if (!
relay.list().empty())
801 pv[jss::public_key] =
base64Encode(sp->getNodePublic().data(), sp->getNodePublic().size());
802 pv[jss::type] = sp->slot()->inbound() ? jss::in : jss::out;
806 pv[jss::ip] = sp->getRemoteAddress().address().to_string();
807 if (sp->slot()->inbound())
809 if (
auto port = sp->slot()->listeningPort())
810 pv[jss::port] = *port;
814 pv[jss::port] = sp->getRemoteAddress().port();
819 auto version{sp->getVersion()};
820 if (!version.empty())
828 sp->ledgerRange(minSeq, maxSeq);
829 if (minSeq != 0 || maxSeq != 0)
839 bool const humanReadable =
false;
840 bool const admin =
false;
841 bool const counters =
false;
843 json::Value serverInfo =
app_.getOPs().getServerInfo(humanReadable, admin, counters);
847 serverInfo.
removeMember(jss::load_factor_fee_escalation);
851 if (serverInfo.
isMember(jss::validated_ledger))
853 json::Value& validatedLedger = serverInfo[jss::validated_ledger];
874 if (validators.
isMember(jss::publisher_lists))
876 json::Value& publisherLists = validators[jss::publisher_lists];
878 for (
auto& publisher : publisherLists)
880 publisher.removeMember(jss::list);
890 if (validatorSites.
isMember(jss::validator_sites))
892 validators[jss::validator_sites] = std::move(validatorSites[jss::validator_sites]);
905 json.append(peer->json());
916 boost::beast::http::response<JsonBody> msg;
917 msg.version(req.version());
918 msg.result(boost::beast::http::status::ok);
920 msg.insert(
"Content-Type",
"application/json");
921 msg.insert(
"Connection",
"close");
941 msg.prepare_payload();
953 if (!req.target().starts_with(kPrefix) || !
setup_.vlEnabled)
958 boost::beast::http::response<JsonBody> msg;
959 msg.version(req.version());
961 msg.insert(
"Content-Type",
"application/json");
962 msg.insert(
"Connection",
"close");
964 auto fail = [&msg, &handoff](
auto status) {
966 msg.insert(
"Content-Length",
"0");
970 msg.prepare_payload();
977 if (
auto slash = key.
find(
'/'); slash != std::string_view::npos)
979 auto verString = key.
substr(0, slash);
980 if (!boost::conversion::try_lexical_convert(verString, version))
981 return fail(boost::beast::http::status::bad_request);
982 key = key.
substr(slash + 1);
986 return fail(boost::beast::http::status::bad_request);
989 auto vl =
app_.getValidators().getAvailable(key, version);
994 return fail(boost::beast::http::status::not_found);
998 return fail(boost::beast::http::status::bad_request);
1001 msg.result(boost::beast::http::status::ok);
1005 msg.prepare_payload();
1013 if (req.target() !=
"/health")
1015 boost::beast::http::response<JsonBody> msg;
1016 msg.version(req.version());
1018 msg.insert(
"Content-Type",
"application/json");
1019 msg.insert(
"Connection",
"close");
1023 int lastValidatedLedgerAge = -1;
1024 if (info.isMember(jss::validated_ledger))
1025 lastValidatedLedgerAge = info[jss::validated_ledger][jss::age].asInt();
1026 bool amendmentBlocked =
false;
1027 if (info.isMember(jss::amendment_blocked))
1028 amendmentBlocked =
true;
1029 int const numberPeers = info[jss::peers].asInt();
1030 std::string const serverState = info[jss::server_state].asString();
1031 auto loadFactor = info[jss::load_factor_server].asDouble() / info[jss::load_base].asDouble();
1033 enum class HealthState { Healthy, Warning, Critical };
1034 auto health = HealthState::Healthy;
1035 auto setHealth = [&health](HealthState state) { health =
std::max(health, state); };
1038 if (lastValidatedLedgerAge >= 7 || lastValidatedLedgerAge < 0)
1040 msg.body()[jss::info][jss::validated_ledger] = lastValidatedLedgerAge;
1041 if (lastValidatedLedgerAge < 20)
1043 setHealth(HealthState::Warning);
1047 setHealth(HealthState::Critical);
1051 if (amendmentBlocked)
1053 msg.body()[jss::info][jss::amendment_blocked] =
true;
1054 setHealth(HealthState::Critical);
1057 if (numberPeers <= 7)
1059 msg.body()[jss::info][jss::peers] = numberPeers;
1060 if (numberPeers != 0)
1062 setHealth(HealthState::Warning);
1066 setHealth(HealthState::Critical);
1070 if (!(serverState ==
"full" || serverState ==
"validating" || serverState ==
"proposing"))
1072 msg.body()[jss::info][jss::server_state] = serverState;
1073 if (serverState ==
"syncing" || serverState ==
"tracking" || serverState ==
"connected")
1075 setHealth(HealthState::Warning);
1079 setHealth(HealthState::Critical);
1083 if (loadFactor > 100)
1085 msg.body()[jss::info][jss::load_factor] = loadFactor;
1086 if (loadFactor < 1000)
1088 setHealth(HealthState::Warning);
1092 setHealth(HealthState::Critical);
1098 case HealthState::Healthy:
1099 msg.result(boost::beast::http::status::ok);
1101 case HealthState::Warning:
1102 msg.result(boost::beast::http::status::service_unavailable);
1104 case HealthState::Critical:
1105 msg.result(boost::beast::http::status::internal_server_error);
1109 msg.prepare_payload();
1143 active =
ids_.size();
1144 disabled = enabledInSkip = 0;
1149 for (
auto& [
id, w] :
ids_)
1151 if (p = w.lock(); p !=
nullptr)
1153 bool const reduceRelayEnabled = p->txReduceRelayEnabled();
1155 if (!reduceRelayEnabled)
1162 else if (reduceRelayEnabled)
1182 auto const iter =
ids_.find(
id);
1183 if (iter !=
ids_.end())
1184 return iter->second.lock();
1196 for (
auto const& e :
ids_)
1198 if (peer = e.second.lock(); peer !=
nullptr)
1200 if (peer->getNodePublic() == pubKey)
1217 if (
auto const toSkip =
app_.getHashRouter().shouldRelay(uid))
1221 if (!toSkip->contains(p->id()))
1239 if (
auto const toSkip =
app_.getHashRouter().shouldRelay(uid))
1243 if (!toSkip->contains(p->id()))
1264 struct CachedManifest
1271 app_.getValidatorManifests().forEachManifest(
1273 [&cached](
Manifest const& manifest) {
1275 {.masterKey = manifest.masterKey,
1276 .serialized = manifest.serialized,
1277 .hash = manifest.hash()});
1286 for (
auto const& e : cached)
1288 if (
app_.getValidators().listed(e.masterKey))
1306 protocol::TMManifests
tm;
1307 auto& hr =
app_.getHashRouter();
1308 tm.mutable_list()->Reserve(
static_cast<int>(selected.
size()));
1309 for (
auto const* e : selected)
1311 tm.add_list()->set_stobject(e->serialized.data(), e->serialized.size());
1312 hr.addSuppression(e->hash);
1317 if (
tm.list_size() != 0)
1332 bool relay = tx.has_value();
1335 auto& txn = tx->get();
1344 JLOG(
journal_.debug()) <<
"Could not construct STTx: " <<
hash;
1356 if (!
app_.config().txReduceRelayEnable)
1360 JLOG(
journal_.trace()) <<
"not relaying tx, total peers " << peers.
size();
1361 for (
auto const& p : peers)
1362 p->addTxQueue(
hash);
1366 auto& txn = tx->get();
1369 auto const minRelay =
app_.config().txReduceRelayMinPeers + disabled;
1371 if (!
app_.config().txReduceRelayEnable || total <= minRelay)
1373 for (
auto const& p : peers)
1375 if (
app_.config().txReduceRelayEnable ||
app_.config().txReduceRelayMetrics)
1383 auto const enabledTarget =
app_.config().txReduceRelayMinPeers +
1384 ((total - minRelay) *
app_.config().txRelayPercentage / 100);
1388 if (enabledTarget > enabledInSkip)
1391 JLOG(
journal_.trace()) <<
"relaying tx, total peers " << peers.
size() <<
" selected "
1392 << enabledTarget <<
" skip " << toSkip.
size() <<
" disabled "
1397 for (
auto const& p : peers)
1400 if (!p->txReduceRelayEnabled())
1404 else if (enabledAndRelayed < enabledTarget)
1406 enabledAndRelayed++;
1411 p->addTxQueue(
hash);
1422 list_.erase(&child);
1443 work_ = std::nullopt;
1446 for (
auto const& element :
list_)
1452 for (
auto const& child : children)
1454 if (child !=
nullptr)
1463 for (
auto const& addr : result)
1470 auto const result =
peerFinder_->buildEndpointsForPeers();
1471 for (
auto const& e : result)
1476 auto const iter =
peers_.find(e.first);
1477 if (iter !=
peers_.end())
1478 peer = iter->second.lock();
1481 peer->sendEndpoints(e.second.begin(), e.second.end());
1489 if (p->txReduceRelayEnabled())
1497 protocol::TMSquelch m;
1499 m.set_validatorpubkey(validator.data(), validator.size());
1501 m.set_squelchduration(squelchDuration);
1530 protocol::MessageType type)
1532 if (!
slots_.baseSquelchReady())
1535 if (!
strand_.running_in_this_thread())
1540 [
this, key = key, validator = validator, peers = std::move(peers), type]()
mutable {
1547 for (
auto id : peers)
1549 slots_.updateSlotAndSquelch(key, validator,
id, type, [&]() {
1560 protocol::MessageType type)
1562 if (!
slots_.baseSquelchReady())
1565 if (!
strand_.running_in_this_thread())
1571 [
this, key = key, validator = validator, peer, type]() {
1578 slots_.updateSlotAndSquelch(key, validator, peer, type, [&]() {
1586 if (!
strand_.running_in_this_thread())
1592 slots_.deletePeer(
id,
true);
1598 if (!
strand_.running_in_this_thread())
1604 slots_.deleteIdlePeers();
1623 set(ip,
"public_ip", section);
1626 boost::system::error_code ec;
1627 setup.
publicIp = boost::asio::ip::make_address(ip, ec);
1635 JLOG(j.
warn()) <<
"Endpoint verification is disabled. This is a "
1636 "security risk and should only be used for "
1643 auto const& values = section.
values();
1645 if (values.size() > 1)
1650 bool crawlEnabled =
true;
1653 if (values.size() == 1)
1657 crawlEnabled = boost::lexical_cast<bool>(values.front());
1659 catch (boost::bad_lexical_cast
const&)
1662 "Configured [crawl] section has invalid value: " + values.front());
1701 if (
id ==
"testnet")
1713 "Configured [network_id] section is invalid: must be a number "
1714 "or one of the strings 'main', 'testnet' or 'devnet'.");
1727 boost::asio::io_context& ioContext,
1732 app, setup, serverHandler, resourceManager, resolver, ioContext, config, collector);
A generic endpoint for log messages.
std::string const & name() const
Returns the name of this source.
void add(Source &source)
Add a child source.
Wraps a Journal::Sink to prefix its output with a string.
std::shared_ptr< Collector > ptr
A version-independent IP address and port combination.
Value removeMember(char const *key)
Remove and return the named member.
Value & append(Value const &value)
Append value to array at the end.
bool isMember(char const *key) const
Return true if the object has a member named key.
Holds unparsed configuration information.
void legacy(std::string const §ion, std::string value)
Set a value that is not a key/value pair.
Section & section(std::string const &name)
Returns the section with the given name.
Child(OverlayImpl &overlay)
void deletePeer(Peer::id_t id)
Called when the peer is deleted.
boost::asio::io_context & ioContext_
resource::Manager & resourceManager()
bool processRequest(http_request_type const &req, Handoff &handoff)
Handles non-peer protocol requests.
json::Value getOverlayInfo() const
Returns information about peers on the overlay network.
boost::asio::ip::address address_type
static bool isPeerUpgrade(http_request_type const &request)
void addActive(std::shared_ptr< PeerImp > const &peer)
boost::system::error_code error_code
bool processCrawl(http_request_type const &req, Handoff &handoff)
Handles crawl requests.
void broadcast(protocol::TMProposeSet const &m) override
Broadcast a proposal.
bool processHealth(http_request_type const &req, Handoff &handoff)
Handles health requests.
void activate(std::shared_ptr< PeerImp > const &peer)
Called when a peer has connected successfully This is called after the peer handshake has been comple...
std::optional< boost::asio::executor_work_guard< boost::asio::io_context::executor_type > > work_
void connect(beast::ip::Endpoint const &remoteEndpoint) override
Establish a peer connection to the specified endpoint.
peer_finder::Manager & peerFinder()
void remove(std::shared_ptr< peer_finder::Slot > const &slot)
std::set< Peer::id_t > relay(protocol::TMProposeSet const &m, uint256 const &uid, PublicKey const &validator) override
Relay a proposal.
std::size_t size() const override
The number of active peers on the network Active peers are only those peers that have completed the h...
static bool isUpgrade(boost::beast::http::header< true, Fields > const &req)
ServerHandler & serverHandler_
void onManifests(std::shared_ptr< protocol::TMManifests > const &m, std::shared_ptr< PeerImp > const &from)
static std::shared_ptr< Writer > makeErrorResponse(std::shared_ptr< peer_finder::Slot > const &slot, http_request_type const &request, address_type remoteAddress, std::string const &msg)
std::shared_ptr< Writer > makeRedirectResponse(std::shared_ptr< peer_finder::Slot > const &slot, http_request_type const &request, address_type remoteAddress)
Handoff onHandoff(std::unique_ptr< stream_type > &&bundle, http_request_type &&request, endpoint_type remoteEndpoint) override
Conditionally accept an incoming HTTP request.
peer_finder::StoreSqdb store_
reduce_relay::Slots< UptimeClock > slots_
hash_map< Peer::id_t, std::weak_ptr< PeerImp > > ids_
void deleteIdlePeers()
Check if peers stopped relaying messages and if slots stopped receiving messages from the validator.
OverlayImpl(Application &app, Setup setup, ServerHandler &serverHandler, resource::Manager &resourceManager, Resolver &resolver, boost::asio::io_context &ioContext, BasicConfig const &config, beast::insight::Collector::ptr const &collector)
void squelch(PublicKey const &validator, Peer::id_t const id, std::uint32_t squelchDuration) const override
Squelch handler.
void reportInboundTraffic(TrafficCount::Category cat, int bytes)
std::shared_ptr< Message > manifestMessage_
void sendTxQueue() const
Send once a second transactions' hashes aggregated by peers.
std::optional< std::uint32_t > manifestListSeq_
std::unique_ptr< peer_finder::Manager > peerFinder_
void onWrite(beast::PropertyStream::Map &stream) override
Subclass override.
resource::Manager & resourceManager_
std::atomic< Peer::id_t > nextId_
json::Value getServerCounts()
Returns information about the local server's performance counters.
std::recursive_mutex mutex_
beast::Journal const journal_
json::Value json() override
Return diagnostics on the status of all peers.
boost::asio::ip::tcp::endpoint endpoint_type
void forEach(UnaryFunc &&f) const
void onPeerDeactivate(Peer::id_t id)
boost::asio::strand< boost::asio::io_context::executor_type > strand_
static std::string makePrefix(std::uint32_t id)
Setup const & setup() const
metrics::TxMetrics txMetrics_
boost::container::flat_map< Child *, std::weak_ptr< Child > > list_
int limit() override
Returns the maximum number of peers we are configured to allow.
std::condition_variable_any cond_
json::Value getUnlInfo()
Returns information about the local server's UNL.
std::shared_ptr< Message > getManifestsMessage()
std::shared_ptr< Peer > findPeerByPublicKey(PublicKey const &pubKey) override
Returns the peer with the matching public key, or null.
hash_map< std::shared_ptr< peer_finder::Slot >, std::weak_ptr< PeerImp > > peers_
bool processValidatorList(http_request_type const &req, Handoff &handoff)
Handles validator list requests.
void checkTracking(std::uint32_t) override
Calls the checkTracking function on each peer.
json::Value getServerInfo()
Returns information about the local server.
void updateSlotAndSquelch(uint256 const &key, PublicKey const &validator, std::set< Peer::id_t > &&peers, protocol::MessageType type)
Updates message count for validator/peer.
void reportOutboundTraffic(TrafficCount::Category cat, int bytes)
std::shared_ptr< Peer > findPeerByShortID(Peer::id_t const &id) const override
Returns the peer with the matching short id, or null.
PeerSequence getActivePeers() const override
Returns a sequence representing the current list of peers.
void unsquelch(PublicKey const &validator, Peer::id_t id) const override
Unsquelch handler.
std::vector< std::shared_ptr< Peer > > PeerSequence
std::uint32_t id_t
Uniquely identifies a peer.
std::vector< std::string > const & values() const
Returns all the values in the section.
virtual std::pair< std::shared_ptr< Slot >, Result > newOutboundSlot(beast::ip::Endpoint const &remoteEndpoint)=0
Create a new outbound slot with the specified remote endpoint.
Tracks load and resource consumption.
virtual Consumer newOutboundEndpoint(beast::ip::Endpoint const &address)=0
Create a new endpoint keyed by outbound IP address and port.
T duration_cast(T... args)
T emplace_back(T... args)
bool isPublic(Address const &addr)
Returns true if the address is a public routable address.
bool isKeepAlive(boost::beast::http::message< IsRequest, Body, Fields > const &m)
Result splitCommas(FwdIt first, FwdIt last)
constexpr Out lexicalCastThrow(In in)
Convert from one type to another, throw on error.
JSON (JavaScript Object Notation).
@ Array
array value (ordered list)
@ Object
object value (collection of name/value pairs).
std::string const & getFullVersionString()
Full server version string.
static constexpr auto kDisabled
static constexpr auto kOverlay
static constexpr auto kUnl
static constexpr auto kServerCounts
static constexpr auto kServerInfo
Config makeConfig(xrpl::Config const &cfg, std::uint16_t port, bool validationPublicKey, int ipLimit, bool verifyEndpoints)
Charge const kFeeMalformedRequest
Schedule of fees charged for imposing load on the server.
static constexpr auto kCheckIdlePeers
How often we check for idle peers (seconds).
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::vector< ProtocolVersion > parseProtocolVersions(boost::beast::string_view const &value)
Parse a set of protocol versions.
bool set(T &target, std::string const &name, Section const §ion)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
std::optional< uint256 > makeSharedValue(stream_type &ssl, beast::Journal journal)
Computes a shared value based on the SSL connection state.
Stopwatch & stopwatch()
Returns an instance of a wall clock.
T get(Section const §ion, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
std::string strHex(FwdIt begin, FwdIt end)
std::optional< ProtocolVersion > negotiateProtocolVersion(std::vector< ProtocolVersion > const &versions)
Given a list of supported protocol versions, choose the one we prefer.
std::string to_string(BaseUInt< Bits, Tag > const &a)
void addValidatorManifest(soci::session &session, std::string const &serialized)
addValidatorManifest Saves the manifest of a validator to the database.
std::optional< Manifest > deserializeManifest(Slice s, beast::Journal journal)
Constructs Manifest from serialized string.
@ Uncapped
Bypasses the cap (listed/trusted or config manifests).
@ Capped
Subject to the untrusted cap (unlisted peer gossip).
Slice makeSlice(std::array< T, N > const &a)
std::shared_ptr< boost::asio::ssl::context > makeSslContext(std::string const &cipherList)
Create a self-signed SSL context that allows anonymous Diffie Hellman.
std::string base64Encode(std::uint8_t const *data, std::size_t len)
std::unique_ptr< Overlay > makeOverlay(Application &app, Overlay::Setup const &setup, ServerHandler &serverHandler, resource::Manager &resourceManager, Resolver &resolver, boost::asio::io_context &ioContext, BasicConfig const &config, beast::insight::Collector::ptr const &collector)
Creates the implementation of Overlay.
constexpr Number squelch(Number const &x, Number const &limit) noexcept
beast::xor_shift_engine & defaultPrng()
Return the default random engine.
std::shared_ptr< Message > makeSquelchMessage(PublicKey const &validator, bool squelch, uint32_t squelchDuration)
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
constexpr std::size_t untrustedManifestCount(std::optional< std::size_t > const &configured)
Number of untrusted manifests to store in cache and allowed in one Manifest message.
Overlay::Setup setupOverlay(BasicConfig const &config, beast::Journal j)
json::Value getCountsJson(Application &app, int minObjectCount)
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
PublicKey verifyHandshake(boost::beast::http::fields const &headers, xrpl::uint256 const &sharedValue, std::optional< std::uint32_t > networkID, beast::ip::Address publicIp, beast::ip::Address remote, Application &app)
Validate header fields necessary for upgrading the link to the peer protocol.
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
@ Accepted
Manifest is valid.
T shared_from_this(T... args)
static boost::asio::ip::tcp::endpoint toAsioEndpoint(ip::Endpoint const &address)
static ip::Endpoint fromAsio(boost::asio::ip::address const &address)
Used to indicate the result of a server connection handoff.
std::shared_ptr< Writer > response
static constexpr auto kUnl
static constexpr auto kCounts
static constexpr auto kOverlay
static constexpr auto kServer
void onTimer(error_code ec)
boost::asio::basic_waitable_timer< clock_type > timer
Timer(OverlayImpl &overlay)
std::uint32_t crawlOptions
std::optional< std::uint32_t > networkID
beast::ip::Address publicIp
std::shared_ptr< boost::asio::ssl::context > context
static constexpr auto kOverlay
static constexpr auto kVl
static constexpr auto kCrawl
static constexpr auto kNetworkId
PeerFinder configuration settings.