xrpld
Loading...
Searching...
No Matches
View.cpp
1#include <xrpl/ledger/View.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/basics/chrono.h>
6#include <xrpl/basics/safe_cast.h>
7#include <xrpl/beast/utility/Journal.h>
8#include <xrpl/beast/utility/Zero.h>
9#include <xrpl/beast/utility/instrumentation.h>
10#include <xrpl/ledger/ApplyView.h>
11#include <xrpl/ledger/ReadView.h>
12#include <xrpl/ledger/helpers/AccountRootHelpers.h>
13#include <xrpl/ledger/helpers/CredentialHelpers.h>
14#include <xrpl/ledger/helpers/DirectoryHelpers.h>
15#include <xrpl/ledger/helpers/MPTokenHelpers.h>
16#include <xrpl/ledger/helpers/RippleStateHelpers.h>
17#include <xrpl/ledger/helpers/SponsorHelpers.h>
18#include <xrpl/ledger/helpers/TokenHelpers.h>
19#include <xrpl/protocol/AccountID.h>
20#include <xrpl/protocol/Asset.h>
21#include <xrpl/protocol/Feature.h>
22#include <xrpl/protocol/Indexes.h>
23#include <xrpl/protocol/Issue.h>
24#include <xrpl/protocol/Keylet.h>
25#include <xrpl/protocol/LedgerFormats.h>
26#include <xrpl/protocol/MPTIssue.h>
27#include <xrpl/protocol/Protocol.h>
28#include <xrpl/protocol/SField.h>
29#include <xrpl/protocol/STAmount.h>
30#include <xrpl/protocol/STLedgerEntry.h>
31#include <xrpl/protocol/STTx.h>
32#include <xrpl/protocol/TER.h>
33#include <xrpl/protocol/XRPAmount.h>
34
35#include <cstdint>
36#include <optional>
37#include <set>
38
39namespace xrpl {
40
41//------------------------------------------------------------------------------
42//
43// Observers
44//
45//------------------------------------------------------------------------------
46
47bool
49 ReadView const& view,
51 ExpiryComparison comparison)
52{
53 using d = NetClock::duration;
54 using tp = NetClock::time_point;
55
56 if (!exp)
57 return false;
58 auto const boundary = tp{d{*exp}};
59 return comparison == ExpiryComparison::Inclusive //
60 ? view.parentCloseTime() >= boundary
61 : view.parentCloseTime() > boundary;
62}
63
64bool
66 ReadView const& view,
67 AccountID const& account,
68 MPTIssue const& mptShare,
69 std::uint8_t depth)
70{
71 if (!view.rules().enabled(featureSingleAssetVault))
72 return false;
73
74 if (depth >= kMaxAssetCheckDepth)
75 {
76 // LCOV_EXCL_START
77 UNREACHABLE("xrpl::View::isVaultPseudoAccountFrozen : reached asset check depth");
78 return true;
79 // LCOV_EXCL_STOP
80 }
81
82 auto const mptIssuance = view.read(keylet::mptokenIssuance(mptShare.getMptID()));
83 if (mptIssuance == nullptr)
84 return false; // zero MPToken won't block deletion of MPTokenIssuance
85
86 auto const issuer = mptIssuance->getAccountID(sfIssuer);
87
88 // Post-fixCleanup3_2_0: vault shares carry sfReferenceHolding pointing
89 // to the vault pseudo's MPToken or RippleState for the underlying.
90 // Read it to derive the underlying asset and recurse, skipping the
91 // issuer-account-then-vault chain. Pre-amendment shares (no field)
92 // fall back to the chain lookup below.
93 if (mptIssuance->isFieldPresent(sfReferenceHolding))
94 {
95 auto const sleHolding =
96 view.read(keylet::unchecked(mptIssuance->getFieldH256(sfReferenceHolding)));
97 if (!sleHolding)
98 {
99 // LCOV_EXCL_START
100 UNREACHABLE("xrpl::isVaultPseudoAccountFrozen : dangling sfReferenceHolding");
101 return false;
102 // LCOV_EXCL_STOP
103 }
104 return isAnyFrozen(
105 view, {issuer, account}, assetOfHolding(*mptIssuance, *sleHolding), depth + 1);
106 }
107
108 auto const mptIssuer = view.read(keylet::account(issuer));
109 if (mptIssuer == nullptr)
110 {
111 // LCOV_EXCL_START
112 UNREACHABLE("xrpl::isVaultPseudoAccountFrozen : null MPToken issuer");
113 return false;
114 // LCOV_EXCL_STOP
115 }
116
117 if (!mptIssuer->isFieldPresent(sfVaultID))
118 return false; // not a Vault pseudo-account, common case
119
120 auto const vault = view.read(keylet::vault(mptIssuer->getFieldH256(sfVaultID)));
121 if (vault == nullptr)
122 { // LCOV_EXCL_START
123 UNREACHABLE("xrpl::isVaultPseudoAccountFrozen : null vault");
124 return false;
125 // LCOV_EXCL_STOP
126 }
127
128 return isAnyFrozen(view, {issuer, account}, vault->at(sfAsset), depth + 1);
129}
130
131bool
133 ReadView const& view,
134 AccountID const& account,
135 Asset const& asset,
136 Asset const& asset2)
137{
138 return isFrozen(view, account, asset) || isFrozen(view, account, asset2);
139}
140
141bool
143 ReadView const& validLedger,
144 ReadView const& testLedger,
146 char const* reason)
147{
148 bool ret = true;
149
150 if (validLedger.header().seq < testLedger.header().seq)
151 {
152 // valid -> ... -> test
153 auto hash = hashOfSeq(
154 testLedger, validLedger.header().seq, beast::Journal{beast::Journal::getNullSink()});
155 if (hash && (*hash != validLedger.header().hash))
156 {
157 JLOG(s) << reason << " incompatible with valid ledger";
158
159 JLOG(s) << "Hash(VSeq): " << to_string(*hash);
160
161 ret = false;
162 }
163 }
164 else if (validLedger.header().seq > testLedger.header().seq)
165 {
166 // test -> ... -> valid
167 auto hash = hashOfSeq(
168 validLedger, testLedger.header().seq, beast::Journal{beast::Journal::getNullSink()});
169 if (hash && (*hash != testLedger.header().hash))
170 {
171 JLOG(s) << reason << " incompatible preceding ledger";
172
173 JLOG(s) << "Hash(NSeq): " << to_string(*hash);
174
175 ret = false;
176 }
177 }
178 else if (
179 (validLedger.header().seq == testLedger.header().seq) &&
180 (validLedger.header().hash != testLedger.header().hash))
181 {
182 // Same sequence number, different hash
183 JLOG(s) << reason << " incompatible ledger";
184
185 ret = false;
186 }
187
188 if (!ret)
189 {
190 JLOG(s) << "Val: " << validLedger.header().seq << " "
191 << to_string(validLedger.header().hash);
192
193 JLOG(s) << "New: " << testLedger.header().seq << " " << to_string(testLedger.header().hash);
194 }
195
196 return ret;
197}
198
199bool
201 uint256 const& validHash,
202 LedgerIndex validIndex,
203 ReadView const& testLedger,
205 char const* reason)
206{
207 bool ret = true;
208
209 if (testLedger.header().seq > validIndex)
210 {
211 // Ledger we are testing follows last valid ledger
212 auto hash =
213 hashOfSeq(testLedger, validIndex, beast::Journal{beast::Journal::getNullSink()});
214 if (hash && (*hash != validHash))
215 {
216 JLOG(s) << reason << " incompatible following ledger";
217 JLOG(s) << "Hash(VSeq): " << to_string(*hash);
218
219 ret = false;
220 }
221 }
222 else if ((validIndex == testLedger.header().seq) && (testLedger.header().hash != validHash))
223 {
224 JLOG(s) << reason << " incompatible ledger";
225
226 ret = false;
227 }
228
229 if (!ret)
230 {
231 JLOG(s) << "Val: " << validIndex << " " << to_string(validHash);
232
233 JLOG(s) << "New: " << testLedger.header().seq << " " << to_string(testLedger.header().hash);
234 }
235
236 return ret;
237}
238
241{
242 std::set<uint256> amendments;
243
244 if (auto const sle = view.read(keylet::amendments()))
245 {
246 if (sle->isFieldPresent(sfAmendments))
247 {
248 auto const& v = sle->getFieldV256(sfAmendments);
249 amendments.insert(v.begin(), v.end());
250 }
251 }
252
253 return amendments;
254}
255
258{
260
261 if (auto const sle = view.read(keylet::amendments()))
262 {
263 if (sle->isFieldPresent(sfMajorities))
264 {
265 using tp = NetClock::time_point;
266 using d = tp::duration;
267
268 auto const majorities = sle->getFieldArray(sfMajorities);
269
270 for (auto const& m : majorities)
271 ret[m.getFieldH256(sfAmendment)] = tp(d(m.getFieldU32(sfCloseTime)));
272 }
273 }
274
275 return ret;
276}
277
279hashOfSeq(ReadView const& ledger, LedgerIndex seq, beast::Journal journal)
280{
281 // Easy cases...
282 if (seq > ledger.seq())
283 {
284 JLOG(journal.warn()) << "Can't get seq " << seq << " from " << ledger.seq() << " future";
285 return std::nullopt;
286 }
287 if (seq == ledger.seq())
288 return ledger.header().hash;
289 if (seq == (ledger.seq() - 1))
290 return ledger.header().parentHash;
291
292 if (int const diff = ledger.seq() - seq; diff <= 256)
293 {
294 // Within 256...
295 auto const hashIndex = ledger.read(keylet::skip());
296 if (hashIndex)
297 {
298 XRPL_ASSERT(
299 hashIndex->getFieldU32(sfLastLedgerSequence) == (ledger.seq() - 1),
300 "xrpl::hashOfSeq : matching ledger sequence");
301 STVector256 vec = hashIndex->getFieldV256(sfHashes);
302 if (vec.size() >= diff)
303 return vec[vec.size() - diff];
304 JLOG(journal.warn()) << "Ledger " << ledger.seq() << " missing hash for " << seq << " ("
305 << vec.size() << "," << diff << ")";
306 }
307 else
308 {
309 JLOG(journal.warn()) << "Ledger " << ledger.seq() << ":" << ledger.header().hash
310 << " missing normal list";
311 }
312 }
313
314 if ((seq & 0xff) != 0)
315 {
316 JLOG(journal.debug()) << "Can't get seq " << seq << " from " << ledger.seq() << " past";
317 return std::nullopt;
318 }
319
320 // in skiplist
321 auto const hashIndex = ledger.read(keylet::skip(seq));
322 if (hashIndex)
323 {
324 auto const lastSeq = hashIndex->getFieldU32(sfLastLedgerSequence);
325 XRPL_ASSERT(lastSeq >= seq, "xrpl::hashOfSeq : minimum last ledger");
326 XRPL_ASSERT((lastSeq & 0xff) == 0, "xrpl::hashOfSeq : valid last ledger");
327 auto const diff = (lastSeq - seq) >> 8;
328 STVector256 vec = hashIndex->getFieldV256(sfHashes);
329 if (vec.size() > diff)
330 return vec[vec.size() - diff - 1];
331 }
332 JLOG(journal.warn()) << "Can't get seq " << seq << " from " << ledger.seq() << " error";
333 return std::nullopt;
334}
335
336//------------------------------------------------------------------------------
337//
338// Modifiers
339//
340//------------------------------------------------------------------------------
341
342TER
343dirLink(ApplyView& view, AccountID const& owner, SLE::pointer& object, SF_UINT64 const& node)
344{
345 auto const page =
346 view.dirInsert(keylet::ownerDir(owner), object->key(), describeOwnerDir(owner));
347 if (!page)
348 return tecDIR_FULL; // LCOV_EXCL_LINE
349 object->setFieldU64(node, *page);
350 return tesSUCCESS;
351}
352
353/*
354 * Checks if a withdrawal amount into the destination account exceeds
355 * any applicable receiving limit.
356 * Called by VaultWithdraw and LoanBrokerCoverWithdraw.
357 *
358 * IOU : Performs the trustline check against the destination account's
359 * credit limit to ensure the account's trust maximum is not exceeded.
360 *
361 * MPT: The limit check is effectively skipped (returns true). This is
362 * because MPT MaximumAmount relates to token supply, and withdrawal does not
363 * involve minting new tokens that could exceed the global cap.
364 * On withdrawal, tokens are simply transferred from the vault's pseudo-account
365 * to the destination account. Since no new MPT tokens are minted during this
366 * transfer, the withdrawal cannot violate the MPT MaximumAmount/supply cap
367 * even if `from` is the issuer.
368 */
369static TER
371 ReadView const& view,
372 AccountID const& from,
373 AccountID const& to,
374 STAmount const& amount)
375{
376 auto const& issuer = amount.getIssuer();
377 if (from == to || to == issuer || isXRP(issuer))
378 return tesSUCCESS;
379
380 return amount.asset().visit(
381 [&](Issue const& issue) -> TER {
382 auto const& currency = issue.currency;
383 auto const owed = creditBalance(view, to, issuer, currency);
384 if (owed <= beast::kZero)
385 {
386 auto const limit = creditLimit(view, to, issuer, currency);
387 if (-owed >= limit || amount > (limit + owed))
388 return tecNO_LINE;
389 }
390 return tesSUCCESS;
391 },
392 [](MPTIssue const&) -> TER { return tesSUCCESS; });
393}
394
395[[nodiscard]] TER
397 ReadView const& view,
398 AccountID const& from,
399 AccountID const& to,
400 SLE::const_ref toSle,
401 STAmount const& amount,
402 bool hasDestinationTag)
403{
404 if (auto const ret = checkDestinationAndTag(toSle, hasDestinationTag))
405 return ret;
406
407 if (from == to)
408 return tesSUCCESS;
409
410 if (toSle->isFlag(lsfDepositAuth))
411 {
412 if (!view.exists(keylet::depositPreauth(to, from)))
413 return tecNO_PERMISSION;
414 }
415
416 return withdrawToDestExceedsLimit(view, from, to, amount);
417}
418
419[[nodiscard]] TER
421 ReadView const& view,
422 AccountID const& from,
423 AccountID const& to,
424 STAmount const& amount,
425 bool hasDestinationTag)
426{
427 auto const toSle = view.read(keylet::account(to));
428
429 return canWithdraw(view, from, to, toSle, amount, hasDestinationTag);
430}
431
432[[nodiscard]] TER
433canWithdraw(ReadView const& view, STTx const& tx)
434{
435 auto const from = tx[sfAccount];
436 auto const to = tx[~sfDestination].value_or(from);
437
438 return canWithdraw(view, from, to, tx[sfAmount], tx.isFieldPresent(sfDestinationTag));
439}
440
441TER
444 AccountID const& senderAcct,
445 AccountID const& dstAcct,
446 AccountID const& sourceAcct,
447 XRPAmount priorBalance,
448 STAmount const& amount,
450{
451 auto const dstSle = ctx.view.read(keylet::account(dstAcct));
452
453 // Create trust line or MPToken for the receiving account
454 if (dstAcct == senderAcct)
455 {
456 if (auto const ter = addEmptyHolding(ctx, senderAcct, priorBalance, amount.asset(), j);
457 !isTesSuccess(ter) && ter != tecDUPLICATE)
458 return ter;
459 }
460 else
461 {
462 if (auto err = verifyDepositPreauth(ctx.tx, ctx.view, senderAcct, dstAcct, dstSle, j))
463 return err;
464 }
465
466 // Sanity check
467 if (accountHolds(
468 ctx.view,
469 sourceAcct,
470 amount.asset(),
473 j) < amount)
474 {
475 // LCOV_EXCL_START
476 JLOG(j.error()) << "doWithdraw: negative balance of broker cover assets.";
477 return tefINTERNAL;
478 // LCOV_EXCL_STOP
479 }
480
481 // A reserve sponsor only covers tx.Account's own objects, so resolve the
482 // sponsor against the destination. accountSend can auto-create a holding
483 // for dstAcct; keying on the destination ensures a third-party destination's
484 // holding is never stamped with the tx's reserve sponsor.
485 auto const sponsorSle = getEffectiveTxReserveSponsor(ctx, dstSle);
486 if (!sponsorSle)
487 return sponsorSle.error(); // LCOV_EXCL_LINE
488
489 // Move the funds directly from the broker's pseudo-account to the
490 // dstAcct
491 return accountSend(
492 ctx.view, sourceAcct, dstAcct, amount, j, *sponsorSle, WaiveTransferFee::Yes);
493}
494
495TER
497 ApplyView& view,
498 Keylet const& ownerDirKeylet,
499 EntryDeleter const& deleter,
501 std::optional<uint16_t> maxNodesToDelete)
502{
503 // Delete all the entries in the account directory.
504 SLE::pointer sleDirNode{};
505 unsigned int uDirEntry{0};
506 uint256 dirEntry{beast::kZero};
507 std::uint32_t deleted = 0;
508
509 if (view.exists(ownerDirKeylet) &&
510 dirFirst(view, ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry))
511 {
512 do
513 {
514 if (maxNodesToDelete && ++deleted > *maxNodesToDelete)
515 return tecINCOMPLETE;
516
517 // Choose the right way to delete each directory node.
518 auto sleItem = view.peek(keylet::child(dirEntry));
519 if (!sleItem)
520 {
521 // Directory node has an invalid index. Bail out.
522 // LCOV_EXCL_START
523 JLOG(j.fatal()) << "DeleteAccount: Directory node in ledger " << view.seq()
524 << " has index to object that is missing: " << to_string(dirEntry);
525 return tefBAD_LEDGER;
526 // LCOV_EXCL_STOP
527 }
528
529 LedgerEntryType const nodeType{
530 safeCast<LedgerEntryType>(sleItem->getFieldU16(sfLedgerEntryType))};
531
532 // Deleter handles the details of specific account-owned object
533 // deletion
534 auto const [ter, skipEntry] = deleter(nodeType, dirEntry, sleItem);
535 if (!isTesSuccess(ter))
536 return ter;
537
538 // dirFirst() and dirNext() are like iterators with exposed
539 // internal state. We'll take advantage of that exposed state
540 // to solve a common C++ problem: iterator invalidation while
541 // deleting elements from a container.
542 //
543 // We have just deleted one directory entry, which means our
544 // "iterator state" is invalid.
545 //
546 // 1. During the process of getting an entry from the
547 // directory uDirEntry was incremented from 'it' to 'it'+1.
548 //
549 // 2. We then deleted the entry at index 'it', which means the
550 // entry that was at 'it'+1 has now moved to 'it'.
551 //
552 // 3. So we verify that uDirEntry is indeed 'it'+1. Then we jam it
553 // back to 'it' to "un-invalidate" the iterator.
554 XRPL_ASSERT(uDirEntry >= 1, "xrpl::cleanupOnAccountDelete : minimum dir entries");
555 if (uDirEntry == 0)
556 {
557 // LCOV_EXCL_START
558 JLOG(j.error()) << "DeleteAccount iterator re-validation failed.";
559 return tefBAD_LEDGER;
560 // LCOV_EXCL_STOP
561 }
562 if (skipEntry == SkipEntry::No)
563 uDirEntry--;
564
565 } while (dirNext(view, ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry));
566 }
567
568 return tesSUCCESS;
569}
570
571bool
573{
574 return now.time_since_epoch().count() > mark;
575}
576
577} // namespace xrpl
Provide a light-weight way to check active() before string formatting.
Definition Journal.h:199
A generic endpoint for log messages.
Definition Journal.h:44
Stream fatal() const
Definition Journal.h:368
Stream error() const
Definition Journal.h:362
Stream debug() const
Definition Journal.h:344
static Sink & getNullSink()
Returns a Sink which does nothing.
Stream warn() const
Definition Journal.h:356
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:134
virtual SLE::pointer peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(SLE::ref)> const &describe)
Insert an entry to a directory.
Definition ApplyView.h:366
constexpr auto visit(Visitors &&... visitors) const -> decltype(auto)
Definition Asset.h:117
A currency issued by an account.
Definition Issue.h:18
Currency currency
Definition Issue.h:20
constexpr MPTID const & getMptID() const
Definition MPTIssue.h:43
std::chrono::time_point< NetClock > time_point
Definition chrono.h:48
std::chrono::duration< rep, period > duration
Definition chrono.h:47
A view into a ledger.
Definition ReadView.h:41
virtual Rules const & rules() const =0
Returns the tx processing rules.
NetClock::time_point parentCloseTime() const
Returns the close time of the previous ledger.
Definition ReadView.h:106
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
virtual LedgerHeader const & header() const =0
Returns information about the ledger.
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition ReadView.h:115
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:180
Asset const & asset() const
Definition STAmount.h:496
AccountID const & getIssuer() const
Definition STAmount.h:516
uint256 const & key() const
Returns the 'key' (or 'index') of this item.
std::shared_ptr< STLedgerEntry > pointer
std::shared_ptr< STLedgerEntry const > const & const_ref
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:464
std::size_t size() const
constexpr Zero kZero
Definition Zero.h:30
Keylet const & skip() noexcept
The index of the "short" skip list.
Definition Indexes.cpp:210
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition Indexes.cpp:367
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition Indexes.cpp:344
Keylet const & amendments() noexcept
The index of the amendment table.
Definition Indexes.cpp:226
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:373
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Definition Indexes.cpp:204
Keylet vault(AccountID const &owner, SeqProxy const &seq) noexcept
Definition Indexes.cpp:561
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:198
Keylet mptokenIssuance(MPTID const &issuanceID) noexcept
Definition Indexes.cpp:537
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool hasExpired(ReadView const &view, std::optional< std::uint32_t > const &exp, ExpiryComparison comparison=ExpiryComparison::Inclusive)
Determines whether the given expiration time has passed.
Definition View.cpp:48
TypedField< STInteger< std::uint64_t > > SF_UINT64
Definition SField.h:342
bool isXRP(AccountID const &c)
Definition AccountID.h:84
std::set< uint256 > getEnabledAmendments(ReadView const &view)
Definition View.cpp:240
TER accountSend(ApplyView &view, AccountID const &from, AccountID const &to, STAmount const &saAmount, beast::Journal j, SLE::ref sponsorSle={}, WaiveTransferFee waiveFee=WaiveTransferFee::No, AllowMPTOverflow allowOverflow=AllowMPTOverflow::No)
Calls static accountSendIOU if saAmount represents Issue.
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:370
@ tefBAD_LEDGER
Definition TER.h:162
@ tefINTERNAL
Definition TER.h:165
TER addEmptyHolding(ApplyViewContext ctx, AccountID const &accountID, XRPAmount priorBalance, MPTIssue const &mptIssue, beast::Journal journal)
ExpiryComparison
Whether an expiration check should be inclusive or exclusive.
Definition View.h:41
bool dirNext(ApplyView &view, uint256 const &root, SLE::pointer &page, unsigned int &index, uint256 &entry)
Asset assetOfHolding(SLE const &sleShareIssuance, SLE const &sleHolding)
Resolve the underlying asset of a vault share.
STAmount creditLimit(ReadView const &view, AccountID const &account, AccountID const &issuer, Currency const &currency)
Calculate the maximum amount of IOUs that an account can hold.
constexpr Dest safeCast(Src s) noexcept
Definition safe_cast.h:21
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
bool isVaultPseudoAccountFrozen(ReadView const &view, AccountID const &account, MPTIssue const &mptShare, std::uint8_t depth)
Definition View.cpp:65
bool areCompatible(ReadView const &validLedger, ReadView const &testLedger, beast::Journal::Stream &s, char const *reason)
Return false if the test ledger is provably incompatible with the valid ledger, that is,...
Definition View.cpp:142
std::expected< SLE::pointer, TER > getEffectiveTxReserveSponsor(ApplyViewContext ctx, SLE::const_ref accountSle)
The transaction's reserve sponsor for the given account, if applicable.
TER doWithdraw(ApplyViewContext ctx, AccountID const &senderAcct, AccountID const &dstAcct, AccountID const &sourceAcct, XRPAmount priorBalance, STAmount const &amount, beast::Journal j)
Definition View.cpp:442
std::optional< uint256 > hashOfSeq(ReadView const &ledger, LedgerIndex seq, beast::Journal journal)
Return the hash of a ledger by sequence.
Definition View.cpp:279
constexpr std::uint8_t kMaxAssetCheckDepth
Maximum recursion depth for vault shares being put as an asset inside another vault; counted from 0.
Definition Protocol.h:365
TER dirLink(ApplyView &view, AccountID const &owner, SLE::pointer &object, SF_UINT64 const &node=sfOwnerNode)
Definition View.cpp:343
static TER withdrawToDestExceedsLimit(ReadView const &view, AccountID const &from, AccountID const &to, STAmount const &amount)
Definition View.cpp:370
majorityAmendments_t getMajorityAmendments(ReadView const &view)
Definition View.cpp:257
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:572
STAmount creditBalance(ReadView const &view, AccountID const &account, AccountID const &issuer, Currency const &currency)
Returns the amount of IOUs issued by issuer that are held by an account.
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Returns a function that sets the owner on a directory SLE.
bool isFrozen(ReadView const &view, AccountID const &account, MPTIssue const &mptIssue, std::uint8_t depth=0)
std::map< uint256, NetClock::time_point > majorityAmendments_t
Definition View.h:93
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
bool isTesSuccess(TER x) noexcept
Definition TER.h:676
bool isAnyFrozen(ReadView const &view, std::initializer_list< AccountID > const &accounts, MPTIssue const &mptIssue, std::uint8_t depth=0)
TERSubset< CanCvtToTER > TER
Definition TER.h:647
bool isLPTokenFrozen(ReadView const &view, AccountID const &account, Asset const &asset, Asset const &asset2)
Definition View.cpp:132
std::function< std::pair< TER, SkipEntry >(LedgerEntryType, uint256 const &, SLE::pointer &)> EntryDeleter
Deleter function prototype.
Definition View.h:243
LedgerEntryType
Identifiers for on-ledger objects.
@ tecDIR_FULL
Definition TER.h:290
@ tecINCOMPLETE
Definition TER.h:338
@ tecNO_LINE
Definition TER.h:304
@ tecNO_PERMISSION
Definition TER.h:308
@ tecDUPLICATE
Definition TER.h:318
TER canWithdraw(ReadView const &view, AccountID const &from, AccountID const &to, SLE::const_ref toSle, STAmount const &amount, bool hasDestinationTag)
Checks that can withdraw funds from an object to itself or a destination.
Definition View.cpp:396
TER checkDestinationAndTag(SLE::const_ref toSle, bool hasDestinationTag)
Checks the destination and tag.
BaseUInt< 256 > uint256
Definition base_uint.h:580
bool dirFirst(ApplyView &view, uint256 const &root, SLE::pointer &page, unsigned int &index, uint256 &entry)
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j, SpendableHandling includeFullBalance=SpendableHandling::SimpleBalance)
@ tesSUCCESS
Definition TER.h:245
TER cleanupOnAccountDelete(ApplyView &view, Keylet const &ownerDirKeylet, EntryDeleter const &deleter, beast::Journal j, std::optional< std::uint16_t > maxNodesToDelete=std::nullopt)
Cleanup owner directory entries on account delete.
TER verifyDepositPreauth(STTx const &tx, ApplyView &view, AccountID const &src, AccountID const &dst, SLE::const_ref sleDst, beast::Journal j)
Bundles the mutable ledger view and the transaction being applied.
Definition ApplyView.h:444
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20
uint256 key
Definition Keylet.h:21
T time_since_epoch(T... args)