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();
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::ownerCount(Account const& account) const
204{
205 auto const sle = le(account);
206 if (!sle)
207 Throw<std::runtime_error>("missing account root");
208 return sle->getFieldU32(sfOwnerCount);
209}
210
212Env::seq(Account const& account) const
213{
214 auto const sle = le(account);
215 if (!sle)
216 Throw<std::runtime_error>("missing account root");
217 return sle->getFieldU32(sfSequence);
218}
219
221Env::le(Account const& account) const
222{
223 return le(keylet::account(account.id()));
224}
225
227Env::le(Keylet const& k) const
228{
229 return current()->read(k);
230}
231
232void
233Env::fund(bool setDefaultRipple, STAmount const& amount, Account const& account)
234{
235 memoize(account);
236 if (setDefaultRipple)
237 {
238 // VFALCO NOTE Is the fee formula correct?
239 apply(
240 pay(master, account, amount + drops(current()->fees().base)),
244 apply(
245 fset(account, asfDefaultRipple),
249 require(flags(account, asfDefaultRipple));
250 }
251 else
252 {
253 apply(
254 pay(master, account, amount),
259 }
260 require(jtx::balance(account, amount));
261}
262
263void
264Env::trust(STAmount const& amount, Account const& account)
265{
266 auto const start = balance(account);
267 apply(
268 jtx::trust(account, amount),
272 apply(
273 pay(master, account, drops(current()->fees().base)),
277 test.expect(balance(account) == start);
278}
279
282{
283 auto error = [](ParsedResult& parsed, Json::Value const& object) {
284 // Use an error code that is not used anywhere in the transaction
285 // engine to distinguish this case.
286 parsed.ter = telENV_RPC_FAILED;
287 // Extract information about the error
288 if (!object.isObject())
289 return;
290 if (object.isMember(jss::error_code))
291 parsed.rpcCode =
292 safe_cast<error_code_i>(object[jss::error_code].asInt());
293 if (object.isMember(jss::error_message))
294 parsed.rpcMessage = object[jss::error_message].asString();
295 if (object.isMember(jss::error))
296 parsed.rpcError = object[jss::error].asString();
297 if (object.isMember(jss::error_exception))
298 parsed.rpcException = object[jss::error_exception].asString();
299 };
300 ParsedResult parsed;
301 if (jr.isObject() && jr.isMember(jss::result))
302 {
303 auto const& result = jr[jss::result];
304 if (result.isMember(jss::engine_result_code))
305 {
306 parsed.ter = TER::fromInt(result[jss::engine_result_code].asInt());
307 parsed.rpcCode.emplace(rpcSUCCESS);
308 }
309 else
310 error(parsed, result);
311 }
312 else
313 error(parsed, jr);
314
315 return parsed;
316}
317
318void
320{
321 ParsedResult parsedResult;
322 auto const jr = [&]() {
323 if (jt.stx)
324 {
325 txid_ = jt.stx->getTransactionID();
326 Serializer s;
327 jt.stx->add(s);
328 auto const jr = rpc("submit", strHex(s.slice()));
329
330 parsedResult = parseResult(jr);
331 test.expect(parsedResult.ter, "ter uninitialized!");
332 ter_ = parsedResult.ter.value_or(telENV_RPC_FAILED);
333
334 return jr;
335 }
336 else
337 {
338 // Parsing failed or the JTx is
339 // otherwise missing the stx field.
340 parsedResult.ter = ter_ = temMALFORMED;
341
342 return Json::Value();
343 }
344 }();
345 return postconditions(jt, parsedResult, jr);
346}
347
348void
350{
351 auto const account = lookup(jt.jv[jss::Account].asString());
352 auto const& passphrase = account.name();
353
354 Json::Value jr;
355 if (params.isNull())
356 {
357 // Use the command line interface
358 auto const jv = boost::lexical_cast<std::string>(jt.jv);
359 jr = rpc("submit", passphrase, jv);
360 }
361 else
362 {
363 // Use the provided parameters, and go straight
364 // to the (RPC) client.
365 assert(params.isObject());
366 if (!params.isMember(jss::secret) && !params.isMember(jss::key_type) &&
367 !params.isMember(jss::seed) && !params.isMember(jss::seed_hex) &&
368 !params.isMember(jss::passphrase))
369 {
370 params[jss::secret] = passphrase;
371 }
372 params[jss::tx_json] = jt.jv;
373 jr = client().invoke("submit", params);
374 }
375
376 if (!txid_.parseHex(jr[jss::result][jss::tx_json][jss::hash].asString()))
377 txid_.zero();
378
379 ParsedResult const parsedResult = parseResult(jr);
380 test.expect(parsedResult.ter, "ter uninitialized!");
381 ter_ = parsedResult.ter.value_or(telENV_RPC_FAILED);
382
383 return postconditions(jt, parsedResult, jr);
384}
385
386void
388 JTx const& jt,
389 ParsedResult const& parsed,
390 Json::Value const& jr)
391{
392 bool bad = !test.expect(parsed.ter, "apply: No ter result!");
393 bad =
394 (jt.ter && parsed.ter &&
395 !test.expect(
396 *parsed.ter == *jt.ter,
397 "apply: Got " + transToken(*parsed.ter) + " (" +
398 transHuman(*parsed.ter) + "); Expected " +
399 transToken(*jt.ter) + " (" + transHuman(*jt.ter) + ")"));
400 using namespace std::string_literals;
401 bad = (jt.rpcCode &&
402 !test.expect(
403 parsed.rpcCode == jt.rpcCode->first &&
404 parsed.rpcMessage == jt.rpcCode->second,
405 "apply: Got RPC result "s +
406 (parsed.rpcCode
408 : "NO RESULT") +
409 " (" + parsed.rpcMessage + "); Expected " +
410 RPC::get_error_info(jt.rpcCode->first).token.c_str() + " (" +
411 jt.rpcCode->second + ")")) ||
412 bad;
413 // If we have an rpcCode (just checked), then the rpcException check is
414 // optional - the 'error' field may not be defined, but if it is, it must
415 // match rpcError.
416 bad =
417 (jt.rpcException &&
418 !test.expect(
419 (jt.rpcCode && parsed.rpcError.empty()) ||
420 (parsed.rpcError == jt.rpcException->first &&
421 (!jt.rpcException->second ||
422 parsed.rpcException == *jt.rpcException->second)),
423 "apply: Got RPC result "s + parsed.rpcError + " (" +
424 parsed.rpcException + "); Expected " + jt.rpcException->first +
425 " (" + jt.rpcException->second.value_or("n/a") + ")")) ||
426 bad;
427 if (bad)
428 {
429 test.log << pretty(jt.jv) << std::endl;
430 if (jr)
431 test.log << pretty(jr) << std::endl;
432 // Don't check postconditions if
433 // we didn't get the expected result.
434 return;
435 }
436 if (trace_)
437 {
438 if (trace_ > 0)
439 --trace_;
440 test.log << pretty(jt.jv) << std::endl;
441 }
442 for (auto const& f : jt.require)
443 f(*this);
444}
445
448{
449 close();
450 auto const item = closed()->txRead(txid_);
451 return item.second;
452}
453
455Env::tx() const
456{
457 return current()->txRead(txid_).first;
458}
459
460void
462{
463 auto& jv = jt.jv;
464 if (jt.signer)
465 return jt.signer(*this, jt);
466 if (!jt.fill_sig)
467 return;
468 auto const account = jv.isMember(sfDelegate.jsonName)
469 ? lookup(jv[sfDelegate.jsonName].asString())
470 : lookup(jv[jss::Account].asString());
471 if (!app().checkSigs())
472 {
473 jv[jss::SigningPubKey] = strHex(account.pk().slice());
474 // dummy sig otherwise STTx is invalid
475 jv[jss::TxnSignature] = "00";
476 return;
477 }
478 auto const ar = le(account);
479 if (ar && ar->isFieldPresent(sfRegularKey))
480 jtx::sign(jv, lookup(ar->getAccountID(sfRegularKey)));
481 else
482 jtx::sign(jv, account);
483}
484
485void
487{
488 auto& jv = jt.jv;
489 if (jt.fill_fee)
490 jtx::fill_fee(jv, *current());
491 if (jt.fill_seq)
492 jtx::fill_seq(jv, *current());
493
494 if (jt.fill_netid)
495 {
496 uint32_t networkID = app().config().NETWORK_ID;
497 if (!jv.isMember(jss::NetworkID) && networkID > 1024)
498 jv[jss::NetworkID] = std::to_string(networkID);
499 }
500
501 // Must come last
502 try
503 {
505 }
506 catch (parse_error const&)
507 {
509 test.log << "parse failed:\n" << pretty(jv) << std::endl;
510 Rethrow();
511 }
512}
513
516{
517 // The parse must succeed, since we
518 // generated the JSON ourselves.
520 try
521 {
522 obj = jtx::parse(jt.jv);
523 }
524 catch (jtx::parse_error const&)
525 {
526 test.log << "Exception: parse_error\n" << pretty(jt.jv) << std::endl;
527 Rethrow();
528 }
529
530 try
531 {
532 return sterilize(STTx{std::move(*obj)});
533 }
534 catch (std::exception const&)
535 {
536 }
537 return nullptr;
538}
539
542{
543 // The parse must succeed, since we
544 // generated the JSON ourselves.
546 try
547 {
548 obj = jtx::parse(jt.jv);
549 }
550 catch (jtx::parse_error const&)
551 {
552 test.log << "Exception: parse_error\n" << pretty(jt.jv) << std::endl;
553 Rethrow();
554 }
555
556 try
557 {
558 return std::make_shared<STTx const>(std::move(*obj));
559 }
560 catch (std::exception const&)
561 {
562 }
563 return nullptr;
564}
565
568 unsigned apiVersion,
569 std::vector<std::string> const& args,
571{
572 auto response =
573 rpcClient(args, app().config(), app().logs(), apiVersion, headers);
574
575 for (unsigned ctr = 0; (ctr < retries_) and (response.first == rpcINTERNAL);
576 ++ctr)
577 {
578 JLOG(journal.error())
579 << "Env::do_rpc error, retrying, attempt #" << ctr + 1 << " ...";
581
582 response =
583 rpcClient(args, app().config(), app().logs(), apiVersion, headers);
584 }
585
586 return response.second;
587}
588
589void
591{
592 // Env::close() must be called for feature
593 // enable to take place.
594 app().config().features.insert(feature);
595}
596
597void
599{
600 // Env::close() must be called for feature
601 // enable to take place.
602 app().config().features.erase(feature);
603}
604
605} // namespace jtx
606
607} // namespace test
608} // namespace ripple
constexpr const char * c_str() const
Definition: json_value.h:75
Represents a JSON value.
Definition: json_value.h:148
bool isObject() const
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:475
bool isNull() const
isNull() tests to see if this field is null.
Definition: json_value.cpp:986
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:949
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 void signalStop(std::string msg="")=0
virtual LedgerMaster & getLedgerMaster()=0
virtual Logs & logs()=0
uint32_t NETWORK_ID
Definition: Config.h:156
std::unordered_set< uint256, beast::uhash<> > features
Definition: Config.h:277
static void initializeSSLContext(Config const &config, beast::Journal j)
Definition: HTTPClient.cpp:39
A currency issued by an account.
Definition: Issue.h:36
AccountID account
Definition: Issue.h:39
Currency currency
Definition: Issue.h:38
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
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:67
static constexpr TERSubset fromInt(int from)
Definition: TER.h:411
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:598
bool parseFailureExpected_
Definition: Env.h:721
static ParsedResult parseResult(Json::Value const &jr)
Gets the TER result and didApply flag from a RPC Json result object.
Definition: Env.cpp:281
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition: Env.cpp:203
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition: Env.cpp:212
std::unordered_map< AccountID, Account > map_
Definition: Env.h:764
beast::unit_test::suite & test
Definition: Env.h:122
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition: Env.cpp:455
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:330
void postconditions(JTx const &jt, ParsedResult const &parsed, Json::Value const &jr=Json::Value())
Check expected postconditions of JTx submission.
Definition: Env.cpp:387
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:349
virtual void autofill(JTx &jt)
Definition: Env.cpp:486
AbstractClient & client()
Returns the connected client.
Definition: Env.h:290
void autofill_sig(JTx &jt)
Definition: Env.cpp:461
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:264
Json::Value do_rpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition: Env.cpp:567
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:515
void enableFeature(uint256 const feature)
Definition: Env.cpp:590
Account const & master
Definition: Env.h:124
Account const & lookup(AccountID const &id) const
Returns the Account given the AccountID.
Definition: Env.cpp:158
unsigned retries_
Definition: Env.h:722
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:495
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:541
Application & app()
Definition: Env.h:260
beast::Journal const journal
Definition: Env.h:161
ManualTimeKeeper & timeKeeper()
Definition: Env.h:272
virtual void submit(JTx const &jt)
Submit an existing JTx.
Definition: Env.cpp:319
Env & apply(JsonValue &&jv, FN const &... fN)
Apply funclets and submit.
Definition: Env.h:569
bool close()
Close and advance the ledger.
Definition: Env.h:392
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:233
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition: Env.cpp:447
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:221
A balance matches.
Definition: balance.h:39
Set the fee on a JTx.
Definition: fee.h:37
Match set account flags.
Definition: flags.h:125
Match clear account flags.
Definition: flags.h:142
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:179
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:236
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:176
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:26
std::string transHuman(TER code)
Definition: TER.cpp:266
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Definition: STTx.cpp:631
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:1462
bool isXRP(AccountID const &c)
Definition: AccountID.h:91
@ 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:257
constexpr std::uint32_t asfDefaultRipple
Definition: TxFlags.h:83
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:210
std::unique_ptr< Application > owned
Definition: Env.h:144
ManualTimeKeeper * timeKeeper
Definition: Env.h:145
std::unique_ptr< AbstractClient > client
Definition: Env.h:147
Used by parseResult() and postConditions()
Definition: Env.h:128
std::optional< error_code_i > rpcCode
Definition: Env.h:134
std::optional< TER > ter
Definition: Env.h:129
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)