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 <source_location>
47#include <string>
48#include <tuple>
49#include <type_traits>
50#include <utility>
51#include <vector>
52
53namespace xrpl::test::jtx {
54
61template <
62 class SField,
63 // NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
64 class StoredValue = typename SField::type::value_type,
65 class OutputValue = StoredValue>
67{
68 using SF = SField;
69 using SV = StoredValue;
70 using OV = OutputValue;
71
72protected:
73 SF const& sfield_;
75
76public:
77 explicit JTxField(SF const& sfield, SV value) : sfield_(sfield), value_(std::move(value))
78 {
79 }
80
81 virtual ~JTxField() = default;
82
83 [[nodiscard]] virtual OV
84 value() const = 0;
85
86 virtual void
87 operator()(Env&, JTx& jt) const
88 {
89 jt.jv[sfield_.jsonName] = value();
90 }
91};
92
93template <class SField, class StoredValue>
94struct JTxField<SField, StoredValue, StoredValue>
95{
96 using SF = SField;
97 using SV = StoredValue;
98 using OV = SV;
99
100protected:
101 SF const& sfield_;
103
104public:
105 explicit JTxField(SF const& sfield, SV value) : sfield_(sfield), value_(std::move(value))
106 {
107 }
108
109 void
110 operator()(Env&, JTx& jt) const
111 {
112 jt.jv[sfield_.jsonName] = value_;
113 }
114};
115
116struct TimePointField : public JTxField<SF_UINT32, NetClock::time_point, NetClock::rep>
117{
118 using SF = SF_UINT32;
122
123protected:
124 using Base::value_;
125
126public:
127 explicit TimePointField(SF const& sfield, SV const& value) : JTxField(sfield, value)
128 {
129 }
130
131 [[nodiscard]] OV
132 value() const override
133 {
134 return value_.time_since_epoch().count();
135 }
136};
137
138struct UInt256Field : public JTxField<SF_UINT256, UInt256, std::string>
139{
140 using SF = SF_UINT256;
141 using SV = UInt256;
144
145protected:
146 using Base::value_;
147
148public:
149 explicit UInt256Field(SF const& sfield, SV const& value) : JTxField(sfield, value)
150 {
151 }
152
153 [[nodiscard]] OV
154 value() const override
155 {
156 return to_string(value_);
157 }
158};
159
160struct AccountIdField : public JTxField<SF_ACCOUNT, AccountID, std::string>
161{
162 using SF = SF_ACCOUNT;
163 using SV = AccountID;
166
167protected:
168 using Base::value_;
169
170public:
171 explicit AccountIdField(SF const& sfield, SV const& value) : JTxField(sfield, value)
172 {
173 }
174
175 [[nodiscard]] OV
176 value() const override
177 {
178 return toBase58(value_);
179 }
180};
181
182struct StAmountField : public JTxField<SF_AMOUNT, STAmount, json::Value>
183{
184 using SF = SF_AMOUNT;
185 using SV = STAmount;
188
189protected:
190 using Base::value_;
191
192public:
193 explicit StAmountField(SF const& sfield, SV const& value) : JTxField(sfield, value)
194 {
195 }
196
197 [[nodiscard]] OV
198 value() const override
199 {
200 return value_.getJson(JsonOptions::Values::None);
201 }
202};
203
204struct BlobField : public JTxField<SF_VL, std::string>
205{
206 using SF = SF_VL;
209
210 using JTxField::JTxField;
211
212 explicit BlobField(SF const& sfield, Slice const& cond) : JTxField(sfield, strHex(cond))
213 {
214 }
215
216 template <size_t N>
217 explicit BlobField(SF const& sfield, std::array<std::uint8_t, N> const& c)
218 : BlobField(sfield, makeSlice(c))
219 {
220 }
221};
222
223template <class SField, class UnitTag, class ValueType>
224struct ValueUnitField : public JTxField<SField, unit::ValueUnit<UnitTag, ValueType>, ValueType>
225{
226 using SF = SField;
228 using OV = ValueType;
230
232
233protected:
234 using Base::value_;
235
236public:
237 using JTxField<SF, SV, OV>::JTxField;
238
239 [[nodiscard]] OV
240 value() const override
241 {
242 return value_.value();
243 }
244};
245
246template <class JTxField>
248{
249 using JF = JTxField;
250 using SF = JF::SF;
251 using SV = JF::SV;
252
253protected:
254 SF const& sfield_;
255
256public:
257 explicit JTxFieldWrapper(SF const& sfield) : sfield_(sfield)
258 {
259 }
260
261 JF
262 operator()(SV const& value) const
263 {
264 return JTxField(sfield_, value);
265 }
266};
267
268template <>
270{
271 using JF = BlobField;
272 using SF = JF::SF;
273 using SV = JF::SV;
274
275protected:
276 SF const& sfield_;
277
278public:
279 explicit JTxFieldWrapper(SF const& sfield) : sfield_(sfield)
280 {
281 }
282
283 JF
284 operator()(SV const& cond) const
285 {
286 return JF(sfield_, makeSlice(cond));
287 }
288
289 JF
290 operator()(Slice const& cond) const
291 {
292 return JF(sfield_, cond);
293 }
294
295 template <size_t N>
296 JF
298 {
299 return operator()(makeSlice(c));
300 }
301};
302
303// NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
304template <class SField, class UnitTag, class ValueType = typename SField::type::value_type>
306
307// NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
308template <class SField, class StoredValue = typename SField::type::value_type>
310
315
317
318// Functions used in debugging
320getAccountOffers(Env& env, AccountID const& acct, bool current = false);
321
322inline json::Value
323getAccountOffers(Env& env, Account const& acct, bool current = false)
324{
325 return getAccountOffers(env, acct.id(), current);
326}
327
329getAccountLines(Env& env, AccountID const& acctId);
330
331inline json::Value
332getAccountLines(Env& env, Account const& acct)
333{
334 return getAccountLines(env, acct.id());
335}
336
337template <typename... IOU>
339getAccountLines(Env& env, AccountID const& acctId, IOU... ious)
340{
341 auto jrr = getAccountLines(env, acctId);
342 json::Value res;
343 for (auto const& line : jrr[jss::lines])
344 {
345 for (auto const& iou : {ious...})
346 {
347 if (line[jss::currency].asString() == to_string(iou.currency))
348 {
349 json::Value v;
350 v[jss::currency] = line[jss::currency];
351 v[jss::balance] = line[jss::balance];
352 v[jss::limit] = line[jss::limit];
353 v[jss::account] = line[jss::account];
354 res[jss::lines].append(v);
355 }
356 }
357 }
358 if (!res.isNull())
359 return res;
360 return jrr;
361}
362
363[[nodiscard]] bool
364checkArraySize(json::Value const& val, unsigned int size);
365
366// Helper function that returns the owner count on an account.
368ownerCount(test::jtx::Env const& env, test::jtx::Account const& account);
369
370// Helper function that returns the sponsored owner count on an account.
372sponsoredOwnerCount(test::jtx::Env const& env, test::jtx::Account const& account);
373
374// Helper function that returns the sponsoring owner count on an account.
376sponsoringOwnerCount(test::jtx::Env const& env, test::jtx::Account const& account);
377
378// Helper function that returns the sponsoring account count on an account.
381
382[[nodiscard]]
383inline bool
384checkVL(Slice const& result, std::string const& expected)
385{
386 Serializer s;
387 s.addRaw(result);
388 return s.getString() == expected;
389}
390
391[[nodiscard]]
392inline bool
393checkVL(SLE::ConstRef sle, SField const& field, std::string const& expected)
394{
395 return strHex(expected) == strHex(sle->getFieldVL(field));
396}
397
398/* Path finding */
399/******************************************************************************/
400void
401stpathAppendOne(STPath& st, Account const& account);
402
403template <class T>
404void
405stpathAppendOne(STPath& st, T const& t)
407{
408 stpathAppendOne(st, Account{t});
409}
410
411void
412stpathAppendOne(STPath& st, STPathElement const& pe);
413
414template <class T, class... Args>
415void
416stpathAppend(STPath& st, T const& t, Args const&... args)
417{
418 stpathAppendOne(st, t);
419 if constexpr (sizeof...(args) > 0)
420 stpathAppend(st, args...);
421}
422
423template <class... Args>
424void
425stpathsetAppend(STPathSet& st, STPath const& p, Args const&... args)
426{
427 st.pushBack(p);
428 if constexpr (sizeof...(args) > 0)
429 stpathsetAppend(st, args...);
430}
431
432bool
433equal(STAmount const& sa1, STAmount const& sa2);
434
435template <class... Args>
436STPath
437stpath(Args const&... args)
438{
439 STPath st;
440 stpathAppend(st, args...);
441 return st;
442}
443
444template <class... Args>
445bool
446same(STPathSet const& st1, Args const&... args)
447{
448 STPathSet st2;
449 stpathsetAppend(st2, args...);
450 if (st1.size() != st2.size())
451 return false;
452
453 return std::ranges::all_of(
454 st2, [&st1](auto const& p) { return std::ranges::find(st1, p) != st1.end(); });
455}
456
458rpf(jtx::Account const& src,
459 jtx::Account const& dst,
460 STAmount const& dstAmount,
461 std::optional<STAmount> const& sendMax = std::nullopt,
462 std::optional<PathAsset> const& srcAsset = std::nullopt,
463 std::optional<AccountID> const& srcIssuer = std::nullopt);
464
467
468class Gate
469{
470private:
473 bool signaled_ = false;
474
475public:
476 // Thread safe, blocks until signaled or period expires.
477 // Returns `true` if signaled.
478 template <class Rep, class Period>
479 bool
481 {
483 auto b = cv_.wait_for(lk, relTime, [this] { return signaled_; });
484 signaled_ = false;
485 return b;
486 }
487
488 void
490 {
491 std::scoped_lock const lk(mutex_);
492 signaled_ = true;
493 cv_.notify_all();
494 }
495};
496
499 jtx::Env& env,
500 jtx::Account const& src,
501 jtx::Account const& dst,
502 STAmount const& saDstAmount,
503 std::optional<STAmount> const& saSendMax = std::nullopt,
504 std::optional<PathAsset> const& srcAsset = std::nullopt,
505 std::optional<AccountID> const& srcIssuer = std::nullopt,
506 std::optional<UInt256> const& domain = std::nullopt);
507
510 jtx::Env& env,
511 jtx::Account const& src,
512 jtx::Account const& dst,
513 STAmount const& saDstAmount,
514 std::optional<STAmount> const& saSendMax = std::nullopt,
515 std::optional<PathAsset> const& srcAsset = std::nullopt,
516 std::optional<AccountID> const& srcIssuer = std::nullopt,
517 std::optional<UInt256> const& domain = std::nullopt);
518
521 jtx::Env& env,
522 jtx::Account const& src,
523 jtx::Account const& dst,
524 STAmount const& saDstAmount,
525 std::optional<STAmount> const& saSendMax = std::nullopt,
526 std::optional<STPathElement> const& srcElement = std::nullopt,
527 std::optional<AccountID> const& srcIssuer = std::nullopt,
528 std::optional<UInt256> const& domain = std::nullopt);
529
530/******************************************************************************/
531
533txFee(Env const& env, std::uint16_t n);
534
536xrpMinusFee(Env const& env, std::int64_t xrpAmount);
537
538bool
540 Env& env,
541 AccountID const& account,
542 STAmount const& value,
543 bool defaultLimits = false);
544
545template <typename... Amts>
546bool
547expectHolding(Env& env, AccountID const& account, STAmount const& value, Amts const&... amts)
548{
549 return expectHolding(env, account, value, false) && expectHolding(env, account, amts...);
550}
551
552bool
553expectHolding(Env& env, AccountID const& account, None const& value);
554
555bool
556expectMPT(Env& env, AccountID const& account, STAmount const& value);
557
558bool
560 Env& env,
561 AccountID const& account,
562 std::uint16_t size,
563 std::vector<Amounts> const& toMatch = {});
564
566ledgerEntryRoot(Env& env, Account const& acct);
567
569ledgerEntryState(Env& env, Account const& acctA, Account const& acctB, std::string const& currency);
570
572ledgerEntryOffer(jtx::Env& env, jtx::Account const& acct, std::uint32_t offerSeq);
573
575ledgerEntryMPT(jtx::Env& env, jtx::Account const& acct, MPTID const& mptID);
576
578getBookOffers(jtx::Env& env, Asset const& takerPays, Asset const& takerGets);
579
581accountBalance(Env& env, Account const& acct);
582
583[[nodiscard]] bool
584expectLedgerEntryRoot(Env& env, Account const& acct, STAmount const& expectedValue);
585
586/* Payment Channel */
587/******************************************************************************/
588namespace paychan {
589
591create(
592 AccountID const& account,
593 AccountID const& to,
594 STAmount const& amount,
595 NetClock::duration const& settleDelay,
596 PublicKey const& pk,
597 std::optional<NetClock::time_point> const& cancelAfter = std::nullopt,
598 std::optional<std::uint32_t> const& dstTag = std::nullopt);
599
600inline json::Value
602 Account const& account,
603 Account const& to,
604 STAmount const& amount,
605 NetClock::duration const& settleDelay,
606 PublicKey const& pk,
607 std::optional<NetClock::time_point> const& cancelAfter = std::nullopt,
608 std::optional<std::uint32_t> const& dstTag = std::nullopt)
609{
610 return create(account.id(), to.id(), amount, settleDelay, pk, cancelAfter, dstTag);
611}
612
614fund(
615 AccountID const& account,
616 UInt256 const& channel,
617 STAmount const& amount,
618 std::optional<NetClock::time_point> const& expiration = std::nullopt);
619
621claim(
622 AccountID const& account,
623 UInt256 const& channel,
624 std::optional<STAmount> const& balance = std::nullopt,
625 std::optional<STAmount> const& amount = std::nullopt,
626 std::optional<Slice> const& signature = std::nullopt,
627 std::optional<PublicKey> const& pk = std::nullopt);
628
630channel(AccountID const& account, AccountID const& dst, std::uint32_t seqProxyValue);
631
632inline UInt256
633channel(Account const& account, Account const& dst, std::uint32_t seqProxyValue)
634{
635 return channel(account.id(), dst.id(), seqProxyValue);
636}
637
639channelBalance(ReadView const& view, UInt256 const& chan);
640
641bool
642channelExists(ReadView const& view, UInt256 const& chan);
643
644} // namespace paychan
645
646/* Crossing Limits */
647/******************************************************************************/
648
649void
650nOffers(Env& env, std::size_t n, Account const& account, STAmount const& in, STAmount const& out);
651
652/* Pay Strand */
653/***************************************************************/
654
661
668
673
674// Currency/MPTID path element
676cpe(PathAsset const& pa);
677
678// Currency/MPTID and issuer path element
680ipe(Asset const& asset);
681
682// Issuer path element
684iape(AccountID const& account);
685
686// Account path element
688ape(AccountID const& a);
689
690// All path element
692allPathElements(AccountID const& a, Asset const& asset);
693
694bool
695equal(std::unique_ptr<Step> const& s1, DirectStepInfo const& dsi);
696
697bool
698equal(std::unique_ptr<Step> const& s1, MPTEndpointStepInfo const& dsi);
699
700bool
701equal(std::unique_ptr<Step> const& s1, XRPEndpointStepInfo const& xrpStepInfo);
702
703bool
704equal(std::unique_ptr<Step> const& s1, xrpl::Book const& bsi);
705
706template <class Iter>
707bool
709{
710 // base case. all args processed and found equal.
711 return true;
712}
713
714template <class Iter, class StepInfo, class... Args>
715bool
716strandEqualHelper(Iter i, StepInfo&& si, Args&&... args)
717{
719 return false;
720 return strandEqualHelper(++i, std::forward<Args>(args)...);
721}
722
723template <class... Args>
724bool
725equal(Strand const& strand, Args&&... args)
726{
727 if (strand.size() != sizeof...(Args))
728 return false;
729 if (strand.empty())
730 return true;
731 return strandEqualHelper(strand.begin(), std::forward<Args>(args)...);
732}
733
734/***************************************************************/
735
736/* Check */
737/***************************************************************/
738namespace check {
739
743template <typename A>
746create(A const& account, A const& dest, STAmount const& sendMax)
747{
748 json::Value jv;
749 jv[sfAccount.jsonName] = to_string(account);
750 jv[sfSendMax.jsonName] = sendMax.getJson(JsonOptions::Values::None);
751 jv[sfDestination.jsonName] = to_string(dest);
752 jv[sfTransactionType.jsonName] = jss::CheckCreate;
753 return jv;
754}
755
756inline json::Value
757create(jtx::Account const& account, jtx::Account const& dest, STAmount const& sendMax)
758{
759 return create(account.id(), dest.id(), sendMax);
760}
761
762} // namespace check
763
766
767inline UInt256
768getCheckIndex(AccountID const& account, std::uint32_t const sequence)
769{
770 return keylet::check(account, SeqProxy::rawSequence(sequence)).key;
771}
772
773template <class Suite>
774void
776 Suite& test,
777 jtx::Env& env,
778 std::size_t expectedCount,
779 std::optional<std::size_t> expectedMaxCount,
780 std::size_t expectedInLedger,
781 std::size_t expectedPerLedger,
782 std::uint64_t expectedMinFeeLevel = kBaseFeeLevel.fee(),
783 std::uint64_t expectedMedFeeLevel = kMinEscalationFeeLevel.fee(),
785{
786 int const line = location.line();
787 char const* file = location.file_name();
788 FeeLevel64 const expectedMin{expectedMinFeeLevel};
789 FeeLevel64 const expectedMed{expectedMedFeeLevel};
790 auto const metrics = env.app().getTxQ().getMetrics(*env.current());
791 using namespace std::string_literals;
792
793 metrics.referenceFeeLevel == kBaseFeeLevel
794 ? test.pass()
795 : test.fail(
796 "reference: "s + std::to_string(metrics.referenceFeeLevel.value()) + "/" +
798 file,
799 line);
800
801 metrics.txCount == expectedCount
802 ? test.pass()
803 : test.fail(
804 "txCount: "s + std::to_string(metrics.txCount) + "/" + std::to_string(expectedCount),
805 file,
806 line);
807
808 metrics.txQMaxSize == expectedMaxCount
809 ? test.pass()
810 : test.fail(
811 "txQMaxSize: "s + std::to_string(metrics.txQMaxSize.value_or(0)) + "/" +
812 std::to_string(expectedMaxCount.value_or(0)),
813 file,
814 line);
815
816 metrics.txInLedger == expectedInLedger
817 ? test.pass()
818 : test.fail(
819 "txInLedger: "s + std::to_string(metrics.txInLedger) + "/" +
820 std::to_string(expectedInLedger),
821 file,
822 line);
823
824 metrics.txPerLedger == expectedPerLedger
825 ? test.pass()
826 : test.fail(
827 "txPerLedger: "s + std::to_string(metrics.txPerLedger) + "/" +
828 std::to_string(expectedPerLedger),
829 file,
830 line);
831
832 metrics.minProcessingFeeLevel == expectedMin
833 ? test.pass()
834 : test.fail(
835 "minProcessingFeeLevel: "s + std::to_string(metrics.minProcessingFeeLevel.value()) +
836 "/" + std::to_string(expectedMin.value()),
837 file,
838 line);
839
840 metrics.medFeeLevel == expectedMed
841 ? test.pass()
842 : test.fail(
843 "medFeeLevel: "s + std::to_string(metrics.medFeeLevel.value()) + "/" +
844 std::to_string(expectedMed.value()),
845 file,
846 line);
847
848 auto const expectedCurFeeLevel = expectedInLedger > expectedPerLedger
849 ? expectedMed * expectedInLedger * expectedInLedger /
850 (expectedPerLedger * expectedPerLedger)
851 : metrics.referenceFeeLevel;
852
853 metrics.openLedgerFeeLevel == expectedCurFeeLevel
854 ? test.pass()
855 : test.fail(
856 "openLedgerFeeLevel: "s + std::to_string(metrics.openLedgerFeeLevel.value()) + "/" +
857 std::to_string(expectedCurFeeLevel.value()),
858 file,
859 line);
860}
861
862/* LoanBroker */
863/******************************************************************************/
864
865namespace loan_broker {
866
868set(AccountID const& account, UInt256 const& vaultId, std::uint32_t flags = 0);
869
870// Use "del" because "delete" is a reserved word in C++.
872del(AccountID const& account, UInt256 const& brokerID, std::uint32_t flags = 0);
873
876 AccountID const& account,
877 UInt256 const& brokerID,
878 STAmount const& amount,
879 std::uint32_t flags = 0);
880
883 AccountID const& account,
884 UInt256 const& brokerID,
885 STAmount const& amount,
886 std::uint32_t flags = 0);
887
888// Must specify at least one of loanBrokerID or amount.
890coverClawback(AccountID const& account, std::uint32_t flags = 0);
891
892auto const kLoanBrokerId = JTxFieldWrapper<UInt256Field>(sfLoanBrokerID);
893
896
897auto const kDebtMaximum = SimpleField<SF_NUMBER>(sfDebtMaximum);
898
900
903
905
906} // namespace loan_broker
907
908/* Loan */
909/******************************************************************************/
910namespace loan {
911
913set(AccountID const& account,
914 UInt256 const& loanBrokerID,
915 Number principalRequested,
916 std::uint32_t flags = 0);
917
919
920// For `CounterPartySignature`, use `Sig(sfCounterpartySignature, ...)`
921
922auto const kLoanOriginationFee = SimpleField<SF_NUMBER>(sfLoanOriginationFee);
923
924auto const kLoanServiceFee = SimpleField<SF_NUMBER>(sfLoanServiceFee);
925
926auto const kLatePaymentFee = SimpleField<SF_NUMBER>(sfLatePaymentFee);
927
928auto const kClosePaymentFee = SimpleField<SF_NUMBER>(sfClosePaymentFee);
929
931
933
935
938
940 ValueUnitWrapper<SF_UINT32, unit::TenthBipsTag>(sfOverpaymentInterestRate);
941
942auto const kPaymentTotal = SimpleField<SF_UINT32>(sfPaymentTotal);
943
944auto const kPaymentInterval = SimpleField<SF_UINT32>(sfPaymentInterval);
945
946auto const kGracePeriod = SimpleField<SF_UINT32>(sfGracePeriod);
947
949manage(AccountID const& account, UInt256 const& loanID, std::uint32_t flags);
950
952del(AccountID const& account, UInt256 const& loanID, std::uint32_t flags = 0);
953
955pay(AccountID const& account,
956 UInt256 const& loanID,
957 STAmount const& amount,
958 std::uint32_t flags = 0);
959
960} // namespace loan
961
966{
967private:
969
970public:
971 explicit Expiration(NetClock::time_point const& expiry)
972 : expiry_{expiry.time_since_epoch().count()}
973 {
974 }
975
976 void
977 operator()(Env&, JTx& jt) const
978 {
979 jt[sfExpiration.jsonName] = expiry_;
980 }
981};
982
987{
988private:
990
991public:
992 explicit SourceTag(std::uint32_t tag) : tag_{tag}
993 {
994 }
995
996 void
997 operator()(Env&, JTx& jt) const
998 {
999 jt[sfSourceTag.jsonName] = tag_;
1000 }
1001};
1002
1007{
1008private:
1010
1011public:
1012 explicit DestTag(std::uint32_t tag) : tag_{tag}
1013 {
1014 }
1015
1016 void
1017 operator()(Env&, JTx& jt) const
1018 {
1019 jt[sfDestinationTag.jsonName] = tag_;
1020 }
1021};
1022
1024{
1026 // 3-letter currency if Issue, ignored if MPT
1029 std::vector<jtx::Account> holders = {}; // NOLINT(readability-redundant-member-init)
1030 // trust-limit if Issue, maxAmount if MPT
1032 // 0-50'000 (0-50%)
1034};
1035
1036namespace detail {
1037
1038IOU
1039issueHelperIOU(IssuerArgs const& args);
1040
1041MPT
1042issueHelperMPT(IssuerArgs const& args);
1043
1044} // namespace detail
1045
1046template <typename TTester>
1047void
1054
1055template <typename TTester>
1056void
1067
1068} // namespace xrpl::test::jtx
T all_of(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:735
std::shared_ptr< STLedgerEntry const > const & ConstRef
std::vector< STPath >::size_type size() const
Definition STPathSet.h:624
bool pushBack(STPath const &e)
pushBack adds a path to the set.
Definition STPathSet.h:669
std::vector< STPath >::const_iterator end() const
Definition STPathSet.h:618
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:309
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:1786
static constexpr FeeLevel64 kBaseLevel
Fee level for single-signed reference transaction.
Definition TxQ.h:64
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
SourceTag(std::uint32_t tag)
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:360
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 coverWithdraw(AccountID const &account, UInt256 const &brokerID, STAmount const &amount, uint32_t flags)
json::Value coverDeposit(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 coverClawback(AccountID const &account, std::uint32_t flags)
json::Value manage(AccountID const &account, UInt256 const &loanID, std::uint32_t flags)
json::Value set(AccountID const &account, UInt256 const &loanBrokerID, Number principalRequested, 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 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 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)
STAmount channelBalance(ReadView const &view, UInt256 const &chan)
bool channelExists(ReadView const &view, UInt256 const &chan)
UInt256 channel(AccountID const &account, AccountID const &dst, std::uint32_t seqProxyValue)
void nOffers(Env &env, std::size_t n, Account const &account, STAmount const &in, STAmount const &out)
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)
JTxFieldWrapper< JTxField< SField, StoredValue > > SimpleField
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)
JTxFieldWrapper< ValueUnitField< SField, UnitTag, ValueType > > ValueUnitWrapper
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)
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)
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)
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)
STPathElement ipe(Asset const &asset)
json::Value ledgerEntryState(Env &env, Account const &acctA, Account const &acctB, std::string const &currency)
bool equal(STAmount const &sa1, STAmount const &sa2)
STPathElement iape(AccountID const &account)
std::uint32_t sponsoredOwnerCount(Env const &env, Account const &account)
json::Value ledgerEntryRoot(Env &env, Account const &acct)
void stpathsetAppend(STPathSet &st, STPath const &p, Args const &... args)
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)
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)
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)
UInt256 getCheckIndex(AccountID const &account, std::uint32_t const sequence)
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:344
TypedField< STAmount > SF_AMOUNT
Definition SField.h:358
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:657
Slice makeSlice(std::array< T, N > const &a)
Definition Slice.h:228
BaseUInt< 256 > UInt256
Definition base_uint.h:580
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:362
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:357
TypedField< STBitString< 256 > > SF_UINT256
Definition SField.h:350
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)