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