xrpld
Loading...
Searching...
No Matches
PermissionedDEXInvariant.cpp
1#include <xrpl/tx/invariants/PermissionedDEXInvariant.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/beast/utility/Journal.h>
5#include <xrpl/ledger/ReadView.h>
6#include <xrpl/protocol/Feature.h>
7#include <xrpl/protocol/Indexes.h>
8#include <xrpl/protocol/LedgerFormats.h>
9#include <xrpl/protocol/SField.h>
10#include <xrpl/protocol/STArray.h>
11#include <xrpl/protocol/STLedgerEntry.h>
12#include <xrpl/protocol/STTx.h>
13#include <xrpl/protocol/TER.h>
14#include <xrpl/protocol/TxFormats.h>
15#include <xrpl/protocol/XRPAmount.h>
16
17namespace xrpl {
18
19void
21{
22 if (after && after->getType() == ltDIR_NODE)
23 {
24 if (after->isFieldPresent(sfDomainID))
25 domains_.insert(after->getFieldH256(sfDomainID));
26 }
27
28 if (after && after->getType() == ltOFFER)
29 {
30 if (after->isFieldPresent(sfDomainID))
31 {
32 domains_.insert(after->getFieldH256(sfDomainID));
33 }
34 else
35 {
36 regularOffersOld_ = true;
37 if (!isDelete)
38 regularOffers_ = true;
39 }
40
41 // pre-fixCleanup3_1_3: hybrid offer missing domain, missing
42 // sfAdditionalBooks, or sfAdditionalBooks has more than one entry
43 if (after->isFlag(lsfHybrid) &&
44 (!after->isFieldPresent(sfDomainID) || !after->isFieldPresent(sfAdditionalBooks) ||
45 after->getFieldArray(sfAdditionalBooks).size() > 1))
46 badHybridsOld_ = true;
47
48 // post-fixCleanup3_1_3: same as above but also catches size == 0
49 if (after->isFlag(lsfHybrid) &&
50 (!after->isFieldPresent(sfDomainID) || !after->isFieldPresent(sfAdditionalBooks) ||
51 after->getFieldArray(sfAdditionalBooks).size() != 1))
52 badHybrids_ = true;
53 }
54}
55
56bool
58 STTx const& tx,
59 TER const result,
60 XRPAmount const,
61 ReadView const& view,
62 beast::Journal const& j)
63{
64 auto const txType = tx.getTxnType();
65 if ((txType != ttPAYMENT && txType != ttOFFER_CREATE) || !isTesSuccess(result))
66 return true;
67
68 // For each offercreate transaction, check if
69 // permissioned offers are valid
70 bool const isMalformed = view.rules().enabled(fixCleanup3_1_3) ? badHybrids_ : badHybridsOld_;
71 if (txType == ttOFFER_CREATE && isMalformed)
72 {
73 JLOG(j.fatal()) << "Invariant failed: hybrid offer is malformed";
74 return false;
75 }
76
77 if (!tx.isFieldPresent(sfDomainID))
78 return true;
79
80 auto const domain = tx.getFieldH256(sfDomainID);
81
82 if (!view.exists(keylet::permissionedDomain(domain)))
83 {
84 JLOG(j.fatal()) << "Invariant failed: domain doesn't exist";
85 return false;
86 }
87
88 // for both payment and offercreate, there shouldn't be another domain
89 // that's different from the domain specified
90 for (auto const& d : domains_)
91 {
92 if (d != domain)
93 {
94 JLOG(j.fatal()) << "Invariant failed: transaction"
95 " consumed wrong domains";
96 return false;
97 }
98 }
99
100 bool const hasRegularOffers =
101 view.rules().enabled(fixCleanup3_2_0) ? regularOffers_ : regularOffersOld_;
102 if (hasRegularOffers)
103 {
104 JLOG(j.fatal()) << "Invariant failed: domain transaction"
105 " affected regular offers";
106 return false;
107 }
108
109 return true;
110}
111
112} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:38
Stream fatal() const
Definition Journal.h:321
A view into a ledger.
Definition ReadView.h:31
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:171
std::shared_ptr< STLedgerEntry const > const & const_ref
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:454
uint256 getFieldH256(SField const &field) const
Definition STObject.cpp:621
TxType getTxnType() const
Definition STTx.h:188
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, std::uint32_t seq) noexcept
Definition Indexes.cpp:569
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:554
bool isTesSuccess(TER x) noexcept
Definition TER.h:663
TERSubset< CanCvtToTER > TER
Definition TER.h:634