rippled
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 <ripple/app/misc/HashRouter.h>
21 #include <ripple/basics/chrono.h>
22 #include <ripple/beast/unit_test.h>
23 
24 namespace ripple {
25 namespace test {
26 
27 class HashRouter_test : public beast::unit_test::suite
28 {
29  void
31  {
32  using namespace std::chrono_literals;
34  HashRouter router(stopwatch, 2s, 2);
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, 2);
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 &&
78  key2 != key3 &&
79  key3 != key4);
80 
81  // t=0
82  router.setFlags(key1, 12345);
83  BEAST_EXPECT(router.getFlags(key1) == 12345);
84  // key1 : 0
85  // key2 : null
86  // key3 : null
87 
88  ++stopwatch;
89 
90  // Expiration is triggered by insertion,
91  // and timestamps are updated on access,
92  // so key1 will be expired after the second
93  // call to setFlags.
94  // t=1
95  router.setFlags(key2, 9999);
96  BEAST_EXPECT(router.getFlags(key1) == 12345);
97  BEAST_EXPECT(router.getFlags(key2) == 9999);
98  // key1 : 1
99  // key2 : 1
100  // key3 : null
101 
102  ++stopwatch;
103  // t=2
104  BEAST_EXPECT(router.getFlags(key2) == 9999);
105  // key1 : 1
106  // key2 : 2
107  // key3 : null
108 
109  ++stopwatch;
110  // t=3
111  router.setFlags(key3, 2222);
112  BEAST_EXPECT(router.getFlags(key1) == 0);
113  BEAST_EXPECT(router.getFlags(key2) == 9999);
114  BEAST_EXPECT(router.getFlags(key3) == 2222);
115  // key1 : 3
116  // key2 : 3
117  // key3 : 3
118 
119  ++stopwatch;
120  // t=4
121  // No insertion, no expiration
122  router.setFlags(key1, 7654);
123  BEAST_EXPECT(router.getFlags(key1) == 7654);
124  BEAST_EXPECT(router.getFlags(key2) == 9999);
125  BEAST_EXPECT(router.getFlags(key3) == 2222);
126  // key1 : 4
127  // key2 : 4
128  // key3 : 4
129 
130  ++stopwatch;
131  ++stopwatch;
132 
133  // t=6
134  router.setFlags(key4, 7890);
135  BEAST_EXPECT(router.getFlags(key1) == 0);
136  BEAST_EXPECT(router.getFlags(key2) == 0);
137  BEAST_EXPECT(router.getFlags(key3) == 0);
138  BEAST_EXPECT(router.getFlags(key4) == 7890);
139  // key1 : 6
140  // key2 : 6
141  // key3 : 6
142  // key4 : 6
143  }
144 
146  {
147  // Normal HashRouter
148  using namespace std::chrono_literals;
150  HashRouter router(stopwatch, 2s, 2);
151 
152  uint256 const key1(1);
153  uint256 const key2(2);
154  uint256 const key3(3);
155  uint256 const key4(4);
156  BEAST_EXPECT(key1 != key2 &&
157  key2 != key3 &&
158  key3 != key4);
159 
160  int flags = 12345; // This value is ignored
161  router.addSuppression(key1);
162  BEAST_EXPECT(router.addSuppressionPeer(key2, 15));
163  BEAST_EXPECT(router.addSuppressionPeer(key3, 20, flags));
164  BEAST_EXPECT(flags == 0);
165 
166  ++stopwatch;
167 
168  BEAST_EXPECT(!router.addSuppressionPeer(key1, 2));
169  BEAST_EXPECT(!router.addSuppressionPeer(key2, 3));
170  BEAST_EXPECT(!router.addSuppressionPeer(key3, 4, flags));
171  BEAST_EXPECT(flags == 0);
172  BEAST_EXPECT(router.addSuppressionPeer(key4, 5));
173  }
174 
175  void
177  {
178  using namespace std::chrono_literals;
180  HashRouter router(stopwatch, 2s, 2);
181 
182  uint256 const key1(1);
183  BEAST_EXPECT(router.setFlags(key1, 10));
184  BEAST_EXPECT(!router.setFlags(key1, 10));
185  BEAST_EXPECT(router.setFlags(key1, 20));
186  }
187 
188  void
190  {
191  using namespace std::chrono_literals;
193  HashRouter router(stopwatch, 1s, 2);
194 
195  uint256 const key1(1);
196 
197  boost::optional<std::set<HashRouter::PeerShortID>> peers;
198 
199  peers = router.shouldRelay(key1);
200  BEAST_EXPECT(peers && peers->empty());
201  router.addSuppressionPeer(key1, 1);
202  router.addSuppressionPeer(key1, 3);
203  router.addSuppressionPeer(key1, 5);
204  // No action, because relayed
205  BEAST_EXPECT(!router.shouldRelay(key1));
206  // Expire, but since the next search will
207  // be for this entry, it will get refreshed
208  // instead. However, the relay won't.
209  ++stopwatch;
210  // Get those peers we added earlier
211  peers = router.shouldRelay(key1);
212  BEAST_EXPECT(peers && peers->size() == 3);
213  router.addSuppressionPeer(key1, 2);
214  router.addSuppressionPeer(key1, 4);
215  // No action, because relayed
216  BEAST_EXPECT(!router.shouldRelay(key1));
217  // Expire, but since the next search will
218  // be for this entry, it will get refreshed
219  // instead. However, the relay won't.
220  ++stopwatch;
221  // Relay again
222  peers = router.shouldRelay(key1);
223  BEAST_EXPECT(peers && peers->size() == 2);
224  // Expire again
225  ++stopwatch;
226  // Confirm that peers list is empty.
227  peers = router.shouldRelay(key1);
228  BEAST_EXPECT(peers && peers->size() == 0);
229  }
230 
231  void
233  {
234  using namespace std::chrono_literals;
236  HashRouter router(stopwatch, 1s, 5);
237 
238  uint256 const key1(1);
239 
240  BEAST_EXPECT(router.shouldRecover(key1));
241  BEAST_EXPECT(router.shouldRecover(key1));
242  BEAST_EXPECT(router.shouldRecover(key1));
243  BEAST_EXPECT(router.shouldRecover(key1));
244  BEAST_EXPECT(router.shouldRecover(key1));
245  BEAST_EXPECT(!router.shouldRecover(key1));
246  // Expire, but since the next search will
247  // be for this entry, it will get refreshed
248  // instead.
249  ++stopwatch;
250  BEAST_EXPECT(router.shouldRecover(key1));
251  // Expire, but since the next search will
252  // be for this entry, it will get refreshed
253  // instead.
254  ++stopwatch;
255  // Recover again. Recovery is independent of
256  // time as long as the entry doesn't expire.
257  BEAST_EXPECT(router.shouldRecover(key1));
258  BEAST_EXPECT(router.shouldRecover(key1));
259  BEAST_EXPECT(router.shouldRecover(key1));
260  // Expire again
261  ++stopwatch;
262  BEAST_EXPECT(router.shouldRecover(key1));
263  BEAST_EXPECT(!router.shouldRecover(key1));
264  }
265 
266  void
268  {
269  using namespace std::chrono_literals;
271  HashRouter router(stopwatch, 5s, 5);
272  uint256 const key(1);
273  HashRouter::PeerShortID peer = 1;
274  int flags;
275 
276  BEAST_EXPECT(router.shouldProcess(key, peer, flags, 1s));
277  BEAST_EXPECT(! router.shouldProcess(key, peer, flags, 1s));
278  ++stopwatch;
279  ++stopwatch;
280  BEAST_EXPECT(router.shouldProcess(key, peer, flags, 1s));
281  }
282 
283 
284 public:
285 
286  void
287  run() override
288  {
290  testExpiration();
291  testSuppression();
292  testSetFlags();
293  testRelay();
294  testRecover();
295  testProcess();
296  }
297 };
298 
300 
301 }
302 }
ripple::HashRouter::addSuppressionPeer
bool addSuppressionPeer(uint256 const &key, PeerShortID peer)
Definition: HashRouter.cpp:53
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
ripple::HashRouter::getFlags
int getFlags(uint256 const &key)
Definition: HashRouter.cpp:84
ripple::HashRouter::shouldProcess
bool shouldProcess(uint256 const &key, PeerShortID peer, int &flags, std::chrono::seconds tx_interval)
Definition: HashRouter.cpp:72
ripple::test::HashRouter_test::testProcess
void testProcess()
Definition: HashRouter_test.cpp:267
ripple::stopwatch
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition: chrono.h:87
ripple::test::HashRouter_test
Definition: HashRouter_test.cpp:27
ripple::HashRouter
Routing table for objects identified by hash.
Definition: HashRouter.h:53
ripple::test::HashRouter_test::testNonExpiration
void testNonExpiration()
Definition: HashRouter_test.cpp:30
ripple::base_uint< 256 >
ripple::test::HashRouter_test::testRecover
void testRecover()
Definition: HashRouter_test.cpp:232
ripple::HashRouter::addSuppression
void addSuppression(uint256 const &key)
Definition: HashRouter.cpp:46
ripple::HashRouter::shouldRecover
bool shouldRecover(uint256 const &key)
Determines whether the hashed item should be recovered from the open ledger into the next open ledger...
Definition: HashRouter.cpp:121
std::uint32_t
ripple::HashRouter::shouldRelay
boost::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
Definition: HashRouter.cpp:107
ripple::test::HashRouter_test::testSetFlags
void testSetFlags()
Definition: HashRouter_test.cpp:176
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::jtx::flags
Match set account flags.
Definition: flags.h:99
ripple::test::HashRouter_test::run
void run() override
Definition: HashRouter_test.cpp:287
ripple::test::HashRouter_test::testExpiration
void testExpiration()
Definition: HashRouter_test.cpp:67
beast::manual_clock< std::chrono::steady_clock >
ripple::test::HashRouter_test::testSuppression
void testSuppression()
Definition: HashRouter_test.cpp:145
ripple::test::HashRouter_test::testRelay
void testRelay()
Definition: HashRouter_test.cpp:189
ripple::HashRouter::setFlags
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
Definition: HashRouter.cpp:91