xrpld
Loading...
Searching...
No Matches
jtx/TestHelpers.h
1#pragma once
2
3#include <test/jtx/Env.h>
4
5#include <xrpld/app/misc/TxQ.h>
6
7#include <xrpl/basics/base_uint.h>
8#include <xrpl/json/json_value.h>
9#include <xrpl/protocol/AccountID.h>
10#include <xrpl/protocol/Quality.h>
11#include <xrpl/protocol/STNumber.h>
12#include <xrpl/protocol/Units.h>
13#include <xrpl/protocol/jss.h>
14#include <xrpl/tx/paths/detail/Steps.h>
15
16#include <algorithm>
17#include <source_location>
18#include <utility>
19#include <vector>
20
21namespace xrpl::test::jtx {
22
28template <
29 class SField,
30 // NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
31 class StoredValue = typename SField::type::value_type,
32 class OutputValue = StoredValue>
34{
35 using SF = SField;
36 using SV = StoredValue;
37 using OV = OutputValue;
38
39protected:
40 SF const& sfield_;
42
43public:
44 explicit JTxField(SF const& sfield, SV value) : sfield_(sfield), value_(std::move(value))
45 {
46 }
47
48 virtual ~JTxField() = default;
49
50 [[nodiscard]] virtual OV
51 value() const = 0;
52
53 virtual void
54 operator()(Env&, JTx& jt) const
55 {
56 jt.jv[sfield_.jsonName] = value();
57 }
58};
59
60template <class SField, class StoredValue>
61struct JTxField<SField, StoredValue, StoredValue>
62{
63 using SF = SField;
64 using SV = StoredValue;
65 using OV = SV;
66
67protected:
68 SF const& sfield_;
70
71public:
72 explicit JTxField(SF const& sfield, SV value) : sfield_(sfield), value_(std::move(value))
73 {
74 }
75
76 void
77 operator()(Env&, JTx& jt) const
78 {
79 jt.jv[sfield_.jsonName] = value_;
80 }
81};
82
83struct TimePointField : public JTxField<SF_UINT32, NetClock::time_point, NetClock::rep>
84{
85 using SF = SF_UINT32;
89
90protected:
91 using base::value_;
92
93public:
94 explicit TimePointField(SF const& sfield, SV const& value) : JTxField(sfield, value)
95 {
96 }
97
98 [[nodiscard]] OV
99 value() const override
100 {
101 return value_.time_since_epoch().count();
102 }
103};
104
105struct UInt256Field : public JTxField<SF_UINT256, uint256, std::string>
106{
107 using SF = SF_UINT256;
108 using SV = uint256;
111
112protected:
113 using base::value_;
114
115public:
116 explicit UInt256Field(SF const& sfield, SV const& value) : JTxField(sfield, value)
117 {
118 }
119
120 [[nodiscard]] OV
121 value() const override
122 {
123 return to_string(value_);
124 }
125};
126
127struct AccountIdField : public JTxField<SF_ACCOUNT, AccountID, std::string>
128{
129 using SF = SF_ACCOUNT;
130 using SV = AccountID;
133
134protected:
135 using base::value_;
136
137public:
138 explicit AccountIdField(SF const& sfield, SV const& value) : JTxField(sfield, value)
139 {
140 }
141
142 [[nodiscard]] OV
143 value() const override
144 {
145 return toBase58(value_);
146 }
147};
148
149struct StAmountField : public JTxField<SF_AMOUNT, STAmount, json::Value>
150{
151 using SF = SF_AMOUNT;
152 using SV = STAmount;
155
156protected:
157 using base::value_;
158
159public:
160 explicit StAmountField(SF const& sfield, SV const& value) : JTxField(sfield, value)
161 {
162 }
163
164 [[nodiscard]] OV
165 value() const override
166 {
167 return value_.getJson(JsonOptions::Values::None);
168 }
169};
170
171struct BlobField : public JTxField<SF_VL, std::string>
172{
173 using SF = SF_VL;
176
177 using JTxField::JTxField;
178
179 explicit BlobField(SF const& sfield, Slice const& cond) : JTxField(sfield, strHex(cond))
180 {
181 }
182
183 template <size_t N>
184 explicit BlobField(SF const& sfield, std::array<std::uint8_t, N> const& c)
185 : BlobField(sfield, makeSlice(c))
186 {
187 }
188};
189
190template <class SField, class UnitTag, class ValueType>
191struct ValueUnitField : public JTxField<SField, unit::ValueUnit<UnitTag, ValueType>, ValueType>
192{
193 using SF = SField;
195 using OV = ValueType;
197
199
200protected:
201 using base::value_;
202
203public:
204 using JTxField<SF, SV, OV>::JTxField;
205
206 [[nodiscard]] OV
207 value() const override
208 {
209 return value_.value();
210 }
211};
212
213template <class JTxField>
215{
216 using JF = JTxField;
217 using SF = JF::SF;
218 using SV = JF::SV;
219
220protected:
221 SF const& sfield_;
222
223public:
224 explicit JTxFieldWrapper(SF const& sfield) : sfield_(sfield)
225 {
226 }
227
228 JF
229 operator()(SV const& value) const
230 {
231 return JTxField(sfield_, value);
232 }
233};
234
235template <>
237{
238 using JF = BlobField;
239 using SF = JF::SF;
240 using SV = JF::SV;
241
242protected:
243 SF const& sfield_;
244
245public:
246 explicit JTxFieldWrapper(SF const& sfield) : sfield_(sfield)
247 {
248 }
249
250 JF
251 operator()(SV const& cond) const
252 {
253 return JF(sfield_, makeSlice(cond));
254 }
255
256 JF
257 operator()(Slice const& cond) const
258 {
259 return JF(sfield_, cond);
260 }
261
262 template <size_t N>
263 JF
265 {
266 return operator()(makeSlice(c));
267 }
268};
269
270// NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
271template <class SField, class UnitTag, class ValueType = typename SField::type::value_type>
273
274// NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
275template <class SField, class StoredValue = typename SField::type::value_type>
277
281
283
284// TODO We only need this long "requires" clause as polyfill, for C++20
285// implementations which are missing <ranges> header. Replace with
286// `std::ranges::range<Input>`, and accordingly use std::ranges::begin/end
287// when we have moved to better compilers.
288template <typename Input>
289auto
290makeVector(Input const& input)
291 requires requires(Input& v) {
292 std::begin(v);
293 std::end(v);
294 }
295{
296 return std::vector(std::begin(input), std::end(input));
297}
298
299// Functions used in debugging
301getAccountOffers(Env& env, AccountID const& acct, bool current = false);
302
303inline json::Value
304getAccountOffers(Env& env, Account const& acct, bool current = false)
305{
306 return getAccountOffers(env, acct.id(), current);
307}
308
310getAccountLines(Env& env, AccountID const& acctId);
311
312inline json::Value
313getAccountLines(Env& env, Account const& acct)
314{
315 return getAccountLines(env, acct.id());
316}
317
318template <typename... IOU>
320getAccountLines(Env& env, AccountID const& acctId, IOU... ious)
321{
322 auto jrr = getAccountLines(env, acctId);
323 json::Value res;
324 for (auto const& line : jrr[jss::lines])
325 {
326 for (auto const& iou : {ious...})
327 {
328 if (line[jss::currency].asString() == to_string(iou.currency))
329 {
330 json::Value v;
331 v[jss::currency] = line[jss::currency];
332 v[jss::balance] = line[jss::balance];
333 v[jss::limit] = line[jss::limit];
334 v[jss::account] = line[jss::account];
335 res[jss::lines].append(v);
336 }
337 }
338 }
339 if (!res.isNull())
340 return res;
341 return jrr;
342}
343
344[[nodiscard]] bool
345checkArraySize(json::Value const& val, unsigned int size);
346
347// Helper function that returns the owner count on an account.
349ownerCount(test::jtx::Env const& env, test::jtx::Account const& account);
350
351[[nodiscard]]
352inline bool
353checkVL(Slice const& result, std::string const& expected)
354{
355 Serializer s;
356 s.addRaw(result);
357 return s.getString() == expected;
358}
359
360[[nodiscard]]
361inline bool
362checkVL(SLE::const_ref sle, SField const& field, std::string const& expected)
363{
364 return strHex(expected) == strHex(sle->getFieldVL(field));
365}
366
367/* Path finding */
368/******************************************************************************/
369void
370stpathAppendOne(STPath& st, Account const& account);
371
372template <class T>
374stpathAppendOne(STPath& st, T const& t)
375{
376 stpathAppendOne(st, Account{t});
377}
378
379void
380stpathAppendOne(STPath& st, STPathElement const& pe);
381
382template <class T, class... Args>
383void
384stpathAppend(STPath& st, T const& t, Args const&... args)
385{
386 stpathAppendOne(st, t);
387 if constexpr (sizeof...(args) > 0)
388 stpathAppend(st, args...);
389}
390
391template <class... Args>
392void
393stpathsetAppend(STPathSet& st, STPath const& p, Args const&... args)
394{
395 st.pushBack(p);
396 if constexpr (sizeof...(args) > 0)
397 stpathsetAppend(st, args...);
398}
399
400bool
401equal(STAmount const& sa1, STAmount const& sa2);
402
403template <class... Args>
404STPath
405stpath(Args const&... args)
406{
407 STPath st;
408 stpathAppend(st, args...);
409 return st;
410}
411
412template <class... Args>
413bool
414same(STPathSet const& st1, Args const&... args)
415{
416 STPathSet st2;
417 stpathsetAppend(st2, args...);
418 if (st1.size() != st2.size())
419 return false;
420
421 for (auto const& p : st2)
422 {
423 if (std::ranges::find(st1, p) == st1.end())
424 return false;
425 }
426 return true;
427}
428
430rpf(jtx::Account const& src,
431 jtx::Account const& dst,
432 STAmount const& dstAmount,
433 std::optional<STAmount> const& sendMax = std::nullopt,
434 std::optional<PathAsset> const& srcAsset = std::nullopt,
435 std::optional<AccountID> const& srcIssuer = std::nullopt);
436
439
440class Gate
441{
442private:
445 bool signaled_ = false;
446
447public:
448 // Thread safe, blocks until signaled or period expires.
449 // Returns `true` if signaled.
450 template <class Rep, class Period>
451 bool
453 {
455 auto b = cv_.wait_for(lk, relTime, [this] { return signaled_; });
456 signaled_ = false;
457 return b;
458 }
459
460 void
462 {
463 std::scoped_lock const lk(mutex_);
464 signaled_ = true;
465 cv_.notify_all();
466 }
467};
468
471 jtx::Env& env,
472 jtx::Account const& src,
473 jtx::Account const& dst,
474 STAmount const& saDstAmount,
475 std::optional<STAmount> const& saSendMax = std::nullopt,
476 std::optional<PathAsset> const& srcAsset = std::nullopt,
477 std::optional<AccountID> const& srcIssuer = std::nullopt,
478 std::optional<uint256> const& domain = std::nullopt);
479
482 jtx::Env& env,
483 jtx::Account const& src,
484 jtx::Account const& dst,
485 STAmount const& saDstAmount,
486 std::optional<STAmount> const& saSendMax = std::nullopt,
487 std::optional<PathAsset> const& srcAsset = std::nullopt,
488 std::optional<AccountID> const& srcIssuer = std::nullopt,
489 std::optional<uint256> const& domain = std::nullopt);
490
493 jtx::Env& env,
494 jtx::Account const& src,
495 jtx::Account const& dst,
496 STAmount const& saDstAmount,
497 std::optional<STAmount> const& saSendMax = std::nullopt,
498 std::optional<STPathElement> const& srcElement = std::nullopt,
499 std::optional<AccountID> const& srcIssuer = std::nullopt,
500 std::optional<uint256> const& domain = std::nullopt);
501
502/******************************************************************************/
503
505txFee(Env const& env, std::uint16_t n);
506
508xrpMinusFee(Env const& env, std::int64_t xrpAmount);
509
510bool
512 Env& env,
513 AccountID const& account,
514 STAmount const& value,
515 bool defaultLimits = false);
516
517template <typename... Amts>
518bool
519expectHolding(Env& env, AccountID const& account, STAmount const& value, Amts const&... amts)
520{
521 return expectHolding(env, account, value, false) && expectHolding(env, account, amts...);
522}
523
524bool
525expectHolding(Env& env, AccountID const& account, None const& value);
526
527bool
528expectMPT(Env& env, AccountID const& account, STAmount const& value);
529
530bool
532 Env& env,
533 AccountID const& account,
534 std::uint16_t size,
535 std::vector<Amounts> const& toMatch = {});
536
538ledgerEntryRoot(Env& env, Account const& acct);
539
541ledgerEntryState(Env& env, Account const& acctA, Account const& acctB, std::string const& currency);
542
544ledgerEntryOffer(jtx::Env& env, jtx::Account const& acct, std::uint32_t offerSeq);
545
547ledgerEntryMPT(jtx::Env& env, jtx::Account const& acct, MPTID const& mptID);
548
550getBookOffers(jtx::Env& env, Asset const& takerPays, Asset const& takerGets);
551
553accountBalance(Env& env, Account const& acct);
554
555[[nodiscard]] bool
556expectLedgerEntryRoot(Env& env, Account const& acct, STAmount const& expectedValue);
557
558/* Payment Channel */
559/******************************************************************************/
560namespace paychan {
561
563create(
564 AccountID const& account,
565 AccountID const& to,
566 STAmount const& amount,
567 NetClock::duration const& settleDelay,
568 PublicKey const& pk,
569 std::optional<NetClock::time_point> const& cancelAfter = std::nullopt,
570 std::optional<std::uint32_t> const& dstTag = std::nullopt);
571
572inline json::Value
574 Account const& account,
575 Account const& to,
576 STAmount const& amount,
577 NetClock::duration const& settleDelay,
578 PublicKey const& pk,
579 std::optional<NetClock::time_point> const& cancelAfter = std::nullopt,
580 std::optional<std::uint32_t> const& dstTag = std::nullopt)
581{
582 return create(account.id(), to.id(), amount, settleDelay, pk, cancelAfter, dstTag);
583}
584
586fund(
587 AccountID const& account,
588 uint256 const& channel,
589 STAmount const& amount,
590 std::optional<NetClock::time_point> const& expiration = std::nullopt);
591
593claim(
594 AccountID const& account,
595 uint256 const& channel,
596 std::optional<STAmount> const& balance = std::nullopt,
597 std::optional<STAmount> const& amount = std::nullopt,
598 std::optional<Slice> const& signature = std::nullopt,
599 std::optional<PublicKey> const& pk = std::nullopt);
600
602channel(AccountID const& account, AccountID const& dst, std::uint32_t seqProxyValue);
603
604inline uint256
605channel(Account const& account, Account const& dst, std::uint32_t seqProxyValue)
606{
607 return channel(account.id(), dst.id(), seqProxyValue);
608}
609
611channelBalance(ReadView const& view, uint256 const& chan);
612
613bool
614channelExists(ReadView const& view, uint256 const& chan);
615
616} // namespace paychan
617
618/* Crossing Limits */
619/******************************************************************************/
620
621void
622nOffers(Env& env, std::size_t n, Account const& account, STAmount const& in, STAmount const& out);
623
624/* Pay Strand */
625/***************************************************************/
626
633
640
645
646// Currency/MPTID path element
648cpe(PathAsset const& pa);
649
650// Currency/MPTID and issuer path element
652ipe(Asset const& asset);
653
654// Issuer path element
656iape(AccountID const& account);
657
658// Account path element
660ape(AccountID const& a);
661
662// All path element
664allPathElements(AccountID const& a, Asset const& asset);
665
666bool
667equal(std::unique_ptr<Step> const& s1, DirectStepInfo const& dsi);
668
669bool
670equal(std::unique_ptr<Step> const& s1, MPTEndpointStepInfo const& dsi);
671
672bool
673equal(std::unique_ptr<Step> const& s1, XRPEndpointStepInfo const& xrpStepInfo);
674
675bool
676equal(std::unique_ptr<Step> const& s1, xrpl::Book const& bsi);
677
678template <class Iter>
679bool
681{
682 // base case. all args processed and found equal.
683 return true;
684}
685
686template <class Iter, class StepInfo, class... Args>
687bool
688strandEqualHelper(Iter i, StepInfo&& si, Args&&... args)
689{
691 return false;
692 return strandEqualHelper(++i, std::forward<Args>(args)...);
693}
694
695template <class... Args>
696bool
697equal(Strand const& strand, Args&&... args)
698{
699 if (strand.size() != sizeof...(Args))
700 return false;
701 if (strand.empty())
702 return true;
703 return strandEqualHelper(strand.begin(), std::forward<Args>(args)...);
704}
705
706/***************************************************************/
707
708/* Check */
709/***************************************************************/
710namespace check {
711
713template <typename A>
716create(A const& account, A const& dest, STAmount const& sendMax)
717{
718 json::Value jv;
719 jv[sfAccount.jsonName] = to_string(account);
720 jv[sfSendMax.jsonName] = sendMax.getJson(JsonOptions::Values::None);
721 jv[sfDestination.jsonName] = to_string(dest);
722 jv[sfTransactionType.jsonName] = jss::CheckCreate;
723 return jv;
724}
725
726inline json::Value
727create(jtx::Account const& account, jtx::Account const& dest, STAmount const& sendMax)
728{
729 return create(account.id(), dest.id(), sendMax);
730}
731
732} // namespace check
733
736
737inline uint256
738getCheckIndex(AccountID const& account, std::uint32_t uSequence)
739{
740 return keylet::check(account, uSequence).key;
741}
742
743template <class Suite>
744void
746 Suite& test,
747 jtx::Env& env,
748 std::size_t expectedCount,
749 std::optional<std::size_t> expectedMaxCount,
750 std::size_t expectedInLedger,
751 std::size_t expectedPerLedger,
752 std::uint64_t expectedMinFeeLevel = kBaseFeeLevel.fee(),
753 std::uint64_t expectedMedFeeLevel = kMinEscalationFeeLevel.fee(),
755{
756 int const line = location.line();
757 char const* file = location.file_name();
758 FeeLevel64 const expectedMin{expectedMinFeeLevel};
759 FeeLevel64 const expectedMed{expectedMedFeeLevel};
760 auto const metrics = env.app().getTxQ().getMetrics(*env.current());
761 using namespace std::string_literals;
762
763 metrics.referenceFeeLevel == kBaseFeeLevel
764 ? test.pass()
765 : test.fail(
766 "reference: "s + std::to_string(metrics.referenceFeeLevel.value()) + "/" +
768 file,
769 line);
770
771 metrics.txCount == expectedCount
772 ? test.pass()
773 : test.fail(
774 "txCount: "s + std::to_string(metrics.txCount) + "/" + std::to_string(expectedCount),
775 file,
776 line);
777
778 metrics.txQMaxSize == expectedMaxCount
779 ? test.pass()
780 : test.fail(
781 "txQMaxSize: "s + std::to_string(metrics.txQMaxSize.value_or(0)) + "/" +
782 std::to_string(expectedMaxCount.value_or(0)),
783 file,
784 line);
785
786 metrics.txInLedger == expectedInLedger
787 ? test.pass()
788 : test.fail(
789 "txInLedger: "s + std::to_string(metrics.txInLedger) + "/" +
790 std::to_string(expectedInLedger),
791 file,
792 line);
793
794 metrics.txPerLedger == expectedPerLedger
795 ? test.pass()
796 : test.fail(
797 "txPerLedger: "s + std::to_string(metrics.txPerLedger) + "/" +
798 std::to_string(expectedPerLedger),
799 file,
800 line);
801
802 metrics.minProcessingFeeLevel == expectedMin
803 ? test.pass()
804 : test.fail(
805 "minProcessingFeeLevel: "s + std::to_string(metrics.minProcessingFeeLevel.value()) +
806 "/" + std::to_string(expectedMin.value()),
807 file,
808 line);
809
810 metrics.medFeeLevel == expectedMed
811 ? test.pass()
812 : test.fail(
813 "medFeeLevel: "s + std::to_string(metrics.medFeeLevel.value()) + "/" +
814 std::to_string(expectedMed.value()),
815 file,
816 line);
817
818 auto const expectedCurFeeLevel = expectedInLedger > expectedPerLedger
819 ? expectedMed * expectedInLedger * expectedInLedger /
820 (expectedPerLedger * expectedPerLedger)
821 : metrics.referenceFeeLevel;
822
823 metrics.openLedgerFeeLevel == expectedCurFeeLevel
824 ? test.pass()
825 : test.fail(
826 "openLedgerFeeLevel: "s + std::to_string(metrics.openLedgerFeeLevel.value()) + "/" +
827 std::to_string(expectedCurFeeLevel.value()),
828 file,
829 line);
830}
831
832/* LoanBroker */
833/******************************************************************************/
834
835namespace loanBroker {
836
838set(AccountID const& account, uint256 const& vaultId, std::uint32_t flags = 0);
839
840// Use "del" because "delete" is a reserved word in C++.
842del(AccountID const& account, uint256 const& brokerID, std::uint32_t flags = 0);
843
846 AccountID const& account,
847 uint256 const& brokerID,
848 STAmount const& amount,
849 std::uint32_t flags = 0);
850
853 AccountID const& account,
854 uint256 const& brokerID,
855 STAmount const& amount,
856 std::uint32_t flags = 0);
857
858// Must specify at least one of loanBrokerID or amount.
860coverClawback(AccountID const& account, std::uint32_t flags = 0);
861
862auto const kLoanBrokerId = JTxFieldWrapper<UInt256Field>(sfLoanBrokerID);
863
866
867auto const kDebtMaximum = simpleField<SF_NUMBER>(sfDebtMaximum);
868
870
873
875
876} // namespace loanBroker
877
878/* Loan */
879/******************************************************************************/
880namespace loan {
881
883set(AccountID const& account,
884 uint256 const& loanBrokerID,
885 Number principalRequested,
886 std::uint32_t flags = 0);
887
889
890// For `CounterPartySignature`, use `Sig(sfCounterpartySignature, ...)`
891
892auto const kLoanOriginationFee = simpleField<SF_NUMBER>(sfLoanOriginationFee);
893
894auto const kLoanServiceFee = simpleField<SF_NUMBER>(sfLoanServiceFee);
895
896auto const kLatePaymentFee = simpleField<SF_NUMBER>(sfLatePaymentFee);
897
898auto const kClosePaymentFee = simpleField<SF_NUMBER>(sfClosePaymentFee);
899
901
903
905
908
910 valueUnitWrapper<SF_UINT32, unit::TenthBipsTag>(sfOverpaymentInterestRate);
911
912auto const kPaymentTotal = simpleField<SF_UINT32>(sfPaymentTotal);
913
914auto const kPaymentInterval = simpleField<SF_UINT32>(sfPaymentInterval);
915
916auto const kGracePeriod = simpleField<SF_UINT32>(sfGracePeriod);
917
919manage(AccountID const& account, uint256 const& loanID, std::uint32_t flags);
920
922del(AccountID const& account, uint256 const& loanID, std::uint32_t flags = 0);
923
925pay(AccountID const& account,
926 uint256 const& loanID,
927 STAmount const& amount,
928 std::uint32_t flags = 0);
929
930} // namespace loan
931
934{
935private:
937
938public:
939 explicit Expiration(NetClock::time_point const& expiry)
940 : expiry_{expiry.time_since_epoch().count()}
941 {
942 }
943
944 void
945 operator()(Env&, JTx& jt) const
946 {
947 jt[sfExpiration.jsonName] = expiry_;
948 }
949};
950
953{
954private:
956
957public:
958 explicit SourceTag(std::uint32_t tag) : tag_{tag}
959 {
960 }
961
962 void
963 operator()(Env&, JTx& jt) const
964 {
965 jt[sfSourceTag.jsonName] = tag_;
966 }
967};
968
971{
972private:
974
975public:
976 explicit DestTag(std::uint32_t tag) : tag_{tag}
977 {
978 }
979
980 void
981 operator()(Env&, JTx& jt) const
982 {
983 jt[sfDestinationTag.jsonName] = tag_;
984 }
985};
986
988{
990 // 3-letter currency if Issue, ignored if MPT
993 std::vector<jtx::Account> holders = {}; // NOLINT(readability-redundant-member-init)
994 // trust-limit if Issue, maxAmount if MPT
996 // 0-50'000 (0-50%)
998};
999
1000namespace detail {
1001
1002IOU
1003issueHelperIOU(IssuerArgs const& args);
1004
1005MPT
1006issueHelperMPT(IssuerArgs const& args);
1007
1008} // namespace detail
1009
1010template <typename TTester>
1011void
1018
1019template <typename TTester>
1020void
1031
1032} // namespace xrpl::test::jtx
T begin(T... args)
A testsuite class.
Definition suite.h:50
Represents a JSON value.
Definition json_value.h:130
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:16
std::uint32_t rep
Definition chrono.h:43
std::chrono::time_point< NetClock > time_point
Definition chrono.h:46
std::chrono::duration< rep, period > duration
Definition chrono.h:45
Number is a floating point type that can represent a wide range of values.
Definition Number.h:306
A public key.
Definition PublicKey.h:42
A view into a ledger.
Definition ReadView.h:31
Identifies fields.
Definition SField.h:130
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:528
void pushBack(STPath const &e)
Definition STPathSet.h:540
std::vector< STPath >::const_iterator end() const
Definition STPathSet.h:522
std::string getString() const
Definition Serializer.h:212
int addRaw(Blob const &vector)
virtual TxQ & getTxQ()=0
An immutable linear range of bytes.
Definition Slice.h:26
Metrics getMetrics(OpenView const &view) const
Returns fee metrics in reference fee level units.
Definition TxQ.cpp:1739
static constexpr FeeLevel64 kBaseLevel
Fee level for single-signed reference transaction.
Definition TxQ.h:43
Immutable cryptographic account descriptor.
Definition jtx/Account.h:17
AccountID id() const
Returns the Account ID.
Definition jtx/Account.h:85
std::uint32_t const tag_
void operator()(Env &, JTx &jt) const
DestTag(std::uint32_t tag)
A transaction testing environment.
Definition Env.h:143
Application & app()
Definition Env.h:280
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:353
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:323
T current(T... args)
T end(T... args)
T find(T... args)
T forward(T... args)
T is_same_v
STL namespace.
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Definition Indexes.cpp:322
Check operations.
Definition check.h:12
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 coverClawback(AccountID const &account, std::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)
static 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)
static 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)
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)
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)
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)
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)
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 uSequence)
auto makeVector(Input const &input)
constexpr XRPAmount
Convert XRP to drops (integral types).
Definition TxTest.h:48
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:10
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:93
BaseUInt< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition UintTypes.h:36
TypedField< STInteger< std::uint32_t > > SF_UINT32
Definition SField.h:335
TypedField< STAmount > SF_AMOUNT
Definition SField.h:349
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:633
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:44
TypedField< STBlob > SF_VL
Definition SField.h:353
FeeLevel< std::uint64_t > FeeLevel64
Definition Units.h:428
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
TypedField< STAccount > SF_ACCOUNT
Definition SField.h:348
BaseUInt< 256 > uint256
Definition base_uint.h:562
std::enable_if_t< std::is_same_v< T, char >||std::is_same_v< T, unsigned char >, Slice > makeSlice(std::array< T, N > const &a)
Definition Slice.h:215
TypedField< STBitString< 256 > > SF_UINT256
Definition SField.h:341
uint256 key
Definition Keylet.h:20
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:23
json::Value jv
Definition JTx.h:24
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
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)