xrpld
Loading...
Searching...
No Matches
Env.cpp
1#include <test/jtx/Env.h>
2
3#include <test/jtx/Account.h>
4#include <test/jtx/JSONRPCClient.h>
5#include <test/jtx/JTx.h>
6#include <test/jtx/ManualTimeKeeper.h>
7#include <test/jtx/amount.h>
8#include <test/jtx/balance.h>
9#include <test/jtx/fee.h>
10#include <test/jtx/flags.h>
11#include <test/jtx/pay.h>
12#include <test/jtx/seq.h>
13#include <test/jtx/sig.h>
14#include <test/jtx/tags.h>
15#include <test/jtx/trust.h>
16#include <test/jtx/utility.h>
17#include <test/unit_test/SuiteJournal.h>
18
19#include <xrpld/app/ledger/LedgerMaster.h>
20#include <xrpld/app/main/Application.h>
21#include <xrpld/core/Config.h>
22#include <xrpld/rpc/RPCCall.h>
23
24#include <xrpl/basics/Log.h>
25#include <xrpl/basics/Number.h>
26#include <xrpl/basics/chrono.h>
27#include <xrpl/basics/contract.h>
28#include <xrpl/basics/safe_cast.h>
29#include <xrpl/basics/scope.h>
30#include <xrpl/basics/strHex.h>
31#include <xrpl/beast/unit_test/suite.h>
32#include <xrpl/beast/utility/Journal.h>
33#include <xrpl/core/NetworkIDService.h>
34#include <xrpl/core/ServiceRegistry.h>
35#include <xrpl/json/to_string.h>
36#include <xrpl/net/HTTPClient.h>
37#include <xrpl/protocol/AccountID.h>
38#include <xrpl/protocol/Asset.h>
39#include <xrpl/protocol/ErrorCodes.h>
40#include <xrpl/protocol/Indexes.h>
41#include <xrpl/protocol/Issue.h>
42#include <xrpl/protocol/Keylet.h>
43#include <xrpl/protocol/MPTIssue.h>
44#include <xrpl/protocol/SField.h>
45#include <xrpl/protocol/STTx.h>
46#include <xrpl/protocol/Serializer.h>
47#include <xrpl/protocol/TER.h>
48#include <xrpl/protocol/TxFlags.h>
49#include <xrpl/protocol/UintTypes.h>
50#include <xrpl/protocol/jss.h>
51#include <xrpl/server/NetworkOPs.h>
52
53#include <cassert>
54#include <chrono>
55#include <cstdint>
56#include <iostream>
57#include <memory>
58#include <optional>
59#include <ostream>
60#include <source_location>
61#include <stdexcept>
62#include <string>
63#include <thread>
64#include <unordered_map>
65#include <utility>
66#include <vector>
67
68namespace xrpl::test::jtx {
69
70//------------------------------------------------------------------------------
71
76 beast::Severity thresh)
77 : AppBundle()
78{
79 using beast::Severity;
80 if (logs)
81 {
82 setDebugLogSink(logs->makeSink("Debug", Severity::Fatal));
83 }
84 else
85 {
86 logs = std::make_unique<SuiteLogs>(suite);
87 // Use kFatal threshold to reduce noise from STObject.
88 setDebugLogSink(std::make_unique<SuiteJournalSink>("Debug", Severity::Fatal, suite));
89 }
91 timeKeeper = tk.get();
92 // Hack so we don't have to call Config::setup
94 config->sslVerifyDir, config->sslVerifyFile, config->sslVerify, debugLog());
95 owned = makeApplication(std::move(config), std::move(logs), std::move(tk));
96 app = owned.get();
97 app->getLogs().threshold(thresh);
98 if (!app->setup({}))
99 Throw<std::runtime_error>("Env::AppBundle: setup failed");
100 timeKeeper->set(app->getLedgerMaster().getClosedLedger()->header().closeTime);
101 app->start(false /*don't start timers*/);
102 thread = std::thread([&]() { app->run(); });
103
104 client = makeJSONRPCClient(app->config());
105}
106
108{
109 client.reset();
110 // Make sure all jobs finish, otherwise tests
111 // might not get the coverage they expect.
112 if (app != nullptr)
113 {
114 app->getJobQueue().rendezvous();
115 app->signalStop("~AppBundle");
116 }
117 if (thread.joinable())
118 thread.join();
119
120 // Remove the debugLogSink before the suite goes out of scope.
121 setDebugLogSink(nullptr);
122}
123
124//------------------------------------------------------------------------------
125
128{
130}
131
132bool
134{
135 // Round up to next distinguishable value
136 using namespace std::chrono_literals;
137 bool res = true;
138 closeTime += closed()->header().closeTimeResolution - 1s;
139 timeKeeper().set(closeTime);
140 // Go through the rpc interface unless we need to simulate
141 // a specific consensus delay.
142 if (consensusDelay)
143 {
144 app().getOPs().acceptLedger(consensusDelay);
145 }
146 else
147 {
148 auto resp = rpc("ledger_accept");
149 if (resp["result"]["status"] != std::string("success"))
150 {
151 std::string reason = "internal error";
152 if (resp.isMember("error_what"))
153 {
154 reason = resp["error_what"].asString();
155 }
156 else if (resp.isMember("error_message"))
157 {
158 reason = resp["error_message"].asString();
159 }
160 else if (resp.isMember("error"))
161 {
162 reason = resp["error"].asString();
163 }
164
165 JLOG(journal.error()) << "Env::close() failed: " << reason;
166 res = false;
167 }
168 }
169 timeKeeper().set(closed()->header().closeTime);
170 return res;
171}
172
173void
174Env::memoize(Account const& account)
175{
176 map_.emplace(account.id(), account);
177}
178
179Account const&
180Env::lookup(AccountID const& id) const
181{
182 auto const iter = map_.find(id);
183 if (iter == map_.end())
184 {
185 std::cout << "Unknown account: " << id << "\n";
186 Throw<std::runtime_error>("Env::lookup:: unknown account ID");
187 }
188 return iter->second;
189}
190
191Account const&
192Env::lookup(std::string const& base58ID) const
193{
194 auto const account = parseBase58<AccountID>(base58ID);
195 if (!account)
196 Throw<std::runtime_error>("Env::lookup: invalid account ID");
197 return lookup(*account);
198}
199
201Env::balance(Account const& account) const
202{
203 auto const sle = le(account);
204 if (!sle)
205 return XRP(0);
206 return {sle->getFieldAmount(sfBalance), ""};
207}
208
210Env::balance(Account const& account, Asset const& asset) const
211{
212 return asset.visit(
213 [&](Issue const& issue) -> PrettyAmount {
214 if (isXRP(issue.currency))
215 return balance(account);
216 auto const sle = le(keylet::trustLine(account.id(), issue));
217 if (!sle)
218 return {STAmount(issue, 0), account.name()};
219 auto amount = sle->getFieldAmount(sfBalance);
220 amount.get<Issue>().account = issue.account;
221 if (account.id() > issue.account)
222 amount.negate();
223 return {amount, lookup(issue.account).name()};
224 },
225 [&](MPTIssue const& mptIssue) -> PrettyAmount {
226 MPTID const& id = mptIssue.getMptID();
227 if (!id)
228 return {STAmount(mptIssue, 0), account.name()};
229
230 AccountID const& issuer = mptIssue.getIssuer();
231 if (account.id() == issuer)
232 {
233 // Issuer balance
234 auto const sle = le(keylet::mptokenIssuance(id));
235 if (!sle)
236 return {STAmount(mptIssue, 0), account.name()};
237
238 // Make it negative
239 STAmount const amount{mptIssue, sle->getFieldU64(sfOutstandingAmount), 0, true};
240 return {amount, lookup(issuer).name()};
241 }
242
243 // Holder balance
244 auto const sle = le(keylet::mptoken(id, account));
245 if (!sle)
246 return {STAmount(mptIssue, 0), account.name()};
247
248 STAmount const amount{mptIssue, sle->getFieldU64(sfMPTAmount)};
249 return {amount, lookup(issuer).name()};
250 });
251}
252
254Env::limit(Account const& account, Issue const& issue) const
255{
256 auto const sle = le(keylet::trustLine(account.id(), issue));
257 if (!sle)
258 return {STAmount(issue, 0), account.name()};
259 auto const aHigh = account.id() > issue.account;
260 if (sle && sle->isFieldPresent(aHigh ? sfLowLimit : sfHighLimit))
261 return {(*sle)[aHigh ? sfLowLimit : sfHighLimit], account.name()};
262 return {STAmount(issue, 0), account.name()};
263}
264
266Env::ownerCount(Account const& account) const
267{
268 auto const sle = le(account);
269 if (!sle)
270 Throw<std::runtime_error>("missing account root");
271 return sle->getFieldU32(sfOwnerCount);
272}
273
276{
277 auto const sle = le(account);
278 if (!sle)
279 Throw<std::runtime_error>("missing account root");
280 return sle->getFieldU32(sfSponsoredOwnerCount);
281}
282
285{
286 auto const sle = le(account);
287 if (!sle)
288 Throw<std::runtime_error>("missing account root");
289 return sle->getFieldU32(sfSponsoringOwnerCount);
290}
291
294{
295 auto const sle = le(account);
296 if (!sle)
297 Throw<std::runtime_error>("missing account root");
298 return sle->getFieldU32(sfSponsoringAccountCount);
299}
300
302Env::seq(Account const& account) const
303{
304 auto const sle = le(account);
305 if (!sle)
306 Throw<std::runtime_error>("missing account root");
307 return sle->getFieldU32(sfSequence);
308}
309
311Env::le(Account const& account) const
312{
313 return le(keylet::account(account.id()));
314}
315
317Env::le(Keylet const& k) const
318{
319 return current()->read(k);
320}
321
322void
323Env::fund(bool setDefaultRipple, STAmount const& amount, Account const& account)
324{
325 memoize(account);
326 if (setDefaultRipple)
327 {
328 // VFALCO NOTE Is the fee formula correct?
329 apply(
330 pay(master, account, amount + drops(current()->fees().base)),
334 apply(
335 fset(account, asfDefaultRipple),
339 require(Flags(account, asfDefaultRipple));
340 }
341 else
342 {
343 apply(
344 pay(master, account, amount),
348 require(Nflags(account, asfDefaultRipple));
349 }
350 require(jtx::Balance(account, amount));
351}
352
353void
354Env::trust(STAmount const& amount, Account const& account)
355{
356 if (!amount.holds<Issue>())
357 Throw<std::runtime_error>("Env::trust: amount doesn't hold Issue");
358 auto const start = balance(account);
359 apply(
360 jtx::trust(account, amount),
364 apply(
365 pay(master, account, drops(current()->fees().base)),
369 test.expect(balance(account) == start);
370}
371
374{
375 auto error = [](ParsedResult& parsed, json::Value const& object) {
376 // Use an error code that is not used anywhere in the transaction
377 // engine to distinguish this case.
378 parsed.ter = telENV_RPC_FAILED;
379 // Extract information about the error
380 if (!object.isObject())
381 return;
382 if (object.isMember(jss::error_code))
383 parsed.rpcCode = safeCast<ErrorCodeI>(object[jss::error_code].asInt());
384 if (object.isMember(jss::error_message))
385 parsed.rpcMessage = object[jss::error_message].asString();
386 if (object.isMember(jss::error))
387 parsed.rpcError = object[jss::error].asString();
388 if (object.isMember(jss::error_exception))
389 parsed.rpcException = object[jss::error_exception].asString();
390 };
391 ParsedResult parsed;
392 if (jr.isObject() && jr.isMember(jss::result))
393 {
394 auto const& result = jr[jss::result];
395 if (result.isMember(jss::engine_result_code))
396 {
397 parsed.ter = TER::fromInt(result[jss::engine_result_code].asInt());
398 parsed.rpcCode.emplace(RpcSuccess);
399 }
400 else
401 {
402 error(parsed, result);
403 }
404 }
405 else
406 {
407 error(parsed, jr);
408 }
409
410 return parsed;
411}
412
413void
415{
416 ParsedResult parsedResult;
417 auto const jr = [&]() {
418 if (jt.stx)
419 {
420 txid_ = jt.stx->getTransactionID();
421 Serializer s;
422 jt.stx->add(s);
423 auto const jr = rpc("submit", strHex(s.slice()));
424
425 parsedResult = parseResult(jr);
426 test.expect(parsedResult.ter, "ter uninitialized!");
427 ter_ = parsedResult.ter.value_or(telENV_RPC_FAILED);
428
429 return jr;
430 }
431
432 // Parsing failed or the JTx is
433 // otherwise missing the stx field.
434 parsedResult.ter = ter_ = temMALFORMED;
435
436 return json::Value();
437 }();
438 postconditions(jt, parsedResult, jr, loc);
439}
440
441void
443{
444 auto const account = lookup(jt.jv[jss::Account].asString());
445 auto const& passphrase = account.name();
446
447 json::Value jr;
448 if (params.isNull())
449 {
450 // Use the command line interface
451 auto const jv = to_string(jt.jv);
452 jr = rpc("submit", passphrase, jv);
453 }
454 else
455 {
456 // Use the provided parameters, and go straight
457 // to the (RPC) client.
458 assert(params.isObject());
459 if (!params.isMember(jss::secret) && !params.isMember(jss::key_type) &&
460 !params.isMember(jss::seed) && !params.isMember(jss::seed_hex) &&
461 !params.isMember(jss::passphrase))
462 {
463 params[jss::secret] = passphrase;
464 }
465 params[jss::tx_json] = jt.jv;
466 jr = client().invoke("submit", params);
467 }
468
469 if (!txid_.parseHex(jr[jss::result][jss::tx_json][jss::hash].asString()))
470 txid_.zero();
471
472 ParsedResult const parsedResult = parseResult(jr);
473 test.expect(parsedResult.ter, "ter uninitialized!");
474 ter_ = parsedResult.ter.value_or(telENV_RPC_FAILED);
475
476 postconditions(jt, parsedResult, jr, loc);
477}
478
479void
481 JTx const& jt,
482 ParsedResult const& parsed,
483 json::Value const& jr,
484 std::source_location const& loc)
485{
486 auto const locStr = std::string("(") + loc.file_name() + ":" + to_string(loc.line()) + ")";
487 bool bad = !test.expect(parsed.ter, "apply " + locStr + ": No ter result!");
488 bad =
489 (jt.ter && parsed.ter &&
490 !test.expect(
491 *parsed.ter == *jt.ter,
492 "apply " + locStr + ": Got " + transToken(*parsed.ter) + " (" +
493 transHuman(*parsed.ter) + "); Expected " + transToken(*jt.ter) + " (" +
494 transHuman(*jt.ter) + ")"));
495 using namespace std::string_literals;
496 bad =
497 (jt.rpcCode &&
498 !test.expect(
499 parsed.rpcCode == jt.rpcCode->first && parsed.rpcMessage == jt.rpcCode->second,
500 "apply " + locStr + ": Got RPC result "s +
501 (parsed.rpcCode ? rpc::getErrorInfo(*parsed.rpcCode).token.cStr() : "NO RESULT") +
502 " (" + parsed.rpcMessage + "); Expected " +
503 rpc::getErrorInfo(jt.rpcCode->first).token.cStr() + " (" + jt.rpcCode->second +
504 ")")) ||
505 bad;
506 // If we have an rpcCode (just checked), then the rpcException check is
507 // optional - the 'error' field may not be defined, but if it is, it must
508 // match rpcError.
509 bad = (jt.rpcException &&
510 !test.expect(
511 (jt.rpcCode && parsed.rpcError.empty()) ||
512 (parsed.rpcError == jt.rpcException->first &&
513 (!jt.rpcException->second || parsed.rpcException == *jt.rpcException->second)),
514 "apply " + locStr + ": Got RPC result "s + parsed.rpcError + " (" +
515 parsed.rpcException + "); Expected " + jt.rpcException->first + " (" +
516 jt.rpcException->second.value_or("n/a") + ")")) ||
517 bad;
518 if (bad)
519 {
520 test.log << pretty(jt.jv) << std::endl;
521 if (jr)
522 test.log << pretty(jr) << std::endl;
523 // Don't check postconditions if
524 // we didn't get the expected result.
525 return;
526 }
527 if (trace_ != 0)
528 {
529 if (trace_ > 0)
530 --trace_;
531 test.log << pretty(jt.jv) << std::endl;
532 }
533 for (auto const& f : jt.require)
534 f(*this);
535}
536
539{
540 if (current()->txCount() != 0)
541 {
542 // close the ledger if it has not already been closed
543 // (metadata is not finalized until the ledger is closed)
544 close();
545 }
546 auto const item = closed()->txRead(txid_);
547 auto const result = item.second;
548 if (result == nullptr)
549 {
550 test.log << "Env::meta: no metadata for txid: " << txid_ << std::endl;
551 test.log << "This is probably because the transaction failed with a "
552 "non-tec error."
553 << std::endl;
554 Throw<std::runtime_error>("Env::meta: no metadata for txid");
555 }
556 return result;
557}
558
560Env::tx() const
561{
562 return current()->txRead(txid_).first;
563}
564
565void
567{
568 auto& jv = jt.jv;
569
570 ScopeSuccess const success([&]() {
571 // Call all the post-signers after the main signers or autofill are done
572 for (auto const& signer : jt.postSigners)
573 signer(*this, jt);
574 });
575
576 // Call all the main signers
577 if (!jt.mainSigners.empty())
578 {
579 for (auto const& signer : jt.mainSigners)
580 signer(*this, jt);
581 return;
582 }
583
584 // If the sig is still needed, get it here.
585 if (!jt.fillSig)
586 return;
587 auto const account = jv.isMember(sfDelegate.jsonName)
588 ? lookup(jv[sfDelegate.jsonName].asString())
589 : lookup(jv[jss::Account].asString());
590 if (!app().checkSigs())
591 {
592 jv[jss::SigningPubKey] = strHex(account.pk().slice());
593 // dummy sig otherwise STTx is invalid
594 jv[jss::TxnSignature] = "00";
595 return;
596 }
597 auto const ar = le(account);
598 if (ar && ar->isFieldPresent(sfRegularKey))
599 {
600 jtx::sign(jv, lookup(ar->getAccountID(sfRegularKey)));
601 }
602 else
603 {
604 jtx::sign(jv, account);
605 }
606}
607
608void
610{
611 auto& jv = jt.jv;
612 if (jt.fillFee)
613 jtx::fillFee(jv, *current());
614 if (jt.fillSeq)
615 jtx::fillSeq(jv, *current());
616
617 if (jt.fillNetid)
618 {
619 uint32_t const networkID = app().getNetworkIDService().getNetworkID();
620 if (!jv.isMember(jss::NetworkID) && networkID > 1024)
621 jv[jss::NetworkID] = std::to_string(networkID);
622 }
623
624 // Must come last
625 try
626 {
628 }
629 catch (ParseError const&)
630 {
632 test.log << "parse failure:\n" << pretty(jv) << std::endl;
633 rethrow();
634 }
635}
636
639{
640 // The parse must succeed, since we
641 // generated the JSON ourselves.
643 try
644 {
645 obj = jtx::parse(jt.jv);
646 }
647 catch (jtx::ParseError const&)
648 {
649 test.log << "Exception: ParseError\n" << pretty(jt.jv) << std::endl;
650 rethrow();
651 }
652
653 try
654 {
655 return sterilize(STTx{std::move(*obj)});
656 }
657 catch (...)
658 {
659 return nullptr;
660 }
661}
662
665{
666 // The parse must succeed, since we
667 // generated the JSON ourselves.
669 try
670 {
671 obj = jtx::parse(jt.jv);
672 }
673 catch (jtx::ParseError const&)
674 {
675 test.log << "Exception: ParseError\n" << pretty(jt.jv) << std::endl;
676 rethrow();
677 }
678
679 try
680 {
681 return std::make_shared<STTx const>(std::move(*obj));
682 }
683 catch (...)
684 {
685 return nullptr;
686 }
687}
688
691 unsigned apiVersion,
692 std::vector<std::string> const& args,
694{
695 auto response = rpcClient(args, app().config(), app().getLogs(), apiVersion, headers);
696
697 for (unsigned ctr = 0; (ctr < retries_) and (response.first == RpcInternal); ++ctr)
698 {
699 JLOG(journal.error()) << "Env::doRpc error, retrying, attempt #" << ctr + 1 << " ...";
701
702 response = rpcClient(args, app().config(), app().getLogs(), apiVersion, headers);
703 }
704
705 return response.second;
706}
707
708void
710{
711 // Env::close() must be called for feature
712 // enable to take place.
713 app().config().features.insert(feature);
714}
715
716void
718{
719 // Env::close() must be called for feature
720 // enable to take place.
721 app().config().features.erase(feature);
722}
723
724} // namespace xrpl::test::jtx
A testsuite class.
Definition suite.h:52
Represents a JSON value.
Definition json_value.h:117
bool isNull() const
isNull() tests to see if this field is null.
bool isObject() const
std::string asString() const
Returns the unquoted string value.
bool isMember(char const *key) const
Return true if the object has a member named key.
virtual Config & config()=0
constexpr auto visit(Visitors &&... visitors) const -> decltype(auto)
Definition Asset.h:117
std::unordered_set< uint256, beast::Uhash<> > features
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:18
Currency currency
Definition Issue.h:20
AccountID account
Definition Issue.h:21
std::shared_ptr< Ledger const > getClosedLedger()
std::chrono::time_point< NetClock > time_point
Definition chrono.h:48
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.
constexpr bool holds() const noexcept
Definition STAmount.h:478
std::shared_ptr< STLedgerEntry const > const_pointer
Slice slice() const noexcept
Definition Serializer.h:45
virtual NetworkOPs & getOPs()=0
virtual NetworkIDService & getNetworkIDService()=0
virtual LedgerMaster & getLedgerMaster()=0
static constexpr TERSubset fromInt(int from)
Definition TER.h:437
virtual json::Value invoke(std::string const &cmd, json::Value const &params={})=0
Submit a command synchronously.
Immutable cryptographic account descriptor.
Definition jtx/Account.h:21
std::string const & name() const
Return the name.
Definition jtx/Account.h:75
A balance matches.
Definition balance.h:24
Application & app()
Definition Env.h:300
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:638
std::uint32_t sponsoringAccountCount(Account const &account) const
Return the number of sponsoring accounts owned by an account.
Definition Env.cpp:293
std::uint32_t sponsoringOwnerCount(Account const &account) const
Return the number of sponsoring objects owned by an account.
Definition Env.cpp:284
SLE::const_pointer le(Account const &account) const
Return an account root.
Definition Env.cpp:311
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition Env.cpp:266
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition Env.cpp:127
static ParsedResult parseResult(json::Value const &jr)
Gets the TER result and didApply flag from a RPC Json result object.
Definition Env.cpp:373
Account const & lookup(AccountID const &id) const
Returns the Account given the AccountID.
Definition Env.cpp:180
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:323
virtual void submit(JTx const &jt, std::source_location const &loc=std::source_location::current())
Submit an existing JTx.
Definition Env.cpp:414
void enableFeature(uint256 const feature)
Definition Env.cpp:709
PrettyAmount limit(Account const &account, Issue const &issue) const
Returns the IOU limit on an account.
Definition Env.cpp:254
void disableFeature(uint256 const feature)
Definition Env.cpp:717
json::Value doRpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition Env.cpp:690
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition Env.cpp:302
virtual void autofill(JTx &jt)
Definition Env.cpp:609
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:480
bool close()
Close and advance the ledger.
Definition Env.h:443
Account const & master
Definition Env.h:165
json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition Env.h:1056
void autofillSig(JTx &jt)
Definition Env.cpp:566
void signAndSubmit(JTx const &jt, json::Value params=json::ValueType::Null, std::source_location const &loc=std::source_location::current())
Use the submit RPC command with a provided JTx object.
Definition Env.cpp:442
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition Env.h:721
std::uint32_t sponsoredOwnerCount(Account const &account) const
Return the number of sponsored objects owned by an account.
Definition Env.cpp:275
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
Definition Env.cpp:201
unsigned retries_
Definition Env.h:1008
beast::unit_test::Suite & test
Definition Env.h:163
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition Env.cpp:354
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:664
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition Env.cpp:538
Env & apply(WithSourceLocation< json::Value > jv, FN const &... fN)
Apply funclets and submit.
Definition Env.h:809
std::unordered_map< AccountID, Account > map_
Definition Env.h:1051
ManualTimeKeeper & timeKeeper()
Definition Env.h:313
bool parseFailureExpected_
Definition Env.h:1007
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition Env.cpp:560
void memoize(Account const &account)
Associate AccountID with account.
Definition Env.cpp:174
beast::Journal const journal
Definition Env.h:204
AbstractClient & client()
Returns the connected client.
Definition Env.h:336
void require(Args const &... args)
Check a set of requirements.
Definition Env.h:764
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:377
Set the fee on a JTx.
Definition fee.h:20
Match set account flags.
Definition flags.h:119
Match clear account flags.
Definition flags.h:137
Set the regular signature on a JTx.
Definition sig.h:19
T emplace(T... args)
T empty(T... args)
T endl(T... args)
T file_name(T... args)
T make_shared(T... args)
T make_unique(T... args)
Severity
Severity level / threshold of a Journal message.
Definition Journal.h:16
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:543
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:198
Keylet mptokenIssuance(MPTID const &issuanceID) noexcept
Definition Indexes.cpp:537
Keylet trustLine(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition Indexes.cpp:253
ErrorInfo const & getErrorInfo(ErrorCodeI code)
Returns an ErrorInfo that reflects the error code.
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Definition pay.cpp:14
void fillFee(json::Value &jv, ReadView const &view)
Set the fee automatically.
Definition utility.cpp:57
XrpT const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:92
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:40
json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Definition trust.cpp:18
static AutofillT const kAutofill
Definition tags.h:15
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
STObject parse(json::Value const &jv)
Convert JSON to STObject.
Definition utility.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:15
void fillSeq(json::Value &jv, ReadView const &view)
Set the sequence number automatically.
Definition utility.cpp:80
std::unique_ptr< AbstractClient > makeJSONRPCClient(Config const &cfg, unsigned rpcVersion)
Returns a client using JSON-RPC over HTTP/S.
@ telENV_RPC_FAILED
Definition TER.h:54
@ RpcInternal
Definition ErrorCodes.h:113
@ RpcSuccess
Definition ErrorCodes.h:27
bool isXRP(AccountID const &c)
Definition AccountID.h:84
std::optional< AccountID > parseBase58(std::string const &s)
Parse AccountID from checked, base58 string.
beast::Journal debugLog()
Returns a debug journal.
Definition Log.cpp:399
std::unique_ptr< beast::Journal::Sink > setDebugLogSink(std::unique_ptr< beast::Journal::Sink > sink)
Set the sink for the debug journal.
Definition Log.cpp:393
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:13
std::string transHuman(TER code)
Definition TER.cpp:260
constexpr Dest safeCast(Src s) noexcept
Definition safe_cast.h:21
std::string transToken(TER code)
Definition TER.cpp:251
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
XRPL_NO_SANITIZE_ADDRESS void rethrow()
Rethrow the exception currently being handled.
Definition contract.h:36
BaseUInt< 192 > MPTID
MPTID is a 192-bit value representing MPT Issuance ID, which is a concatenation of a 32-bit sequence ...
Definition UintTypes.h:54
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:1664
std::unique_ptr< Application > makeApplication(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
@ temMALFORMED
Definition TER.h:75
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Definition STTx.cpp:877
BaseUInt< 256 > uint256
Definition base_uint.h:580
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
T sleep_for(T... args)
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20
ManualTimeKeeper * timeKeeper
Definition Env.h:188
std::unique_ptr< AbstractClient > client
Definition Env.h:190
std::unique_ptr< Application > owned
Definition Env.h:187
Used by parseResult() and postConditions().
Definition Env.h:171
std::optional< TER > ter
Definition Env.h:172
std::optional< ErrorCodeI > rpcCode
Definition Env.h:177
Execution context for applying a JSON transaction.
Definition JTx.h:27
Thrown when parse fails.
Definition utility.h:20
Represents an XRP, IOU, or MPT quantity This customizes the string conversion and supports XRP conver...
Set the sequence number on a JTx.
Definition seq.h:16
T to_string(T... args)