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