rippled
Loading...
Searching...
No Matches
HashRouter_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012-2015 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/app/misc/HashRouter.h>
21#include <xrpl/basics/chrono.h>
22#include <xrpl/beast/unit_test.h>
23
24namespace ripple {
25namespace test {
26
28{
29 void
31 {
32 using namespace std::chrono_literals;
34 HashRouter router(stopwatch, 2s);
35
36 uint256 const key1(1);
37 uint256 const key2(2);
38 uint256 const key3(3);
39
40 // t=0
41 router.setFlags(key1, 11111);
42 BEAST_EXPECT(router.getFlags(key1) == 11111);
43 router.setFlags(key2, 22222);
44 BEAST_EXPECT(router.getFlags(key2) == 22222);
45 // key1 : 0
46 // key2 : 0
47 // key3: null
48
49 ++stopwatch;
50
51 // Because we are accessing key1 here, it
52 // will NOT be expired for another two ticks
53 BEAST_EXPECT(router.getFlags(key1) == 11111);
54 // key1 : 1
55 // key2 : 0
56 // key3 null
57
58 ++stopwatch;
59
60 // t=3
61 router.setFlags(key3, 33333); // force expiration
62 BEAST_EXPECT(router.getFlags(key1) == 11111);
63 BEAST_EXPECT(router.getFlags(key2) == 0);
64 }
65
66 void
68 {
69 using namespace std::chrono_literals;
71 HashRouter router(stopwatch, 2s);
72
73 uint256 const key1(1);
74 uint256 const key2(2);
75 uint256 const key3(3);
76 uint256 const key4(4);
77 BEAST_EXPECT(key1 != key2 && key2 != key3 && key3 != key4);
78
79 // t=0
80 router.setFlags(key1, 12345);
81 BEAST_EXPECT(router.getFlags(key1) == 12345);
82 // key1 : 0
83 // key2 : null
84 // key3 : null
85
86 ++stopwatch;
87
88 // Expiration is triggered by insertion,
89 // and timestamps are updated on access,
90 // so key1 will be expired after the second
91 // call to setFlags.
92 // t=1
93 router.setFlags(key2, 9999);
94 BEAST_EXPECT(router.getFlags(key1) == 12345);
95 BEAST_EXPECT(router.getFlags(key2) == 9999);
96 // key1 : 1
97 // key2 : 1
98 // key3 : null
99
100 ++stopwatch;
101 // t=2
102 BEAST_EXPECT(router.getFlags(key2) == 9999);
103 // key1 : 1
104 // key2 : 2
105 // key3 : null
106
107 ++stopwatch;
108 // t=3
109 router.setFlags(key3, 2222);
110 BEAST_EXPECT(router.getFlags(key1) == 0);
111 BEAST_EXPECT(router.getFlags(key2) == 9999);
112 BEAST_EXPECT(router.getFlags(key3) == 2222);
113 // key1 : 3
114 // key2 : 3
115 // key3 : 3
116
117 ++stopwatch;
118 // t=4
119 // No insertion, no expiration
120 router.setFlags(key1, 7654);
121 BEAST_EXPECT(router.getFlags(key1) == 7654);
122 BEAST_EXPECT(router.getFlags(key2) == 9999);
123 BEAST_EXPECT(router.getFlags(key3) == 2222);
124 // key1 : 4
125 // key2 : 4
126 // key3 : 4
127
128 ++stopwatch;
129 ++stopwatch;
130
131 // t=6
132 router.setFlags(key4, 7890);
133 BEAST_EXPECT(router.getFlags(key1) == 0);
134 BEAST_EXPECT(router.getFlags(key2) == 0);
135 BEAST_EXPECT(router.getFlags(key3) == 0);
136 BEAST_EXPECT(router.getFlags(key4) == 7890);
137 // key1 : 6
138 // key2 : 6
139 // key3 : 6
140 // key4 : 6
141 }
142
143 void
145 {
146 // Normal HashRouter
147 using namespace std::chrono_literals;
149 HashRouter router(stopwatch, 2s);
150
151 uint256 const key1(1);
152 uint256 const key2(2);
153 uint256 const key3(3);
154 uint256 const key4(4);
155 BEAST_EXPECT(key1 != key2 && key2 != key3 && key3 != key4);
156
157 int flags = 12345; // This value is ignored
158 router.addSuppression(key1);
159 BEAST_EXPECT(router.addSuppressionPeer(key2, 15));
160 BEAST_EXPECT(router.addSuppressionPeer(key3, 20, flags));
161 BEAST_EXPECT(flags == 0);
162
163 ++stopwatch;
164
165 BEAST_EXPECT(!router.addSuppressionPeer(key1, 2));
166 BEAST_EXPECT(!router.addSuppressionPeer(key2, 3));
167 BEAST_EXPECT(!router.addSuppressionPeer(key3, 4, flags));
168 BEAST_EXPECT(flags == 0);
169 BEAST_EXPECT(router.addSuppressionPeer(key4, 5));
170 }
171
172 void
174 {
175 using namespace std::chrono_literals;
177 HashRouter router(stopwatch, 2s);
178
179 uint256 const key1(1);
180 BEAST_EXPECT(router.setFlags(key1, 10));
181 BEAST_EXPECT(!router.setFlags(key1, 10));
182 BEAST_EXPECT(router.setFlags(key1, 20));
183 }
184
185 void
187 {
188 using namespace std::chrono_literals;
190 HashRouter router(stopwatch, 1s);
191
192 uint256 const key1(1);
193
195
196 peers = router.shouldRelay(key1);
197 BEAST_EXPECT(peers && peers->empty());
198 router.addSuppressionPeer(key1, 1);
199 router.addSuppressionPeer(key1, 3);
200 router.addSuppressionPeer(key1, 5);
201 // No action, because relayed
202 BEAST_EXPECT(!router.shouldRelay(key1));
203 // Expire, but since the next search will
204 // be for this entry, it will get refreshed
205 // instead. However, the relay won't.
206 ++stopwatch;
207 // Get those peers we added earlier
208 peers = router.shouldRelay(key1);
209 BEAST_EXPECT(peers && peers->size() == 3);
210 router.addSuppressionPeer(key1, 2);
211 router.addSuppressionPeer(key1, 4);
212 // No action, because relayed
213 BEAST_EXPECT(!router.shouldRelay(key1));
214 // Expire, but since the next search will
215 // be for this entry, it will get refreshed
216 // instead. However, the relay won't.
217 ++stopwatch;
218 // Relay again
219 peers = router.shouldRelay(key1);
220 BEAST_EXPECT(peers && peers->size() == 2);
221 // Expire again
222 ++stopwatch;
223 // Confirm that peers list is empty.
224 peers = router.shouldRelay(key1);
225 BEAST_EXPECT(peers && peers->size() == 0);
226 }
227
228 void
230 {
231 using namespace std::chrono_literals;
233 HashRouter router(stopwatch, 5s);
234 uint256 const key(1);
236 int flags;
237
238 BEAST_EXPECT(router.shouldProcess(key, peer, flags, 1s));
239 BEAST_EXPECT(!router.shouldProcess(key, peer, flags, 1s));
240 ++stopwatch;
241 ++stopwatch;
242 BEAST_EXPECT(router.shouldProcess(key, peer, flags, 1s));
243 }
244
245 void
247 {
248 using namespace std::chrono_literals;
250 HashRouter router(stopwatch, 5s);
251 uint256 const key(1);
252 HashRouter::PeerShortID peer1 = 1;
253 HashRouter::PeerShortID peer2 = 2;
254 auto const timeout = 2s;
255
256 BEAST_EXPECT(router.shouldProcessForPeer(key, peer1, timeout));
257 BEAST_EXPECT(!router.shouldProcessForPeer(key, peer1, timeout));
258 ++stopwatch;
259 BEAST_EXPECT(!router.shouldProcessForPeer(key, peer1, timeout));
260 BEAST_EXPECT(router.shouldProcessForPeer(key, peer2, timeout));
261 BEAST_EXPECT(!router.shouldProcessForPeer(key, peer2, timeout));
262 ++stopwatch;
263 BEAST_EXPECT(router.shouldProcessForPeer(key, peer1, timeout));
264 BEAST_EXPECT(!router.shouldProcessForPeer(key, peer2, timeout));
265 ++stopwatch;
266 BEAST_EXPECT(router.shouldProcessForPeer(key, peer2, timeout));
267 ++stopwatch;
268 BEAST_EXPECT(router.shouldProcessForPeer(key, peer1, timeout));
269 BEAST_EXPECT(!router.shouldProcessForPeer(key, peer2, timeout));
270 }
271
272public:
273 void
274 run() override
275 {
279 testSetFlags();
280 testRelay();
281 testProcess();
283 }
284};
285
286BEAST_DEFINE_TESTSUITE(HashRouter, app, ripple);
287
288} // namespace test
289} // namespace ripple
A testsuite class.
Definition: suite.h:53
Routing table for objects identified by hash.
Definition: HashRouter.h:54
std::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
Definition: HashRouter.cpp:132
bool shouldProcess(uint256 const &key, PeerShortID peer, int &flags, std::chrono::seconds tx_interval)
Definition: HashRouter.cpp:78
int getFlags(uint256 const &key)
Definition: HashRouter.cpp:108
bool shouldProcessForPeer(uint256 const &key, PeerShortID peer, std::chrono::seconds interval)
Determines whether the hashed item should be processed for the given peer.
Definition: HashRouter.cpp:94
bool addSuppressionPeer(uint256 const &key, PeerShortID peer)
Definition: HashRouter.cpp:51
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
Definition: HashRouter.cpp:116
void addSuppression(uint256 const &key)
Definition: HashRouter.cpp:43
void run() override
Runs the suite.
Match set account flags.
Definition: flags.h:112
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition: chrono.h:120