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.
59  return view.fees().increment;
60 }
61 
62 namespace {
63 // Define a function pointer type that can be used to delete ledger node types.
64 using DeleterFuncPtr = TER (*)(
65  Application& app,
66  ApplyView& view,
67  AccountID const& account,
68  uint256 const& delIndex,
69  std::shared_ptr<SLE> const& sleDel,
70  beast::Journal j);
71 
72 // Local function definitions that provides signature compatibility.
73 TER
75  Application& app,
76  ApplyView& view,
77  AccountID const& account,
78  uint256 const& delIndex,
79  std::shared_ptr<SLE> const& sleDel,
81 {
82  return offerDelete(view, sleDel, j);
83 }
84 
85 TER
87  Application& app,
88  ApplyView& view,
89  AccountID const& account,
90  uint256 const& delIndex,
91  std::shared_ptr<SLE> const& sleDel,
93 {
94  return SetSignerList::removeFromLedger(app, view, account, j);
95 }
96 
97 TER
98 removeTicketFromLedger(
99  Application&,
100  ApplyView& view,
101  AccountID const& account,
102  uint256 const& delIndex,
103  std::shared_ptr<SLE> const&,
104  beast::Journal j)
105 {
106  return Transactor::ticketDelete(view, account, delIndex, j);
107 }
108 
109 TER
110 removeDepositPreauthFromLedger(
111  Application& app,
112  ApplyView& view,
113  AccountID const& account,
114  uint256 const& delIndex,
115  std::shared_ptr<SLE> const& sleDel,
116  beast::Journal j)
117 {
118  return DepositPreauth::removeFromLedger(app, view, delIndex, j);
119 }
120 
121 TER
122 removeNFTokenOfferFromLedger(
123  Application& app,
124  ApplyView& view,
125  AccountID const& account,
126  uint256 const& delIndex,
127  std::shared_ptr<SLE> const& sleDel,
129 {
130  if (!nft::deleteTokenOffer(view, sleDel))
131  return tefBAD_LEDGER;
132 
133  return tesSUCCESS;
134 }
135 
136 // Return nullptr if the LedgerEntryType represents an obligation that can't
137 // be deleted. Otherwise return the pointer to the function that can delete
138 // the non-obligation
139 DeleterFuncPtr
140 nonObligationDeleter(LedgerEntryType t)
141 {
142  switch (t)
143  {
144  case ltOFFER:
145  return offerDelete;
146  case ltSIGNER_LIST:
148  case ltTICKET:
149  return removeTicketFromLedger;
150  case ltDEPOSIT_PREAUTH:
151  return removeDepositPreauthFromLedger;
152  case ltNFTOKEN_OFFER:
153  return removeNFTokenOfferFromLedger;
154  default:
155  return nullptr;
156  }
157 }
158 
159 } // namespace
160 
161 TER
163 {
164  AccountID const account{ctx.tx[sfAccount]};
165  AccountID const dst{ctx.tx[sfDestination]};
166 
167  auto sleDst = ctx.view.read(keylet::account(dst));
168 
169  if (!sleDst)
170  return tecNO_DST;
171 
172  if ((*sleDst)[sfFlags] & lsfRequireDestTag && !ctx.tx[~sfDestinationTag])
173  return tecDST_TAG_NEEDED;
174 
175  // Check whether the destination account requires deposit authorization.
176  if (ctx.view.rules().enabled(featureDepositAuth) &&
177  (sleDst->getFlags() & lsfDepositAuth))
178  {
179  if (!ctx.view.exists(keylet::depositPreauth(dst, account)))
180  return tecNO_PERMISSION;
181  }
182 
183  auto sleAccount = ctx.view.read(keylet::account(account));
184  assert(sleAccount);
185  if (!sleAccount)
186  return terNO_ACCOUNT;
187 
189  {
190  // If an issuer has any issued NFTs resident in the ledger then it
191  // cannot be deleted.
192  if ((*sleAccount)[~sfMintedNFTokens] !=
193  (*sleAccount)[~sfBurnedNFTokens])
194  return tecHAS_OBLIGATIONS;
195 
196  // If the account owns any NFTs it cannot be deleted.
197  Keylet const first = keylet::nftpage_min(account);
198  Keylet const last = keylet::nftpage_max(account);
199 
200  auto const cp = ctx.view.read(Keylet(
202  ctx.view.succ(first.key, last.key.next()).value_or(last.key)));
203  if (cp)
204  return tecHAS_OBLIGATIONS;
205  }
206 
207  // We don't allow an account to be deleted if its sequence number
208  // is within 256 of the current ledger. This prevents replay of old
209  // transactions if this account is resurrected after it is deleted.
210  //
211  // We look at the account's Sequence rather than the transaction's
212  // Sequence in preparation for Tickets.
213  constexpr std::uint32_t seqDelta{255};
214  if ((*sleAccount)[sfSequence] + seqDelta > ctx.view.seq())
215  return tecTOO_SOON;
216 
217  // Verify that the account does not own any objects that would prevent
218  // the account from being deleted.
219  Keylet const ownerDirKeylet{keylet::ownerDir(account)};
220  if (dirIsEmpty(ctx.view, ownerDirKeylet))
221  return tesSUCCESS;
222 
223  std::shared_ptr<SLE const> sleDirNode{};
224  unsigned int uDirEntry{0};
225  uint256 dirEntry{beast::zero};
226 
227  // Account has no directory at all. This _should_ have been caught
228  // by the dirIsEmpty() check earlier, but it's okay to catch it here.
229  if (!cdirFirst(
230  ctx.view, ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry))
231  return tesSUCCESS;
232 
233  std::int32_t deletableDirEntryCount{0};
234  do
235  {
236  // Make sure any directory node types that we find are the kind
237  // we can delete.
238  auto sleItem = ctx.view.read(keylet::child(dirEntry));
239  if (!sleItem)
240  {
241  // Directory node has an invalid index. Bail out.
242  JLOG(ctx.j.fatal())
243  << "DeleteAccount: directory node in ledger " << ctx.view.seq()
244  << " has index to object that is missing: "
245  << to_string(dirEntry);
246  return tefBAD_LEDGER;
247  }
248 
249  LedgerEntryType const nodeType{
250  safe_cast<LedgerEntryType>((*sleItem)[sfLedgerEntryType])};
251 
252  if (!nonObligationDeleter(nodeType))
253  return tecHAS_OBLIGATIONS;
254 
255  // We found a deletable directory entry. Count it. If we find too
256  // many deletable directory entries then bail out.
257  if (++deletableDirEntryCount > maxDeletableDirEntries)
258  return tefTOO_BIG;
259 
260  } while (cdirNext(
261  ctx.view, ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry));
262 
263  return tesSUCCESS;
264 }
265 
266 TER
268 {
269  auto src = view().peek(keylet::account(account_));
270  assert(src);
271 
272  auto dst = view().peek(keylet::account(ctx_.tx[sfDestination]));
273  assert(dst);
274 
275  if (!src || !dst)
276  return tefBAD_LEDGER;
277 
278  // Delete all of the entries in the account directory.
279  Keylet const ownerDirKeylet{keylet::ownerDir(account_)};
280  std::shared_ptr<SLE> sleDirNode{};
281  unsigned int uDirEntry{0};
282  uint256 dirEntry{beast::zero};
283 
284  if (view().exists(ownerDirKeylet) &&
285  dirFirst(view(), ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry))
286  {
287  do
288  {
289  // Choose the right way to delete each directory node.
290  auto sleItem = view().peek(keylet::child(dirEntry));
291  if (!sleItem)
292  {
293  // Directory node has an invalid index. Bail out.
294  JLOG(j_.fatal())
295  << "DeleteAccount: Directory node in ledger "
296  << view().seq() << " has index to object that is missing: "
297  << to_string(dirEntry);
298  return tefBAD_LEDGER;
299  }
300 
301  LedgerEntryType const nodeType{safe_cast<LedgerEntryType>(
302  sleItem->getFieldU16(sfLedgerEntryType))};
303 
304  if (auto deleter = nonObligationDeleter(nodeType))
305  {
306  TER const result{
307  deleter(ctx_.app, view(), account_, dirEntry, sleItem, j_)};
308 
309  if (!isTesSuccess(result))
310  return result;
311  }
312  else
313  {
314  assert(!"Undeletable entry should be found in preclaim.");
315  JLOG(j_.error())
316  << "DeleteAccount undeletable item not found in preclaim.";
317  return tecHAS_OBLIGATIONS;
318  }
319 
320  // dirFirst() and dirNext() are like iterators with exposed
321  // internal state. We'll take advantage of that exposed state
322  // to solve a common C++ problem: iterator invalidation while
323  // deleting elements from a container.
324  //
325  // We have just deleted one directory entry, which means our
326  // "iterator state" is invalid.
327  //
328  // 1. During the process of getting an entry from the
329  // directory uDirEntry was incremented from 0 to 1.
330  //
331  // 2. We then deleted the entry at index 0, which means the
332  // entry that was at 1 has now moved to 0.
333  //
334  // 3. So we verify that uDirEntry is indeed 1. Then we jam it
335  // back to zero to "un-invalidate" the iterator.
336  assert(uDirEntry == 1);
337  if (uDirEntry != 1)
338  {
339  JLOG(j_.error())
340  << "DeleteAccount iterator re-validation failed.";
341  return tefBAD_LEDGER;
342  }
343  uDirEntry = 0;
344 
345  } while (dirNext(
346  view(), ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry));
347  }
348 
349  // Transfer any XRP remaining after the fee is paid to the destination:
350  (*dst)[sfBalance] = (*dst)[sfBalance] + mSourceBalance;
351  (*src)[sfBalance] = (*src)[sfBalance] - mSourceBalance;
353 
354  assert((*src)[sfBalance] == XRPAmount(0));
355 
356  // If there's still an owner directory associated with the source account
357  // delete it.
358  if (view().exists(ownerDirKeylet) && !view().emptyDirDelete(ownerDirKeylet))
359  {
360  JLOG(j_.error()) << "DeleteAccount cannot delete root dir node of "
361  << toBase58(account_);
362  return tecHAS_OBLIGATIONS;
363  }
364 
365  // Re-arm the password change fee if we can and need to.
366  if (mSourceBalance > XRPAmount(0) && dst->isFlag(lsfPasswordSpent))
367  dst->clearFlag(lsfPasswordSpent);
368 
369  view().update(dst);
370  view().erase(src);
371 
372  return tesSUCCESS;
373 }
374 
375 } // 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
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:267
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:162
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::Fees::increment
XRPAmount increment
Definition: ReadView.h:53
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::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::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::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:125
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:193
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::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:60
ripple::keylet::depositPreauth
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition: Indexes.cpp:287
ripple::DeleteAccount::calculateBaseFee
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: DeleteAccount.cpp:56
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:602
ripple::tecNO_DST
@ tecNO_DST
Definition: TER.h:254
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:525