xrpld
Loading...
Searching...
No Matches
jtx/TestHelpers.h
1#pragma once
2
3#include <test/jtx/Account.h>
4#include <test/jtx/Env.h>
5#include <test/jtx/JTx.h>
6#include <test/jtx/amount.h>
7
8#include <xrpld/app/misc/TxQ.h>
9
10#include <xrpl/basics/Number.h>
11#include <xrpl/basics/Slice.h>
12#include <xrpl/basics/base_uint.h>
13#include <xrpl/basics/chrono.h>
14#include <xrpl/basics/strHex.h>
15#include <xrpl/beast/unit_test/suite.h>
16#include <xrpl/core/ServiceRegistry.h>
17#include <xrpl/json/json_value.h>
18#include <xrpl/protocol/AccountID.h>
19#include <xrpl/protocol/Asset.h>
20#include <xrpl/protocol/Book.h>
21#include <xrpl/protocol/Indexes.h>
22#include <xrpl/protocol/PathAsset.h>
23#include <xrpl/protocol/PublicKey.h>
24#include <xrpl/protocol/Quality.h>
25#include <xrpl/protocol/SField.h>
26#include <xrpl/protocol/STAmount.h>
27#include <xrpl/protocol/STNumber.h> // IWYU pragma: keep
28#include <xrpl/protocol/STPathSet.h>
29#include <xrpl/protocol/SeqProxy.h>
30#include <xrpl/protocol/Serializer.h>
31#include <xrpl/protocol/UintTypes.h>
32#include <xrpl/protocol/Units.h>
33#include <xrpl/protocol/XRPAmount.h>
34#include <xrpl/protocol/jss.h>
35#include <xrpl/tx/paths/detail/Steps.h>
36
37#include <algorithm>
38#include <array>
39#include <chrono>
40#include <condition_variable>
41#include <cstddef>
42#include <cstdint>
43#include <memory>
44#include <mutex>
45#include <optional>
46#include <ranges>
47#include <source_location>
48#include <string>
49#include <tuple>
50#include <type_traits>
51#include <utility>
52#include <vector>
53
54namespace xrpl::test::jtx {
55
62template <
63 class SField,
64 // NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
65 class StoredValue = typename SField::type::value_type,
66 class OutputValue = StoredValue>
68{
69 using SF = SField;
70 using SV = StoredValue;
71 using OV = OutputValue;
72
73protected:
74 SF const& sfield_;
76
77public:
78 explicit JTxField(SF const& sfield, SV value) : sfield_(sfield), value_(std::move(value))
79 {
80 }
81
82 virtual ~JTxField() = default;
83
84 [[nodiscard]] virtual OV
85 value() const = 0;
86
87 virtual void
88 operator()(Env&, JTx& jt) const
89 {
90 jt.jv[sfield_.jsonName] = value();
91 }
92};
93
94template <class SField, class StoredValue>
95struct JTxField<SField, StoredValue, StoredValue>
96{
97 using SF = SField;
98 using SV = StoredValue;
99 using OV = SV;
100
101protected:
102 SF const& sfield_;
104
105public:
106 explicit JTxField(SF const& sfield, SV value) : sfield_(sfield), value_(std::move(value))
107 {
108 }
109
110 void
111 operator()(Env&, JTx& jt) const
112 {
113 jt.jv[sfield_.jsonName] = value_;
114 }
115};
116
117struct TimePointField : public JTxField<SF_UINT32, NetClock::time_point, NetClock::rep>
118{
119 using SF = SF_UINT32;
123
124protected:
125 using base::value_;
126
127public:
128 explicit TimePointField(SF const& sfield, SV const& value) : JTxField(sfield, value)
129 {
130 }
131
132 [[nodiscard]] OV
133 value() const override
134 {
135 return value_.time_since_epoch().count();
136 }
137};
138
139struct UInt256Field : public JTxField<SF_UINT256, uint256, std::string>
140{
141 using SF = SF_UINT256;
142 using SV = uint256;
145
146protected:
147 using base::value_;
148
149public:
150 explicit UInt256Field(SF const& sfield, SV const& value) : JTxField(sfield, value)
151 {
152 }
153
154 [[nodiscard]] OV
155 value() const override
156 {
157 return to_string(value_);
158 }
159};
160
161struct AccountIdField : public JTxField<SF_ACCOUNT, AccountID, std::string>
162{
163 using SF = SF_ACCOUNT;
164 using SV = AccountID;
167
168protected:
169 using base::value_;
170
171public:
172 explicit AccountIdField(SF const& sfield, SV const& value) : JTxField(sfield, value)
173 {
174 }
175
176 [[nodiscard]] OV
177 value() const override
178 {
179 return toBase58(value_);
180 }
181};
182
183struct StAmountField : public JTxField<SF_AMOUNT, STAmount, json::Value>
184{
185 using SF = SF_AMOUNT;
186 using SV = STAmount;
189
190protected:
191 using base::value_;
192
193public:
194 explicit StAmountField(SF const& sfield, SV const& value) : JTxField(sfield, value)
195 {
196 }
197
198 [[nodiscard]] OV
199 value() const override
200 {
201 return value_.getJson(JsonOptions::Values::None);
202 }
203};
204
205struct BlobField : public JTxField<SF_VL, std::string>
206{
207 using SF = SF_VL;
210
211 using JTxField::JTxField;
212
213 explicit BlobField(SF const& sfield, Slice const& cond) : JTxField(sfield, strHex(cond))
214 {
215 }
216
217 template <size_t N>
218 explicit BlobField(SF const& sfield, std::array<std::uint8_t, N> const& c)
219 : BlobField(sfield, makeSlice(c))
220 {
221 }
222};
223
224template <class SField, class UnitTag, class ValueType>
225struct ValueUnitField : public JTxField<SField, unit::ValueUnit<UnitTag, ValueType>, ValueType>
226{
227 using SF = SField;
229 using OV = ValueType;
231
233
234protected:
235 using base::value_;
236
237public:
238 using JTxField<SF, SV, OV>::JTxField;
239
240 [[nodiscard]] OV
241 value() const override
242 {
243 return value_.value();
244 }
245};
246
247template <class JTxField>
249{
250 using JF = JTxField;
251 using SF = JF::SF;
252 using SV = JF::SV;
253
254protected:
255 SF const& sfield_;
256
257public:
258 explicit JTxFieldWrapper(SF const& sfield) : sfield_(sfield)
259 {
260 }
261
262 JF
263 operator()(SV const& value) const
264 {
265 return JTxField(sfield_, value);
266 }
267};
268
269template <>
271{
272 using JF = BlobField;
273 using SF = JF::SF;
274 using SV = JF::SV;
275
276protected:
277 SF const& sfield_;
278
279public:
280 explicit JTxFieldWrapper(SF const& sfield) : sfield_(sfield)
281 {
282 }
283
284 JF
285 operator()(SV const& cond) const
286 {
287 return JF(sfield_, makeSlice(cond));
288 }
289
290 JF
291 operator()(Slice const& cond) const
292 {
293 return JF(sfield_, cond);
294 }
295
296 template <size_t N>
297 JF
299 {
300 return operator()(makeSlice(c));
301 }
302};
303
304// NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
305template <class SField, class UnitTag, class ValueType = typename SField::type::value_type>
307
308// NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
309template <class SField, class StoredValue = typename SField::type::value_type>
311
316
318
319template <std::ranges::range Input>
320auto
321makeVector(Input const& input)
322{
323 return std::vector(std::ranges::begin(input), std::ranges::end(input));
324}
325
326// Functions used in debugging
328getAccountOffers(Env& env, AccountID const& acct, bool current = false);
329
330inline json::Value
331getAccountOffers(Env& env, Account const& acct, bool current = false)
332{
333 return getAccountOffers(env, acct.id(), current);
334}
335
337getAccountLines(Env& env, AccountID const& acctId);
338
339inline json::Value
340getAccountLines(Env& env, Account const& acct)
341{
342 return getAccountLines(env, acct.id());
343}
344
345template <typename... IOU>
347getAccountLines(Env& env, AccountID const& acctId, IOU... ious)
348{
349 auto jrr = getAccountLines(env, acctId);
350 json::Value res;
351 for (auto const& line : jrr[jss::lines])
352 {
353 for (auto const& iou : {ious...})
354 {
355 if (line[jss::currency].asString() == to_string(iou.currency))
356 {
357 json::Value v;
358 v[jss::currency] = line[jss::currency];
359 v[jss::balance] = line[jss::balance];
360 v[jss::limit] = line[jss::limit];
361 v[jss::account] = line[jss::account];
362 res[jss::lines].append(v);
363 }
364 }
365 }
366 if (!res.isNull())
367 return res;
368 return jrr;
369}
370
371[[nodiscard]] bool
372checkArraySize(json::Value const& val, unsigned int size);
373
374// Helper function that returns the owner count on an account.
376ownerCount(test::jtx::Env const& env, test::jtx::Account const& account);
377
378// Helper function that returns the sponsored owner count on an account.
380sponsoredOwnerCount(test::jtx::Env const& env, test::jtx::Account const& account);
381
382// Helper function that returns the sponsoring owner count on an account.
384sponsoringOwnerCount(test::jtx::Env const& env, test::jtx::Account const& account);
385
386// Helper function that returns the sponsoring account count on an account.
389
390[[nodiscard]]
391inline bool
392checkVL(Slice const& result, std::string const& expected)
393{
394 Serializer s;
395 s.addRaw(result);
396 return s.getString() == expected;
397}
398
399[[nodiscard]]
400inline bool
401checkVL(SLE::const_ref sle, SField const& field, std::string const& expected)
402{
403 return strHex(expected) == strHex(sle->getFieldVL(field));
404}
405
406/* Path finding */
407/******************************************************************************/
408void
409stpathAppendOne(STPath& st, Account const& account);
410
411template <class T>
412void
413stpathAppendOne(STPath& st, T const& t)
415{
416 stpathAppendOne(st, Account{t});
417}
418
419void
420stpathAppendOne(STPath& st, STPathElement const& pe);
421
422template <class T, class... Args>
423void
424stpathAppend(STPath& st, T const& t, Args const&... args)
425{
426 stpathAppendOne(st, t);
427 if constexpr (sizeof...(args) > 0)
428 stpathAppend(st, args...);
429}
430
431template <class... Args>
432void
433stpathsetAppend(STPathSet& st, STPath const& p, Args const&... args)
434{
435 st.pushBack(p);
436 if constexpr (sizeof...(args) > 0)
437 stpathsetAppend(st, args...);
438}
439
440bool
441equal(STAmount const& sa1, STAmount const& sa2);
442
443template <class... Args>
444STPath
445stpath(Args const&... args)
446{
447 STPath st;
448 stpathAppend(st, args...);
449 return st;
450}
451
452template <class... Args>
453bool
454same(STPathSet const& st1, Args const&... args)
455{
456 STPathSet st2;
457 stpathsetAppend(st2, args...);
458 if (st1.size() != st2.size())
459 return false;
460
461 return std::ranges::all_of(
462 st2, [&st1](auto const& p) { return std::ranges::find(st1, p) != st1.end(); });
463}
464
466rpf(jtx::Account const& src,
467 jtx::Account const& dst,
468 STAmount const& dstAmount,
469 std::optional<STAmount> const& sendMax = std::nullopt,
470 std::optional<PathAsset> const& srcAsset = std::nullopt,
471 std::optional<AccountID> const& srcIssuer = std::nullopt);
472
475
476class Gate
477{
478private:
481 bool signaled_ = false;
482
483public:
484 // Thread safe, blocks until signaled or period expires.
485 // Returns `true` if signaled.
486 template <class Rep, class Period>
487 bool
489 {
491 auto b = cv_.wait_for(lk, relTime, [this] { return signaled_; });
492 signaled_ = false;
493 return b;
494 }
495
496 void
498 {
499 std::scoped_lock const lk(mutex_);
500 signaled_ = true;
501 cv_.notify_all();
502 }
503};
504
507 jtx::Env& env,
508 jtx::Account const& src,
509 jtx::Account const& dst,
510 STAmount const& saDstAmount,
511 std::optional<STAmount> const& saSendMax = std::nullopt,
512 std::optional<PathAsset> const& srcAsset = std::nullopt,
513 std::optional<AccountID> const& srcIssuer = std::nullopt,
514 std::optional<uint256> const& domain = std::nullopt);
515
518 jtx::Env& env,
519 jtx::Account const& src,
520 jtx::Account const& dst,
521 STAmount const& saDstAmount,
522 std::optional<STAmount> const& saSendMax = std::nullopt,
523 std::optional<PathAsset> const& srcAsset = std::nullopt,
524 std::optional<AccountID> const& srcIssuer = std::nullopt,
525 std::optional<uint256> const& domain = std::nullopt);
526
529 jtx::Env& env,
530 jtx::Account const& src,
531 jtx::Account const& dst,
532 STAmount const& saDstAmount,
533 std::optional<STAmount> const& saSendMax = std::nullopt,
534 std::optional<STPathElement> const& srcElement = std::nullopt,
535 std::optional<AccountID> const& srcIssuer = std::nullopt,
536 std::optional<uint256> const& domain = std::nullopt);
537
538/******************************************************************************/
539
541txFee(Env const& env, std::uint16_t n);
542
544xrpMinusFee(Env const& env, std::int64_t xrpAmount);
545
546bool
548 Env& env,
549 AccountID const& account,
550 STAmount const& value,
551 bool defaultLimits = false);
552
553template <typename... Amts>
554bool
555expectHolding(Env& env, AccountID const& account, STAmount const& value, Amts const&... amts)
556{
557 return expectHolding(env, account, value, false) && expectHolding(env, account, amts...);
558}
559
560bool
561expectHolding(Env& env, AccountID const& account, None const& value);
562
563bool
564expectMPT(Env& env, AccountID const& account, STAmount const& value);
565
566bool
568 Env& env,
569 AccountID const& account,
570 std::uint16_t size,
571 std::vector<Amounts> const& toMatch = {});
572
574ledgerEntryRoot(Env& env, Account const& acct);
575
577ledgerEntryState(Env& env, Account const& acctA, Account const& acctB, std::string const& currency);
578
580ledgerEntryOffer(jtx::Env& env, jtx::Account const& acct, std::uint32_t offerSeq);
581
583ledgerEntryMPT(jtx::Env& env, jtx::Account const& acct, MPTID const& mptID);
584
586getBookOffers(jtx::Env& env, Asset const& takerPays, Asset const& takerGets);
587
589accountBalance(Env& env, Account const& acct);
590
591[[nodiscard]] bool
592expectLedgerEntryRoot(Env& env, Account const& acct, STAmount const& expectedValue);
593
594/* Payment Channel */
595/******************************************************************************/
596namespace paychan {
597
599create(
600 AccountID const& account,
601 AccountID const& to,
602 STAmount const& amount,
603 NetClock::duration const& settleDelay,
604 PublicKey const& pk,
605 std::optional<NetClock::time_point> const& cancelAfter = std::nullopt,
606 std::optional<std::uint32_t> const& dstTag = std::nullopt);
607
608inline json::Value
610 Account const& account,
611 Account const& to,
612 STAmount const& amount,
613 NetClock::duration const& settleDelay,
614 PublicKey const& pk,
615 std::optional<NetClock::time_point> const& cancelAfter = std::nullopt,
616 std::optional<std::uint32_t> const& dstTag = std::nullopt)
617{
618 return create(account.id(), to.id(), amount, settleDelay, pk, cancelAfter, dstTag);
619}
620
622fund(
623 AccountID const& account,
624 uint256 const& channel,
625 STAmount const& amount,
626 std::optional<NetClock::time_point> const& expiration = std::nullopt);
627
629claim(
630 AccountID const& account,
631 uint256 const& channel,
632 std::optional<STAmount> const& balance = std::nullopt,
633 std::optional<STAmount> const& amount = std::nullopt,
634 std::optional<Slice> const& signature = std::nullopt,
635 std::optional<PublicKey> const& pk = std::nullopt);
636
638channel(AccountID const& account, AccountID const& dst, std::uint32_t seqProxyValue);
639
640inline uint256
641channel(Account const& account, Account const& dst, std::uint32_t seqProxyValue)
642{
643 return channel(account.id(), dst.id(), seqProxyValue);
644}
645
647channelBalance(ReadView const& view, uint256 const& chan);
648
649bool
650channelExists(ReadView const& view, uint256 const& chan);
651
652} // namespace paychan
653
654/* Crossing Limits */
655/******************************************************************************/
656
657void
658nOffers(Env& env, std::size_t n, Account const& account, STAmount const& in, STAmount const& out);
659
660/* Pay Strand */
661/***************************************************************/
662
669
676
681
682// Currency/MPTID path element
684cpe(PathAsset const& pa);
685
686// Currency/MPTID and issuer path element
688ipe(Asset const& asset);
689
690// Issuer path element
692iape(AccountID const& account);
693
694// Account path element
696ape(AccountID const& a);
697
698// All path element
700allPathElements(AccountID const& a, Asset const& asset);
701
702bool
703equal(std::unique_ptr<Step> const& s1, DirectStepInfo const& dsi);
704
705bool
706equal(std::unique_ptr<Step> const& s1, MPTEndpointStepInfo const& dsi);
707
708bool
709equal(std::unique_ptr<Step> const& s1, XRPEndpointStepInfo const& xrpStepInfo);
710
711bool
712equal(std::unique_ptr<Step> const& s1, xrpl::Book const& bsi);
713
714template <class Iter>
715bool
717{
718 // base case. all args processed and found equal.
719 return true;
720}
721
722template <class Iter, class StepInfo, class... Args>
723bool
724strandEqualHelper(Iter i, StepInfo&& si, Args&&... args)
725{
727 return false;
728 return strandEqualHelper(++i, std::forward<Args>(args)...);
729}
730
731template <class... Args>
732bool
733equal(Strand const& strand, Args&&... args)
734{
735 if (strand.size() != sizeof...(Args))
736 return false;
737 if (strand.empty())
738 return true;
739 return strandEqualHelper(strand.begin(), std::forward<Args>(args)...);
740}
741
742/***************************************************************/
743
744/* Check */
745/***************************************************************/
746namespace check {
747
751template <typename A>
754create(A const& account, A const& dest, STAmount const& sendMax)
755{
756 json::Value jv;
757 jv[sfAccount.jsonName] = to_string(account);
758 jv[sfSendMax.jsonName] = sendMax.getJson(JsonOptions::Values::None);
759 jv[sfDestination.jsonName] = to_string(dest);
760 jv[sfTransactionType.jsonName] = jss::CheckCreate;
761 return jv;
762}
763
764inline json::Value
765create(jtx::Account const& account, jtx::Account const& dest, STAmount const& sendMax)
766{
767 return create(account.id(), dest.id(), sendMax);
768}
769
770} // namespace check
771
774
775inline uint256
776getCheckIndex(AccountID const& account, std::uint32_t const sequence)
777{
778 return keylet::check(account, SeqProxy::rawSequence(sequence)).key;
779}
780
781template <class Suite>
782void
784 Suite& test,
785 jtx::Env& env,
786 std::size_t expectedCount,
787 std::optional<std::size_t> expectedMaxCount,
788 std::size_t expectedInLedger,
789 std::size_t expectedPerLedger,
790 std::uint64_t expectedMinFeeLevel = kBaseFeeLevel.fee(),
791 std::uint64_t expectedMedFeeLevel = kMinEscalationFeeLevel.fee(),
793{
794 int const line = location.line();
795 char const* file = location.file_name();
796 FeeLevel64 const expectedMin{expectedMinFeeLevel};
797 FeeLevel64 const expectedMed{expectedMedFeeLevel};
798 auto const metrics = env.app().getTxQ().getMetrics(*env.current());
799 using namespace std::string_literals;
800
801 metrics.referenceFeeLevel == kBaseFeeLevel
802 ? test.pass()
803 : test.fail(
804 "reference: "s + std::to_string(metrics.referenceFeeLevel.value()) + "/" +
806 file,
807 line);
808
809 metrics.txCount == expectedCount
810 ? test.pass()
811 : test.fail(
812 "txCount: "s + std::to_string(metrics.txCount) + "/" + std::to_string(expectedCount),
813 file,
814 line);
815
816 metrics.txQMaxSize == expectedMaxCount
817 ? test.pass()
818 : test.fail(
819 "txQMaxSize: "s + std::to_string(metrics.txQMaxSize.value_or(0)) + "/" +
820 std::to_string(expectedMaxCount.value_or(0)),
821 file,
822 line);
823
824 metrics.txInLedger == expectedInLedger
825 ? test.pass()
826 : test.fail(
827 "txInLedger: "s + std::to_string(metrics.txInLedger) + "/" +
828 std::to_string(expectedInLedger),
829 file,
830 line);
831
832 metrics.txPerLedger == expectedPerLedger
833 ? test.pass()
834 : test.fail(
835 "txPerLedger: "s + std::to_string(metrics.txPerLedger) + "/" +
836 std::to_string(expectedPerLedger),
837 file,
838 line);
839
840 metrics.minProcessingFeeLevel == expectedMin
841 ? test.pass()
842 : test.fail(
843 "minProcessingFeeLevel: "s + std::to_string(metrics.minProcessingFeeLevel.value()) +
844 "/" + std::to_string(expectedMin.value()),
845 file,
846 line);
847
848 metrics.medFeeLevel == expectedMed
849 ? test.pass()
850 : test.fail(
851 "medFeeLevel: "s + std::to_string(metrics.medFeeLevel.value()) + "/" +
852 std::to_string(expectedMed.value()),
853 file,
854 line);
855
856 auto const expectedCurFeeLevel = expectedInLedger > expectedPerLedger
857 ? expectedMed * expectedInLedger * expectedInLedger /
858 (expectedPerLedger * expectedPerLedger)
859 : metrics.referenceFeeLevel;
860
861 metrics.openLedgerFeeLevel == expectedCurFeeLevel
862 ? test.pass()
863 : test.fail(
864 "openLedgerFeeLevel: "s + std::to_string(metrics.openLedgerFeeLevel.value()) + "/" +
865 std::to_string(expectedCurFeeLevel.value()),
866 file,
867 line);
868}
869
870/* LoanBroker */
871/******************************************************************************/
872
873namespace loan_broker {
874
876set(AccountID const& account, uint256 const& vaultId, std::uint32_t flags = 0);
877
878// Use "del" because "delete" is a reserved word in C++.
880del(AccountID const& account, uint256 const& brokerID, std::uint32_t flags = 0);
881
884 AccountID const& account,
885 uint256 const& brokerID,
886 STAmount const& amount,
887 std::uint32_t flags = 0);
888
891 AccountID const& account,
892 uint256 const& brokerID,
893 STAmount const& amount,
894 std::uint32_t flags = 0);
895
896// Must specify at least one of loanBrokerID or amount.
898coverClawback(AccountID const& account, std::uint32_t flags = 0);
899
900auto const kLoanBrokerId = JTxFieldWrapper<UInt256Field>(sfLoanBrokerID);
901
904
905auto const kDebtMaximum = simpleField<SF_NUMBER>(sfDebtMaximum);
906
908
911
913
914} // namespace loan_broker
915
916/* Loan */
917/******************************************************************************/
918namespace loan {
919
921set(AccountID const& account,
922 uint256 const& loanBrokerID,
923 Number principalRequested,
924 std::uint32_t flags = 0);
925
927
928// For `CounterPartySignature`, use `Sig(sfCounterpartySignature, ...)`
929
930auto const kLoanOriginationFee = simpleField<SF_NUMBER>(sfLoanOriginationFee);
931
932auto const kLoanServiceFee = simpleField<SF_NUMBER>(sfLoanServiceFee);
933
934auto const kLatePaymentFee = simpleField<SF_NUMBER>(sfLatePaymentFee);
935
936auto const kClosePaymentFee = simpleField<SF_NUMBER>(sfClosePaymentFee);
937
939
941
943
946
948 valueUnitWrapper<SF_UINT32, unit::TenthBipsTag>(sfOverpaymentInterestRate);
949
950auto const kPaymentTotal = simpleField<SF_UINT32>(sfPaymentTotal);
951
952auto const kPaymentInterval = simpleField<SF_UINT32>(sfPaymentInterval);
953
954auto const kGracePeriod = simpleField<SF_UINT32>(sfGracePeriod);
955
957manage(AccountID const& account, uint256 const& loanID, std::uint32_t flags);
958
960del(AccountID const& account, uint256 const& loanID, std::uint32_t flags = 0);
961
963pay(AccountID const& account,
964 uint256 const& loanID,
965 STAmount const& amount,
966 std::uint32_t flags = 0);
967
968} // namespace loan
969
974{
975private:
977
978public:
979 explicit Expiration(NetClock::time_point const& expiry)
980 : expiry_{expiry.time_since_epoch().count()}
981 {
982 }
983
984 void
985 operator()(Env&, JTx& jt) const
986 {
987 jt[sfExpiration.jsonName] = expiry_;
988 }
989};
990
995{
996private:
998
999public:
1000 explicit SourceTag(std::uint32_t tag) : tag_{tag}
1001 {
1002 }
1003
1004 void
1005 operator()(Env&, JTx& jt) const
1006 {
1007 jt[sfSourceTag.jsonName] = tag_;
1008 }
1009};
1010
1015{
1016private:
1018
1019public:
1020 explicit DestTag(std::uint32_t tag) : tag_{tag}
1021 {
1022 }
1023
1024 void
1025 operator()(Env&, JTx& jt) const
1026 {
1027 jt[sfDestinationTag.jsonName] = tag_;
1028 }
1029};
1030
1032{
1034 // 3-letter currency if Issue, ignored if MPT
1037 std::vector<jtx::Account> holders = {}; // NOLINT(readability-redundant-member-init)
1038 // trust-limit if Issue, maxAmount if MPT
1040 // 0-50'000 (0-50%)
1042};
1043
1044namespace detail {
1045
1046IOU
1047issueHelperIOU(IssuerArgs const& args);
1048
1049MPT
1050issueHelperMPT(IssuerArgs const& args);
1051
1052} // namespace detail
1053
1054template <typename TTester>
1055void
1062
1063template <typename TTester>
1064void
1075
1076} // namespace xrpl::test::jtx
T all_of(T... args)
T begin(T... args)
A testsuite class.
Definition suite.h:52
Represents a JSON value.
Definition json_value.h:117
bool isNull() const
isNull() tests to see if this field is null.
Value & append(Value const &value)
Append value to array at the end.
Specifies an order book.
Definition Book.h:28
std::uint32_t rep
Definition chrono.h:45
std::chrono::time_point< NetClock > time_point
Definition chrono.h:48
std::chrono::duration< rep, period > duration
Definition chrono.h:47
Number is a floating point type that can represent a wide range of values.
Definition Number.h:351
A public key.
Definition PublicKey.h:53
A view into a ledger.
Definition ReadView.h:41
Identifies fields.
Definition SField.h:132
json::Value getJson(JsonOptions=JsonOptions::Values::None) const override
Definition STAmount.cpp:734
std::shared_ptr< STLedgerEntry const > const & const_ref
std::vector< STPath >::size_type size() const
Definition STPathSet.h:537
void pushBack(STPath const &e)
Definition STPathSet.h:549
std::vector< STPath >::const_iterator end() const
Definition STPathSet.h:531
static constexpr SeqProxy rawSequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
Definition SeqProxy.h:62
std::string getString() const
Definition Serializer.h:213
int addRaw(Blob const &vector)
virtual TxQ & getTxQ()=0
An immutable linear range of bytes.
Definition Slice.h:28
Metrics getMetrics(OpenView const &view) const
Returns fee metrics in reference fee level units.
Definition TxQ.cpp:1750
static constexpr FeeLevel64 kBaseLevel
Fee level for single-signed reference transaction.
Definition TxQ.h:63
Immutable cryptographic account descriptor.
Definition jtx/Account.h:21
AccountID id() const
Returns the Account ID.
std::uint32_t const tag_
void operator()(Env &, JTx &jt) const
DestTag(std::uint32_t tag)
A transaction testing environment.
Definition Env.h:161
Application & app()
Definition Env.h:300
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:377
std::uint32_t const expiry_
Expiration(NetClock::time_point const &expiry)
void operator()(Env &, JTx &jt) const
bool waitFor(std::chrono::duration< Rep, Period > const &relTime)
std::condition_variable cv_
Converts to IOU Issue or STAmount.
Converts to MPT Issue or STAmount.
void operator()(Env &, JTx &jt) const
constexpr value_type value() const
Returns the underlying value.
Definition Units.h:338
T current(T... args)
T find(T... args)
T forward(T... args)
T is_constructible_v
T is_same_v
STL namespace.
Keylet check(AccountID const &id, SeqProxy const &seq) noexcept
A Check.
Definition Indexes.cpp:338
Check operations.
Definition check.h:18
json::Value create(A const &account, A const &dest, STAmount const &sendMax)
Create a check.
MPT issueHelperMPT(IssuerArgs const &args)
IOU issueHelperIOU(IssuerArgs const &args)
json::Value set(AccountID const &account, uint256 const &vaultId, uint32_t flags)
json::Value coverDeposit(AccountID const &account, uint256 const &brokerID, STAmount const &amount, uint32_t flags)
json::Value coverClawback(AccountID const &account, std::uint32_t flags)
json::Value coverWithdraw(AccountID const &account, uint256 const &brokerID, STAmount const &amount, uint32_t flags)
json::Value del(AccountID const &account, uint256 const &brokerID, uint32_t flags)
json::Value set(AccountID const &account, uint256 const &loanBrokerID, Number principalRequested, std::uint32_t flags)
json::Value manage(AccountID const &account, uint256 const &loanID, std::uint32_t flags)
auto const kOverpaymentInterestRate
json::Value del(AccountID const &account, uint256 const &loanID, std::uint32_t flags)
json::Value pay(AccountID const &account, uint256 const &loanID, STAmount const &amount, std::uint32_t flags)
json::Value fund(AccountID const &account, uint256 const &channel, STAmount const &amount, std::optional< NetClock::time_point > const &expiration)
STAmount channelBalance(ReadView const &view, uint256 const &chan)
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)
bool channelExists(ReadView const &view, uint256 const &chan)
void nOffers(Env &env, std::size_t n, Account const &account, STAmount const &in, STAmount const &out)
json::Value findPathsRequest(jtx::Env &env, jtx::Account const &src, jtx::Account const &dst, STAmount const &saDstAmount, std::optional< STAmount > const &saSendMax, std::optional< PathAsset > const &srcAsset, std::optional< AccountID > const &srcIssuer, std::optional< uint256 > const &domain)
jtx::Env pathTestEnv(beast::unit_test::Suite &suite)
json::Value ledgerEntryMPT(jtx::Env &env, jtx::Account const &acct, MPTID const &mptID)
constexpr FeeLevel64 kBaseFeeLevel
bool expectLedgerEntryRoot(Env &env, Account const &acct, STAmount const &expectedValue)
bool expectMPT(Env &env, AccountID const &account, STAmount const &value)
PrettyAmount xrpMinusFee(Env const &env, std::int64_t xrpAmount)
constexpr FeeLevel64 kMinEscalationFeeLevel
bool expectOffers(Env &env, AccountID const &account, std::uint16_t size, std::vector< Amounts > const &toMatch)
STPathElement allPathElements(AccountID const &a, Asset const &asset)
void testHelper2TokensMix(TTester &&tester)
bool expectHolding(Env &env, AccountID const &account, STAmount const &value, bool defaultLimits)
json::Value getBookOffers(jtx::Env &env, Asset const &takerPays, Asset const &takerGets)
std::uint32_t sponsoringAccountCount(Env const &env, Account const &account)
bool same(STPathSet const &st1, Args const &... args)
std::uint32_t ownerCount(Env const &env, Account const &account)
XRPAmount txFee(Env const &env, std::uint16_t n)
std::tuple< STPathSet, STAmount, STAmount > findPaths(jtx::Env &env, jtx::Account const &src, jtx::Account const &dst, STAmount const &saDstAmount, std::optional< STAmount > const &saSendMax, std::optional< PathAsset > const &srcAsset, std::optional< AccountID > const &srcIssuer, std::optional< uint256 > const &domain)
uint256 getCheckIndex(AccountID const &account, std::uint32_t const sequence)
void checkMetrics(Suite &test, jtx::Env &env, std::size_t expectedCount, std::optional< std::size_t > expectedMaxCount, std::size_t expectedInLedger, std::size_t expectedPerLedger, std::uint64_t expectedMinFeeLevel=kBaseFeeLevel.fee(), std::uint64_t expectedMedFeeLevel=kMinEscalationFeeLevel.fee(), std::source_location const location=std::source_location::current())
json::Value rpf(jtx::Account const &src, jtx::Account const &dst, STAmount const &dstAmount, std::optional< STAmount > const &sendMax, std::optional< PathAsset > const &srcAsset, std::optional< AccountID > const &srcIssuer)
std::uint32_t sponsoringOwnerCount(Env const &env, Account const &account)
bool strandEqualHelper(Iter i)
void testHelper3TokensMix(TTester &&tester)
auto const kData
General field definitions, or fields used in multiple transaction namespaces.
STPathElement cpe(PathAsset const &pa)
std::tuple< STPathSet, STAmount, STAmount > findPathsByElement(jtx::Env &env, jtx::Account const &src, jtx::Account const &dst, STAmount const &saDstAmount, std::optional< STAmount > const &saSendMax, std::optional< STPathElement > const &srcElement, std::optional< AccountID > const &srcIssuer, std::optional< uint256 > const &domain)
STPathElement ipe(Asset const &asset)
json::Value ledgerEntryState(Env &env, Account const &acctA, Account const &acctB, std::string const &currency)
JTxFieldWrapper< JTxField< SField, StoredValue > > simpleField
bool equal(STAmount const &sa1, STAmount const &sa2)
STPathElement iape(AccountID const &account)
std::uint32_t sponsoredOwnerCount(Env const &env, Account const &account)
JTxFieldWrapper< ValueUnitField< SField, UnitTag, ValueType > > valueUnitWrapper
json::Value ledgerEntryRoot(Env &env, Account const &acct)
void stpathsetAppend(STPathSet &st, STPath const &p, Args const &... args)
void stpathAppendOne(STPath &st, Account const &account)
json::Value accountBalance(Env &env, Account const &acct)
STPath stpath(Args const &... args)
json::Value getAccountLines(Env &env, AccountID const &acctId)
auto makeVector(Input const &input)
bool checkArraySize(json::Value const &val, unsigned int size)
json::Value ledgerEntryOffer(jtx::Env &env, jtx::Account const &acct, std::uint32_t offerSeq)
bool checkVL(Slice const &result, std::string const &expected)
void stpathAppend(STPath &st, T const &t, Args const &... args)
STPathElement ape(AccountID const &a)
json::Value getAccountOffers(Env &env, AccountID const &acct, bool current)
constexpr XRPAmount
Convert XRP to drops (integral types).
Definition TxTest.h:54
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:13
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:95
BaseUInt< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition UintTypes.h:42
TypedField< STInteger< std::uint32_t > > SF_UINT32
Definition SField.h:341
TypedField< STAmount > SF_AMOUNT
Definition SField.h:355
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
Slice makeSlice(std::array< T, N > const &a)
Definition Slice.h:228
BaseUInt< 192 > MPTID
MPTID is a 192-bit value representing MPT Issuance ID, which is a concatenation of a 32-bit sequence ...
Definition UintTypes.h:54
TypedField< STBlob > SF_VL
Definition SField.h:359
FeeLevel< std::uint64_t > FeeLevel64
Definition Units.h:443
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
TypedField< STAccount > SF_ACCOUNT
Definition SField.h:354
BaseUInt< 256 > uint256
Definition base_uint.h:580
TypedField< STBitString< 256 > > SF_UINT256
Definition SField.h:347
uint256 key
Definition Keylet.h:21
AccountIdField(SF const &sfield, SV const &value)
BlobField(SF const &sfield, std::array< std::uint8_t, N > const &c)
JTxField(SF const &sfield, SV value)
BlobField(SF const &sfield, Slice const &cond)
JTxField< SF, SV, SV > base
std::optional< std::uint64_t > limit
std::vector< jtx::Account > holders
JF operator()(std::array< std::uint8_t, N > const &c) const
JF operator()(SV const &value) const
Generic helper class for helper classes that set a field on a JTx.
JTxField(SF const &sfield, SV value)
virtual void operator()(Env &, JTx &jt) const
virtual ~JTxField()=default
Execution context for applying a JSON transaction.
Definition JTx.h:27
json::Value jv
Definition JTx.h:28
Represents an XRP, IOU, or MPT quantity This customizes the string conversion and supports XRP conver...
StAmountField(SF const &sfield, SV const &value)
JTxField< SF, SV, OV > base
TimePointField(SF const &sfield, SV const &value)
JTxField< SF, SV, OV > base
UInt256Field(SF const &sfield, SV const &value)
unit::ValueUnit< UnitTag, ValueType > SV
T to_string(T... args)
T value_or(T... args)