rippled
Issue_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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/basics/UnorderedContainers.h>
21 #include <ripple/beast/unit_test.h>
22 #include <ripple/protocol/Book.h>
23 #include <ripple/protocol/Issue.h>
24 #include <map>
25 #include <set>
26 #include <typeinfo>
27 #include <unordered_set>
28 
29 #if BEAST_MSVC
30 #define STL_SET_HAS_EMPLACE 1
31 #else
32 #define STL_SET_HAS_EMPLACE 0
33 #endif
34 
35 #ifndef RIPPLE_ASSETS_ENABLE_STD_HASH
36 #if BEAST_MAC || BEAST_IOS
37 #define RIPPLE_ASSETS_ENABLE_STD_HASH 0
38 #else
39 #define RIPPLE_ASSETS_ENABLE_STD_HASH 1
40 #endif
41 #endif
42 
43 namespace ripple {
44 
45 class Issue_test : public beast::unit_test::suite
46 {
47 public:
48  // Comparison, hash tests for uint60 (via base_uint)
49  template <typename Unsigned>
50  void
52  {
53  Unsigned const u1(1);
54  Unsigned const u2(2);
55  Unsigned const u3(3);
56 
57  BEAST_EXPECT(u1 != u2);
58  BEAST_EXPECT(u1 < u2);
59  BEAST_EXPECT(u1 <= u2);
60  BEAST_EXPECT(u2 <= u2);
61  BEAST_EXPECT(u2 == u2);
62  BEAST_EXPECT(u2 >= u2);
63  BEAST_EXPECT(u3 >= u2);
64  BEAST_EXPECT(u3 > u2);
65 
67 
68  BEAST_EXPECT(hash(u1) == hash(u1));
69  BEAST_EXPECT(hash(u2) == hash(u2));
70  BEAST_EXPECT(hash(u3) == hash(u3));
71  BEAST_EXPECT(hash(u1) != hash(u2));
72  BEAST_EXPECT(hash(u1) != hash(u3));
73  BEAST_EXPECT(hash(u2) != hash(u3));
74  }
75 
76  //--------------------------------------------------------------------------
77 
78  // Comparison, hash tests for Issue
79  template <class Issue>
80  void
82  {
83  Currency const c1(1);
84  AccountID const i1(1);
85  Currency const c2(2);
86  AccountID const i2(2);
87  Currency const c3(3);
88  AccountID const i3(3);
89 
90  BEAST_EXPECT(Issue(c1, i1) != Issue(c2, i1));
91  BEAST_EXPECT(Issue(c1, i1) < Issue(c2, i1));
92  BEAST_EXPECT(Issue(c1, i1) <= Issue(c2, i1));
93  BEAST_EXPECT(Issue(c2, i1) <= Issue(c2, i1));
94  BEAST_EXPECT(Issue(c2, i1) == Issue(c2, i1));
95  BEAST_EXPECT(Issue(c2, i1) >= Issue(c2, i1));
96  BEAST_EXPECT(Issue(c3, i1) >= Issue(c2, i1));
97  BEAST_EXPECT(Issue(c3, i1) > Issue(c2, i1));
98  BEAST_EXPECT(Issue(c1, i1) != Issue(c1, i2));
99  BEAST_EXPECT(Issue(c1, i1) < Issue(c1, i2));
100  BEAST_EXPECT(Issue(c1, i1) <= Issue(c1, i2));
101  BEAST_EXPECT(Issue(c1, i2) <= Issue(c1, i2));
102  BEAST_EXPECT(Issue(c1, i2) == Issue(c1, i2));
103  BEAST_EXPECT(Issue(c1, i2) >= Issue(c1, i2));
104  BEAST_EXPECT(Issue(c1, i3) >= Issue(c1, i2));
105  BEAST_EXPECT(Issue(c1, i3) > Issue(c1, i2));
106 
107  std::hash<Issue> hash;
108 
109  BEAST_EXPECT(hash(Issue(c1, i1)) == hash(Issue(c1, i1)));
110  BEAST_EXPECT(hash(Issue(c1, i2)) == hash(Issue(c1, i2)));
111  BEAST_EXPECT(hash(Issue(c1, i3)) == hash(Issue(c1, i3)));
112  BEAST_EXPECT(hash(Issue(c2, i1)) == hash(Issue(c2, i1)));
113  BEAST_EXPECT(hash(Issue(c2, i2)) == hash(Issue(c2, i2)));
114  BEAST_EXPECT(hash(Issue(c2, i3)) == hash(Issue(c2, i3)));
115  BEAST_EXPECT(hash(Issue(c3, i1)) == hash(Issue(c3, i1)));
116  BEAST_EXPECT(hash(Issue(c3, i2)) == hash(Issue(c3, i2)));
117  BEAST_EXPECT(hash(Issue(c3, i3)) == hash(Issue(c3, i3)));
118  BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c1, i2)));
119  BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c1, i3)));
120  BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i1)));
121  BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i2)));
122  BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i3)));
123  BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i1)));
124  BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i2)));
125  BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i3)));
126  }
127 
128  template <class Set>
129  void
131  {
132  Currency const c1(1);
133  AccountID const i1(1);
134  Currency const c2(2);
135  AccountID const i2(2);
136  Issue const a1(c1, i1);
137  Issue const a2(c2, i2);
138 
139  {
140  Set c;
141 
142  c.insert(a1);
143  if (!BEAST_EXPECT(c.size() == 1))
144  return;
145  c.insert(a2);
146  if (!BEAST_EXPECT(c.size() == 2))
147  return;
148 
149  if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
150  return;
151  if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
152  return;
153  if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
154  return;
155  if (!BEAST_EXPECT(c.empty()))
156  return;
157  }
158 
159  {
160  Set c;
161 
162  c.insert(a1);
163  if (!BEAST_EXPECT(c.size() == 1))
164  return;
165  c.insert(a2);
166  if (!BEAST_EXPECT(c.size() == 2))
167  return;
168 
169  if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
170  return;
171  if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
172  return;
173  if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
174  return;
175  if (!BEAST_EXPECT(c.empty()))
176  return;
177 
178 #if STL_SET_HAS_EMPLACE
179  c.emplace(c1, i1);
180  if (!BEAST_EXPECT(c.size() == 1))
181  return;
182  c.emplace(c2, i2);
183  if (!BEAST_EXPECT(c.size() == 2))
184  return;
185 #endif
186  }
187  }
188 
189  template <class Map>
190  void
192  {
193  Currency const c1(1);
194  AccountID const i1(1);
195  Currency const c2(2);
196  AccountID const i2(2);
197  Issue const a1(c1, i1);
198  Issue const a2(c2, i2);
199 
200  {
201  Map c;
202 
203  c.insert(std::make_pair(a1, 1));
204  if (!BEAST_EXPECT(c.size() == 1))
205  return;
206  c.insert(std::make_pair(a2, 2));
207  if (!BEAST_EXPECT(c.size() == 2))
208  return;
209 
210  if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
211  return;
212  if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
213  return;
214  if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
215  return;
216  if (!BEAST_EXPECT(c.empty()))
217  return;
218  }
219 
220  {
221  Map c;
222 
223  c.insert(std::make_pair(a1, 1));
224  if (!BEAST_EXPECT(c.size() == 1))
225  return;
226  c.insert(std::make_pair(a2, 2));
227  if (!BEAST_EXPECT(c.size() == 2))
228  return;
229 
230  if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
231  return;
232  if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
233  return;
234  if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
235  return;
236  if (!BEAST_EXPECT(c.empty()))
237  return;
238  }
239  }
240 
241  void
243  {
244  testcase("std::set <Issue>");
245  testIssueSet<std::set<Issue>>();
246 
247  testcase("std::set <Issue>");
248  testIssueSet<std::set<Issue>>();
249 
250 #if RIPPLE_ASSETS_ENABLE_STD_HASH
251  testcase("std::unordered_set <Issue>");
252  testIssueSet<std::unordered_set<Issue>>();
253 
254  testcase("std::unordered_set <Issue>");
255  testIssueSet<std::unordered_set<Issue>>();
256 #endif
257 
258  testcase("hash_set <Issue>");
259  testIssueSet<hash_set<Issue>>();
260 
261  testcase("hash_set <Issue>");
262  testIssueSet<hash_set<Issue>>();
263  }
264 
265  void
267  {
268  testcase("std::map <Issue, int>");
269  testIssueMap<std::map<Issue, int>>();
270 
271  testcase("std::map <Issue, int>");
272  testIssueMap<std::map<Issue, int>>();
273 
274 #if RIPPLE_ASSETS_ENABLE_STD_HASH
275  testcase("std::unordered_map <Issue, int>");
276  testIssueMap<std::unordered_map<Issue, int>>();
277 
278  testcase("std::unordered_map <Issue, int>");
279  testIssueMap<std::unordered_map<Issue, int>>();
280 
281  testcase("hash_map <Issue, int>");
282  testIssueMap<hash_map<Issue, int>>();
283 
284  testcase("hash_map <Issue, int>");
285  testIssueMap<hash_map<Issue, int>>();
286 
287 #endif
288  }
289 
290  //--------------------------------------------------------------------------
291 
292  // Comparison, hash tests for Book
293  template <class Book>
294  void
296  {
297  Currency const c1(1);
298  AccountID const i1(1);
299  Currency const c2(2);
300  AccountID const i2(2);
301  Currency const c3(3);
302  AccountID const i3(3);
303 
304  Issue a1(c1, i1);
305  Issue a2(c1, i2);
306  Issue a3(c2, i2);
307  Issue a4(c3, i2);
308 
309  BEAST_EXPECT(Book(a1, a2) != Book(a2, a3));
310  BEAST_EXPECT(Book(a1, a2) < Book(a2, a3));
311  BEAST_EXPECT(Book(a1, a2) <= Book(a2, a3));
312  BEAST_EXPECT(Book(a2, a3) <= Book(a2, a3));
313  BEAST_EXPECT(Book(a2, a3) == Book(a2, a3));
314  BEAST_EXPECT(Book(a2, a3) >= Book(a2, a3));
315  BEAST_EXPECT(Book(a3, a4) >= Book(a2, a3));
316  BEAST_EXPECT(Book(a3, a4) > Book(a2, a3));
317 
318  std::hash<Book> hash;
319 
320  // log << std::hex << hash (Book (a1, a2));
321  // log << std::hex << hash (Book (a1, a2));
322  //
323  // log << std::hex << hash (Book (a1, a3));
324  // log << std::hex << hash (Book (a1, a3));
325  //
326  // log << std::hex << hash (Book (a1, a4));
327  // log << std::hex << hash (Book (a1, a4));
328  //
329  // log << std::hex << hash (Book (a2, a3));
330  // log << std::hex << hash (Book (a2, a3));
331  //
332  // log << std::hex << hash (Book (a2, a4));
333  // log << std::hex << hash (Book (a2, a4));
334  //
335  // log << std::hex << hash (Book (a3, a4));
336  // log << std::hex << hash (Book (a3, a4));
337 
338  BEAST_EXPECT(hash(Book(a1, a2)) == hash(Book(a1, a2)));
339  BEAST_EXPECT(hash(Book(a1, a3)) == hash(Book(a1, a3)));
340  BEAST_EXPECT(hash(Book(a1, a4)) == hash(Book(a1, a4)));
341  BEAST_EXPECT(hash(Book(a2, a3)) == hash(Book(a2, a3)));
342  BEAST_EXPECT(hash(Book(a2, a4)) == hash(Book(a2, a4)));
343  BEAST_EXPECT(hash(Book(a3, a4)) == hash(Book(a3, a4)));
344 
345  BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a1, a3)));
346  BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a1, a4)));
347  BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a2, a3)));
348  BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a2, a4)));
349  BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a3, a4)));
350  }
351 
352  //--------------------------------------------------------------------------
353 
354  template <class Set>
355  void
357  {
358  Currency const c1(1);
359  AccountID const i1(1);
360  Currency const c2(2);
361  AccountID const i2(2);
362  Issue const a1(c1, i1);
363  Issue const a2(c2, i2);
364  Book const b1(a1, a2);
365  Book const b2(a2, a1);
366 
367  {
368  Set c;
369 
370  c.insert(b1);
371  if (!BEAST_EXPECT(c.size() == 1))
372  return;
373  c.insert(b2);
374  if (!BEAST_EXPECT(c.size() == 2))
375  return;
376 
377  if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
378  return;
379  if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
380  return;
381  if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
382  return;
383  if (!BEAST_EXPECT(c.empty()))
384  return;
385  }
386 
387  {
388  Set c;
389 
390  c.insert(b1);
391  if (!BEAST_EXPECT(c.size() == 1))
392  return;
393  c.insert(b2);
394  if (!BEAST_EXPECT(c.size() == 2))
395  return;
396 
397  if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
398  return;
399  if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
400  return;
401  if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
402  return;
403  if (!BEAST_EXPECT(c.empty()))
404  return;
405 
406 #if STL_SET_HAS_EMPLACE
407  c.emplace(a1, a2);
408  if (!BEAST_EXPECT(c.size() == 1))
409  return;
410  c.emplace(a2, a1);
411  if (!BEAST_EXPECT(c.size() == 2))
412  return;
413 #endif
414  }
415  }
416 
417  template <class Map>
418  void
420  {
421  Currency const c1(1);
422  AccountID const i1(1);
423  Currency const c2(2);
424  AccountID const i2(2);
425  Issue const a1(c1, i1);
426  Issue const a2(c2, i2);
427  Book const b1(a1, a2);
428  Book const b2(a2, a1);
429 
430  // typename Map::value_type value_type;
431  // std::pair <Book const, int> value_type;
432 
433  {
434  Map c;
435 
436  // c.insert (value_type (b1, 1));
437  c.insert(std::make_pair(b1, 1));
438  if (!BEAST_EXPECT(c.size() == 1))
439  return;
440  // c.insert (value_type (b2, 2));
441  c.insert(std::make_pair(b2, 1));
442  if (!BEAST_EXPECT(c.size() == 2))
443  return;
444 
445  if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
446  return;
447  if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
448  return;
449  if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
450  return;
451  if (!BEAST_EXPECT(c.empty()))
452  return;
453  }
454 
455  {
456  Map c;
457 
458  // c.insert (value_type (b1, 1));
459  c.insert(std::make_pair(b1, 1));
460  if (!BEAST_EXPECT(c.size() == 1))
461  return;
462  // c.insert (value_type (b2, 2));
463  c.insert(std::make_pair(b2, 1));
464  if (!BEAST_EXPECT(c.size() == 2))
465  return;
466 
467  if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
468  return;
469  if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
470  return;
471  if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
472  return;
473  if (!BEAST_EXPECT(c.empty()))
474  return;
475  }
476  }
477 
478  void
480  {
481  testcase("std::set <Book>");
482  testBookSet<std::set<Book>>();
483 
484  testcase("std::set <Book>");
485  testBookSet<std::set<Book>>();
486 
487 #if RIPPLE_ASSETS_ENABLE_STD_HASH
488  testcase("std::unordered_set <Book>");
489  testBookSet<std::unordered_set<Book>>();
490 
491  testcase("std::unordered_set <Book>");
492  testBookSet<std::unordered_set<Book>>();
493 #endif
494 
495  testcase("hash_set <Book>");
496  testBookSet<hash_set<Book>>();
497 
498  testcase("hash_set <Book>");
499  testBookSet<hash_set<Book>>();
500  }
501 
502  void
504  {
505  testcase("std::map <Book, int>");
506  testBookMap<std::map<Book, int>>();
507 
508  testcase("std::map <Book, int>");
509  testBookMap<std::map<Book, int>>();
510 
511 #if RIPPLE_ASSETS_ENABLE_STD_HASH
512  testcase("std::unordered_map <Book, int>");
513  testBookMap<std::unordered_map<Book, int>>();
514 
515  testcase("std::unordered_map <Book, int>");
516  testBookMap<std::unordered_map<Book, int>>();
517 
518  testcase("hash_map <Book, int>");
519  testBookMap<hash_map<Book, int>>();
520 
521  testcase("hash_map <Book, int>");
522  testBookMap<hash_map<Book, int>>();
523 #endif
524  }
525 
526  //--------------------------------------------------------------------------
527 
528  void
529  run() override
530  {
531  testcase("Currency");
532  testUnsigned<Currency>();
533 
534  testcase("AccountID");
535  testUnsigned<AccountID>();
536 
537  // ---
538 
539  testcase("Issue");
540  testIssue<Issue>();
541 
542  testcase("Issue");
543  testIssue<Issue>();
544 
545  testIssueSets();
546  testIssueMaps();
547 
548  // ---
549 
550  testcase("Book");
551  testBook<Book>();
552 
553  testcase("Book");
554  testBook<Book>();
555 
556  testBookSets();
557  testBookMaps();
558  }
559 };
560 
562 
563 } // namespace ripple
ripple::Issue_test::testIssue
void testIssue()
Definition: Issue_test.cpp:81
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
ripple::Issue_test::testBookMaps
void testBookMaps()
Definition: Issue_test.cpp:503
unordered_set
ripple::Issue_test::run
void run() override
Definition: Issue_test.cpp:529
ripple::Issue_test::testIssueMap
void testIssueMap()
Definition: Issue_test.cpp:191
ripple::Issue_test
Definition: Issue_test.cpp:45
ripple::Issue_test::testIssueSets
void testIssueSets()
Definition: Issue_test.cpp:242
ripple::base_uint< 160, detail::CurrencyTag >
ripple::Issue_test::testIssueMaps
void testIssueMaps()
Definition: Issue_test.cpp:266
map
ripple::Issue_test::testIssueSet
void testIssueSet()
Definition: Issue_test.cpp:130
ripple::Issue_test::testBookMap
void testBookMap()
Definition: Issue_test.cpp:419
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
protocol
Definition: ValidatorList.h:38
ripple::Issue_test::testBook
void testBook()
Definition: Issue_test.cpp:295
typeinfo
ripple::Book
Specifies an order book.
Definition: Book.h:33
std::make_pair
T make_pair(T... args)
ripple::Issue_test::testUnsigned
void testUnsigned()
Definition: Issue_test.cpp:51
ripple::Issue_test::testBookSet
void testBookSet()
Definition: Issue_test.cpp:356
set
std::hash
ripple::Issue_test::testBookSets
void testBookSets()
Definition: Issue_test.cpp:479