rippled
InvariantCheck.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-2016 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/InvariantCheck.h>
21 
22 #include <ripple/app/tx/impl/details/NFTokenUtils.h>
23 #include <ripple/basics/FeeUnits.h>
24 #include <ripple/basics/Log.h>
25 #include <ripple/ledger/ReadView.h>
26 #include <ripple/ledger/View.h>
27 #include <ripple/protocol/Feature.h>
28 #include <ripple/protocol/STArray.h>
29 #include <ripple/protocol/SystemParameters.h>
30 #include <ripple/protocol/nftPageMask.h>
31 
32 namespace ripple {
33 
34 void
36  bool,
39 {
40  // nothing to do
41 }
42 
43 bool
45  STTx const& tx,
46  TER const,
47  XRPAmount const fee,
48  ReadView const&,
49  beast::Journal const& j)
50 {
51  // We should never charge a negative fee
52  if (fee.drops() < 0)
53  {
54  JLOG(j.fatal()) << "Invariant failed: fee paid was negative: "
55  << fee.drops();
56  return false;
57  }
58 
59  // We should never charge a fee that's greater than or equal to the
60  // entire XRP supply.
61  if (fee >= INITIAL_XRP)
62  {
63  JLOG(j.fatal()) << "Invariant failed: fee paid exceeds system limit: "
64  << fee.drops();
65  return false;
66  }
67 
68  // We should never charge more for a transaction than the transaction
69  // authorizes. It's possible to charge less in some circumstances.
70  if (fee > tx.getFieldAmount(sfFee).xrp())
71  {
72  JLOG(j.fatal()) << "Invariant failed: fee paid is " << fee.drops()
73  << " exceeds fee specified in transaction.";
74  return false;
75  }
76 
77  return true;
78 }
79 
80 //------------------------------------------------------------------------------
81 
82 void
84  bool isDelete,
85  std::shared_ptr<SLE const> const& before,
87 {
88  /* We go through all modified ledger entries, looking only at account roots,
89  * escrow payments, and payment channels. We remove from the total any
90  * previous XRP values and add to the total any new XRP values. The net
91  * balance of a payment channel is computed from two fields (amount and
92  * balance) and deletions are ignored for paychan and escrow because the
93  * amount fields have not been adjusted for those in the case of deletion.
94  */
95  if (before)
96  {
97  switch (before->getType())
98  {
99  case ltACCOUNT_ROOT:
100  drops_ -= (*before)[sfBalance].xrp().drops();
101  break;
102  case ltPAYCHAN:
103  drops_ -=
104  ((*before)[sfAmount] - (*before)[sfBalance]).xrp().drops();
105  break;
106  case ltESCROW:
107  drops_ -= (*before)[sfAmount].xrp().drops();
108  break;
109  default:
110  break;
111  }
112  }
113 
114  if (after)
115  {
116  switch (after->getType())
117  {
118  case ltACCOUNT_ROOT:
119  drops_ += (*after)[sfBalance].xrp().drops();
120  break;
121  case ltPAYCHAN:
122  if (!isDelete)
123  drops_ += ((*after)[sfAmount] - (*after)[sfBalance])
124  .xrp()
125  .drops();
126  break;
127  case ltESCROW:
128  if (!isDelete)
129  drops_ += (*after)[sfAmount].xrp().drops();
130  break;
131  default:
132  break;
133  }
134  }
135 }
136 
137 bool
139  STTx const& tx,
140  TER const,
141  XRPAmount const fee,
142  ReadView const&,
143  beast::Journal const& j)
144 {
145  // The net change should never be positive, as this would mean that the
146  // transaction created XRP out of thin air. That's not possible.
147  if (drops_ > 0)
148  {
149  JLOG(j.fatal()) << "Invariant failed: XRP net change was positive: "
150  << drops_;
151  return false;
152  }
153 
154  // The negative of the net change should be equal to actual fee charged.
155  if (-drops_ != fee.drops())
156  {
157  JLOG(j.fatal()) << "Invariant failed: XRP net change of " << drops_
158  << " doesn't match fee " << fee.drops();
159  return false;
160  }
161 
162  return true;
163 }
164 
165 //------------------------------------------------------------------------------
166 
167 void
169  bool,
170  std::shared_ptr<SLE const> const& before,
172 {
173  auto isBad = [](STAmount const& balance) {
174  if (!balance.native())
175  return true;
176 
177  auto const drops = balance.xrp();
178 
179  // Can't have more than the number of drops instantiated
180  // in the genesis ledger.
181  if (drops > INITIAL_XRP)
182  return true;
183 
184  // Can't have a negative balance (0 is OK)
185  if (drops < XRPAmount{0})
186  return true;
187 
188  return false;
189  };
190 
191  if (before && before->getType() == ltACCOUNT_ROOT)
192  bad_ |= isBad((*before)[sfBalance]);
193 
194  if (after && after->getType() == ltACCOUNT_ROOT)
195  bad_ |= isBad((*after)[sfBalance]);
196 }
197 
198 bool
200  STTx const&,
201  TER const,
202  XRPAmount const,
203  ReadView const&,
204  beast::Journal const& j)
205 {
206  if (bad_)
207  {
208  JLOG(j.fatal()) << "Invariant failed: incorrect account XRP balance";
209  return false;
210  }
211 
212  return true;
213 }
214 
215 //------------------------------------------------------------------------------
216 
217 void
219  bool isDelete,
220  std::shared_ptr<SLE const> const& before,
222 {
223  auto isBad = [](STAmount const& pays, STAmount const& gets) {
224  // An offer should never be negative
225  if (pays < beast::zero)
226  return true;
227 
228  if (gets < beast::zero)
229  return true;
230 
231  // Can't have an XRP to XRP offer:
232  return pays.native() && gets.native();
233  };
234 
235  if (before && before->getType() == ltOFFER)
236  bad_ |= isBad((*before)[sfTakerPays], (*before)[sfTakerGets]);
237 
238  if (after && after->getType() == ltOFFER)
239  bad_ |= isBad((*after)[sfTakerPays], (*after)[sfTakerGets]);
240 }
241 
242 bool
244  STTx const&,
245  TER const,
246  XRPAmount const,
247  ReadView const&,
248  beast::Journal const& j)
249 {
250  if (bad_)
251  {
252  JLOG(j.fatal()) << "Invariant failed: offer with a bad amount";
253  return false;
254  }
255 
256  return true;
257 }
258 
259 //------------------------------------------------------------------------------
260 
261 void
263  bool isDelete,
264  std::shared_ptr<SLE const> const& before,
266 {
267  auto isBad = [](STAmount const& amount) {
268  if (!amount.native())
269  return true;
270 
271  if (amount.xrp() <= XRPAmount{0})
272  return true;
273 
274  if (amount.xrp() >= INITIAL_XRP)
275  return true;
276 
277  return false;
278  };
279 
280  if (before && before->getType() == ltESCROW)
281  bad_ |= isBad((*before)[sfAmount]);
282 
283  if (after && after->getType() == ltESCROW)
284  bad_ |= isBad((*after)[sfAmount]);
285 }
286 
287 bool
289  STTx const&,
290  TER const,
291  XRPAmount const,
292  ReadView const&,
293  beast::Journal const& j)
294 {
295  if (bad_)
296  {
297  JLOG(j.fatal()) << "Invariant failed: escrow specifies invalid amount";
298  return false;
299  }
300 
301  return true;
302 }
303 
304 //------------------------------------------------------------------------------
305 
306 void
308  bool isDelete,
309  std::shared_ptr<SLE const> const& before,
311 {
312  if (isDelete && before && before->getType() == ltACCOUNT_ROOT)
314 }
315 
316 bool
318  STTx const& tx,
319  TER const result,
320  XRPAmount const,
321  ReadView const&,
322  beast::Journal const& j)
323 {
324  // AMM account root can be deleted as the result of AMM withdraw/delete
325  // transaction when the total AMM LP Tokens balance goes to 0.
326  // A successful AccountDelete or AMMDelete MUST delete exactly
327  // one account root.
328  if ((tx.getTxnType() == ttACCOUNT_DELETE ||
329  tx.getTxnType() == ttAMM_DELETE) &&
330  result == tesSUCCESS)
331  {
332  if (accountsDeleted_ == 1)
333  return true;
334 
335  if (accountsDeleted_ == 0)
336  JLOG(j.fatal()) << "Invariant failed: account deletion "
337  "succeeded without deleting an account";
338  else
339  JLOG(j.fatal()) << "Invariant failed: account deletion "
340  "succeeded but deleted multiple accounts!";
341  return false;
342  }
343 
344  // A successful AMMWithdraw MAY delete one account root
345  // when the total AMM LP Tokens balance goes to 0. Not every AMM withdraw
346  // deletes the AMM account, accountsDeleted_ is set if it is deleted.
347  if (tx.getTxnType() == ttAMM_WITHDRAW && result == tesSUCCESS &&
348  accountsDeleted_ == 1)
349  return true;
350 
351  if (accountsDeleted_ == 0)
352  return true;
353 
354  JLOG(j.fatal()) << "Invariant failed: an account root was deleted";
355  return false;
356 }
357 
358 //------------------------------------------------------------------------------
359 
360 void
362  bool,
363  std::shared_ptr<SLE const> const& before,
365 {
366  if (before && after && before->getType() != after->getType())
367  typeMismatch_ = true;
368 
369  if (after)
370  {
371  switch (after->getType())
372  {
373  case ltACCOUNT_ROOT:
374  case ltDIR_NODE:
375  case ltRIPPLE_STATE:
376  case ltTICKET:
377  case ltSIGNER_LIST:
378  case ltOFFER:
379  case ltLEDGER_HASHES:
380  case ltAMENDMENTS:
381  case ltFEE_SETTINGS:
382  case ltESCROW:
383  case ltPAYCHAN:
384  case ltCHECK:
385  case ltDEPOSIT_PREAUTH:
386  case ltNEGATIVE_UNL:
387  case ltNFTOKEN_PAGE:
388  case ltNFTOKEN_OFFER:
389  case ltAMM:
390  break;
391  default:
392  invalidTypeAdded_ = true;
393  break;
394  }
395  }
396 }
397 
398 bool
400  STTx const&,
401  TER const,
402  XRPAmount const,
403  ReadView const&,
404  beast::Journal const& j)
405 {
406  if ((!typeMismatch_) && (!invalidTypeAdded_))
407  return true;
408 
409  if (typeMismatch_)
410  {
411  JLOG(j.fatal()) << "Invariant failed: ledger entry type mismatch";
412  }
413 
414  if (invalidTypeAdded_)
415  {
416  JLOG(j.fatal()) << "Invariant failed: invalid ledger entry type added";
417  }
418 
419  return false;
420 }
421 
422 //------------------------------------------------------------------------------
423 
424 void
426  bool,
429 {
430  if (after && after->getType() == ltRIPPLE_STATE)
431  {
432  // checking the issue directly here instead of
433  // relying on .native() just in case native somehow
434  // were systematically incorrect
435  xrpTrustLine_ =
436  after->getFieldAmount(sfLowLimit).issue() == xrpIssue() ||
437  after->getFieldAmount(sfHighLimit).issue() == xrpIssue();
438  }
439 }
440 
441 bool
443  STTx const&,
444  TER const,
445  XRPAmount const,
446  ReadView const&,
447  beast::Journal const& j)
448 {
449  if (!xrpTrustLine_)
450  return true;
451 
452  JLOG(j.fatal()) << "Invariant failed: an XRP trust line was created";
453  return false;
454 }
455 
456 //------------------------------------------------------------------------------
457 
458 void
460  bool,
461  std::shared_ptr<SLE const> const& before,
463 {
464  if (!before && after->getType() == ltACCOUNT_ROOT)
465  {
467  accountSeq_ = (*after)[sfSequence];
468  }
469 }
470 
471 bool
473  STTx const& tx,
474  TER const result,
475  XRPAmount const,
476  ReadView const& view,
477  beast::Journal const& j)
478 {
479  if (accountsCreated_ == 0)
480  return true;
481 
482  if (accountsCreated_ > 1)
483  {
484  JLOG(j.fatal()) << "Invariant failed: multiple accounts "
485  "created in a single transaction";
486  return false;
487  }
488 
489  // From this point on we know exactly one account was created.
490  if ((tx.getTxnType() == ttPAYMENT || tx.getTxnType() == ttAMM_CREATE) &&
491  result == tesSUCCESS)
492  {
493  std::uint32_t const startingSeq{
494  view.rules().enabled(featureDeletableAccounts) ? view.seq() : 1};
495 
496  if (accountSeq_ != startingSeq)
497  {
498  JLOG(j.fatal()) << "Invariant failed: account created with "
499  "wrong starting sequence number";
500  return false;
501  }
502  return true;
503  }
504 
505  JLOG(j.fatal()) << "Invariant failed: account root created "
506  "by a non-Payment, by an unsuccessful transaction, "
507  "or by AMM";
508  return false;
509 }
510 
511 //------------------------------------------------------------------------------
512 
513 void
515  bool isDelete,
516  std::shared_ptr<SLE const> const& before,
518 {
519  static constexpr uint256 const& pageBits = nft::pageMask;
520  static constexpr uint256 const accountBits = ~pageBits;
521 
522  auto check = [this, isDelete](std::shared_ptr<SLE const> const& sle) {
523  uint256 const account = sle->key() & accountBits;
524  uint256 const hiLimit = sle->key() & pageBits;
525  std::optional<uint256> const prev = (*sle)[~sfPreviousPageMin];
526 
527  // Make sure that any page links...
528  // 1. Are properly associated with the owning account and
529  // 2. The page is correctly ordered between links.
530  if (prev)
531  {
532  if (account != (*prev & accountBits))
533  badLink_ = true;
534 
535  if (hiLimit <= (*prev & pageBits))
536  badLink_ = true;
537  }
538 
539  if (auto const next = (*sle)[~sfNextPageMin])
540  {
541  if (account != (*next & accountBits))
542  badLink_ = true;
543 
544  if (hiLimit >= (*next & pageBits))
545  badLink_ = true;
546  }
547 
548  {
549  auto const& nftokens = sle->getFieldArray(sfNFTokens);
550 
551  // An NFTokenPage should never contain too many tokens or be empty.
552  if (std::size_t const nftokenCount = nftokens.size();
553  (!isDelete && nftokenCount == 0) ||
554  nftokenCount > dirMaxTokensPerPage)
555  invalidSize_ = true;
556 
557  // If prev is valid, use it to establish a lower bound for
558  // page entries. If prev is not valid the lower bound is zero.
559  uint256 const loLimit =
560  prev ? *prev & pageBits : uint256(beast::zero);
561 
562  // Also verify that all NFTokenIDs in the page are sorted.
563  uint256 loCmp = loLimit;
564  for (auto const& obj : nftokens)
565  {
566  uint256 const tokenID = obj[sfNFTokenID];
567  if (!nft::compareTokens(loCmp, tokenID))
568  badSort_ = true;
569  loCmp = tokenID;
570 
571  // None of the NFTs on this page should belong on lower or
572  // higher pages.
573  if (uint256 const tokenPageBits = tokenID & pageBits;
574  tokenPageBits < loLimit || tokenPageBits >= hiLimit)
575  badEntry_ = true;
576 
577  if (auto uri = obj[~sfURI]; uri && uri->empty())
578  badURI_ = true;
579  }
580  }
581  };
582 
583  if (before && before->getType() == ltNFTOKEN_PAGE)
584  check(before);
585 
586  if (after && after->getType() == ltNFTOKEN_PAGE)
587  check(after);
588 }
589 
590 bool
592  STTx const& tx,
593  TER const result,
594  XRPAmount const,
595  ReadView const& view,
596  beast::Journal const& j)
597 {
598  if (badLink_)
599  {
600  JLOG(j.fatal()) << "Invariant failed: NFT page is improperly linked.";
601  return false;
602  }
603 
604  if (badEntry_)
605  {
606  JLOG(j.fatal()) << "Invariant failed: NFT found in incorrect page.";
607  return false;
608  }
609 
610  if (badSort_)
611  {
612  JLOG(j.fatal()) << "Invariant failed: NFTs on page are not sorted.";
613  return false;
614  }
615 
616  if (badURI_)
617  {
618  JLOG(j.fatal()) << "Invariant failed: NFT contains empty URI.";
619  return false;
620  }
621 
622  if (invalidSize_)
623  {
624  JLOG(j.fatal()) << "Invariant failed: NFT page has invalid size.";
625  return false;
626  }
627 
628  return true;
629 }
630 
631 //------------------------------------------------------------------------------
632 void
634  bool,
635  std::shared_ptr<SLE const> const& before,
637 {
638  if (before && before->getType() == ltACCOUNT_ROOT)
639  {
640  beforeMintedTotal += (*before)[~sfMintedNFTokens].value_or(0);
641  beforeBurnedTotal += (*before)[~sfBurnedNFTokens].value_or(0);
642  }
643 
644  if (after && after->getType() == ltACCOUNT_ROOT)
645  {
646  afterMintedTotal += (*after)[~sfMintedNFTokens].value_or(0);
647  afterBurnedTotal += (*after)[~sfBurnedNFTokens].value_or(0);
648  }
649 }
650 
651 bool
653  STTx const& tx,
654  TER const result,
655  XRPAmount const,
656  ReadView const& view,
657  beast::Journal const& j)
658 {
659  if (TxType const txType = tx.getTxnType();
660  txType != ttNFTOKEN_MINT && txType != ttNFTOKEN_BURN)
661  {
663  {
664  JLOG(j.fatal()) << "Invariant failed: the number of minted tokens "
665  "changed without a mint transaction!";
666  return false;
667  }
668 
670  {
671  JLOG(j.fatal()) << "Invariant failed: the number of burned tokens "
672  "changed without a burn transaction!";
673  return false;
674  }
675 
676  return true;
677  }
678 
679  if (tx.getTxnType() == ttNFTOKEN_MINT)
680  {
681  if (result == tesSUCCESS && beforeMintedTotal >= afterMintedTotal)
682  {
683  JLOG(j.fatal())
684  << "Invariant failed: successful minting didn't increase "
685  "the number of minted tokens.";
686  return false;
687  }
688 
689  if (result != tesSUCCESS && beforeMintedTotal != afterMintedTotal)
690  {
691  JLOG(j.fatal()) << "Invariant failed: failed minting changed the "
692  "number of minted tokens.";
693  return false;
694  }
695 
697  {
698  JLOG(j.fatal())
699  << "Invariant failed: minting changed the number of "
700  "burned tokens.";
701  return false;
702  }
703  }
704 
705  if (tx.getTxnType() == ttNFTOKEN_BURN)
706  {
707  if (result == tesSUCCESS)
708  {
710  {
711  JLOG(j.fatal())
712  << "Invariant failed: successful burning didn't increase "
713  "the number of burned tokens.";
714  return false;
715  }
716  }
717 
718  if (result != tesSUCCESS && beforeBurnedTotal != afterBurnedTotal)
719  {
720  JLOG(j.fatal()) << "Invariant failed: failed burning changed the "
721  "number of burned tokens.";
722  return false;
723  }
724 
726  {
727  JLOG(j.fatal())
728  << "Invariant failed: burning changed the number of "
729  "minted tokens.";
730  return false;
731  }
732  }
733 
734  return true;
735 }
736 
737 //------------------------------------------------------------------------------
738 
739 void
741  bool,
742  std::shared_ptr<SLE const> const& before,
744 {
745  if (before && before->getType() == ltRIPPLE_STATE)
747 }
748 
749 bool
751  STTx const& tx,
752  TER const result,
753  XRPAmount const,
754  ReadView const& view,
755  beast::Journal const& j)
756 {
757  if (tx.getTxnType() != ttCLAWBACK)
758  return true;
759 
760  if (result == tesSUCCESS)
761  {
762  if (trustlinesChanged > 1)
763  {
764  JLOG(j.fatal())
765  << "Invariant failed: more than one trustline changed.";
766  return false;
767  }
768 
769  AccountID const issuer = tx.getAccountID(sfAccount);
770  STAmount const amount = tx.getFieldAmount(sfAmount);
771  AccountID const& holder = amount.getIssuer();
772  STAmount const holderBalance = accountHolds(
773  view, holder, amount.getCurrency(), issuer, fhIGNORE_FREEZE, j);
774 
775  if (holderBalance.signum() < 0)
776  {
777  JLOG(j.fatal())
778  << "Invariant failed: trustline balance is negative";
779  return false;
780  }
781  }
782  else
783  {
784  if (trustlinesChanged != 0)
785  {
786  JLOG(j.fatal()) << "Invariant failed: some trustlines were changed "
787  "despite failure of the transaction.";
788  return false;
789  }
790  }
791 
792  return true;
793 }
794 
795 } // namespace ripple
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:339
ripple::STTx::getTxnType
TxType getTxnType() const
Definition: STTx.h:179
ripple::ValidNFTokenPage::badURI_
bool badURI_
Definition: InvariantCheck.h:337
ripple::LedgerEntryTypesMatch::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:361
ripple::ttACCOUNT_DELETE
@ ttACCOUNT_DELETE
This transaction type deletes an existing account.
Definition: TxFormats.h:122
ripple::ltTICKET
@ ltTICKET
A ledger object which describes a ticket.
Definition: LedgerFormats.h:80
ripple::NoZeroEscrow::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:262
ripple::ttAMM_DELETE
@ ttAMM_DELETE
This transaction type deletes AMM in the empty state.
Definition: TxFormats.h:161
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::TransactionFeeCheck::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:44
ripple::sfAmount
const SF_AMOUNT sfAmount
ripple::ttCLAWBACK
@ ttCLAWBACK
This transaction claws back issued tokens.
Definition: TxFormats.h:143
ripple::sfNFTokenID
const SF_UINT256 sfNFTokenID
ripple::ltLEDGER_HASHES
@ ltLEDGER_HASHES
A ledger object that contains a list of ledger hashes.
Definition: LedgerFormats.h:102
ripple::XRPBalanceChecks::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:199
ripple::XRPAmount::drops
constexpr value_type drops() const
Returns the number of drops.
Definition: XRPAmount.h:172
ripple::sfSequence
const SF_UINT32 sfSequence
ripple::NoXRPTrustLines::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:425
ripple::accountHolds
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
Definition: View.cpp:226
ripple::ValidNFTokenPage::badSort_
bool badSort_
Definition: InvariantCheck.h:336
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::NoBadOffers::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:218
ripple::NoZeroEscrow::bad_
bool bad_
Definition: InvariantCheck.h:277
ripple::ValidNFTokenPage::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:514
ripple::dirMaxTokensPerPage
constexpr std::size_t dirMaxTokensPerPage
The maximum number of items in an NFT page.
Definition: Protocol.h:61
ripple::STAmount::signum
int signum() const noexcept
Definition: STAmount.h:365
ripple::TxType
TxType
Transaction type identifiers.
Definition: TxFormats.h:56
ripple::NoBadOffers::bad_
bool bad_
Definition: InvariantCheck.h:253
ripple::NFTokenCountTracking::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:652
ripple::ValidNFTokenPage::invalidSize_
bool invalidSize_
Definition: InvariantCheck.h:338
ripple::NFTokenCountTracking::beforeMintedTotal
std::uint32_t beforeMintedTotal
Definition: InvariantCheck.h:371
ripple::ltCHECK
@ ltCHECK
A ledger object which describes a check.
Definition: LedgerFormats.h:136
ripple::ltFEE_SETTINGS
@ ltFEE_SETTINGS
The ledger object which lists the network's fee settings.
Definition: LedgerFormats.h:118
ripple::NFTokenCountTracking::afterMintedTotal
std::uint32_t afterMintedTotal
Definition: InvariantCheck.h:373
ripple::nft::compareTokens
bool compareTokens(uint256 const &a, uint256 const &b)
Definition: NFTokenUtils.cpp:227
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:334
ripple::INITIAL_XRP
constexpr XRPAmount INITIAL_XRP
Configure the native currency.
Definition: SystemParameters.h:43
ripple::ValidNewAccountRoot::accountSeq_
std::uint32_t accountSeq_
Definition: InvariantCheck.h:303
ripple::ltDIR_NODE
@ ltDIR_NODE
A ledger object which contains a list of object identifiers.
Definition: LedgerFormats.h:66
ripple::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:359
ripple::ValidNewAccountRoot::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:472
ripple::nft::pageMask
constexpr uint256 pageMask(std::string_view("0000000000000000000000000000000000000000ffffffffffffffffffffffff"))
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:550
ripple::featureDeletableAccounts
const uint256 featureDeletableAccounts
ripple::ttPAYMENT
@ ttPAYMENT
This transaction type executes a payment.
Definition: TxFormats.h:59
ripple::NoXRPTrustLines::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:442
ripple::base_uint< 256 >
ripple::sfTakerPays
const SF_AMOUNT sfTakerPays
ripple::ltAMENDMENTS
@ ltAMENDMENTS
The ledger object which lists details about amendments on the network.
Definition: LedgerFormats.h:110
ripple::sfLowLimit
const SF_AMOUNT sfLowLimit
ripple::LedgerEntryTypesMatch::typeMismatch_
bool typeMismatch_
Definition: InvariantCheck.h:199
ripple::ValidNFTokenPage::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:591
ripple::ltOFFER
@ ltOFFER
A ledger object which describes an offer on the DEX.
Definition: LedgerFormats.h:92
ripple::NoBadOffers::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:243
ripple::LedgerEntryTypesMatch::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:399
ripple::NFTokenCountTracking::afterBurnedTotal
std::uint32_t afterBurnedTotal
Definition: InvariantCheck.h:374
ripple::ttAMM_CREATE
@ ttAMM_CREATE
This transaction type creates an AMM instance.
Definition: TxFormats.h:146
ripple::ltESCROW
@ ltESCROW
A ledger object describing a single escrow.
Definition: LedgerFormats.h:124
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:589
ripple::ltNFTOKEN_OFFER
@ ltNFTOKEN_OFFER
A ledger object which identifies an offer to buy or sell an NFT.
Definition: LedgerFormats.h:162
ripple::ValidNFTokenPage::badEntry_
bool badEntry_
Definition: InvariantCheck.h:334
ripple::TERSubset< CanCvtToTER >
ripple::ttNFTOKEN_MINT
@ ttNFTOKEN_MINT
This transaction mints a new NFT.
Definition: TxFormats.h:128
ripple::ValidNewAccountRoot::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:459
ripple::ValidClawback::trustlinesChanged
std::uint32_t trustlinesChanged
Definition: InvariantCheck.h:402
ripple::ValidClawback::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:750
ripple::ltDEPOSIT_PREAUTH
@ ltDEPOSIT_PREAUTH
A ledger object which describes a deposit preauthorization.
Definition: LedgerFormats.h:142
ripple::STAmount
Definition: STAmount.h:45
ripple::XRPNotCreated::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:83
ripple::ttAMM_WITHDRAW
@ ttAMM_WITHDRAW
This transaction type withdraws from an AMM instance.
Definition: TxFormats.h:152
ripple::sfTakerGets
const SF_AMOUNT sfTakerGets
ripple::XRPNotCreated::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:138
ripple::STTx
Definition: STTx.h:45
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint32_t
ripple::sfHighLimit
const SF_AMOUNT sfHighLimit
ripple::NoZeroEscrow::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:288
ripple::AccountRootsNotDeleted::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition: InvariantCheck.cpp:317
ripple::NFTokenCountTracking::beforeBurnedTotal
std::uint32_t beforeBurnedTotal
Definition: InvariantCheck.h:372
ripple::sfNFTokens
const SField sfNFTokens
ripple::sfURI
const SF_VL sfURI
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:329
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:156
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::ltNEGATIVE_UNL
@ ltNEGATIVE_UNL
The ledger object which tracks the current negative UNL state.
Definition: LedgerFormats.h:150
ripple::NoXRPTrustLines::xrpTrustLine_
bool xrpTrustLine_
Definition: InvariantCheck.h:226
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:122
ripple::ValidNewAccountRoot::accountsCreated_
std::uint32_t accountsCreated_
Definition: InvariantCheck.h:302
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::ltACCOUNT_ROOT
@ ltACCOUNT_ROOT
A ledger object which describes an account.
Definition: LedgerFormats.h:59
ripple::TransactionFeeCheck::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:35
ripple::sfBalance
const SF_AMOUNT sfBalance
ripple::AccountRootsNotDeleted::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:307
ripple::sfNextPageMin
const SF_UINT256 sfNextPageMin
ripple::xrpIssue
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition: Issue.h:105
ripple::fhIGNORE_FREEZE
@ fhIGNORE_FREEZE
Definition: View.h:78
std::optional
ripple::sfPreviousPageMin
const SF_UINT256 sfPreviousPageMin
ripple::ttNFTOKEN_BURN
@ ttNFTOKEN_BURN
This transaction burns (i.e.
Definition: TxFormats.h:131
ripple::after
static bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition: Escrow.cpp:88
std::size_t
ripple::ValidClawback::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:740
ripple::AccountRootsNotDeleted::accountsDeleted_
std::uint32_t accountsDeleted_
Definition: InvariantCheck.h:148
ripple::sfFee
const SF_AMOUNT sfFee
ripple::XRPBalanceChecks::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:168
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::ltRIPPLE_STATE
@ ltRIPPLE_STATE
A ledger object which describes a bidirectional trust line.
Definition: LedgerFormats.h:74
ripple::NFTokenCountTracking::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition: InvariantCheck.cpp:633
ripple::XRPBalanceChecks::bad_
bool bad_
Definition: InvariantCheck.h:175
ripple::sfBurnedNFTokens
const SF_UINT32 sfBurnedNFTokens
ripple::LedgerEntryTypesMatch::invalidTypeAdded_
bool invalidTypeAdded_
Definition: InvariantCheck.h:200
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:353
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:226
ripple::XRPNotCreated::drops_
std::int64_t drops_
Definition: InvariantCheck.h:120
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:603
ripple::ltAMM
@ ltAMM
The ledger object which tracks the AMM.
Definition: LedgerFormats.h:168
ripple::ltPAYCHAN
@ ltPAYCHAN
A ledger object describing a single unidirectional XRP payment channel.
Definition: LedgerFormats.h:130
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::ValidNFTokenPage::badLink_
bool badLink_
Definition: InvariantCheck.h:335