xrpld
Loading...
Searching...
No Matches
InvariantsTrustLine_test.cpp
1#include <test/app/invariants/InvariantsBase.h>
2#include <test/jtx/Account.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/amount.h>
5#include <test/jtx/pay.h>
6#include <test/jtx/trust.h>
7#include <test/jtx/vault.h>
8
9#include <xrpl/beast/unit_test/suite.h>
10#include <xrpl/ledger/ApplyView.h>
11#include <xrpl/protocol/Indexes.h>
12#include <xrpl/protocol/Issue.h>
13#include <xrpl/protocol/LedgerFormats.h>
14#include <xrpl/protocol/SField.h>
15#include <xrpl/protocol/STLedgerEntry.h>
16#include <xrpl/protocol/STObject.h>
17#include <xrpl/protocol/STTx.h>
18#include <xrpl/protocol/TER.h>
19#include <xrpl/protocol/TxFlags.h>
20#include <xrpl/protocol/TxFormats.h>
21#include <xrpl/protocol/XRPAmount.h>
22#include <xrpl/tx/ApplyContext.h>
23#include <xrpl/tx/applySteps.h>
24
25#include <cstdint>
26#include <functional>
27#include <initializer_list>
28#include <memory>
29#include <string>
30#include <vector>
31
32namespace xrpl::test {
33
35{
36 void
38 {
39 using namespace test::jtx;
40 testcase << "trust lines with XRP not allowed";
42 {{"an XRP trust line was created"}},
43 [](Account const& a1, Account const& a2, ApplyContext& ac) {
44 // create simple trust SLE with xrp currency
45 auto const sleNew =
47 ac.view().insert(sleNew);
48 return true;
49 });
50 }
51
52 void
54 {
55 using namespace test::jtx;
56 testcase << "trust lines with deep freeze flag without freeze "
57 "not allowed";
59 {{"a trust line with deep freeze flag without normal freeze was "
60 "created"}},
61 [](Account const& a1, Account const& a2, ApplyContext& ac) {
62 auto const sleNew =
63 std::make_shared<SLE>(keylet::trustLine(a1, a2, a1["USD"].currency));
64 sleNew->setFieldAmount(sfLowLimit, a1["USD"](0));
65 sleNew->setFieldAmount(sfHighLimit, a1["USD"](0));
66
67 std::uint32_t uFlags = 0u;
68 uFlags |= lsfLowDeepFreeze;
69 sleNew->setFieldU32(sfFlags, uFlags);
70 ac.view().insert(sleNew);
71 return true;
72 });
73
75 {{"a trust line with deep freeze flag without normal freeze was "
76 "created"}},
77 [](Account const& a1, Account const& a2, ApplyContext& ac) {
78 auto const sleNew =
79 std::make_shared<SLE>(keylet::trustLine(a1, a2, a1["USD"].currency));
80 sleNew->setFieldAmount(sfLowLimit, a1["USD"](0));
81 sleNew->setFieldAmount(sfHighLimit, a1["USD"](0));
82 std::uint32_t uFlags = 0u;
83 uFlags |= lsfHighDeepFreeze;
84 sleNew->setFieldU32(sfFlags, uFlags);
85 ac.view().insert(sleNew);
86 return true;
87 });
88
90 {{"a trust line with deep freeze flag without normal freeze was "
91 "created"}},
92 [](Account const& a1, Account const& a2, ApplyContext& ac) {
93 auto const sleNew =
94 std::make_shared<SLE>(keylet::trustLine(a1, a2, a1["USD"].currency));
95 sleNew->setFieldAmount(sfLowLimit, a1["USD"](0));
96 sleNew->setFieldAmount(sfHighLimit, a1["USD"](0));
97 std::uint32_t uFlags = 0u;
98 uFlags |= lsfLowDeepFreeze | lsfHighDeepFreeze;
99 sleNew->setFieldU32(sfFlags, uFlags);
100 ac.view().insert(sleNew);
101 return true;
102 });
103
105 {{"a trust line with deep freeze flag without normal freeze was "
106 "created"}},
107 [](Account const& a1, Account const& a2, ApplyContext& ac) {
108 auto const sleNew =
109 std::make_shared<SLE>(keylet::trustLine(a1, a2, a1["USD"].currency));
110 sleNew->setFieldAmount(sfLowLimit, a1["USD"](0));
111 sleNew->setFieldAmount(sfHighLimit, a1["USD"](0));
112 std::uint32_t uFlags = 0u;
113 uFlags |= lsfLowDeepFreeze | lsfHighFreeze;
114 sleNew->setFieldU32(sfFlags, uFlags);
115 ac.view().insert(sleNew);
116 return true;
117 });
118
120 {{"a trust line with deep freeze flag without normal freeze was "
121 "created"}},
122 [](Account const& a1, Account const& a2, ApplyContext& ac) {
123 auto const sleNew =
124 std::make_shared<SLE>(keylet::trustLine(a1, a2, a1["USD"].currency));
125 sleNew->setFieldAmount(sfLowLimit, a1["USD"](0));
126 sleNew->setFieldAmount(sfHighLimit, a1["USD"](0));
127 std::uint32_t uFlags = 0u;
128 uFlags |= lsfLowFreeze | lsfHighDeepFreeze;
129 sleNew->setFieldU32(sfFlags, uFlags);
130 ac.view().insert(sleNew);
131 return true;
132 });
133 }
134
135 void
137 {
138 using namespace test::jtx;
139 testcase << "transfers when frozen";
140
141 Account const g1{"G1"};
142 // Helper function to establish the trustlines
143 auto const createTrustlines = [&](Account const& a1, Account const& a2, Env& env) {
144 // Preclose callback to establish trust lines with gateway
145 env.fund(XRP(1000), g1);
146
147 env.trust(g1["USD"](10000), a1);
148 env.trust(g1["USD"](10000), a2);
149 env.close();
150
151 env(pay(g1, a1, g1["USD"](1000)));
152 env(pay(g1, a2, g1["USD"](1000)));
153 env.close();
154
155 return true;
156 };
157
158 auto const a1FrozenByIssuer = [&](Account const& a1, Account const& a2, Env& env) {
159 createTrustlines(a1, a2, env);
160 env(trust(g1, a1["USD"](10000), tfSetFreeze));
161 env.close();
162
163 return true;
164 };
165
166 auto const a1DeepFrozenByIssuer = [&](Account const& a1, Account const& a2, Env& env) {
167 a1FrozenByIssuer(a1, a2, env);
168 env(trust(g1, a1["USD"](10000), tfSetDeepFreeze));
169 env.close();
170
171 return true;
172 };
173
174 auto const changeBalances = [&](Account const& a1,
175 Account const& a2,
176 ApplyContext& ac,
177 int a1Balance,
178 int a2Balance) {
179 auto const sleA1 = ac.view().peek(keylet::trustLine(a1, g1["USD"]));
180 auto const sleA2 = ac.view().peek(keylet::trustLine(a2, g1["USD"]));
181
182 sleA1->setFieldAmount(sfBalance, g1["USD"](a1Balance));
183 sleA2->setFieldAmount(sfBalance, g1["USD"](a2Balance));
184
185 ac.view().update(sleA1);
186 ac.view().update(sleA2);
187 };
188
189 // test: imitating frozen A1 making a payment to A2.
191 {{"Attempting to move frozen funds"}},
192 [&](Account const& a1, Account const& a2, ApplyContext& ac) {
193 changeBalances(a1, a2, ac, -900, -1100);
194 return true;
195 },
196 XRPAmount{},
197 STTx{ttPAYMENT, [](STObject& tx) {}},
199 a1FrozenByIssuer);
200
201 // test: imitating deep frozen A1 making a payment to A2.
203 {{"Attempting to move frozen funds"}},
204 [&](Account const& a1, Account const& a2, ApplyContext& ac) {
205 changeBalances(a1, a2, ac, -900, -1100);
206 return true;
207 },
208 XRPAmount{},
209 STTx{ttPAYMENT, [](STObject& tx) {}},
211 a1DeepFrozenByIssuer);
212
213 // test: imitating A2 making a payment to deep frozen A1.
215 {{"Attempting to move frozen funds"}},
216 [&](Account const& a1, Account const& a2, ApplyContext& ac) {
217 changeBalances(a1, a2, ac, -1100, -900);
218 return true;
219 },
220 XRPAmount{},
221 STTx{ttPAYMENT, [](STObject& tx) {}},
223 a1DeepFrozenByIssuer);
224 }
225
226 void
233};
234
235BEAST_DEFINE_TESTSUITE(InvariantsTrustLine, app, xrpl);
236
237} // namespace xrpl::test
TestcaseT testcase
Memberspace for declaring test cases.
Definition suite.h:155
State information when applying a tx.
void doInvariantCheck(std::vector< std::string > const &expectLogs, Precheck const &precheck, XRPAmount fee=XRPAmount{}, STTx tx=STTx{ttACCOUNT_SET, [](STObject &) {}}, std::initializer_list< TER > ters={tecINVARIANT_FAILED, tefINVARIANT_FAILED}, Preclose const &preclose={}, TxAccount setTxAccount=TxAccount::None, std::source_location const &loc=std::source_location::current(), TER initialResult=tesSUCCESS)
Run a specific test case to put the ledger into a state that will be detected by an invariant.
Immutable cryptographic account descriptor.
Definition jtx/Account.h:21
A transaction testing environment.
Definition Env.h:161
T make_shared(T... args)
Keylet trustLine(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition Indexes.cpp:275
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Definition pay.cpp:14
XrpT const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:92
json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Definition trust.cpp:18
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
constexpr XRPAmount
Convert XRP to drops (integral types).
Definition TxTest.h:54
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition Issue.h:108
@ tefINVARIANT_FAILED
Definition TER.h:178
@ tecINVARIANT_FAILED
Definition TER.h:321