rippled
Loading...
Searching...
No Matches
Env.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_TEST_JTX_ENV_H_INCLUDED
21#define RIPPLE_TEST_JTX_ENV_H_INCLUDED
22
23#include <test/jtx/AbstractClient.h>
24#include <test/jtx/Account.h>
25#include <test/jtx/JTx.h>
26#include <test/jtx/ManualTimeKeeper.h>
27#include <test/jtx/amount.h>
28#include <test/jtx/envconfig.h>
29#include <test/jtx/require.h>
30#include <test/jtx/tags.h>
31#include <test/jtx/vault.h>
32#include <test/unit_test/SuiteJournal.h>
33
34#include <xrpld/app/ledger/Ledger.h>
35#include <xrpld/app/ledger/OpenLedger.h>
36#include <xrpld/app/main/Application.h>
37#include <xrpld/app/paths/Pathfinder.h>
38#include <xrpld/core/Config.h>
39#include <xrpld/rpc/detail/RPCHelpers.h>
40
41#include <xrpl/basics/Log.h>
42#include <xrpl/basics/chrono.h>
43#include <xrpl/beast/utility/Journal.h>
44#include <xrpl/json/json_value.h>
45#include <xrpl/json/to_string.h>
46#include <xrpl/protocol/Feature.h>
47#include <xrpl/protocol/Indexes.h>
48#include <xrpl/protocol/Issue.h>
49#include <xrpl/protocol/STAmount.h>
50#include <xrpl/protocol/STObject.h>
51#include <xrpl/protocol/STTx.h>
52
53#include <functional>
54#include <string>
55#include <tuple>
56#include <type_traits>
57#include <unordered_map>
58#include <utility>
59#include <vector>
60
61namespace ripple {
62namespace test {
63namespace jtx {
64
66template <class... Args>
67std::array<Account, 1 + sizeof...(Args)>
68noripple(Account const& account, Args const&... args)
69{
70 return {{account, args...}};
71}
72
73inline FeatureBitset
75{
76 static FeatureBitset const ids = [] {
77 auto const& sa = allAmendments();
79 feats.reserve(sa.size());
80 for (auto const& [s, vote] : sa)
81 {
82 (void)vote;
83 if (auto const f = getRegisteredFeature(s))
84 feats.push_back(*f);
85 else
86 Throw<std::runtime_error>(
87 "Unknown feature: " + s + " in allAmendments.");
88 }
89 return FeatureBitset(feats);
90 }();
91 return ids;
92}
93
94//------------------------------------------------------------------------------
95
96class SuiteLogs : public Logs
97{
99
100public:
102 : Logs(beast::severities::kError), suite_(suite)
103 {
104 }
105
106 ~SuiteLogs() override = default;
107
110 std::string const& partition,
112 {
113 return std::make_unique<SuiteJournalSink>(partition, threshold, suite_);
114 }
115};
116
117//------------------------------------------------------------------------------
118
120class Env
121{
122public:
124
126
129 {
131 // RPC errors tend to return either a "code" and a "message" (sometimes
132 // with an "error" that corresponds to the "code"), or with an "error"
133 // and an "exception". However, this structure allows all possible
134 // combinations.
139 };
140
141private:
143 {
144 Application* app = nullptr;
149
150 AppBundle() = default;
151 AppBundle(
156 ~AppBundle();
157 };
158
160
161public:
163
164 Env() = delete;
165 Env&
166 operator=(Env const&) = delete;
167 Env(Env const&) = delete;
168
183 // VFALCO Could wrap the suite::log in a Journal here
186 FeatureBitset features,
187 std::unique_ptr<Logs> logs = nullptr,
189 : test(suite_)
190 , bundle_(suite_, std::move(config), std::move(logs), thresh)
191 , journal{bundle_.app->journal("Env")}
192 {
196 features, [&appFeats = app().config().features](uint256 const& f) {
197 appFeats.insert(f);
198 });
199 }
200
215 FeatureBitset features,
216 std::unique_ptr<Logs> logs = nullptr)
217 : Env(suite_, envconfig(), features, std::move(logs))
218 {
219 }
220
235 std::unique_ptr<Logs> logs = nullptr,
237 : Env(suite_,
238 std::move(config),
240 std::move(logs),
241 thresh)
242 {
243 }
244
255 {
256 }
257
258 virtual ~Env() = default;
259
262 {
263 return *bundle_.app;
264 }
265
266 Application const&
267 app() const
268 {
269 return *bundle_.app;
270 }
271
274 {
275 return *bundle_.timeKeeper;
276 }
277
285 {
286 return timeKeeper().now();
287 }
288
292 {
293 return *bundle_.client;
294 }
295
301 template <class... Args>
303 rpc(unsigned apiVersion,
305 std::string const& cmd,
306 Args&&... args);
307
308 template <class... Args>
310 rpc(unsigned apiVersion, std::string const& cmd, Args&&... args);
311
312 template <class... Args>
315 std::string const& cmd,
316 Args&&... args);
317
318 template <class... Args>
320 rpc(std::string const& cmd, Args&&... args);
321
331 current() const
332 {
333 return app().openLedger().current();
334 }
335
344 closed();
345
365 bool
366 close(
367 NetClock::time_point closeTime,
368 std::optional<std::chrono::milliseconds> consensusDelay = std::nullopt);
369
377 template <class Rep, class Period>
378 bool
380 {
381 // VFALCO Is this the correct time?
382 return close(now() + elapsed);
383 }
384
392 bool
394 {
395 // VFALCO Is this the correct time?
396 return close(std::chrono::seconds(5));
397 }
398
402 void
403 trace(int howMany = -1)
404 {
405 trace_ = howMany;
406 }
407
409 void
411 {
412 trace_ = 0;
413 }
414
415 void
417 {
419 }
420
422 void
424 {
425 app().checkSigs(false);
426 }
427
428 // set rpc retries
429 void
430 set_retries(unsigned r = 5)
431 {
432 retries_ = r;
433 }
434
435 // get rpc retries
436 unsigned
437 retries() const
438 {
439 return retries_;
440 }
441
443 void
444 memoize(Account const& account);
445
448 Account const&
449 lookup(AccountID const& id) const;
450
451 Account const&
452 lookup(std::string const& base58ID) const;
459 balance(Account const& account) const;
460
466 seq(Account const& account) const;
467
471 // VFALCO NOTE This should return a unit-less amount
473 balance(Account const& account, Issue const& issue) const;
474
476 balance(Account const& account, MPTIssue const& mptIssue) const;
477
482 limit(Account const& account, Issue const& issue) const;
483
488 ownerCount(Account const& account) const;
489
494 le(Account const& account) const;
495
500 le(Keylet const& k) const;
501
503 template <class JsonValue, class... FN>
504 JTx
505 jt(JsonValue&& jv, FN const&... fN)
506 {
507 JTx jt(std::forward<JsonValue>(jv));
508 invoke(jt, fN...);
509 autofill(jt);
510 jt.stx = st(jt);
511 return jt;
512 }
513
515 template <class JsonValue, class... FN>
516 JTx
517 jtnofill(JsonValue&& jv, FN const&... fN)
518 {
519 JTx jt(std::forward<JsonValue>(jv));
520 invoke(jt, fN...);
522 jt.stx = st(jt);
523 return jt;
524 }
525
529 template <class JsonValue, class... FN>
531 json(JsonValue&& jv, FN const&... fN)
532 {
533 auto tj = jt(std::forward<JsonValue>(jv), fN...);
534 return std::move(tj.jv);
535 }
536
542 template <class... Args>
543 void
544 require(Args const&... args)
545 {
546 jtx::required(args...)(*this);
547 }
548
551 static ParsedResult
552 parseResult(Json::Value const& jr);
553
557 virtual void
558 submit(JTx const& jt);
559
563 void
565
569 void
571 JTx const& jt,
572 ParsedResult const& parsed,
573 Json::Value const& jr = Json::Value());
574
577 template <class JsonValue, class... FN>
578 Env&
579 apply(JsonValue&& jv, FN const&... fN)
580 {
581 submit(jt(std::forward<JsonValue>(jv), fN...));
582 return *this;
583 }
584
585 template <class JsonValue, class... FN>
586 Env&
587 operator()(JsonValue&& jv, FN const&... fN)
588 {
589 return apply(std::forward<JsonValue>(jv), fN...);
590 }
594 TER
595 ter() const
596 {
597 return ter_;
598 }
599
612 meta();
613
626 tx() const;
627
628 void
629 enableFeature(uint256 const feature);
630
631 void
632 disableFeature(uint256 const feature);
633
634 bool
635 enabled(uint256 feature) const
636 {
637 return current()->rules().enabled(feature);
638 }
639
640private:
641 void
642 fund(bool setDefaultRipple, STAmount const& amount, Account const& account);
643
644 void
645 fund_arg(STAmount const& amount, Account const& account)
646 {
647 fund(true, amount, account);
648 }
649
650 template <std::size_t N>
651 void
652 fund_arg(STAmount const& amount, std::array<Account, N> const& list)
653 {
654 for (auto const& account : list)
655 fund(false, amount, account);
656 }
657
658public:
685 template <class Arg, class... Args>
686 void
687 fund(STAmount const& amount, Arg const& arg, Args const&... args)
688 {
689 fund_arg(amount, arg);
690 if constexpr (sizeof...(args) > 0)
691 fund(amount, args...);
692 }
693
712 void
713 trust(STAmount const& amount, Account const& account);
714
715 template <class... Accounts>
716 void
718 STAmount const& amount,
719 Account const& to0,
720 Account const& to1,
721 Accounts const&... toN)
722 {
723 trust(amount, to0);
724 trust(amount, to1, toN...);
725 }
733 ust(JTx const& jt);
734
735protected:
736 int trace_ = 0;
741 unsigned retries_ = 5;
742
744 do_rpc(
745 unsigned apiVersion,
746 std::vector<std::string> const& args,
748
749 void
751
752 virtual void
753 autofill(JTx& jt);
754
763 st(JTx const& jt);
764
765 // Invoke funclets on stx
766 // Note: The STTx may not be modified
767 template <class... FN>
768 void
769 invoke(STTx& stx, FN const&... fN)
770 {
771 (fN(*this, stx), ...);
772 }
773
774 // Invoke funclets on jt
775 template <class... FN>
776 void
777 invoke(JTx& jt, FN const&... fN)
778 {
779 (fN(*this, jt), ...);
780 }
781
782 // Map of account IDs to Account
784};
785
786template <class... Args>
789 unsigned apiVersion,
791 std::string const& cmd,
792 Args&&... args)
793{
794 return do_rpc(
795 apiVersion,
796 std::vector<std::string>{cmd, std::forward<Args>(args)...},
797 headers);
798}
799
800template <class... Args>
802Env::rpc(unsigned apiVersion, std::string const& cmd, Args&&... args)
803{
804 return rpc(
805 apiVersion,
807 cmd,
808 std::forward<Args>(args)...);
809}
810
811template <class... Args>
815 std::string const& cmd,
816 Args&&... args)
817{
818 return do_rpc(
820 std::vector<std::string>{cmd, std::forward<Args>(args)...},
821 headers);
822}
823
824template <class... Args>
826Env::rpc(std::string const& cmd, Args&&... args)
827{
828 return rpc(
830 cmd,
831 std::forward<Args>(args)...);
832}
833
834} // namespace jtx
835} // namespace test
836} // namespace ripple
837
838#endif
Represents a JSON value.
Definition: json_value.h:149
A generic endpoint for log messages.
Definition: Journal.h:60
A testsuite class.
Definition: suite.h:55
virtual OpenLedger & openLedger()=0
virtual bool checkSigs() const =0
A currency issued by an account.
Definition: Issue.h:33
Manages partitions for logging.
Definition: Log.h:51
beast::severities::Severity threshold() const
Definition: Log.cpp:166
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
Definition: OpenLedger.cpp:51
static void initPathTable()
time_point now() const override
Returns the current time.
Immutable cryptographic account descriptor.
Definition: Account.h:39
static Account const master
The master account.
Definition: Account.h:48
A transaction testing environment.
Definition: Env.h:121
void fund_arg(STAmount const &amount, std::array< Account, N > const &list)
Definition: Env.h:652
Json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
Definition: Env.h:531
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition: Env.cpp:111
void trace(int howMany=-1)
Turn on JSON tracing.
Definition: Env.h:403
void disableFeature(uint256 const feature)
Definition: Env.cpp:645
bool parseFailureExpected_
Definition: Env.h:740
static ParsedResult parseResult(Json::Value const &jr)
Gets the TER result and didApply flag from a RPC Json result object.
Definition: Env.cpp:323
Env(beast::unit_test::suite &suite_, std::unique_ptr< Config > config, std::unique_ptr< Logs > logs=nullptr, beast::severities::Severity thresh=beast::severities::kError)
Create Env using suite and Config pointer.
Definition: Env.h:233
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition: Env.cpp:245
std::unordered_map< AccountID, Account > map_
Definition: Env.h:783
void notrace()
Turn off JSON tracing.
Definition: Env.h:410
void require(Args const &... args)
Check a set of requirements.
Definition: Env.h:544
void trust(STAmount const &amount, Account const &to0, Account const &to1, Accounts const &... toN)
Definition: Env.h:717
unsigned retries() const
Definition: Env.h:437
TER ter() const
Return the TER for the last JTx.
Definition: Env.h:595
beast::unit_test::suite & test
Definition: Env.h:123
virtual ~Env()=default
bool close(std::chrono::duration< Rep, Period > const &elapsed)
Close and advance the ledger.
Definition: Env.h:379
PrettyAmount limit(Account const &account, Issue const &issue) const
Returns the IOU limit on an account.
Definition: Env.cpp:233
AppBundle bundle_
Definition: Env.h:159
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition: Env.cpp:502
void invoke(JTx &jt, FN const &... fN)
Definition: Env.h:777
Env & operator=(Env const &)=delete
Env & operator()(JsonValue &&jv, FN const &... fN)
Definition: Env.h:587
Env(Env const &)=delete
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:331
void postconditions(JTx const &jt, ParsedResult const &parsed, Json::Value const &jr=Json::Value())
Check expected postconditions of JTx submission.
Definition: Env.cpp:429
bool enabled(uint256 feature) const
Definition: Env.h:635
void sign_and_submit(JTx const &jt, Json::Value params=Json::nullValue)
Use the submit RPC command with a provided JTx object.
Definition: Env.cpp:391
AbstractClient & client()
Returns the connected client.
Definition: Env.h:291
void autofill_sig(JTx &jt)
Definition: Env.cpp:508
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:306
void fund(STAmount const &amount, Arg const &arg, Args const &... args)
Create a new account with some XRP.
Definition: Env.h:687
Json::Value do_rpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition: Env.cpp:614
void invoke(STTx &stx, FN const &... fN)
Definition: Env.h:769
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:562
void enableFeature(uint256 const feature)
Definition: Env.cpp:637
Env(beast::unit_test::suite &suite_)
Create Env with only the current test suite.
Definition: Env.h:254
Account const & master
Definition: Env.h:125
Account const & lookup(AccountID const &id) const
Returns the Account given the AccountID.
Definition: Env.cpp:158
unsigned retries_
Definition: Env.h:741
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:505
NetClock::time_point now()
Returns the current network time.
Definition: Env.h:284
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:588
Application & app()
Definition: Env.h:261
beast::Journal const journal
Definition: Env.h:162
ManualTimeKeeper & timeKeeper()
Definition: Env.h:273
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:788
virtual void submit(JTx const &jt)
Submit an existing JTx.
Definition: Env.cpp:361
Env & apply(JsonValue &&jv, FN const &... fN)
Apply funclets and submit.
Definition: Env.h:579
void disable_sigs()
Turn off signature checks.
Definition: Env.h:423
void set_retries(unsigned r=5)
Definition: Env.h:430
bool close()
Close and advance the ledger.
Definition: Env.h:393
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:275
TestStopwatch stopwatch_
Definition: Env.h:737
Application const & app() const
Definition: Env.h:267
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition: Env.cpp:489
JTx jtnofill(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:517
void set_parse_failure_expected(bool b)
Definition: Env.h:416
void memoize(Account const &account)
Associate AccountID with account.
Definition: Env.cpp:152
Env(beast::unit_test::suite &suite_, std::unique_ptr< Config > config, FeatureBitset features, std::unique_ptr< Logs > logs=nullptr, beast::severities::Severity thresh=beast::severities::kError)
Create Env using suite, Config pointer, and explicit features.
Definition: Env.h:184
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition: Env.cpp:263
void fund_arg(STAmount const &amount, Account const &account)
Definition: Env.h:645
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:214
SuiteLogs(beast::unit_test::suite &suite)
Definition: Env.h:101
beast::unit_test::suite & suite_
Definition: Env.h:98
std::unique_ptr< beast::Journal::Sink > makeSink(std::string const &partition, beast::severities::Severity threshold) override
Definition: Env.h:109
~SuiteLogs() override=default
A balance matches.
Definition: balance.h:39
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition: rpc.h:35
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition: ter.h:35
@ nullValue
'null' value
Definition: json_value.h:38
Severity
Severity level / threshold of a Journal message.
Definition: Journal.h:32
static constexpr auto apiCommandLineVersion
Definition: ApiVersion.h:59
static autofill_t const autofill
Definition: tags.h:42
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
require_t required(Args const &... args)
Compose many condition functors into one.
Definition: require.h:48
FeatureBitset testable_amendments()
Definition: Env.h:74
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:25
std::map< std::string, AmendmentSupport > const & allAmendments()
All amendments libxrpl knows about.
Definition: Feature.cpp:351
std::optional< uint256 > getRegisteredFeature(std::string const &name)
Definition: Feature.cpp:382
@ tesSUCCESS
Definition: TER.h:244
void foreachFeature(FeatureBitset bs, F &&f)
Definition: Feature.h:355
STL namespace.
T push_back(T... args)
T reserve(T... args)
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:39
std::unique_ptr< Application > owned
Definition: Env.h:145
ManualTimeKeeper * timeKeeper
Definition: Env.h:146
std::unique_ptr< AbstractClient > client
Definition: Env.h:148
Used by parseResult() and postConditions()
Definition: Env.h:129
std::optional< error_code_i > rpcCode
Definition: Env.h:135
Execution context for applying a JSON transaction.
Definition: JTx.h:45
std::shared_ptr< STTx const > stx
Definition: JTx.h:56
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
Set the sequence number on a JTx.
Definition: seq.h:34