rippled
Loading...
Searching...
No Matches
InvariantCheck.h
1#ifndef XRPL_APP_TX_INVARIANTCHECK_H_INCLUDED
2#define XRPL_APP_TX_INVARIANTCHECK_H_INCLUDED
3
4#include <xrpl/basics/Number.h>
5#include <xrpl/basics/base_uint.h>
6#include <xrpl/beast/utility/Journal.h>
7#include <xrpl/protocol/MPTIssue.h>
8#include <xrpl/protocol/STLedgerEntry.h>
9#include <xrpl/protocol/STTx.h>
10#include <xrpl/protocol/TER.h>
11
12#include <cstdint>
13#include <tuple>
14#include <unordered_set>
15
16namespace xrpl {
17
18class ReadView;
19
20#if GENERATING_DOCS
30{
31public:
32 explicit InvariantChecker_PROTOTYPE() = default;
33
41 void
43 bool isDelete,
44 std::shared_ptr<SLE const> const& before,
46
59 bool
61 STTx const& tx,
62 TER const tec,
63 XRPAmount const fee,
64 ReadView const& view,
65 beast::Journal const& j);
66};
67#endif
68
76{
77public:
78 void
80 bool,
83
84 bool
86 STTx const&,
87 TER const,
88 XRPAmount const,
89 ReadView const&,
90 beast::Journal const&);
91};
92
102{
104
105public:
106 void
108 bool,
111
112 bool
113 finalize(
114 STTx const&,
115 TER const,
116 XRPAmount const,
117 ReadView const&,
118 beast::Journal const&);
119};
120
130{
132
133public:
134 void
136 bool,
139
140 bool
141 finalize(
142 STTx const&,
143 TER const,
144 XRPAmount const,
145 ReadView const&,
146 beast::Journal const&);
147};
148
160{
161 // Pair is <before, after>. Before is used for most of the checks, so that
162 // if, for example, an object ID field is cleared, but the object is not
163 // deleted, it can still be found. After is used specifically for any checks
164 // that are expected as part of the deletion, such as zeroing out the
165 // balance.
169
170public:
171 void
173 bool,
176
177 bool
178 finalize(
179 STTx const&,
180 TER const,
181 XRPAmount const,
182 ReadView const&,
183 beast::Journal const&);
184};
185
194{
195 bool bad_ = false;
196
197public:
198 void
200 bool,
203
204 bool
205 finalize(
206 STTx const&,
207 TER const,
208 XRPAmount const,
209 ReadView const&,
210 beast::Journal const&);
211};
212
218{
219 bool typeMismatch_ = false;
220 bool invalidTypeAdded_ = false;
221
222public:
223 void
225 bool,
228
229 bool
230 finalize(
231 STTx const&,
232 TER const,
233 XRPAmount const,
234 ReadView const&,
235 beast::Journal const&);
236};
237
245{
246 bool xrpTrustLine_ = false;
247
248public:
249 void
251 bool,
254
255 bool
256 finalize(
257 STTx const&,
258 TER const,
259 XRPAmount const,
260 ReadView const&,
261 beast::Journal const&);
262};
263
272{
274
275public:
276 void
278 bool,
281
282 bool
283 finalize(
284 STTx const&,
285 TER const,
286 XRPAmount const,
287 ReadView const&,
288 beast::Journal const&);
289};
290
298{
304
310
313
315
316public:
317 void
319 bool,
322
323 bool
324 finalize(
325 STTx const&,
326 TER const,
327 XRPAmount const,
328 ReadView const&,
329 beast::Journal const&);
330
331private:
332 bool
334 std::shared_ptr<SLE const> const& before,
336
339 std::shared_ptr<SLE const> const& before,
341 bool isDelete);
342
343 void
344 recordBalance(Issue const& issue, BalanceChange change);
345
346 void
349 STAmount const& balanceChange);
350
352 findIssuer(AccountID const& issuerID, ReadView const& view);
353
354 bool
356 std::shared_ptr<SLE const> const& issuer,
357 IssuerChanges const& changes,
358 STTx const& tx,
359 beast::Journal const& j,
360 bool enforce);
361
362 bool
364 BalanceChange const& change,
365 bool high,
366 STTx const& tx,
367 beast::Journal const& j,
368 bool enforce,
369 bool globalFreeze);
370};
371
380{
381 bool bad_ = false;
382
383public:
384 void
386 bool,
389
390 bool
391 finalize(
392 STTx const&,
393 TER const,
394 XRPAmount const,
395 ReadView const&,
396 beast::Journal const&);
397};
398
404{
405 bool bad_ = false;
406
407public:
408 void
410 bool,
413
414 bool
415 finalize(
416 STTx const&,
417 TER const,
418 XRPAmount const,
419 ReadView const&,
420 beast::Journal const&);
421};
422
429{
432 bool pseudoAccount_ = false;
434
435public:
436 void
438 bool,
441
442 bool
443 finalize(
444 STTx const&,
445 TER const,
446 XRPAmount const,
447 ReadView const&,
448 beast::Journal const&);
449};
450
463{
464 bool badEntry_ = false;
465 bool badLink_ = false;
466 bool badSort_ = false;
467 bool badURI_ = false;
468 bool invalidSize_ = false;
469 bool deletedFinalPage_ = false;
470 bool deletedLink_ = false;
471
472public:
473 void
475 bool,
478
479 bool
480 finalize(
481 STTx const&,
482 TER const,
483 XRPAmount const,
484 ReadView const&,
485 beast::Journal const&);
486};
487
502{
507
508public:
509 void
511 bool,
514
515 bool
516 finalize(
517 STTx const&,
518 TER const,
519 XRPAmount const,
520 ReadView const&,
521 beast::Journal const&);
522};
523
533{
536
537public:
538 void
540 bool,
543
544 bool
545 finalize(
546 STTx const&,
547 TER const,
548 XRPAmount const,
549 ReadView const&,
550 beast::Journal const&);
551};
552
554{
557
560 // non-MPT transactions may attempt to create
561 // MPToken by an issuer
563
564public:
565 void
567 bool,
570
571 bool
572 finalize(
573 STTx const&,
574 TER const,
575 XRPAmount const,
576 ReadView const&,
577 beast::Journal const&);
578};
579
591{
593 {
595 bool isSorted_ = false, isUnique_ = false;
596 };
598
599public:
600 void
602 bool,
605
606 bool
607 finalize(
608 STTx const&,
609 TER const,
610 XRPAmount const,
611 ReadView const&,
612 beast::Journal const&);
613};
614
624{
626
627public:
628 void
630 bool,
633
634 bool
635 finalize(
636 STTx const&,
637 TER const,
638 XRPAmount const,
639 ReadView const&,
640 beast::Journal const&);
641};
642
644{
645 bool regularOffers_ = false;
646 bool badHybrids_ = false;
648
649public:
650 void
652 bool,
655
656 bool
657 finalize(
658 STTx const&,
659 TER const,
660 XRPAmount const,
661 ReadView const&,
662 beast::Journal const&);
663};
664
666{
671
672public:
673 enum class ZeroAllowed : bool { No = false, Yes = true };
674
676 {
677 }
678 void
680 bool,
683
684 bool
685 finalize(
686 STTx const&,
687 TER const,
688 XRPAmount const,
689 ReadView const&,
690 beast::Journal const&);
691
692private:
693 bool
694 finalizeBid(bool enforce, beast::Journal const&) const;
695 bool
696 finalizeVote(bool enforce, beast::Journal const&) const;
697 bool
699 STTx const&,
700 ReadView const&,
701 bool enforce,
702 beast::Journal const&) const;
703 bool
704 finalizeDelete(bool enforce, TER res, beast::Journal const&) const;
705 bool
707 STTx const&,
708 ReadView const&,
709 bool enforce,
710 beast::Journal const&) const;
711 // Includes clawback
712 bool
714 STTx const&,
715 ReadView const&,
716 bool enforce,
717 beast::Journal const&) const;
718 bool
719 finalizeDEX(bool enforce, beast::Journal const&) const;
720 bool
722 STTx const&,
723 ReadView const&,
724 ZeroAllowed zeroAllowed,
725 beast::Journal const&) const;
726};
727
736{
737 // Pair is <before, after>.
739
740public:
741 void
743 bool,
746
747 bool
748 finalize(
749 STTx const&,
750 TER const,
751 XRPAmount const,
752 ReadView const&,
753 beast::Journal const&);
754};
755
765{
766 // Not all of these elements will necessarily be populated. Remaining items
767 // will be looked up as needed.
769 {
771 // After is used for most of the checks, except
772 // those that check changed values.
774 };
775 // Collect all the LoanBrokers found directly or indirectly through
776 // pseudo-accounts. Key is the brokerID / index. It will be used to find the
777 // LoanBroker object if brokerBefore and brokerAfter are nullptr
779 // Collect all the modified trust lines. Their high and low accounts will be
780 // loaded to look for LoanBroker pseudo-accounts.
782 // Collect all the modified MPTokens. Their accounts will be loaded to look
783 // for LoanBroker pseudo-accounts.
785
786 bool
788 ReadView const& view,
789 SLE::const_ref dir,
790 beast::Journal const& j) const;
791
792public:
793 void
795 bool,
798
799 bool
800 finalize(
801 STTx const&,
802 TER const,
803 XRPAmount const,
804 ReadView const&,
805 beast::Journal const&);
806};
807
815{
816 // Pair is <before, after>. After is used for most of the checks, except
817 // those that check changed values.
819
820public:
821 void
823 bool,
826
827 bool
828 finalize(
829 STTx const&,
830 TER const,
831 XRPAmount const,
832 ReadView const&,
833 beast::Journal const&);
834};
835
836/*
837 * @brief Invariants: Vault object and MPTokenIssuance for vault shares
838 *
839 * - vault deleted and vault created is empty
840 * - vault created must be linked to pseudo-account for shares and assets
841 * - vault must have MPTokenIssuance for shares
842 * - vault without shares outstanding must have no shares
843 * - loss unrealized does not exceed the difference between assets total and
844 * assets available
845 * - assets available do not exceed assets total
846 * - vault deposit increases assets and share issuance, and adds to:
847 * total assets, assets available, shares outstanding
848 * - vault withdrawal and clawback reduce assets and share issuance, and
849 * subtracts from: total assets, assets available, shares outstanding
850 * - vault set must not alter the vault assets or shares balance
851 * - no vault transaction can change loss unrealized (it's updated by loan
852 * transactions)
853 *
854 */
856{
857 Number static constexpr zero{};
858
859 struct Vault final
860 {
861 uint256 key = beast::zero;
865 uint192 shareMPTID = beast::zero;
870
871 Vault static make(SLE const&);
872 };
873
874 struct Shares final
875 {
879
880 Shares static make(SLE const&);
881 };
882
888
889public:
890 void
892 bool,
895
896 bool
897 finalize(
898 STTx const&,
899 TER const,
900 XRPAmount const,
901 ReadView const&,
902 beast::Journal const&);
903};
904
905// additional invariant checks can be declared above and then added to this
906// tuple
926 ValidAMM,
930 ValidLoan,
931 ValidVault>;
932
941inline InvariantChecks
943{
944 return InvariantChecks{};
945}
946
947} // namespace xrpl
948
949#endif
A generic endpoint for log messages.
Definition Journal.h:41
Invariant: a deleted account must not have any objects left.
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
std::vector< std::pair< std::shared_ptr< SLE const >, std::shared_ptr< SLE const > > > accountsDeleted_
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Invariant: we cannot remove an account ledger entry.
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Prototype for invariant check implementations.
bool finalize(STTx const &tx, TER const tec, XRPAmount const fee, ReadView const &view, beast::Journal const &j)
called after all ledger entries have been visited to determine the final status of the check
void visitEntry(bool isDelete, std::shared_ptr< SLE const > const &before, std::shared_ptr< SLE const > const &after)
called for each ledger entry in the current transaction.
A currency issued by an account.
Definition Issue.h:14
Invariant: corresponding modified ledger entries should match in type and added entries should be a v...
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Invariant: Validates counts of NFTokens after all transaction types.
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Invariant: offers should be for non-negative amounts and must not be XRP to XRP.
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Invariant: Trust lines with deep freeze flag are not allowed if normal freeze flag is not set.
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Invariants: Some fields are unmodifiable.
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
std::set< std::pair< SLE::const_pointer, SLE::const_pointer > > changedEntries_
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Invariant: Trust lines using XRP are not allowed.
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Invariant: an escrow entry must take a value between 0 and INITIAL_XRP drops exclusive.
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
A view into a ledger.
Definition ReadView.h:32
Invariant: We should never charge a transaction a negative fee or a fee that is larger than what the ...
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Invariant: frozen trust line balance change is not allowed.
std::shared_ptr< SLE const > findIssuer(AccountID const &issuerID, ReadView const &view)
void recordBalance(Issue const &issue, BalanceChange change)
bool isValidEntry(std::shared_ptr< SLE const > const &before, std::shared_ptr< SLE const > const &after)
bool validateIssuerChanges(std::shared_ptr< SLE const > const &issuer, IssuerChanges const &changes, STTx const &tx, beast::Journal const &j, bool enforce)
std::map< AccountID, std::shared_ptr< SLE const > const > possibleIssuers_
STAmount calculateBalanceChange(std::shared_ptr< SLE const > const &before, std::shared_ptr< SLE const > const &after, bool isDelete)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
bool validateFrozenState(BalanceChange const &change, bool high, STTx const &tx, beast::Journal const &j, bool enforce, bool globalFreeze)
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
void recordBalanceChanges(std::shared_ptr< SLE const > const &after, STAmount const &balanceChange)
std::optional< AccountID > ammAccount_
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
bool finalizeWithdraw(STTx const &, ReadView const &, bool enforce, beast::Journal const &) const
bool finalizeBid(bool enforce, beast::Journal const &) const
bool finalizeCreate(STTx const &, ReadView const &, bool enforce, beast::Journal const &) const
bool finalizeDEX(bool enforce, beast::Journal const &) const
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalizeDeposit(STTx const &, ReadView const &, bool enforce, beast::Journal const &) const
bool generalInvariant(STTx const &, ReadView const &, ZeroAllowed zeroAllowed, beast::Journal const &) const
std::optional< STAmount > lptAMMBalanceAfter_
bool finalizeVote(bool enforce, beast::Journal const &) const
bool finalizeDelete(bool enforce, TER res, beast::Journal const &) const
std::optional< STAmount > lptAMMBalanceBefore_
Invariant: Token holder's trustline balance cannot be negative after Clawback.
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
std::uint32_t trustlinesChanged
std::uint32_t mptokensChanged
Invariants: Loan brokers are internally consistent.
std::map< uint256, BrokerInfo > brokers_
bool goodZeroDirectory(ReadView const &view, SLE::const_ref dir, beast::Journal const &j) const
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
std::vector< SLE::const_pointer > mpts_
std::vector< SLE::const_pointer > lines_
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Invariants: Loans are internally consistent.
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
std::vector< std::pair< SLE::const_pointer, SLE::const_pointer > > loans_
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
std::uint32_t mptokensCreated_
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
std::uint32_t mptokensDeleted_
std::uint32_t mptIssuancesCreated_
std::uint32_t mptIssuancesDeleted_
Invariant: Validates several invariants for NFToken pages.
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Invariant: a new account root must be the consequence of a payment, must have the right starting sequ...
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
hash_set< uint256 > domains_
Invariants: Permissioned Domains must have some rules and AcceptedCredentials must have length betwee...
std::optional< SleStatus > sleStatus_[2]
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Invariants: Pseudo-accounts have valid and consistent properties.
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
std::vector< std::string > errors_
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
static Number constexpr zero
std::vector< Shares > afterMPTs_
std::unordered_map< uint256, Number > deltas_
std::vector< Vault > afterVault_
std::vector< Shares > beforeMPTs_
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
std::vector< Vault > beforeVault_
Invariant: An account XRP balance must be in XRP and take a value between 0 and INITIAL_XRP drops,...
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Invariant: A transaction must not create XRP and should only destroy the XRP fee.
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
InvariantChecks getInvariantChecks()
get a tuple of all invariant checks
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:3922
std::shared_ptr< SLE const > const line
std::vector< BalanceChange > senders
std::vector< BalanceChange > receivers
static Shares make(SLE const &)
static Vault make(SLE const &)