rippled
Loading...
Searching...
No Matches
TestHelpers.cpp
1#include <test/jtx/TestHelpers.h>
2#include <test/jtx/offer.h>
3#include <test/jtx/owners.h>
4
5#include <xrpl/protocol/TxFlags.h>
6
7namespace xrpl {
8namespace test {
9namespace jtx {
10
11// Functions used in debugging
13getAccountOffers(Env& env, AccountID const& acct, bool current)
14{
15 Json::Value jv;
16 jv[jss::account] = to_string(acct);
17 return env.rpc("json", "account_offers", to_string(jv))[jss::result];
18}
19
21getAccountLines(Env& env, AccountID const& acctId)
22{
23 Json::Value jv;
24 jv[jss::account] = to_string(acctId);
25 return env.rpc("json", "account_lines", to_string(jv))[jss::result];
26}
27
28bool
29checkArraySize(Json::Value const& val, unsigned int size)
30{
31 return val.isArray() && val.size() == size;
32}
33
35ownerCount(Env const& env, Account const& account)
36{
37 return env.ownerCount(account);
38}
39
40/* Path finding */
41/******************************************************************************/
42void
43stpath_append_one(STPath& st, Account const& account)
44{
46}
47
48void
50{
51 st.push_back(pe);
52}
53
54bool
55equal(STAmount const& sa1, STAmount const& sa2)
56{
57 return sa1 == sa2 && sa1.issue().account == sa2.issue().account;
58}
59
60// Issue path element
67
68/******************************************************************************/
69
71txfee(Env const& env, std::uint16_t n)
72{
73 return env.current()->fees().base * n;
74}
75
77xrpMinusFee(Env const& env, std::int64_t xrpAmount)
78{
79 auto feeDrops = env.current()->fees().base;
80 return drops(dropsPerXRP * xrpAmount - feeDrops);
81};
82
83[[nodiscard]] bool
84expectHolding(Env& env, AccountID const& account, STAmount const& value, bool defaultLimits)
85{
86 if (auto const sle = env.le(keylet::line(account, value.issue())))
87 {
88 Issue const issue = value.issue();
89 bool const accountLow = account < issue.account;
90
91 bool expectDefaultTrustLine = true;
92 if (defaultLimits)
93 {
94 STAmount low{issue};
95 STAmount high{issue};
96
97 low.setIssuer(accountLow ? account : issue.account);
98 high.setIssuer(accountLow ? issue.account : account);
99
100 expectDefaultTrustLine = sle->getFieldAmount(sfLowLimit) == low && sle->getFieldAmount(sfHighLimit) == high;
101 }
102
103 auto amount = sle->getFieldAmount(sfBalance);
104 amount.setIssuer(value.issue().account);
105 if (!accountLow)
106 amount.negate();
107 return amount == value && expectDefaultTrustLine;
108 }
109 return false;
110}
111
112[[nodiscard]] bool
113expectHolding(Env& env, AccountID const& account, None const&, Issue const& issue)
114{
115 return !env.le(keylet::line(account, issue));
116}
117
118[[nodiscard]] bool
119expectHolding(Env& env, AccountID const& account, None const&, MPTIssue const& mptIssue)
120{
121 return !env.le(keylet::mptoken(mptIssue.getMptID(), account));
122}
123
124[[nodiscard]] bool
125expectHolding(Env& env, AccountID const& account, None const& value)
126{
127 return std::visit(
128 [&](auto const& issue) { return expectHolding(env, account, value, issue); }, value.asset.value());
129}
130
131[[nodiscard]] bool
132expectOffers(Env& env, AccountID const& account, std::uint16_t size, std::vector<Amounts> const& toMatch)
133{
134 std::uint16_t cnt = 0;
135 std::uint16_t matched = 0;
136 forEachItem(*env.current(), account, [&](std::shared_ptr<SLE const> const& sle) {
137 if (!sle)
138 return false;
139 if (sle->getType() == ltOFFER)
140 {
141 ++cnt;
142 if (std::find_if(toMatch.begin(), toMatch.end(), [&](auto const& a) {
143 return a.in == sle->getFieldAmount(sfTakerPays) && a.out == sle->getFieldAmount(sfTakerGets);
144 }) != toMatch.end())
145 ++matched;
146 }
147 return true;
148 });
149 return size == cnt && matched == toMatch.size();
150}
151
153ledgerEntryRoot(Env& env, Account const& acct)
154{
155 Json::Value jvParams;
156 jvParams[jss::ledger_index] = "current";
157 jvParams[jss::account_root] = acct.human();
158 return env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
159}
160
162ledgerEntryState(Env& env, Account const& acct_a, Account const& acct_b, std::string const& currency)
163{
164 Json::Value jvParams;
165 jvParams[jss::ledger_index] = "current";
166 jvParams[jss::ripple_state][jss::currency] = currency;
167 jvParams[jss::ripple_state][jss::accounts] = Json::arrayValue;
168 jvParams[jss::ripple_state][jss::accounts].append(acct_a.human());
169 jvParams[jss::ripple_state][jss::accounts].append(acct_b.human());
170 return env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
171}
172
174accountBalance(Env& env, Account const& acct)
175{
176 auto const jrr = ledgerEntryRoot(env, acct);
177 return jrr[jss::node][sfBalance.fieldName];
178}
179
180[[nodiscard]] bool
181expectLedgerEntryRoot(Env& env, Account const& acct, STAmount const& expectedValue)
182{
183 return accountBalance(env, acct) == to_string(expectedValue.xrp());
184}
185
186/* Payment Channel */
187/******************************************************************************/
188namespace paychan {
189
192 AccountID const& account,
193 AccountID const& to,
194 STAmount const& amount,
195 NetClock::duration const& settleDelay,
196 PublicKey const& pk,
197 std::optional<NetClock::time_point> const& cancelAfter,
198 std::optional<std::uint32_t> const& dstTag)
199{
200 Json::Value jv;
201 jv[jss::TransactionType] = jss::PaymentChannelCreate;
202 jv[jss::Account] = to_string(account);
203 jv[jss::Destination] = to_string(to);
204 jv[jss::Amount] = amount.getJson(JsonOptions::none);
205 jv[jss::SettleDelay] = settleDelay.count();
206 jv[sfPublicKey.fieldName] = strHex(pk.slice());
207 if (cancelAfter)
208 jv[sfCancelAfter.fieldName] = cancelAfter->time_since_epoch().count();
209 if (dstTag)
210 jv[sfDestinationTag.fieldName] = *dstTag;
211 return jv;
212}
213
216 AccountID const& account,
217 uint256 const& channel,
218 STAmount const& amount,
220{
221 Json::Value jv;
222 jv[jss::TransactionType] = jss::PaymentChannelFund;
223 jv[jss::Account] = to_string(account);
224 jv[sfChannel.fieldName] = to_string(channel);
225 jv[jss::Amount] = amount.getJson(JsonOptions::none);
226 if (expiration)
227 jv[sfExpiration.fieldName] = expiration->time_since_epoch().count();
228 return jv;
229}
230
233 AccountID const& account,
234 uint256 const& channel,
237 std::optional<Slice> const& signature,
238 std::optional<PublicKey> const& pk)
239{
240 Json::Value jv;
241 jv[jss::TransactionType] = jss::PaymentChannelClaim;
242 jv[jss::Account] = to_string(account);
243 jv["Channel"] = to_string(channel);
244 if (amount)
245 jv[jss::Amount] = amount->getJson(JsonOptions::none);
246 if (balance)
247 jv["Balance"] = balance->getJson(JsonOptions::none);
248 if (signature)
249 jv["Signature"] = strHex(*signature);
250 if (pk)
251 jv["PublicKey"] = strHex(pk->slice());
252 return jv;
253}
254
256channel(AccountID const& account, AccountID const& dst, std::uint32_t seqProxyValue)
257{
258 auto const k = keylet::payChan(account, dst, seqProxyValue);
259 return k.key;
260}
261
263channelBalance(ReadView const& view, uint256 const& chan)
264{
265 auto const slep = view.read({ltPAYCHAN, chan});
266 if (!slep)
267 return XRPAmount{-1};
268 return (*slep)[sfBalance];
269}
270
271bool
272channelExists(ReadView const& view, uint256 const& chan)
273{
274 auto const slep = view.read({ltPAYCHAN, chan});
275 return bool(slep);
276}
277
278} // namespace paychan
279
280/* Crossing Limits */
281/******************************************************************************/
282
283void
284n_offers(Env& env, std::size_t n, Account const& account, STAmount const& in, STAmount const& out)
285{
286 auto const ownerCount = env.le(account)->getFieldU32(sfOwnerCount);
287 for (std::size_t i = 0; i < n; i++)
288 {
289 env(offer(account, in, out));
290 env.close();
291 }
292 env.require(owners(account, ownerCount + n));
293}
294
295/* Pay Strand */
296/***************************************************************/
297
298// Currency path element
304
305// All path element
307allpe(AccountID const& a, Issue const& iss)
308{
309 return STPathElement(
311 a,
312 iss.currency,
313 iss.account);
314};
315
316/* LoanBroker */
317/******************************************************************************/
318
319namespace loanBroker {
320
322set(AccountID const& account, uint256 const& vaultId, uint32_t flags)
323{
324 Json::Value jv;
325 jv[sfTransactionType] = jss::LoanBrokerSet;
326 jv[sfAccount] = to_string(account);
327 jv[sfVaultID] = to_string(vaultId);
328 jv[sfFlags] = flags;
329 return jv;
330}
331
333del(AccountID const& account, uint256 const& brokerID, uint32_t flags)
334{
335 Json::Value jv;
336 jv[sfTransactionType] = jss::LoanBrokerDelete;
337 jv[sfAccount] = to_string(account);
338 jv[sfLoanBrokerID] = to_string(brokerID);
339 jv[sfFlags] = flags;
340 return jv;
341}
342
344coverDeposit(AccountID const& account, uint256 const& brokerID, STAmount const& amount, uint32_t flags)
345{
346 Json::Value jv;
347 jv[sfTransactionType] = jss::LoanBrokerCoverDeposit;
348 jv[sfAccount] = to_string(account);
349 jv[sfLoanBrokerID] = to_string(brokerID);
350 jv[sfAmount] = amount.getJson(JsonOptions::none);
351 jv[sfFlags] = flags;
352 return jv;
353}
354
356coverWithdraw(AccountID const& account, uint256 const& brokerID, STAmount const& amount, uint32_t flags)
357{
358 Json::Value jv;
359 jv[sfTransactionType] = jss::LoanBrokerCoverWithdraw;
360 jv[sfAccount] = to_string(account);
361 jv[sfLoanBrokerID] = to_string(brokerID);
362 jv[sfAmount] = amount.getJson(JsonOptions::none);
363 jv[sfFlags] = flags;
364 return jv;
365}
366
369{
370 Json::Value jv;
371 jv[sfTransactionType] = jss::LoanBrokerCoverClawback;
372 jv[sfAccount] = to_string(account);
373 jv[sfFlags] = flags;
374 return jv;
375}
376
377} // namespace loanBroker
378
379/* Loan */
380/******************************************************************************/
381namespace loan {
382
384set(AccountID const& account, uint256 const& loanBrokerID, Number principalRequested, std::uint32_t flags)
385{
386 Json::Value jv;
387 jv[sfTransactionType] = jss::LoanSet;
388 jv[sfAccount] = to_string(account);
389 jv[sfLoanBrokerID] = to_string(loanBrokerID);
390 jv[sfPrincipalRequested] = to_string(principalRequested);
391 jv[sfFlags] = flags;
392 return jv;
393}
394
396manage(AccountID const& account, uint256 const& loanID, std::uint32_t flags)
397{
398 Json::Value jv;
399 jv[sfTransactionType] = jss::LoanManage;
400 jv[sfAccount] = to_string(account);
401 jv[sfLoanID] = to_string(loanID);
402 jv[sfFlags] = flags;
403 return jv;
404}
405
407del(AccountID const& account, uint256 const& loanID, std::uint32_t flags)
408{
409 Json::Value jv;
410 jv[sfTransactionType] = jss::LoanDelete;
411 jv[sfAccount] = to_string(account);
412 jv[sfLoanID] = to_string(loanID);
413 jv[sfFlags] = flags;
414 return jv;
415}
416
418pay(AccountID const& account, uint256 const& loanID, STAmount const& amount, std::uint32_t flags)
419{
420 Json::Value jv;
421 jv[sfTransactionType] = jss::LoanPay;
422 jv[sfAccount] = to_string(account);
423 jv[sfLoanID] = to_string(loanID);
424 jv[sfAmount] = amount.getJson();
425 jv[sfFlags] = flags;
426 return jv;
427}
428
429} // namespace loan
430} // namespace jtx
431} // namespace test
432} // namespace xrpl
Represents a JSON value.
Definition json_value.h:131
bool isArray() const
Value & append(Value const &value)
Append value to array at the end.
UInt size() const
Number of values in array or object.
constexpr value_type const & value() const
Definition Asset.h:155
A currency issued by an account.
Definition Issue.h:14
Currency currency
Definition Issue.h:16
AccountID account
Definition Issue.h:17
constexpr MPTID const & getMptID() const
Definition MPTIssue.h:27
Number is a floating point type that can represent a wide range of values.
Definition Number.h:208
A public key.
Definition PublicKey.h:43
Slice slice() const noexcept
Definition PublicKey.h:104
A view into a ledger.
Definition ReadView.h:32
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
Issue const & issue() const
Definition STAmount.h:455
XRPAmount xrp() const
Definition STAmount.cpp:249
void push_back(STPathElement const &e)
Definition STPathSet.h:370
Immutable cryptographic account descriptor.
Definition Account.h:20
std::string const & human() const
Returns the human readable public key.
Definition Account.h:95
A transaction testing environment.
Definition Env.h:98
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:97
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition Env.cpp:230
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition Env.cpp:248
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition Env.h:749
void require(Args const &... args)
Check a set of requirements.
Definition Env.h:512
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:298
A balance matches.
Definition balance.h:20
Set Expiration on a JTx.
Match set account flags.
Definition flags.h:109
Match the number of items in the account's owner directory.
Definition owners.h:49
T is_same_v
@ arrayValue
array value (ordered list)
Definition json_value.h:26
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Definition Indexes.cpp:346
Keylet line(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition Indexes.cpp:214
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:474
Json::Value coverDeposit(AccountID const &account, uint256 const &brokerID, STAmount const &amount, uint32_t flags)
Json::Value coverWithdraw(AccountID const &account, uint256 const &brokerID, STAmount const &amount, uint32_t flags)
Json::Value del(AccountID const &account, uint256 const &brokerID, uint32_t flags)
Json::Value coverClawback(AccountID const &account, std::uint32_t flags)
Json::Value pay(AccountID const &account, uint256 const &loanID, STAmount const &amount, std::uint32_t flags)
Json::Value manage(AccountID const &account, uint256 const &loanID, std::uint32_t flags)
Json::Value del(AccountID const &account, uint256 const &loanID, std::uint32_t flags)
STAmount channelBalance(ReadView const &view, uint256 const &chan)
uint256 channel(AccountID const &account, AccountID const &dst, std::uint32_t seqProxyValue)
Json::Value claim(AccountID const &account, uint256 const &channel, std::optional< STAmount > const &balance, std::optional< STAmount > const &amount, std::optional< Slice > const &signature, std::optional< PublicKey > const &pk)
Json::Value fund(AccountID const &account, uint256 const &channel, STAmount const &amount, std::optional< NetClock::time_point > const &expiration)
bool channelExists(ReadView const &view, uint256 const &chan)
Json::Value create(AccountID const &account, AccountID const &to, STAmount const &amount, NetClock::duration const &settleDelay, PublicKey const &pk, std::optional< NetClock::time_point > const &cancelAfter, std::optional< std::uint32_t > const &dstTag)
bool expectLedgerEntryRoot(Env &env, Account const &acct, STAmount const &expectedValue)
Json::Value getAccountOffers(Env &env, AccountID const &acct, bool current)
PrettyAmount xrpMinusFee(Env const &env, std::int64_t xrpAmount)
bool expectOffers(Env &env, AccountID const &account, std::uint16_t size, std::vector< Amounts > const &toMatch)
bool expectHolding(Env &env, AccountID const &account, STAmount const &value, bool defaultLimits)
Json::Value ledgerEntryState(Env &env, Account const &acct_a, Account const &acct_b, std::string const &currency)
std::uint32_t ownerCount(Env const &env, Account const &account)
XRPAmount txfee(Env const &env, std::uint16_t n)
STPathElement allpe(AccountID const &a, Issue const &iss)
Json::Value accountBalance(Env &env, Account const &acct)
STPathElement IPE(Issue const &iss)
STPathElement cpe(Currency const &c)
Json::Value ledgerEntryRoot(Env &env, Account const &acct)
bool equal(STAmount const &sa1, STAmount const &sa2)
constexpr XRPAmount dropsPerXRP
auto const amount
bool checkArraySize(Json::Value const &val, unsigned int size)
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
void stpath_append_one(STPath &st, Account const &account)
void n_offers(Env &env, std::size_t n, Account const &account, STAmount const &in, STAmount const &out)
Json::Value getAccountLines(Env &env, AccountID const &acctId)
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
Definition offer.cpp:10
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:598
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:11
void forEachItem(ReadView const &view, Keylet const &root, std::function< void(std::shared_ptr< SLE const > const &)> const &f)
Iterate all items in the given directory.
Definition View.cpp:598
@ current
This was a new validation and was added.
AccountID const & xrpAccount()
Compute AccountID from public key.
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
T visit(T... args)