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 ripple {
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
62IPE(Issue const& iss)
63{
64 return STPathElement(
66 xrpAccount(),
67 iss.currency,
68 iss.account);
69}
70
71/******************************************************************************/
72
74txfee(Env const& env, std::uint16_t n)
75{
76 return env.current()->fees().base * n;
77}
78
80xrpMinusFee(Env const& env, std::int64_t xrpAmount)
81{
82 auto feeDrops = env.current()->fees().base;
83 return drops(dropsPerXRP * xrpAmount - feeDrops);
84};
85
86[[nodiscard]] bool
88 Env& env,
89 AccountID const& account,
90 STAmount const& value,
91 bool defaultLimits)
92{
93 if (auto const sle = env.le(keylet::line(account, value.issue())))
94 {
95 Issue const issue = value.issue();
96 bool const accountLow = account < issue.account;
97
98 bool expectDefaultTrustLine = true;
99 if (defaultLimits)
100 {
101 STAmount low{issue};
102 STAmount high{issue};
103
104 low.setIssuer(accountLow ? account : issue.account);
105 high.setIssuer(accountLow ? issue.account : account);
106
107 expectDefaultTrustLine = sle->getFieldAmount(sfLowLimit) == low &&
108 sle->getFieldAmount(sfHighLimit) == high;
109 }
110
111 auto amount = sle->getFieldAmount(sfBalance);
112 amount.setIssuer(value.issue().account);
113 if (!accountLow)
114 amount.negate();
115 return amount == value && expectDefaultTrustLine;
116 }
117 return false;
118}
119
120[[nodiscard]] bool
122 Env& env,
123 AccountID const& account,
124 None const&,
125 Issue const& issue)
126{
127 return !env.le(keylet::line(account, issue));
128}
129
130[[nodiscard]] bool
132 Env& env,
133 AccountID const& account,
134 None const&,
135 MPTIssue const& mptIssue)
136{
137 return !env.le(keylet::mptoken(mptIssue.getMptID(), account));
138}
139
140[[nodiscard]] bool
141expectHolding(Env& env, AccountID const& account, None const& value)
142{
143 return std::visit(
144 [&](auto const& issue) {
145 return expectHolding(env, account, value, issue);
146 },
147 value.asset.value());
148}
149
150[[nodiscard]] bool
152 Env& env,
153 AccountID const& account,
154 std::uint16_t size,
155 std::vector<Amounts> const& toMatch)
156{
157 std::uint16_t cnt = 0;
158 std::uint16_t matched = 0;
160 *env.current(), account, [&](std::shared_ptr<SLE const> const& sle) {
161 if (!sle)
162 return false;
163 if (sle->getType() == ltOFFER)
164 {
165 ++cnt;
166 if (std::find_if(
167 toMatch.begin(), toMatch.end(), [&](auto const& a) {
168 return a.in == sle->getFieldAmount(sfTakerPays) &&
169 a.out == sle->getFieldAmount(sfTakerGets);
170 }) != toMatch.end())
171 ++matched;
172 }
173 return true;
174 });
175 return size == cnt && matched == toMatch.size();
176}
177
179ledgerEntryRoot(Env& env, Account const& acct)
180{
181 Json::Value jvParams;
182 jvParams[jss::ledger_index] = "current";
183 jvParams[jss::account_root] = acct.human();
184 return env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
185}
186
189 Env& env,
190 Account const& acct_a,
191 Account const& acct_b,
192 std::string const& currency)
193{
194 Json::Value jvParams;
195 jvParams[jss::ledger_index] = "current";
196 jvParams[jss::ripple_state][jss::currency] = currency;
197 jvParams[jss::ripple_state][jss::accounts] = Json::arrayValue;
198 jvParams[jss::ripple_state][jss::accounts].append(acct_a.human());
199 jvParams[jss::ripple_state][jss::accounts].append(acct_b.human());
200 return env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
201}
202
204accountBalance(Env& env, Account const& acct)
205{
206 auto const jrr = ledgerEntryRoot(env, acct);
207 return jrr[jss::node][sfBalance.fieldName];
208}
209
210[[nodiscard]] bool
212 Env& env,
213 Account const& acct,
214 STAmount const& expectedValue)
215{
216 return accountBalance(env, acct) == to_string(expectedValue.xrp());
217}
218
219/* Payment Channel */
220/******************************************************************************/
221namespace paychan {
222
225 AccountID const& account,
226 AccountID const& to,
227 STAmount const& amount,
228 NetClock::duration const& settleDelay,
229 PublicKey const& pk,
230 std::optional<NetClock::time_point> const& cancelAfter,
231 std::optional<std::uint32_t> const& dstTag)
232{
233 Json::Value jv;
234 jv[jss::TransactionType] = jss::PaymentChannelCreate;
235 jv[jss::Account] = to_string(account);
236 jv[jss::Destination] = to_string(to);
237 jv[jss::Amount] = amount.getJson(JsonOptions::none);
238 jv[jss::SettleDelay] = settleDelay.count();
239 jv[sfPublicKey.fieldName] = strHex(pk.slice());
240 if (cancelAfter)
241 jv[sfCancelAfter.fieldName] = cancelAfter->time_since_epoch().count();
242 if (dstTag)
243 jv[sfDestinationTag.fieldName] = *dstTag;
244 return jv;
245}
246
249 AccountID const& account,
250 uint256 const& channel,
251 STAmount const& amount,
253{
254 Json::Value jv;
255 jv[jss::TransactionType] = jss::PaymentChannelFund;
256 jv[jss::Account] = to_string(account);
257 jv[sfChannel.fieldName] = to_string(channel);
258 jv[jss::Amount] = amount.getJson(JsonOptions::none);
259 if (expiration)
260 jv[sfExpiration.fieldName] = expiration->time_since_epoch().count();
261 return jv;
262}
263
266 AccountID const& account,
267 uint256 const& channel,
269 std::optional<STAmount> const& amount,
270 std::optional<Slice> const& signature,
271 std::optional<PublicKey> const& pk)
272{
273 Json::Value jv;
274 jv[jss::TransactionType] = jss::PaymentChannelClaim;
275 jv[jss::Account] = to_string(account);
276 jv["Channel"] = to_string(channel);
277 if (amount)
278 jv[jss::Amount] = amount->getJson(JsonOptions::none);
279 if (balance)
280 jv["Balance"] = balance->getJson(JsonOptions::none);
281 if (signature)
282 jv["Signature"] = strHex(*signature);
283 if (pk)
284 jv["PublicKey"] = strHex(pk->slice());
285 return jv;
286}
287
290 AccountID const& account,
291 AccountID const& dst,
292 std::uint32_t seqProxyValue)
293{
294 auto const k = keylet::payChan(account, dst, seqProxyValue);
295 return k.key;
296}
297
299channelBalance(ReadView const& view, uint256 const& chan)
300{
301 auto const slep = view.read({ltPAYCHAN, chan});
302 if (!slep)
303 return XRPAmount{-1};
304 return (*slep)[sfBalance];
305}
306
307bool
308channelExists(ReadView const& view, uint256 const& chan)
309{
310 auto const slep = view.read({ltPAYCHAN, chan});
311 return bool(slep);
312}
313
314} // namespace paychan
315
316/* Crossing Limits */
317/******************************************************************************/
318
319void
321 Env& env,
322 std::size_t n,
323 Account const& account,
324 STAmount const& in,
325 STAmount const& out)
326{
327 auto const ownerCount = env.le(account)->getFieldU32(sfOwnerCount);
328 for (std::size_t i = 0; i < n; i++)
329 {
330 env(offer(account, in, out));
331 env.close();
332 }
333 env.require(owners(account, ownerCount + n));
334}
335
336/* Pay Strand */
337/***************************************************************/
338
339// Currency path element
341cpe(Currency const& c)
342{
343 return STPathElement(
345};
346
347// All path element
349allpe(AccountID const& a, Issue const& iss)
350{
351 return STPathElement(
354 a,
355 iss.currency,
356 iss.account);
357};
358
359} // namespace jtx
360} // namespace test
361} // namespace ripple
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:137
A currency issued by an account.
Definition Issue.h:14
AccountID account
Definition Issue.h:17
Currency currency
Definition Issue.h:16
constexpr MPTID const & getMptID() const
Definition MPTIssue.h:27
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.
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STAmount.cpp:753
XRPAmount xrp() const
Definition STAmount.cpp:264
Issue const & issue() const
Definition STAmount.h:477
void push_back(STPathElement const &e)
Definition STPathSet.h:391
Immutable cryptographic account descriptor.
Definition Account.h:20
std::string const & human() const
Returns the human readable public key.
Definition Account.h:99
A transaction testing environment.
Definition Env.h:102
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition Env.cpp:241
void require(Args const &... args)
Check a set of requirements.
Definition Env.h:528
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:312
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:103
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:772
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition Env.cpp:259
A balance matches.
Definition balance.h:20
Set Expiration on a JTx.
Match the number of items in the account's owner directory.
Definition owners.h:54
T is_same_v
@ arrayValue
array value (ordered list)
Definition json_value.h:25
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:521
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:225
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Definition Indexes.cpp:376
bool channelExists(ReadView const &view, uint256 const &chan)
Json::Value fund(AccountID const &account, uint256 const &channel, STAmount const &amount, std::optional< NetClock::time_point > const &expiration)
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)
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)
STAmount channelBalance(ReadView const &view, uint256 const &chan)
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)
PrettyAmount xrpMinusFee(Env const &env, std::int64_t xrpAmount)
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
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 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 offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
Definition offer.cpp:10
bool expectHolding(Env &env, AccountID const &account, STAmount const &value, bool defaultLimits)
STPathElement cpe(Currency const &c)
bool expectLedgerEntryRoot(Env &env, Account const &acct, STAmount const &expectedValue)
STPathElement allpe(AccountID const &a, Issue const &iss)
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:6
AccountID const & xrpAccount()
Compute AccountID from public key.
@ current
This was a new validation and was added.
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:637
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:11
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
T visit(T... args)