rippled
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/instrumentation.h>
5#include <xrpl/protocol/Indexes.h>
6#include <xrpl/protocol/LedgerFormats.h>
7#include <xrpl/protocol/STArray.h>
8#include <xrpl/protocol/TxFormats.h>
9
10namespace xrpl {
11
12void
14 bool,
15 std::shared_ptr<SLE const> const& before,
17{
18 if (after && after->getType() == ltDIR_NODE)
19 {
20 if (after->isFieldPresent(sfDomainID))
21 domains_.insert(after->getFieldH256(sfDomainID));
22 }
23
24 if (after && after->getType() == ltOFFER)
25 {
26 if (after->isFieldPresent(sfDomainID))
27 {
28 domains_.insert(after->getFieldH256(sfDomainID));
29 }
30 else
31 {
32 regularOffers_ = true;
33 }
34
35 // if a hybrid offer is missing domain or additional book, there's
36 // something wrong
37 if (after->isFlag(lsfHybrid) &&
38 (!after->isFieldPresent(sfDomainID) || !after->isFieldPresent(sfAdditionalBooks) ||
39 after->getFieldArray(sfAdditionalBooks).size() > 1))
40 badHybrids_ = true;
41 }
42}
43
44bool
46 STTx const& tx,
47 TER const result,
48 XRPAmount const,
49 ReadView const& view,
50 beast::Journal const& j)
51{
52 auto const txType = tx.getTxnType();
53 if ((txType != ttPAYMENT && txType != ttOFFER_CREATE) || !isTesSuccess(result))
54 return true;
55
56 // For each offercreate transaction, check if
57 // permissioned offers are valid
58 if (txType == ttOFFER_CREATE && badHybrids_)
59 {
60 JLOG(j.fatal()) << "Invariant failed: hybrid offer is malformed";
61 return false;
62 }
63
64 if (!tx.isFieldPresent(sfDomainID))
65 return true;
66
67 auto const domain = tx.getFieldH256(sfDomainID);
68
69 if (!view.exists(keylet::permissionedDomain(domain)))
70 {
71 JLOG(j.fatal()) << "Invariant failed: domain doesn't exist";
72 return false;
73 }
74
75 // for both payment and offercreate, there shouldn't be another domain
76 // that's different from the domain specified
77 for (auto const& d : domains_)
78 {
79 if (d != domain)
80 {
81 JLOG(j.fatal()) << "Invariant failed: transaction"
82 " consumed wrong domains";
83 return false;
84 }
85 }
86
88 {
89 JLOG(j.fatal()) << "Invariant failed: domain transaction"
90 " affected regular offers";
91 return false;
92 }
93
94 return true;
95}
96
97} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:40
Stream fatal() const
Definition Journal.h:325
A view into a ledger.
Definition ReadView.h:31
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:456
uint256 getFieldH256(SField const &field) const
Definition STObject.cpp:623
TxType getTxnType() const
Definition STTx.h:188
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 &)
Keylet permissionedDomain(AccountID const &account, std::uint32_t seq) noexcept
Definition Indexes.cpp:522
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:523
bool isTesSuccess(TER x) noexcept
Definition TER.h:651