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