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