rippled
Loading...
Searching...
No Matches
Env.cpp
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#include <test/jtx/Env.h>
21#include <test/jtx/JSONRPCClient.h>
22#include <test/jtx/balance.h>
23#include <test/jtx/fee.h>
24#include <test/jtx/flags.h>
25#include <test/jtx/pay.h>
26#include <test/jtx/seq.h>
27#include <test/jtx/sig.h>
28#include <test/jtx/trust.h>
29#include <test/jtx/utility.h>
30#include <xrpld/app/ledger/LedgerMaster.h>
31#include <xrpld/app/misc/NetworkOPs.h>
32#include <xrpld/net/HTTPClient.h>
33#include <xrpld/net/RPCCall.h>
34#include <xrpl/basics/Slice.h>
35#include <xrpl/basics/contract.h>
36#include <xrpl/json/to_string.h>
37#include <xrpl/protocol/ErrorCodes.h>
38#include <xrpl/protocol/Indexes.h>
39#include <xrpl/protocol/Serializer.h>
40#include <xrpl/protocol/TER.h>
41#include <xrpl/protocol/TxFlags.h>
42#include <xrpl/protocol/UintTypes.h>
43#include <xrpl/protocol/jss.h>
44
45#include <memory>
46
47namespace ripple {
48namespace test {
49namespace jtx {
50
51//------------------------------------------------------------------------------
52
58 : AppBundle()
59{
60 using namespace beast::severities;
61 if (logs)
62 {
63 setDebugLogSink(logs->makeSink("Debug", kFatal));
64 }
65 else
66 {
67 logs = std::make_unique<SuiteLogs>(suite);
68 // Use kFatal threshold to reduce noise from STObject.
70 std::make_unique<SuiteJournalSink>("Debug", kFatal, suite));
71 }
72 auto timeKeeper_ = std::make_unique<ManualTimeKeeper>();
73 timeKeeper = timeKeeper_.get();
74 // Hack so we don't have to call Config::setup
77 std::move(config), std::move(logs), std::move(timeKeeper_));
78 app = owned.get();
79 app->logs().threshold(thresh);
80 if (!app->setup({}))
81 Throw<std::runtime_error>("Env::AppBundle: setup failed");
82 timeKeeper->set(app->getLedgerMaster().getClosedLedger()->info().closeTime);
83 app->start(false /*don't start timers*/);
84 thread = std::thread([&]() { app->run(); });
85
87}
88
90{
91 client.reset();
92 // Make sure all jobs finish, otherwise tests
93 // might not get the coverage they expect.
94 if (app)
95 {
97 app->signalStop();
98 }
99 if (thread.joinable())
100 thread.join();
101
102 // Remove the debugLogSink before the suite goes out of scope.
103 setDebugLogSink(nullptr);
104}
105
106//------------------------------------------------------------------------------
107
110{
112}
113
114bool
116 NetClock::time_point closeTime,
118{
119 // Round up to next distinguishable value
120 using namespace std::chrono_literals;
121 bool res = true;
122 closeTime += closed()->info().closeTimeResolution - 1s;
123 timeKeeper().set(closeTime);
124 // Go through the rpc interface unless we need to simulate
125 // a specific consensus delay.
126 if (consensusDelay)
127 app().getOPs().acceptLedger(consensusDelay);
128 else
129 {
130 auto resp = rpc("ledger_accept");
131 if (resp["result"]["status"] != std::string("success"))
132 {
133 std::string reason = "internal error";
134 if (resp.isMember("error_what"))
135 reason = resp["error_what"].asString();
136 else if (resp.isMember("error_message"))
137 reason = resp["error_message"].asString();
138 else if (resp.isMember("error"))
139 reason = resp["error"].asString();
140
141 JLOG(journal.error()) << "Env::close() failed: " << reason;
142 res = false;
143 }
144 }
145 timeKeeper().set(closed()->info().closeTime);
146 return res;
147}
148
149void
150Env::memoize(Account const& account)
151{
152 map_.emplace(account.id(), account);
153}
154
155Account const&
156Env::lookup(AccountID const& id) const
157{
158 auto const iter = map_.find(id);
159 if (iter == map_.end())
160 {
161 std::cout << "Unknown account: " << id << "\n";
162 Throw<std::runtime_error>("Env::lookup:: unknown account ID");
163 }
164 return iter->second;
165}
166
167Account const&
168Env::lookup(std::string const& base58ID) const
169{
170 auto const account = parseBase58<AccountID>(base58ID);
171 if (!account)
172 Throw<std::runtime_error>("Env::lookup: invalid account ID");
173 return lookup(*account);
174}
175
177Env::balance(Account const& account) const
178{
179 auto const sle = le(account);
180 if (!sle)
181 return XRP(0);
182 return {sle->getFieldAmount(sfBalance), ""};
183}
184
186Env::balance(Account const& account, Issue const& issue) const
187{
188 if (isXRP(issue.currency))
189 return balance(account);
190 auto const sle = le(keylet::line(account.id(), issue));
191 if (!sle)
192 return {STAmount(issue, 0), account.name()};
193 auto amount = sle->getFieldAmount(sfBalance);
194 amount.setIssuer(issue.account);
195 if (account.id() > issue.account)
196 amount.negate();
197 return {amount, lookup(issue.account).name()};
198}
199
201Env::ownerCount(Account const& account) const
202{
203 auto const sle = le(account);
204 if (!sle)
205 Throw<std::runtime_error>("missing account root");
206 return sle->getFieldU32(sfOwnerCount);
207}
208
210Env::seq(Account const& account) const
211{
212 auto const sle = le(account);
213 if (!sle)
214 Throw<std::runtime_error>("missing account root");
215 return sle->getFieldU32(sfSequence);
216}
217
219Env::le(Account const& account) const
220{
221 return le(keylet::account(account.id()));
222}
223
225Env::le(Keylet const& k) const
226{
227 return current()->read(k);
228}
229
230void
231Env::fund(bool setDefaultRipple, STAmount const& amount, Account const& account)
232{
233 memoize(account);
234 if (setDefaultRipple)
235 {
236 // VFALCO NOTE Is the fee formula correct?
237 apply(
238 pay(master, account, amount + drops(current()->fees().base)),
242 apply(
243 fset(account, asfDefaultRipple),
247 require(flags(account, asfDefaultRipple));
248 }
249 else
250 {
251 apply(
252 pay(master, account, amount),
257 }
258 require(jtx::balance(account, amount));
259}
260
261void
262Env::trust(STAmount const& amount, Account const& account)
263{
264 auto const start = balance(account);
265 apply(
266 jtx::trust(account, amount),
270 apply(
271 pay(master, account, drops(current()->fees().base)),
275 test.expect(balance(account) == start);
276}
277
280{
281 auto error = [](ParsedResult& parsed, Json::Value const& object) {
282 // Use an error code that is not used anywhere in the transaction
283 // engine to distinguish this case.
284 parsed.ter = telENV_RPC_FAILED;
285 // Extract information about the error
286 if (!object.isObject())
287 return;
288 if (object.isMember(jss::error_code))
289 parsed.rpcCode =
290 safe_cast<error_code_i>(object[jss::error_code].asInt());
291 if (object.isMember(jss::error_message))
292 parsed.rpcMessage = object[jss::error_message].asString();
293 if (object.isMember(jss::error))
294 parsed.rpcError = object[jss::error].asString();
295 if (object.isMember(jss::error_exception))
296 parsed.rpcException = object[jss::error_exception].asString();
297 };
298 ParsedResult parsed;
299 if (jr.isObject() && jr.isMember(jss::result))
300 {
301 auto const& result = jr[jss::result];
302 if (result.isMember(jss::engine_result_code))
303 {
304 parsed.ter = TER::fromInt(result[jss::engine_result_code].asInt());
305 parsed.rpcCode.emplace(rpcSUCCESS);
306 }
307 else
308 error(parsed, result);
309 }
310 else
311 error(parsed, jr);
312
313 return parsed;
314}
315
316void
318{
319 ParsedResult parsedResult;
320 auto const jr = [&]() {
321 if (jt.stx)
322 {
323 txid_ = jt.stx->getTransactionID();
324 Serializer s;
325 jt.stx->add(s);
326 auto const jr = rpc("submit", strHex(s.slice()));
327
328 parsedResult = parseResult(jr);
329 test.expect(parsedResult.ter, "ter uninitialized!");
330 ter_ = parsedResult.ter.value_or(telENV_RPC_FAILED);
331
332 return jr;
333 }
334 else
335 {
336 // Parsing failed or the JTx is
337 // otherwise missing the stx field.
338 parsedResult.ter = ter_ = temMALFORMED;
339
340 return Json::Value();
341 }
342 }();
343 return postconditions(jt, parsedResult, jr);
344}
345
346void
348{
349 auto const account = lookup(jt.jv[jss::Account].asString());
350 auto const& passphrase = account.name();
351
352 Json::Value jr;
353 if (params.isNull())
354 {
355 // Use the command line interface
356 auto const jv = boost::lexical_cast<std::string>(jt.jv);
357 jr = rpc("submit", passphrase, jv);
358 }
359 else
360 {
361 // Use the provided parameters, and go straight
362 // to the (RPC) client.
363 assert(params.isObject());
364 if (!params.isMember(jss::secret) && !params.isMember(jss::key_type) &&
365 !params.isMember(jss::seed) && !params.isMember(jss::seed_hex) &&
366 !params.isMember(jss::passphrase))
367 {
368 params[jss::secret] = passphrase;
369 }
370 params[jss::tx_json] = jt.jv;
371 jr = client().invoke("submit", params);
372 }
373
374 if (!txid_.parseHex(jr[jss::result][jss::tx_json][jss::hash].asString()))
375 txid_.zero();
376
377 ParsedResult const parsedResult = parseResult(jr);
378 test.expect(parsedResult.ter, "ter uninitialized!");
379 ter_ = parsedResult.ter.value_or(telENV_RPC_FAILED);
380
381 return postconditions(jt, parsedResult, jr);
382}
383
384void
386 JTx const& jt,
387 ParsedResult const& parsed,
388 Json::Value const& jr)
389{
390 bool bad = !test.expect(parsed.ter, "apply: No ter result!");
391 bad =
392 (jt.ter && parsed.ter &&
393 !test.expect(
394 *parsed.ter == *jt.ter,
395 "apply: Got " + transToken(*parsed.ter) + " (" +
396 transHuman(*parsed.ter) + "); Expected " +
397 transToken(*jt.ter) + " (" + transHuman(*jt.ter) + ")"));
398 using namespace std::string_literals;
399 bad = (jt.rpcCode &&
400 !test.expect(
401 parsed.rpcCode == jt.rpcCode->first &&
402 parsed.rpcMessage == jt.rpcCode->second,
403 "apply: Got RPC result "s +
404 (parsed.rpcCode
406 : "NO RESULT") +
407 " (" + parsed.rpcMessage + "); Expected " +
408 RPC::get_error_info(jt.rpcCode->first).token.c_str() + " (" +
409 jt.rpcCode->second + ")")) ||
410 bad;
411 // If we have an rpcCode (just checked), then the rpcException check is
412 // optional - the 'error' field may not be defined, but if it is, it must
413 // match rpcError.
414 bad =
415 (jt.rpcException &&
416 !test.expect(
417 (jt.rpcCode && parsed.rpcError.empty()) ||
418 (parsed.rpcError == jt.rpcException->first &&
419 (!jt.rpcException->second ||
420 parsed.rpcException == *jt.rpcException->second)),
421 "apply: Got RPC result "s + parsed.rpcError + " (" +
422 parsed.rpcException + "); Expected " + jt.rpcException->first +
423 " (" + jt.rpcException->second.value_or("n/a") + ")")) ||
424 bad;
425 if (bad)
426 {
427 test.log << pretty(jt.jv) << std::endl;
428 if (jr)
429 test.log << pretty(jr) << std::endl;
430 // Don't check postconditions if
431 // we didn't get the expected result.
432 return;
433 }
434 if (trace_)
435 {
436 if (trace_ > 0)
437 --trace_;
438 test.log << pretty(jt.jv) << std::endl;
439 }
440 for (auto const& f : jt.require)
441 f(*this);
442}
443
446{
447 close();
448 auto const item = closed()->txRead(txid_);
449 return item.second;
450}
451
453Env::tx() const
454{
455 return current()->txRead(txid_).first;
456}
457
458void
460{
461 auto& jv = jt.jv;
462 if (jt.signer)
463 return jt.signer(*this, jt);
464 if (!jt.fill_sig)
465 return;
466 auto const account = lookup(jv[jss::Account].asString());
467 if (!app().checkSigs())
468 {
469 jv[jss::SigningPubKey] = strHex(account.pk().slice());
470 // dummy sig otherwise STTx is invalid
471 jv[jss::TxnSignature] = "00";
472 return;
473 }
474 auto const ar = le(account);
475 if (ar && ar->isFieldPresent(sfRegularKey))
476 jtx::sign(jv, lookup(ar->getAccountID(sfRegularKey)));
477 else
478 jtx::sign(jv, account);
479}
480
481void
483{
484 auto& jv = jt.jv;
485 if (jt.fill_fee)
486 jtx::fill_fee(jv, *current());
487 if (jt.fill_seq)
488 jtx::fill_seq(jv, *current());
489
490 if (jt.fill_netid)
491 {
492 uint32_t networkID = app().config().NETWORK_ID;
493 if (!jv.isMember(jss::NetworkID) && networkID > 1024)
494 jv[jss::NetworkID] = std::to_string(networkID);
495 }
496
497 // Must come last
498 try
499 {
501 }
502 catch (parse_error const&)
503 {
505 test.log << "parse failed:\n" << pretty(jv) << std::endl;
506 Rethrow();
507 }
508}
509
512{
513 // The parse must succeed, since we
514 // generated the JSON ourselves.
516 try
517 {
518 obj = jtx::parse(jt.jv);
519 }
520 catch (jtx::parse_error const&)
521 {
522 test.log << "Exception: parse_error\n" << pretty(jt.jv) << std::endl;
523 Rethrow();
524 }
525
526 try
527 {
528 return sterilize(STTx{std::move(*obj)});
529 }
530 catch (std::exception const&)
531 {
532 }
533 return nullptr;
534}
535
538{
539 // The parse must succeed, since we
540 // generated the JSON ourselves.
542 try
543 {
544 obj = jtx::parse(jt.jv);
545 }
546 catch (jtx::parse_error const&)
547 {
548 test.log << "Exception: parse_error\n" << pretty(jt.jv) << std::endl;
549 Rethrow();
550 }
551
552 try
553 {
554 return std::make_shared<STTx const>(std::move(*obj));
555 }
556 catch (std::exception const&)
557 {
558 }
559 return nullptr;
560}
561
564 unsigned apiVersion,
565 std::vector<std::string> const& args,
567{
568 auto response =
569 rpcClient(args, app().config(), app().logs(), apiVersion, headers);
570
571 for (unsigned ctr = 0; (ctr < retries_) and (response.first == rpcINTERNAL);
572 ++ctr)
573 {
574 JLOG(journal.error())
575 << "Env::do_rpc error, retrying, attempt #" << ctr + 1 << " ...";
577
578 response =
579 rpcClient(args, app().config(), app().logs(), apiVersion, headers);
580 }
581
582 return response.second;
583}
584
585void
587{
588 // Env::close() must be called for feature
589 // enable to take place.
590 app().config().features.insert(feature);
591}
592
593void
595{
596 // Env::close() must be called for feature
597 // enable to take place.
598 app().config().features.erase(feature);
599}
600
601} // namespace jtx
602
603} // namespace test
604} // namespace ripple
constexpr const char * c_str() const
Definition: json_value.h:75
Represents a JSON value.
Definition: json_value.h:148
bool isObject() const
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:475
bool isNull() const
isNull() tests to see if this field is null.
Definition: json_value.cpp:986
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:949
Stream error() const
Definition: Journal.h:346
A testsuite class.
Definition: suite.h:55
log_os< char > log
Logging output stream.
Definition: suite.h:152
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
Definition: suite.h:229
virtual Config & config()=0
virtual void start(bool withTimers)=0
virtual bool setup(boost::program_options::variables_map const &options)=0
virtual void run()=0
virtual JobQueue & getJobQueue()=0
virtual NetworkOPs & getOPs()=0
virtual void signalStop(std::string msg="")=0
virtual LedgerMaster & getLedgerMaster()=0
virtual Logs & logs()=0
uint32_t NETWORK_ID
Definition: Config.h:156
std::unordered_set< uint256, beast::uhash<> > features
Definition: Config.h:277
static void initializeSSLContext(Config const &config, beast::Journal j)
Definition: HTTPClient.cpp:38
A currency issued by an account.
Definition: Issue.h:36
AccountID account
Definition: Issue.h:39
Currency currency
Definition: Issue.h:38
void rendezvous()
Block until no jobs running.
Definition: JobQueue.cpp:272
std::shared_ptr< Ledger const > getClosedLedger()
Definition: LedgerMaster.h:78
beast::severities::Severity threshold() const
Definition: Log.cpp:166
virtual std::uint32_t acceptLedger(std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)=0
Accepts the current transaction tree, return the new ledger's sequence.
Slice slice() const noexcept
Definition: Serializer.h:67
static constexpr TERSubset fromInt(int from)
Definition: TER.h:411
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition: base_uint.h:503
virtual Json::Value invoke(std::string const &cmd, Json::Value const &params={})=0
Submit a command synchronously.
Immutable cryptographic account descriptor.
Definition: Account.h:39
std::string const & name() const
Return the name.
Definition: Account.h:83
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition: Env.cpp:109
void disableFeature(uint256 const feature)
Definition: Env.cpp:594
bool parseFailureExpected_
Definition: Env.h:717
static ParsedResult parseResult(Json::Value const &jr)
Gets the TER result and didApply flag from a RPC Json result object.
Definition: Env.cpp:279
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition: Env.cpp:201
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition: Env.cpp:210
std::unordered_map< AccountID, Account > map_
Definition: Env.h:760
beast::unit_test::suite & test
Definition: Env.h:120
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition: Env.cpp:453
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:326
void postconditions(JTx const &jt, ParsedResult const &parsed, Json::Value const &jr=Json::Value())
Check expected postconditions of JTx submission.
Definition: Env.cpp:385
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:347
virtual void autofill(JTx &jt)
Definition: Env.cpp:482
AbstractClient & client()
Returns the connected client.
Definition: Env.h:286
void autofill_sig(JTx &jt)
Definition: Env.cpp:459
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:262
Json::Value do_rpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition: Env.cpp:563
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:511
void enableFeature(uint256 const feature)
Definition: Env.cpp:586
Account const & master
Definition: Env.h:122
Account const & lookup(AccountID const &id) const
Returns the Account given the AccountID.
Definition: Env.cpp:156
unsigned retries_
Definition: Env.h:718
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:491
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:537
Application & app()
Definition: Env.h:256
beast::Journal const journal
Definition: Env.h:159
ManualTimeKeeper & timeKeeper()
Definition: Env.h:268
virtual void submit(JTx const &jt)
Submit an existing JTx.
Definition: Env.cpp:317
Env & apply(JsonValue &&jv, FN const &... fN)
Apply funclets and submit.
Definition: Env.h:565
bool close()
Close and advance the ledger.
Definition: Env.h:388
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:231
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition: Env.cpp:445
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
Definition: Env.cpp:177
void memoize(Account const &account)
Associate AccountID with account.
Definition: Env.cpp:150
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition: Env.cpp:219
A balance matches.
Definition: balance.h:39
Set the fee on a JTx.
Definition: fee.h:36
Match set account flags.
Definition: flags.h:112
Match clear account flags.
Definition: flags.h:129
Check a set of conditions.
Definition: require.h:65
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition: rpc.h:35
Set the regular signature on a JTx.
Definition: sig.h:35
T emplace(T... args)
T empty(T... args)
T endl(T... args)
A namespace for easy access to logging severity values.
Definition: Journal.h:30
Severity
Severity level / threshold of a Journal message.
Definition: Journal.h:32
ErrorInfo const & get_error_info(error_code_i code)
Returns an ErrorInfo that reflects the error code.
Definition: ErrorCodes.cpp:177
Keylet line(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition: Indexes.cpp:235
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:175
void fill_seq(Json::Value &jv, ReadView const &view)
Set the sequence number automatically.
Definition: utility.cpp:64
static autofill_t const autofill
Definition: tags.h:42
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Definition: trust.cpp:31
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Definition: flags.cpp:28
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Definition: pay.cpp:29
void sign(Json::Value &jv, Account const &account)
Sign automatically.
Definition: utility.cpp:45
STObject parse(Json::Value const &jv)
Convert JSON to STObject.
Definition: utility.cpp:36
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:104
void fill_fee(Json::Value &jv, ReadView const &view)
Set the fee automatically.
Definition: utility.cpp:56
std::unique_ptr< AbstractClient > makeJSONRPCClient(Config const &cfg, unsigned rpc_version)
Returns a client using JSON-RPC over HTTP/S.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
std::string transHuman(TER code)
Definition: TER.cpp:266
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Definition: STTx.cpp:631
std::pair< int, Json::Value > rpcClient(std::vector< std::string > const &args, Config const &config, Logs &logs, unsigned int apiVersion, std::unordered_map< std::string, std::string > const &headers)
Internal invocation of RPC client.
Definition: RPCCall.cpp:1461
bool isXRP(AccountID const &c)
Definition: AccountID.h:91
@ telENV_RPC_FAILED
Definition: TER.h:68
@ rpcSUCCESS
Definition: ErrorCodes.h:44
@ rpcINTERNAL
Definition: ErrorCodes.h:130
std::unique_ptr< Application > make_Application(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
std::string transToken(TER code)
Definition: TER.cpp:257
constexpr std::uint32_t asfDefaultRipple
Definition: TxFlags.h:83
beast::Journal debugLog()
Returns a debug journal.
Definition: Log.cpp:468
std::unique_ptr< beast::Journal::Sink > setDebugLogSink(std::unique_ptr< beast::Journal::Sink > sink)
Set the sink for the debug journal.
Definition: Log.cpp:462
void Rethrow()
Rethrow the exception currently being handled.
Definition: contract.h:48
@ temMALFORMED
Definition: TER.h:87
T sleep_for(T... args)
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:39
Json::StaticString token
Definition: ErrorCodes.h:210
std::unique_ptr< Application > owned
Definition: Env.h:142
ManualTimeKeeper * timeKeeper
Definition: Env.h:143
std::unique_ptr< AbstractClient > client
Definition: Env.h:145
Used by parseResult() and postConditions()
Definition: Env.h:126
std::optional< error_code_i > rpcCode
Definition: Env.h:132
std::optional< TER > ter
Definition: Env.h:127
Execution context for applying a JSON transaction.
Definition: JTx.h:44
std::optional< std::pair< error_code_i, std::string > > rpcCode
Definition: JTx.h:48
std::shared_ptr< STTx const > stx
Definition: JTx.h:55
Json::Value jv
Definition: JTx.h:45
std::optional< std::pair< std::string, std::optional< std::string > > > rpcException
Definition: JTx.h:50
std::function< void(Env &, JTx &)> signer
Definition: JTx.h:56
requires_t require
Definition: JTx.h:46
std::optional< TER > ter
Definition: JTx.h:47
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
Thrown when parse fails.
Definition: utility.h:37
Set the sequence number on a JTx.
Definition: seq.h:34
T to_string(T... args)
T value_or(T... args)