mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-22 14:50:54 +00:00
178 lines
5.1 KiB
C++
178 lines
5.1 KiB
C++
#pragma once
|
|
|
|
#include <test/jtx.h>
|
|
|
|
#include <date/date.h>
|
|
|
|
namespace xrpl::test::jtx::oracle {
|
|
|
|
using AnyValue = std::variant<std::string, double, Json::Int, Json::UInt>;
|
|
using OraclesData = std::vector<std::pair<std::optional<Account>, std::optional<AnyValue>>>;
|
|
|
|
// Special string value, which is converted to unquoted string in the string
|
|
// passed to rpc.
|
|
constexpr char const* NoneTag = "%None%";
|
|
constexpr char const* UnquotedNone = "None";
|
|
constexpr char const* NonePattern = "\"%None%\"";
|
|
|
|
std::uint32_t
|
|
asUInt(AnyValue const& v);
|
|
|
|
bool
|
|
validDocumentID(AnyValue const& v);
|
|
|
|
void
|
|
toJson(Json::Value& jv, AnyValue const& v);
|
|
|
|
void
|
|
toJsonHex(Json::Value& jv, AnyValue const& v);
|
|
|
|
// base asset, quote asset, price, scale
|
|
using DataSeries = std::vector<
|
|
std::
|
|
tuple<std::string, std::string, std::optional<std::uint32_t>, std::optional<std::uint8_t>>>;
|
|
|
|
// Typical defaults for Create
|
|
struct CreateArg
|
|
{
|
|
std::optional<AccountID> owner = std::nullopt;
|
|
std::optional<AnyValue> documentID = 1;
|
|
DataSeries series = {{"XRP", "USD", 740, 1}};
|
|
std::optional<AnyValue> assetClass = "currency";
|
|
std::optional<AnyValue> provider = "provider";
|
|
std::optional<AnyValue> uri = "URI";
|
|
std::optional<AnyValue> lastUpdateTime = std::nullopt;
|
|
std::uint32_t flags = 0;
|
|
std::optional<jtx::msig> msig = std::nullopt;
|
|
std::optional<jtx::seq> seq = std::nullopt;
|
|
int fee = 10;
|
|
std::optional<ter> err = std::nullopt;
|
|
bool close = false;
|
|
};
|
|
|
|
// Typical defaults for Update
|
|
struct UpdateArg
|
|
{
|
|
std::optional<AccountID> owner = std::nullopt;
|
|
std::optional<AnyValue> documentID = std::nullopt;
|
|
DataSeries series = {}; // NOLINT(readability-redundant-member-init)
|
|
std::optional<AnyValue> assetClass = std::nullopt;
|
|
std::optional<AnyValue> provider = std::nullopt;
|
|
std::optional<AnyValue> uri = "URI";
|
|
std::optional<AnyValue> lastUpdateTime = std::nullopt;
|
|
std::uint32_t flags = 0;
|
|
std::optional<jtx::msig> msig = std::nullopt;
|
|
std::optional<jtx::seq> seq = std::nullopt;
|
|
int fee = 10;
|
|
std::optional<ter> err = std::nullopt;
|
|
};
|
|
|
|
struct RemoveArg
|
|
{
|
|
std::optional<AccountID> const& owner = std::nullopt;
|
|
std::optional<AnyValue> const& documentID = std::nullopt;
|
|
std::uint32_t flags = 0;
|
|
std::optional<jtx::msig> const& msig = std::nullopt;
|
|
std::optional<jtx::seq> seq = std::nullopt;
|
|
int fee = 10;
|
|
std::optional<ter> const& err = std::nullopt;
|
|
};
|
|
|
|
// Simulate testStartTime as 10'000s from XRPL epoch time to make
|
|
// LastUpdateTime validation to work and to make unit-test consistent.
|
|
// The value doesn't matter much, it has to be greater
|
|
// than maxLastUpdateTimeDelta in order to pass LastUpdateTime
|
|
// validation {close-maxLastUpdateTimeDelta,close+maxLastUpdateTimeDelta}.
|
|
constexpr static std::chrono::seconds testStartTime = epoch_offset + std::chrono::seconds(10'000);
|
|
|
|
/** Oracle class facilitates unit-testing of the Price Oracle feature.
|
|
* It defines functions to create, update, and delete the Oracle object,
|
|
* to query for various states, and to call APIs.
|
|
*/
|
|
class Oracle
|
|
{
|
|
private:
|
|
// Global fee if not 0
|
|
static inline std::uint32_t fee = 0;
|
|
Env& env_;
|
|
AccountID owner_;
|
|
std::uint32_t documentID_{};
|
|
|
|
private:
|
|
void
|
|
submit(
|
|
Json::Value const& jv,
|
|
std::optional<jtx::msig> const& msig,
|
|
std::optional<jtx::seq> const& seq,
|
|
std::optional<ter> const& err);
|
|
|
|
public:
|
|
Oracle(Env& env, CreateArg const& arg, bool submit = true);
|
|
|
|
void
|
|
remove(RemoveArg const& arg);
|
|
|
|
void
|
|
set(CreateArg const& arg);
|
|
void
|
|
set(UpdateArg const& arg);
|
|
|
|
static Json::Value
|
|
aggregatePrice(
|
|
Env& env,
|
|
std::optional<AnyValue> const& baseAsset,
|
|
std::optional<AnyValue> const& quoteAsset,
|
|
std::optional<OraclesData> const& oracles = std::nullopt,
|
|
std::optional<AnyValue> const& trim = std::nullopt,
|
|
std::optional<AnyValue> const& timeThreshold = std::nullopt);
|
|
|
|
[[nodiscard]] std::uint32_t
|
|
documentID() const
|
|
{
|
|
return documentID_;
|
|
}
|
|
|
|
[[nodiscard]] bool
|
|
exists() const
|
|
{
|
|
return exists(env_, owner_, documentID_);
|
|
}
|
|
|
|
[[nodiscard]] static bool
|
|
exists(Env& env, AccountID const& account, std::uint32_t documentID);
|
|
|
|
[[nodiscard]] bool
|
|
expectPrice(DataSeries const& prices) const;
|
|
|
|
[[nodiscard]] bool
|
|
expectLastUpdateTime(std::uint32_t lastUpdateTime) const;
|
|
|
|
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);
|
|
|
|
[[nodiscard]] Json::Value
|
|
ledgerEntry(std::optional<std::string> const& index = std::nullopt) const
|
|
{
|
|
return Oracle::ledgerEntry(env_, owner_, documentID_, index);
|
|
}
|
|
|
|
static void
|
|
setFee(std::uint32_t f)
|
|
{
|
|
fee = f;
|
|
}
|
|
|
|
friend std::ostream&
|
|
operator<<(std::ostream& strm, Oracle const& oracle)
|
|
{
|
|
strm << oracle.ledgerEntry().toStyledString();
|
|
return strm;
|
|
}
|
|
};
|
|
|
|
} // namespace xrpl::test::jtx::oracle
|