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);
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);
235  HashRouter::PeerShortID peer = 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 public:
246  void
247  run() override
248  {
250  testExpiration();
251  testSuppression();
252  testSetFlags();
253  testRelay();
254  testProcess();
255  }
256 };
257 
259 
260 } // namespace test
261 } // namespace ripple
ripple::HashRouter::addSuppressionPeer
bool addSuppressionPeer(uint256 const &key, PeerShortID peer)
Definition: HashRouter.cpp:51
ripple::HashRouter::getFlags
int getFlags(uint256 const &key)
Definition: HashRouter.cpp:94
ripple::HashRouter::shouldProcess
bool shouldProcess(uint256 const &key, PeerShortID peer, int &flags, std::chrono::seconds tx_interval)
Definition: HashRouter.cpp:78
ripple::test::HashRouter_test::testProcess
void testProcess()
Definition: HashRouter_test.cpp:229
ripple::stopwatch
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition: chrono.h:88
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::HashRouter::addSuppression
void addSuppression(uint256 const &key)
Definition: HashRouter.cpp:43
std::uint32_t
ripple::HashRouter::shouldRelay
std::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
Definition: HashRouter.cpp:118
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:247
ripple::test::HashRouter_test::testExpiration
void testExpiration()
Definition: HashRouter_test.cpp:67
std::optional
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:102
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(DeliverMin, app, ripple)