rippled
Loading...
Searching...
No Matches
TestHelpers.h
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#ifndef RIPPLE_TEST_JTX_TESTHELPERS_H_INCLUDED
21#define RIPPLE_TEST_JTX_TESTHELPERS_H_INCLUDED
22
23#include <test/jtx/Env.h>
24#include <xrpl/basics/base_uint.h>
25#include <xrpl/json/json_value.h>
26#include <xrpl/protocol/AccountID.h>
27#include <xrpl/protocol/Quality.h>
28#include <xrpl/protocol/TxFlags.h>
29#include <xrpl/protocol/jss.h>
30
31#include <vector>
32
33namespace ripple {
34namespace test {
35namespace jtx {
36
37// TODO We only need this long "requires" clause as polyfill, for C++20
38// implementations which are missing <ranges> header. Replace with
39// `std::ranges::range<Input>`, and accordingly use std::ranges::begin/end
40// when we have moved to better compilers.
41template <typename Input>
42auto
43make_vector(Input const& input)
44 requires requires(Input& v) {
45 std::begin(v);
46 std::end(v);
47 }
48{
49 return std::vector(std::begin(input), std::end(input));
50}
51
52// Functions used in debugging
54getAccountOffers(Env& env, AccountID const& acct, bool current = false);
55
56inline Json::Value
57getAccountOffers(Env& env, Account const& acct, bool current = false)
58{
59 return getAccountOffers(env, acct.id(), current);
60}
61
63getAccountLines(Env& env, AccountID const& acctId);
64
65inline Json::Value
66getAccountLines(Env& env, Account const& acct)
67{
68 return getAccountLines(env, acct.id());
69}
70
71template <typename... IOU>
73getAccountLines(Env& env, AccountID const& acctId, IOU... ious)
74{
75 auto const jrr = getAccountLines(env, acctId);
76 Json::Value res;
77 for (auto const& line : jrr[jss::lines])
78 {
79 for (auto const& iou : {ious...})
80 {
81 if (line[jss::currency].asString() == to_string(iou.currency))
82 {
84 v[jss::currency] = line[jss::currency];
85 v[jss::balance] = line[jss::balance];
86 v[jss::limit] = line[jss::limit];
87 v[jss::account] = line[jss::account];
88 res[jss::lines].append(v);
89 }
90 }
91 }
92 if (!res.isNull())
93 return res;
94 return jrr;
95}
96
97[[nodiscard]] bool
98checkArraySize(Json::Value const& val, unsigned int size);
99
100// Helper function that returns the owner count on an account.
102ownerCount(test::jtx::Env const& env, test::jtx::Account const& account);
103
104/* Path finding */
105/******************************************************************************/
106void
107stpath_append_one(STPath& st, Account const& account);
108
109template <class T>
111stpath_append_one(STPath& st, T const& t)
112{
114}
115
116void
118
119template <class T, class... Args>
120void
121stpath_append(STPath& st, T const& t, Args const&... args)
122{
123 stpath_append_one(st, t);
124 if constexpr (sizeof...(args) > 0)
125 stpath_append(st, args...);
126}
127
128template <class... Args>
129void
130stpathset_append(STPathSet& st, STPath const& p, Args const&... args)
131{
132 st.push_back(p);
133 if constexpr (sizeof...(args) > 0)
134 stpathset_append(st, args...);
135}
136
137bool
138equal(STAmount const& sa1, STAmount const& sa2);
139
140// Issue path element
142IPE(Issue const& iss);
143
144template <class... Args>
145STPath
146stpath(Args const&... args)
147{
148 STPath st;
149 stpath_append(st, args...);
150 return st;
151}
152
153template <class... Args>
154bool
155same(STPathSet const& st1, Args const&... args)
156{
157 STPathSet st2;
158 stpathset_append(st2, args...);
159 if (st1.size() != st2.size())
160 return false;
161
162 for (auto const& p : st2)
163 {
164 if (std::find(st1.begin(), st1.end(), p) == st1.end())
165 return false;
166 }
167 return true;
168}
169
170/******************************************************************************/
171
173txfee(Env const& env, std::uint16_t n);
174
176xrpMinusFee(Env const& env, std::int64_t xrpAmount);
177
178bool
180 Env& env,
181 AccountID const& account,
182 STAmount const& value,
183 bool defaultLimits = false);
184
185template <typename... Amts>
186bool
188 Env& env,
189 AccountID const& account,
190 STAmount const& value,
191 Amts const&... amts)
192{
193 return expectLine(env, account, value, false) &&
194 expectLine(env, account, amts...);
195}
196
197bool
198expectLine(Env& env, AccountID const& account, None const& value);
199
200bool
202 Env& env,
203 AccountID const& account,
204 std::uint16_t size,
205 std::vector<Amounts> const& toMatch = {});
206
208ledgerEntryRoot(Env& env, Account const& acct);
209
212 Env& env,
213 Account const& acct_a,
214 Account const& acct_b,
215 std::string const& currency);
216
218accountBalance(Env& env, Account const& acct);
219
220[[nodiscard]] bool
222 Env& env,
223 Account const& acct,
224 STAmount const& expectedValue);
225
226/* Escrow */
227/******************************************************************************/
228
230escrow(AccountID const& account, AccountID const& to, STAmount const& amount);
231
232inline Json::Value
233escrow(Account const& account, Account const& to, STAmount const& amount)
234{
235 return escrow(account.id(), to.id(), amount);
236}
237
239finish(AccountID const& account, AccountID const& from, std::uint32_t seq);
240
241inline Json::Value
242finish(Account const& account, Account const& from, std::uint32_t seq)
243{
244 return finish(account.id(), from.id(), seq);
245}
246
248cancel(AccountID const& account, Account const& from, std::uint32_t seq);
249
250inline Json::Value
251cancel(Account const& account, Account const& from, std::uint32_t seq)
252{
253 return cancel(account.id(), from, seq);
254}
255
257 {0xA0, 0x25, 0x80, 0x20, 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC,
258 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
259 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95,
260 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55, 0x81, 0x01, 0x00}};
261
262// A PreimageSha256 fulfillments and its associated condition.
263std::array<std::uint8_t, 4> const fb1 = {{0xA0, 0x02, 0x80, 0x00}};
264
267{
268private:
270
271public:
272 explicit finish_time(NetClock::time_point const& value) : value_(value)
273 {
274 }
275
276 void
277 operator()(Env&, JTx& jt) const
278 {
279 jt.jv[sfFinishAfter.jsonName] = value_.time_since_epoch().count();
280 }
281};
282
285{
286private:
288
289public:
290 explicit cancel_time(NetClock::time_point const& value) : value_(value)
291 {
292 }
293
294 void
296 {
297 jt.jv[sfCancelAfter.jsonName] = value_.time_since_epoch().count();
298 }
299};
300
302{
303private:
305
306public:
307 explicit condition(Slice const& cond) : value_(strHex(cond))
308 {
309 }
310
311 template <size_t N>
313 : condition(makeSlice(c))
314 {
315 }
316
317 void
318 operator()(Env&, JTx& jt) const
319 {
320 jt.jv[sfCondition.jsonName] = value_;
321 }
322};
323
325{
326private:
328
329public:
331 {
332 }
333
334 template <size_t N>
337 {
338 }
339
340 void
341 operator()(Env&, JTx& jt) const
342 {
343 jt.jv[sfFulfillment.jsonName] = value_;
344 }
345};
346
347/* Payment Channel */
348/******************************************************************************/
349
351create(
352 AccountID const& account,
353 AccountID const& to,
354 STAmount const& amount,
355 NetClock::duration const& settleDelay,
356 PublicKey const& pk,
357 std::optional<NetClock::time_point> const& cancelAfter = std::nullopt,
358 std::optional<std::uint32_t> const& dstTag = std::nullopt);
359
360inline Json::Value
362 Account const& account,
363 Account const& to,
364 STAmount const& amount,
365 NetClock::duration const& settleDelay,
366 PublicKey const& pk,
367 std::optional<NetClock::time_point> const& cancelAfter = std::nullopt,
368 std::optional<std::uint32_t> const& dstTag = std::nullopt)
369{
370 return create(
371 account.id(), to.id(), amount, settleDelay, pk, cancelAfter, dstTag);
372}
373
375fund(
376 AccountID const& account,
377 uint256 const& channel,
378 STAmount const& amount,
379 std::optional<NetClock::time_point> const& expiration = std::nullopt);
380
382claim(
383 AccountID const& account,
384 uint256 const& channel,
385 std::optional<STAmount> const& balance = std::nullopt,
386 std::optional<STAmount> const& amount = std::nullopt,
387 std::optional<Slice> const& signature = std::nullopt,
388 std::optional<PublicKey> const& pk = std::nullopt);
389
391channel(
392 AccountID const& account,
393 AccountID const& dst,
394 std::uint32_t seqProxyValue);
395
396inline uint256
397channel(Account const& account, Account const& dst, std::uint32_t seqProxyValue)
398{
399 return channel(account.id(), dst.id(), seqProxyValue);
400}
401
403channelBalance(ReadView const& view, uint256 const& chan);
404
405bool
406channelExists(ReadView const& view, uint256 const& chan);
407
408/* Crossing Limits */
409/******************************************************************************/
410
411void
413 Env& env,
414 std::size_t n,
415 Account const& account,
416 STAmount const& in,
417 STAmount const& out);
418
419/* Pay Strand */
420/***************************************************************/
421
422// Currency path element
424cpe(Currency const& c);
425
426// All path element
428allpe(AccountID const& a, Issue const& iss);
429/***************************************************************/
430
431/* Check */
432/***************************************************************/
433namespace check {
434
436// clang-format off
437template <typename A>
438 requires std::is_same_v<A, AccountID>
440create(A const& account, A const& dest, STAmount const& sendMax)
441{
442 Json::Value jv;
443 jv[sfAccount.jsonName] = to_string(account);
444 jv[sfSendMax.jsonName] = sendMax.getJson(JsonOptions::none);
445 jv[sfDestination.jsonName] = to_string(dest);
446 jv[sfTransactionType.jsonName] = jss::CheckCreate;
447 jv[sfFlags.jsonName] = tfUniversal;
448 return jv;
449}
450// clang-format on
451
452inline Json::Value
454 jtx::Account const& account,
455 jtx::Account const& dest,
456 STAmount const& sendMax)
457{
458 return create(account.id(), dest.id(), sendMax);
459}
460
461} // namespace check
462
463} // namespace jtx
464} // namespace test
465} // namespace ripple
466
467#endif // RIPPLE_TEST_JTX_TESTHELPERS_H_INCLUDED
T begin(T... args)
Represents a JSON value.
Definition: json_value.h:148
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:897
bool isNull() const
isNull() tests to see if this field is null.
Definition: json_value.cpp:986
A currency issued by an account.
Definition: Issue.h:36
A public key.
Definition: PublicKey.h:62
A view into a ledger.
Definition: ReadView.h:51
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:636
std::vector< STPath >::const_iterator end() const
Definition: STPathSet.h:496
void push_back(STPath const &e)
Definition: STPathSet.h:514
std::vector< STPath >::const_iterator begin() const
Definition: STPathSet.h:490
std::vector< STPath >::size_type size() const
Definition: STPathSet.h:502
An immutable linear range of bytes.
Definition: Slice.h:46
Immutable cryptographic account descriptor.
Definition: Account.h:39
AccountID id() const
Returns the Account ID.
Definition: Account.h:107
A transaction testing environment.
Definition: Env.h:118
Converts to IOU Issue or STAmount.
A balance matches.
Definition: balance.h:39
Set Expiration on a JTx.
Definition: Check_test.cpp:30
T end(T... args)
T find(T... args)
Json::Value create(A const &account, A const &dest, STAmount const &sendMax)
Create a check.
Definition: TestHelpers.h:440
bool checkArraySize(Json::Value const &val, unsigned int size)
Definition: TestHelpers.cpp:47
std::uint32_t ownerCount(Env const &env, Account const &account)
Definition: TestHelpers.cpp:53
Json::Value ledgerEntryRoot(Env &env, Account const &acct)
auto make_vector(Input const &input)
Definition: TestHelpers.h:43
Json::Value escrow(AccountID const &account, AccountID const &to, STAmount const &amount)
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)
Definition: TestHelpers.cpp:98
bool expectLine(Env &env, AccountID const &account, STAmount const &value, bool defaultLimits)
bool equal(STAmount const &sa1, STAmount const &sa2)
Definition: TestHelpers.cpp:73
Json::Value getAccountLines(Env &env, AccountID const &acctId)
Definition: TestHelpers.cpp:39
bool same(STPathSet const &st1, Args const &... args)
Definition: TestHelpers.h:155
Json::Value ledgerEntryState(Env &env, Account const &acct_a, Account const &acct_b, std::string const &currency)
std::array< std::uint8_t, 4 > const fb1
Definition: TestHelpers.h:263
void stpath_append_one(STPath &st, Account const &account)
Definition: TestHelpers.cpp:61
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:34
void stpath_append(STPath &st, T const &t, Args const &... args)
Definition: TestHelpers.h:121
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)
Json::Value cancel(AccountID const &account, Account const &from, std::uint32_t seq)
STPathElement IPE(Issue const &iss)
Definition: TestHelpers.cpp:80
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 finish(AccountID const &account, AccountID const &from, std::uint32_t seq)
std::array< std::uint8_t, 39 > constexpr cb1
Definition: TestHelpers.h:256
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)
void stpathset_append(STPathSet &st, STPath const &p, Args const &... args)
Definition: TestHelpers.h:130
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)
Definition: TestHelpers.cpp:92
STPath stpath(Args const &... args)
Definition: TestHelpers.h:146
Json::Value getAccountOffers(Env &env, AccountID const &acct, bool current)
Definition: TestHelpers.cpp:31
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
@ current
This was a new validation and was added.
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:244
constexpr std::uint32_t tfUniversal
Definition: TxFlags.h:61
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:630
Execution context for applying a JSON transaction.
Definition: JTx.h:44
Json::Value jv
Definition: JTx.h:45
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
Set the "CancelAfter" time tag on a JTx.
Definition: TestHelpers.h:285
NetClock::time_point value_
Definition: TestHelpers.h:287
cancel_time(NetClock::time_point const &value)
Definition: TestHelpers.h:290
void operator()(jtx::Env &, jtx::JTx &jt) const
Definition: TestHelpers.h:295
void operator()(Env &, JTx &jt) const
Definition: TestHelpers.h:318
condition(Slice const &cond)
Definition: TestHelpers.h:307
condition(std::array< std::uint8_t, N > const &c)
Definition: TestHelpers.h:312
Set the "FinishAfter" time tag on a JTx.
Definition: TestHelpers.h:267
finish_time(NetClock::time_point const &value)
Definition: TestHelpers.h:272
void operator()(Env &, JTx &jt) const
Definition: TestHelpers.h:277
NetClock::time_point value_
Definition: TestHelpers.h:269
fulfillment(Slice condition)
Definition: TestHelpers.h:330
fulfillment(std::array< std::uint8_t, N > f)
Definition: TestHelpers.h:335
void operator()(Env &, JTx &jt) const
Definition: TestHelpers.h:341
Set the sequence number on a JTx.
Definition: seq.h:34
T time_since_epoch(T... args)