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