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/unit_test/SuiteJournal.h>
32
33#include <xrpld/app/ledger/Ledger.h>
34#include <xrpld/app/ledger/OpenLedger.h>
35#include <xrpld/app/main/Application.h>
36#include <xrpld/app/paths/Pathfinder.h>
37#include <xrpld/core/Config.h>
38#include <xrpld/rpc/detail/RPCHelpers.h>
39
40#include <xrpl/basics/Log.h>
41#include <xrpl/basics/chrono.h>
42#include <xrpl/beast/utility/Journal.h>
43#include <xrpl/json/json_value.h>
44#include <xrpl/json/to_string.h>
45#include <xrpl/protocol/Feature.h>
46#include <xrpl/protocol/Indexes.h>
47#include <xrpl/protocol/Issue.h>
48#include <xrpl/protocol/STAmount.h>
49#include <xrpl/protocol/STObject.h>
50#include <xrpl/protocol/STTx.h>
51
52#include <functional>
53#include <string>
54#include <tuple>
55#include <type_traits>
56#include <unordered_map>
57#include <utility>
58#include <vector>
59
60namespace ripple {
61namespace test {
62namespace jtx {
63
65template <class... Args>
66std::array<Account, 1 + sizeof...(Args)>
67noripple(Account const& account, Args const&... args)
68{
69 return {{account, args...}};
70}
71
72inline FeatureBitset
74{
75 static const FeatureBitset ids = [] {
76 auto const& sa = ripple::detail::supportedAmendments();
78 feats.reserve(sa.size());
79 for (auto const& [s, vote] : sa)
80 {
81 (void)vote;
82 if (auto const f = getRegisteredFeature(s))
83 feats.push_back(*f);
84 else
85 Throw<std::runtime_error>(
86 "Unknown feature: " + s + " in supportedAmendments.");
87 }
88 return FeatureBitset(feats);
89 }();
90 return ids;
91}
92
93//------------------------------------------------------------------------------
94
95class SuiteLogs : public Logs
96{
98
99public:
101 : Logs(beast::severities::kError), suite_(suite)
102 {
103 }
104
105 ~SuiteLogs() override = default;
106
109 std::string const& partition,
111 {
112 return std::make_unique<SuiteJournalSink>(partition, threshold, suite_);
113 }
114};
115
116//------------------------------------------------------------------------------
117
119class Env
120{
121public:
123
125
128 {
130 // RPC errors tend to return either a "code" and a "message" (sometimes
131 // with an "error" that corresponds to the "code"), or with an "error"
132 // and an "exception". However, this structure allows all possible
133 // combinations.
138 };
139
140private:
142 {
143 Application* app = nullptr;
148
149 AppBundle() = default;
150 AppBundle(
155 ~AppBundle();
156 };
157
159
160public:
162
163 Env() = delete;
164 Env&
165 operator=(Env const&) = delete;
166 Env(Env const&) = delete;
167
182 // VFALCO Could wrap the suite::log in a Journal here
185 FeatureBitset features,
186 std::unique_ptr<Logs> logs = nullptr,
188 : test(suite_)
189 , bundle_(suite_, std::move(config), std::move(logs), thresh)
190 , journal{bundle_.app->journal("Env")}
191 {
195 features, [&appFeats = app().config().features](uint256 const& f) {
196 appFeats.insert(f);
197 });
198 }
199
214 FeatureBitset features,
215 std::unique_ptr<Logs> logs = nullptr)
216 : Env(suite_, envconfig(), features, std::move(logs))
217 {
218 }
219
234 std::unique_ptr<Logs> logs = nullptr,
236 : Env(suite_,
237 std::move(config),
239 std::move(logs),
240 thresh)
241 {
242 }
243
254 {
255 }
256
257 virtual ~Env() = default;
258
261 {
262 return *bundle_.app;
263 }
264
265 Application const&
266 app() const
267 {
268 return *bundle_.app;
269 }
270
273 {
274 return *bundle_.timeKeeper;
275 }
276
284 {
285 return timeKeeper().now();
286 }
287
291 {
292 return *bundle_.client;
293 }
294
300 template <class... Args>
302 rpc(unsigned apiVersion,
304 std::string const& cmd,
305 Args&&... args);
306
307 template <class... Args>
309 rpc(unsigned apiVersion, std::string const& cmd, Args&&... args);
310
311 template <class... Args>
314 std::string const& cmd,
315 Args&&... args);
316
317 template <class... Args>
319 rpc(std::string const& cmd, Args&&... args);
320
330 current() const
331 {
332 return app().openLedger().current();
333 }
334
343 closed();
344
364 bool
365 close(
366 NetClock::time_point closeTime,
367 std::optional<std::chrono::milliseconds> consensusDelay = std::nullopt);
368
376 template <class Rep, class Period>
377 bool
379 {
380 // VFALCO Is this the correct time?
381 return close(now() + elapsed);
382 }
383
391 bool
393 {
394 // VFALCO Is this the correct time?
395 return close(std::chrono::seconds(5));
396 }
397
401 void
402 trace(int howMany = -1)
403 {
404 trace_ = howMany;
405 }
406
408 void
410 {
411 trace_ = 0;
412 }
413
414 void
416 {
418 }
419
421 void
423 {
424 app().checkSigs(false);
425 }
426
427 // set rpc retries
428 void
429 set_retries(unsigned r = 5)
430 {
431 retries_ = r;
432 }
433
434 // get rpc retries
435 unsigned
436 retries() const
437 {
438 return retries_;
439 }
440
442 void
443 memoize(Account const& account);
444
447 Account const&
448 lookup(AccountID const& id) const;
449
450 Account const&
451 lookup(std::string const& base58ID) const;
458 balance(Account const& account) const;
459
465 seq(Account const& account) const;
466
470 // VFALCO NOTE This should return a unit-less amount
472 balance(Account const& account, Issue const& issue) const;
473
478 ownerCount(Account const& account) const;
479
484 le(Account const& account) const;
485
490 le(Keylet const& k) const;
491
493 template <class JsonValue, class... FN>
494 JTx
495 jt(JsonValue&& jv, FN const&... fN)
496 {
497 JTx jt(std::forward<JsonValue>(jv));
498 invoke(jt, fN...);
499 autofill(jt);
500 jt.stx = st(jt);
501 return jt;
502 }
503
505 template <class JsonValue, class... FN>
506 JTx
507 jtnofill(JsonValue&& jv, FN const&... fN)
508 {
509 JTx jt(std::forward<JsonValue>(jv));
510 invoke(jt, fN...);
512 jt.stx = st(jt);
513 return jt;
514 }
515
519 template <class JsonValue, class... FN>
521 json(JsonValue&& jv, FN const&... fN)
522 {
523 auto tj = jt(std::forward<JsonValue>(jv), fN...);
524 return std::move(tj.jv);
525 }
526
532 template <class... Args>
533 void
534 require(Args const&... args)
535 {
536 jtx::required(args...)(*this);
537 }
538
541 static ParsedResult
542 parseResult(Json::Value const& jr);
543
547 virtual void
548 submit(JTx const& jt);
549
553 void
555
559 void
561 JTx const& jt,
562 ParsedResult const& parsed,
563 Json::Value const& jr = Json::Value());
564
567 template <class JsonValue, class... FN>
568 Env&
569 apply(JsonValue&& jv, FN const&... fN)
570 {
571 submit(jt(std::forward<JsonValue>(jv), fN...));
572 return *this;
573 }
574
575 template <class JsonValue, class... FN>
576 Env&
577 operator()(JsonValue&& jv, FN const&... fN)
578 {
579 return apply(std::forward<JsonValue>(jv), fN...);
580 }
584 TER
585 ter() const
586 {
587 return ter_;
588 }
589
599 meta();
600
613 tx() const;
614
615 void
616 enableFeature(uint256 const feature);
617
618 void
619 disableFeature(uint256 const feature);
620
621private:
622 void
623 fund(bool setDefaultRipple, STAmount const& amount, Account const& account);
624
625 void
626 fund_arg(STAmount const& amount, Account const& account)
627 {
628 fund(true, amount, account);
629 }
630
631 template <std::size_t N>
632 void
633 fund_arg(STAmount const& amount, std::array<Account, N> const& list)
634 {
635 for (auto const& account : list)
636 fund(false, amount, account);
637 }
638
639public:
666 template <class Arg, class... Args>
667 void
668 fund(STAmount const& amount, Arg const& arg, Args const&... args)
669 {
670 fund_arg(amount, arg);
671 if constexpr (sizeof...(args) > 0)
672 fund(amount, args...);
673 }
674
693 void
694 trust(STAmount const& amount, Account const& account);
695
696 template <class... Accounts>
697 void
699 STAmount const& amount,
700 Account const& to0,
701 Account const& to1,
702 Accounts const&... toN)
703 {
704 trust(amount, to0);
705 trust(amount, to1, toN...);
706 }
714 ust(JTx const& jt);
715
716protected:
717 int trace_ = 0;
722 unsigned retries_ = 5;
723
725 do_rpc(
726 unsigned apiVersion,
727 std::vector<std::string> const& args,
729
730 void
732
733 virtual void
734 autofill(JTx& jt);
735
744 st(JTx const& jt);
745
746 // Invoke funclets on stx
747 // Note: The STTx may not be modified
748 template <class... FN>
749 void
750 invoke(STTx& stx, FN const&... fN)
751 {
752 (fN(*this, stx), ...);
753 }
754
755 // Invoke funclets on jt
756 template <class... FN>
757 void
758 invoke(JTx& jt, FN const&... fN)
759 {
760 (fN(*this, jt), ...);
761 }
762
763 // Map of account IDs to Account
765};
766
767template <class... Args>
770 unsigned apiVersion,
772 std::string const& cmd,
773 Args&&... args)
774{
775 return do_rpc(
776 apiVersion,
777 std::vector<std::string>{cmd, std::forward<Args>(args)...},
778 headers);
779}
780
781template <class... Args>
783Env::rpc(unsigned apiVersion, std::string const& cmd, Args&&... args)
784{
785 return rpc(
786 apiVersion,
788 cmd,
789 std::forward<Args>(args)...);
790}
791
792template <class... Args>
796 std::string const& cmd,
797 Args&&... args)
798{
799 return do_rpc(
801 std::vector<std::string>{cmd, std::forward<Args>(args)...},
802 headers);
803}
804
805template <class... Args>
807Env::rpc(std::string const& cmd, Args&&... args)
808{
809 return rpc(
811 cmd,
812 std::forward<Args>(args)...);
813}
814
815} // namespace jtx
816} // namespace test
817} // namespace ripple
818
819#endif
Represents a JSON value.
Definition: json_value.h:148
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:49
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:120
void fund_arg(STAmount const &amount, std::array< Account, N > const &list)
Definition: Env.h:633
Json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
Definition: Env.h:521
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:402
void disableFeature(uint256 const feature)
Definition: Env.cpp:598
bool parseFailureExpected_
Definition: Env.h:721
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:232
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:764
void notrace()
Turn off JSON tracing.
Definition: Env.h:409
void require(Args const &... args)
Check a set of requirements.
Definition: Env.h:534
void trust(STAmount const &amount, Account const &to0, Account const &to1, Accounts const &... toN)
Definition: Env.h:698
unsigned retries() const
Definition: Env.h:436
TER ter() const
Return the TER for the last JTx.
Definition: Env.h:585
beast::unit_test::suite & test
Definition: Env.h:122
virtual ~Env()=default
bool close(std::chrono::duration< Rep, Period > const &elapsed)
Close and advance the ledger.
Definition: Env.h:378
AppBundle bundle_
Definition: Env.h:158
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition: Env.cpp:455
void invoke(JTx &jt, FN const &... fN)
Definition: Env.h:758
Env & operator=(Env const &)=delete
Env & operator()(JsonValue &&jv, FN const &... fN)
Definition: Env.h:577
Env(Env const &)=delete
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:330
void postconditions(JTx const &jt, ParsedResult const &parsed, Json::Value const &jr=Json::Value())
Check expected postconditions of JTx submission.
Definition: Env.cpp:387
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:290
void autofill_sig(JTx &jt)
Definition: Env.cpp:461
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:668
Json::Value do_rpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition: Env.cpp:567
void invoke(STTx &stx, FN const &... fN)
Definition: Env.h:750
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:515
void enableFeature(uint256 const feature)
Definition: Env.cpp:590
Env(beast::unit_test::suite &suite_)
Create Env with only the current test suite.
Definition: Env.h:253
Account const & master
Definition: Env.h:124
Account const & lookup(AccountID const &id) const
Returns the Account given the AccountID.
Definition: Env.cpp:158
unsigned retries_
Definition: Env.h:722
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:495
NetClock::time_point now()
Returns the current network time.
Definition: Env.h:283
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:541
Application & app()
Definition: Env.h:260
beast::Journal const journal
Definition: Env.h:161
ManualTimeKeeper & timeKeeper()
Definition: Env.h:272
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:769
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:569
void disable_sigs()
Turn off signature checks.
Definition: Env.h:422
void set_retries(unsigned r=5)
Definition: Env.h:429
bool close()
Close and advance the ledger.
Definition: Env.h:392
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:233
TestStopwatch stopwatch_
Definition: Env.h:718
Application const & app() const
Definition: Env.h:266
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:507
void set_parse_failure_expected(bool b)
Definition: Env.h:415
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:183
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:626
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:213
SuiteLogs(beast::unit_test::suite &suite)
Definition: Env.h:100
beast::unit_test::suite & suite_
Definition: Env.h:97
std::unique_ptr< beast::Journal::Sink > makeSink(std::string const &partition, beast::severities::Severity threshold) override
Definition: Env.h:108
~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:37
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:73
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:242
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:144
ManualTimeKeeper * timeKeeper
Definition: Env.h:145
std::unique_ptr< AbstractClient > client
Definition: Env.h:147
Used by parseResult() and postConditions()
Definition: Env.h:128
std::optional< error_code_i > rpcCode
Definition: Env.h:134
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