xrpld
Loading...
Searching...
No Matches
PermissionedDEXInvariant.cpp
1#include <xrpl/tx/invariants/PermissionedDEXInvariant.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/beast/utility/Journal.h>
6#include <xrpl/ledger/ReadView.h>
7#include <xrpl/protocol/Feature.h>
8#include <xrpl/protocol/Indexes.h>
9#include <xrpl/protocol/LedgerFormats.h>
10#include <xrpl/protocol/SField.h>
11#include <xrpl/protocol/STArray.h>
12#include <xrpl/protocol/STLedgerEntry.h>
13#include <xrpl/protocol/STTx.h>
14#include <xrpl/protocol/TER.h>
15#include <xrpl/protocol/TxFormats.h>
16#include <xrpl/protocol/XRPAmount.h>
17
18namespace xrpl {
19
20void
22{
23 auto trackDomain = [this, isDelete](uint256 const& domain) {
24 domainsOld_.insert(domain);
25 if (!isDelete)
26 domains_.insert(domain);
27 };
28
29 if (after && after->getType() == ltDIR_NODE)
30 {
31 if (after->isFieldPresent(sfDomainID))
32 trackDomain(after->getFieldH256(sfDomainID));
33 }
34
35 if (after && after->getType() == ltOFFER)
36 {
37 if (after->isFieldPresent(sfDomainID))
38 {
39 trackDomain(after->getFieldH256(sfDomainID));
40 }
41 else
42 {
43 regularOffersOld_ = true;
44 if (!isDelete)
45 regularOffers_ = true;
46 }
47
48 // pre-fixCleanup3_1_3: hybrid offer missing domain, missing
49 // sfAdditionalBooks, or sfAdditionalBooks has more than one entry
50 if (after->isFlag(lsfHybrid) &&
51 (!after->isFieldPresent(sfDomainID) || !after->isFieldPresent(sfAdditionalBooks) ||
52 after->getFieldArray(sfAdditionalBooks).size() > 1))
53 badHybridsOld_ = true;
54
55 // post-fixCleanup3_1_3: same as above but also catches size == 0
56 if (after->isFlag(lsfHybrid) &&
57 (!after->isFieldPresent(sfDomainID) || !after->isFieldPresent(sfAdditionalBooks) ||
58 after->getFieldArray(sfAdditionalBooks).size() != 1))
59 badHybrids_ = true;
60 }
61}
62
63bool
65 STTx const& tx,
66 TER const result,
67 XRPAmount const,
68 ReadView const& view,
69 beast::Journal const& j)
70{
71 auto const txType = tx.getTxnType();
72 if ((txType != ttPAYMENT && txType != ttOFFER_CREATE) || !isTesSuccess(result))
73 return true;
74
75 // For each offercreate transaction, check if
76 // permissioned offers are valid
77 bool const isMalformed = view.rules().enabled(fixCleanup3_1_3) ? badHybrids_ : badHybridsOld_;
78 if (txType == ttOFFER_CREATE && isMalformed)
79 {
80 JLOG(j.fatal()) << "Invariant failed: hybrid offer is malformed";
81 return false;
82 }
83
84 if (!tx.isFieldPresent(sfDomainID))
85 return true;
86
87 auto const domain = tx.getFieldH256(sfDomainID);
88
89 if (!view.exists(keylet::permissionedDomain(domain)))
90 {
91 JLOG(j.fatal()) << "Invariant failed: domain doesn't exist";
92 return false;
93 }
94
95 // for both payment and offercreate, there shouldn't be another domain
96 // that's different from the domain specified
97 auto const& domains = view.rules().enabled(fixCleanup3_4_0) ? domains_ : domainsOld_;
98 for (auto const& d : domains)
99 {
100 if (d != domain)
101 {
102 JLOG(j.fatal()) << "Invariant failed: transaction"
103 " consumed wrong domains";
104 return false;
105 }
106 }
107
108 bool const hasRegularOffers =
109 view.rules().enabled(fixCleanup3_2_0) ? regularOffers_ : regularOffersOld_;
110 if (hasRegularOffers)
111 {
112 JLOG(j.fatal()) << "Invariant failed: domain transaction"
113 " affected regular offers";
114 return false;
115 }
116
117 return true;
118}
119
120} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:44
Stream fatal() const
Definition Journal.h:368
A view into a ledger.
Definition ReadView.h:41
virtual Rules const & rules() const =0
Returns the tx processing rules.
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:180
std::shared_ptr< STLedgerEntry const > const & const_ref
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:464
uint256 getFieldH256(SField const &field) const
Definition STObject.cpp:631
TxType getTxnType() const
Definition STTx.h:226
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
void visitEntry(bool, SLE::const_ref, SLE::const_ref)
Keylet permissionedDomain(AccountID const &account, SeqProxy const &seq) noexcept
Definition Indexes.cpp:579
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:572
bool isTesSuccess(TER x) noexcept
Definition TER.h:676
TERSubset< CanCvtToTER > TER
Definition TER.h:647
BaseUInt< 256 > uint256
Definition base_uint.h:580