20#include <xrpld/app/tx/detail/SetOracle.h>
21#include <xrpld/ledger/Sandbox.h>
22#include <xrpld/ledger/View.h>
24#include <xrpl/protocol/Feature.h>
25#include <xrpl/protocol/InnerObjectFormats.h>
26#include <xrpl/protocol/TxFlags.h>
27#include <xrpl/protocol/digest.h>
52 if (dataSeries.empty())
57 auto isInvalidLength = [&](
auto const& sField,
std::size_t length) {
59 (ctx.
tx[sField].length() == 0 || ctx.
tx[sField].length() > length);
73 auto const sleSetter =
105 if (entry[sfBaseAsset] == entry[sfQuoteAsset])
112 if (entry.isFieldPresent(sfAssetPrice))
124 auto const v = ctx.
tx[~field];
125 return !v || *v == (*sle)[field];
135 if (ctx.
tx[sfLastUpdateTime] <= (*sle)[sfLastUpdateTime])
141 for (
auto const& entry : sle->getFieldArray(sfPriceDataSeries))
152 if (!pairsDel.
empty())
155 auto const oldCount =
156 sle->getFieldArray(sfPriceDataSeries).size() > 5 ? 2 : 1;
157 auto const newCount = pairs.
size() > 5 ? 2 : 1;
158 adjustReserve = newCount - oldCount;
167 adjustReserve = pairs.
size() > 5 ? 2 : 1;
176 sleSetter->getFieldU32(sfOwnerCount) + adjustReserve);
177 auto const& balance = sleSetter->getFieldAmount(sfBalance);
179 if (balance < reserve)
188 if (
auto const sleAccount =
220 for (
auto const& entry : sle->getFieldArray(sfPriceDataSeries))
224 priceData.setFieldCurrency(
225 sfBaseAsset, entry.getFieldCurrency(sfBaseAsset));
226 priceData.setFieldCurrency(
227 sfQuoteAsset, entry.getFieldCurrency(sfQuoteAsset));
230 auto const oldCount = pairs.
size() > 5 ? 2 : 1;
235 if (!entry.isFieldPresent(sfAssetPrice))
240 else if (
auto iter = pairs.
find(key); iter != pairs.
end())
243 iter->second.setFieldU64(
244 sfAssetPrice, entry.getFieldU64(sfAssetPrice));
245 if (entry.isFieldPresent(sfScale))
246 iter->second.setFieldU8(sfScale, entry.getFieldU8(sfScale));
253 priceData.setFieldCurrency(
254 sfBaseAsset, entry.getFieldCurrency(sfBaseAsset));
255 priceData.setFieldCurrency(
256 sfQuoteAsset, entry.getFieldCurrency(sfQuoteAsset));
257 priceData.setFieldU64(
258 sfAssetPrice, entry.getFieldU64(sfAssetPrice));
259 if (entry.isFieldPresent(sfScale))
260 priceData.setFieldU8(sfScale, entry.getFieldU8(sfScale));
261 pairs.
emplace(key, std::move(priceData));
265 for (
auto const& iter : pairs)
266 updatedSeries.
push_back(std::move(iter.second));
267 sle->setFieldArray(sfPriceDataSeries, updatedSeries);
269 sle->setFieldVL(sfURI,
ctx_.
tx[sfURI]);
270 sle->setFieldU32(sfLastUpdateTime,
ctx_.
tx[sfLastUpdateTime]);
272 auto const newCount = pairs.
size() > 5 ? 2 : 1;
273 auto const adjust = newCount - oldCount;
283 sle = std::make_shared<SLE>(oracleID);
285 sle->setFieldVL(sfProvider,
ctx_.
tx[sfProvider]);
287 sle->setFieldVL(sfURI,
ctx_.
tx[sfURI]);
289 sle->setFieldArray(sfPriceDataSeries, series);
290 sle->setFieldVL(sfAssetClass,
ctx_.
tx[sfAssetClass]);
291 sle->setFieldU32(sfLastUpdateTime,
ctx_.
tx[sfLastUpdateTime]);
298 (*sle)[sfOwnerNode] = *page;
300 auto const count = series.size() > 5 ? 2 : 1;
State information when applying a tx.
beast::Journal const journal
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Defines the fields and their attributes within a STObject.
void push_back(STObject const &object)
Currency const & currency() const
AccountID getAccountID(SField const &field) const
STArray const & getFieldArray(SField const &field) const
void set(SOTemplate const &)
bool isFieldPresent(SField const &field) const
STCurrency const & getFieldCurrency(SField const &field) const
std::uint32_t getFlags() const
static NotTEC preflight(PreflightContext const &ctx)
static TER preclaim(PreclaimContext const &ctx)
Keylet oracle(AccountID const &account, std::uint32_t const &documentID) noexcept
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
static void setPriceDataInnerObjTemplate(STObject &obj)
bool isConsistent(Book const &book)
std::size_t constexpr maxPriceScale
The maximum price scaling factor.
std::size_t constexpr maxOracleURI
The maximum length of a URI inside an Oracle.
std::size_t constexpr maxOracleProvider
The maximum length of a Provider inside an Oracle.
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
static std::pair< Currency, Currency > tokenPairKey(STObject const &pair)
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
static bool adjustOwnerCount(ApplyContext &ctx, int count)
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
@ tecINSUFFICIENT_RESERVE
@ tecTOKEN_PAIR_NOT_FOUND
static constexpr std::chrono::seconds epoch_offset
Clock for measuring the network time.
std::size_t constexpr maxOracleSymbolClass
The maximum length of a SymbolClass inside an Oracle.
constexpr std::uint32_t tfUniversalMask
std::size_t constexpr maxOracleDataSeries
The maximum size of a data series array inside an Oracle.
TERSubset< CanCvtToTER > TER
std::size_t constexpr maxLastUpdateTimeDelta
The maximum allowed time difference between lastUpdateTime and the time of the last closed ledger.
TERSubset< CanCvtToNotTEC > NotTEC
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
State information when determining if a tx is likely to claim a fee.
State information when preflighting a tx.
T time_since_epoch(T... args)