rippled
Loading...
Searching...
No Matches
BasicNetwork.h
1#ifndef XRPL_TEST_CSF_BASICNETWORK_H_INCLUDED
2#define XRPL_TEST_CSF_BASICNETWORK_H_INCLUDED
3
4#include <test/csf/Digraph.h>
5#include <test/csf/Scheduler.h>
6
7namespace ripple {
8namespace test {
9namespace csf {
63template <class Peer>
65{
66 using peer_type = Peer;
67
69
71
73
74 struct link_type
75 {
76 bool inbound = false;
79 link_type() = default;
80 link_type(bool inbound_, duration delay_, time_point established_)
81 : inbound(inbound_), delay(delay_), established(established_)
82 {
83 }
84 };
85
88
89public:
90 BasicNetwork(BasicNetwork const&) = delete;
92 operator=(BasicNetwork const&) = delete;
93
95
118 bool
120 Peer const& from,
121 Peer const& to,
122 duration const& delay = std::chrono::seconds{0});
123
136 bool
137 disconnect(Peer const& peer1, Peer const& peer2);
138
157 template <class Function>
158 void
159 send(Peer const& from, Peer const& to, Function&& f);
160
165 auto
166 links(Peer const& from)
167 {
168 return links_.outEdges(from);
169 }
170
174 graph() const
175 {
176 return links_;
177 }
178};
179//------------------------------------------------------------------------------
180template <class Peer>
182{
183}
184
185template <class Peer>
186inline bool
188 Peer const& from,
189 Peer const& to,
190 duration const& delay)
191{
192 if (to == from)
193 return false;
194 time_point const now = scheduler.now();
195 if (!links_.connect(from, to, link_type{false, delay, now}))
196 return false;
197 auto const result = links_.connect(to, from, link_type{true, delay, now});
198 (void)result;
199 assert(result);
200 return true;
201}
202
203template <class Peer>
204inline bool
205BasicNetwork<Peer>::disconnect(Peer const& peer1, Peer const& peer2)
206{
207 if (!links_.disconnect(peer1, peer2))
208 return false;
209 bool r = links_.disconnect(peer2, peer1);
210 (void)r;
211 assert(r);
212 return true;
213}
214
215template <class Peer>
216template <class Function>
217inline void
218BasicNetwork<Peer>::send(Peer const& from, Peer const& to, Function&& f)
219{
220 auto link = links_.edge(from, to);
221 if (!link)
222 return;
223 time_point const sent = scheduler.now();
224 scheduler.in(
225 link->delay, [from, to, sent, f = std::forward<Function>(f), this] {
226 // only process if still connected and connection was
227 // not broken since the message was sent
228 if (auto l = links_.edge(from, to); l && l->established <= sent)
229 {
230 f();
231 }
232 });
233}
234
235} // namespace csf
236} // namespace test
237} // namespace ripple
238
239#endif
typename Clock::time_point time_point
typename Clock::duration duration
Peer to peer network simulator.
typename clock_type::duration duration
void send(Peer const &from, Peer const &to, Function &&f)
Send a message to a peer.
BasicNetwork & operator=(BasicNetwork const &)=delete
bool disconnect(Peer const &peer1, Peer const &peer2)
Break a link.
auto links(Peer const &from)
Return the range of active links.
Digraph< Peer, link_type > links_
BasicNetwork(BasicNetwork const &)=delete
Digraph< Peer, link_type > const & graph() const
Return the underlying digraph.
typename clock_type::time_point time_point
bool connect(Peer const &from, Peer const &to, duration const &delay=std::chrono::seconds{0})
Connect two peers.
Directed graph.
Definition Digraph.h:37
std::optional< EdgeData > edge(Vertex source, Vertex target) const
Return edge data between two vertices.
Definition Digraph.h:100
bool disconnect(Vertex source, Vertex target)
Disconnect two vertices.
Definition Digraph.h:82
bool connect(Vertex source, Vertex target, EdgeData e)
Connect two vertices.
Definition Digraph.h:55
Simulated discrete-event scheduler.
beast::manual_clock< std::chrono::steady_clock > clock_type
time_point now() const
Return the current network time.
cancel_token in(duration const &delay, Function &&f)
Schedule an event after a specified duration passes.
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
A single peer in the simulation.