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/ledger/helpers/DirectoryHelpers.h>
6#include <xrpl/protocol/TxFlags.h>
7
8namespace xrpl {
9namespace test {
10namespace jtx {
11
12// Functions used in debugging
14getAccountOffers(Env& env, AccountID const& acct, bool current)
15{
16 Json::Value jv;
17 jv[jss::account] = to_string(acct);
18 return env.rpc("json", "account_offers", to_string(jv))[jss::result];
19}
20
22getAccountLines(Env& env, AccountID const& acctId)
23{
24 Json::Value jv;
25 jv[jss::account] = to_string(acctId);
26 return env.rpc("json", "account_lines", to_string(jv))[jss::result];
27}
28
29bool
30checkArraySize(Json::Value const& val, unsigned int size)
31{
32 return val.isArray() && val.size() == size;
33}
34
36ownerCount(Env const& env, Account const& account)
37{
38 return env.ownerCount(account);
39}
40
41/* Path finding */
42/******************************************************************************/
43void
44stpath_append_one(STPath& st, Account const& account)
45{
47}
48
49void
51{
52 st.push_back(pe);
53}
54
55bool
56equal(STAmount const& sa1, STAmount const& sa2)
57{
58 return sa1 == sa2 && sa1.issue().account == sa2.issue().account;
59}
60
61// Issue path element
63IPE(Issue const& iss)
64{
65 return STPathElement(
67 xrpAccount(),
68 iss.currency,
69 iss.account);
70}
71
72/******************************************************************************/
73
75txfee(Env const& env, std::uint16_t n)
76{
77 return env.current()->fees().base * n;
78}
79
81xrpMinusFee(Env const& env, std::int64_t xrpAmount)
82{
83 auto feeDrops = env.current()->fees().base;
84 return drops(dropsPerXRP * xrpAmount - feeDrops);
85};
86
87[[nodiscard]] bool
88expectHolding(Env& env, AccountID const& account, STAmount const& value, bool defaultLimits)
89{
90 if (auto const sle = env.le(keylet::line(account, value.issue())))
91 {
92 Issue const issue = value.issue();
93 bool const accountLow = account < issue.account;
94
95 bool expectDefaultTrustLine = true;
96 if (defaultLimits)
97 {
98 STAmount low{issue};
99 STAmount high{issue};
100
101 low.setIssuer(accountLow ? account : issue.account);
102 high.setIssuer(accountLow ? issue.account : account);
103
104 expectDefaultTrustLine =
105 sle->getFieldAmount(sfLowLimit) == low && sle->getFieldAmount(sfHighLimit) == high;
106 }
107
108 auto amount = sle->getFieldAmount(sfBalance);
109 amount.setIssuer(value.issue().account);
110 if (!accountLow)
111 amount.negate();
112 return amount == value && expectDefaultTrustLine;
113 }
114 return false;
115}
116
117[[nodiscard]] bool
118expectHolding(Env& env, AccountID const& account, None const&, Issue const& issue)
119{
120 return !env.le(keylet::line(account, issue));
121}
122
123[[nodiscard]] bool
124expectHolding(Env& env, AccountID const& account, None const&, MPTIssue const& mptIssue)
125{
126 return !env.le(keylet::mptoken(mptIssue.getMptID(), account));
127}
128
129[[nodiscard]] bool
130expectHolding(Env& env, AccountID const& account, None const& value)
131{
132 return std::visit(
133 [&](auto const& issue) { return expectHolding(env, account, value, issue); },
134 value.asset.value());
135}
136
137[[nodiscard]] bool
139 Env& env,
140 AccountID const& account,
141 std::uint16_t size,
142 std::vector<Amounts> const& toMatch)
143{
144 std::uint16_t cnt = 0;
145 std::uint16_t matched = 0;
146 forEachItem(*env.current(), account, [&](std::shared_ptr<SLE const> const& sle) {
147 if (!sle)
148 return false;
149 if (sle->getType() == ltOFFER)
150 {
151 ++cnt;
152 if (std::find_if(toMatch.begin(), toMatch.end(), [&](auto const& a) {
153 return a.in == sle->getFieldAmount(sfTakerPays) &&
154 a.out == sle->getFieldAmount(sfTakerGets);
155 }) != toMatch.end())
156 ++matched;
157 }
158 return true;
159 });
160 return size == cnt && matched == toMatch.size();
161}
162
164ledgerEntryRoot(Env& env, Account const& acct)
165{
166 Json::Value jvParams;
167 jvParams[jss::ledger_index] = "current";
168 jvParams[jss::account_root] = acct.human();
169 return env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
170}
171
174 Env& env,
175 Account const& acct_a,
176 Account const& acct_b,
177 std::string const& currency)
178{
179 Json::Value jvParams;
180 jvParams[jss::ledger_index] = "current";
181 jvParams[jss::ripple_state][jss::currency] = currency;
182 jvParams[jss::ripple_state][jss::accounts] = Json::arrayValue;
183 jvParams[jss::ripple_state][jss::accounts].append(acct_a.human());
184 jvParams[jss::ripple_state][jss::accounts].append(acct_b.human());
185 return env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
186}
187
189accountBalance(Env& env, Account const& acct)
190{
191 auto const jrr = ledgerEntryRoot(env, acct);
192 return jrr[jss::node][sfBalance.fieldName];
193}
194
195[[nodiscard]] bool
196expectLedgerEntryRoot(Env& env, Account const& acct, STAmount const& expectedValue)
197{
198 return accountBalance(env, acct) == to_string(expectedValue.xrp());
199}
200
201/* Payment Channel */
202/******************************************************************************/
203namespace paychan {
204
207 AccountID const& account,
208 AccountID const& to,
209 STAmount const& amount,
210 NetClock::duration const& settleDelay,
211 PublicKey const& pk,
212 std::optional<NetClock::time_point> const& cancelAfter,
213 std::optional<std::uint32_t> const& dstTag)
214{
215 Json::Value jv;
216 jv[jss::TransactionType] = jss::PaymentChannelCreate;
217 jv[jss::Account] = to_string(account);
218 jv[jss::Destination] = to_string(to);
219 jv[jss::Amount] = amount.getJson(JsonOptions::none);
220 jv[jss::SettleDelay] = settleDelay.count();
221 jv[sfPublicKey.fieldName] = strHex(pk.slice());
222 if (cancelAfter)
223 jv[sfCancelAfter.fieldName] = cancelAfter->time_since_epoch().count();
224 if (dstTag)
225 jv[sfDestinationTag.fieldName] = *dstTag;
226 return jv;
227}
228
231 AccountID const& account,
232 uint256 const& channel,
233 STAmount const& amount,
235{
236 Json::Value jv;
237 jv[jss::TransactionType] = jss::PaymentChannelFund;
238 jv[jss::Account] = to_string(account);
239 jv[sfChannel.fieldName] = to_string(channel);
240 jv[jss::Amount] = amount.getJson(JsonOptions::none);
241 if (expiration)
242 jv[sfExpiration.fieldName] = expiration->time_since_epoch().count();
243 return jv;
244}
245
248 AccountID const& account,
249 uint256 const& channel,
252 std::optional<Slice> const& signature,
253 std::optional<PublicKey> const& pk)
254{
255 Json::Value jv;
256 jv[jss::TransactionType] = jss::PaymentChannelClaim;
257 jv[jss::Account] = to_string(account);
258 jv["Channel"] = to_string(channel);
259 if (amount)
260 jv[jss::Amount] = amount->getJson(JsonOptions::none);
261 if (balance)
262 jv["Balance"] = balance->getJson(JsonOptions::none);
263 if (signature)
264 jv["Signature"] = strHex(*signature);
265 if (pk)
266 jv["PublicKey"] = strHex(pk->slice());
267 return jv;
268}
269
271channel(AccountID const& account, AccountID const& dst, std::uint32_t seqProxyValue)
272{
273 auto const k = keylet::payChan(account, dst, seqProxyValue);
274 return k.key;
275}
276
278channelBalance(ReadView const& view, uint256 const& chan)
279{
280 auto const slep = view.read({ltPAYCHAN, chan});
281 if (!slep)
282 return XRPAmount{-1};
283 return (*slep)[sfBalance];
284}
285
286bool
287channelExists(ReadView const& view, uint256 const& chan)
288{
289 auto const slep = view.read({ltPAYCHAN, chan});
290 return bool(slep);
291}
292
293} // namespace paychan
294
295/* Crossing Limits */
296/******************************************************************************/
297
298void
299n_offers(Env& env, std::size_t n, Account const& account, STAmount const& in, STAmount const& out)
300{
301 auto const ownerCount = env.le(account)->getFieldU32(sfOwnerCount);
302 for (std::size_t i = 0; i < n; i++)
303 {
304 env(offer(account, in, out));
305 env.close();
306 }
307 env.require(owners(account, ownerCount + n));
308}
309
310/* Pay Strand */
311/***************************************************************/
312
313// Currency path element
319
320// All path element
330
331/* LoanBroker */
332/******************************************************************************/
333
334namespace loanBroker {
335
337set(AccountID const& account, uint256 const& vaultId, uint32_t flags)
338{
339 Json::Value jv;
340 jv[sfTransactionType] = jss::LoanBrokerSet;
341 jv[sfAccount] = to_string(account);
342 jv[sfVaultID] = to_string(vaultId);
343 jv[sfFlags] = flags;
344 return jv;
345}
346
348del(AccountID const& account, uint256 const& brokerID, uint32_t flags)
349{
350 Json::Value jv;
351 jv[sfTransactionType] = jss::LoanBrokerDelete;
352 jv[sfAccount] = to_string(account);
353 jv[sfLoanBrokerID] = to_string(brokerID);
354 jv[sfFlags] = flags;
355 return jv;
356}
357
360 AccountID const& account,
361 uint256 const& brokerID,
362 STAmount const& amount,
363 uint32_t flags)
364{
365 Json::Value jv;
366 jv[sfTransactionType] = jss::LoanBrokerCoverDeposit;
367 jv[sfAccount] = to_string(account);
368 jv[sfLoanBrokerID] = to_string(brokerID);
369 jv[sfAmount] = amount.getJson(JsonOptions::none);
370 jv[sfFlags] = flags;
371 return jv;
372}
373
376 AccountID const& account,
377 uint256 const& brokerID,
378 STAmount const& amount,
379 uint32_t flags)
380{
381 Json::Value jv;
382 jv[sfTransactionType] = jss::LoanBrokerCoverWithdraw;
383 jv[sfAccount] = to_string(account);
384 jv[sfLoanBrokerID] = to_string(brokerID);
385 jv[sfAmount] = amount.getJson(JsonOptions::none);
386 jv[sfFlags] = flags;
387 return jv;
388}
389
392{
393 Json::Value jv;
394 jv[sfTransactionType] = jss::LoanBrokerCoverClawback;
395 jv[sfAccount] = to_string(account);
396 jv[sfFlags] = flags;
397 return jv;
398}
399
400} // namespace loanBroker
401
402/* Loan */
403/******************************************************************************/
404namespace loan {
405
407set(AccountID const& account,
408 uint256 const& loanBrokerID,
409 Number principalRequested,
411{
412 Json::Value jv;
413 jv[sfTransactionType] = jss::LoanSet;
414 jv[sfAccount] = to_string(account);
415 jv[sfLoanBrokerID] = to_string(loanBrokerID);
416 jv[sfPrincipalRequested] = to_string(principalRequested);
417 jv[sfFlags] = flags;
418 return jv;
419}
420
422manage(AccountID const& account, uint256 const& loanID, std::uint32_t flags)
423{
424 Json::Value jv;
425 jv[sfTransactionType] = jss::LoanManage;
426 jv[sfAccount] = to_string(account);
427 jv[sfLoanID] = to_string(loanID);
428 jv[sfFlags] = flags;
429 return jv;
430}
431
433del(AccountID const& account, uint256 const& loanID, std::uint32_t flags)
434{
435 Json::Value jv;
436 jv[sfTransactionType] = jss::LoanDelete;
437 jv[sfAccount] = to_string(account);
438 jv[sfLoanID] = to_string(loanID);
439 jv[sfFlags] = flags;
440 return jv;
441}
442
444pay(AccountID const& account, uint256 const& loanID, STAmount const& amount, std::uint32_t flags)
445{
446 Json::Value jv;
447 jv[sfTransactionType] = jss::LoanPay;
448 jv[sfAccount] = to_string(account);
449 jv[sfLoanID] = to_string(loanID);
450 jv[sfAmount] = amount.getJson();
451 jv[sfFlags] = flags;
452 return jv;
453}
454
455} // namespace loan
456} // namespace jtx
457} // namespace test
458} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
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:154
A currency issued by an account.
Definition Issue.h:13
Currency currency
Definition Issue.h:15
AccountID account
Definition Issue.h:16
constexpr MPTID const & getMptID() const
Definition MPTIssue.h:26
Number is a floating point type that can represent a wide range of values.
Definition Number.h:207
A public key.
Definition PublicKey.h:42
Slice slice() const noexcept
Definition PublicKey.h:103
A view into a ledger.
Definition ReadView.h:31
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:470
XRPAmount xrp() const
Definition STAmount.cpp:261
void push_back(STPathElement const &e)
Definition STPathSet.h:382
Immutable cryptographic account descriptor.
Definition Account.h:19
std::string const & human() const
Returns the human readable public key.
Definition Account.h:94
A transaction testing environment.
Definition Env.h:122
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:100
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition Env.cpp:240
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition Env.cpp:258
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:847
void require(Args const &... args)
Check a set of requirements.
Definition Env.h:588
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:329
A balance matches.
Definition balance.h:19
Set Expiration on a JTx.
Match set account flags.
Definition flags.h:108
Match the number of items in the account's owner directory.
Definition owners.h:52
T is_same_v
@ arrayValue
array value (ordered list)
Definition json_value.h:25
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Definition Indexes.cpp:357
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:220
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:486
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 allPathElements(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
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:5
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:602
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:10
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.
@ 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)