rippled
Loading...
Searching...
No Matches
TestHelpers.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2023 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <test/jtx/TestHelpers.h>
21#include <test/jtx/offer.h>
22#include <test/jtx/owners.h>
23
24#include <xrpl/protocol/TxFlags.h>
25
26namespace ripple {
27namespace test {
28namespace jtx {
29
30// Functions used in debugging
32getAccountOffers(Env& env, AccountID const& acct, bool current)
33{
34 Json::Value jv;
35 jv[jss::account] = to_string(acct);
36 return env.rpc("json", "account_offers", to_string(jv))[jss::result];
37}
38
40getAccountLines(Env& env, AccountID const& acctId)
41{
42 Json::Value jv;
43 jv[jss::account] = to_string(acctId);
44 return env.rpc("json", "account_lines", to_string(jv))[jss::result];
45}
46
47bool
48checkArraySize(Json::Value const& val, unsigned int size)
49{
50 return val.isArray() && val.size() == size;
51}
52
54ownerCount(Env const& env, Account const& account)
55{
56 return env.ownerCount(account);
57}
58
59/* Path finding */
60/******************************************************************************/
61void
62stpath_append_one(STPath& st, Account const& account)
63{
65}
66
67void
69{
70 st.push_back(pe);
71}
72
73bool
74equal(STAmount const& sa1, STAmount const& sa2)
75{
76 return sa1 == sa2 && sa1.issue().account == sa2.issue().account;
77}
78
79// Issue path element
81IPE(Issue const& iss)
82{
83 return STPathElement(
85 xrpAccount(),
86 iss.currency,
87 iss.account);
88}
89
90/******************************************************************************/
91
93txfee(Env const& env, std::uint16_t n)
94{
95 return env.current()->fees().base * n;
96}
97
99xrpMinusFee(Env const& env, std::int64_t xrpAmount)
100{
101 auto feeDrops = env.current()->fees().base;
102 return drops(dropsPerXRP * xrpAmount - feeDrops);
103};
104
105[[nodiscard]] bool
107 Env& env,
108 AccountID const& account,
109 STAmount const& value,
110 bool defaultLimits)
111{
112 if (auto const sle = env.le(keylet::line(account, value.issue())))
113 {
114 Issue const issue = value.issue();
115 bool const accountLow = account < issue.account;
116
117 bool expectDefaultTrustLine = true;
118 if (defaultLimits)
119 {
120 STAmount low{issue};
121 STAmount high{issue};
122
123 low.setIssuer(accountLow ? account : issue.account);
124 high.setIssuer(accountLow ? issue.account : account);
125
126 expectDefaultTrustLine = sle->getFieldAmount(sfLowLimit) == low &&
127 sle->getFieldAmount(sfHighLimit) == high;
128 }
129
130 auto amount = sle->getFieldAmount(sfBalance);
131 amount.setIssuer(value.issue().account);
132 if (!accountLow)
133 amount.negate();
134 return amount == value && expectDefaultTrustLine;
135 }
136 return false;
137}
138
139[[nodiscard]] bool
140expectLine(Env& env, AccountID const& account, None const& value)
141{
142 return !env.le(keylet::line(account, value.issue));
143}
144
145[[nodiscard]] bool
147 Env& env,
148 AccountID const& account,
149 std::uint16_t size,
150 std::vector<Amounts> const& toMatch)
151{
152 std::uint16_t cnt = 0;
153 std::uint16_t matched = 0;
155 *env.current(), account, [&](std::shared_ptr<SLE const> const& sle) {
156 if (!sle)
157 return false;
158 if (sle->getType() == ltOFFER)
159 {
160 ++cnt;
161 if (std::find_if(
162 toMatch.begin(), toMatch.end(), [&](auto const& a) {
163 return a.in == sle->getFieldAmount(sfTakerPays) &&
164 a.out == sle->getFieldAmount(sfTakerGets);
165 }) != toMatch.end())
166 ++matched;
167 }
168 return true;
169 });
170 return size == cnt && matched == toMatch.size();
171}
172
174ledgerEntryRoot(Env& env, Account const& acct)
175{
176 Json::Value jvParams;
177 jvParams[jss::ledger_index] = "current";
178 jvParams[jss::account_root] = acct.human();
179 return env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
180}
181
184 Env& env,
185 Account const& acct_a,
186 Account const& acct_b,
187 std::string const& currency)
188{
189 Json::Value jvParams;
190 jvParams[jss::ledger_index] = "current";
191 jvParams[jss::ripple_state][jss::currency] = currency;
192 jvParams[jss::ripple_state][jss::accounts] = Json::arrayValue;
193 jvParams[jss::ripple_state][jss::accounts].append(acct_a.human());
194 jvParams[jss::ripple_state][jss::accounts].append(acct_b.human());
195 return env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
196}
197
199accountBalance(Env& env, Account const& acct)
200{
201 auto const jrr = ledgerEntryRoot(env, acct);
202 return jrr[jss::node][sfBalance.fieldName];
203}
204
205[[nodiscard]] bool
207 Env& env,
208 Account const& acct,
209 STAmount const& expectedValue)
210{
211 return accountBalance(env, acct) == to_string(expectedValue.xrp());
212}
213
214/* Payment Channel */
215/******************************************************************************/
218 AccountID const& account,
219 AccountID const& to,
220 STAmount const& amount,
221 NetClock::duration const& settleDelay,
222 PublicKey const& pk,
223 std::optional<NetClock::time_point> const& cancelAfter,
224 std::optional<std::uint32_t> const& dstTag)
225{
226 Json::Value jv;
227 jv[jss::TransactionType] = jss::PaymentChannelCreate;
228 jv[jss::Account] = to_string(account);
229 jv[jss::Destination] = to_string(to);
230 jv[jss::Amount] = amount.getJson(JsonOptions::none);
231 jv[jss::SettleDelay] = settleDelay.count();
232 jv[sfPublicKey.fieldName] = strHex(pk.slice());
233 if (cancelAfter)
234 jv[sfCancelAfter.fieldName] = cancelAfter->time_since_epoch().count();
235 if (dstTag)
236 jv[sfDestinationTag.fieldName] = *dstTag;
237 return jv;
238}
239
242 AccountID const& account,
243 uint256 const& channel,
244 STAmount const& amount,
246{
247 Json::Value jv;
248 jv[jss::TransactionType] = jss::PaymentChannelFund;
249 jv[jss::Account] = to_string(account);
250 jv[sfChannel.fieldName] = to_string(channel);
251 jv[jss::Amount] = amount.getJson(JsonOptions::none);
252 if (expiration)
253 jv[sfExpiration.fieldName] = expiration->time_since_epoch().count();
254 return jv;
255}
256
259 AccountID const& account,
260 uint256 const& channel,
262 std::optional<STAmount> const& amount,
263 std::optional<Slice> const& signature,
264 std::optional<PublicKey> const& pk)
265{
266 Json::Value jv;
267 jv[jss::TransactionType] = jss::PaymentChannelClaim;
268 jv[jss::Account] = to_string(account);
269 jv["Channel"] = to_string(channel);
270 if (amount)
271 jv[jss::Amount] = amount->getJson(JsonOptions::none);
272 if (balance)
273 jv["Balance"] = balance->getJson(JsonOptions::none);
274 if (signature)
275 jv["Signature"] = strHex(*signature);
276 if (pk)
277 jv["PublicKey"] = strHex(pk->slice());
278 return jv;
279}
280
283 AccountID const& account,
284 AccountID const& dst,
285 std::uint32_t seqProxyValue)
286{
287 auto const k = keylet::payChan(account, dst, seqProxyValue);
288 return k.key;
289}
290
292channelBalance(ReadView const& view, uint256 const& chan)
293{
294 auto const slep = view.read({ltPAYCHAN, chan});
295 if (!slep)
296 return XRPAmount{-1};
297 return (*slep)[sfBalance];
298}
299
300bool
301channelExists(ReadView const& view, uint256 const& chan)
302{
303 auto const slep = view.read({ltPAYCHAN, chan});
304 return bool(slep);
305}
306
307/* Crossing Limits */
308/******************************************************************************/
309
310void
312 Env& env,
313 std::size_t n,
314 Account const& account,
315 STAmount const& in,
316 STAmount const& out)
317{
318 auto const ownerCount = env.le(account)->getFieldU32(sfOwnerCount);
319 for (std::size_t i = 0; i < n; i++)
320 {
321 env(offer(account, in, out));
322 env.close();
323 }
324 env.require(owners(account, ownerCount + n));
325}
326
327/* Pay Strand */
328/***************************************************************/
329
330// Currency path element
332cpe(Currency const& c)
333{
334 return STPathElement(
336};
337
338// All path element
340allpe(AccountID const& a, Issue const& iss)
341{
342 return STPathElement(
345 a,
346 iss.currency,
347 iss.account);
348};
349
350} // namespace jtx
351} // namespace test
352} // namespace ripple
Represents a JSON value.
Definition json_value.h:149
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.
A currency issued by an account.
Definition Issue.h:33
AccountID account
Definition Issue.h:36
Currency currency
Definition Issue.h:35
A public key.
Definition PublicKey.h:61
Slice slice() const noexcept
Definition PublicKey.h:122
A view into a ledger.
Definition ReadView.h:52
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STAmount.cpp:795
XRPAmount xrp() const
Definition STAmount.cpp:306
Issue const & issue() const
Definition STAmount.h:496
void push_back(STPathElement const &e)
Definition STPathSet.h:410
Immutable cryptographic account descriptor.
Definition Account.h:39
std::string const & human() const
Returns the human readable public key.
Definition Account.h:114
A transaction testing environment.
Definition Env.h:121
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition Env.cpp:249
void require(Args const &... args)
Check a set of requirements.
Definition Env.h:544
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:331
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:121
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:788
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition Env.cpp:267
A balance matches.
Definition balance.h:39
Set Expiration on a JTx.
Match the number of items in the account's owner directory.
Definition owners.h:73
T is_same_v
@ arrayValue
array value (ordered list)
Definition json_value.h:44
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:244
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Definition Indexes.cpp:395
bool checkArraySize(Json::Value const &val, unsigned int size)
std::uint32_t ownerCount(Env const &env, Account const &account)
Json::Value ledgerEntryRoot(Env &env, Account const &acct)
bool expectOffers(Env &env, AccountID const &account, std::uint16_t size, std::vector< Amounts > const &toMatch)
STAmount channelBalance(ReadView const &view, uint256 const &chan)
uint256 channel(AccountID const &account, AccountID const &dst, std::uint32_t seqProxyValue)
PrettyAmount xrpMinusFee(Env const &env, std::int64_t xrpAmount)
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
bool expectLine(Env &env, AccountID const &account, STAmount const &value, bool defaultLimits)
bool equal(STAmount const &sa1, STAmount const &sa2)
constexpr XRPAmount dropsPerXRP
Json::Value getAccountLines(Env &env, AccountID const &acctId)
Json::Value ledgerEntryState(Env &env, Account const &acct_a, Account const &acct_b, std::string const &currency)
void stpath_append_one(STPath &st, Account const &account)
void fund(jtx::Env &env, jtx::Account const &gw, std::vector< jtx::Account > const &accounts, std::vector< STAmount > const &amts, Fund how)
Definition AMMTest.cpp:37
void n_offers(Env &env, std::size_t n, Account const &account, STAmount const &in, STAmount const &out)
Json::Value accountBalance(Env &env, Account const &acct)
STPathElement IPE(Issue const &iss)
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 offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
Definition offer.cpp:29
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)
STPathElement cpe(Currency const &c)
bool expectLedgerEntryRoot(Env &env, Account const &acct, STAmount const &expectedValue)
STPathElement allpe(AccountID const &a, Issue const &iss)
bool channelExists(ReadView const &view, uint256 const &chan)
XRPAmount txfee(Env const &env, std::uint16_t n)
Json::Value getAccountOffers(Env &env, AccountID const &acct, bool current)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
AccountID const & xrpAccount()
Compute AccountID from public key.
@ current
This was a new validation and was added.
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:30
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:630
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:654
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...