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 = ripple::detail::supportedAmendments();
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 supportedAmendments.");
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
479 ownerCount(Account const& account) const;
480
485 le(Account const& account) const;
486
491 le(Keylet const& k) const;
492
494 template <class JsonValue, class... FN>
495 JTx
496 jt(JsonValue&& jv, FN const&... fN)
497 {
498 JTx jt(std::forward<JsonValue>(jv));
499 invoke(jt, fN...);
500 autofill(jt);
501 jt.stx = st(jt);
502 return jt;
503 }
504
506 template <class JsonValue, class... FN>
507 JTx
508 jtnofill(JsonValue&& jv, FN const&... fN)
509 {
510 JTx jt(std::forward<JsonValue>(jv));
511 invoke(jt, fN...);
513 jt.stx = st(jt);
514 return jt;
515 }
516
520 template <class JsonValue, class... FN>
522 json(JsonValue&& jv, FN const&... fN)
523 {
524 auto tj = jt(std::forward<JsonValue>(jv), fN...);
525 return std::move(tj.jv);
526 }
527
533 template <class... Args>
534 void
535 require(Args const&... args)
536 {
537 jtx::required(args...)(*this);
538 }
539
542 static ParsedResult
543 parseResult(Json::Value const& jr);
544
548 virtual void
549 submit(JTx const& jt);
550
554 void
556
560 void
562 JTx const& jt,
563 ParsedResult const& parsed,
564 Json::Value const& jr = Json::Value());
565
568 template <class JsonValue, class... FN>
569 Env&
570 apply(JsonValue&& jv, FN const&... fN)
571 {
572 submit(jt(std::forward<JsonValue>(jv), fN...));
573 return *this;
574 }
575
576 template <class JsonValue, class... FN>
577 Env&
578 operator()(JsonValue&& jv, FN const&... fN)
579 {
580 return apply(std::forward<JsonValue>(jv), fN...);
581 }
585 TER
586 ter() const
587 {
588 return ter_;
589 }
590
603 meta();
604
617 tx() const;
618
619 void
620 enableFeature(uint256 const feature);
621
622 void
623 disableFeature(uint256 const feature);
624
625 bool
626 enabled(uint256 feature) const
627 {
628 return current()->rules().enabled(feature);
629 }
630
631private:
632 void
633 fund(bool setDefaultRipple, STAmount const& amount, Account const& account);
634
635 void
636 fund_arg(STAmount const& amount, Account const& account)
637 {
638 fund(true, amount, account);
639 }
640
641 template <std::size_t N>
642 void
643 fund_arg(STAmount const& amount, std::array<Account, N> const& list)
644 {
645 for (auto const& account : list)
646 fund(false, amount, account);
647 }
648
649public:
676 template <class Arg, class... Args>
677 void
678 fund(STAmount const& amount, Arg const& arg, Args const&... args)
679 {
680 fund_arg(amount, arg);
681 if constexpr (sizeof...(args) > 0)
682 fund(amount, args...);
683 }
684
703 void
704 trust(STAmount const& amount, Account const& account);
705
706 template <class... Accounts>
707 void
709 STAmount const& amount,
710 Account const& to0,
711 Account const& to1,
712 Accounts const&... toN)
713 {
714 trust(amount, to0);
715 trust(amount, to1, toN...);
716 }
724 ust(JTx const& jt);
725
726protected:
727 int trace_ = 0;
732 unsigned retries_ = 5;
733
735 do_rpc(
736 unsigned apiVersion,
737 std::vector<std::string> const& args,
739
740 void
742
743 virtual void
744 autofill(JTx& jt);
745
754 st(JTx const& jt);
755
756 // Invoke funclets on stx
757 // Note: The STTx may not be modified
758 template <class... FN>
759 void
760 invoke(STTx& stx, FN const&... fN)
761 {
762 (fN(*this, stx), ...);
763 }
764
765 // Invoke funclets on jt
766 template <class... FN>
767 void
768 invoke(JTx& jt, FN const&... fN)
769 {
770 (fN(*this, jt), ...);
771 }
772
773 // Map of account IDs to Account
775};
776
777template <class... Args>
780 unsigned apiVersion,
782 std::string const& cmd,
783 Args&&... args)
784{
785 return do_rpc(
786 apiVersion,
787 std::vector<std::string>{cmd, std::forward<Args>(args)...},
788 headers);
789}
790
791template <class... Args>
793Env::rpc(unsigned apiVersion, std::string const& cmd, Args&&... args)
794{
795 return rpc(
796 apiVersion,
798 cmd,
799 std::forward<Args>(args)...);
800}
801
802template <class... Args>
806 std::string const& cmd,
807 Args&&... args)
808{
809 return do_rpc(
811 std::vector<std::string>{cmd, std::forward<Args>(args)...},
812 headers);
813}
814
815template <class... Args>
817Env::rpc(std::string const& cmd, Args&&... args)
818{
819 return rpc(
821 cmd,
822 std::forward<Args>(args)...);
823}
824
825} // namespace jtx
826} // namespace test
827} // namespace ripple
828
829#endif
Represents a JSON value.
Definition: json_value.h:150
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:36
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:643
Json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
Definition: Env.h:522
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:603
bool parseFailureExpected_
Definition: Env.h:731
static ParsedResult parseResult(Json::Value const &jr)
Gets the TER result and didApply flag from a RPC Json result object.
Definition: Env.cpp:281
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:203
std::unordered_map< AccountID, Account > map_
Definition: Env.h:774
void notrace()
Turn off JSON tracing.
Definition: Env.h:410
void require(Args const &... args)
Check a set of requirements.
Definition: Env.h:535
void trust(STAmount const &amount, Account const &to0, Account const &to1, Accounts const &... toN)
Definition: Env.h:708
unsigned retries() const
Definition: Env.h:437
TER ter() const
Return the TER for the last JTx.
Definition: Env.h:586
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
AppBundle bundle_
Definition: Env.h:159
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition: Env.cpp:460
void invoke(JTx &jt, FN const &... fN)
Definition: Env.h:768
Env & operator=(Env const &)=delete
Env & operator()(JsonValue &&jv, FN const &... fN)
Definition: Env.h:578
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:387
bool enabled(uint256 feature) const
Definition: Env.h:626
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:349
AbstractClient & client()
Returns the connected client.
Definition: Env.h:291
void autofill_sig(JTx &jt)
Definition: Env.cpp:466
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:264
void fund(STAmount const &amount, Arg const &arg, Args const &... args)
Create a new account with some XRP.
Definition: Env.h:678
Json::Value do_rpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition: Env.cpp:572
void invoke(STTx &stx, FN const &... fN)
Definition: Env.h:760
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:520
void enableFeature(uint256 const feature)
Definition: Env.cpp:595
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:732
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:496
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:546
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:779
virtual void submit(JTx const &jt)
Submit an existing JTx.
Definition: Env.cpp:319
Env & apply(JsonValue &&jv, FN const &... fN)
Apply funclets and submit.
Definition: Env.h:570
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:233
TestStopwatch stopwatch_
Definition: Env.h:728
Application const & app() const
Definition: Env.h:267
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition: Env.cpp:447
JTx jtnofill(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:508
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:221
void fund_arg(STAmount const &amount, Account const &account)
Definition: Env.h:636
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:39
Severity
Severity level / threshold of a Journal message.
Definition: Journal.h:32
static constexpr auto apiCommandLineVersion
Definition: ApiVersion.h:60
std::map< std::string, VoteBehavior > const & supportedAmendments()
Amendments that this server supports and the default voting behavior.
Definition: Feature.cpp:360
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 supported_amendments()
Definition: Env.h:74
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
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:339
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