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()),
47 env.
fund(env.
current()->fees().accountReserve(1) + env.
current()->fees().base * 2, owner);
48 Oracle oracle(env, {.owner = owner, .fee =
static_cast<int>(env.
current()->fees().base.drops())});
49 BEAST_EXPECT(oracle.exists());
54 {
"XRP",
"EUR", 740, 1},
55 {
"XRP",
"GBP", 740, 1},
56 {
"XRP",
"CNY", 740, 1},
57 {
"XRP",
"CAD", 740, 1},
58 {
"XRP",
"AUD", 740, 1},
60 .fee =
static_cast<int>(env.
current()->fees().base.drops()),
66 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
68 Oracle oracle(env, {.owner = owner, .fee = baseFee},
false);
76 .
series = {{
"XRP",
"USD", 740, 1}, {
"XRP",
"USD", 750, 1}},
104 {{
"XRP",
"US1", 740, 1},
105 {
"XRP",
"US2", 750, 1},
106 {
"XRP",
"US3", 740, 1},
107 {
"XRP",
"US4", 750, 1},
108 {
"XRP",
"US5", 740, 1},
109 {
"XRP",
"US6", 750, 1},
110 {
"XRP",
"US7", 740, 1},
111 {
"XRP",
"US8", 750, 1},
112 {
"XRP",
"US9", 740, 1},
113 {
"XRP",
"U10", 750, 1},
114 {
"XRP",
"U11", 740, 1}},
123 auto const baseFee =
static_cast<int>(env.current()->fees().base.drops());
126 Oracle oracle(env,
CreateArg{.
owner = owner, .series = {{{
"XRP",
"USD", 740, 1}}}, .fee = baseFee});
131 {
"XRP",
"US1", 740, 1},
132 {
"XRP",
"US2", 750, 1},
133 {
"XRP",
"US3", 740, 1},
134 {
"XRP",
"US4", 750, 1},
135 {
"XRP",
"US5", 740, 1},
136 {
"XRP",
"US6", 750, 1},
137 {
"XRP",
"US7", 740, 1},
138 {
"XRP",
"US8", 750, 1},
139 {
"XRP",
"US9", 740, 1},
140 {
"XRP",
"U10", 750, 1},
148 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
150 Oracle oracle(env, {.owner = owner, .fee = baseFee},
false);
167 BEAST_EXPECT(oracle.exists());
170 .
series = {{
"XRP",
"USD", 740, 1}},
171 .provider =
"provider1",
176 .
series = {{
"XRP",
"USD", 740, 1}},
177 .assetClass =
"currency1",
184 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
186 Oracle oracle(env, {.owner = owner, .fee = baseFee},
false);
210 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
214 Oracle oracle(env, {.owner = owner, .fee = baseFee});
215 BEAST_EXPECT(oracle.exists());
224 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
225 auto closeTime = [&]() {
226 return duration_cast<seconds>(env.
current()->header().closeTime.time_since_epoch() - 10'000s).count();
229 Oracle oracle(env, {.owner = owner, .fee = baseFee});
230 BEAST_EXPECT(oracle.exists());
235 .
series = {{
"XRP",
"USD", 740, 1}},
236 .lastUpdateTime =
static_cast<std::uint32_t>(closeTime() - 301),
242 .
series = {{
"XRP",
"USD", 740, 1}},
243 .lastUpdateTime =
static_cast<std::uint32_t>(closeTime() + 311),
246 oracle.set(
UpdateArg{.
series = {{
"XRP",
"USD", 740, 1}}, .fee = baseFee});
251 .
series = {{
"XRP",
"USD", 740, 1}},
258 .
series = {{
"XRP",
"USD", 740, 1}},
267 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
269 Oracle oracle(env, {.owner = owner, .fee = baseFee});
270 BEAST_EXPECT(oracle.exists());
287 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
290 env, {.owner = owner, .series = {{
"USD",
"USD", 740, 1}}, .fee = baseFee, .err =
ter(
temMALFORMED)});
296 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
309 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
311 Oracle oracle(env, {.owner = owner, .fee = baseFee});
337 Oracle oracle1(env, {.owner = owner, .fee =
static_cast<int>(env.
current()->fees().base.drops())});
350 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
353 Oracle oracle(env, {.owner = owner, .series = series, .fee = baseFee});
354 BEAST_EXPECT(oracle.exists());
355 BEAST_EXPECT(
ownerCount(env, owner) == (count + adj));
356 auto const entry = oracle.ledgerEntry();
357 BEAST_EXPECT(entry[jss::node][jss::Owner] == owner.
human());
358 if (features[fixIncludeKeyletFields])
360 BEAST_EXPECT(entry[jss::node][jss::OracleDocumentID] == oracle.documentID());
364 BEAST_EXPECT(!entry[jss::node].isMember(jss::OracleDocumentID));
366 BEAST_EXPECT(oracle.expectLastUpdateTime(946694810));
371 Env env(*
this, features);
372 test(env, {{
"XRP",
"USD", 740, 1}}, 1);
377 Env env(*
this, features);
380 {{
"XRP",
"USD", 740, 1},
381 {
"BTC",
"USD", 740, 1},
382 {
"ETH",
"USD", 740, 1},
383 {
"CAN",
"USD", 740, 1},
384 {
"YAN",
"USD", 740, 1},
385 {
"GBP",
"USD", 740, 1}},
391 Env env(*
this, features);
392 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
396 Oracle oracle(env, {.owner = owner, .fee = baseFee});
397 BEAST_EXPECT(oracle.exists());
398 oracle.set(
CreateArg{.
owner =
some, .series = {{
"912810RR9",
"USD", 740, 1}}, .fee = baseFee});
446 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
448 Oracle oracle(env, {.owner = owner, .series = series, .fee = baseFee});
450 BEAST_EXPECT(oracle.exists());
451 oracle.remove({.fee = baseFee});
452 BEAST_EXPECT(!oracle.exists());
453 BEAST_EXPECT(
ownerCount(env, owner) == (count - adj));
459 test(env, {{
"XRP",
"USD", 740, 1}}, 1);
468 {
"XRP",
"USD", 740, 1},
469 {
"BTC",
"USD", 740, 1},
470 {
"ETH",
"USD", 740, 1},
471 {
"CAN",
"USD", 740, 1},
472 {
"YAN",
"USD", 740, 1},
473 {
"GBP",
"USD", 740, 1},
481 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
483 auto const alice =
Account(
"alice");
484 auto const acctDelFee{
drops(env.
current()->fees().increment)};
487 Oracle oracle(env, {.owner = owner, .series = {{
"XRP",
"USD", 740, 1}}, .fee = baseFee});
488 Oracle oracle1(env, {.owner = owner, .documentID = 2, .series = {{
"XRP",
"EUR", 740, 1}}, .fee = baseFee});
490 BEAST_EXPECT(oracle.exists());
491 BEAST_EXPECT(oracle1.exists());
492 auto const index = env.
closed()->seq();
493 auto const hash = env.
closed()->header().hash;
494 for (
int i = 0; i < 256; ++i)
498 BEAST_EXPECT(!oracle.exists());
499 BEAST_EXPECT(!oracle1.exists());
502 auto verifyLedgerData = [&](
auto const& field,
auto const& value) {
504 jvParams[field] = value;
505 jvParams[jss::binary] =
false;
506 jvParams[jss::type] = jss::oracle;
508 BEAST_EXPECT(jrr[jss::result][jss::state].size() == 2);
510 verifyLedgerData(jss::ledger_index, index);
524 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
527 Oracle oracle(env, {.owner = owner, .fee = baseFee});
528 BEAST_EXPECT(oracle.exists());
531 oracle.set(
UpdateArg{.
series = {{
"XRP",
"USD", 740, 2}}, .fee = baseFee});
532 BEAST_EXPECT(oracle.expectPrice({{
"XRP",
"USD", 740, 2}}));
536 BEAST_EXPECT(
ownerCount(env, owner) == count);
539 oracle.set(
UpdateArg{.
series = {{
"XRP",
"EUR", 700, 2}}, .fee = baseFee});
540 BEAST_EXPECT(oracle.expectPrice({{
"XRP",
"USD", 0, 0}, {
"XRP",
"EUR", 700, 2}}));
542 BEAST_EXPECT(
ownerCount(env, owner) == count);
545 oracle.set(
UpdateArg{.
series = {{
"XRP",
"USD", 741, 2}, {
"XRP",
"EUR", 710, 2}}, .fee = baseFee});
546 BEAST_EXPECT(oracle.expectPrice({{
"XRP",
"USD", 741, 2}, {
"XRP",
"EUR", 710, 2}}));
548 BEAST_EXPECT(
ownerCount(env, owner) == count);
555 {
"BTC",
"USD", 741, 2},
556 {
"ETH",
"EUR", 710, 2},
557 {
"YAN",
"EUR", 710, 2},
558 {
"CAN",
"EUR", 710, 2},
562 BEAST_EXPECT(
ownerCount(env, owner) == count);
569 {{
"XRP",
"USD", 742, 2},
570 {
"XRP",
"EUR", 711, 2},
575 BEAST_EXPECT(
oracle.expectPrice({{
"XRP",
"USD", 742, 2}, {
"XRP",
"EUR", 711, 2}}));
578 BEAST_EXPECT(
ownerCount(env, owner) == count);
584 auto const baseFee =
static_cast<int>(env.current()->fees().base.drops());
585 env.fund(env.current()->fees().accountReserve(1) + env.current()->fees().base * 2, owner);
586 Oracle
oracle(env, {.owner = owner, .fee = baseFee});
587 oracle.set(UpdateArg{.series = {{
"XRP",
"USD", 742, 2}}, .fee = baseFee});
590 for (
bool const withFixOrder : {
false,
true})
594 auto const baseFee =
static_cast<int>(env.current()->fees().base.drops());
596 auto test = [&](Env& env,
DataSeries const& series) {
597 env.fund(
XRP(1'000), owner);
598 Oracle
oracle(env, {.owner = owner, .series = series, .fee = baseFee});
599 BEAST_EXPECT(
oracle.exists());
601 BEAST_EXPECT(sle->getFieldArray(sfPriceDataSeries).size() == series.size());
603 auto const beforeQuoteAssetName1 =
604 sle->getFieldArray(sfPriceDataSeries)[0].getFieldCurrency(sfQuoteAsset).getText();
605 auto const beforeQuoteAssetName2 =
606 sle->getFieldArray(sfPriceDataSeries)[1].getFieldCurrency(sfQuoteAsset).getText();
608 oracle.set(UpdateArg{.series = series, .fee = baseFee});
611 auto const afterQuoteAssetName1 =
612 sle->getFieldArray(sfPriceDataSeries)[0].getFieldCurrency(sfQuoteAsset).getText();
613 auto const afterQuoteAssetName2 =
614 sle->getFieldArray(sfPriceDataSeries)[1].getFieldCurrency(sfQuoteAsset).getText();
616 if (env.current()->rules().enabled(fixPriceOracleOrder))
618 BEAST_EXPECT(afterQuoteAssetName1 == beforeQuoteAssetName1);
619 BEAST_EXPECT(afterQuoteAssetName2 == beforeQuoteAssetName2);
623 BEAST_EXPECT(afterQuoteAssetName1 != beforeQuoteAssetName1);
624 BEAST_EXPECT(afterQuoteAssetName2 != beforeQuoteAssetName2);
627 test(env, {{
"XRP",
"USD", 742, 2}, {
"XRP",
"EUR", 711, 2}});
634 testcase(
"Multisig");
636 Oracle::setFee(100'000);
639 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
647 env.
fund(
XRP(10'000), alice, becky, zelda, ed, bob);
655 env(signers(alice, 2, {{becky, 1}, {bogie, 1}, {ed, 2}}),
sig(alie));
667 BEAST_EXPECT(oracle.exists());
676 oracle.set(
UpdateArg{.
series = {{
"XRP",
"USD", 741, 1}}, .msig =
msig(becky, bogie), .fee = baseFee});
677 BEAST_EXPECT(oracle.expectPrice({{
"XRP",
"USD", 741, 1}}));
679 env(signers(alice, jtx::none),
sig(alie));
681 env.require(
owners(alice, 1));
683 env(signers(alice, 2, {{zelda, 1}, {bob, 1}, {ed, 2}}), sig(alie));
688 .series = {{
"XRP",
"USD", 740, 1}},
689 .msig = msig(becky, bogie),
693 oracle.set(UpdateArg{.series = {{
"XRP",
"USD", 7412, 2}}, .msig = msig(zelda, bob), .fee = baseFee});
694 BEAST_EXPECT(
oracle.expectPrice({{
"XRP",
"USD", 7412, 2}}));
695 oracle.set(UpdateArg{.series = {{
"XRP",
"USD", 74245, 3}}, .msig = msig(ed), .fee = baseFee});
696 BEAST_EXPECT(
oracle.expectPrice({{
"XRP",
"USD", 74245, 3}}));
699 oracle.remove({.msig = msig(bob), .fee = baseFee, .err = ter(tefBAD_QUORUM)});
700 oracle.remove({.msig = msig(becky), .fee = baseFee, .err = ter(tefBAD_SIGNATURE)});
701 oracle.remove({.msig = msig(ed), .fee = baseFee});
702 BEAST_EXPECT(!
oracle.exists());