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>
103static constexpr auto kUnl = (1 << 3);
137 boost::asio::bind_executor(
147 if (ec && ec != boost::asio::error::operation_aborted)
149 JLOG(
overlay_.journal_.error()) <<
"on_timer: " << ec.message();
154 overlay_.peerFinder_->oncePerSecond();
157 if (
overlay_.app_.config().txReduceRelayEnable)
174 boost::asio::io_context& ioContext,
190 app_.getJournal(
"PeerFinder"),
195 ,
slots_(app, *this, app.config())
199 [counts = traffic_.getCounts(), collector]() {
202 for (
auto const& pair : counts)
203 ret.
emplace(pair.first, TrafficGauges(pair.second.name, collector));
219 auto peerJournal =
app_.getJournal(
"Peer");
229 handoff.
moved =
true;
231 JLOG(journal.
debug()) <<
"Peer connection upgrade from " << remoteEndpoint;
234 auto const localEndpoint(streamPtr->next_layer().socket().local_endpoint(ec));
237 JLOG(journal.
debug()) << remoteEndpoint <<
" failed: " << ec.message();
243 if (consumer.disconnect(journal))
246 auto const [slot, result] =
peerFinder_->newInboundSlot(
253 handoff.
moved =
false;
254 JLOG(journal.
debug()) <<
"Peer " << remoteEndpoint <<
" refused, " <<
to_string(result);
263 return boost::iequals(s,
"peer");
266 handoff.
moved =
false;
274 if (!negotiatedVersion)
277 handoff.
moved =
false;
279 slot, request, remoteEndpoint.address(),
"Unable to agree on a protocol version");
288 handoff.
moved =
false;
290 makeErrorResponse(slot, request, remoteEndpoint.address(),
"Incorrect security cookie");
302 remoteEndpoint.address(),
305 consumer.setPublicKey(publicKey);
310 bool const reserved =
app_.getCluster().isMember(publicKey) ||
311 app_.getPeerReservations().contains(publicKey);
312 auto const result =
peerFinder_->activate(slot, publicKey, reserved);
313 if (result != peer_finder::Result::Success)
316 JLOG(journal.
debug())
317 <<
"Peer " << remoteEndpoint <<
" redirected, " <<
to_string(result);
318 handoff.
moved =
false;
333 std::move(streamPtr),
341 auto const result =
peers_.emplace(peer->slot(), peer);
342 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::onHandoff : peer is inserted");
345 list_.emplace(peer.get(), peer);
349 handoff.
moved =
true;
354 JLOG(journal.
debug()) <<
"Peer " << remoteEndpoint <<
" fails handshake (" << e.
what()
358 handoff.
moved =
false;
373 return !versions.empty();
390 boost::beast::http::response<JsonBody> msg;
391 msg.version(request.version());
392 msg.result(boost::beast::http::status::service_unavailable);
396 ostr << remoteAddress;
397 msg.insert(
"Remote-Address", ostr.
str());
399 msg.insert(
"Content-Type",
"application/json");
400 msg.insert(boost::beast::http::field::connection,
"close");
405 ips.
append(_.address.toString());
407 msg.prepare_payload();
418 boost::beast::http::response<boost::beast::http::empty_body> msg;
419 msg.version(request.version());
420 msg.result(boost::beast::http::status::bad_request);
421 msg.reason(
"Bad Request (" + text +
")");
423 msg.insert(
"Remote-Address", remoteAddress.to_string());
424 msg.insert(boost::beast::http::field::connection,
"close");
425 msg.prepare_payload();
434 XRPL_ASSERT(
work_,
"xrpl::OverlayImpl::connect : work is set");
439 JLOG(
journal_.info()) <<
"Over resource limit: " << remoteEndpoint;
446 JLOG(
journal_.debug()) <<
"Connect: No slot for " << remoteEndpoint <<
": "
459 app_.getJournal(
"Peer"),
463 list_.emplace(p.get(), p);
479 auto const result =
peers_.emplace(peer->slot(), peer);
480 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::addActive : peer is inserted");
485 auto const result =
ids_.emplace(
487 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::addActive : peer ID is inserted");
493 JLOG(journal.
debug()) <<
"activated";
505 auto const iter =
peers_.find(slot);
506 XRPL_ASSERT(iter !=
peers_.end(),
"xrpl::OverlayImpl::remove : valid input");
516 app_.getValidationPublicKey().has_value(),
525 auto bootstrapIps =
app_.config().ips.empty() ?
app_.config().ipsFixed :
app_.config().ips;
529 if (bootstrapIps.empty())
532 bootstrapIps.emplace_back(
"r.ripple.com 51235");
535 bootstrapIps.emplace_back(
"sahyadri.isrdc.in 51235");
538 bootstrapIps.emplace_back(
"hubs.xrpkuwait.com 51235");
541 bootstrapIps.emplace_back(
"hub.xrpl-commons.org 51235");
549 for (
auto const& addr : addresses)
551 if (addr.port() == 0)
567 if (!
app_.config().standalone() && !
app_.config().ipsFixed.empty())
570 app_.config().ipsFixed,
572 std::vector<beast::ip::Endpoint> ips;
573 ips.reserve(addresses.size());
575 for (auto& addr : addresses)
577 if (addr.port() == 0)
579 ips.emplace_back(addr.address(), kDefaultPeerPort);
583 ips.emplace_back(addr);
593 list_.emplace(timer.get(), timer);
604 cond_.wait(lock, [
this] {
return list_.empty(); });
619 auto const stats =
traffic_.getCounts();
620 for (
auto const& pair : stats)
623 item[
"category"] = pair.second.name;
625 item[
"messages_in"] =
std::to_string(pair.second.messagesIn.load());
627 item[
"messages_out"] =
std::to_string(pair.second.messagesOut.load());
647 auto const result(
ids_.emplace(
649 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::activate : peer ID is inserted");
653 JLOG(journal.
debug()) <<
"activated";
656 XRPL_ASSERT(
size(),
"xrpl::OverlayImpl::activate : nonzero peers");
671 auto const& journal = from->pJournal();
678 auto const total =
static_cast<std::size_t>(m->list_size());
680 bool skippedUntrusted =
false;
682 protocol::TMManifests
relay;
686 auto& s = m->list().Get(i).stobject();
690 auto const serialized = mo->serialized;
694 bool const isTrusted =
app_.getValidators().listed(mo->masterKey);
701 if (untrusted >= maxUntrusted)
703 skippedUntrusted =
true;
709 auto const result =
app_.getValidatorManifests().applyManifest(
722 "xrpl::OverlayImpl::onManifests : manifest "
723 "deserialization succeeded");
725 app_.getOPs().pubManifest(*mo);
728 relay.add_list()->set_stobject(s);
734 auto db =
app_.getWalletDB().checkoutDb();
741 JLOG(journal.debug()) <<
"Malformed manifest #" << i + 1 <<
": " <<
strHex(s);
746 if (skippedUntrusted)
752 JLOG(journal.warn()) <<
"Manifests: message had " << total
753 <<
" entries; processed all trusted plus the first " << maxUntrusted
757 if (!
relay.list().empty())
802 pv[jss::public_key] =
base64Encode(sp->getNodePublic().data(), sp->getNodePublic().size());
803 pv[jss::type] = sp->slot()->inbound() ? jss::in : jss::out;
807 pv[jss::ip] = sp->getRemoteAddress().address().to_string();
808 if (sp->slot()->inbound())
810 if (
auto port = sp->slot()->listeningPort())
811 pv[jss::port] = *port;
815 pv[jss::port] = sp->getRemoteAddress().port();
820 auto version{sp->getVersion()};
821 if (!version.empty())
829 sp->ledgerRange(minSeq, maxSeq);
830 if (minSeq != 0 || maxSeq != 0)
840 bool const humanReadable =
false;
841 bool const admin =
false;
842 bool const counters =
false;
844 json::Value serverInfo =
app_.getOPs().getServerInfo(humanReadable, admin, counters);
848 serverInfo.
removeMember(jss::load_factor_fee_escalation);
852 if (serverInfo.
isMember(jss::validated_ledger))
854 json::Value& validatedLedger = serverInfo[jss::validated_ledger];
875 if (validators.
isMember(jss::publisher_lists))
877 json::Value& publisherLists = validators[jss::publisher_lists];
879 for (
auto& publisher : publisherLists)
881 publisher.removeMember(jss::list);
891 if (validatorSites.
isMember(jss::validator_sites))
893 validators[jss::validator_sites] = std::move(validatorSites[jss::validator_sites]);
906 json.append(peer->json());
917 boost::beast::http::response<JsonBody> msg;
918 msg.version(req.version());
919 msg.result(boost::beast::http::status::ok);
921 msg.insert(
"Content-Type",
"application/json");
922 msg.insert(
"Connection",
"close");
942 msg.prepare_payload();
954 if (!req.target().starts_with(kPrefix) || !
setup_.vlEnabled)
959 boost::beast::http::response<JsonBody> msg;
960 msg.version(req.version());
962 msg.insert(
"Content-Type",
"application/json");
963 msg.insert(
"Connection",
"close");
965 auto fail = [&msg, &handoff](
auto status) {
967 msg.insert(
"Content-Length",
"0");
971 msg.prepare_payload();
978 if (
auto slash = key.
find(
'/'); slash != std::string_view::npos)
980 auto verString = key.
substr(0, slash);
981 if (!boost::conversion::try_lexical_convert(verString, version))
982 return fail(boost::beast::http::status::bad_request);
983 key = key.
substr(slash + 1);
987 return fail(boost::beast::http::status::bad_request);
990 auto vl =
app_.getValidators().getAvailable(key, version);
995 return fail(boost::beast::http::status::not_found);
999 return fail(boost::beast::http::status::bad_request);
1002 msg.result(boost::beast::http::status::ok);
1006 msg.prepare_payload();
1014 if (req.target() !=
"/health")
1016 boost::beast::http::response<JsonBody> msg;
1017 msg.version(req.version());
1019 msg.insert(
"Content-Type",
"application/json");
1020 msg.insert(
"Connection",
"close");
1024 int lastValidatedLedgerAge = -1;
1025 if (info.isMember(jss::validated_ledger))
1026 lastValidatedLedgerAge = info[jss::validated_ledger][jss::age].asInt();
1027 bool amendmentBlocked =
false;
1028 if (info.isMember(jss::amendment_blocked))
1029 amendmentBlocked =
true;
1030 int const numberPeers = info[jss::peers].asInt();
1031 std::string const serverState = info[jss::server_state].asString();
1032 auto loadFactor = info[jss::load_factor_server].asDouble() / info[jss::load_base].asDouble();
1034 enum class HealthState { Healthy, Warning, Critical };
1035 auto health = HealthState::Healthy;
1036 auto setHealth = [&health](HealthState state) { health =
std::max(health, state); };
1039 if (lastValidatedLedgerAge >= 7 || lastValidatedLedgerAge < 0)
1041 msg.body()[jss::info][jss::validated_ledger] = lastValidatedLedgerAge;
1042 if (lastValidatedLedgerAge < 20)
1044 setHealth(HealthState::Warning);
1048 setHealth(HealthState::Critical);
1052 if (amendmentBlocked)
1054 msg.body()[jss::info][jss::amendment_blocked] =
true;
1055 setHealth(HealthState::Critical);
1058 if (numberPeers <= 7)
1060 msg.body()[jss::info][jss::peers] = numberPeers;
1061 if (numberPeers != 0)
1063 setHealth(HealthState::Warning);
1067 setHealth(HealthState::Critical);
1071 if (!(serverState ==
"full" || serverState ==
"validating" || serverState ==
"proposing"))
1073 msg.body()[jss::info][jss::server_state] = serverState;
1074 if (serverState ==
"syncing" || serverState ==
"tracking" || serverState ==
"connected")
1076 setHealth(HealthState::Warning);
1080 setHealth(HealthState::Critical);
1084 if (loadFactor > 100)
1086 msg.body()[jss::info][jss::load_factor] = loadFactor;
1087 if (loadFactor < 1000)
1089 setHealth(HealthState::Warning);
1093 setHealth(HealthState::Critical);
1099 case HealthState::Healthy:
1100 msg.result(boost::beast::http::status::ok);
1102 case HealthState::Warning:
1103 msg.result(boost::beast::http::status::service_unavailable);
1105 case HealthState::Critical:
1106 msg.result(boost::beast::http::status::internal_server_error);
1110 msg.prepare_payload();
1144 active =
ids_.size();
1145 disabled = enabledInSkip = 0;
1150 for (
auto& [
id, w] :
ids_)
1152 if (p = w.lock(); p !=
nullptr)
1154 bool const reduceRelayEnabled = p->txReduceRelayEnabled();
1156 if (!reduceRelayEnabled)
1163 else if (reduceRelayEnabled)
1183 auto const iter =
ids_.find(
id);
1184 if (iter !=
ids_.end())
1185 return iter->second.lock();
1197 for (
auto const& e :
ids_)
1199 if (peer = e.second.lock(); peer !=
nullptr)
1201 if (peer->getNodePublic() == pubKey)
1218 if (
auto const toSkip =
app_.getHashRouter().shouldRelay(uid))
1222 if (!toSkip->contains(p->id()))
1240 if (
auto const toSkip =
app_.getHashRouter().shouldRelay(uid))
1244 if (!toSkip->contains(p->id()))
1265 struct CachedManifest
1272 app_.getValidatorManifests().forEachManifest(
1274 [&cached](
Manifest const& manifest) {
1276 {.masterKey = manifest.masterKey,
1277 .serialized = manifest.serialized,
1278 .hash = manifest.hash()});
1287 for (
auto const& e : cached)
1289 if (
app_.getValidators().listed(e.masterKey))
1307 protocol::TMManifests
tm;
1308 auto& hr =
app_.getHashRouter();
1309 tm.mutable_list()->Reserve(
static_cast<int>(selected.
size()));
1310 for (
auto const* e : selected)
1312 tm.add_list()->set_stobject(e->serialized.data(), e->serialized.size());
1313 hr.addSuppression(e->hash);
1318 if (
tm.list_size() != 0)
1333 bool relay = tx.has_value();
1336 auto& txn = tx->get();
1345 JLOG(
journal_.debug()) <<
"Could not construct STTx: " <<
hash;
1357 if (!
app_.config().txReduceRelayEnable)
1361 JLOG(
journal_.trace()) <<
"not relaying tx, total peers " << peers.
size();
1362 for (
auto const& p : peers)
1364 if (p->txReduceRelayEnabled())
1365 p->addTxQueue(
hash);
1370 auto& txn = tx->get();
1373 auto const minRelay =
app_.config().txReduceRelayMinPeers + disabled;
1375 if (!
app_.config().txReduceRelayEnable || total <= minRelay)
1377 for (
auto const& p : peers)
1379 if (
app_.config().txReduceRelayEnable ||
app_.config().txReduceRelayMetrics)
1387 auto const enabledTarget =
app_.config().txReduceRelayMinPeers +
1388 ((total - minRelay) *
app_.config().txRelayPercentage / 100);
1392 if (enabledTarget > enabledInSkip)
1395 JLOG(
journal_.trace()) <<
"relaying tx, total peers " << peers.
size() <<
" selected "
1396 << enabledTarget <<
" skip " << toSkip.
size() <<
" disabled "
1401 for (
auto const& p : peers)
1404 if (!p->txReduceRelayEnabled())
1408 else if (enabledAndRelayed < enabledTarget)
1410 enabledAndRelayed++;
1415 p->addTxQueue(
hash);
1426 list_.erase(&child);
1447 work_ = std::nullopt;
1450 for (
auto const& element :
list_)
1456 for (
auto const& child : children)
1458 if (child !=
nullptr)
1467 for (
auto const& addr : result)
1474 auto const result =
peerFinder_->buildEndpointsForPeers();
1475 for (
auto const& e : result)
1480 auto const iter =
peers_.find(e.first);
1481 if (iter !=
peers_.end())
1482 peer = iter->second.lock();
1485 peer->sendEndpoints(e.second.begin(), e.second.end());
1493 if (p->txReduceRelayEnabled())
1501 protocol::TMSquelch m;
1503 m.set_validatorpubkey(validator.data(), validator.size());
1505 m.set_squelchduration(squelchDuration);
1534 protocol::MessageType type)
1536 if (!
slots_.baseSquelchReady())
1539 if (!
strand_.running_in_this_thread())
1544 [
this, key = key, validator = validator, peers = std::move(peers), type]()
mutable {
1551 for (
auto id : peers)
1553 slots_.updateSlotAndSquelch(key, validator,
id, type, [&]() {
1564 protocol::MessageType type)
1566 if (!
slots_.baseSquelchReady())
1569 if (!
strand_.running_in_this_thread())
1575 [
this, key = key, validator = validator, peer, type]() {
1582 slots_.updateSlotAndSquelch(key, validator, peer, type, [&]() {
1590 if (!
strand_.running_in_this_thread())
1596 slots_.deletePeer(
id,
true);
1602 if (!
strand_.running_in_this_thread())
1608 slots_.deleteIdlePeers();
1627 set(ip,
"public_ip", section);
1630 boost::system::error_code ec;
1631 setup.
publicIp = boost::asio::ip::make_address(ip, ec);
1639 JLOG(j.
warn()) <<
"Endpoint verification is disabled. This is a "
1640 "security risk and should only be used for "
1647 auto const& values = section.
values();
1649 if (values.size() > 1)
1654 bool crawlEnabled =
true;
1657 if (values.size() == 1)
1661 crawlEnabled = boost::lexical_cast<bool>(values.front());
1663 catch (boost::bad_lexical_cast
const&)
1666 "Configured [crawl] section has invalid value: {}", values.front()));
1705 if (
id ==
"testnet")
1717 "Configured [network_id] section is invalid: must be a number "
1718 "or one of the strings 'main', 'testnet' or 'devnet'.");
1731 boost::asio::io_context& ioContext,
1736 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)
static std::shared_ptr< Writer > makeErrorResponse(std::shared_ptr< peer_finder::Slot > const &slot, HttpRequestType const &request, AddressType remoteAddress, std::string const &msg)
boost::system::error_code ErrorCode
boost::asio::io_context & ioContext_
resource::Manager & resourceManager()
void squelch(PublicKey const &validator, Peer::ID const id, std::uint32_t squelchDuration) const override
Squelch handler.
std::set< Peer::ID > relay(protocol::TMProposeSet const &m, UInt256 const &uid, PublicKey const &validator) override
Relay a proposal.
json::Value getOverlayInfo() const
Returns information about peers on the overlay network.
bool processRequest(HttpRequestType const &req, Handoff &handoff)
Handles non-peer protocol requests.
bool processValidatorList(HttpRequestType const &req, Handoff &handoff)
Handles validator list requests.
void addActive(std::shared_ptr< PeerImp > const &peer)
std::atomic< Peer::ID > nextId_
void broadcast(protocol::TMProposeSet const &m) override
Broadcast a proposal.
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)
void onPeerDeactivate(Peer::ID id)
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)
std::shared_ptr< Writer > makeRedirectResponse(std::shared_ptr< peer_finder::Slot > const &slot, HttpRequestType const &request, AddressType remoteAddress)
peer_finder::StoreSqdb store_
reduce_relay::Slots< UptimeClock > slots_
void deleteIdlePeers()
Check if peers stopped relaying messages and if slots stopped receiving messages from the validator.
void unsquelch(PublicKey const &validator, Peer::ID id) const override
Unsquelch handler.
bool processHealth(HttpRequestType const &req, Handoff &handoff)
Handles health requests.
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_
HashMap< std::shared_ptr< peer_finder::Slot >, std::weak_ptr< PeerImp > > peers_
json::Value getServerCounts()
Returns information about the local server's performance counters.
std::recursive_mutex mutex_
bool processCrawl(HttpRequestType const &req, Handoff &handoff)
Handles crawl requests.
beast::Journal const journal_
json::Value json() override
Return diagnostics on the status of all peers.
void forEach(UnaryFunc &&f) const
std::shared_ptr< Peer > findPeerByShortID(Peer::ID const &id) const override
Returns the peer with the matching short id, or null.
Handoff onHandoff(std::unique_ptr< StreamType > &&bundle, HttpRequestType &&request, EndpointType remoteEndpoint) override
Conditionally accept an incoming HTTP request.
boost::asio::strand< boost::asio::io_context::executor_type > strand_
static std::string makePrefix(std::uint32_t id)
Setup const & setup() const
HashMap< Peer::ID, std::weak_ptr< PeerImp > > ids_
boost::asio::ip::address AddressType
static bool isPeerUpgrade(HttpRequestType const &request)
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_
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)
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.
boost::asio::ip::tcp::endpoint EndpointType
void deletePeer(Peer::ID id)
Called when the peer is deleted.
void checkTracking(std::uint32_t) override
Calls the checkTracking function on each peer.
json::Value getServerInfo()
Returns information about the local server.
void reportOutboundTraffic(TrafficCount::Category cat, int bytes)
PeerSequence getActivePeers() const override
Returns a sequence representing the current list of peers.
void updateSlotAndSquelch(UInt256 const &key, PublicKey const &validator, std::set< Peer::ID > &&peers, protocol::MessageType type)
Updates message count for validator/peer.
std::vector< std::shared_ptr< Peer > > PeerSequence
std::uint32_t ID
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.
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,...
beast::XorShiftEngine & defaultPrng()
Return the default random engine.
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)
boost::beast::http::request< boost::beast::http::dynamic_body > HttpRequestType
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::optional< UInt256 > makeSharedValue(StreamType &ssl, beast::Journal journal)
Computes a shared value based on the SSL connection state.
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
std::shared_ptr< Message > makeSquelchMessage(PublicKey const &validator, bool squelch, uint32_t squelchDuration)
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)
std::vector< ProtocolVersion > parseProtocolVersions(std::string_view value)
Parse a set of protocol versions.
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
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.
@ 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(ErrorCode ec)
boost::asio::basic_waitable_timer< ClockType > 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.