rippled
Loading...
Searching...
No Matches
Taker_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 <xrpld/app/tx/detail/Taker.h>
21
22#include <xrpl/beast/unit_test.h>
23
24namespace ripple {
25
27{
28 static bool const Buy = false;
29 static bool const Sell = true;
30
31 class TestTaker : public BasicTaker
32 {
35
36 public:
39 Amounts const& amount,
40 Quality const& quality,
41 STAmount const& funds,
42 std::uint32_t flags,
43 Rate const& rate_in,
44 Rate const& rate_out)
45 : BasicTaker(
47 AccountID(0x4701),
48 amount,
49 quality,
50 flags,
51 rate_in,
52 rate_out)
53 , funds_(funds)
54 {
55 }
56
57 void
58 set_funds(STAmount const& funds)
59 {
60 cross_funds = funds;
61 }
62
64 get_funds(AccountID const& owner, STAmount const& funds) const override
65 {
66 if (owner == account())
67 return funds_;
68
69 return cross_funds;
70 }
71
72 Amounts
73 cross(Amounts offer, Quality quality)
74 {
75 if (reject(quality))
76 return Amounts(offer.in.zeroed(), offer.out.zeroed());
77
78 // we need to emulate "unfunded offers" behavior
79 if (get_funds(AccountID(0x4702), offer.out) == beast::zero)
80 return Amounts(offer.in.zeroed(), offer.out.zeroed());
81
82 if (done())
83 return Amounts(offer.in.zeroed(), offer.out.zeroed());
84
85 auto result = do_cross(offer, quality, AccountID(0x4702));
86
87 funds_ -= result.order.in;
88
89 return result.order;
90 }
91
94 Amounts offer1,
95 Quality quality1,
96 Amounts offer2,
97 Quality quality2)
98 {
99 /* check if composed quality should be rejected */
100 Quality const quality(composed_quality(quality1, quality2));
101
102 if (reject(quality))
103 return std::make_pair(
104 Amounts{offer1.in.zeroed(), offer1.out.zeroed()},
105 Amounts{offer2.in.zeroed(), offer2.out.zeroed()});
106
107 if (done())
108 return std::make_pair(
109 Amounts{offer1.in.zeroed(), offer1.out.zeroed()},
110 Amounts{offer2.in.zeroed(), offer2.out.zeroed()});
111
112 auto result = do_cross(
113 offer1,
114 quality1,
115 AccountID(0x4703),
116 offer2,
117 quality2,
118 AccountID(0x4704));
119
120 return std::make_pair(result.first.order, result.second.order);
121 }
122 };
123
124private:
125 Issue const&
126 usd() const
127 {
128 static Issue const issue(
129 Currency(0x5553440000000000), AccountID(0x4985601));
130 return issue;
131 }
132
133 Issue const&
134 eur() const
135 {
136 static Issue const issue(
137 Currency(0x4555520000000000), AccountID(0x4985602));
138 return issue;
139 }
140
141 Issue const&
142 xrp() const
143 {
144 static Issue const issue(xrpCurrency(), xrpAccount());
145 return issue;
146 }
147
149 parse_amount(std::string const& amount, Issue const& issue)
150 {
151 return amountFromString(issue, amount);
152 }
153
154 Amounts
156 std::string const& amount_in,
157 Issue const& issue_in,
158 std::string const& amount_out,
159 Issue const& issue_out)
160 {
161 STAmount const in(parse_amount(amount_in, issue_in));
162 STAmount const out(parse_amount(amount_out, issue_out));
163
164 return {in, out};
165 }
166
168 {
170 : in(in_), out(out_)
171 {
172 }
173
176 };
177
178private:
180 format_amount(STAmount const& amount)
181 {
182 std::string txt = amount.getText();
183 txt += "/";
184 txt += to_string(amount.issue().currency);
185 return txt;
186 }
187
188 void
190 bool sell,
191 std::string name,
192 Quality taker_quality,
193 cross_attempt_offer const offer,
194 std::string const funds,
195 Quality cross_quality,
196 cross_attempt_offer const cross,
197 std::string const cross_funds,
199 Issue const& issue_in,
200 Issue const& issue_out,
201 Rate rate_in = parityRate,
202 Rate rate_out = parityRate)
203 {
204 Amounts taker_offer(
205 parse_amounts(offer.in, issue_in, offer.out, issue_out));
206
207 Amounts cross_offer(
208 parse_amounts(cross.in, issue_in, cross.out, issue_out));
209
210 CrossType cross_type;
211
212 if (isXRP(issue_out))
213 cross_type = CrossType::IouToXrp;
214 else if (isXRP(issue_in))
215 cross_type = CrossType::XrpToIou;
216 else
217 cross_type = CrossType::IouToIou;
218
219 // FIXME: We are always invoking the IOU-to-IOU taker. We should select
220 // the correct type dynamically.
221 TestTaker taker(
222 cross_type,
223 taker_offer,
224 taker_quality,
225 parse_amount(funds, issue_in),
226 sell ? tfSell : 0,
227 rate_in,
228 rate_out);
229
230 taker.set_funds(parse_amount(cross_funds, issue_out));
231
232 auto result = taker.cross(cross_offer, cross_quality);
233
234 Amounts const expected(
235 parse_amounts(flow.in, issue_in, flow.out, issue_out));
236
237 BEAST_EXPECT(expected == result);
238
239 if (expected != result)
240 {
241 log << "Expected: " << format_amount(expected.in) << " : "
242 << format_amount(expected.out) << '\n'
243 << " Actual: " << format_amount(result.in) << " : "
244 << format_amount(result.out) << std::endl;
245 }
246 }
247
248 Quality
250 {
251 return Quality(parse_amounts(in, xrp(), out, xrp()));
252 }
253
254public:
255 // Notation for clamp scenario descriptions:
256 //
257 // IN:OUT (with the last in the list being limiting factor)
258 // N = Nothing
259 // T = Taker Offer Balance
260 // A = Taker Account Balance
261 // B = Owner Account Balance
262 //
263 // (s) = sell semantics: taker wants unlimited output
264 // (b) = buy semantics: taker wants a limited amount out
265
266 // NIKB TODO: Augment TestTaker so currencies and rates can be specified
267 // once without need for repetition.
268 void
270 {
271 testcase("XRP Quantization: input");
272
273 Quality q1 = get_quality("1", "1");
274
275 for (auto NumberSwitchOver : {false, true})
276 {
277 NumberSO stNumberSO{NumberSwitchOver};
278 // TAKER OWNER
279 // QUAL OFFER FUNDS QUAL OFFER FUNDS
280 // EXPECTED
281 // XRP USD
282 attempt(
283 Sell,
284 "N:N",
285 q1,
286 {"2", "2"},
287 "2",
288 q1,
289 {"2", "2"},
290 "2",
291 {"2", "2"},
292 xrp(),
293 usd());
294 if (NumberSwitchOver)
295 {
296 attempt(
297 Sell,
298 "N:B",
299 q1,
300 {"2", "2"},
301 "2",
302 q1,
303 {"2", "2"},
304 "1.8",
305 {"2", "1.8"},
306 xrp(),
307 usd());
308 }
309 else
310 {
311 attempt(
312 Sell,
313 "N:B",
314 q1,
315 {"2", "2"},
316 "2",
317 q1,
318 {"2", "2"},
319 "1.8",
320 {"1", "1.8"},
321 xrp(),
322 usd());
323 }
324 attempt(
325 Buy,
326 "N:T",
327 q1,
328 {"1", "1"},
329 "2",
330 q1,
331 {"2", "2"},
332 "2",
333 {"1", "1"},
334 xrp(),
335 usd());
336 attempt(
337 Buy,
338 "N:BT",
339 q1,
340 {"1", "1"},
341 "2",
342 q1,
343 {"2", "2"},
344 "1.8",
345 {"1", "1"},
346 xrp(),
347 usd());
348 if (NumberSwitchOver)
349 {
350 attempt(
351 Buy,
352 "N:TB",
353 q1,
354 {"1", "1"},
355 "2",
356 q1,
357 {"2", "2"},
358 "0.8",
359 {"1", "0.8"},
360 xrp(),
361 usd());
362 }
363 else
364 {
365 attempt(
366 Buy,
367 "N:TB",
368 q1,
369 {"1", "1"},
370 "2",
371 q1,
372 {"2", "2"},
373 "0.8",
374 {"0", "0.8"},
375 xrp(),
376 usd());
377 }
378 attempt(
379 Sell,
380 "T:N",
381 q1,
382 {"1", "1"},
383 "2",
384 q1,
385 {"2", "2"},
386 "2",
387 {"1", "1"},
388 xrp(),
389 usd());
390 if (NumberSwitchOver)
391 {
392 attempt(
393 Sell,
394 "T:B",
395 q1,
396 {"1", "1"},
397 "2",
398 q1,
399 {"2", "2"},
400 "1.8",
401 {"1", "1"},
402 xrp(),
403 usd());
404 }
405 else
406 {
407 attempt(
408 Sell,
409 "T:B",
410 q1,
411 {"1", "1"},
412 "2",
413 q1,
414 {"2", "2"},
415 "1.8",
416 {"1", "1.8"},
417 xrp(),
418 usd());
419 }
420 attempt(
421 Buy,
422 "T:T",
423 q1,
424 {"1", "1"},
425 "2",
426 q1,
427 {"2", "2"},
428 "2",
429 {"1", "1"},
430 xrp(),
431 usd());
432 attempt(
433 Buy,
434 "T:BT",
435 q1,
436 {"1", "1"},
437 "2",
438 q1,
439 {"2", "2"},
440 "1.8",
441 {"1", "1"},
442 xrp(),
443 usd());
444 if (NumberSwitchOver)
445 {
446 attempt(
447 Buy,
448 "T:TB",
449 q1,
450 {"1", "1"},
451 "2",
452 q1,
453 {"2", "2"},
454 "0.8",
455 {"1", "0.8"},
456 xrp(),
457 usd());
458 }
459 else
460 {
461 attempt(
462 Buy,
463 "T:TB",
464 q1,
465 {"1", "1"},
466 "2",
467 q1,
468 {"2", "2"},
469 "0.8",
470 {"0", "0.8"},
471 xrp(),
472 usd());
473 }
474
475 attempt(
476 Sell,
477 "A:N",
478 q1,
479 {"2", "2"},
480 "1",
481 q1,
482 {"2", "2"},
483 "2",
484 {"1", "1"},
485 xrp(),
486 usd());
487 if (NumberSwitchOver)
488 {
489 attempt(
490 Sell,
491 "A:B",
492 q1,
493 {"2", "2"},
494 "1",
495 q1,
496 {"2", "2"},
497 "1.8",
498 {"1", "1"},
499 xrp(),
500 usd());
501 }
502 else
503 {
504 attempt(
505 Sell,
506 "A:B",
507 q1,
508 {"2", "2"},
509 "1",
510 q1,
511 {"2", "2"},
512 "1.8",
513 {"1", "1.8"},
514 xrp(),
515 usd());
516 }
517 attempt(
518 Buy,
519 "A:T",
520 q1,
521 {"2", "2"},
522 "1",
523 q1,
524 {"3", "3"},
525 "3",
526 {"1", "1"},
527 xrp(),
528 usd());
529 attempt(
530 Buy,
531 "A:BT",
532 q1,
533 {"2", "2"},
534 "1",
535 q1,
536 {"3", "3"},
537 "2.4",
538 {"1", "1"},
539 xrp(),
540 usd());
541 if (NumberSwitchOver)
542 {
543 attempt(
544 Buy,
545 "A:TB",
546 q1,
547 {"2", "2"},
548 "1",
549 q1,
550 {"3", "3"},
551 "0.8",
552 {"1", "0.8"},
553 xrp(),
554 usd());
555 }
556 else
557 {
558 attempt(
559 Buy,
560 "A:TB",
561 q1,
562 {"2", "2"},
563 "1",
564 q1,
565 {"3", "3"},
566 "0.8",
567 {"0", "0.8"},
568 xrp(),
569 usd());
570 }
571
572 attempt(
573 Sell,
574 "TA:N",
575 q1,
576 {"2", "2"},
577 "1",
578 q1,
579 {"2", "2"},
580 "2",
581 {"1", "1"},
582 xrp(),
583 usd());
584 if (NumberSwitchOver)
585 {
586 attempt(
587 Sell,
588 "TA:B",
589 q1,
590 {"2", "2"},
591 "1",
592 q1,
593 {"3", "3"},
594 "1.8",
595 {"1", "1"},
596 xrp(),
597 usd());
598 }
599 else
600 {
601 attempt(
602 Sell,
603 "TA:B",
604 q1,
605 {"2", "2"},
606 "1",
607 q1,
608 {"3", "3"},
609 "1.8",
610 {"1", "1.8"},
611 xrp(),
612 usd());
613 }
614 attempt(
615 Buy,
616 "TA:T",
617 q1,
618 {"2", "2"},
619 "1",
620 q1,
621 {"3", "3"},
622 "3",
623 {"1", "1"},
624 xrp(),
625 usd());
626 if (NumberSwitchOver)
627 {
628 attempt(
629 Buy,
630 "TA:BT",
631 q1,
632 {"2", "2"},
633 "1",
634 q1,
635 {"3", "3"},
636 "1.8",
637 {"1", "1"},
638 xrp(),
639 usd());
640 attempt(
641 Buy,
642 "TA:TB",
643 q1,
644 {"2", "2"},
645 "1",
646 q1,
647 {"3", "3"},
648 "1.8",
649 {"1", "1"},
650 xrp(),
651 usd());
652 }
653 else
654 {
655 attempt(
656 Buy,
657 "TA:BT",
658 q1,
659 {"2", "2"},
660 "1",
661 q1,
662 {"3", "3"},
663 "1.8",
664 {"1", "1.8"},
665 xrp(),
666 usd());
667 attempt(
668 Buy,
669 "TA:TB",
670 q1,
671 {"2", "2"},
672 "1",
673 q1,
674 {"3", "3"},
675 "1.8",
676 {"1", "1.8"},
677 xrp(),
678 usd());
679 }
680
681 attempt(
682 Sell,
683 "AT:N",
684 q1,
685 {"2", "2"},
686 "1",
687 q1,
688 {"3", "3"},
689 "3",
690 {"1", "1"},
691 xrp(),
692 usd());
693 if (NumberSwitchOver)
694 {
695 attempt(
696 Sell,
697 "AT:B",
698 q1,
699 {"2", "2"},
700 "1",
701 q1,
702 {"3", "3"},
703 "1.8",
704 {"1", "1"},
705 xrp(),
706 usd());
707 }
708 else
709 {
710 attempt(
711 Sell,
712 "AT:B",
713 q1,
714 {"2", "2"},
715 "1",
716 q1,
717 {"3", "3"},
718 "1.8",
719 {"1", "1.8"},
720 xrp(),
721 usd());
722 }
723 attempt(
724 Buy,
725 "AT:T",
726 q1,
727 {"2", "2"},
728 "1",
729 q1,
730 {"3", "3"},
731 "3",
732 {"1", "1"},
733 xrp(),
734 usd());
735 if (NumberSwitchOver)
736 {
737 attempt(
738 Buy,
739 "AT:BT",
740 q1,
741 {"2", "2"},
742 "1",
743 q1,
744 {"3", "3"},
745 "1.8",
746 {"1", "1"},
747 xrp(),
748 usd());
749 attempt(
750 Buy,
751 "AT:TB",
752 q1,
753 {"2", "2"},
754 "1",
755 q1,
756 {"3", "3"},
757 "0.8",
758 {"1", "0.8"},
759 xrp(),
760 usd());
761 }
762 else
763 {
764 attempt(
765 Buy,
766 "AT:BT",
767 q1,
768 {"2", "2"},
769 "1",
770 q1,
771 {"3", "3"},
772 "1.8",
773 {"1", "1.8"},
774 xrp(),
775 usd());
776 attempt(
777 Buy,
778 "AT:TB",
779 q1,
780 {"2", "2"},
781 "1",
782 q1,
783 {"3", "3"},
784 "0.8",
785 {"0", "0.8"},
786 xrp(),
787 usd());
788 }
789 }
790 }
791
792 void
794 {
795 testcase("XRP Quantization: output");
796
797 for (auto NumberSwitchOver : {false, true})
798 {
799 NumberSO stNumberSO{NumberSwitchOver};
800 Quality q1 = get_quality("1", "1");
801
802 // TAKER OWNER
803 // QUAL OFFER FUNDS QUAL OFFER FUNDS
804 // EXPECTED
805 // USD XRP
806 attempt(
807 Sell,
808 "N:N",
809 q1,
810 {"3", "3"},
811 "3",
812 q1,
813 {"3", "3"},
814 "3",
815 {"3", "3"},
816 usd(),
817 xrp());
818 attempt(
819 Sell,
820 "N:B",
821 q1,
822 {"3", "3"},
823 "3",
824 q1,
825 {"3", "3"},
826 "2",
827 {"2", "2"},
828 usd(),
829 xrp());
830 if (NumberSwitchOver)
831 {
832 attempt(
833 Buy,
834 "N:T",
835 q1,
836 {"3", "3"},
837 "2.5",
838 q1,
839 {"5", "5"},
840 "5",
841 {"2.5", "3"},
842 usd(),
843 xrp());
844 attempt(
845 Buy,
846 "N:BT",
847 q1,
848 {"3", "3"},
849 "1.5",
850 q1,
851 {"5", "5"},
852 "4",
853 {"1.5", "2"},
854 usd(),
855 xrp());
856 }
857 else
858 {
859 attempt(
860 Buy,
861 "N:T",
862 q1,
863 {"3", "3"},
864 "2.5",
865 q1,
866 {"5", "5"},
867 "5",
868 {"2.5", "2"},
869 usd(),
870 xrp());
871 attempt(
872 Buy,
873 "N:BT",
874 q1,
875 {"3", "3"},
876 "1.5",
877 q1,
878 {"5", "5"},
879 "4",
880 {"1.5", "1"},
881 usd(),
882 xrp());
883 }
884 attempt(
885 Buy,
886 "N:TB",
887 q1,
888 {"3", "3"},
889 "2.2",
890 q1,
891 {"5", "5"},
892 "1",
893 {"1", "1"},
894 usd(),
895 xrp());
896
897 attempt(
898 Sell,
899 "T:N",
900 q1,
901 {"1", "1"},
902 "2",
903 q1,
904 {"2", "2"},
905 "2",
906 {"1", "1"},
907 usd(),
908 xrp());
909 attempt(
910 Sell,
911 "T:B",
912 q1,
913 {"2", "2"},
914 "2",
915 q1,
916 {"3", "3"},
917 "1",
918 {"1", "1"},
919 usd(),
920 xrp());
921 attempt(
922 Buy,
923 "T:T",
924 q1,
925 {"1", "1"},
926 "2",
927 q1,
928 {"2", "2"},
929 "2",
930 {"1", "1"},
931 usd(),
932 xrp());
933 attempt(
934 Buy,
935 "T:BT",
936 q1,
937 {"1", "1"},
938 "2",
939 q1,
940 {"3", "3"},
941 "2",
942 {"1", "1"},
943 usd(),
944 xrp());
945 attempt(
946 Buy,
947 "T:TB",
948 q1,
949 {"2", "2"},
950 "2",
951 q1,
952 {"3", "3"},
953 "1",
954 {"1", "1"},
955 usd(),
956 xrp());
957
958 if (NumberSwitchOver)
959 {
960 attempt(
961 Sell,
962 "A:N",
963 q1,
964 {"2", "2"},
965 "1.5",
966 q1,
967 {"2", "2"},
968 "2",
969 {"1.5", "2"},
970 usd(),
971 xrp());
972 attempt(
973 Sell,
974 "A:B",
975 q1,
976 {"2", "2"},
977 "1.8",
978 q1,
979 {"3", "3"},
980 "2",
981 {"1.8", "2"},
982 usd(),
983 xrp());
984 }
985 else
986 {
987 attempt(
988 Sell,
989 "A:N",
990 q1,
991 {"2", "2"},
992 "1.5",
993 q1,
994 {"2", "2"},
995 "2",
996 {"1.5", "1"},
997 usd(),
998 xrp());
999 attempt(
1000 Sell,
1001 "A:B",
1002 q1,
1003 {"2", "2"},
1004 "1.8",
1005 q1,
1006 {"3", "3"},
1007 "2",
1008 {"1.8", "1"},
1009 usd(),
1010 xrp());
1011 }
1012 attempt(
1013 Buy,
1014 "A:T",
1015 q1,
1016 {"2", "2"},
1017 "1.2",
1018 q1,
1019 {"3", "3"},
1020 "3",
1021 {"1.2", "1"},
1022 usd(),
1023 xrp());
1024 if (NumberSwitchOver)
1025 {
1026 attempt(
1027 Buy,
1028 "A:BT",
1029 q1,
1030 {"2", "2"},
1031 "1.5",
1032 q1,
1033 {"4", "4"},
1034 "3",
1035 {"1.5", "2"},
1036 usd(),
1037 xrp());
1038 }
1039 else
1040 {
1041 attempt(
1042 Buy,
1043 "A:BT",
1044 q1,
1045 {"2", "2"},
1046 "1.5",
1047 q1,
1048 {"4", "4"},
1049 "3",
1050 {"1.5", "1"},
1051 usd(),
1052 xrp());
1053 }
1054 attempt(
1055 Buy,
1056 "A:TB",
1057 q1,
1058 {"2", "2"},
1059 "1.5",
1060 q1,
1061 {"4", "4"},
1062 "1",
1063 {"1", "1"},
1064 usd(),
1065 xrp());
1066
1067 if (NumberSwitchOver)
1068 {
1069 attempt(
1070 Sell,
1071 "TA:N",
1072 q1,
1073 {"2", "2"},
1074 "1.5",
1075 q1,
1076 {"2", "2"},
1077 "2",
1078 {"1.5", "2"},
1079 usd(),
1080 xrp());
1081 }
1082 else
1083 {
1084 attempt(
1085 Sell,
1086 "TA:N",
1087 q1,
1088 {"2", "2"},
1089 "1.5",
1090 q1,
1091 {"2", "2"},
1092 "2",
1093 {"1.5", "1"},
1094 usd(),
1095 xrp());
1096 }
1097 attempt(
1098 Sell,
1099 "TA:B",
1100 q1,
1101 {"2", "2"},
1102 "1.5",
1103 q1,
1104 {"3", "3"},
1105 "1",
1106 {"1", "1"},
1107 usd(),
1108 xrp());
1109 if (NumberSwitchOver)
1110 {
1111 attempt(
1112 Buy,
1113 "TA:T",
1114 q1,
1115 {"2", "2"},
1116 "1.5",
1117 q1,
1118 {"3", "3"},
1119 "3",
1120 {"1.5", "2"},
1121 usd(),
1122 xrp());
1123 attempt(
1124 Buy,
1125 "TA:BT",
1126 q1,
1127 {"2", "2"},
1128 "1.8",
1129 q1,
1130 {"4", "4"},
1131 "3",
1132 {"1.8", "2"},
1133 usd(),
1134 xrp());
1135 }
1136 else
1137 {
1138 attempt(
1139 Buy,
1140 "TA:T",
1141 q1,
1142 {"2", "2"},
1143 "1.5",
1144 q1,
1145 {"3", "3"},
1146 "3",
1147 {"1.5", "1"},
1148 usd(),
1149 xrp());
1150 attempt(
1151 Buy,
1152 "TA:BT",
1153 q1,
1154 {"2", "2"},
1155 "1.8",
1156 q1,
1157 {"4", "4"},
1158 "3",
1159 {"1.8", "1"},
1160 usd(),
1161 xrp());
1162 }
1163 attempt(
1164 Buy,
1165 "TA:TB",
1166 q1,
1167 {"2", "2"},
1168 "1.2",
1169 q1,
1170 {"3", "3"},
1171 "1",
1172 {"1", "1"},
1173 usd(),
1174 xrp());
1175
1176 attempt(
1177 Sell,
1178 "AT:N",
1179 q1,
1180 {"2", "2"},
1181 "2.5",
1182 q1,
1183 {"4", "4"},
1184 "4",
1185 {"2", "2"},
1186 usd(),
1187 xrp());
1188 attempt(
1189 Sell,
1190 "AT:B",
1191 q1,
1192 {"2", "2"},
1193 "2.5",
1194 q1,
1195 {"3", "3"},
1196 "1",
1197 {"1", "1"},
1198 usd(),
1199 xrp());
1200 attempt(
1201 Buy,
1202 "AT:T",
1203 q1,
1204 {"2", "2"},
1205 "2.5",
1206 q1,
1207 {"3", "3"},
1208 "3",
1209 {"2", "2"},
1210 usd(),
1211 xrp());
1212 attempt(
1213 Buy,
1214 "AT:BT",
1215 q1,
1216 {"2", "2"},
1217 "2.5",
1218 q1,
1219 {"4", "4"},
1220 "3",
1221 {"2", "2"},
1222 usd(),
1223 xrp());
1224 attempt(
1225 Buy,
1226 "AT:TB",
1227 q1,
1228 {"2", "2"},
1229 "2.5",
1230 q1,
1231 {"3", "3"},
1232 "1",
1233 {"1", "1"},
1234 usd(),
1235 xrp());
1236 }
1237 }
1238
1239 void
1241 {
1242 testcase("IOU to IOU");
1243
1244 for (auto NumberSwitchOver : {false, true})
1245 {
1246 NumberSO stNumberSO{NumberSwitchOver};
1247 Quality q1 = get_quality("1", "1");
1248
1249 // Highly exaggerated 50% transfer rate for the input and output:
1250 Rate const rate{parityRate.value + (parityRate.value / 2)};
1251
1252 // TAKER OWNER
1253 // QUAL OFFER FUNDS QUAL OFFER FUNDS
1254 // EXPECTED
1255 // EUR USD
1256 attempt(
1257 Sell,
1258 "N:N",
1259 q1,
1260 {"2", "2"},
1261 "10",
1262 q1,
1263 {"2", "2"},
1264 "10",
1265 {"2", "2"},
1266 eur(),
1267 usd(),
1268 rate,
1269 rate);
1270 if (NumberSwitchOver)
1271 {
1272 attempt(
1273 Sell,
1274 "N:B",
1275 q1,
1276 {"4", "4"},
1277 "10",
1278 q1,
1279 {"4", "4"},
1280 "4",
1281 {"2.666666666666667", "2.666666666666667"},
1282 eur(),
1283 usd(),
1284 rate,
1285 rate);
1286 }
1287 else
1288 {
1289 attempt(
1290 Sell,
1291 "N:B",
1292 q1,
1293 {"4", "4"},
1294 "10",
1295 q1,
1296 {"4", "4"},
1297 "4",
1298 {"2.666666666666666", "2.666666666666666"},
1299 eur(),
1300 usd(),
1301 rate,
1302 rate);
1303 }
1304 attempt(
1305 Buy,
1306 "N:T",
1307 q1,
1308 {"1", "1"},
1309 "10",
1310 q1,
1311 {"2", "2"},
1312 "10",
1313 {"1", "1"},
1314 eur(),
1315 usd(),
1316 rate,
1317 rate);
1318 attempt(
1319 Buy,
1320 "N:BT",
1321 q1,
1322 {"2", "2"},
1323 "10",
1324 q1,
1325 {"6", "6"},
1326 "5",
1327 {"2", "2"},
1328 eur(),
1329 usd(),
1330 rate,
1331 rate);
1332 attempt(
1333 Buy,
1334 "N:TB",
1335 q1,
1336 {"2", "2"},
1337 "2",
1338 q1,
1339 {"6", "6"},
1340 "1",
1341 {"0.6666666666666667", "0.6666666666666667"},
1342 eur(),
1343 usd(),
1344 rate,
1345 rate);
1346 if (NumberSwitchOver)
1347 {
1348 attempt(
1349 Sell,
1350 "A:N",
1351 q1,
1352 {"2", "2"},
1353 "2.5",
1354 q1,
1355 {"2", "2"},
1356 "10",
1357 {"1.666666666666667", "1.666666666666667"},
1358 eur(),
1359 usd(),
1360 rate,
1361 rate);
1362 }
1363 else
1364 {
1365 attempt(
1366 Sell,
1367 "A:N",
1368 q1,
1369 {"2", "2"},
1370 "2.5",
1371 q1,
1372 {"2", "2"},
1373 "10",
1374 {"1.666666666666666", "1.666666666666666"},
1375 eur(),
1376 usd(),
1377 rate,
1378 rate);
1379 }
1380 }
1381 }
1382
1383 void
1384 run() override
1385 {
1389 }
1390};
1391
1392BEAST_DEFINE_TESTSUITE(Taker, tx, ripple);
1393
1394} // namespace ripple
A testsuite class.
Definition: suite.h:55
log_os< char > log
Logging output stream.
Definition: suite.h:152
testcase_t testcase
Memberspace for declaring test cases.
Definition: suite.h:155
State for the active party during order book or payment operations.
Definition: Taker.h:39
bool done() const
Returns true if order crossing should not continue.
Definition: Taker.cpp:123
CrossType cross_type() const
Returns the type of crossing that is being performed.
Definition: Taker.h:185
AccountID const & account() const noexcept
Returns the account identifier of the taker.
Definition: Taker.h:171
bool reject(Quality const &quality) const noexcept
Returns true if the quality does not meet the taker's requirements.
Definition: Taker.h:178
BasicTaker::Flow do_cross(Amounts offer, Quality quality, AccountID const &owner)
Perform direct crossing through given offer.
Definition: Taker.cpp:400
A currency issued by an account.
Definition: Issue.h:36
Currency currency
Definition: Issue.h:38
RAII class to set and restore the Number switchover.
Definition: IOUAmount.h:211
std::string getText() const override
Definition: STAmount.cpp:550
Issue const & issue() const
Definition: STAmount.h:496
STAmount get_funds(AccountID const &owner, STAmount const &funds) const override
Definition: Taker_test.cpp:64
void set_funds(STAmount const &funds)
Definition: Taker_test.cpp:58
Amounts cross(Amounts offer, Quality quality)
Definition: Taker_test.cpp:73
TestTaker(CrossType cross_type, Amounts const &amount, Quality const &quality, STAmount const &funds, std::uint32_t flags, Rate const &rate_in, Rate const &rate_out)
Definition: Taker_test.cpp:37
std::pair< Amounts, Amounts > cross(Amounts offer1, Quality quality1, Amounts offer2, Quality quality2)
Definition: Taker_test.cpp:93
void run() override
Runs the suite.
Quality get_quality(std::string in, std::string out)
Definition: Taker_test.cpp:249
static bool const Sell
Definition: Taker_test.cpp:29
STAmount parse_amount(std::string const &amount, Issue const &issue)
Definition: Taker_test.cpp:149
std::string format_amount(STAmount const &amount)
Definition: Taker_test.cpp:180
Issue const & xrp() const
Definition: Taker_test.cpp:142
Issue const & usd() const
Definition: Taker_test.cpp:126
static bool const Buy
Definition: Taker_test.cpp:28
Issue const & eur() const
Definition: Taker_test.cpp:134
void attempt(bool sell, std::string name, Quality taker_quality, cross_attempt_offer const offer, std::string const funds, Quality cross_quality, cross_attempt_offer const cross, std::string const cross_funds, cross_attempt_offer const flow, Issue const &issue_in, Issue const &issue_out, Rate rate_in=parityRate, Rate rate_out=parityRate)
Definition: Taker_test.cpp:189
Amounts parse_amounts(std::string const &amount_in, Issue const &issue_in, std::string const &amount_out, Issue const &issue_out)
Definition: Taker_test.cpp:155
T endl(T... args)
T make_pair(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition: AccountID.h:49
bool isXRP(AccountID const &c)
Definition: AccountID.h:91
AccountID const & xrpAccount()
Compute AccountID from public key.
Definition: AccountID.cpp:178
StrandResult< TInAmt, TOutAmt > flow(PaymentSandbox const &baseView, Strand const &strand, std::optional< TInAmt > const &maxIn, TOutAmt const &out, beast::Journal j)
Request out amount from a strand.
Definition: StrandFlow.h:105
@ sell
Definition: Steps.h:45
Quality composed_quality(Quality const &lhs, Quality const &rhs)
Definition: Quality.cpp:158
base_uint< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition: UintTypes.h:56
Currency const & xrpCurrency()
XRP currency.
Definition: UintTypes.cpp:119
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:630
STAmount amountFromString(Asset const &asset, std::string const &amount)
Definition: STAmount.cpp:869
constexpr std::uint32_t tfSell
Definition: TxFlags.h:100
CrossType
The flavor of an offer crossing.
Definition: Taker.h:35
Rate const parityRate
A transfer rate signifying a 1:1 exchange.
Represents a transfer rate.
Definition: Rate.h:40
std::uint32_t value
Definition: Rate.h:41
cross_attempt_offer(std::string const &in_, std::string const &out_)
Definition: Taker_test.cpp:169