rippled
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/Account.h>
24 #include <test/jtx/amount.h>
25 #include <test/jtx/envconfig.h>
26 #include <test/jtx/JTx.h>
27 #include <test/jtx/require.h>
28 #include <test/jtx/tags.h>
29 #include <test/jtx/AbstractClient.h>
30 #include <test/jtx/ManualTimeKeeper.h>
31 #include <test/unit_test/SuiteJournal.h>
32 #include <ripple/app/main/Application.h>
33 #include <ripple/app/ledger/Ledger.h>
34 #include <ripple/app/ledger/OpenLedger.h>
35 #include <ripple/app/paths/Pathfinder.h>
36 #include <ripple/basics/chrono.h>
37 #include <ripple/basics/Log.h>
38 #include <ripple/core/Config.h>
39 #include <ripple/json/json_value.h>
40 #include <ripple/json/to_string.h>
41 #include <ripple/ledger/CachedSLEs.h>
42 #include <ripple/protocol/Feature.h>
43 #include <ripple/protocol/Indexes.h>
44 #include <ripple/protocol/Issue.h>
45 #include <ripple/protocol/STAmount.h>
46 #include <ripple/protocol/STObject.h>
47 #include <ripple/protocol/STTx.h>
48 #include <functional>
49 #include <string>
50 #include <tuple>
51 #include <ripple/beast/cxx17/type_traits.h> // <type_traits>
52 #include <utility>
53 #include <unordered_map>
54 #include <vector>
55 
56 
57 namespace ripple {
58 namespace test {
59 namespace jtx {
60 
62 template <class... Args>
63 std::array<Account, 1 + sizeof...(Args)>
64 noripple (Account const& account, Args const&... args)
65 {
66  return {{account, args...}};
67 }
68 
69 inline
72 {
73  static const FeatureBitset ids = []{
74  auto const& sa = ripple::detail::supportedAmendments();
76  feats.reserve(sa.size());
77  for (auto const& s : sa)
78  {
79  if (auto const f = getRegisteredFeature(s))
80  feats.push_back(*f);
81  else
82  Throw<std::runtime_error> ("Unknown feature: " + s + " in supportedAmendments.");
83  }
84  return FeatureBitset(feats);
85  }();
86  return ids;
87 }
88 
89 //------------------------------------------------------------------------------
90 
91 class SuiteLogs : public Logs
92 {
93  beast::unit_test::suite& suite_;
94 
95 public:
96  explicit
97  SuiteLogs(beast::unit_test::suite& suite)
98  : Logs (beast::severities::kError)
99  , suite_(suite)
100  {
101  }
102 
103  ~SuiteLogs() override = default;
104 
106  makeSink(std::string const& partition,
108  {
109  return std::make_unique<SuiteJournalSink>(
110  partition, threshold, suite_);
111  }
112 };
113 
114 //------------------------------------------------------------------------------
115 
117 class Env
118 {
119 public:
120  beast::unit_test::suite& test;
121 
123 
124 private:
125  struct AppBundle
126  {
127  Application* app = nullptr;
132 
133  AppBundle() = default;
134  AppBundle (beast::unit_test::suite& suite,
136  std::unique_ptr<Logs> logs);
137  ~AppBundle();
138  };
139 
141 
142 public:
144 
145  Env() = delete;
146  Env& operator= (Env const&) = delete;
147  Env (Env const&) = delete;
148 
162  // VFALCO Could wrap the suite::log in a Journal here
163  Env (beast::unit_test::suite& suite_,
165  FeatureBitset features,
166  std::unique_ptr<Logs> logs = nullptr)
167  : test (suite_)
168  , bundle_ (
169  suite_,
170  std::move(config),
171  logs ? std::move(logs) : std::make_unique<SuiteLogs>(suite_))
172  , journal {bundle_.app->journal ("Env")}
173  {
177  features, [& appFeats = app().config().features](uint256 const& f) {
178  appFeats.insert(f);
179  });
180  }
181 
195  Env (beast::unit_test::suite& suite_,
196  FeatureBitset features)
197  : Env(suite_, envconfig(), features)
198  {
199  }
200 
212  Env (beast::unit_test::suite& suite_,
214  std::unique_ptr<Logs> logs = nullptr)
215  : Env(suite_, std::move(config),
216  supported_amendments(), std::move(logs))
217  {
218  }
219 
229  Env (beast::unit_test::suite& suite_)
230  : Env(suite_, envconfig())
231  {
232  }
233 
234  virtual ~Env() = default;
235 
236  Application&
237  app()
238  {
239  return *bundle_.app;
240  }
241 
242  Application const&
243  app() const
244  {
245  return *bundle_.app;
246  }
247 
250  {
251  return *bundle_.timeKeeper;
252  }
253 
260  now()
261  {
262  return timeKeeper().now();
263  }
264 
268  {
269  return *bundle_.client;
270  }
271 
277  template<class... Args>
280  std::string const& cmd,
281  Args&&... args);
282 
283  template<class... Args>
285  rpc(std::string const& cmd, Args&&... args);
286 
296  current() const
297  {
298  return app().openLedger().current();
299  }
300 
309  closed();
310 
328  void
329  close (NetClock::time_point closeTime,
330  boost::optional<std::chrono::milliseconds> consensusDelay = boost::none);
331 
337  template <class Rep, class Period>
338  void
340  Rep, Period> const& elapsed)
341  {
342  // VFALCO Is this the correct time?
343  close (now() + elapsed);
344  }
345 
351  void
353  {
354  // VFALCO Is this the correct time?
356  }
357 
361  void
362  trace (int howMany = -1)
363  {
364  trace_ = howMany;
365  }
366 
368  void
370  {
371  trace_ = 0;
372  }
373 
375  void
377  {
378  app().checkSigs(false);
379  }
380 
382  void
383  memoize (Account const& account);
384 
387  Account const&
388  lookup (AccountID const& id) const;
389 
390  Account const&
391  lookup (std::string const& base58ID) const;
398  balance (Account const& account) const;
399 
405  seq (Account const& account) const;
406 
410  // VFALCO NOTE This should return a unit-less amount
412  balance (Account const& account,
413  Issue const& issue) const;
414 
419  le (Account const& account) const;
420 
425  le (Keylet const& k) const;
426 
428  template <class JsonValue,
429  class... FN>
430  JTx
431  jt (JsonValue&& jv, FN const&... fN)
432  {
433  JTx jt(std::forward<JsonValue>(jv));
434  invoke(jt, fN...);
435  autofill(jt);
436  jt.stx = st(jt);
437  return jt;
438  }
439 
443  template <class JsonValue,
444  class... FN>
446  json (JsonValue&&jv, FN const&... fN)
447  {
448  auto tj = jt(
449  std::forward<JsonValue>(jv),
450  fN...);
451  return std::move(tj.jv);
452  }
453 
459  template <class... Args>
460  void
461  require (Args const&... args)
462  {
463  jtx::required(args...)(*this);
464  }
465 
468  static
470  parseResult(Json::Value const& jr);
471 
475  virtual
476  void
477  submit (JTx const& jt);
478 
482  void
484 
488  void
489  postconditions(JTx const& jt, TER ter, bool didApply);
490 
493  template <class JsonValue, class... FN>
494  void
495  apply (JsonValue&& jv, FN const&... fN)
496  {
498  JsonValue>(jv), fN...));
499  }
500 
501  template <class JsonValue,
502  class... FN>
503  void
504  operator()(JsonValue&& jv, FN const&... fN)
505  {
507  JsonValue>(jv), fN...);
508  }
512  TER
513  ter() const
514  {
515  return ter_;
516  }
517 
527  meta();
528 
541  tx() const;
542 
543  void
544  enableFeature(uint256 const feature);
545 
546 private:
547  void
548  fund (bool setDefaultRipple,
549  STAmount const& amount,
550  Account const& account);
551 
552  void
553  fund_arg (STAmount const& amount,
554  Account const& account)
555  {
556  fund (true, amount, account);
557  }
558 
559  template <std::size_t N>
560  void
561  fund_arg (STAmount const& amount,
562  std::array<Account, N> const& list)
563  {
564  for (auto const& account : list)
565  fund (false, amount, account);
566  }
567 public:
568 
595  template<class Arg, class... Args>
596  void
597  fund (STAmount const& amount,
598  Arg const& arg, Args const&... args)
599  {
600  fund_arg (amount, arg);
601  if constexpr (sizeof...(args) > 0)
602  fund(amount, args...);
603  }
604 
623  void
624  trust (STAmount const& amount,
625  Account const& account);
626 
627  template<class... Accounts>
628  void
629  trust (STAmount const& amount, Account const& to0,
630  Account const& to1, Accounts const&... toN)
631  {
632  trust(amount, to0);
633  trust(amount, to1, toN...);
634  }
637 protected:
638  int trace_ = 0;
642 
644  do_rpc(std::vector<std::string> const& args,
646 
647  void
648  autofill_sig (JTx& jt);
649 
650  virtual
651  void
652  autofill (JTx& jt);
653 
662  st (JTx const& jt);
663 
664  // Invoke funclets on stx
665  // Note: The STTx may not be modified
666  template <class... FN>
667  void
668  invoke (STTx& stx, FN const&... fN)
669  {
670  (fN(*this, stx),...);
671  }
672 
673  // Invoke funclets on jt
674  template <class... FN>
675  void
676  invoke (JTx& jt, FN const&... fN)
677  {
678  (fN(*this, jt),...);
679  }
680 
681  // Map of account IDs to Account
684 };
685 
686 template<class... Args>
689  std::string const& cmd,
690  Args&&... args)
691 {
692  return do_rpc(std::vector<std::string>{cmd, std::forward<Args>(args)...},
693  headers);
694 }
695 
696 template<class... Args>
698 Env::rpc(std::string const& cmd, Args&&... args)
699 {
701  std::forward<Args>(args)...);
702 }
703 
704 } // jtx
705 } // test
706 } // ripple
707 
708 #endif
ripple::test::jtx::Env::AppBundle::app
Application * app
Definition: Env.h:127
ripple::test::jtx::Env::invoke
void invoke(STTx &stx, FN const &... fN)
Definition: Env.h:668
ripple::Application
Definition: Application.h:85
ripple::Application::checkSigs
virtual bool checkSigs() const =0
ripple::test::jtx::Env::Env
Env(beast::unit_test::suite &suite_, FeatureBitset features)
Create Env with default config and specified features.
Definition: Env.h:195
ripple::test::jtx::Env::autofill_sig
void autofill_sig(JTx &jt)
Definition: Env.cpp:376
ripple::test::jtx::SuiteLogs::suite_
beast::unit_test::suite & suite_
Definition: Env.h:93
ripple::test::jtx::Env::fund
void fund(STAmount const &amount, Arg const &arg, Args const &... args)
Create a new account with some XRP.
Definition: Env.h:597
ripple::Keylet
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:38
ripple::OpenLedger::current
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
Definition: OpenLedger.cpp:52
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
std::string
STL class.
ripple::test::jtx::Env::close
void close(std::chrono::duration< Rep, Period > const &elapsed)
Close and advance the ledger.
Definition: Env.h:339
std::shared_ptr
STL class.
utility
ripple::Logs
Manages partitions for logging.
Definition: Log.h:49
ripple::test::jtx::Env::ter_
TER ter_
Definition: Env.h:641
ripple::test::AbstractClient
Definition: AbstractClient.h:33
ripple::test::jtx::Env::AppBundle::client
std::unique_ptr< AbstractClient > client
Definition: Env.h:131
ripple::test::jtx::Env::tx
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition: Env.cpp:370
ripple::test::jtx::ter
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition: ter.h:33
functional
ripple::test::jtx::Env::require
void require(Args const &... args)
Check a set of requirements.
Definition: Env.h:461
ripple::test::jtx::Env::apply
void apply(JsonValue &&jv, FN const &... fN)
Apply funclets and submit.
Definition: Env.h:495
ripple::test::jtx::Env::closed
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition: Env.cpp:108
std::pair
ripple::test::jtx::Env::close
void close()
Close and advance the ledger.
Definition: Env.h:352
std::vector::reserve
T reserve(T... args)
ripple::test::jtx::Env::fund_arg
void fund_arg(STAmount const &amount, std::array< Account, N > const &list)
Definition: Env.h:561
ripple::test::jtx::Env::AppBundle::AppBundle
AppBundle()=default
vector
ripple::test::jtx::Env::enableFeature
void enableFeature(uint256 const feature)
Definition: Env.cpp:457
ripple::test::jtx::Env::AppBundle::timeKeeper
ManualTimeKeeper * timeKeeper
Definition: Env.h:129
ripple::test::jtx::Env::txid_
uint256 txid_
Definition: Env.h:640
ripple::test::jtx::Env::AppBundle::~AppBundle
~AppBundle()
Definition: Env.cpp:88
ripple::test::jtx::JTx::stx
std::shared_ptr< STTx const > stx
Definition: JTx.h:49
ripple::test::jtx::Env::jt
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:431
std::chrono::duration
ripple::test::jtx::Env::Env
Env(beast::unit_test::suite &suite_, std::unique_ptr< Config > config, FeatureBitset features, std::unique_ptr< Logs > logs=nullptr)
Create Env using suite, Config pointer, and explicit features.
Definition: Env.h:163
ripple::test::jtx::Env::journal
const beast::Journal journal
Definition: Env.h:143
ripple::test::jtx::Env::notrace
void notrace()
Turn off JSON tracing.
Definition: Env.h:369
ripple::test::jtx::Env::disable_sigs
void disable_sigs()
Turn off signature checks.
Definition: Env.h:376
ripple::test::jtx::Env::timeKeeper
ManualTimeKeeper & timeKeeper()
Definition: Env.h:249
ripple::test::jtx::SuiteLogs::~SuiteLogs
~SuiteLogs() override=default
ripple::test::jtx::Env::sign_and_submit
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:298
ripple::test::jtx::Env::Env
Env(beast::unit_test::suite &suite_, std::unique_ptr< Config > config, std::unique_ptr< Logs > logs=nullptr)
Create Env using suite and Config pointer.
Definition: Env.h:212
tuple
ripple::test::jtx::Env::AppBundle::thread
std::thread thread
Definition: Env.h:130
ripple::Pathfinder::initPathTable
static void initPathTable()
Definition: Pathfinder.cpp:1240
ripple::test::jtx::Env::balance
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
Definition: Env.cpp:162
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:237
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:52
ripple::Application::openLedger
virtual OpenLedger & openLedger()=0
ripple::test::jtx::Env::bundle_
AppBundle bundle_
Definition: Env.h:140
ripple::test::jtx::Env::ter
TER ter() const
Return the TER for the last JTx.
Definition: Env.h:513
ripple::test::jtx::Env::trust
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:245
ripple::test::jtx::Env::st
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:423
ripple::test::jtx::Env::parseResult
static std::pair< TER, bool > parseResult(Json::Value const &jr)
Gets the TER result and didApply flag from a RPC Json result object.
Definition: Env.cpp:262
std::vector::push_back
T push_back(T... args)
ripple::test::ManualTimeKeeper
Definition: ManualTimeKeeper.h:29
ripple::base_uint< 256 >
ripple::test::jtx::SuiteLogs::SuiteLogs
SuiteLogs(beast::unit_test::suite &suite)
Definition: Env.h:97
ripple::test::jtx::Env::stopwatch_
TestStopwatch stopwatch_
Definition: Env.h:639
ripple::test::jtx::Env::meta
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition: Env.cpp:362
ripple::foreachFeature
void foreachFeature(FeatureBitset bs, F &&f)
Definition: Feature.h:359
ripple::test::jtx::Env::operator()
void operator()(JsonValue &&jv, FN const &... fN)
Definition: Env.h:504
std::thread
STL class.
std::forward
T forward(T... args)
ripple::test::jtx::Env::trace
void trace(int howMany=-1)
Turn on JSON tracing.
Definition: Env.h:362
ripple::test::jtx::Env::postconditions
void postconditions(JTx const &jt, TER ter, bool didApply)
Check expected postconditions of JTx submission.
Definition: Env.cpp:338
ripple::TERSubset< CanCvtToTER >
ripple::test::jtx::SuiteLogs
Definition: Env.h:91
ripple::test::jtx::JTx
Execution context for applying a JSON transaction.
Definition: JTx.h:41
std::array
STL class.
ripple::test::jtx::Env::submit
virtual void submit(JTx const &jt)
Submit an existing JTx.
Definition: Env.cpp:275
ripple::STAmount
Definition: STAmount.h:42
std::chrono::time_point
ripple::STTx
Definition: STTx.h:43
ripple::test::jtx::Env::lookup
Account const & lookup(AccountID const &id) const
Returns the Account given the AccountID.
Definition: Env.cpp:141
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:60
ripple::test::jtx::supported_amendments
FeatureBitset supported_amendments()
Definition: Env.h:71
std::uint32_t
ripple::test::jtx::Account::master
static const Account master
The master account.
Definition: Account.h:44
ripple::test::jtx::Env::seq
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition: Env.cpp:192
ripple::test::jtx::Env::app
Application const & app() const
Definition: Env.h:243
ripple::test::jtx::Env::test
beast::unit_test::suite & test
Definition: Env.h:120
ripple::test::jtx::Env::invoke
void invoke(JTx &jt, FN const &... fN)
Definition: Env.h:676
ripple::test::jtx::required
require_t required(Args const &... args)
Compose many condition functors into one.
Definition: require.h:49
ripple::test::jtx::Env::client
AbstractClient & client()
Returns the connected client.
Definition: Env.h:267
ripple::detail::supportedAmendments
std::vector< std::string > const & supportedAmendments()
Amendments that this server supports, but doesn't enable by default.
Definition: Feature.cpp:81
ripple::Logs::threshold
beast::severities::Severity threshold() const
Definition: Log.cpp:146
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::jtx::Env::operator=
Env & operator=(Env const &)=delete
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::test::jtx::noripple
std::array< Account, 1+sizeof...(Args)> noripple(Account const &account, Args const &... args)
Designate accounts as no-ripple in Env::fund.
Definition: Env.h:64
ripple::test::jtx::Env::autofill
virtual void autofill(JTx &jt)
Definition: Env.cpp:402
ripple::test::jtx::Env::do_rpc
Json::Value do_rpc(std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition: Env.cpp:450
ripple::test::jtx::Env::now
NetClock::time_point now()
Returns the current Ripple Network Time.
Definition: Env.h:260
beast::severities::Severity
Severity
Severity level / threshold of a Journal message.
Definition: Journal.h:32
std
STL namespace.
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:214
ripple::test::jtx::Env::le
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition: Env.cpp:202
ripple::test::jtx::Env::AppBundle::owned
std::unique_ptr< Application > owned
Definition: Env.h:128
ripple::test::jtx::Env::master
Account const & master
Definition: Env.h:122
Json::nullValue
@ nullValue
'null' value
Definition: json_value.h:38
ripple::test::jtx::Env::map_
std::unordered_map< AccountID, Account > map_
Definition: Env.h:683
ripple::FeatureBitset
Definition: Feature.h:153
ripple::test::jtx::Env::Env
Env(beast::unit_test::suite &suite_)
Create Env with only the current test suite.
Definition: Env.h:229
ripple::test::jtx::Env::~Env
virtual ~Env()=default
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
ripple::test::jtx::Env::fund_arg
void fund_arg(STAmount const &amount, Account const &account)
Definition: Env.h:553
ripple::test::ManualTimeKeeper::now
time_point now() const override
Returns the estimate of wall time, in network time.
Definition: ManualTimeKeeper.cpp:39
beast::manual_clock< std::chrono::steady_clock >
ripple::test::jtx::Env::memoize
void memoize(Account const &account)
Associate AccountID with account.
Definition: Env.cpp:135
ripple::test::jtx::Env::Env
Env()=delete
std::unique_ptr< beast::Journal::Sink >
unordered_map
ripple::test::jtx::SuiteLogs::makeSink
std::unique_ptr< beast::Journal::Sink > makeSink(std::string const &partition, beast::severities::Severity threshold) override
Definition: Env.h:106
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:219
ripple::test::jtx::Env::current
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:296
ripple::test::jtx::Env::json
Json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
Definition: Env.h:446
ripple::test::jtx::Env::trust
void trust(STAmount const &amount, Account const &to0, Account const &to1, Accounts const &... toN)
Definition: Env.h:629
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:117
ripple::test::jtx::Env::AppBundle
Definition: Env.h:125
ripple::test::jtx::Env::rpc
Json::Value rpc(std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:688
Json::Value
Represents a JSON value.
Definition: json_value.h:141
ripple::test::jtx::PrettyAmount
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
Definition: amount.h:73
ripple::test::jtx::Env::trace_
int trace_
Definition: Env.h:638
ripple::getRegisteredFeature
boost::optional< uint256 > getRegisteredFeature(std::string const &name)
Definition: Feature.cpp:141
beast
Definition: base_uint.h:582
string