rippled
DeleteAccount.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2019 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/app/tx/impl/DeleteAccount.h>
21 #include <ripple/app/tx/impl/DepositPreauth.h>
22 #include <ripple/app/tx/impl/SetSignerList.h>
23 #include <ripple/app/tx/impl/details/NFTokenUtils.h>
24 #include <ripple/basics/FeeUnits.h>
25 #include <ripple/basics/Log.h>
26 #include <ripple/basics/mulDiv.h>
27 #include <ripple/ledger/View.h>
28 #include <ripple/protocol/Feature.h>
29 #include <ripple/protocol/Indexes.h>
30 #include <ripple/protocol/Protocol.h>
31 #include <ripple/protocol/TxFlags.h>
32 #include <ripple/protocol/st.h>
33 
34 namespace ripple {
35 
36 NotTEC
38 {
40  return temDISABLED;
41 
42  if (ctx.tx.getFlags() & tfUniversalMask)
43  return temINVALID_FLAG;
44 
45  if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
46  return ret;
47 
48  if (ctx.tx[sfAccount] == ctx.tx[sfDestination])
49  // An account cannot be deleted and give itself the resulting XRP.
50  return temDST_IS_SRC;
51 
52  return preflight2(ctx);
53 }
54 
57 {
58  // The fee required for AccountDelete is one owner reserve. But the
59  // owner reserve is stored in drops. We need to convert it to fee units.
60  Fees const& fees{view.fees()};
61  std::pair<bool, FeeUnit64> const mulDivResult{
62  mulDiv(fees.increment, safe_cast<FeeUnit64>(fees.units), fees.base)};
63  if (mulDivResult.first)
64  return mulDivResult.second;
65 
66  // If mulDiv returns false then overflow happened. Punt by using the
67  // standard calculation.
69 }
70 
71 namespace {
72 // Define a function pointer type that can be used to delete ledger node types.
73 using DeleterFuncPtr = TER (*)(
74  Application& app,
75  ApplyView& view,
76  AccountID const& account,
77  uint256 const& delIndex,
78  std::shared_ptr<SLE> const& sleDel,
79  beast::Journal j);
80 
81 // Local function definitions that provides signature compatibility.
82 TER
84  Application& app,
85  ApplyView& view,
86  AccountID const& account,
87  uint256 const& delIndex,
88  std::shared_ptr<SLE> const& sleDel,
90 {
91  return offerDelete(view, sleDel, j);
92 }
93 
94 TER
96  Application& app,
97  ApplyView& view,
98  AccountID const& account,
99  uint256 const& delIndex,
100  std::shared_ptr<SLE> const& sleDel,
101  beast::Journal j)
102 {
103  return SetSignerList::removeFromLedger(app, view, account, j);
104 }
105 
106 TER
107 removeTicketFromLedger(
108  Application&,
109  ApplyView& view,
110  AccountID const& account,
111  uint256 const& delIndex,
112  std::shared_ptr<SLE> const&,
113  beast::Journal j)
114 {
115  return Transactor::ticketDelete(view, account, delIndex, j);
116 }
117 
118 TER
119 removeDepositPreauthFromLedger(
120  Application& app,
121  ApplyView& view,
122  AccountID const& account,
123  uint256 const& delIndex,
124  std::shared_ptr<SLE> const& sleDel,
125  beast::Journal j)
126 {
127  return DepositPreauth::removeFromLedger(app, view, delIndex, j);
128 }
129 
130 TER
131 removeNFTokenOfferFromLedger(
132  Application& app,
133  ApplyView& view,
134  AccountID const& account,
135  uint256 const& delIndex,
136  std::shared_ptr<SLE> const& sleDel,
138 {
139  if (!nft::deleteTokenOffer(view, sleDel))
140  return tefBAD_LEDGER;
141 
142  return tesSUCCESS;
143 }
144 
145 // Return nullptr if the LedgerEntryType represents an obligation that can't
146 // be deleted. Otherwise return the pointer to the function that can delete
147 // the non-obligation
148 DeleterFuncPtr
149 nonObligationDeleter(LedgerEntryType t)
150 {
151  switch (t)
152  {
153  case ltOFFER:
154  return offerDelete;
155  case ltSIGNER_LIST:
157  case ltTICKET:
158  return removeTicketFromLedger;
159  case ltDEPOSIT_PREAUTH:
160  return removeDepositPreauthFromLedger;
161  case ltNFTOKEN_OFFER:
162  return removeNFTokenOfferFromLedger;
163  default:
164  return nullptr;
165  }
166 }
167 
168 } // namespace
169 
170 TER
172 {
173  AccountID const account{ctx.tx[sfAccount]};
174  AccountID const dst{ctx.tx[sfDestination]};
175 
176  auto sleDst = ctx.view.read(keylet::account(dst));
177 
178  if (!sleDst)
179  return tecNO_DST;
180 
181  if ((*sleDst)[sfFlags] & lsfRequireDestTag && !ctx.tx[~sfDestinationTag])
182  return tecDST_TAG_NEEDED;
183 
184  // Check whether the destination account requires deposit authorization.
185  if (ctx.view.rules().enabled(featureDepositAuth) &&
186  (sleDst->getFlags() & lsfDepositAuth))
187  {
188  if (!ctx.view.exists(keylet::depositPreauth(dst, account)))
189  return tecNO_PERMISSION;
190  }
191 
192  auto sleAccount = ctx.view.read(keylet::account(account));
193  assert(sleAccount);
194  if (!sleAccount)
195  return terNO_ACCOUNT;
196 
198  {
199  // If an issuer has any issued NFTs resident in the ledger then it
200  // cannot be deleted.
201  if ((*sleAccount)[~sfMintedNFTokens] !=
202  (*sleAccount)[~sfBurnedNFTokens])
203  return tecHAS_OBLIGATIONS;
204 
205  // If the account owns any NFTs it cannot be deleted.
206  Keylet const first = keylet::nftpage_min(account);
207  Keylet const last = keylet::nftpage_max(account);
208 
209  auto const cp = ctx.view.read(Keylet(
211  ctx.view.succ(first.key, last.key.next()).value_or(last.key)));
212  if (cp)
213  return tecHAS_OBLIGATIONS;
214  }
215 
216  // We don't allow an account to be deleted if its sequence number
217  // is within 256 of the current ledger. This prevents replay of old
218  // transactions if this account is resurrected after it is deleted.
219  //
220  // We look at the account's Sequence rather than the transaction's
221  // Sequence in preparation for Tickets.
222  constexpr std::uint32_t seqDelta{255};
223  if ((*sleAccount)[sfSequence] + seqDelta > ctx.view.seq())
224  return tecTOO_SOON;
225 
226  // Verify that the account does not own any objects that would prevent
227  // the account from being deleted.
228  Keylet const ownerDirKeylet{keylet::ownerDir(account)};
229  if (dirIsEmpty(ctx.view, ownerDirKeylet))
230  return tesSUCCESS;
231 
232  std::shared_ptr<SLE const> sleDirNode{};
233  unsigned int uDirEntry{0};
234  uint256 dirEntry{beast::zero};
235 
236  // Account has no directory at all. This _should_ have been caught
237  // by the dirIsEmpty() check earlier, but it's okay to catch it here.
238  if (!cdirFirst(
239  ctx.view, ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry))
240  return tesSUCCESS;
241 
242  std::int32_t deletableDirEntryCount{0};
243  do
244  {
245  // Make sure any directory node types that we find are the kind
246  // we can delete.
247  auto sleItem = ctx.view.read(keylet::child(dirEntry));
248  if (!sleItem)
249  {
250  // Directory node has an invalid index. Bail out.
251  JLOG(ctx.j.fatal())
252  << "DeleteAccount: directory node in ledger " << ctx.view.seq()
253  << " has index to object that is missing: "
254  << to_string(dirEntry);
255  return tefBAD_LEDGER;
256  }
257 
258  LedgerEntryType const nodeType{
259  safe_cast<LedgerEntryType>((*sleItem)[sfLedgerEntryType])};
260 
261  if (!nonObligationDeleter(nodeType))
262  return tecHAS_OBLIGATIONS;
263 
264  // We found a deletable directory entry. Count it. If we find too
265  // many deletable directory entries then bail out.
266  if (++deletableDirEntryCount > maxDeletableDirEntries)
267  return tefTOO_BIG;
268 
269  } while (cdirNext(
270  ctx.view, ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry));
271 
272  return tesSUCCESS;
273 }
274 
275 TER
277 {
278  auto src = view().peek(keylet::account(account_));
279  assert(src);
280 
281  auto dst = view().peek(keylet::account(ctx_.tx[sfDestination]));
282  assert(dst);
283 
284  if (!src || !dst)
285  return tefBAD_LEDGER;
286 
287  // Delete all of the entries in the account directory.
288  Keylet const ownerDirKeylet{keylet::ownerDir(account_)};
289  std::shared_ptr<SLE> sleDirNode{};
290  unsigned int uDirEntry{0};
291  uint256 dirEntry{beast::zero};
292 
293  if (view().exists(ownerDirKeylet) &&
294  dirFirst(view(), ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry))
295  {
296  do
297  {
298  // Choose the right way to delete each directory node.
299  auto sleItem = view().peek(keylet::child(dirEntry));
300  if (!sleItem)
301  {
302  // Directory node has an invalid index. Bail out.
303  JLOG(j_.fatal())
304  << "DeleteAccount: Directory node in ledger "
305  << view().seq() << " has index to object that is missing: "
306  << to_string(dirEntry);
307  return tefBAD_LEDGER;
308  }
309 
310  LedgerEntryType const nodeType{safe_cast<LedgerEntryType>(
311  sleItem->getFieldU16(sfLedgerEntryType))};
312 
313  if (auto deleter = nonObligationDeleter(nodeType))
314  {
315  TER const result{
316  deleter(ctx_.app, view(), account_, dirEntry, sleItem, j_)};
317 
318  if (!isTesSuccess(result))
319  return result;
320  }
321  else
322  {
323  assert(!"Undeletable entry should be found in preclaim.");
324  JLOG(j_.error())
325  << "DeleteAccount undeletable item not found in preclaim.";
326  return tecHAS_OBLIGATIONS;
327  }
328 
329  // dirFirst() and dirNext() are like iterators with exposed
330  // internal state. We'll take advantage of that exposed state
331  // to solve a common C++ problem: iterator invalidation while
332  // deleting elements from a container.
333  //
334  // We have just deleted one directory entry, which means our
335  // "iterator state" is invalid.
336  //
337  // 1. During the process of getting an entry from the
338  // directory uDirEntry was incremented from 0 to 1.
339  //
340  // 2. We then deleted the entry at index 0, which means the
341  // entry that was at 1 has now moved to 0.
342  //
343  // 3. So we verify that uDirEntry is indeed 1. Then we jam it
344  // back to zero to "un-invalidate" the iterator.
345  assert(uDirEntry == 1);
346  if (uDirEntry != 1)
347  {
348  JLOG(j_.error())
349  << "DeleteAccount iterator re-validation failed.";
350  return tefBAD_LEDGER;
351  }
352  uDirEntry = 0;
353 
354  } while (dirNext(
355  view(), ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry));
356  }
357 
358  // Transfer any XRP remaining after the fee is paid to the destination:
359  (*dst)[sfBalance] = (*dst)[sfBalance] + mSourceBalance;
360  (*src)[sfBalance] = (*src)[sfBalance] - mSourceBalance;
362 
363  assert((*src)[sfBalance] == XRPAmount(0));
364 
365  // If there's still an owner directory associated with the source account
366  // delete it.
367  if (view().exists(ownerDirKeylet) && !view().emptyDirDelete(ownerDirKeylet))
368  {
369  JLOG(j_.error()) << "DeleteAccount cannot delete root dir node of "
370  << toBase58(account_);
371  return tecHAS_OBLIGATIONS;
372  }
373 
374  // Re-arm the password change fee if we can and need to.
375  if (mSourceBalance > XRPAmount(0) && dst->isFlag(lsfPasswordSpent))
376  dst->clearFlag(lsfPasswordSpent);
377 
378  view().update(dst);
379  view().erase(src);
380 
381  return tesSUCCESS;
382 }
383 
384 } // namespace ripple
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:339
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:303
ripple::Application
Definition: Application.h:115
ripple::cdirNext
bool cdirNext(ReadView const &view, uint256 const &root, std::shared_ptr< SLE const > &page, unsigned int &index, uint256 &entry)
Returns the next entry in the directory, advancing the index.
Definition: View.cpp:145
ripple::dirNext
bool dirNext(ApplyView &view, uint256 const &root, std::shared_ptr< SLE > &page, unsigned int &index, uint256 &entry)
Definition: View.cpp:123
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:109
ripple::ltTICKET
@ ltTICKET
A ledger object which describes a ticket.
Definition: LedgerFormats.h:80
ripple::lsfPasswordSpent
@ lsfPasswordSpent
Definition: LedgerFormats.h:223
ripple::Keylet
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:38
ripple::Rules::enabled
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition: Rules.cpp:81
std::shared_ptr
STL class.
ripple::PreclaimContext::view
ReadView const & view
Definition: Transactor.h:56
ripple::PreclaimContext::j
const beast::Journal j
Definition: Transactor.h:60
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
ripple::sfDestination
const SF_ACCOUNT sfDestination
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:89
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:594
std::pair
ripple::sfSequence
const SF_UINT32 sfSequence
ripple::ApplyView::erase
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::ltSIGNER_LIST
@ ltSIGNER_LIST
A ledger object which contains a signer list for an account.
Definition: LedgerFormats.h:86
ripple::sfMintedNFTokens
const SF_UINT32 sfMintedNFTokens
ripple::featureDepositAuth
const uint256 featureDepositAuth
ripple::tecDST_TAG_NEEDED
@ tecDST_TAG_NEEDED
Definition: TER.h:273
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:104
ripple::DeleteAccount::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: DeleteAccount.cpp:37
ripple::keylet::child
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Definition: Indexes.cpp:139
ripple::ApplyView::update
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
ripple::DeleteAccount::doApply
TER doApply() override
Definition: DeleteAccount.cpp:276
ripple::base_uint::next
base_uint next() const
Definition: base_uint.h:447
ripple::DeleteAccount::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition: DeleteAccount.cpp:171
ripple::temDST_IS_SRC
@ temDST_IS_SRC
Definition: TER.h:103
ripple::Transactor::ticketDelete
static TER ticketDelete(ApplyView &view, AccountID const &account, uint256 const &ticketIndex, beast::Journal j)
Definition: Transactor.cpp:362
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:57
ripple::lsfDepositAuth
@ lsfDepositAuth
Definition: LedgerFormats.h:234
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition: ApplyView.h:134
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:47
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:549
ripple::featureDeletableAccounts
const uint256 featureDeletableAccounts
ripple::DeleteAccount::calculateBaseFee
static FeeUnit64 calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: DeleteAccount.cpp:56
ripple::Keylet::key
uint256 key
Definition: Keylet.h:40
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:81
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:106
ripple::keylet::nftpage_min
Keylet nftpage_min(AccountID const &owner)
NFT page keylets.
Definition: Indexes.cpp:332
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition: TER.h:149
ripple::DepositPreauth::removeFromLedger
static TER removeFromLedger(Application &app, ApplyView &view, uint256 const &delIndex, beast::Journal j)
Definition: DepositPreauth.cpp:166
ripple::ltOFFER
@ ltOFFER
A ledger object which describes an offer on the DEX.
Definition: LedgerFormats.h:92
ripple::Fees
Reflects the fee settings for a particular ledger.
Definition: ReadView.h:49
ripple::maxDeletableDirEntries
constexpr std::size_t maxDeletableDirEntries
The maximum number of owner directory entries for account to be deletable.
Definition: Protocol.h:64
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:133
ripple::offerDelete
TER offerDelete(ApplyView &view, std::shared_ptr< SLE > const &sle, beast::Journal j)
Delete an offer.
Definition: View.cpp:893
ripple::ltNFTOKEN_OFFER
@ ltNFTOKEN_OFFER
A ledger object which identifies an offer to buy or sell an NFT.
Definition: LedgerFormats.h:162
ripple::TERSubset< CanCvtToTER >
ripple::TER
TERSubset< CanCvtToTER > TER
Definition: TER.h:565
ripple::ltDEPOSIT_PREAUTH
@ ltDEPOSIT_PREAUTH
A ledger object which describes a deposit preauthorization.
Definition: LedgerFormats.h:142
ripple::keylet::nftpage_max
Keylet nftpage_max(AccountID const &owner)
A keylet for the owner's last possible NFT page.
Definition: Indexes.cpp:340
beast::Journal::error
Stream error() const
Definition: Journal.h:333
ripple::ReadView::exists
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:481
ripple::STTx
Definition: STTx.h:45
ripple::SetSignerList::removeFromLedger
static TER removeFromLedger(Application &app, ApplyView &view, AccountID const &account, beast::Journal j)
Definition: SetSignerList.cpp:229
ripple::Transactor::calculateBaseFee
static FeeUnit64 calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Transactor.cpp:141
ripple::ApplyContext::deliver
void deliver(STAmount const &amount)
Sets the DeliveredAmount field in the metadata.
Definition: ApplyContext.h:74
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint32_t
ripple::ReadView::succ
virtual std::optional< key_type > succ(key_type const &key, std::optional< key_type > const &last=std::nullopt) const =0
Return the key of the next state item.
ripple::feeunit::TaggedFee
Definition: FeeUnits.h:70
ripple::ReadView::read
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
ripple::PreclaimContext::tx
STTx const & tx
Definition: Transactor.h:58
ripple::lsfRequireDestTag
@ lsfRequireDestTag
Definition: LedgerFormats.h:224
ripple::terNO_ACCOUNT
@ terNO_ACCOUNT
Definition: TER.h:195
ripple::PreclaimContext
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:52
ripple::tecTOO_SOON
@ tecTOO_SOON
Definition: TER.h:282
ripple::dirIsEmpty
bool dirIsEmpty(ReadView const &view, Keylet const &k)
Returns true if the directory is empty.
Definition: View.cpp:590
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:135
ripple::ltNFTOKEN_PAGE
@ ltNFTOKEN_PAGE
A ledger object which contains a list of NFTs.
Definition: LedgerFormats.h:156
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::featureNonFungibleTokensV1
const uint256 featureNonFungibleTokensV1
ripple::dirFirst
bool dirFirst(ApplyView &view, uint256 const &root, std::shared_ptr< SLE > &page, unsigned int &index, uint256 &entry)
Definition: View.cpp:112
ripple::sfLedgerEntryType
const SF_UINT16 sfLedgerEntryType
ripple::LedgerEntryType
LedgerEntryType
Identifiers for on-ledger objects.
Definition: LedgerFormats.h:53
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:107
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:109
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:203
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::sfDestinationTag
const SF_UINT32 sfDestinationTag
ripple::tefTOO_BIG
@ tefTOO_BIG
Definition: TER.h:163
ripple::tecHAS_OBLIGATIONS
@ tecHAS_OBLIGATIONS
Definition: TER.h:281
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:269
ripple::Transactor::mSourceBalance
XRPAmount mSourceBalance
Definition: Transactor.h:93
ripple::sfBalance
const SF_AMOUNT sfBalance
ripple::removeSignersFromLedger
static TER removeSignersFromLedger(Application &app, ApplyView &view, Keylet const &accountKeylet, Keylet const &ownerDirKeylet, Keylet const &signerListKeylet, beast::Journal j)
Definition: SetSignerList.cpp:180
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:88
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::mulDiv
std::pair< bool, Dest > mulDiv(Source1 value, Dest mul, Source2 div)
Definition: FeeUnits.h:473
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:35
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:31
ripple::sfBurnedNFTokens
const SF_UINT32 sfBurnedNFTokens
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:36
ripple::cdirFirst
bool cdirFirst(ReadView const &view, uint256 const &root, std::shared_ptr< SLE const > &page, unsigned int &index, uint256 &entry)
Returns the first entry in the directory, advancing the index.
Definition: View.cpp:134
ripple::tfUniversalMask
constexpr std::uint32_t tfUniversalMask
Definition: TxFlags.h:58
ripple::keylet::depositPreauth
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition: Indexes.cpp:287
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:219
ripple::Transactor::account_
const AccountID account_
Definition: Transactor.h:91
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::AccountID
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition: AccountID.h:47
ripple::nft::deleteTokenOffer
bool deleteTokenOffer(ApplyView &view, std::shared_ptr< SLE > const &offer)
Deletes the given token offer.
Definition: NFTokenUtils.cpp:581
ripple::tecNO_DST
@ tecNO_DST
Definition: TER.h:254
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:525