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/DID.h>
21 #include <ripple/app/tx/impl/DeleteAccount.h>
22 #include <ripple/app/tx/impl/DepositPreauth.h>
23 #include <ripple/app/tx/impl/SetSignerList.h>
24 #include <ripple/app/tx/impl/details/NFTokenUtils.h>
25 #include <ripple/basics/FeeUnits.h>
26 #include <ripple/basics/Log.h>
27 #include <ripple/basics/mulDiv.h>
28 #include <ripple/ledger/View.h>
29 #include <ripple/protocol/Feature.h>
30 #include <ripple/protocol/Indexes.h>
31 #include <ripple/protocol/Protocol.h>
32 #include <ripple/protocol/TxFlags.h>
33 #include <ripple/protocol/st.h>
34 
35 namespace ripple {
36 
37 NotTEC
39 {
41  return temDISABLED;
42 
43  if (ctx.tx.getFlags() & tfUniversalMask)
44  return temINVALID_FLAG;
45 
46  if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
47  return ret;
48 
49  if (ctx.tx[sfAccount] == ctx.tx[sfDestination])
50  // An account cannot be deleted and give itself the resulting XRP.
51  return temDST_IS_SRC;
52 
53  return preflight2(ctx);
54 }
55 
58 {
59  // The fee required for AccountDelete is one owner reserve.
60  return view.fees().increment;
61 }
62 
63 namespace {
64 // Define a function pointer type that can be used to delete ledger node types.
65 using DeleterFuncPtr = TER (*)(
66  Application& app,
67  ApplyView& view,
68  AccountID const& account,
69  uint256 const& delIndex,
70  std::shared_ptr<SLE> const& sleDel,
71  beast::Journal j);
72 
73 // Local function definitions that provides signature compatibility.
74 TER
76  Application& app,
77  ApplyView& view,
78  AccountID const& account,
79  uint256 const& delIndex,
80  std::shared_ptr<SLE> const& sleDel,
82 {
83  return offerDelete(view, sleDel, j);
84 }
85 
86 TER
88  Application& app,
89  ApplyView& view,
90  AccountID const& account,
91  uint256 const& delIndex,
92  std::shared_ptr<SLE> const& sleDel,
94 {
95  return SetSignerList::removeFromLedger(app, view, account, j);
96 }
97 
98 TER
99 removeTicketFromLedger(
100  Application&,
101  ApplyView& view,
102  AccountID const& account,
103  uint256 const& delIndex,
104  std::shared_ptr<SLE> const&,
105  beast::Journal j)
106 {
107  return Transactor::ticketDelete(view, account, delIndex, j);
108 }
109 
110 TER
111 removeDepositPreauthFromLedger(
112  Application& app,
113  ApplyView& view,
114  AccountID const& account,
115  uint256 const& delIndex,
116  std::shared_ptr<SLE> const& sleDel,
117  beast::Journal j)
118 {
119  return DepositPreauth::removeFromLedger(app, view, delIndex, j);
120 }
121 
122 TER
123 removeNFTokenOfferFromLedger(
124  Application& app,
125  ApplyView& view,
126  AccountID const& account,
127  uint256 const& delIndex,
128  std::shared_ptr<SLE> const& sleDel,
130 {
131  if (!nft::deleteTokenOffer(view, sleDel))
132  return tefBAD_LEDGER;
133 
134  return tesSUCCESS;
135 }
136 
137 TER
138 removeDIDFromLedger(
139  Application& app,
140  ApplyView& view,
141  AccountID const& account,
142  uint256 const& delIndex,
143  std::shared_ptr<SLE> const& sleDel,
144  beast::Journal j)
145 {
146  return DIDDelete::deleteSLE(view, sleDel, account, j);
147 }
148 
149 // Return nullptr if the LedgerEntryType represents an obligation that can't
150 // be deleted. Otherwise return the pointer to the function that can delete
151 // the non-obligation
152 DeleterFuncPtr
153 nonObligationDeleter(LedgerEntryType t)
154 {
155  switch (t)
156  {
157  case ltOFFER:
158  return offerDelete;
159  case ltSIGNER_LIST:
161  case ltTICKET:
162  return removeTicketFromLedger;
163  case ltDEPOSIT_PREAUTH:
164  return removeDepositPreauthFromLedger;
165  case ltNFTOKEN_OFFER:
166  return removeNFTokenOfferFromLedger;
167  case ltDID:
168  return removeDIDFromLedger;
169  default:
170  return nullptr;
171  }
172 }
173 
174 } // namespace
175 
176 TER
178 {
179  AccountID const account{ctx.tx[sfAccount]};
180  AccountID const dst{ctx.tx[sfDestination]};
181 
182  auto sleDst = ctx.view.read(keylet::account(dst));
183 
184  if (!sleDst)
185  return tecNO_DST;
186 
187  if ((*sleDst)[sfFlags] & lsfRequireDestTag && !ctx.tx[~sfDestinationTag])
188  return tecDST_TAG_NEEDED;
189 
190  // Check whether the destination account requires deposit authorization.
191  if (ctx.view.rules().enabled(featureDepositAuth) &&
192  (sleDst->getFlags() & lsfDepositAuth))
193  {
194  if (!ctx.view.exists(keylet::depositPreauth(dst, account)))
195  return tecNO_PERMISSION;
196  }
197 
198  auto sleAccount = ctx.view.read(keylet::account(account));
199  assert(sleAccount);
200  if (!sleAccount)
201  return terNO_ACCOUNT;
202 
204  {
205  // If an issuer has any issued NFTs resident in the ledger then it
206  // cannot be deleted.
207  if ((*sleAccount)[~sfMintedNFTokens] !=
208  (*sleAccount)[~sfBurnedNFTokens])
209  return tecHAS_OBLIGATIONS;
210 
211  // If the account owns any NFTs it cannot be deleted.
212  Keylet const first = keylet::nftpage_min(account);
213  Keylet const last = keylet::nftpage_max(account);
214 
215  auto const cp = ctx.view.read(Keylet(
217  ctx.view.succ(first.key, last.key.next()).value_or(last.key)));
218  if (cp)
219  return tecHAS_OBLIGATIONS;
220  }
221 
222  // We don't allow an account to be deleted if its sequence number
223  // is within 256 of the current ledger. This prevents replay of old
224  // transactions if this account is resurrected after it is deleted.
225  //
226  // We look at the account's Sequence rather than the transaction's
227  // Sequence in preparation for Tickets.
228  constexpr std::uint32_t seqDelta{255};
229  if ((*sleAccount)[sfSequence] + seqDelta > ctx.view.seq())
230  return tecTOO_SOON;
231 
232  // When fixNFTokenRemint is enabled, we don't allow an account to be
233  // deleted if <FirstNFTokenSequence + MintedNFTokens> is within 256 of the
234  // current ledger. This is to prevent having duplicate NFTokenIDs after
235  // account re-creation.
236  //
237  // Without this restriction, duplicate NFTokenIDs can be reproduced when
238  // authorized minting is involved. Because when the minter mints a NFToken,
239  // the issuer's sequence does not change. So when the issuer re-creates
240  // their account and mints a NFToken, it is possible that the
241  // NFTokenSequence of this NFToken is the same as the one that the
242  // authorized minter minted in a previous ledger.
243  if (ctx.view.rules().enabled(fixNFTokenRemint) &&
244  ((*sleAccount)[~sfFirstNFTokenSequence].value_or(0) +
245  (*sleAccount)[~sfMintedNFTokens].value_or(0) + seqDelta >
246  ctx.view.seq()))
247  return tecTOO_SOON;
248 
249  // Verify that the account does not own any objects that would prevent
250  // the account from being deleted.
251  Keylet const ownerDirKeylet{keylet::ownerDir(account)};
252  if (dirIsEmpty(ctx.view, ownerDirKeylet))
253  return tesSUCCESS;
254 
255  std::shared_ptr<SLE const> sleDirNode{};
256  unsigned int uDirEntry{0};
257  uint256 dirEntry{beast::zero};
258 
259  // Account has no directory at all. This _should_ have been caught
260  // by the dirIsEmpty() check earlier, but it's okay to catch it here.
261  if (!cdirFirst(
262  ctx.view, ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry))
263  return tesSUCCESS;
264 
265  std::int32_t deletableDirEntryCount{0};
266  do
267  {
268  // Make sure any directory node types that we find are the kind
269  // we can delete.
270  auto sleItem = ctx.view.read(keylet::child(dirEntry));
271  if (!sleItem)
272  {
273  // Directory node has an invalid index. Bail out.
274  JLOG(ctx.j.fatal())
275  << "DeleteAccount: directory node in ledger " << ctx.view.seq()
276  << " has index to object that is missing: "
277  << to_string(dirEntry);
278  return tefBAD_LEDGER;
279  }
280 
281  LedgerEntryType const nodeType{
282  safe_cast<LedgerEntryType>((*sleItem)[sfLedgerEntryType])};
283 
284  if (!nonObligationDeleter(nodeType))
285  return tecHAS_OBLIGATIONS;
286 
287  // We found a deletable directory entry. Count it. If we find too
288  // many deletable directory entries then bail out.
289  if (++deletableDirEntryCount > maxDeletableDirEntries)
290  return tefTOO_BIG;
291 
292  } while (cdirNext(
293  ctx.view, ownerDirKeylet.key, sleDirNode, uDirEntry, dirEntry));
294 
295  return tesSUCCESS;
296 }
297 
298 TER
300 {
301  auto src = view().peek(keylet::account(account_));
302  assert(src);
303 
304  auto dst = view().peek(keylet::account(ctx_.tx[sfDestination]));
305  assert(dst);
306 
307  if (!src || !dst)
308  return tefBAD_LEDGER;
309 
310  Keylet const ownerDirKeylet{keylet::ownerDir(account_)};
311  auto const ter = cleanupOnAccountDelete(
312  view(),
313  ownerDirKeylet,
314  [&](LedgerEntryType nodeType,
315  uint256 const& dirEntry,
317  if (auto deleter = nonObligationDeleter(nodeType))
318  {
319  TER const result{
320  deleter(ctx_.app, view(), account_, dirEntry, sleItem, j_)};
321 
322  return {result, SkipEntry::No};
323  }
324 
325  assert(!"Undeletable entry should be found in preclaim.");
326  JLOG(j_.error()) << "DeleteAccount undeletable item not "
327  "found in preclaim.";
329  },
330  ctx_.journal);
331  if (ter != tesSUCCESS)
332  return ter;
333 
334  // Transfer any XRP remaining after the fee is paid to the destination:
335  (*dst)[sfBalance] = (*dst)[sfBalance] + mSourceBalance;
336  (*src)[sfBalance] = (*src)[sfBalance] - mSourceBalance;
338 
339  assert((*src)[sfBalance] == XRPAmount(0));
340 
341  // If there's still an owner directory associated with the source account
342  // delete it.
343  if (view().exists(ownerDirKeylet) && !view().emptyDirDelete(ownerDirKeylet))
344  {
345  JLOG(j_.error()) << "DeleteAccount cannot delete root dir node of "
346  << toBase58(account_);
347  return tecHAS_OBLIGATIONS;
348  }
349 
350  // Re-arm the password change fee if we can and need to.
351  if (mSourceBalance > XRPAmount(0) && dst->isFlag(lsfPasswordSpent))
352  dst->clearFlag(lsfPasswordSpent);
353 
354  view().update(dst);
355  view().erase(src);
356 
357  return tesSUCCESS;
358 }
359 
360 } // namespace ripple
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:338
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:312
ripple::Application
Definition: Application.h:116
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::sfFirstNFTokenSequence
const SF_UINT32 sfFirstNFTokenSequence
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:133
ripple::ltTICKET
@ ltTICKET
A ledger object which describes a ticket.
Definition: LedgerFormats.h:80
ripple::lsfPasswordSpent
@ lsfPasswordSpent
Definition: LedgerFormats.h:254
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:94
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:637
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:290
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:38
ripple::keylet::child
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Definition: Indexes.cpp:148
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:299
ripple::ApplyContext::journal
const beast::Journal journal
Definition: ApplyContext.h:51
ripple::base_uint::next
base_uint next() const
Definition: base_uint.h:448
ripple::DeleteAccount::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition: DeleteAccount.cpp:177
ripple::temDST_IS_SRC
@ temDST_IS_SRC
Definition: TER.h:107
ripple::Transactor::ticketDelete
static TER ticketDelete(ApplyView &view, AccountID const &account, uint256 const &ticketIndex, beast::Journal j)
Definition: Transactor.cpp:386
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:81
ripple::lsfDepositAuth
@ lsfDepositAuth
Definition: LedgerFormats.h:265
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::fixNFTokenRemint
const uint256 fixNFTokenRemint
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:550
ripple::featureDeletableAccounts
const uint256 featureDeletableAccounts
ripple::Fees::increment
XRPAmount increment
Definition: protocol/Fees.h:36
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:82
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:110
ripple::keylet::nftpage_min
Keylet nftpage_min(AccountID const &owner)
NFT page keylets.
Definition: Indexes.cpp:341
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition: TER.h:164
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:142
ripple::DIDDelete::deleteSLE
static TER deleteSLE(ApplyContext &ctx, Keylet sleKeylet, AccountID const owner)
Definition: DID.cpp:184
ripple::offerDelete
TER offerDelete(ApplyView &view, std::shared_ptr< SLE > const &sle, beast::Journal j)
Delete an offer.
Definition: View.cpp:910
ripple::ltDID
@ ltDID
The ledger object which tracks the DID.
Definition: LedgerFormats.h:193
ripple::ltNFTOKEN_OFFER
@ ltNFTOKEN_OFFER
A ledger object which identifies an offer to buy or sell an NFT.
Definition: LedgerFormats.h:181
ripple::TERSubset< CanCvtToTER >
ripple::TER
TERSubset< CanCvtToTER > TER
Definition: TER.h:608
ripple::ltDEPOSIT_PREAUTH
@ ltDEPOSIT_PREAUTH
A ledger object which describes a deposit preauthorization.
Definition: LedgerFormats.h:161
ripple::keylet::nftpage_max
Keylet nftpage_max(AccountID const &owner)
A keylet for the owner's last possible NFT page.
Definition: Indexes.cpp:349
beast::Journal::error
Stream error() const
Definition: Journal.h:332
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::cleanupOnAccountDelete
TER cleanupOnAccountDelete(ApplyView &view, Keylet const &ownerDirKeylet, EntryDeleter const &deleter, beast::Journal j, std::optional< uint16_t > maxNodesToDelete)
Definition: View.cpp:1531
ripple::PreclaimContext::tx
STTx const & tx
Definition: Transactor.h:58
ripple::lsfRequireDestTag
@ lsfRequireDestTag
Definition: LedgerFormats.h:255
ripple::terNO_ACCOUNT
@ terNO_ACCOUNT
Definition: TER.h:210
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:299
ripple::dirIsEmpty
bool dirIsEmpty(ReadView const &view, Keylet const &k)
Returns true if the directory is empty.
Definition: View.cpp:607
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:54
ripple::ltNFTOKEN_PAGE
@ ltNFTOKEN_PAGE
A ledger object which contains a list of NFTs.
Definition: LedgerFormats.h:175
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::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:113
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:122
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:178
ripple::tecHAS_OBLIGATIONS
@ tecHAS_OBLIGATIONS
Definition: TER.h:298
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:286
ripple::Transactor::mSourceBalance
XRPAmount mSourceBalance
Definition: Transactor.h:93
ripple::SkipEntry::No
@ No
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:296
ripple::DeleteAccount::calculateBaseFee
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: DeleteAccount.cpp:57
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:236
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:49
ripple::nft::deleteTokenOffer
bool deleteTokenOffer(ApplyView &view, std::shared_ptr< SLE > const &offer)
Deletes the given token offer.
Definition: NFTokenUtils.cpp:605
ripple::tecNO_DST
@ tecNO_DST
Definition: TER.h:271
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:568