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