18 #include <ripple/protocol/jss.h>
19 #include <ripple/protocol/Indexes.h>
20 #include <test/jtx/WSClient.h>
22 #include <ripple/beast/unit_test.h>
23 #include <ripple/rpc/impl/Tuning.h>
36 auto key = view->succ(uBookBase, uBookEnd);
39 auto sleOfferDir = view->read(
keylet::page(key.value()));
41 unsigned int bookEntry;
42 cdirFirst(*view, sleOfferDir->key(), sleOfferDir, bookEntry, offerIndex, env.
journal);
53 testcase(
"One Side Empty Book");
54 using namespace std::chrono_literals;
58 auto USD =
Account(
"alice")[
"USD"];
67 j[jss::snapshot] =
true;
68 j[jss::taker_gets][jss::currency] =
"XRP";
69 j[jss::taker_pays][jss::currency] =
"USD";
70 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
73 auto jv = wsc->invoke(
"subscribe", books);
74 if (wsc->version() == 2)
76 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
77 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
78 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
80 if(! BEAST_EXPECT(jv[jss::status] ==
"success"))
82 BEAST_EXPECT(jv[jss::result].isMember(jss::offers) &&
83 jv[jss::result][jss::offers].size() == 0);
84 BEAST_EXPECT(! jv[jss::result].isMember(jss::asks));
85 BEAST_EXPECT(! jv[jss::result].isMember(jss::bids));
90 env(
offer(
"alice",
XRP(700), USD(100)),
95 BEAST_EXPECT(wsc->findMsg(5s,
98 auto const& t = jv[jss::transaction];
99 return t[jss::TransactionType] == jss::OfferCreate &&
101 USD(100).value().getJson(JsonOptions::none) &&
103 XRP(700).value().getJson(JsonOptions::none);
109 env(
offer(
"alice", USD(100),
XRP(75)),
112 BEAST_EXPECT(! wsc->getMsg(10ms));
116 auto jv = wsc->invoke(
"unsubscribe", books);
117 BEAST_EXPECT(jv[jss::status] ==
"success");
118 if (wsc->version() == 2)
120 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
121 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
122 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
129 testcase(
"One Side Offers In Book");
130 using namespace std::chrono_literals;
134 auto USD =
Account(
"alice")[
"USD"];
139 env(
offer(
"alice",
XRP(500), USD(100)),
143 env(
offer(
"alice", USD(100),
XRP(200)),
152 j[jss::snapshot] =
true;
153 j[jss::taker_gets][jss::currency] =
"XRP";
154 j[jss::taker_pays][jss::currency] =
"USD";
155 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
158 auto jv = wsc->invoke(
"subscribe", books);
159 if (wsc->version() == 2)
161 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
162 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
163 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
165 if(! BEAST_EXPECT(jv[jss::status] ==
"success"))
167 BEAST_EXPECT(jv[jss::result].isMember(jss::offers) &&
168 jv[jss::result][jss::offers].size() == 1);
169 BEAST_EXPECT(jv[jss::result][jss::offers][0u][jss::TakerGets] ==
171 BEAST_EXPECT(jv[jss::result][jss::offers][0u][jss::TakerPays] ==
173 BEAST_EXPECT(! jv[jss::result].isMember(jss::asks));
174 BEAST_EXPECT(! jv[jss::result].isMember(jss::bids));
179 env(
offer(
"alice",
XRP(700), USD(100)),
184 BEAST_EXPECT(wsc->findMsg(5s,
187 auto const& t = jv[jss::transaction];
188 return t[jss::TransactionType] == jss::OfferCreate &&
190 USD(100).value().getJson(JsonOptions::none) &&
192 XRP(700).value().getJson(JsonOptions::none);
198 env(
offer(
"alice", USD(100),
XRP(75)),
201 BEAST_EXPECT(! wsc->getMsg(10ms));
205 auto jv = wsc->invoke(
"unsubscribe", books);
206 BEAST_EXPECT(jv[jss::status] ==
"success");
207 if (wsc->version() == 2)
209 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
210 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
211 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
218 testcase(
"Both Sides Empty Book");
219 using namespace std::chrono_literals;
223 auto USD =
Account(
"alice")[
"USD"];
232 j[jss::snapshot] =
true;
234 j[jss::taker_gets][jss::currency] =
"XRP";
235 j[jss::taker_pays][jss::currency] =
"USD";
236 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
239 auto jv = wsc->invoke(
"subscribe", books);
240 if (wsc->version() == 2)
242 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
243 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
244 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
246 if(! BEAST_EXPECT(jv[jss::status] ==
"success"))
248 BEAST_EXPECT(jv[jss::result].isMember(jss::asks) &&
249 jv[jss::result][jss::asks].size() == 0);
250 BEAST_EXPECT(jv[jss::result].isMember(jss::bids) &&
251 jv[jss::result][jss::bids].size() == 0);
252 BEAST_EXPECT(! jv[jss::result].isMember(jss::offers));
257 env(
offer(
"alice",
XRP(700), USD(100)),
262 BEAST_EXPECT(wsc->findMsg(5s,
265 auto const& t = jv[jss::transaction];
266 return t[jss::TransactionType] == jss::OfferCreate &&
268 USD(100).value().getJson(JsonOptions::none) &&
270 XRP(700).value().getJson(JsonOptions::none);
276 env(
offer(
"alice", USD(100),
XRP(75)),
281 BEAST_EXPECT(wsc->findMsg(5s,
284 auto const& t = jv[jss::transaction];
285 return t[jss::TransactionType] == jss::OfferCreate &&
287 XRP(75).value().getJson(JsonOptions::none) &&
289 USD(100).value().getJson(JsonOptions::none);
294 auto jv = wsc->invoke(
"unsubscribe", books);
295 BEAST_EXPECT(jv[jss::status] ==
"success");
296 if (wsc->version() == 2)
298 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
299 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
300 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
307 testcase(
"Both Sides Offers In Book");
308 using namespace std::chrono_literals;
312 auto USD =
Account(
"alice")[
"USD"];
317 env(
offer(
"alice",
XRP(500), USD(100)),
321 env(
offer(
"alice", USD(100),
XRP(200)),
330 j[jss::snapshot] =
true;
332 j[jss::taker_gets][jss::currency] =
"XRP";
333 j[jss::taker_pays][jss::currency] =
"USD";
334 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
337 auto jv = wsc->invoke(
"subscribe", books);
338 if (wsc->version() == 2)
340 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
341 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
342 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
344 if(! BEAST_EXPECT(jv[jss::status] ==
"success"))
346 BEAST_EXPECT(jv[jss::result].isMember(jss::asks) &&
347 jv[jss::result][jss::asks].size() == 1);
348 BEAST_EXPECT(jv[jss::result].isMember(jss::bids) &&
349 jv[jss::result][jss::bids].size() == 1);
350 BEAST_EXPECT(jv[jss::result][jss::asks][0u][jss::TakerGets] ==
352 BEAST_EXPECT(jv[jss::result][jss::asks][0u][jss::TakerPays] ==
354 BEAST_EXPECT(jv[jss::result][jss::bids][0u][jss::TakerGets] ==
356 BEAST_EXPECT(jv[jss::result][jss::bids][0u][jss::TakerPays] ==
358 BEAST_EXPECT(! jv[jss::result].isMember(jss::offers));
363 env(
offer(
"alice",
XRP(700), USD(100)),
368 BEAST_EXPECT(wsc->findMsg(5s,
371 auto const& t = jv[jss::transaction];
372 return t[jss::TransactionType] == jss::OfferCreate &&
374 USD(100).value().getJson(JsonOptions::none) &&
376 XRP(700).value().getJson(JsonOptions::none);
382 env(
offer(
"alice", USD(100),
XRP(75)),
387 BEAST_EXPECT(wsc->findMsg(5s,
390 auto const& t = jv[jss::transaction];
391 return t[jss::TransactionType] == jss::OfferCreate &&
393 XRP(75).value().getJson(JsonOptions::none) &&
395 USD(100).value().getJson(JsonOptions::none);
400 auto jv = wsc->invoke(
"unsubscribe", books);
401 BEAST_EXPECT(jv[jss::status] ==
"success");
402 if (wsc->version() == 2)
404 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
405 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
406 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
413 testcase(
"Multiple Books, One Side Empty");
414 using namespace std::chrono_literals;
418 auto USD =
Account(
"alice")[
"USD"];
419 auto CNY =
Account(
"alice")[
"CNY"];
420 auto JPY =
Account(
"alice")[
"JPY"];
429 j[jss::snapshot] =
true;
430 j[jss::taker_gets][jss::currency] =
"XRP";
431 j[jss::taker_pays][jss::currency] =
"USD";
432 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
436 j[jss::snapshot] =
true;
437 j[jss::taker_gets][jss::currency] =
"CNY";
438 j[jss::taker_gets][jss::issuer] =
Account(
"alice").
human();
439 j[jss::taker_pays][jss::currency] =
"JPY";
440 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
443 auto jv = wsc->invoke(
"subscribe", books);
444 if (wsc->version() == 2)
446 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
447 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
448 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
450 if(! BEAST_EXPECT(jv[jss::status] ==
"success"))
452 BEAST_EXPECT(jv[jss::result].isMember(jss::offers) &&
453 jv[jss::result][jss::offers].size() == 0);
454 BEAST_EXPECT(! jv[jss::result].isMember(jss::asks));
455 BEAST_EXPECT(! jv[jss::result].isMember(jss::bids));
460 env(
offer(
"alice",
XRP(700), USD(100)),
465 BEAST_EXPECT(wsc->findMsg(5s,
468 auto const& t = jv[jss::transaction];
469 return t[jss::TransactionType] == jss::OfferCreate &&
471 USD(100).value().getJson(JsonOptions::none) &&
473 XRP(700).value().getJson(JsonOptions::none);
479 env(
offer(
"alice", USD(100),
XRP(75)),
482 BEAST_EXPECT(! wsc->getMsg(10ms));
487 env(
offer(
"alice", CNY(700), JPY(100)),
492 BEAST_EXPECT(wsc->findMsg(5s,
495 auto const& t = jv[jss::transaction];
496 return t[jss::TransactionType] == jss::OfferCreate &&
498 JPY(100).value().getJson(JsonOptions::none) &&
500 CNY(700).value().getJson(JsonOptions::none);
506 env(
offer(
"alice", JPY(100), CNY(75)),
509 BEAST_EXPECT(! wsc->getMsg(10ms));
513 auto jv = wsc->invoke(
"unsubscribe", books);
514 BEAST_EXPECT(jv[jss::status] ==
"success");
515 if (wsc->version() == 2)
517 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
518 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
519 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
526 testcase(
"Multiple Books, One Side Offers In Book");
527 using namespace std::chrono_literals;
531 auto USD =
Account(
"alice")[
"USD"];
532 auto CNY =
Account(
"alice")[
"CNY"];
533 auto JPY =
Account(
"alice")[
"JPY"];
538 env(
offer(
"alice",
XRP(500), USD(100)),
542 env(
offer(
"alice", CNY(500), JPY(100)),
546 env(
offer(
"alice", USD(100),
XRP(200)),
550 env(
offer(
"alice", JPY(100), CNY(200)),
559 j[jss::snapshot] =
true;
560 j[jss::taker_gets][jss::currency] =
"XRP";
561 j[jss::taker_pays][jss::currency] =
"USD";
562 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
566 j[jss::snapshot] =
true;
567 j[jss::taker_gets][jss::currency] =
"CNY";
568 j[jss::taker_gets][jss::issuer] =
Account(
"alice").
human();
569 j[jss::taker_pays][jss::currency] =
"JPY";
570 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
573 auto jv = wsc->invoke(
"subscribe", books);
574 if (wsc->version() == 2)
576 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
577 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
578 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
580 if(! BEAST_EXPECT(jv[jss::status] ==
"success"))
582 BEAST_EXPECT(jv[jss::result].isMember(jss::offers) &&
583 jv[jss::result][jss::offers].size() == 2);
584 BEAST_EXPECT(jv[jss::result][jss::offers][0u][jss::TakerGets] ==
586 BEAST_EXPECT(jv[jss::result][jss::offers][0u][jss::TakerPays] ==
588 BEAST_EXPECT(jv[jss::result][jss::offers][1u][jss::TakerGets] ==
590 BEAST_EXPECT(jv[jss::result][jss::offers][1u][jss::TakerPays] ==
592 BEAST_EXPECT(! jv[jss::result].isMember(jss::asks));
593 BEAST_EXPECT(! jv[jss::result].isMember(jss::bids));
598 env(
offer(
"alice",
XRP(700), USD(100)),
603 BEAST_EXPECT(wsc->findMsg(5s,
606 auto const& t = jv[jss::transaction];
607 return t[jss::TransactionType] == jss::OfferCreate &&
609 USD(100).value().getJson(JsonOptions::none) &&
611 XRP(700).value().getJson(JsonOptions::none);
617 env(
offer(
"alice", USD(100),
XRP(75)),
620 BEAST_EXPECT(! wsc->getMsg(10ms));
625 env(
offer(
"alice", CNY(700), JPY(100)),
630 BEAST_EXPECT(wsc->findMsg(5s,
633 auto const& t = jv[jss::transaction];
634 return t[jss::TransactionType] == jss::OfferCreate &&
636 JPY(100).value().getJson(JsonOptions::none) &&
638 CNY(700).value().getJson(JsonOptions::none);
644 env(
offer(
"alice", JPY(100), CNY(75)),
647 BEAST_EXPECT(! wsc->getMsg(10ms));
651 auto jv = wsc->invoke(
"unsubscribe", books);
652 BEAST_EXPECT(jv[jss::status] ==
"success");
653 if (wsc->version() == 2)
655 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
656 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
657 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
664 testcase(
"Multiple Books, Both Sides Empty Book");
665 using namespace std::chrono_literals;
669 auto USD =
Account(
"alice")[
"USD"];
670 auto CNY =
Account(
"alice")[
"CNY"];
671 auto JPY =
Account(
"alice")[
"JPY"];
680 j[jss::snapshot] =
true;
682 j[jss::taker_gets][jss::currency] =
"XRP";
683 j[jss::taker_pays][jss::currency] =
"USD";
684 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
688 j[jss::snapshot] =
true;
690 j[jss::taker_gets][jss::currency] =
"CNY";
691 j[jss::taker_gets][jss::issuer] =
Account(
"alice").
human();
692 j[jss::taker_pays][jss::currency] =
"JPY";
693 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
696 auto jv = wsc->invoke(
"subscribe", books);
697 if (wsc->version() == 2)
699 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
700 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
701 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
703 if(! BEAST_EXPECT(jv[jss::status] ==
"success"))
705 BEAST_EXPECT(jv[jss::result].isMember(jss::asks) &&
706 jv[jss::result][jss::asks].size() == 0);
707 BEAST_EXPECT(jv[jss::result].isMember(jss::bids) &&
708 jv[jss::result][jss::bids].size() == 0);
709 BEAST_EXPECT(! jv[jss::result].isMember(jss::offers));
714 env(
offer(
"alice",
XRP(700), USD(100)),
719 BEAST_EXPECT(wsc->findMsg(5s,
722 auto const& t = jv[jss::transaction];
723 return t[jss::TransactionType] == jss::OfferCreate &&
725 USD(100).value().getJson(JsonOptions::none) &&
727 XRP(700).value().getJson(JsonOptions::none);
733 env(
offer(
"alice", USD(100),
XRP(75)),
738 BEAST_EXPECT(wsc->findMsg(5s,
741 auto const& t = jv[jss::transaction];
742 return t[jss::TransactionType] == jss::OfferCreate &&
744 XRP(75).value().getJson(JsonOptions::none) &&
746 USD(100).value().getJson(JsonOptions::none);
752 env(
offer(
"alice", CNY(700), JPY(100)),
757 BEAST_EXPECT(wsc->findMsg(5s,
760 auto const& t = jv[jss::transaction];
761 return t[jss::TransactionType] == jss::OfferCreate &&
763 JPY(100).value().getJson(JsonOptions::none) &&
765 CNY(700).value().getJson(JsonOptions::none);
771 env(
offer(
"alice", JPY(100), CNY(75)),
776 BEAST_EXPECT(wsc->findMsg(5s,
779 auto const& t = jv[jss::transaction];
780 return t[jss::TransactionType] == jss::OfferCreate &&
782 CNY(75).value().getJson(JsonOptions::none) &&
784 JPY(100).value().getJson(JsonOptions::none);
789 auto jv = wsc->invoke(
"unsubscribe", books);
790 BEAST_EXPECT(jv[jss::status] ==
"success");
791 if (wsc->version() == 2)
793 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
794 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
795 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
802 testcase(
"Multiple Books, Both Sides Offers In Book");
803 using namespace std::chrono_literals;
807 auto USD =
Account(
"alice")[
"USD"];
808 auto CNY =
Account(
"alice")[
"CNY"];
809 auto JPY =
Account(
"alice")[
"JPY"];
814 env(
offer(
"alice",
XRP(500), USD(100)),
818 env(
offer(
"alice", CNY(500), JPY(100)),
822 env(
offer(
"alice", USD(100),
XRP(200)),
826 env(
offer(
"alice", JPY(100), CNY(200)),
835 j[jss::snapshot] =
true;
837 j[jss::taker_gets][jss::currency] =
"XRP";
838 j[jss::taker_pays][jss::currency] =
"USD";
839 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
844 j[jss::snapshot] =
true;
846 j[jss::taker_gets][jss::currency] =
"CNY";
847 j[jss::taker_gets][jss::issuer] =
Account(
"alice").
human();
848 j[jss::taker_pays][jss::currency] =
"JPY";
849 j[jss::taker_pays][jss::issuer] =
Account(
"alice").
human();
852 auto jv = wsc->invoke(
"subscribe", books);
853 if (wsc->version() == 2)
855 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
856 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
857 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
859 if(! BEAST_EXPECT(jv[jss::status] ==
"success"))
861 BEAST_EXPECT(jv[jss::result].isMember(jss::asks) &&
862 jv[jss::result][jss::asks].size() == 2);
863 BEAST_EXPECT(jv[jss::result].isMember(jss::bids) &&
864 jv[jss::result][jss::bids].size() == 2);
865 BEAST_EXPECT(jv[jss::result][jss::asks][0u][jss::TakerGets] ==
867 BEAST_EXPECT(jv[jss::result][jss::asks][0u][jss::TakerPays] ==
869 BEAST_EXPECT(jv[jss::result][jss::asks][1u][jss::TakerGets] ==
871 BEAST_EXPECT(jv[jss::result][jss::asks][1u][jss::TakerPays] ==
873 BEAST_EXPECT(jv[jss::result][jss::bids][0u][jss::TakerGets] ==
875 BEAST_EXPECT(jv[jss::result][jss::bids][0u][jss::TakerPays] ==
877 BEAST_EXPECT(jv[jss::result][jss::bids][1u][jss::TakerGets] ==
879 BEAST_EXPECT(jv[jss::result][jss::bids][1u][jss::TakerPays] ==
881 BEAST_EXPECT(! jv[jss::result].isMember(jss::offers));
886 env(
offer(
"alice",
XRP(700), USD(100)),
891 BEAST_EXPECT(wsc->findMsg(5s,
894 auto const& t = jv[jss::transaction];
895 return t[jss::TransactionType] == jss::OfferCreate &&
897 USD(100).value().getJson(JsonOptions::none) &&
899 XRP(700).value().getJson(JsonOptions::none);
905 env(
offer(
"alice", USD(100),
XRP(75)),
910 BEAST_EXPECT(wsc->findMsg(5s,
913 auto const& t = jv[jss::transaction];
914 return t[jss::TransactionType] == jss::OfferCreate &&
916 XRP(75).value().getJson(JsonOptions::none) &&
918 USD(100).value().getJson(JsonOptions::none);
924 env(
offer(
"alice", CNY(700), JPY(100)),
929 BEAST_EXPECT(wsc->findMsg(5s,
932 auto const& t = jv[jss::transaction];
933 return t[jss::TransactionType] == jss::OfferCreate &&
935 JPY(100).value().getJson(JsonOptions::none) &&
937 CNY(700).value().getJson(JsonOptions::none);
943 env(
offer(
"alice", JPY(100), CNY(75)),
948 BEAST_EXPECT(wsc->findMsg(5s,
951 auto const& t = jv[jss::transaction];
952 return t[jss::TransactionType] == jss::OfferCreate &&
954 CNY(75).value().getJson(JsonOptions::none) &&
956 JPY(100).value().getJson(JsonOptions::none);
961 auto jv = wsc->invoke(
"unsubscribe", books);
962 BEAST_EXPECT(jv[jss::status] ==
"success");
963 if (wsc->version() == 2)
965 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
966 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
967 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
974 testcase(
"TrackOffers");
981 env.
fund(
XRP(20000), alice, bob, gw);
983 auto USD = gw[
"USD"];
990 j[jss::snapshot] =
true;
991 j[jss::taker_gets][jss::currency] =
"XRP";
992 j[jss::taker_pays][jss::currency] =
"USD";
993 j[jss::taker_pays][jss::issuer] = gw.human();
996 auto jv = wsc->invoke(
"subscribe", books);
997 if (wsc->version() == 2)
999 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
1000 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
1001 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
1003 if(! BEAST_EXPECT(jv[jss::status] ==
"success"))
1005 BEAST_EXPECT(jv[jss::result].isMember(jss::offers) &&
1006 jv[jss::result][jss::offers].size() == 0);
1007 BEAST_EXPECT(! jv[jss::result].isMember(jss::asks));
1008 BEAST_EXPECT(! jv[jss::result].isMember(jss::bids));
1013 env.
trust(USD(1000), alice);
1014 env.
trust(USD(1000), bob);
1015 env(
pay(gw, alice, USD(100)));
1016 env(
pay(gw, bob, USD(50)));
1017 env(
offer(alice,
XRP(4000), USD(10)));
1022 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1023 jvParams[jss::ledger_index] =
"validated";
1024 jvParams[jss::taker_gets][jss::currency] =
"USD";
1025 jvParams[jss::taker_gets][jss::issuer] = gw.human();
1027 auto jv = wsc->invoke(
"book_offers", jvParams);
1028 if (wsc->version() == 2)
1030 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
1031 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
1032 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
1034 auto jrr = jv[jss::result];
1036 BEAST_EXPECT(jrr[jss::offers].isArray());
1037 BEAST_EXPECT(jrr[jss::offers].size() == 1);
1038 auto const jrOffer = jrr[jss::offers][0u];
1043 BEAST_EXPECT(jrOffer[jss::Flags] == 0);
1047 BEAST_EXPECT(jrOffer[jss::TakerGets] ==
1049 BEAST_EXPECT(jrOffer[jss::TakerPays] ==
1051 BEAST_EXPECT(jrOffer[jss::owner_funds] ==
"100");
1052 BEAST_EXPECT(jrOffer[jss::quality] ==
"400000000");
1054 using namespace std::chrono_literals;
1055 BEAST_EXPECT(wsc->findMsg(5s,
1056 [&](
auto const& jval)
1058 auto const& t = jval[jss::transaction];
1059 return t[jss::TransactionType] == jss::OfferCreate &&
1060 t[jss::TakerGets] ==
1061 USD(10).value().getJson(JsonOptions::none) &&
1062 t[jss::owner_funds] ==
"100" &&
1063 t[jss::TakerPays] ==
1064 XRP(4000).value().getJson(JsonOptions::none);
1067 env(
offer(bob,
XRP(2000), USD(5)));
1070 BEAST_EXPECT(wsc->findMsg(5s,
1071 [&](
auto const& jval)
1073 auto const& t = jval[jss::transaction];
1074 return t[jss::TransactionType] == jss::OfferCreate &&
1075 t[jss::TakerGets] ==
1076 USD(5).value().getJson(JsonOptions::none) &&
1077 t[jss::owner_funds] ==
"50" &&
1078 t[jss::TakerPays] ==
1079 XRP(2000).value().getJson(JsonOptions::none);
1082 jv = wsc->invoke(
"book_offers", jvParams);
1083 if (wsc->version() == 2)
1085 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
1086 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
1087 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
1089 jrr = jv[jss::result];
1091 BEAST_EXPECT(jrr[jss::offers].isArray());
1092 BEAST_EXPECT(jrr[jss::offers].size() == 2);
1093 auto const jrNextOffer = jrr[jss::offers][1u];
1098 BEAST_EXPECT(jrNextOffer[jss::Flags] == 0);
1102 BEAST_EXPECT(jrNextOffer[jss::TakerGets] ==
1104 BEAST_EXPECT(jrNextOffer[jss::TakerPays] ==
1106 BEAST_EXPECT(jrNextOffer[jss::owner_funds] ==
"50");
1107 BEAST_EXPECT(jrNextOffer[jss::quality] ==
"400000000");
1109 jv = wsc->invoke(
"unsubscribe", books);
1110 if (wsc->version() == 2)
1112 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
1113 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
1114 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
1116 BEAST_EXPECT(jv[jss::status] ==
"success");
1128 auto maybeJv = wsc->getMsg(timeout);
1133 if(!(*maybeJv).isMember(jss::transaction))
1135 auto const& t = (*maybeJv)[jss::transaction];
1136 if (t[jss::TransactionType] != jss::OfferCreate ||
1141 return wsc->getMsg(timeout) == boost::none;
1147 testcase(
"Crossing single book offer");
1153 using namespace jtx;
1160 auto const gw =
Account(
"gateway");
1161 auto const alice =
Account(
"alice");
1162 auto const bob =
Account(
"bob");
1163 auto const charlie =
Account(
"charlie");
1164 auto const USD = gw[
"USD"];
1166 env.
fund (
XRP(1000000), gw, alice, bob, charlie);
1169 env (
trust(alice, USD(500)));
1170 env (
trust(bob, USD(500)));
1173 env (
pay(gw, alice, USD(500)));
1174 env (
pay(gw, bob, USD(500)));
1178 env (
offer (alice,
XRP(500), USD(500)));
1179 env (
offer (bob,
XRP(500), USD(500)));
1189 j[jss::snapshot] =
false;
1190 j[jss::taker_gets][jss::currency] =
"XRP";
1191 j[jss::taker_pays][jss::currency] =
"USD";
1192 j[jss::taker_pays][jss::issuer] = gw.human();
1195 auto jv = wsc->invoke(
"subscribe", books);
1196 if (!BEAST_EXPECT(jv[jss::status] ==
"success"))
1201 env(
offer(charlie, USD(1000),
XRP(1000)));
1204 using namespace std::chrono_literals;
1208 auto jv = wsc->invoke(
"unsubscribe", books);
1209 BEAST_EXPECT(jv[jss::status] ==
"success");
1215 testcase(
"Crossing multi-book offer");
1221 using namespace jtx;
1230 auto const gw =
Account(
"gateway");
1231 auto const alice =
Account(
"alice");
1232 auto const bob =
Account(
"bob");
1233 auto const charlie =
Account(
"charlie");
1234 auto const USD = gw[
"USD"];
1235 auto const EUR = gw[
"EUR"];
1237 env.
fund(
XRP(1000000), gw, alice, bob, charlie);
1240 for (
auto const& account : {alice, bob, charlie})
1242 for (
auto const& iou : {USD, EUR})
1244 env(
trust(account, iou(1)));
1249 env(
pay(gw, alice, USD(1)));
1250 env(
pay(gw, charlie, EUR(1)));
1253 env(
offer(alice,
XRP(100), USD(1)));
1265 j[jss::snapshot] =
false;
1266 j[jss::taker_gets][jss::currency] =
"XRP";
1267 j[jss::taker_pays][jss::currency] =
"USD";
1268 j[jss::taker_pays][jss::issuer] = gw.human();
1273 j[jss::snapshot] =
false;
1274 j[jss::taker_gets][jss::currency] =
"EUR";
1275 j[jss::taker_gets][jss::issuer] = gw.human();
1276 j[jss::taker_pays][jss::currency] =
"XRP";
1279 auto jv = wsc->invoke(
"subscribe", books);
1280 if (!BEAST_EXPECT(jv[jss::status] ==
"success"))
1285 env(
offer(charlie, USD(1), EUR(1)));
1287 using namespace std::chrono_literals;
1291 auto jv = wsc->invoke(
"unsubscribe", books);
1292 BEAST_EXPECT(jv[jss::status] ==
"success");
1298 testcase(
"BookOffersRPC Errors");
1299 using namespace jtx;
1303 env.
fund(
XRP(10000), alice, gw);
1305 auto USD = gw[
"USD"];
1309 jvParams[jss::ledger_index] = 10u;
1310 auto const jrr = env.
rpc(
1311 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1312 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
1313 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
1318 jvParams[jss::ledger_index] =
"validated";
1319 auto const jrr = env.
rpc(
1320 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1321 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1322 BEAST_EXPECT(jrr[jss::error_message] ==
1323 "Missing field 'taker_pays'.");
1328 jvParams[jss::ledger_index] =
"validated";
1330 auto const jrr = env.
rpc(
1331 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1332 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1333 BEAST_EXPECT(jrr[jss::error_message] ==
1334 "Missing field 'taker_gets'.");
1339 jvParams[jss::ledger_index] =
"validated";
1340 jvParams[jss::taker_pays] =
"not an object";
1342 auto const jrr = env.
rpc(
1343 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1344 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1345 BEAST_EXPECT(jrr[jss::error_message] ==
1346 "Invalid field 'taker_pays', not object.");
1351 jvParams[jss::ledger_index] =
"validated";
1353 jvParams[jss::taker_gets] =
"not an object";
1354 auto const jrr = env.
rpc(
1355 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1356 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1357 BEAST_EXPECT(jrr[jss::error_message] ==
1358 "Invalid field 'taker_gets', not object.");
1363 jvParams[jss::ledger_index] =
"validated";
1366 auto const jrr = env.
rpc(
1367 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1368 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1369 BEAST_EXPECT(jrr[jss::error_message] ==
1370 "Missing field 'taker_pays.currency'.");
1375 jvParams[jss::ledger_index] =
"validated";
1376 jvParams[jss::taker_pays][jss::currency] = 1;
1378 auto const jrr = env.
rpc(
1379 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1380 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1381 BEAST_EXPECT(jrr[jss::error_message] ==
1382 "Invalid field 'taker_pays.currency', not string.");
1387 jvParams[jss::ledger_index] =
"validated";
1388 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1390 auto const jrr = env.
rpc(
1391 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1392 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1393 BEAST_EXPECT(jrr[jss::error_message] ==
1394 "Missing field 'taker_gets.currency'.");
1399 jvParams[jss::ledger_index] =
"validated";
1400 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1401 jvParams[jss::taker_gets][jss::currency] = 1;
1402 auto const jrr = env.
rpc(
1403 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1404 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1405 BEAST_EXPECT(jrr[jss::error_message] ==
1406 "Invalid field 'taker_gets.currency', not string.");
1411 jvParams[jss::ledger_index] =
"validated";
1412 jvParams[jss::taker_pays][jss::currency] =
"NOT_VALID";
1413 jvParams[jss::taker_gets][jss::currency] =
"XRP";
1414 auto const jrr = env.
rpc(
1415 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1416 BEAST_EXPECT(jrr[jss::error] ==
"srcCurMalformed");
1417 BEAST_EXPECT(jrr[jss::error_message] ==
1418 "Invalid field 'taker_pays.currency', bad currency.");
1423 jvParams[jss::ledger_index] =
"validated";
1424 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1425 jvParams[jss::taker_gets][jss::currency] =
"NOT_VALID";
1426 auto const jrr = env.
rpc(
1427 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1428 BEAST_EXPECT(jrr[jss::error] ==
"dstAmtMalformed");
1429 BEAST_EXPECT(jrr[jss::error_message] ==
1430 "Invalid field 'taker_gets.currency', bad currency.");
1435 jvParams[jss::ledger_index] =
"validated";
1436 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1437 jvParams[jss::taker_gets][jss::currency] =
"USD";
1438 jvParams[jss::taker_gets][jss::issuer] = 1;
1439 auto const jrr = env.
rpc(
1440 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1441 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1442 BEAST_EXPECT(jrr[jss::error_message] ==
1443 "Invalid field 'taker_gets.issuer', not string.");
1448 jvParams[jss::ledger_index] =
"validated";
1449 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1450 jvParams[jss::taker_pays][jss::issuer] = 1;
1451 jvParams[jss::taker_gets][jss::currency] =
"USD";
1452 auto const jrr = env.
rpc(
1453 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1454 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1455 BEAST_EXPECT(jrr[jss::error_message] ==
1456 "Invalid field 'taker_pays.issuer', not string.");
1461 jvParams[jss::ledger_index] =
"validated";
1462 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1463 jvParams[jss::taker_pays][jss::issuer] = gw.human() +
"DEAD";
1464 jvParams[jss::taker_gets][jss::currency] =
"USD";
1465 auto const jrr = env.
rpc(
1466 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1467 BEAST_EXPECT(jrr[jss::error] ==
"srcIsrMalformed");
1468 BEAST_EXPECT(jrr[jss::error_message] ==
1469 "Invalid field 'taker_pays.issuer', bad issuer.");
1474 jvParams[jss::ledger_index] =
"validated";
1475 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1477 jvParams[jss::taker_gets][jss::currency] =
"USD";
1478 auto const jrr = env.
rpc(
1479 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1480 BEAST_EXPECT(jrr[jss::error] ==
"srcIsrMalformed");
1481 BEAST_EXPECT(jrr[jss::error_message] ==
1482 "Invalid field 'taker_pays.issuer', bad issuer account one.");
1487 jvParams[jss::ledger_index] =
"validated";
1488 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1489 jvParams[jss::taker_gets][jss::currency] =
"USD";
1490 jvParams[jss::taker_gets][jss::issuer] = gw.human() +
"DEAD";
1491 auto const jrr = env.
rpc(
1492 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1493 BEAST_EXPECT(jrr[jss::error] ==
"dstIsrMalformed");
1494 BEAST_EXPECT(jrr[jss::error_message] ==
1495 "Invalid field 'taker_gets.issuer', bad issuer.");
1500 jvParams[jss::ledger_index] =
"validated";
1501 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1502 jvParams[jss::taker_gets][jss::currency] =
"USD";
1504 auto const jrr = env.
rpc(
1505 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1506 BEAST_EXPECT(jrr[jss::error] ==
"dstIsrMalformed");
1507 BEAST_EXPECT(jrr[jss::error_message] ==
1508 "Invalid field 'taker_gets.issuer', bad issuer account one.");
1513 jvParams[jss::ledger_index] =
"validated";
1514 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1515 jvParams[jss::taker_pays][jss::issuer] = alice.human();
1516 jvParams[jss::taker_gets][jss::currency] =
"USD";
1517 jvParams[jss::taker_gets][jss::issuer] = gw.human();
1518 auto const jrr = env.
rpc(
1519 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1520 BEAST_EXPECT(jrr[jss::error] ==
"srcIsrMalformed");
1521 BEAST_EXPECT(jrr[jss::error_message] ==
1522 "Unneeded field 'taker_pays.issuer' "
1523 "for XRP currency specification.");
1528 jvParams[jss::ledger_index] =
"validated";
1529 jvParams[jss::taker_pays][jss::currency] =
"USD";
1531 jvParams[jss::taker_gets][jss::currency] =
"USD";
1532 jvParams[jss::taker_gets][jss::issuer] = gw.human();
1533 auto const jrr = env.
rpc(
1534 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1535 BEAST_EXPECT(jrr[jss::error] ==
"srcIsrMalformed");
1536 BEAST_EXPECT(jrr[jss::error_message] ==
1537 "Invalid field 'taker_pays.issuer', expected non-XRP issuer.");
1542 jvParams[jss::ledger_index] =
"validated";
1543 jvParams[jss::taker] = 1;
1544 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1545 jvParams[jss::taker_gets][jss::currency] =
"USD";
1546 jvParams[jss::taker_gets][jss::issuer] = gw.human();
1547 auto const jrr = env.
rpc(
1548 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1549 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1550 BEAST_EXPECT(jrr[jss::error_message] ==
1551 "Invalid field 'taker', not string.");
1556 jvParams[jss::ledger_index] =
"validated";
1557 jvParams[jss::taker] = env.
master.
human() +
"DEAD";
1558 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1559 jvParams[jss::taker_gets][jss::currency] =
"USD";
1560 jvParams[jss::taker_gets][jss::issuer] = gw.human();
1561 auto const jrr = env.
rpc(
1562 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1563 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1564 BEAST_EXPECT(jrr[jss::error_message] ==
1565 "Invalid field 'taker'.");
1570 jvParams[jss::ledger_index] =
"validated";
1572 jvParams[jss::taker_pays][jss::currency] =
"USD";
1573 jvParams[jss::taker_pays][jss::issuer] = gw.human();
1574 jvParams[jss::taker_gets][jss::currency] =
"USD";
1575 jvParams[jss::taker_gets][jss::issuer] = gw.human();
1576 auto const jrr = env.
rpc(
1577 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1578 BEAST_EXPECT(jrr[jss::error] ==
"badMarket");
1579 BEAST_EXPECT(jrr[jss::error_message] ==
"No such market.");
1584 jvParams[jss::ledger_index] =
"validated";
1586 jvParams[jss::limit] =
"0";
1587 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1588 jvParams[jss::taker_gets][jss::currency] =
"USD";
1589 jvParams[jss::taker_gets][jss::issuer] = gw.human();
1590 auto const jrr = env.
rpc(
1591 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1592 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1593 BEAST_EXPECT(jrr[jss::error_message] ==
1594 "Invalid field 'limit', not unsigned integer.");
1599 jvParams[jss::ledger_index] =
"validated";
1600 jvParams[jss::taker_pays][jss::currency] =
"USD";
1601 jvParams[jss::taker_pays][jss::issuer] = gw.human();
1602 jvParams[jss::taker_gets][jss::currency] =
"USD";
1603 auto const jrr = env.
rpc(
1604 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1605 BEAST_EXPECT(jrr[jss::error] ==
"dstIsrMalformed");
1606 BEAST_EXPECT(jrr[jss::error_message] ==
1607 "Invalid field 'taker_gets.issuer', "
1608 "expected non-XRP issuer.");
1613 jvParams[jss::ledger_index] =
"validated";
1614 jvParams[jss::taker_pays][jss::currency] =
"USD";
1615 jvParams[jss::taker_pays][jss::issuer] = gw.human();
1616 jvParams[jss::taker_gets][jss::currency] =
"XRP";
1617 jvParams[jss::taker_gets][jss::issuer] = gw.human();
1618 auto const jrr = env.
rpc(
1619 "json",
"book_offers",
to_string(jvParams)) [jss::result];
1620 BEAST_EXPECT(jrr[jss::error] ==
"dstIsrMalformed");
1621 BEAST_EXPECT(jrr[jss::error_message] ==
1622 "Unneeded field 'taker_gets.issuer' "
1623 "for XRP currency specification.");
1631 testcase(
"BookOffer Limits");
1632 using namespace jtx;
1635 env.fund(
XRP(200000), gw);
1637 auto USD = gw[
"USD"];
1640 env(
offer(gw,
XRP(50 + 1*i), USD(1.0 + 0.1*i)));
1644 jvParams[jss::limit] = 1;
1645 jvParams[jss::ledger_index] =
"validated";
1646 jvParams[jss::taker_pays][jss::currency] =
"XRP";
1647 jvParams[jss::taker_gets][jss::currency] =
"USD";
1648 jvParams[jss::taker_gets][jss::issuer] = gw.human();
1650 env.rpc(
"json",
"book_offers",
to_string(jvParams)) [jss::result];
1651 BEAST_EXPECT(jrr[jss::offers].isArray());
1652 BEAST_EXPECT(jrr[jss::offers].size() == (asAdmin ? 1u : 0u));
1655 jvParams[jss::limit] = 0u;
1657 env.rpc(
"json",
"book_offers",
to_string(jvParams)) [jss::result];
1658 BEAST_EXPECT(jrr[jss::offers].isArray());
1659 BEAST_EXPECT(jrr[jss::offers].size() == 0u);
1663 env.rpc(
"json",
"book_offers",
to_string(jvParams)) [jss::result];
1664 BEAST_EXPECT(jrr[jss::offers].isArray());
1665 BEAST_EXPECT(jrr[jss::offers].size() ==
1670 env.rpc(
"json",
"book_offers",
to_string(jvParams)) [jss::result];
1671 BEAST_EXPECT(jrr[jss::offers].isArray());
1672 BEAST_EXPECT(jrr[jss::offers].size() ==