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