20#include <xrpld/app/tx/detail/SetOracle.h>
21#include <xrpld/ledger/Sandbox.h>
22#include <xrpld/ledger/View.h>
23#include <xrpl/protocol/Feature.h>
24#include <xrpl/protocol/InnerObjectFormats.h>
25#include <xrpl/protocol/TxFlags.h>
26#include <xrpl/protocol/digest.h>
51 if (dataSeries.empty())
56 auto isInvalidLength = [&](
auto const& sField,
std::size_t length) {
58 (ctx.
tx[sField].length() == 0 || ctx.
tx[sField].length() > length);
72 auto const sleSetter =
104 if (entry[sfBaseAsset] == entry[sfQuoteAsset])
111 if (entry.isFieldPresent(sfAssetPrice))
123 auto const v = ctx.
tx[~field];
124 return !v || *v == (*sle)[field];
134 if (ctx.
tx[sfLastUpdateTime] <= (*sle)[sfLastUpdateTime])
140 for (
auto const& entry : sle->getFieldArray(sfPriceDataSeries))
151 if (!pairsDel.
empty())
154 auto const oldCount =
155 sle->getFieldArray(sfPriceDataSeries).size() > 5 ? 2 : 1;
156 auto const newCount = pairs.
size() > 5 ? 2 : 1;
157 adjustReserve = newCount - oldCount;
166 adjustReserve = pairs.
size() > 5 ? 2 : 1;
175 sleSetter->getFieldU32(sfOwnerCount) + adjustReserve);
176 auto const& balance = sleSetter->getFieldAmount(sfBalance);
178 if (balance < reserve)
187 if (
auto const sleAccount =
219 for (
auto const& entry : sle->getFieldArray(sfPriceDataSeries))
223 priceData.setFieldCurrency(
224 sfBaseAsset, entry.getFieldCurrency(sfBaseAsset));
225 priceData.setFieldCurrency(
226 sfQuoteAsset, entry.getFieldCurrency(sfQuoteAsset));
229 auto const oldCount = pairs.
size() > 5 ? 2 : 1;
234 if (!entry.isFieldPresent(sfAssetPrice))
239 else if (
auto iter = pairs.
find(key); iter != pairs.
end())
242 iter->second.setFieldU64(
243 sfAssetPrice, entry.getFieldU64(sfAssetPrice));
244 if (entry.isFieldPresent(sfScale))
245 iter->second.setFieldU8(sfScale, entry.getFieldU8(sfScale));
252 priceData.setFieldCurrency(
253 sfBaseAsset, entry.getFieldCurrency(sfBaseAsset));
254 priceData.setFieldCurrency(
255 sfQuoteAsset, entry.getFieldCurrency(sfQuoteAsset));
256 priceData.setFieldU64(
257 sfAssetPrice, entry.getFieldU64(sfAssetPrice));
258 if (entry.isFieldPresent(sfScale))
259 priceData.setFieldU8(sfScale, entry.getFieldU8(sfScale));
260 pairs.
emplace(key, std::move(priceData));
264 for (
auto const& iter : pairs)
265 updatedSeries.
push_back(std::move(iter.second));
266 sle->setFieldArray(sfPriceDataSeries, updatedSeries);
268 sle->setFieldVL(sfURI,
ctx_.
tx[sfURI]);
269 sle->setFieldU32(sfLastUpdateTime,
ctx_.
tx[sfLastUpdateTime]);
271 auto const newCount = pairs.
size() > 5 ? 2 : 1;
272 auto const adjust = newCount - oldCount;
282 sle = std::make_shared<SLE>(oracleID);
284 sle->setFieldVL(sfProvider,
ctx_.
tx[sfProvider]);
286 sle->setFieldVL(sfURI,
ctx_.
tx[sfURI]);
288 sle->setFieldArray(sfPriceDataSeries, series);
289 sle->setFieldVL(sfAssetClass,
ctx_.
tx[sfAssetClass]);
290 sle->setFieldU32(sfLastUpdateTime,
ctx_.
tx[sfLastUpdateTime]);
297 (*sle)[sfOwnerNode] = *page;
299 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
const STArray & getFieldArray(SField const &field) const
void set(const SOTemplate &)
bool isFieldPresent(SField const &field) const
const STCurrency & 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)