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