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