20#include <xrpld/app/tx/detail/SetOracle.h>
22#include <xrpl/ledger/Sandbox.h>
23#include <xrpl/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>
43 if (dataSeries.empty())
48 auto isInvalidLength = [&](
auto const& sField,
std::size_t length) {
50 (ctx.
tx[sField].length() == 0 || ctx.
tx[sField].length() > length);
64 auto const sleSetter =
96 if (entry[sfBaseAsset] == entry[sfQuoteAsset])
103 if (entry.isFieldPresent(sfAssetPrice))
115 auto const v = ctx.
tx[~field];
116 return !v || *v == (*sle)[field];
126 if (ctx.
tx[sfLastUpdateTime] <= (*sle)[sfLastUpdateTime])
132 for (
auto const& entry : sle->getFieldArray(sfPriceDataSeries))
143 if (!pairsDel.
empty())
146 auto const oldCount =
147 sle->getFieldArray(sfPriceDataSeries).size() > 5 ? 2 : 1;
148 auto const newCount = pairs.
size() > 5 ? 2 : 1;
149 adjustReserve = newCount - oldCount;
158 adjustReserve = pairs.
size() > 5 ? 2 : 1;
167 sleSetter->getFieldU32(sfOwnerCount) + adjustReserve);
168 auto const& balance = sleSetter->getFieldAmount(sfBalance);
170 if (balance < reserve)
179 if (
auto const sleAccount =
206 sfBaseAsset, entry.getFieldCurrency(sfBaseAsset));
208 sfQuoteAsset, entry.getFieldCurrency(sfQuoteAsset));
209 priceData.
setFieldU64(sfAssetPrice, entry.getFieldU64(sfAssetPrice));
210 if (entry.isFieldPresent(sfScale))
211 priceData.
setFieldU8(sfScale, entry.getFieldU8(sfScale));
222 for (
auto const& entry : sle->getFieldArray(sfPriceDataSeries))
227 sfBaseAsset, entry.getFieldCurrency(sfBaseAsset));
229 sfQuoteAsset, entry.getFieldCurrency(sfQuoteAsset));
232 auto const oldCount = pairs.
size() > 5 ? 2 : 1;
237 if (!entry.isFieldPresent(sfAssetPrice))
242 else if (
auto iter = pairs.
find(key); iter != pairs.
end())
245 iter->second.setFieldU64(
246 sfAssetPrice, entry.getFieldU64(sfAssetPrice));
247 if (entry.isFieldPresent(sfScale))
248 iter->second.setFieldU8(sfScale, entry.getFieldU8(sfScale));
254 populatePriceData(priceData, entry);
255 pairs.
emplace(key, std::move(priceData));
259 for (
auto const& iter : pairs)
260 updatedSeries.
push_back(std::move(iter.second));
261 sle->setFieldArray(sfPriceDataSeries, updatedSeries);
263 sle->setFieldVL(sfURI,
ctx_.
tx[sfURI]);
264 sle->setFieldU32(sfLastUpdateTime,
ctx_.
tx[sfLastUpdateTime]);
265 if (!sle->isFieldPresent(sfOracleDocumentID) &&
268 (*sle)[sfOracleDocumentID] =
ctx_.
tx[sfOracleDocumentID];
271 auto const newCount = pairs.
size() > 5 ? 2 : 1;
272 auto const adjust = newCount - oldCount;
286 (*sle)[sfOracleDocumentID] =
ctx_.
tx[sfOracleDocumentID];
290 sle->setFieldVL(sfURI,
ctx_.
tx[sfURI]);
304 populatePriceData(priceData, entry);
305 pairs.
emplace(key, std::move(priceData));
307 for (
auto const& iter : pairs)
308 series.
push_back(std::move(iter.second));
311 sle->setFieldArray(sfPriceDataSeries, series);
312 sle->setFieldVL(sfAssetClass,
ctx_.
tx[sfAssetClass]);
313 sle->setFieldU32(sfLastUpdateTime,
ctx_.
tx[sfLastUpdateTime]);
320 (*sle)[sfOwnerNode] = *page;
322 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.
virtual Rules const & rules() const =0
Returns the tx processing rules.
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 setFieldCurrency(SField const &field, STCurrency const &)
void setFieldU8(SField const &field, unsigned char)
void set(SOTemplate const &)
bool isFieldPresent(SField const &field) const
STCurrency const & getFieldCurrency(SField const &field) const
void setFieldU64(SField const &field, std::uint64_t)
void setFieldVL(SField const &field, Blob 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.
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
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)
@ 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.
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)