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 && 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, 2);
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, 2);
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, 2);
191 
192  uint256 const key1(1);
193 
194  boost::optional<std::set<HashRouter::PeerShortID>> peers;
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, 1s, 5);
234 
235  uint256 const key1(1);
236 
237  BEAST_EXPECT(router.shouldRecover(key1));
238  BEAST_EXPECT(router.shouldRecover(key1));
239  BEAST_EXPECT(router.shouldRecover(key1));
240  BEAST_EXPECT(router.shouldRecover(key1));
241  BEAST_EXPECT(router.shouldRecover(key1));
242  BEAST_EXPECT(!router.shouldRecover(key1));
243  // Expire, but since the next search will
244  // be for this entry, it will get refreshed
245  // instead.
246  ++stopwatch;
247  BEAST_EXPECT(router.shouldRecover(key1));
248  // Expire, but since the next search will
249  // be for this entry, it will get refreshed
250  // instead.
251  ++stopwatch;
252  // Recover again. Recovery is independent of
253  // time as long as the entry doesn't expire.
254  BEAST_EXPECT(router.shouldRecover(key1));
255  BEAST_EXPECT(router.shouldRecover(key1));
256  BEAST_EXPECT(router.shouldRecover(key1));
257  // Expire again
258  ++stopwatch;
259  BEAST_EXPECT(router.shouldRecover(key1));
260  BEAST_EXPECT(!router.shouldRecover(key1));
261  }
262 
263  void
265  {
266  using namespace std::chrono_literals;
268  HashRouter router(stopwatch, 5s, 5);
269  uint256 const key(1);
270  HashRouter::PeerShortID peer = 1;
271  int flags;
272 
273  BEAST_EXPECT(router.shouldProcess(key, peer, flags, 1s));
274  BEAST_EXPECT(!router.shouldProcess(key, peer, flags, 1s));
275  ++stopwatch;
276  ++stopwatch;
277  BEAST_EXPECT(router.shouldProcess(key, peer, flags, 1s));
278  }
279 
280 public:
281  void
282  run() override
283  {
285  testExpiration();
286  testSuppression();
287  testSetFlags();
288  testRelay();
289  testRecover();
290  testProcess();
291  }
292 };
293 
295 
296 } // namespace test
297 } // namespace ripple
ripple::HashRouter::addSuppressionPeer
bool addSuppressionPeer(uint256 const &key, PeerShortID peer)
Definition: HashRouter.cpp:51
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
ripple::HashRouter::getFlags
int getFlags(uint256 const &key)
Definition: HashRouter.cpp:88
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:264
ripple::stopwatch
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition: chrono.h:86
ripple::test::HashRouter_test
Definition: HashRouter_test.cpp:27
ripple::HashRouter
Routing table for objects identified by hash.
Definition: HashRouter.h:52
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:229
ripple::HashRouter::addSuppression
void addSuppression(uint256 const &key)
Definition: HashRouter.cpp:43
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:126
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:112
ripple::test::HashRouter_test::testSetFlags
void testSetFlags()
Definition: HashRouter_test.cpp:173
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:108
ripple::test::HashRouter_test::run
void run() override
Definition: HashRouter_test.cpp:282
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:144
ripple::test::HashRouter_test::testRelay
void testRelay()
Definition: HashRouter_test.cpp:186
ripple::HashRouter::setFlags
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
Definition: HashRouter.cpp:96