xrpld
Loading...
Searching...
No Matches
PeerSet.cpp
1#include <xrpld/overlay/PeerSet.h>
2
3#include <xrpld/app/main/Application.h>
4#include <xrpld/overlay/Message.h>
5#include <xrpld/overlay/Overlay.h>
6#include <xrpld/overlay/Peer.h>
7
8#include <xrpl/basics/Log.h>
9#include <xrpl/beast/utility/Journal.h>
10
11#include <google/protobuf/message.h>
12
13#include <xrpl.pb.h>
14
15#include <algorithm>
16#include <cstddef>
17#include <functional>
18#include <memory>
19#include <set>
20#include <utility>
21#include <vector>
22
23namespace xrpl {
24
25class PeerSetImpl : public PeerSet
26{
27public:
29
30 void
32 std::size_t limit,
33 std::function<bool(std::shared_ptr<Peer> const&)> hasItem,
34 std::function<void(std::shared_ptr<Peer> const&)> onPeerAdded) override;
35
37 void
39 ::google::protobuf::Message const& message,
40 protocol::MessageType type,
41 std::shared_ptr<Peer> const& peer) override;
42
43 [[nodiscard]] std::set<Peer::id_t> const&
44 getPeerIds() const override;
45
46private:
47 // Used in this class for access to boost::asio::io_context and
48 // xrpl::Overlay.
51
54};
55
56PeerSetImpl::PeerSetImpl(Application& app) : app_(app), journal_(app.getJournal("PeerSet"))
57{
58}
59
60void
62 std::size_t limit,
63 std::function<bool(std::shared_ptr<Peer> const&)> hasItem,
64 std::function<void(std::shared_ptr<Peer> const&)> onPeerAdded)
65{
66 using ScoredPeer = std::pair<int, std::shared_ptr<Peer>>;
67
68 auto const& overlay = app_.getOverlay();
69
71 pairs.reserve(overlay.size());
72
73 overlay.foreach([&](auto const& peer) {
74 auto const score = peer->getScore(hasItem(peer));
75 pairs.emplace_back(score, std::move(peer));
76 });
77
79 pairs, [](ScoredPeer const& lhs, ScoredPeer const& rhs) { return lhs.first > rhs.first; });
80
81 std::size_t accepted = 0;
82 for (auto const& pair : pairs)
83 {
84 auto const peer = pair.second;
85 if (!peers_.insert(peer->id()).second)
86 continue;
87 onPeerAdded(peer);
88 if (++accepted >= limit)
89 break;
90 }
91}
92
93void
95 ::google::protobuf::Message const& message,
96 protocol::MessageType type,
97 std::shared_ptr<Peer> const& peer)
98{
99 auto packet = std::make_shared<Message>(message, type);
100 if (peer)
101 {
102 peer->send(packet);
103 return;
104 }
105
106 for (auto id : peers_)
107 {
108 if (auto p = app_.getOverlay().findPeerByShortID(id))
109 p->send(packet);
110 }
111}
112
115{
116 return peers_;
117}
118
120{
121public:
123 {
124 }
125
127 build() override
128 {
130 }
131
132private:
134};
135
141
142class DummyPeerSet : public PeerSet
143{
144public:
145 DummyPeerSet(Application& app) : j_(app.getJournal("DummyPeerSet"))
146 {
147 }
148
149 void
151 std::size_t limit,
152 std::function<bool(std::shared_ptr<Peer> const&)> hasItem,
153 std::function<void(std::shared_ptr<Peer> const&)> onPeerAdded) override
154 {
155 JLOG(j_.error()) << "DummyPeerSet addPeers should not be called";
156 }
157
158 void
160 ::google::protobuf::Message const& message,
161 protocol::MessageType type,
162 std::shared_ptr<Peer> const& peer) override
163 {
164 JLOG(j_.error()) << "DummyPeerSet sendRequest should not be called";
165 }
166
167 [[nodiscard]] std::set<Peer::id_t> const&
168 getPeerIds() const override
169 {
170 static std::set<Peer::id_t> const kEmptyPeers;
171 JLOG(j_.error()) << "DummyPeerSet getPeerIds should not be called";
172 return kEmptyPeers;
173 }
174
175private:
177};
178
184
185} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:38
DummyPeerSet(Application &app)
Definition PeerSet.cpp:145
beast::Journal j_
Definition PeerSet.cpp:176
void addPeers(std::size_t limit, std::function< bool(std::shared_ptr< Peer > const &)> hasItem, std::function< void(std::shared_ptr< Peer > const &)> onPeerAdded) override
Try add more peers.
Definition PeerSet.cpp:150
void sendRequest(::google::protobuf::Message const &message, protocol::MessageType type, std::shared_ptr< Peer > const &peer) override
Definition PeerSet.cpp:159
std::set< Peer::id_t > const & getPeerIds() const override
get the set of ids of previously added peers
Definition PeerSet.cpp:168
PeerSetBuilderImpl(Application &app)
Definition PeerSet.cpp:122
std::unique_ptr< PeerSet > build() override
Definition PeerSet.cpp:127
Application & app_
Definition PeerSet.cpp:49
std::set< Peer::id_t > peers_
The identifiers of the peers we are tracking.
Definition PeerSet.cpp:53
PeerSetImpl(Application &app)
Definition PeerSet.cpp:56
void addPeers(std::size_t limit, std::function< bool(std::shared_ptr< Peer > const &)> hasItem, std::function< void(std::shared_ptr< Peer > const &)> onPeerAdded) override
Try add more peers.
Definition PeerSet.cpp:61
beast::Journal journal_
Definition PeerSet.cpp:50
void sendRequest(::google::protobuf::Message const &message, protocol::MessageType type, std::shared_ptr< Peer > const &peer) override
Send a message to one or all peers.
Definition PeerSet.cpp:94
std::set< Peer::id_t > const & getPeerIds() const override
get the set of ids of previously added peers
Definition PeerSet.cpp:114
Supports data retrieval by managing a set of peers.
Definition PeerSet.h:20
T emplace_back(T... args)
T make_shared(T... args)
T make_unique(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::unique_ptr< PeerSetBuilder > makePeerSetBuilder(Application &app)
Definition PeerSet.cpp:137
std::unique_ptr< PeerSet > makeDummyPeerSet(Application &app)
Make a dummy PeerSet that does not do anything.
Definition PeerSet.cpp:180
T reserve(T... args)
T sort(T... args)