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 : Env(suite_, envconfig(), features)
215 {
216 }
217
232 std::unique_ptr<Logs> logs = nullptr,
234 : Env(suite_,
235 std::move(config),
237 std::move(logs),
238 thresh)
239 {
240 }
241
252 {
253 }
254
255 virtual ~Env() = default;
256
259 {
260 return *bundle_.app;
261 }
262
263 Application const&
264 app() const
265 {
266 return *bundle_.app;
267 }
268
271 {
272 return *bundle_.timeKeeper;
273 }
274
282 {
283 return timeKeeper().now();
284 }
285
289 {
290 return *bundle_.client;
291 }
292
298 template <class... Args>
300 rpc(unsigned apiVersion,
302 std::string const& cmd,
303 Args&&... args);
304
305 template <class... Args>
307 rpc(unsigned apiVersion, std::string const& cmd, Args&&... args);
308
309 template <class... Args>
312 std::string const& cmd,
313 Args&&... args);
314
315 template <class... Args>
317 rpc(std::string const& cmd, Args&&... args);
318
328 current() const
329 {
330 return app().openLedger().current();
331 }
332
341 closed();
342
362 bool
363 close(
364 NetClock::time_point closeTime,
365 std::optional<std::chrono::milliseconds> consensusDelay = std::nullopt);
366
374 template <class Rep, class Period>
375 bool
377 {
378 // VFALCO Is this the correct time?
379 return close(now() + elapsed);
380 }
381
389 bool
391 {
392 // VFALCO Is this the correct time?
393 return close(std::chrono::seconds(5));
394 }
395
399 void
400 trace(int howMany = -1)
401 {
402 trace_ = howMany;
403 }
404
406 void
408 {
409 trace_ = 0;
410 }
411
412 void
414 {
416 }
417
419 void
421 {
422 app().checkSigs(false);
423 }
424
425 // set rpc retries
426 void
427 set_retries(unsigned r = 5)
428 {
429 retries_ = r;
430 }
431
432 // get rpc retries
433 unsigned
434 retries() const
435 {
436 return retries_;
437 }
438
440 void
441 memoize(Account const& account);
442
445 Account const&
446 lookup(AccountID const& id) const;
447
448 Account const&
449 lookup(std::string const& base58ID) const;
456 balance(Account const& account) const;
457
463 seq(Account const& account) const;
464
468 // VFALCO NOTE This should return a unit-less amount
470 balance(Account const& account, Issue const& issue) const;
471
476 ownerCount(Account const& account) const;
477
482 le(Account const& account) const;
483
488 le(Keylet const& k) const;
489
491 template <class JsonValue, class... FN>
492 JTx
493 jt(JsonValue&& jv, FN const&... fN)
494 {
495 JTx jt(std::forward<JsonValue>(jv));
496 invoke(jt, fN...);
497 autofill(jt);
498 jt.stx = st(jt);
499 return jt;
500 }
501
503 template <class JsonValue, class... FN>
504 JTx
505 jtnofill(JsonValue&& jv, FN const&... fN)
506 {
507 JTx jt(std::forward<JsonValue>(jv));
508 invoke(jt, fN...);
510 jt.stx = st(jt);
511 return jt;
512 }
513
517 template <class JsonValue, class... FN>
519 json(JsonValue&& jv, FN const&... fN)
520 {
521 auto tj = jt(std::forward<JsonValue>(jv), fN...);
522 return std::move(tj.jv);
523 }
524
530 template <class... Args>
531 void
532 require(Args const&... args)
533 {
534 jtx::required(args...)(*this);
535 }
536
539 static ParsedResult
540 parseResult(Json::Value const& jr);
541
545 virtual void
546 submit(JTx const& jt);
547
551 void
553
557 void
559 JTx const& jt,
560 ParsedResult const& parsed,
561 Json::Value const& jr = Json::Value());
562
565 template <class JsonValue, class... FN>
566 Env&
567 apply(JsonValue&& jv, FN const&... fN)
568 {
569 submit(jt(std::forward<JsonValue>(jv), fN...));
570 return *this;
571 }
572
573 template <class JsonValue, class... FN>
574 Env&
575 operator()(JsonValue&& jv, FN const&... fN)
576 {
577 return apply(std::forward<JsonValue>(jv), fN...);
578 }
582 TER
583 ter() const
584 {
585 return ter_;
586 }
587
597 meta();
598
611 tx() const;
612
613 void
614 enableFeature(uint256 const feature);
615
616 void
617 disableFeature(uint256 const feature);
618
619private:
620 void
621 fund(bool setDefaultRipple, STAmount const& amount, Account const& account);
622
623 void
624 fund_arg(STAmount const& amount, Account const& account)
625 {
626 fund(true, amount, account);
627 }
628
629 template <std::size_t N>
630 void
631 fund_arg(STAmount const& amount, std::array<Account, N> const& list)
632 {
633 for (auto const& account : list)
634 fund(false, amount, account);
635 }
636
637public:
664 template <class Arg, class... Args>
665 void
666 fund(STAmount const& amount, Arg const& arg, Args const&... args)
667 {
668 fund_arg(amount, arg);
669 if constexpr (sizeof...(args) > 0)
670 fund(amount, args...);
671 }
672
691 void
692 trust(STAmount const& amount, Account const& account);
693
694 template <class... Accounts>
695 void
697 STAmount const& amount,
698 Account const& to0,
699 Account const& to1,
700 Accounts const&... toN)
701 {
702 trust(amount, to0);
703 trust(amount, to1, toN...);
704 }
712 ust(JTx const& jt);
713
714protected:
715 int trace_ = 0;
720 unsigned retries_ = 5;
721
723 do_rpc(
724 unsigned apiVersion,
725 std::vector<std::string> const& args,
727
728 void
730
731 virtual void
732 autofill(JTx& jt);
733
742 st(JTx const& jt);
743
744 // Invoke funclets on stx
745 // Note: The STTx may not be modified
746 template <class... FN>
747 void
748 invoke(STTx& stx, FN const&... fN)
749 {
750 (fN(*this, stx), ...);
751 }
752
753 // Invoke funclets on jt
754 template <class... FN>
755 void
756 invoke(JTx& jt, FN const&... fN)
757 {
758 (fN(*this, jt), ...);
759 }
760
761 // Map of account IDs to Account
763};
764
765template <class... Args>
768 unsigned apiVersion,
770 std::string const& cmd,
771 Args&&... args)
772{
773 return do_rpc(
774 apiVersion,
775 std::vector<std::string>{cmd, std::forward<Args>(args)...},
776 headers);
777}
778
779template <class... Args>
781Env::rpc(unsigned apiVersion, std::string const& cmd, Args&&... args)
782{
783 return rpc(
784 apiVersion,
786 cmd,
787 std::forward<Args>(args)...);
788}
789
790template <class... Args>
794 std::string const& cmd,
795 Args&&... args)
796{
797 return do_rpc(
799 std::vector<std::string>{cmd, std::forward<Args>(args)...},
800 headers);
801}
802
803template <class... Args>
805Env::rpc(std::string const& cmd, Args&&... args)
806{
807 return rpc(
809 cmd,
810 std::forward<Args>(args)...);
811}
812
813} // namespace jtx
814} // namespace test
815} // namespace ripple
816
817#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:631
Json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
Definition: Env.h:519
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:400
void disableFeature(uint256 const feature)
Definition: Env.cpp:596
bool parseFailureExpected_
Definition: Env.h:719
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:230
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:762
void notrace()
Turn off JSON tracing.
Definition: Env.h:407
void require(Args const &... args)
Check a set of requirements.
Definition: Env.h:532
void trust(STAmount const &amount, Account const &to0, Account const &to1, Accounts const &... toN)
Definition: Env.h:696
unsigned retries() const
Definition: Env.h:434
TER ter() const
Return the TER for the last JTx.
Definition: Env.h:583
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:376
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:756
Env & operator=(Env const &)=delete
Env & operator()(JsonValue &&jv, FN const &... fN)
Definition: Env.h:575
Env(Env const &)=delete
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:328
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:288
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:666
Json::Value do_rpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition: Env.cpp:565
void invoke(STTx &stx, FN const &... fN)
Definition: Env.h:748
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:513
void enableFeature(uint256 const feature)
Definition: Env.cpp:588
Env(beast::unit_test::suite &suite_)
Create Env with only the current test suite.
Definition: Env.h:251
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:720
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:493
NetClock::time_point now()
Returns the current network time.
Definition: Env.h:281
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:539
Application & app()
Definition: Env.h:258
beast::Journal const journal
Definition: Env.h:161
Env(beast::unit_test::suite &suite_, FeatureBitset features)
Create Env with default config and specified features.
Definition: Env.h:213
ManualTimeKeeper & timeKeeper()
Definition: Env.h:270
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:767
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:567
void disable_sigs()
Turn off signature checks.
Definition: Env.h:420
void set_retries(unsigned r=5)
Definition: Env.h:427
bool close()
Close and advance the ledger.
Definition: Env.h:390
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:233
TestStopwatch stopwatch_
Definition: Env.h:716
Application const & app() const
Definition: Env.h:264
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:505
void set_parse_failure_expected(bool b)
Definition: Env.h:413
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:624
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