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/peerfinder/Slot.h>
14#include <xrpld/peerfinder/make_Manager.h>
15#include <xrpld/rpc/ServerHandler.h>
16#include <xrpld/rpc/handlers/admin/status/GetCounts.h>
17#include <xrpld/rpc/json_body.h>
19#include <xrpl/basics/Log.h>
20#include <xrpl/basics/Resolver.h>
21#include <xrpl/basics/Slice.h>
22#include <xrpl/basics/base64.h>
23#include <xrpl/basics/base_uint.h>
24#include <xrpl/basics/chrono.h>
25#include <xrpl/basics/contract.h>
26#include <xrpl/basics/make_SSLContext.h>
27#include <xrpl/basics/random.h>
28#include <xrpl/basics/strHex.h>
29#include <xrpl/beast/core/LexicalCast.h>
30#include <xrpl/beast/insight/Collector.h>
31#include <xrpl/beast/net/IPAddress.h>
32#include <xrpl/beast/net/IPAddressConversion.h>
33#include <xrpl/beast/net/IPEndpoint.h>
34#include <xrpl/beast/rfc2616.h>
35#include <xrpl/beast/utility/PropertyStream.h>
36#include <xrpl/beast/utility/WrappedSink.h>
37#include <xrpl/beast/utility/instrumentation.h>
38#include <xrpl/config/BasicConfig.h>
39#include <xrpl/config/Constants.h>
40#include <xrpl/core/HashRouter.h>
41#include <xrpl/json/json_value.h>
42#include <xrpl/protocol/BuildInfo.h>
43#include <xrpl/protocol/STTx.h>
44#include <xrpl/protocol/Serializer.h>
45#include <xrpl/protocol/SystemParameters.h>
46#include <xrpl/protocol/jss.h>
47#include <xrpl/resource/ResourceManager.h>
48#include <xrpl/server/Handoff.h>
49#include <xrpl/server/Manifest.h>
50#include <xrpl/server/NetworkOPs.h>
51#include <xrpl/server/SimpleWriter.h>
52#include <xrpl/server/Wallet.h>
53#include <xrpl/server/Writer.h>
55#include <boost/algorithm/string/predicate.hpp>
56#include <boost/asio/bind_executor.hpp>
57#include <boost/asio/dispatch.hpp>
58#include <boost/asio/error.hpp>
59#include <boost/asio/executor_work_guard.hpp>
60#include <boost/asio/io_context.hpp>
61#include <boost/asio/ip/address.hpp>
62#include <boost/asio/post.hpp>
63#include <boost/asio/strand.hpp>
64#include <boost/beast/http/empty_body.hpp>
65#include <boost/beast/http/field.hpp>
66#include <boost/beast/http/status.hpp>
67#include <boost/lexical_cast.hpp>
68#include <boost/lexical_cast/bad_lexical_cast.hpp>
69#include <boost/lexical_cast/try_lexical_convert.hpp>
100static constexpr auto kUnl = (1 << 3);
134 boost::asio::bind_executor(
144 if (ec && ec != boost::asio::error::operation_aborted)
146 JLOG(
overlay_.journal_.error()) <<
"on_timer: " << ec.message();
151 overlay_.peerFinder_->oncePerSecond();
154 if (
overlay_.app_.config().txReduceRelayEnable)
171 boost::asio::io_context& ioContext,
186 app_.getJournal(
"PeerFinder"),
191 ,
slots_(app, *this, app.config())
195 [counts =
traffic_.getCounts(), collector]() {
198 for (
auto const& pair : counts)
214 auto peerJournal =
app_.getJournal(
"Peer");
224 handoff.
moved =
true;
226 JLOG(journal.
debug()) <<
"Peer connection upgrade from " << remoteEndpoint;
229 auto const localEndpoint(streamPtr->next_layer().socket().local_endpoint(ec));
232 JLOG(journal.
debug()) << remoteEndpoint <<
" failed: " << ec.message();
238 if (consumer.disconnect(journal))
241 auto const [slot, result] =
peerFinder_->newInboundSlot(
248 handoff.
moved =
false;
249 JLOG(journal.
debug()) <<
"Peer " << remoteEndpoint <<
" refused, " <<
to_string(result);
258 return boost::iequals(s,
"peer");
261 handoff.
moved =
false;
269 if (!negotiatedVersion)
272 handoff.
moved =
false;
274 slot, request, remoteEndpoint.address(),
"Unable to agree on a protocol version");
283 handoff.
moved =
false;
285 makeErrorResponse(slot, request, remoteEndpoint.address(),
"Incorrect security cookie");
297 remoteEndpoint.address(),
300 consumer.setPublicKey(publicKey);
305 bool const reserved =
static_cast<bool>(
app_.getCluster().member(publicKey)) ||
306 app_.getPeerReservations().contains(publicKey);
307 auto const result =
peerFinder_->activate(slot, publicKey, reserved);
308 if (result != PeerFinder::Result::Success)
311 JLOG(journal.
debug())
312 <<
"Peer " << remoteEndpoint <<
" redirected, " <<
to_string(result);
313 handoff.
moved =
false;
328 std::move(streamPtr),
336 auto const result =
peers_.emplace(peer->slot(), peer);
337 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::onHandoff : peer is inserted");
340 list_.emplace(peer.get(), peer);
344 handoff.
moved =
true;
349 JLOG(journal.
debug()) <<
"Peer " << remoteEndpoint <<
" fails handshake (" << e.
what()
353 handoff.
moved =
false;
368 return !versions.empty();
385 boost::beast::http::response<JsonBody> msg;
386 msg.version(request.version());
387 msg.result(boost::beast::http::status::service_unavailable);
391 ostr << remoteAddress;
392 msg.insert(
"Remote-Address", ostr.
str());
394 msg.insert(
"Content-Type",
"application/json");
395 msg.insert(boost::beast::http::field::connection,
"close");
400 ips.
append(_.address.toString());
402 msg.prepare_payload();
413 boost::beast::http::response<boost::beast::http::empty_body> msg;
414 msg.version(request.version());
415 msg.result(boost::beast::http::status::bad_request);
416 msg.reason(
"Bad Request (" + text +
")");
418 msg.insert(
"Remote-Address", remoteAddress.to_string());
419 msg.insert(boost::beast::http::field::connection,
"close");
420 msg.prepare_payload();
429 XRPL_ASSERT(
work_,
"xrpl::OverlayImpl::connect : work is set");
434 JLOG(
journal_.info()) <<
"Over resource limit: " << remoteEndpoint;
441 JLOG(
journal_.debug()) <<
"Connect: No slot for " << remoteEndpoint <<
": "
454 app_.getJournal(
"Peer"),
458 list_.emplace(p.get(), p);
474 auto const result =
peers_.emplace(peer->slot(), peer);
475 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::addActive : peer is inserted");
480 auto const result =
ids_.emplace(
482 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::addActive : peer ID is inserted");
488 JLOG(journal.
debug()) <<
"activated";
500 auto const iter =
peers_.find(slot);
501 XRPL_ASSERT(iter !=
peers_.end(),
"xrpl::OverlayImpl::remove : valid input");
511 app_.getValidationPublicKey().has_value(),
520 auto bootstrapIps =
app_.config().ips.empty() ?
app_.config().ipsFixed :
app_.config().ips;
524 if (bootstrapIps.empty())
527 bootstrapIps.emplace_back(
"r.ripple.com 51235");
530 bootstrapIps.emplace_back(
"sahyadri.isrdc.in 51235");
533 bootstrapIps.emplace_back(
"hubs.xrpkuwait.com 51235");
536 bootstrapIps.emplace_back(
"hub.xrpl-commons.org 51235");
544 for (
auto const& addr : addresses)
546 if (addr.port() == 0)
562 if (!
app_.config().standalone() && !
app_.config().ipsFixed.empty())
565 app_.config().ipsFixed,
567 std::vector<beast::IP::Endpoint> ips;
568 ips.reserve(addresses.size());
570 for (auto& addr : addresses)
572 if (addr.port() == 0)
574 ips.emplace_back(addr.address(), kDefaultPeerPort);
578 ips.emplace_back(addr);
588 list_.emplace(timer.get(), timer);
599 cond_.wait(lock, [
this] {
return list_.empty(); });
614 auto const stats =
traffic_.getCounts();
615 for (
auto const& pair : stats)
618 item[
"category"] = pair.second.name;
620 item[
"messages_in"] =
std::to_string(pair.second.messagesIn.load());
622 item[
"messages_out"] =
std::to_string(pair.second.messagesOut.load());
641 auto const result(
ids_.emplace(
643 XRPL_ASSERT(result.second,
"xrpl::OverlayImpl::activate : peer ID is inserted");
647 JLOG(journal.
debug()) <<
"activated";
650 XRPL_ASSERT(
size(),
"xrpl::OverlayImpl::activate : nonzero peers");
665 auto const n = m->list_size();
666 auto const& journal = from->pJournal();
668 protocol::TMManifests
relay;
672 auto& s = m->list().Get(i).stobject();
676 auto const serialized = mo->serialized;
678 auto const result =
app_.getValidatorManifests().applyManifest(std::move(*mo));
682 relay.add_list()->set_stobject(s);
690 "xrpl::OverlayImpl::onManifests : manifest "
691 "deserialization succeeded");
693 app_.getOPs().pubManifest(*mo);
695 if (
app_.getValidators().listed(mo->masterKey))
697 auto db =
app_.getWalletDB().checkoutDb();
705 JLOG(journal.debug()) <<
"Malformed manifest #" << i + 1 <<
": " <<
strHex(s);
710 if (!
relay.list().empty())
754 pv[jss::public_key] =
base64Encode(sp->getNodePublic().data(), sp->getNodePublic().size());
755 pv[jss::type] = sp->slot()->inbound() ? jss::in : jss::out;
759 pv[jss::ip] = sp->getRemoteAddress().address().to_string();
760 if (sp->slot()->inbound())
762 if (
auto port = sp->slot()->listeningPort())
763 pv[jss::port] = *port;
767 pv[jss::port] = sp->getRemoteAddress().port();
772 auto version{sp->getVersion()};
773 if (!version.empty())
781 sp->ledgerRange(minSeq, maxSeq);
782 if (minSeq != 0 || maxSeq != 0)
792 bool const humanReadable =
false;
793 bool const admin =
false;
794 bool const counters =
false;
796 json::Value serverInfo =
app_.getOPs().getServerInfo(humanReadable, admin, counters);
800 serverInfo.
removeMember(jss::load_factor_fee_escalation);
804 if (serverInfo.
isMember(jss::validated_ledger))
806 json::Value& validatedLedger = serverInfo[jss::validated_ledger];
827 if (validators.
isMember(jss::publisher_lists))
829 json::Value& publisherLists = validators[jss::publisher_lists];
831 for (
auto& publisher : publisherLists)
833 publisher.removeMember(jss::list);
843 if (validatorSites.
isMember(jss::validator_sites))
845 validators[jss::validator_sites] = std::move(validatorSites[jss::validator_sites]);
858 json.append(peer->json());
869 boost::beast::http::response<JsonBody> msg;
870 msg.version(req.version());
871 msg.result(boost::beast::http::status::ok);
873 msg.insert(
"Content-Type",
"application/json");
874 msg.insert(
"Connection",
"close");
894 msg.prepare_payload();
906 if (!req.target().starts_with(kPrefix) || !
setup_.vlEnabled)
911 boost::beast::http::response<JsonBody> msg;
912 msg.version(req.version());
914 msg.insert(
"Content-Type",
"application/json");
915 msg.insert(
"Connection",
"close");
917 auto fail = [&msg, &handoff](
auto status) {
919 msg.insert(
"Content-Length",
"0");
923 msg.prepare_payload();
930 if (
auto slash = key.
find(
'/'); slash != std::string_view::npos)
932 auto verString = key.
substr(0, slash);
933 if (!boost::conversion::try_lexical_convert(verString, version))
934 return fail(boost::beast::http::status::bad_request);
935 key = key.
substr(slash + 1);
939 return fail(boost::beast::http::status::bad_request);
942 auto vl =
app_.getValidators().getAvailable(key, version);
947 return fail(boost::beast::http::status::not_found);
951 return fail(boost::beast::http::status::bad_request);
954 msg.result(boost::beast::http::status::ok);
958 msg.prepare_payload();
966 if (req.target() !=
"/health")
968 boost::beast::http::response<JsonBody> msg;
969 msg.version(req.version());
971 msg.insert(
"Content-Type",
"application/json");
972 msg.insert(
"Connection",
"close");
976 int lastValidatedLedgerAge = -1;
977 if (info.isMember(jss::validated_ledger))
978 lastValidatedLedgerAge = info[jss::validated_ledger][jss::age].asInt();
979 bool amendmentBlocked =
false;
980 if (info.isMember(jss::amendment_blocked))
981 amendmentBlocked =
true;
982 int const numberPeers = info[jss::peers].asInt();
983 std::string const serverState = info[jss::server_state].asString();
984 auto loadFactor = info[jss::load_factor_server].asDouble() / info[jss::load_base].asDouble();
986 enum class HealthState { Healthy, Warning, Critical };
987 auto health = HealthState::Healthy;
988 auto setHealth = [&health](HealthState state) { health =
std::max(health, state); };
991 if (lastValidatedLedgerAge >= 7 || lastValidatedLedgerAge < 0)
993 msg.body()[jss::info][jss::validated_ledger] = lastValidatedLedgerAge;
994 if (lastValidatedLedgerAge < 20)
996 setHealth(HealthState::Warning);
1000 setHealth(HealthState::Critical);
1004 if (amendmentBlocked)
1006 msg.body()[jss::info][jss::amendment_blocked] =
true;
1007 setHealth(HealthState::Critical);
1010 if (numberPeers <= 7)
1012 msg.body()[jss::info][jss::peers] = numberPeers;
1013 if (numberPeers != 0)
1015 setHealth(HealthState::Warning);
1019 setHealth(HealthState::Critical);
1023 if (!(serverState ==
"full" || serverState ==
"validating" || serverState ==
"proposing"))
1025 msg.body()[jss::info][jss::server_state] = serverState;
1026 if (serverState ==
"syncing" || serverState ==
"tracking" || serverState ==
"connected")
1028 setHealth(HealthState::Warning);
1032 setHealth(HealthState::Critical);
1036 if (loadFactor > 100)
1038 msg.body()[jss::info][jss::load_factor] = loadFactor;
1039 if (loadFactor < 1000)
1041 setHealth(HealthState::Warning);
1045 setHealth(HealthState::Critical);
1051 case HealthState::Healthy:
1052 msg.result(boost::beast::http::status::ok);
1054 case HealthState::Warning:
1055 msg.result(boost::beast::http::status::service_unavailable);
1057 case HealthState::Critical:
1058 msg.result(boost::beast::http::status::internal_server_error);
1062 msg.prepare_payload();
1096 active =
ids_.size();
1097 disabled = enabledInSkip = 0;
1102 for (
auto& [
id, w] :
ids_)
1104 if (p = w.lock(); p !=
nullptr)
1106 bool const reduceRelayEnabled = p->txReduceRelayEnabled();
1108 if (!reduceRelayEnabled)
1115 else if (reduceRelayEnabled)
1135 auto const iter =
ids_.find(
id);
1136 if (iter !=
ids_.end())
1137 return iter->second.lock();
1149 for (
auto const& e :
ids_)
1151 if (peer = e.second.lock(); peer !=
nullptr)
1153 if (peer->getNodePublic() == pubKey)
1170 if (
auto const toSkip =
app_.getHashRouter().shouldRelay(uid))
1174 if (!toSkip->contains(p->id()))
1192 if (
auto const toSkip =
app_.getHashRouter().shouldRelay(uid))
1196 if (!toSkip->contains(p->id()))
1211 protocol::TMManifests
tm;
1213 app_.getValidatorManifests().forEachManifest(
1217 hr.addSuppression(manifest.
hash());
1222 if (
tm.list_size() != 0)
1237 bool relay = tx.has_value();
1240 auto& txn = tx->get();
1249 JLOG(
journal_.debug()) <<
"Could not construct STTx: " <<
hash;
1261 if (!
app_.config().txReduceRelayEnable)
1265 JLOG(
journal_.trace()) <<
"not relaying tx, total peers " << peers.
size();
1266 for (
auto const& p : peers)
1267 p->addTxQueue(
hash);
1271 auto& txn = tx->get();
1274 auto const minRelay =
app_.config().txReduceRelayMinPeers + disabled;
1276 if (!
app_.config().txReduceRelayEnable || total <= minRelay)
1278 for (
auto const& p : peers)
1280 if (
app_.config().txReduceRelayEnable ||
app_.config().txReduceRelayMetrics)
1288 auto const enabledTarget =
app_.config().txReduceRelayMinPeers +
1289 ((total - minRelay) *
app_.config().txRelayPercentage / 100);
1293 if (enabledTarget > enabledInSkip)
1296 JLOG(
journal_.trace()) <<
"relaying tx, total peers " << peers.
size() <<
" selected "
1297 << enabledTarget <<
" skip " << toSkip.
size() <<
" disabled "
1302 for (
auto const& p : peers)
1305 if (!p->txReduceRelayEnabled())
1309 else if (enabledAndRelayed < enabledTarget)
1311 enabledAndRelayed++;
1316 p->addTxQueue(
hash);
1327 list_.erase(&child);
1348 work_ = std::nullopt;
1351 for (
auto const& element :
list_)
1357 for (
auto const& child : children)
1359 if (child !=
nullptr)
1368 for (
auto const& addr : result)
1375 auto const result =
peerFinder_->buildEndpointsForPeers();
1376 for (
auto const& e : result)
1381 auto const iter =
peers_.find(e.first);
1382 if (iter !=
peers_.end())
1383 peer = iter->second.lock();
1386 peer->sendEndpoints(e.second.begin(), e.second.end());
1394 if (p->txReduceRelayEnabled())
1402 protocol::TMSquelch m;
1404 m.set_validatorpubkey(validator.data(), validator.size());
1406 m.set_squelchduration(squelchDuration);
1435 protocol::MessageType type)
1437 if (!
slots_.baseSquelchReady())
1440 if (!
strand_.running_in_this_thread())
1445 [
this, key = key, validator = validator, peers = std::move(peers), type]()
mutable {
1452 for (
auto id : peers)
1454 slots_.updateSlotAndSquelch(key, validator,
id, type, [&]() {
1465 protocol::MessageType type)
1467 if (!
slots_.baseSquelchReady())
1470 if (!
strand_.running_in_this_thread())
1476 [
this, key = key, validator = validator, peer, type]() {
1483 slots_.updateSlotAndSquelch(key, validator, peer, type, [&]() {
1491 if (!
strand_.running_in_this_thread())
1497 slots_.deletePeer(
id,
true);
1503 if (!
strand_.running_in_this_thread())
1509 slots_.deleteIdlePeers();
1528 set(ip,
"public_ip", section);
1531 boost::system::error_code ec;
1532 setup.
publicIp = boost::asio::ip::make_address(ip, ec);
1540 JLOG(j.
warn()) <<
"Endpoint verification is disabled. This is a "
1541 "security risk and should only be used for "
1548 auto const& values = section.
values();
1550 if (values.size() > 1)
1555 bool crawlEnabled =
true;
1558 if (values.size() == 1)
1562 crawlEnabled = boost::lexical_cast<bool>(values.front());
1564 catch (boost::bad_lexical_cast
const&)
1567 "Configured [crawl] section has invalid value: " + values.front());
1606 if (
id ==
"testnet")
1618 "Configured [network_id] section is invalid: must be a number "
1619 "or one of the strings 'main', 'testnet' or 'devnet'.");
1632 boost::asio::io_context& ioContext,
1637 app, setup, serverHandler, resourceManager, resolver, ioContext, config, collector);
A version-independent IP address and port combination.
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
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.
void remove(std::shared_ptr< PeerFinder::Slot > const &slot)
boost::asio::io_context & ioContext_
bool processRequest(http_request_type const &req, Handoff &handoff)
Handles non-peer protocol requests.
Resource::Manager & resourceManager_
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_
std::shared_ptr< Writer > makeRedirectResponse(std::shared_ptr< PeerFinder::Slot > const &slot, http_request_type const &request, address_type remoteAddress)
static std::shared_ptr< Writer > makeErrorResponse(std::shared_ptr< PeerFinder::Slot > const &slot, http_request_type const &request, address_type remoteAddress, std::string const &msg)
std::set< Peer::id_t > relay(protocol::TMProposeSet const &m, uint256 const &uid, PublicKey const &validator) override
Relay a proposal.
void connect(beast::IP::Endpoint const &remoteEndpoint) override
Establish a peer connection to the specified endpoint.
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)
Handoff onHandoff(std::unique_ptr< stream_type > &&bundle, http_request_type &&request, endpoint_type remoteEndpoint) override
Conditionally accept an incoming HTTP request.
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.
void squelch(PublicKey const &validator, Peer::id_t const id, std::uint32_t squelchDuration) const override
Squelch handler.
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 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_
void onWrite(beast::PropertyStream::Map &stream) override
Subclass override.
PeerFinder::Manager & peerFinder()
std::atomic< Peer::id_t > nextId_
hash_map< std::shared_ptr< PeerFinder::Slot >, std::weak_ptr< PeerImp > > peers_
json::Value getServerCounts()
Returns information about the local server's performance counters.
std::recursive_mutex mutex_
Resource::Manager & resourceManager()
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
std::unique_ptr< PeerFinder::Manager > peerFinder_
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.
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
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.
std::uint32_t id_t
Uniquely identifies a peer.
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.
std::vector< std::string > const & values() const
Returns all the values in the section.
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)
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 kUnl
static constexpr auto kServerCounts
static constexpr auto kDisabled
static constexpr auto kOverlay
static constexpr auto kServerInfo
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,...
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.
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.
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.
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)
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
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.
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
std::enable_if_t< std::is_same_v< T, char >||std::is_same_v< T, unsigned char >, Slice > makeSlice(std::array< T, N > const &a)
@ Accepted
Manifest is valid.
T shared_from_this(T... args)
static IP::Endpoint fromAsio(boost::asio::ip::address const &address)
static boost::asio::ip::tcp::endpoint toAsioEndpoint(IP::Endpoint 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
std::string serialized
The manifest in serialized form.
uint256 hash() const
Returns hash of serialized manifest data.
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
PeerFinder configuration settings.
static Config makeConfig(xrpl::Config const &config, std::uint16_t port, bool validationPublicKey, int ipLimit, bool verifyEndpoints)
Make PeerFinder::Config from configuration parameters.
static constexpr auto kOverlay
static constexpr auto kVl
static constexpr auto kCrawl
static constexpr auto kNetworkId