xrpld
Loading...
Searching...
No Matches
Env.h
1#pragma once
2
3#include <test/jtx/AbstractClient.h>
4#include <test/jtx/Account.h>
5#include <test/jtx/JTx.h>
6#include <test/jtx/ManualTimeKeeper.h>
7#include <test/jtx/amount.h>
8#include <test/jtx/envconfig.h>
9#include <test/jtx/require.h>
10#include <test/jtx/tags.h>
11#include <test/jtx/vault.h>
12#include <test/unit_test/SuiteJournal.h>
13
14#include <xrpld/app/ledger/OpenLedger.h>
15#include <xrpld/app/main/Application.h>
16#include <xrpld/core/Config.h>
17#include <xrpld/rpc/detail/Pathfinder.h>
18
19#include <xrpl/basics/Log.h>
20#include <xrpl/basics/chrono.h>
21#include <xrpl/beast/utility/Journal.h>
22#include <xrpl/json/json_value.h>
23#include <xrpl/json/to_string.h>
24#include <xrpl/ledger/Ledger.h>
25#include <xrpl/protocol/ApiVersion.h>
26#include <xrpl/protocol/Feature.h>
27#include <xrpl/protocol/Indexes.h>
28#include <xrpl/protocol/Issue.h>
29#include <xrpl/protocol/STAmount.h>
30#include <xrpl/protocol/STObject.h>
31#include <xrpl/protocol/STTx.h>
32
33#include <functional>
34#include <future>
35#include <source_location>
36#include <string>
37#include <tuple>
38#include <type_traits>
39#include <unordered_map>
40#include <utility>
41#include <vector>
42
43namespace xrpl::test::jtx {
44
53template <class T>
55{
58
59 // Non-explicit constructor allows implicit conversion.
60 // The default argument for loc is evaluated at the call site.
65};
66
68template <class... Args>
69std::array<Account, 1 + sizeof...(Args)>
70noripple(Account const& account, Args const&... args)
71{
72 return {{account, args...}};
73}
74
75inline FeatureBitset
77{
78 static FeatureBitset const kIds = [] {
79 auto const& sa = allAmendments();
81 feats.reserve(sa.size());
82 for (auto const& [s, vote] : sa)
83 {
84 (void)vote;
85 if (auto const f = getRegisteredFeature(s))
86 {
87 feats.push_back(*f);
88 }
89 else
90 {
91 Throw<std::runtime_error>("Unknown feature: " + s + " in allAmendments.");
92 }
93 }
94 return FeatureBitset(feats);
95 }();
96 return kIds;
97}
98
108{
109 std::vector<FeatureBitset> result{seed};
110 for (auto const& f : features)
111 {
112 auto const n = result.size();
113 for (std::size_t i = 0; i < n; ++i)
114 result.push_back(result[i] - f);
115 }
116 return result;
117}
118
119//------------------------------------------------------------------------------
120
121class SuiteLogs : public Logs
122{
124
125public:
126 explicit SuiteLogs(beast::unit_test::Suite& suite) : Logs(beast::Severity::Error), suite_(suite)
127 {
128 }
129
130 ~SuiteLogs() override = default;
131
133 makeSink(std::string const& partition, beast::Severity threshold) override
134 {
136 }
137};
138
139//------------------------------------------------------------------------------
140
142class Env
143{
144public:
146
148
151 {
153 // RPC errors tend to return either a "code" and a "message" (sometimes
154 // with an "error" that corresponds to the "code"), or with an "error"
155 // and an "exception". However, this structure allows all possible
156 // combinations.
161 };
162
163private:
180
182
183public:
185
186 Env() = delete;
187 Env&
188 operator=(Env const&) = delete;
189 Env(Env const&) = delete;
190
205 // VFALCO Could wrap the suite::log in a Journal here
208 FeatureBitset features,
209 std::unique_ptr<Logs> logs = nullptr,
211 : test(suite)
212 , bundle_(suite, std::move(config), std::move(logs), thresh)
213 , journal{bundle_.app->getJournal("Env")}
214 {
217 foreachFeature(features, [&appFeats = app().config().features](uint256 const& f) {
218 appFeats.insert(f);
219 });
220 }
221
236 FeatureBitset features,
237 std::unique_ptr<Logs> logs = nullptr)
238 : Env(suite, envconfig(), features, std::move(logs))
239 {
240 }
241
256 std::unique_ptr<Logs> logs = nullptr,
258 : Env(suite, std::move(config), testableAmendments(), std::move(logs), thresh)
259 {
260 }
261
272 : Env(suite, envconfig(), nullptr, thresh)
273 {
274 }
275
276 virtual ~Env() = default;
277
279 // NOLINTNEXTLINE(readability-make-member-function-const)
281 {
282 return *bundle_.app;
283 }
284
285 [[nodiscard]] Application const&
286 app() const
287 {
288 return *bundle_.app;
289 }
290
292 // NOLINTNEXTLINE(readability-make-member-function-const)
294 {
295 return *bundle_.timeKeeper;
296 }
297
304 // NOLINTNEXTLINE(readability-make-member-function-const)
306 {
307 return timeKeeper().now();
308 }
309
312 // NOLINTNEXTLINE(readability-make-member-function-const)
314 {
315 return *bundle_.client;
316 }
317
323 template <class... Args>
325 rpc(unsigned apiVersion,
327 std::string const& cmd,
328 Args&&... args);
329
330 template <class... Args>
332 rpc(unsigned apiVersion, std::string const& cmd, Args&&... args);
333
334 template <class... Args>
337 std::string const& cmd,
338 Args&&... args);
339
340 template <class... Args>
342 rpc(std::string const& cmd, Args&&... args);
343
353 current() const
354 {
355 return app().getOpenLedger().current();
356 }
357
366 closed();
367
387 bool
388 close(
389 NetClock::time_point closeTime,
390 std::optional<std::chrono::milliseconds> consensusDelay = std::nullopt);
391
399 template <class Rep, class Period>
400 bool
402 {
403 // VFALCO Is this the correct time?
404 return close(now() + elapsed);
405 }
406
414 bool
416 {
417 // VFALCO Is this the correct time?
418 return close(std::chrono::seconds(5));
419 }
420
449 [[nodiscard]] bool
450 syncClose(std::chrono::steady_clock::duration timeout = std::chrono::seconds{1})
451 {
452 XRPL_ASSERT(
453 app().getNumberOfThreads() == 1,
454 "syncClose() is only useful on an application with a single thread");
455 auto const result = close();
456 auto serverBarrier = std::make_shared<std::promise<void>>();
457 auto future = serverBarrier->get_future();
458 boost::asio::post(app().getIOContext(), [serverBarrier]() { serverBarrier->set_value(); });
459 auto const status = future.wait_for(timeout);
460 return result && status == std::future_status::ready;
461 }
462
466 void
467 trace(int howMany = -1)
468 {
469 trace_ = howMany;
470 }
471
473 void
475 {
476 trace_ = 0;
477 }
478
479 void
481 {
483 }
484
486 void
488 {
489 app().checkSigs(false);
490 }
491
492 // set rpc retries
493 void
494 setRetries(unsigned r = 5)
495 {
496 retries_ = r;
497 }
498
499 // get rpc retries
500 [[nodiscard]] unsigned
501 retries() const
502 {
503 return retries_;
504 }
505
507 void
508 memoize(Account const& account);
509
512 [[nodiscard]] Account const&
513 lookup(AccountID const& id) const;
514
515 [[nodiscard]] Account const&
516 lookup(std::string const& base58ID) const;
518
522 [[nodiscard]] PrettyAmount
523 balance(Account const& account) const;
524
529 [[nodiscard]] std::uint32_t
530 seq(Account const& account) const;
531
535 // VFALCO NOTE This should return a unit-less amount
536 [[nodiscard]] PrettyAmount
537 balance(Account const& account, Asset const& asset) const;
538
542 [[nodiscard]] PrettyAmount
543 limit(Account const& account, Issue const& issue) const;
544
548 [[nodiscard]] std::uint32_t
549 ownerCount(Account const& account) const;
550
554 [[nodiscard]] SLE::const_pointer
555 le(Account const& account) const;
556
560 [[nodiscard]] SLE::const_pointer
561 le(Keylet const& k) const;
562
564 template <class JsonValue, class... FN>
565 JTx
566 jt(JsonValue&& jv, FN const&... fN)
567 {
569 invoke(jt, fN...);
570 autofill(jt);
571 jt.stx = st(jt);
572 return jt;
573 }
574
576 template <class JsonValue, class... FN>
577 JTx
578 jtnofill(JsonValue&& jv, FN const&... fN)
579 {
581 invoke(jt, fN...);
583 jt.stx = st(jt);
584 return jt;
585 }
586
590 template <class JsonValue, class... FN>
592 json(JsonValue&& jv, FN const&... fN)
593 {
594 auto tj = jt(std::forward<JsonValue>(jv), fN...);
595 return std::move(tj.jv);
596 }
597
603 template <class... Args>
604 void
605 require(Args const&... args)
606 {
607 jtx::required(args...)(*this);
608 }
609
612 static ParsedResult
613 parseResult(json::Value const& jr);
614
618 virtual void
620
624 void
626 JTx const& jt,
629
633 void
635 JTx const& jt,
636 ParsedResult const& parsed,
637 json::Value const& jr = json::Value(),
639
642 template <class... FN>
643 Env&
645 {
646 submit(jt(std::move(jv.value), fN...), jv.loc);
647 return *this;
648 }
649
650 template <class... FN>
651 Env&
652 apply(WithSourceLocation<JTx> jv, FN const&... fN)
653 {
654 submit(jt(std::move(jv.value), fN...), jv.loc);
655 return *this;
656 }
657
658 template <class... FN>
659 Env&
661 {
662 return apply(std::move(jv), fN...);
663 }
664
665 template <class... FN>
666 Env&
668 {
669 return apply(std::move(jv), fN...);
670 }
671
672
674 [[nodiscard]] TER
675 ter() const
676 {
677 return ter_;
678 }
679
692 meta();
693
705 [[nodiscard]] std::shared_ptr<STTx const>
706 tx() const;
707
708 void
709 enableFeature(uint256 const feature);
710
711 void
712 disableFeature(uint256 const feature);
713
714 [[nodiscard]] bool
715 enabled(uint256 feature) const
716 {
717 return current()->rules().enabled(feature);
718 }
719
720private:
721 void
722 fund(bool setDefaultRipple, STAmount const& amount, Account const& account);
723
724 void
725 fundArg(STAmount const& amount, Account const& account)
726 {
727 fund(true, amount, account);
728 }
729
730 template <std::size_t N>
731 void
732 fundArg(STAmount const& amount, std::array<Account, N> const& list)
733 {
734 for (auto const& account : list)
735 fund(false, amount, account);
736 }
737
738public:
765 template <class Arg, class... Args>
766 void
767 fund(STAmount const& amount, Arg const& arg, Args const&... args)
768 {
769 fundArg(amount, arg);
770 if constexpr (sizeof...(args) > 0)
771 fund(amount, args...);
772 }
773
792 void
793 trust(STAmount const& amount, Account const& account);
794
795 template <class... Accounts>
796 void
797 trust(STAmount const& amount, Account const& to0, Account const& to1, Accounts const&... toN)
798 {
799 trust(amount, to0);
800 trust(amount, to1, toN...); // NOLINT(readability-suspicious-call-argument)
801 }
802
803
809 ust(JTx const& jt);
810
811protected:
812 int trace_ = 0;
817 unsigned retries_ = 5;
818
820 doRpc(
821 unsigned apiVersion,
822 std::vector<std::string> const& args,
824
825 void
827
828 virtual void
829 autofill(JTx& jt);
830
839 st(JTx const& jt);
840
841 // Invoke funclets on stx
842 // Note: The STTx may not be modified
843 template <class... FN>
844 void
845 invoke(STTx& stx, FN const&... fN)
846 {
847 (fN(*this, stx), ...);
848 }
849
850 // Invoke funclets on jt
851 template <class... FN>
852 void
853 invoke(JTx& jt, FN const&... fN)
854 {
855 (fN(*this, jt), ...);
856 }
857
858 // Map of account IDs to Account
860};
861
862template <class... Args>
865 unsigned apiVersion,
867 std::string const& cmd,
868 Args&&... args)
869{
870 return doRpc(apiVersion, std::vector<std::string>{cmd, std::forward<Args>(args)...}, headers);
871}
872
873template <class... Args>
875Env::rpc(unsigned apiVersion, std::string const& cmd, Args&&... args)
876{
877 return rpc(
878 apiVersion,
880 cmd,
881 std::forward<Args>(args)...);
882}
883
884template <class... Args>
888 std::string const& cmd,
889 Args&&... args)
890{
891 return doRpc(
894 headers);
895}
896
897template <class... Args>
899Env::rpc(std::string const& cmd, Args&&... args)
900{
902}
903
904} // namespace xrpl::test::jtx
A generic endpoint for log messages.
Definition Journal.h:38
A testsuite class.
Definition suite.h:50
Represents a JSON value.
Definition json_value.h:130
virtual bool checkSigs() const =0
A currency issued by an account.
Definition Issue.h:13
beast::Severity threshold() const
Definition Log.cpp:143
Logs(beast::Severity level)
Definition Log.cpp:112
std::chrono::time_point< NetClock > time_point
Definition chrono.h:46
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
static void initPathTable()
std::shared_ptr< STLedgerEntry const > const_pointer
virtual OpenLedger & getOpenLedger()=0
time_point now() const override
Returns the current time.
Immutable cryptographic account descriptor.
Definition jtx/Account.h:17
static Account const kMaster
The master account.
Definition jtx/Account.h:26
A transaction testing environment.
Definition Env.h:143
Application & app()
Definition Env.h:280
bool close(std::chrono::duration< Rep, Period > const &elapsed)
Close and advance the ledger.
Definition Env.h:401
void notrace()
Turn off JSON tracing.
Definition Env.h:474
bool syncClose(std::chrono::steady_clock::duration timeout=std::chrono::seconds{1})
Close and advance the ledger, then synchronize with the server's io_context to ensure all async opera...
Definition Env.h:450
std::shared_ptr< STTx const > st(JTx const &jt)
Create a STTx from a JTx The framework requires that JSON is valid.
Definition Env.cpp:611
TER ter() const
Return the TER for the last JTx.
Definition Env.h:675
void invoke(JTx &jt, FN const &... fN)
Definition Env.h:853
void setRetries(unsigned r=5)
Definition Env.h:494
void disableSigs()
Turn off signature checks.
Definition Env.h:487
Env(Env const &)=delete
void fund(STAmount const &amount, Arg const &arg, Args const &... args)
Create a new account with some XRP.
Definition Env.h:767
Env(beast::unit_test::Suite &suite, FeatureBitset features, std::unique_ptr< Logs > logs=nullptr)
Create Env with default config and specified features.
Definition Env.h:235
Env(beast::unit_test::Suite &suite, beast::Severity thresh=beast::Severity::Error)
Create Env with only the current test suite.
Definition Env.h:271
Env(beast::unit_test::Suite &suite, std::unique_ptr< Config > config, std::unique_ptr< Logs > logs=nullptr, beast::Severity thresh=beast::Severity::Error)
Create Env using suite and Config pointer.
Definition Env.h:254
Env & operator()(WithSourceLocation< JTx > jv, FN const &... fN)
Definition Env.h:667
json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
Definition Env.h:592
SLE::const_pointer le(Account const &account) const
Return an account root.
Definition Env.cpp:284
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition Env.cpp:266
void fundArg(STAmount const &amount, std::array< Account, N > const &list)
Definition Env.h:732
AppBundle bundle_
Definition Env.h:181
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition Env.cpp:127
static ParsedResult parseResult(json::Value const &jr)
Gets the TER result and didApply flag from a RPC Json result object.
Definition Env.cpp:346
Account const & lookup(AccountID const &id) const
Returns the Account given the AccountID.
Definition Env.cpp:180
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:296
virtual void submit(JTx const &jt, std::source_location const &loc=std::source_location::current())
Submit an existing JTx.
Definition Env.cpp:387
Env(beast::unit_test::Suite &suite, std::unique_ptr< Config > config, FeatureBitset features, std::unique_ptr< Logs > logs=nullptr, beast::Severity thresh=beast::Severity::Error)
Create Env using suite, Config pointer, and explicit features.
Definition Env.h:206
void enableFeature(uint256 const feature)
Definition Env.cpp:682
Env & apply(WithSourceLocation< JTx > jv, FN const &... fN)
Definition Env.h:652
PrettyAmount limit(Account const &account, Issue const &issue) const
Returns the IOU limit on an account.
Definition Env.cpp:254
void disableFeature(uint256 const feature)
Definition Env.cpp:690
json::Value doRpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition Env.cpp:663
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition Env.cpp:275
virtual void autofill(JTx &jt)
Definition Env.cpp:582
void postconditions(JTx const &jt, ParsedResult const &parsed, json::Value const &jr=json::Value(), std::source_location const &loc=std::source_location::current())
Check expected postconditions of JTx submission.
Definition Env.cpp:453
bool close()
Close and advance the ledger.
Definition Env.h:415
Account const & master
Definition Env.h:147
json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition Env.h:864
void setParseFailureExpected(bool b)
Definition Env.h:480
Application const & app() const
Definition Env.h:286
void autofillSig(JTx &jt)
Definition Env.cpp:539
void signAndSubmit(JTx const &jt, json::Value params=json::ValueType::Null, std::source_location const &loc=std::source_location::current())
Use the submit RPC command with a provided JTx object.
Definition Env.cpp:415
Env & operator()(WithSourceLocation< json::Value > jv, FN const &... fN)
Definition Env.h:660
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition Env.h:566
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
Definition Env.cpp:201
virtual ~Env()=default
unsigned retries_
Definition Env.h:817
beast::unit_test::Suite & test
Definition Env.h:145
void trust(STAmount const &amount, Account const &to0, Account const &to1, Accounts const &... toN)
Definition Env.h:797
uint256 txid_
Definition Env.h:814
unsigned retries() const
Definition Env.h:501
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition Env.cpp:327
std::shared_ptr< STTx const > ust(JTx const &jt)
Create a STTx from a JTx without sanitizing Use to inject bogus values into test transactions by firs...
Definition Env.cpp:637
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition Env.cpp:511
Env & apply(WithSourceLocation< json::Value > jv, FN const &... fN)
Apply funclets and submit.
Definition Env.h:644
JTx jtnofill(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition Env.h:578
void invoke(STTx &stx, FN const &... fN)
Definition Env.h:845
std::unordered_map< AccountID, Account > map_
Definition Env.h:859
void fundArg(STAmount const &amount, Account const &account)
Definition Env.h:725
TestStopwatch stopwatch_
Definition Env.h:813
ManualTimeKeeper & timeKeeper()
Definition Env.h:293
bool parseFailureExpected_
Definition Env.h:816
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition Env.cpp:533
bool enabled(uint256 feature) const
Definition Env.h:715
Env & operator=(Env const &)=delete
void memoize(Account const &account)
Associate AccountID with account.
Definition Env.cpp:174
beast::Journal const journal
Definition Env.h:184
AbstractClient & client()
Returns the connected client.
Definition Env.h:313
void require(Args const &... args)
Check a set of requirements.
Definition Env.h:605
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:353
NetClock::time_point now()
Returns the current network time.
Definition Env.h:305
void trace(int howMany=-1)
Turn on JSON tracing.
Definition Env.h:467
~SuiteLogs() override=default
beast::unit_test::Suite & suite_
Definition Env.h:123
SuiteLogs(beast::unit_test::Suite &suite)
Definition Env.h:126
std::unique_ptr< beast::Journal::Sink > makeSink(std::string const &partition, beast::Severity threshold) override
Definition Env.h:133
T current(T... args)
T forward(T... args)
T make_shared(T... args)
T make_unique(T... args)
Severity
Severity level / threshold of a Journal message.
Definition Journal.h:11
@ Null
'null' value
Definition json_value.h:19
STL namespace.
static constexpr auto kApiCommandLineVersion
Definition ApiVersion.h:44
std::vector< FeatureBitset > amendmentCombinations(std::initializer_list< uint256 > features, FeatureBitset seed)
Returns all 2^N permutations of a seed FeatureBitset with each subset of the given features excluded.
Definition Env.h:107
require_t required(Args const &... args)
Compose many condition functors into one.
Definition require.h:28
FeatureBitset testableAmendments()
Definition Env.h:76
std::array< Account, 1+sizeof...(Args)> noripple(Account const &account, Args const &... args)
Designate accounts as no-ripple in Env::fund.
Definition Env.h:70
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition envconfig.h:28
void foreachFeature(FeatureBitset bs, F &&f)
Definition Feature.h:375
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
std::map< std::string, AmendmentSupport > const & allAmendments()
All amendments libxrpl knows about.
TERSubset< CanCvtToTER > TER
Definition TER.h:634
beast::ManualClock< std::chrono::steady_clock > TestStopwatch
A manual Stopwatch for unit tests.
Definition chrono.h:90
std::optional< uint256 > getRegisteredFeature(std::string const &name)
BaseUInt< 256 > uint256
Definition base_uint.h:562
@ tesSUCCESS
Definition TER.h:240
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:49
T push_back(T... args)
T reserve(T... args)
T size(T... args)
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:19
ManualTimeKeeper * timeKeeper
Definition Env.h:168
std::unique_ptr< AbstractClient > client
Definition Env.h:170
std::unique_ptr< Application > owned
Definition Env.h:167
Used by parseResult() and postConditions().
Definition Env.h:151
std::optional< TER > ter
Definition Env.h:152
std::optional< ErrorCodeI > rpcCode
Definition Env.h:157
Execution context for applying a JSON transaction.
Definition JTx.h:23
Represents an XRP, IOU, or MPT quantity This customizes the string conversion and supports XRP conver...
Wrapper that captures std::source_location when implicitly constructed.
Definition Env.h:55
WithSourceLocation(T v, std::source_location l=std::source_location::current())
Definition Env.h:61
std::source_location loc
Definition Env.h:57