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
31#include <xrpld/app/ledger/LedgerMaster.h>
32#include <xrpld/app/misc/NetworkOPs.h>
33#include <xrpld/rpc/RPCCall.h>
34
35#include <xrpl/basics/Slice.h>
36#include <xrpl/basics/contract.h>
37#include <xrpl/json/to_string.h>
38#include <xrpl/net/HTTPClient.h>
39#include <xrpl/protocol/ErrorCodes.h>
40#include <xrpl/protocol/Indexes.h>
41#include <xrpl/protocol/Serializer.h>
42#include <xrpl/protocol/TER.h>
43#include <xrpl/protocol/TxFlags.h>
44#include <xrpl/protocol/UintTypes.h>
45#include <xrpl/protocol/jss.h>
46
47#include <memory>
48
49namespace ripple {
50namespace test {
51namespace jtx {
52
53//------------------------------------------------------------------------------
54
60 : AppBundle()
61{
62 using namespace beast::severities;
63 if (logs)
64 {
65 setDebugLogSink(logs->makeSink("Debug", kFatal));
66 }
67 else
68 {
69 logs = std::make_unique<SuiteLogs>(suite);
70 // Use kFatal threshold to reduce noise from STObject.
73 }
74 auto timeKeeper_ = std::make_unique<ManualTimeKeeper>();
75 timeKeeper = timeKeeper_.get();
76 // Hack so we don't have to call Config::setup
78 config->SSL_VERIFY_DIR,
79 config->SSL_VERIFY_FILE,
80 config->SSL_VERIFY,
81 debugLog());
83 std::move(config), std::move(logs), std::move(timeKeeper_));
84 app = owned.get();
85 app->logs().threshold(thresh);
86 if (!app->setup({}))
87 Throw<std::runtime_error>("Env::AppBundle: setup failed");
88 timeKeeper->set(app->getLedgerMaster().getClosedLedger()->info().closeTime);
89 app->start(false /*don't start timers*/);
90 thread = std::thread([&]() { app->run(); });
91
93}
94
96{
97 client.reset();
98 // Make sure all jobs finish, otherwise tests
99 // might not get the coverage they expect.
100 if (app)
101 {
103 app->signalStop("~AppBundle");
104 }
105 if (thread.joinable())
106 thread.join();
107
108 // Remove the debugLogSink before the suite goes out of scope.
109 setDebugLogSink(nullptr);
110}
111
112//------------------------------------------------------------------------------
113
116{
118}
119
120bool
122 NetClock::time_point closeTime,
124{
125 // Round up to next distinguishable value
126 using namespace std::chrono_literals;
127 bool res = true;
128 closeTime += closed()->info().closeTimeResolution - 1s;
129 timeKeeper().set(closeTime);
130 // Go through the rpc interface unless we need to simulate
131 // a specific consensus delay.
132 if (consensusDelay)
133 app().getOPs().acceptLedger(consensusDelay);
134 else
135 {
136 auto resp = rpc("ledger_accept");
137 if (resp["result"]["status"] != std::string("success"))
138 {
139 std::string reason = "internal error";
140 if (resp.isMember("error_what"))
141 reason = resp["error_what"].asString();
142 else if (resp.isMember("error_message"))
143 reason = resp["error_message"].asString();
144 else if (resp.isMember("error"))
145 reason = resp["error"].asString();
146
147 JLOG(journal.error()) << "Env::close() failed: " << reason;
148 res = false;
149 }
150 }
151 timeKeeper().set(closed()->info().closeTime);
152 return res;
153}
154
155void
156Env::memoize(Account const& account)
157{
158 map_.emplace(account.id(), account);
159}
160
161Account const&
162Env::lookup(AccountID const& id) const
163{
164 auto const iter = map_.find(id);
165 if (iter == map_.end())
166 {
167 std::cout << "Unknown account: " << id << "\n";
168 Throw<std::runtime_error>("Env::lookup:: unknown account ID");
169 }
170 return iter->second;
171}
172
173Account const&
174Env::lookup(std::string const& base58ID) const
175{
176 auto const account = parseBase58<AccountID>(base58ID);
177 if (!account)
178 Throw<std::runtime_error>("Env::lookup: invalid account ID");
179 return lookup(*account);
180}
181
183Env::balance(Account const& account) const
184{
185 auto const sle = le(account);
186 if (!sle)
187 return XRP(0);
188 return {sle->getFieldAmount(sfBalance), ""};
189}
190
192Env::balance(Account const& account, Issue const& issue) const
193{
194 if (isXRP(issue.currency))
195 return balance(account);
196 auto const sle = le(keylet::line(account.id(), issue));
197 if (!sle)
198 return {STAmount(issue, 0), account.name()};
199 auto amount = sle->getFieldAmount(sfBalance);
200 amount.setIssuer(issue.account);
201 if (account.id() > issue.account)
202 amount.negate();
203 return {amount, lookup(issue.account).name()};
204}
205
207Env::balance(Account const& account, MPTIssue const& mptIssue) const
208{
209 MPTID const id = mptIssue.getMptID();
210 if (!id)
211 return {STAmount(mptIssue, 0), account.name()};
212
213 AccountID const issuer = mptIssue.getIssuer();
214 if (account.id() == issuer)
215 {
216 // Issuer balance
217 auto const sle = le(keylet::mptIssuance(id));
218 if (!sle)
219 return {STAmount(mptIssue, 0), account.name()};
220
221 // Make it negative
222 STAmount const amount{
223 mptIssue, sle->getFieldU64(sfOutstandingAmount), 0, true};
224 return {amount, lookup(issuer).name()};
225 }
226 else
227 {
228 // Holder balance
229 auto const sle = le(keylet::mptoken(id, account));
230 if (!sle)
231 return {STAmount(mptIssue, 0), account.name()};
232
233 STAmount const amount{mptIssue, sle->getFieldU64(sfMPTAmount)};
234 return {amount, lookup(issuer).name()};
235 }
236}
237
239Env::balance(Account const& account, Asset const& asset) const
240{
241 return std::visit(
242 [&](auto const& issue) { return balance(account, issue); },
243 asset.value());
244}
245
247Env::limit(Account const& account, Issue const& issue) const
248{
249 auto const sle = le(keylet::line(account.id(), issue));
250 if (!sle)
251 return {STAmount(issue, 0), account.name()};
252 auto const aHigh = account.id() > issue.account;
253 if (sle && sle->isFieldPresent(aHigh ? sfLowLimit : sfHighLimit))
254 return {(*sle)[aHigh ? sfLowLimit : sfHighLimit], account.name()};
255 return {STAmount(issue, 0), account.name()};
256}
257
259Env::ownerCount(Account const& account) const
260{
261 auto const sle = le(account);
262 if (!sle)
263 Throw<std::runtime_error>("missing account root");
264 return sle->getFieldU32(sfOwnerCount);
265}
266
268Env::seq(Account const& account) const
269{
270 auto const sle = le(account);
271 if (!sle)
272 Throw<std::runtime_error>("missing account root");
273 return sle->getFieldU32(sfSequence);
274}
275
277Env::le(Account const& account) const
278{
279 return le(keylet::account(account.id()));
280}
281
283Env::le(Keylet const& k) const
284{
285 return current()->read(k);
286}
287
288void
289Env::fund(bool setDefaultRipple, STAmount const& amount, Account const& account)
290{
291 memoize(account);
292 if (setDefaultRipple)
293 {
294 // VFALCO NOTE Is the fee formula correct?
295 apply(
296 pay(master, account, amount + drops(current()->fees().base)),
300 apply(
301 fset(account, asfDefaultRipple),
305 require(flags(account, asfDefaultRipple));
306 }
307 else
308 {
309 apply(
310 pay(master, account, amount),
315 }
316 require(jtx::balance(account, amount));
317}
318
319void
320Env::trust(STAmount const& amount, Account const& account)
321{
322 auto const start = balance(account);
323 apply(
324 jtx::trust(account, amount),
328 apply(
329 pay(master, account, drops(current()->fees().base)),
333 test.expect(balance(account) == start);
334}
335
338{
339 auto error = [](ParsedResult& parsed, Json::Value const& object) {
340 // Use an error code that is not used anywhere in the transaction
341 // engine to distinguish this case.
342 parsed.ter = telENV_RPC_FAILED;
343 // Extract information about the error
344 if (!object.isObject())
345 return;
346 if (object.isMember(jss::error_code))
347 parsed.rpcCode =
348 safe_cast<error_code_i>(object[jss::error_code].asInt());
349 if (object.isMember(jss::error_message))
350 parsed.rpcMessage = object[jss::error_message].asString();
351 if (object.isMember(jss::error))
352 parsed.rpcError = object[jss::error].asString();
353 if (object.isMember(jss::error_exception))
354 parsed.rpcException = object[jss::error_exception].asString();
355 };
356 ParsedResult parsed;
357 if (jr.isObject() && jr.isMember(jss::result))
358 {
359 auto const& result = jr[jss::result];
360 if (result.isMember(jss::engine_result_code))
361 {
362 parsed.ter = TER::fromInt(result[jss::engine_result_code].asInt());
363 parsed.rpcCode.emplace(rpcSUCCESS);
364 }
365 else
366 error(parsed, result);
367 }
368 else
369 error(parsed, jr);
370
371 return parsed;
372}
373
374void
376{
377 ParsedResult parsedResult;
378 auto const jr = [&]() {
379 if (jt.stx)
380 {
381 txid_ = jt.stx->getTransactionID();
382 Serializer s;
383 jt.stx->add(s);
384 auto const jr = rpc("submit", strHex(s.slice()));
385
386 parsedResult = parseResult(jr);
387 test.expect(parsedResult.ter, "ter uninitialized!");
388 ter_ = parsedResult.ter.value_or(telENV_RPC_FAILED);
389
390 return jr;
391 }
392 else
393 {
394 // Parsing failed or the JTx is
395 // otherwise missing the stx field.
396 parsedResult.ter = ter_ = temMALFORMED;
397
398 return Json::Value();
399 }
400 }();
401 return postconditions(jt, parsedResult, jr);
402}
403
404void
406{
407 auto const account = lookup(jt.jv[jss::Account].asString());
408 auto const& passphrase = account.name();
409
410 Json::Value jr;
411 if (params.isNull())
412 {
413 // Use the command line interface
414 auto const jv = boost::lexical_cast<std::string>(jt.jv);
415 jr = rpc("submit", passphrase, jv);
416 }
417 else
418 {
419 // Use the provided parameters, and go straight
420 // to the (RPC) client.
421 assert(params.isObject());
422 if (!params.isMember(jss::secret) && !params.isMember(jss::key_type) &&
423 !params.isMember(jss::seed) && !params.isMember(jss::seed_hex) &&
424 !params.isMember(jss::passphrase))
425 {
426 params[jss::secret] = passphrase;
427 }
428 params[jss::tx_json] = jt.jv;
429 jr = client().invoke("submit", params);
430 }
431
432 if (!txid_.parseHex(jr[jss::result][jss::tx_json][jss::hash].asString()))
433 txid_.zero();
434
435 ParsedResult const parsedResult = parseResult(jr);
436 test.expect(parsedResult.ter, "ter uninitialized!");
437 ter_ = parsedResult.ter.value_or(telENV_RPC_FAILED);
438
439 return postconditions(jt, parsedResult, jr);
440}
441
442void
444 JTx const& jt,
445 ParsedResult const& parsed,
446 Json::Value const& jr)
447{
448 bool bad = !test.expect(parsed.ter, "apply: No ter result!");
449 bad =
450 (jt.ter && parsed.ter &&
451 !test.expect(
452 *parsed.ter == *jt.ter,
453 "apply: Got " + transToken(*parsed.ter) + " (" +
454 transHuman(*parsed.ter) + "); Expected " +
455 transToken(*jt.ter) + " (" + transHuman(*jt.ter) + ")"));
456 using namespace std::string_literals;
457 bad = (jt.rpcCode &&
458 !test.expect(
459 parsed.rpcCode == jt.rpcCode->first &&
460 parsed.rpcMessage == jt.rpcCode->second,
461 "apply: Got RPC result "s +
462 (parsed.rpcCode
464 : "NO RESULT") +
465 " (" + parsed.rpcMessage + "); Expected " +
466 RPC::get_error_info(jt.rpcCode->first).token.c_str() + " (" +
467 jt.rpcCode->second + ")")) ||
468 bad;
469 // If we have an rpcCode (just checked), then the rpcException check is
470 // optional - the 'error' field may not be defined, but if it is, it must
471 // match rpcError.
472 bad =
473 (jt.rpcException &&
474 !test.expect(
475 (jt.rpcCode && parsed.rpcError.empty()) ||
476 (parsed.rpcError == jt.rpcException->first &&
477 (!jt.rpcException->second ||
478 parsed.rpcException == *jt.rpcException->second)),
479 "apply: Got RPC result "s + parsed.rpcError + " (" +
480 parsed.rpcException + "); Expected " + jt.rpcException->first +
481 " (" + jt.rpcException->second.value_or("n/a") + ")")) ||
482 bad;
483 if (bad)
484 {
485 test.log << pretty(jt.jv) << std::endl;
486 if (jr)
487 test.log << pretty(jr) << std::endl;
488 // Don't check postconditions if
489 // we didn't get the expected result.
490 return;
491 }
492 if (trace_)
493 {
494 if (trace_ > 0)
495 --trace_;
496 test.log << pretty(jt.jv) << std::endl;
497 }
498 for (auto const& f : jt.require)
499 f(*this);
500}
501
504{
505 if (current()->txCount() != 0)
506 {
507 // close the ledger if it has not already been closed
508 // (metadata is not finalized until the ledger is closed)
509 close();
510 }
511 auto const item = closed()->txRead(txid_);
512 auto const result = item.second;
513 if (result == nullptr)
514 {
515 test.log << "Env::meta: no metadata for txid: " << txid_ << std::endl;
516 test.log << "This is probably because the transaction failed with a "
517 "non-tec error."
518 << std::endl;
519 Throw<std::runtime_error>("Env::meta: no metadata for txid");
520 }
521 return result;
522}
523
525Env::tx() const
526{
527 return current()->txRead(txid_).first;
528}
529
530void
532{
533 auto& jv = jt.jv;
534 if (jt.signer)
535 return jt.signer(*this, jt);
536 if (!jt.fill_sig)
537 return;
538 auto const account = jv.isMember(sfDelegate.jsonName)
539 ? lookup(jv[sfDelegate.jsonName].asString())
540 : lookup(jv[jss::Account].asString());
541 if (!app().checkSigs())
542 {
543 jv[jss::SigningPubKey] = strHex(account.pk().slice());
544 // dummy sig otherwise STTx is invalid
545 jv[jss::TxnSignature] = "00";
546 return;
547 }
548 auto const ar = le(account);
549 if (ar && ar->isFieldPresent(sfRegularKey))
550 jtx::sign(jv, lookup(ar->getAccountID(sfRegularKey)));
551 else
552 jtx::sign(jv, account);
553}
554
555void
557{
558 auto& jv = jt.jv;
559 if (jt.fill_fee)
560 jtx::fill_fee(jv, *current());
561 if (jt.fill_seq)
562 jtx::fill_seq(jv, *current());
563
564 if (jt.fill_netid)
565 {
566 uint32_t networkID = app().config().NETWORK_ID;
567 if (!jv.isMember(jss::NetworkID) && networkID > 1024)
568 jv[jss::NetworkID] = std::to_string(networkID);
569 }
570
571 // Must come last
572 try
573 {
575 }
576 catch (parse_error const&)
577 {
579 test.log << "parse failed:\n" << pretty(jv) << std::endl;
580 Rethrow();
581 }
582}
583
586{
587 // The parse must succeed, since we
588 // generated the JSON ourselves.
590 try
591 {
592 obj = jtx::parse(jt.jv);
593 }
594 catch (jtx::parse_error const&)
595 {
596 test.log << "Exception: parse_error\n" << pretty(jt.jv) << std::endl;
597 Rethrow();
598 }
599
600 try
601 {
602 return sterilize(STTx{std::move(*obj)});
603 }
604 catch (std::exception const&)
605 {
606 }
607 return nullptr;
608}
609
612{
613 // The parse must succeed, since we
614 // generated the JSON ourselves.
616 try
617 {
618 obj = jtx::parse(jt.jv);
619 }
620 catch (jtx::parse_error const&)
621 {
622 test.log << "Exception: parse_error\n" << pretty(jt.jv) << std::endl;
623 Rethrow();
624 }
625
626 try
627 {
628 return std::make_shared<STTx const>(std::move(*obj));
629 }
630 catch (std::exception const&)
631 {
632 }
633 return nullptr;
634}
635
638 unsigned apiVersion,
639 std::vector<std::string> const& args,
641{
642 auto response =
643 rpcClient(args, app().config(), app().logs(), apiVersion, headers);
644
645 for (unsigned ctr = 0; (ctr < retries_) and (response.first == rpcINTERNAL);
646 ++ctr)
647 {
648 JLOG(journal.error())
649 << "Env::do_rpc error, retrying, attempt #" << ctr + 1 << " ...";
651
652 response =
653 rpcClient(args, app().config(), app().logs(), apiVersion, headers);
654 }
655
656 return response.second;
657}
658
659void
661{
662 // Env::close() must be called for feature
663 // enable to take place.
664 app().config().features.insert(feature);
665}
666
667void
669{
670 // Env::close() must be called for feature
671 // enable to take place.
672 app().config().features.erase(feature);
673}
674
675} // namespace jtx
676} // namespace test
677} // namespace ripple
constexpr char const * c_str() const
Definition json_value.h:76
Represents a JSON value.
Definition json_value.h:149
bool isObject() const
std::string asString() const
Returns the unquoted string value.
bool isNull() const
isNull() tests to see if this field is null.
bool isMember(char const *key) const
Return true if the object has a member named key.
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 LedgerMaster & getLedgerMaster()=0
virtual Logs & logs()=0
virtual void signalStop(std::string msg)=0
constexpr value_type const & value() const
Definition Asset.h:156
uint32_t NETWORK_ID
Definition Config.h:156
std::unordered_set< uint256, beast::uhash<> > features
Definition Config.h:276
static void initializeSSLContext(std::string const &sslVerifyDir, std::string const &sslVerifyFile, bool sslVerify, beast::Journal j)
A currency issued by an account.
Definition Issue.h:33
AccountID account
Definition Issue.h:36
Currency currency
Definition Issue.h:35
void rendezvous()
Block until no jobs running.
Definition JobQueue.cpp:273
std::shared_ptr< Ledger const > getClosedLedger()
beast::severities::Severity threshold() const
Definition Log.cpp:166
AccountID const & getIssuer() const
Definition MPTIssue.cpp:40
constexpr MPTID const & getMptID() const
Definition MPTIssue.h:46
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:66
static constexpr TERSubset fromInt(int from)
Definition TER.h:429
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:87
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition Env.cpp:115
void disableFeature(uint256 const feature)
Definition Env.cpp:668
bool parseFailureExpected_
Definition Env.h:743
static ParsedResult parseResult(Json::Value const &jr)
Gets the TER result and didApply flag from a RPC Json result object.
Definition Env.cpp:337
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition Env.cpp:259
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition Env.cpp:268
std::unordered_map< AccountID, Account > map_
Definition Env.h:786
beast::unit_test::suite & test
Definition Env.h:123
PrettyAmount limit(Account const &account, Issue const &issue) const
Returns the IOU limit on an account.
Definition Env.cpp:247
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition Env.cpp:525
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:443
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:405
virtual void autofill(JTx &jt)
Definition Env.cpp:556
AbstractClient & client()
Returns the connected client.
Definition Env.h:291
void autofill_sig(JTx &jt)
Definition Env.cpp:531
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition Env.cpp:320
Json::Value do_rpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition Env.cpp:637
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:585
void enableFeature(uint256 const feature)
Definition Env.cpp:660
Account const & master
Definition Env.h:125
Account const & lookup(AccountID const &id) const
Returns the Account given the AccountID.
Definition Env.cpp:162
unsigned retries_
Definition Env.h:744
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition Env.h:508
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:611
Application & app()
Definition Env.h:261
beast::Journal const journal
Definition Env.h:162
ManualTimeKeeper & timeKeeper()
Definition Env.h:273
virtual void submit(JTx const &jt)
Submit an existing JTx.
Definition Env.cpp:375
Env & apply(JsonValue &&jv, FN const &... fN)
Apply funclets and submit.
Definition Env.h:582
bool close()
Close and advance the ledger.
Definition Env.h:393
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:289
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition Env.cpp:503
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
Definition Env.cpp:183
void memoize(Account const &account)
Associate AccountID with account.
Definition Env.cpp:156
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition Env.cpp:277
A balance matches.
Definition balance.h:39
Set the fee on a JTx.
Definition fee.h:37
Match set account flags.
Definition flags.h:128
Match clear account flags.
Definition flags.h:145
Check a set of conditions.
Definition require.h:66
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)
T is_same_v
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.
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:540
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:244
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Definition Indexes.cpp:526
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:184
void fill_seq(Json::Value &jv, ReadView const &view)
Set the sequence number automatically.
Definition utility.cpp:66
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:32
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Definition flags.cpp:29
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Definition pay.cpp:30
void sign(Json::Value &jv, Account const &account)
Sign automatically.
Definition utility.cpp:47
STObject parse(Json::Value const &jv)
Convert JSON to STObject.
Definition utility.cpp:38
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:111
void fill_fee(Json::Value &jv, ReadView const &view)
Set the fee automatically.
Definition utility.cpp:58
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:25
std::string transHuman(TER code)
Definition TER.cpp:273
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Definition STTx.cpp:811
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:1480
bool isXRP(AccountID const &c)
Definition AccountID.h:90
@ 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:264
constexpr std::uint32_t asfDefaultRipple
Definition TxFlags.h:84
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:220
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
std::optional< TER > ter
Definition Env.h:130
Execution context for applying a JSON transaction.
Definition JTx.h:45
std::optional< std::pair< error_code_i, std::string > > rpcCode
Definition JTx.h:49
std::shared_ptr< STTx const > stx
Definition JTx.h:56
Json::Value jv
Definition JTx.h:46
std::optional< std::pair< std::string, std::optional< std::string > > > rpcException
Definition JTx.h:51
std::function< void(Env &, JTx &)> signer
Definition JTx.h:57
requires_t require
Definition JTx.h:47
std::optional< TER > ter
Definition JTx.h:48
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
Thrown when parse fails.
Definition utility.h:39
Set the sequence number on a JTx.
Definition seq.h:34
T to_string(T... args)
T value_or(T... args)
T visit(T... args)