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
22#include <xrpl/basics/chrono.h>
23#include <xrpl/beast/unit_test.h>
24
25namespace ripple {
26namespace test {
27
29{
30 void
32 {
33 using namespace std::chrono_literals;
35 HashRouter router(stopwatch, 2s);
36
37 uint256 const key1(1);
38 uint256 const key2(2);
39 uint256 const key3(3);
40
41 // t=0
42 router.setFlags(key1, 11111);
43 BEAST_EXPECT(router.getFlags(key1) == 11111);
44 router.setFlags(key2, 22222);
45 BEAST_EXPECT(router.getFlags(key2) == 22222);
46 // key1 : 0
47 // key2 : 0
48 // key3: null
49
50 ++stopwatch;
51
52 // Because we are accessing key1 here, it
53 // will NOT be expired for another two ticks
54 BEAST_EXPECT(router.getFlags(key1) == 11111);
55 // key1 : 1
56 // key2 : 0
57 // key3 null
58
59 ++stopwatch;
60
61 // t=3
62 router.setFlags(key3, 33333); // force expiration
63 BEAST_EXPECT(router.getFlags(key1) == 11111);
64 BEAST_EXPECT(router.getFlags(key2) == 0);
65 }
66
67 void
69 {
70 using namespace std::chrono_literals;
72 HashRouter router(stopwatch, 2s);
73
74 uint256 const key1(1);
75 uint256 const key2(2);
76 uint256 const key3(3);
77 uint256 const key4(4);
78 BEAST_EXPECT(key1 != key2 && key2 != key3 && key3 != key4);
79
80 // t=0
81 router.setFlags(key1, 12345);
82 BEAST_EXPECT(router.getFlags(key1) == 12345);
83 // key1 : 0
84 // key2 : null
85 // key3 : null
86
87 ++stopwatch;
88
89 // Expiration is triggered by insertion,
90 // and timestamps are updated on access,
91 // so key1 will be expired after the second
92 // call to setFlags.
93 // t=1
94 router.setFlags(key2, 9999);
95 BEAST_EXPECT(router.getFlags(key1) == 12345);
96 BEAST_EXPECT(router.getFlags(key2) == 9999);
97 // key1 : 1
98 // key2 : 1
99 // key3 : null
100
101 ++stopwatch;
102 // t=2
103 BEAST_EXPECT(router.getFlags(key2) == 9999);
104 // key1 : 1
105 // key2 : 2
106 // key3 : null
107
108 ++stopwatch;
109 // t=3
110 router.setFlags(key3, 2222);
111 BEAST_EXPECT(router.getFlags(key1) == 0);
112 BEAST_EXPECT(router.getFlags(key2) == 9999);
113 BEAST_EXPECT(router.getFlags(key3) == 2222);
114 // key1 : 3
115 // key2 : 3
116 // key3 : 3
117
118 ++stopwatch;
119 // t=4
120 // No insertion, no expiration
121 router.setFlags(key1, 7654);
122 BEAST_EXPECT(router.getFlags(key1) == 7654);
123 BEAST_EXPECT(router.getFlags(key2) == 9999);
124 BEAST_EXPECT(router.getFlags(key3) == 2222);
125 // key1 : 4
126 // key2 : 4
127 // key3 : 4
128
129 ++stopwatch;
130 ++stopwatch;
131
132 // t=6
133 router.setFlags(key4, 7890);
134 BEAST_EXPECT(router.getFlags(key1) == 0);
135 BEAST_EXPECT(router.getFlags(key2) == 0);
136 BEAST_EXPECT(router.getFlags(key3) == 0);
137 BEAST_EXPECT(router.getFlags(key4) == 7890);
138 // key1 : 6
139 // key2 : 6
140 // key3 : 6
141 // key4 : 6
142 }
143
144 void
146 {
147 // Normal HashRouter
148 using namespace std::chrono_literals;
150 HashRouter router(stopwatch, 2s);
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 && key2 != key3 && key3 != key4);
157
158 int flags = 12345; // This value is ignored
159 router.addSuppression(key1);
160 BEAST_EXPECT(router.addSuppressionPeer(key2, 15));
161 BEAST_EXPECT(router.addSuppressionPeer(key3, 20, flags));
162 BEAST_EXPECT(flags == 0);
163
164 ++stopwatch;
165
166 BEAST_EXPECT(!router.addSuppressionPeer(key1, 2));
167 BEAST_EXPECT(!router.addSuppressionPeer(key2, 3));
168 BEAST_EXPECT(!router.addSuppressionPeer(key3, 4, flags));
169 BEAST_EXPECT(flags == 0);
170 BEAST_EXPECT(router.addSuppressionPeer(key4, 5));
171 }
172
173 void
175 {
176 using namespace std::chrono_literals;
178 HashRouter router(stopwatch, 2s);
179
180 uint256 const key1(1);
181 BEAST_EXPECT(router.setFlags(key1, 10));
182 BEAST_EXPECT(!router.setFlags(key1, 10));
183 BEAST_EXPECT(router.setFlags(key1, 20));
184 }
185
186 void
188 {
189 using namespace std::chrono_literals;
191 HashRouter router(stopwatch, 1s);
192
193 uint256 const key1(1);
194
196
197 peers = router.shouldRelay(key1);
198 BEAST_EXPECT(peers && peers->empty());
199 router.addSuppressionPeer(key1, 1);
200 router.addSuppressionPeer(key1, 3);
201 router.addSuppressionPeer(key1, 5);
202 // No action, because relayed
203 BEAST_EXPECT(!router.shouldRelay(key1));
204 // Expire, but since the next search will
205 // be for this entry, it will get refreshed
206 // instead. However, the relay won't.
207 ++stopwatch;
208 // Get those peers we added earlier
209 peers = router.shouldRelay(key1);
210 BEAST_EXPECT(peers && peers->size() == 3);
211 router.addSuppressionPeer(key1, 2);
212 router.addSuppressionPeer(key1, 4);
213 // No action, because relayed
214 BEAST_EXPECT(!router.shouldRelay(key1));
215 // Expire, but since the next search will
216 // be for this entry, it will get refreshed
217 // instead. However, the relay won't.
218 ++stopwatch;
219 // Relay again
220 peers = router.shouldRelay(key1);
221 BEAST_EXPECT(peers && peers->size() == 2);
222 // Expire again
223 ++stopwatch;
224 // Confirm that peers list is empty.
225 peers = router.shouldRelay(key1);
226 BEAST_EXPECT(peers && peers->size() == 0);
227 }
228
229 void
231 {
232 using namespace std::chrono_literals;
234 HashRouter router(stopwatch, 5s);
235 uint256 const key(1);
237 int flags;
238
239 BEAST_EXPECT(router.shouldProcess(key, peer, flags, 1s));
240 BEAST_EXPECT(!router.shouldProcess(key, peer, flags, 1s));
241 ++stopwatch;
242 ++stopwatch;
243 BEAST_EXPECT(router.shouldProcess(key, peer, flags, 1s));
244 }
245
246public:
247 void
248 run() override
249 {
253 testSetFlags();
254 testRelay();
255 testProcess();
256 }
257};
258
259BEAST_DEFINE_TESTSUITE(HashRouter, app, ripple);
260
261} // namespace test
262} // namespace ripple
A testsuite class.
Definition: suite.h:55
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:118
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: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:102
void addSuppression(uint256 const &key)
Definition: HashRouter.cpp:43
void run() override
Runs the suite.
Match set account flags.
Definition: flags.h:113
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:119