1#include <test/jtx/Oracle.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/multisign.h>
5#include <test/jtx/seq.h>
6#include <test/jtx/ter.h>
8#include <xrpl/basics/Number.h>
9#include <xrpl/basics/chrono.h>
10#include <xrpl/basics/strHex.h>
11#include <xrpl/json/json_value.h>
12#include <xrpl/json/to_string.h>
13#include <xrpl/protocol/AccountID.h>
14#include <xrpl/protocol/Indexes.h>
15#include <xrpl/protocol/SField.h>
16#include <xrpl/protocol/STObject.h>
17#include <xrpl/protocol/jss.h>
19#include <boost/lexical_cast/try_lexical_convert.hpp>
20#include <boost/regex.hpp>
21#include <boost/regex/v5/regex_replace.hpp>
40 auto const now =
env_.timeKeeper().now();
41 if (now.time_since_epoch().count() == 0 || arg.
close)
55 jv[jss::TransactionType] = jss::OracleDelete;
62 else if (arg.
fee != 0)
71 jv[jss::Flags] = arg.
flags;
86 env_(jv, *msig, *seq, *err);
90 env_(jv, *msig, *seq);
94 env_(jv, *msig, *err);
103 env_(jv, *seq, *err);
123 assert(account.isNonZero());
132 auto const& leSeries = sle->getFieldArray(sfPriceDataSeries);
133 if (leSeries.empty() || leSeries.size() != series.
size())
135 for (
auto const& data : series)
142 return baseAsset.getText() == std::get<0>(data) &&
143 quoteAsset.getText() == std::get<1>(data) && price == std::get<2>(data) &&
144 scale == std::get<3>(data);
145 }) == leSeries.end())
157 return sle && (*sle)[sfLastUpdateTime] == lastUpdateTime;
173 for (
auto const&
id : *oracles)
182 jv[jss::oracles] = jvOracles;
185 toJson(jv[jss::trim], *trim);
187 toJson(jv[jss::base_asset], *baseAsset);
189 toJson(jv[jss::quote_asset], *quoteAsset);
191 toJson(jv[jss::time_threshold], *timeThreshold);
195 auto jr = env.
rpc(
"json",
"get_aggregate_price", str);
199 if (jr.isMember(jss::result) && jr[jss::result].isMember(jss::status))
201 return jr[jss::result];
203 if (jr.isMember(jss::error))
231 jv[jss::TransactionType] = jss::OracleSet;
240 jv[jss::Flags] = arg.
flags;
245 else if (arg.
fee != 0)
258 jv[jss::LastUpdateTime] =
277 assert(s.size() <= 20);
285 price[jss::BaseAsset] = assetToStr(std::get<0>(
data));
286 price[jss::QuoteAsset] = assetToStr(std::get<1>(
data));
287 if (std::get<2>(
data))
289 price[jss::AssetPrice] =
292 if (std::get<3>(
data))
293 price[jss::Scale] = *std::get<3>(
data);
294 priceData[jss::PriceData] = price;
295 dataSeries.
append(priceData);
297 jv[jss::PriceDataSeries] = dataSeries;
331 jvParams[jss::oracle][jss::account] =
to_string(std::get<AccountID>(*account));
335 jvParams[jss::oracle][jss::account] = std::get<std::string>(*account);
343 if (boost::conversion::try_lexical_convert(*index, i))
345 jvParams[jss::oracle][jss::ledger_index] = i;
349 jvParams[jss::oracle][jss::ledger_index] = *index;
355 auto jr = env.
rpc(
"json",
"ledger_entry", str);
359 if (jr.isMember(jss::error))
361 if (jr.isMember(jss::result) && jr[jss::result].isMember(jss::status))
362 return jr[jss::result];
377 [&]<
typename T>(T&& arg) {
380 if (arg.starts_with(
"##"))
412 [[maybe_unused]]
auto unused1 = jv.
asUInt();
413 [[maybe_unused]]
auto unused2 = jv.
isNumeric();
Value & append(Value const &value)
Append value to array at the end.
STCurrency const & getFieldCurrency(SField const &field) const
unsigned char getFieldU8(SField const &field) const
std::uint64_t getFieldU64(SField const &field) const
A transaction testing environment.
SLE::const_pointer le(Account const &account) const
Return an account root.
json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
void set(CreateArg const &arg)
std::uint32_t documentID_
bool expectLastUpdateTime(std::uint32_t lastUpdateTime) const
std::uint32_t documentID() const
Oracle(Env &env, CreateArg const &arg, bool submit=true)
bool expectPrice(DataSeries const &prices) const
static json::Value aggregatePrice(Env &env, std::optional< AnyValue > const &baseAsset, std::optional< AnyValue > const "eAsset, std::optional< OraclesData > const &oracles=std::nullopt, std::optional< AnyValue > const &trim=std::nullopt, std::optional< AnyValue > const &timeThreshold=std::nullopt)
static json::Value ledgerEntry(Env &env, std::optional< std::variant< AccountID, std::string > > const &account, std::optional< AnyValue > const &documentID, std::optional< std::string > const &index=std::nullopt)
void remove(RemoveArg const &arg)
void submit(json::Value const &jv, std::optional< jtx::Msig > const &msig, std::optional< jtx::Seq > const &seq, std::optional< Ter > const &err)
T duration_cast(T... args)
T holds_alternative(T... args)
@ Array
array value (ordered list)
Keylet oracle(AccountID const &account, std::uint32_t const &documentID) noexcept
std::uint32_t asUInt(AnyValue const &v)
constexpr char const * kUnquotedNone
std::variant< std::string, double, json::Int, json::UInt > AnyValue
void toJsonHex(json::Value &jv, AnyValue const &v)
bool validDocumentID(AnyValue const &v)
void toJson(json::Value &jv, AnyValue const &v)
constexpr char const * kNonePattern
std::vector< std:: tuple< std::string, std::string, std::optional< std::uint32_t >, std::optional< std::uint8_t > > > DataSeries
static constexpr std::chrono::seconds kTestStartTime
static constexpr std::chrono::seconds kEpochOffset
Clock for measuring the network time.
std::string strHex(FwdIt begin, FwdIt end)
int scale(Number const &number, Asset const &asset)
Get the scale of a Number for a given asset.
std::string to_string(BaseUInt< Bits, Tag > const &a)
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
std::optional< AnyValue > documentID
std::optional< AccountID > owner
std::optional< AnyValue > lastUpdateTime
std::optional< AnyValue > provider
std::optional< jtx::Msig > msig
std::optional< jtx::Seq > seq
std::optional< AnyValue > assetClass
std::optional< AnyValue > uri
std::optional< jtx::Seq > seq
std::optional< Ter > const & err
std::optional< AnyValue > const & documentID
std::optional< jtx::Msig > const & msig
std::optional< AccountID > const & owner
std::optional< AccountID > owner
std::optional< AnyValue > documentID
std::optional< AnyValue > uri
std::optional< jtx::Seq > seq
std::optional< jtx::Msig > msig
std::optional< AnyValue > provider
std::optional< AnyValue > lastUpdateTime
std::optional< AnyValue > assetClass