30 .fee =
static_cast<int>(env.
current()->fees().base.drops()),
37 env.
fund(env.
current()->fees().accountReserve(0), owner);
41 .fee =
static_cast<int>(env.
current()->fees().base.drops()),
48 env.
current()->fees().accountReserve(1) + env.
current()->fees().base * 2, owner);
50 env, {.owner = owner, .fee =
static_cast<int>(env.
current()->fees().base.drops())});
51 BEAST_EXPECT(oracle.exists());
56 {
"XRP",
"EUR", 740, 1},
57 {
"XRP",
"GBP", 740, 1},
58 {
"XRP",
"CNY", 740, 1},
59 {
"XRP",
"CAD", 740, 1},
60 {
"XRP",
"AUD", 740, 1},
62 .fee =
static_cast<int>(env.
current()->fees().base.drops()),
68 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
70 Oracle oracle(env, {.owner = owner, .fee = baseFee},
false);
79 .
series = {{
"XRP",
"USD", 740, 1}, {
"XRP",
"USD", 750, 1}},
107 {{
"XRP",
"US1", 740, 1},
108 {
"XRP",
"US2", 750, 1},
109 {
"XRP",
"US3", 740, 1},
110 {
"XRP",
"US4", 750, 1},
111 {
"XRP",
"US5", 740, 1},
112 {
"XRP",
"US6", 750, 1},
113 {
"XRP",
"US7", 740, 1},
114 {
"XRP",
"US8", 750, 1},
115 {
"XRP",
"US9", 740, 1},
116 {
"XRP",
"U10", 750, 1},
117 {
"XRP",
"U11", 740, 1}},
126 auto const baseFee =
static_cast<int>(env.current()->fees().base.drops());
131 CreateArg{.
owner = owner, .series = {{{
"XRP",
"USD", 740, 1}}}, .fee = baseFee});
136 {
"XRP",
"US1", 740, 1},
137 {
"XRP",
"US2", 750, 1},
138 {
"XRP",
"US3", 740, 1},
139 {
"XRP",
"US4", 750, 1},
140 {
"XRP",
"US5", 740, 1},
141 {
"XRP",
"US6", 750, 1},
142 {
"XRP",
"US7", 740, 1},
143 {
"XRP",
"US8", 750, 1},
144 {
"XRP",
"US9", 740, 1},
145 {
"XRP",
"U10", 750, 1},
153 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
155 Oracle oracle(env, {.owner = owner, .fee = baseFee},
false);
161 .provider =
"provider",
175 BEAST_EXPECT(oracle.exists());
178 .
series = {{
"XRP",
"USD", 740, 1}},
179 .provider =
"provider1",
184 .
series = {{
"XRP",
"USD", 740, 1}},
185 .assetClass =
"currency1",
192 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
194 Oracle oracle(env, {.owner = owner, .fee = baseFee},
false);
219 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
223 Oracle oracle(env, {.owner = owner, .fee = baseFee});
224 BEAST_EXPECT(oracle.exists());
228 .series = {{
"XRP",
"USD", 740, 1}},
237 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
238 auto closeTime = [&]() {
239 return duration_cast<seconds>(
240 env.
current()->header().closeTime.time_since_epoch() - 10'000s)
244 Oracle oracle(env, {.owner = owner, .fee = baseFee});
245 BEAST_EXPECT(oracle.exists());
250 .
series = {{
"XRP",
"USD", 740, 1}},
251 .lastUpdateTime =
static_cast<std::uint32_t>(closeTime() - 301),
257 .
series = {{
"XRP",
"USD", 740, 1}},
258 .lastUpdateTime =
static_cast<std::uint32_t>(closeTime() + 311),
261 oracle.set(
UpdateArg{.
series = {{
"XRP",
"USD", 740, 1}}, .fee = baseFee});
262 BEAST_EXPECT(oracle.expectLastUpdateTime(
267 .
series = {{
"XRP",
"USD", 740, 1}},
274 .
series = {{
"XRP",
"USD", 740, 1}},
283 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
285 Oracle oracle(env, {.owner = owner, .fee = baseFee});
286 BEAST_EXPECT(oracle.exists());
303 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
308 .series = {{
"USD",
"USD", 740, 1}},
316 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
329 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
331 Oracle oracle(env, {.owner = owner, .fee = baseFee});
358 env, {.owner = owner, .fee =
static_cast<int>(env.
current()->fees().base.drops())});
371 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
374 Oracle oracle(env, {.owner = owner, .series = series, .fee = baseFee});
375 BEAST_EXPECT(oracle.exists());
376 BEAST_EXPECT(
ownerCount(env, owner) == (count + adj));
377 auto const entry = oracle.ledgerEntry();
378 BEAST_EXPECT(entry[jss::node][jss::Owner] == owner.
human());
379 if (features[fixIncludeKeyletFields])
381 BEAST_EXPECT(entry[jss::node][jss::OracleDocumentID] == oracle.documentID());
385 BEAST_EXPECT(!entry[jss::node].isMember(jss::OracleDocumentID));
387 BEAST_EXPECT(oracle.expectLastUpdateTime(946694810));
392 Env env(*
this, features);
393 test(env, {{
"XRP",
"USD", 740, 1}}, 1);
398 Env env(*
this, features);
401 {{
"XRP",
"USD", 740, 1},
402 {
"BTC",
"USD", 740, 1},
403 {
"ETH",
"USD", 740, 1},
404 {
"CAN",
"USD", 740, 1},
405 {
"YAN",
"USD", 740, 1},
406 {
"GBP",
"USD", 740, 1}},
412 Env env(*
this, features);
413 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
417 Oracle oracle(env, {.owner = owner, .fee = baseFee});
418 BEAST_EXPECT(oracle.exists());
432 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
435 Oracle oracle(env, {.owner = owner, .fee = baseFee});
436 BEAST_EXPECT(oracle.exists());
446 oracle.remove({.documentID = 2, .fee = baseFee, .err =
ter(
tecNO_ENTRY)});
468 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
470 Oracle oracle(env, {.owner = owner, .series = series, .fee = baseFee});
472 BEAST_EXPECT(oracle.exists());
473 oracle.remove({.fee = baseFee});
474 BEAST_EXPECT(!oracle.exists());
475 BEAST_EXPECT(
ownerCount(env, owner) == (count - adj));
481 test(env, {{
"XRP",
"USD", 740, 1}}, 1);
490 {
"XRP",
"USD", 740, 1},
491 {
"BTC",
"USD", 740, 1},
492 {
"ETH",
"USD", 740, 1},
493 {
"CAN",
"USD", 740, 1},
494 {
"YAN",
"USD", 740, 1},
495 {
"GBP",
"USD", 740, 1},
503 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
505 auto const alice =
Account(
"alice");
506 auto const acctDelFee{
drops(env.
current()->fees().increment)};
510 env, {.owner = owner, .series = {{
"XRP",
"USD", 740, 1}}, .fee = baseFee});
515 .series = {{
"XRP",
"EUR", 740, 1}},
518 BEAST_EXPECT(oracle.exists());
519 BEAST_EXPECT(oracle1.exists());
520 auto const index = env.
closed()->seq();
521 auto const hash = env.
closed()->header().hash;
522 for (
int i = 0; i < 256; ++i)
526 BEAST_EXPECT(!oracle.exists());
527 BEAST_EXPECT(!oracle1.exists());
530 auto verifyLedgerData = [&](
auto const& field,
auto const& value) {
532 jvParams[field] = value;
533 jvParams[jss::binary] =
false;
534 jvParams[jss::type] = jss::oracle;
536 BEAST_EXPECT(jrr[jss::result][jss::state].size() == 2);
538 verifyLedgerData(jss::ledger_index, index);
552 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
555 Oracle oracle(env, {.owner = owner, .fee = baseFee});
556 BEAST_EXPECT(oracle.exists());
559 oracle.set(
UpdateArg{.
series = {{
"XRP",
"USD", 740, 2}}, .fee = baseFee});
560 BEAST_EXPECT(oracle.expectPrice({{
"XRP",
"USD", 740, 2}}));
564 BEAST_EXPECT(
ownerCount(env, owner) == count);
567 oracle.set(
UpdateArg{.
series = {{
"XRP",
"EUR", 700, 2}}, .fee = baseFee});
568 BEAST_EXPECT(oracle.expectPrice({{
"XRP",
"USD", 0, 0}, {
"XRP",
"EUR", 700, 2}}));
570 BEAST_EXPECT(
ownerCount(env, owner) == count);
575 .
series = {{
"XRP",
"USD", 741, 2}, {
"XRP",
"EUR", 710, 2}}, .fee = baseFee});
576 BEAST_EXPECT(oracle.expectPrice({{
"XRP",
"USD", 741, 2}, {
"XRP",
"EUR", 710, 2}}));
578 BEAST_EXPECT(
ownerCount(env, owner) == count);
585 {
"BTC",
"USD", 741, 2},
586 {
"ETH",
"EUR", 710, 2},
587 {
"YAN",
"EUR", 710, 2},
588 {
"CAN",
"EUR", 710, 2},
592 BEAST_EXPECT(
ownerCount(env, owner) == count);
600 {{
"XRP",
"USD", 742, 2},
601 {
"XRP",
"EUR", 711, 2},
606 BEAST_EXPECT(
oracle.expectPrice({{
"XRP",
"USD", 742, 2}, {
"XRP",
"EUR", 711, 2}}));
609 BEAST_EXPECT(
ownerCount(env, owner) == count);
615 auto const baseFee =
static_cast<int>(env.current()->fees().base.drops());
617 env.current()->fees().accountReserve(1) + env.current()->fees().base * 2, owner);
618 Oracle
oracle(env, {.owner = owner, .fee = baseFee});
619 oracle.set(UpdateArg{.series = {{
"XRP",
"USD", 742, 2}}, .fee = baseFee});
622 for (
bool const withFixOrder : {
false,
true})
628 auto const baseFee =
static_cast<int>(env.current()->fees().base.drops());
630 auto test = [&](Env& env,
DataSeries const& series) {
631 env.fund(
XRP(1'000), owner);
632 Oracle
oracle(env, {.owner = owner, .series = series, .fee = baseFee});
633 BEAST_EXPECT(
oracle.exists());
635 BEAST_EXPECT(sle->getFieldArray(sfPriceDataSeries).size() == series.size());
637 auto const beforeQuoteAssetName1 = sle->getFieldArray(sfPriceDataSeries)[0]
638 .getFieldCurrency(sfQuoteAsset)
640 auto const beforeQuoteAssetName2 = sle->getFieldArray(sfPriceDataSeries)[1]
641 .getFieldCurrency(sfQuoteAsset)
644 oracle.set(UpdateArg{.series = series, .fee = baseFee});
647 auto const afterQuoteAssetName1 = sle->getFieldArray(sfPriceDataSeries)[0]
648 .getFieldCurrency(sfQuoteAsset)
650 auto const afterQuoteAssetName2 = sle->getFieldArray(sfPriceDataSeries)[1]
651 .getFieldCurrency(sfQuoteAsset)
654 if (env.current()->rules().enabled(fixPriceOracleOrder))
656 BEAST_EXPECT(afterQuoteAssetName1 == beforeQuoteAssetName1);
657 BEAST_EXPECT(afterQuoteAssetName2 == beforeQuoteAssetName2);
661 BEAST_EXPECT(afterQuoteAssetName1 != beforeQuoteAssetName1);
662 BEAST_EXPECT(afterQuoteAssetName2 != beforeQuoteAssetName2);
665 test(env, {{
"XRP",
"USD", 742, 2}, {
"XRP",
"EUR", 711, 2}});
672 testcase(
"Multisig");
674 Oracle::setFee(100'000);
677 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
685 env.
fund(
XRP(10'000), alice, becky, zelda, ed, bob);
693 env(signers(alice, 2, {{becky, 1}, {bogie, 1}, {ed, 2}}),
sig(alie));
705 BEAST_EXPECT(oracle.exists());
710 .
series = {{
"XRP",
"USD", 740, 1}},
716 .
series = {{
"XRP",
"USD", 740, 1}},
722 .
series = {{
"XRP",
"USD", 741, 1}}, .msig =
msig(becky, bogie), .fee = baseFee});
723 BEAST_EXPECT(oracle.expectPrice({{
"XRP",
"USD", 741, 1}}));
725 env(signers(alice, jtx::none),
sig(alie));
727 env.require(
owners(alice, 1));
729 env(signers(alice, 2, {{zelda, 1}, {bob, 1}, {ed, 2}}), sig(alie));
734 .series = {{
"XRP",
"USD", 740, 1}},
735 .msig = msig(becky, bogie),
741 .series = {{
"XRP",
"USD", 7412, 2}}, .msig = msig(zelda, bob), .fee = baseFee});
742 BEAST_EXPECT(
oracle.expectPrice({{
"XRP",
"USD", 7412, 2}}));
744 UpdateArg{.series = {{
"XRP",
"USD", 74245, 3}}, .msig = msig(ed), .fee = baseFee});
745 BEAST_EXPECT(
oracle.expectPrice({{
"XRP",
"USD", 74245, 3}}));
748 oracle.remove({.msig = msig(bob), .fee = baseFee, .err = ter(tefBAD_QUORUM)});
749 oracle.remove({.msig = msig(becky), .fee = baseFee, .err = ter(tefBAD_SIGNATURE)});
750 oracle.remove({.msig = msig(ed), .fee = baseFee});
751 BEAST_EXPECT(!
oracle.exists());