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> 
   12#include <xrpld/app/ledger/LedgerMaster.h> 
   13#include <xrpld/app/misc/NetworkOPs.h> 
   14#include <xrpld/rpc/RPCCall.h> 
   16#include <xrpl/basics/Slice.h> 
   17#include <xrpl/basics/contract.h> 
   18#include <xrpl/basics/scope.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> 
   60        config->SSL_VERIFY_DIR,
 
   61        config->SSL_VERIFY_FILE,
 
   65        std::move(config), std::move(logs), std::move(timeKeeper_));
 
   69        Throw<std::runtime_error>(
"Env::AppBundle: setup failed");
 
 
   87    if (thread.joinable())
 
 
  108    using namespace std::chrono_literals;
 
  110    closeTime += 
closed()->info().closeTimeResolution - 1s;
 
  118        auto resp = 
rpc(
"ledger_accept");
 
  119        if (resp[
"result"][
"status"] != 
std::string(
"success"))
 
  122            if (resp.isMember(
"error_what"))
 
  123                reason = resp[
"error_what"].asString();
 
  124            else if (resp.isMember(
"error_message"))
 
  125                reason = resp[
"error_message"].asString();
 
  126            else if (resp.isMember(
"error"))
 
  127                reason = resp[
"error"].asString();
 
  129            JLOG(
journal.
error()) << 
"Env::close() failed: " << reason;
 
 
  140    map_.emplace(account.id(), account);
 
 
  146    auto const iter = 
map_.find(
id);
 
  147    if (iter == 
map_.end())
 
  149        std::cout << 
"Unknown account: " << 
id << 
"\n";
 
  150        Throw<std::runtime_error>(
"Env::lookup:: unknown account ID");
 
 
  158    auto const account = parseBase58<AccountID>(base58ID);
 
  160        Throw<std::runtime_error>(
"Env::lookup: invalid account ID");
 
 
  167    auto const sle = 
le(account);
 
  170    return {sle->getFieldAmount(sfBalance), 
""};
 
 
  180        return {
STAmount(issue, 0), account.name()};
 
  181    auto amount = sle->getFieldAmount(sfBalance);
 
  182    amount.setIssuer(issue.
account);
 
  183    if (account.id() > issue.
account)
 
 
  193        return {
STAmount(mptIssue, 0), account.name()};
 
  196    if (account.id() == issuer)
 
  201            return {
STAmount(mptIssue, 0), account.name()};
 
  205            mptIssue, sle->getFieldU64(sfOutstandingAmount), 0, 
true};
 
  213            return {
STAmount(mptIssue, 0), account.name()};
 
  215        STAmount const amount{mptIssue, sle->getFieldU64(sfMPTAmount)};
 
 
  224        [&](
auto const& issue) { 
return balance(account, issue); },
 
 
  233        return {
STAmount(issue, 0), account.name()};
 
  234    auto const aHigh = account.id() > issue.
account;
 
  235    if (sle && sle->isFieldPresent(aHigh ? sfLowLimit : sfHighLimit))
 
  236        return {(*sle)[aHigh ? sfLowLimit : sfHighLimit], account.name()};
 
  237    return {
STAmount(issue, 0), account.name()};
 
 
  243    auto const sle = 
le(account);
 
  245        Throw<std::runtime_error>(
"missing account root");
 
  246    return sle->getFieldU32(sfOwnerCount);
 
 
  252    auto const sle = 
le(account);
 
  254        Throw<std::runtime_error>(
"missing account root");
 
  255    return sle->getFieldU32(sfSequence);
 
 
  274    if (setDefaultRipple)
 
 
  304    auto const start = 
balance(account);
 
 
  326        if (!
object.isObject())
 
  328        if (
object.isMember(jss::error_code))
 
  330                safe_cast<error_code_i>(
object[jss::error_code].asInt());
 
  331        if (
object.isMember(jss::error_message))
 
  332            parsed.
rpcMessage = 
object[jss::error_message].asString();
 
  333        if (
object.isMember(jss::error))
 
  334            parsed.
rpcError = 
object[jss::error].asString();
 
  335        if (
object.isMember(jss::error_exception))
 
  336            parsed.
rpcException = 
object[jss::error_exception].asString();
 
  341        auto const& result = jr[jss::result];
 
  342        if (result.isMember(jss::engine_result_code))
 
  348            error(parsed, result);
 
 
  360    auto const jr = [&]() {
 
 
  390    auto const& passphrase = account.name();
 
  397        jr = 
rpc(
"submit", passphrase, jv);
 
  408            params[jss::secret] = passphrase;
 
  410        params[jss::tx_json] = 
jt.
jv;
 
 
  430    bool bad = !
test.
expect(parsed.
ter, 
"apply: No ter result!");
 
  438    using namespace std::string_literals;
 
  443               "apply: Got RPC result "s +
 
  461             "apply: Got RPC result "s + parsed.
rpcError + 
" (" +
 
 
  494    auto const result = item.second;
 
  495    if (result == 
nullptr)
 
  498        test.
log << 
"This is probably because the transaction failed with a " 
  501        Throw<std::runtime_error>(
"Env::meta: no metadata for txid");
 
 
  534    auto const account = jv.isMember(sfDelegate.jsonName)
 
  535        ? 
lookup(jv[sfDelegate.jsonName].asString())
 
  536        : 
lookup(jv[jss::Account].asString());
 
  537    if (!
app().checkSigs())
 
  539        jv[jss::SigningPubKey] = 
strHex(account.pk().slice());
 
  541        jv[jss::TxnSignature] = 
"00";
 
  544    auto const ar = 
le(account);
 
  545    if (ar && ar->isFieldPresent(sfRegularKey))
 
 
  563        if (!jv.isMember(jss::NetworkID) && networkID > 1024)
 
 
  645            << 
"Env::do_rpc error, retrying, attempt #" << ctr + 1 << 
" ...";
 
  652    return response.second;
 
 
constexpr char const * c_str() 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.
 
log_os< char > log
Logging output stream.
 
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
 
virtual Config & config()=0
 
virtual void start(bool withTimers)=0
 
virtual bool setup(boost::program_options::variables_map const &options)=0
 
virtual JobQueue & getJobQueue()=0
 
virtual NetworkOPs & getOPs()=0
 
virtual LedgerMaster & getLedgerMaster()=0
 
virtual void signalStop(std::string msg)=0
 
constexpr value_type const & value() const
 
std::unordered_set< uint256, beast::uhash<> > features
 
static void initializeSSLContext(std::string const &sslVerifyDir, std::string const &sslVerifyFile, bool sslVerify, beast::Journal j)
 
A currency issued by an account.
 
void rendezvous()
Block until no jobs running.
 
std::shared_ptr< Ledger const > getClosedLedger()
 
beast::severities::Severity threshold() const
 
AccountID const & getIssuer() const
 
constexpr MPTID const & getMptID() const
 
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
 
static constexpr TERSubset fromInt(int from)
 
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
 
virtual Json::Value invoke(std::string const &cmd, Json::Value const ¶ms={})=0
Submit a command synchronously.
 
Immutable cryptographic account descriptor.
 
std::string const & name() const
Return the name.
 
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
 
void disableFeature(uint256 const feature)
 
bool parseFailureExpected_
 
static ParsedResult parseResult(Json::Value const &jr)
Gets the TER result and didApply flag from a RPC Json result object.
 
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
 
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
 
std::unordered_map< AccountID, Account > map_
 
beast::unit_test::suite & test
 
PrettyAmount limit(Account const &account, Issue const &issue) const
Returns the IOU limit on an account.
 
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
 
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
 
void postconditions(JTx const &jt, ParsedResult const &parsed, Json::Value const &jr=Json::Value())
Check expected postconditions of JTx submission.
 
void sign_and_submit(JTx const &jt, Json::Value params=Json::nullValue)
Use the submit RPC command with a provided JTx object.
 
virtual void autofill(JTx &jt)
 
AbstractClient & client()
Returns the connected client.
 
void autofill_sig(JTx &jt)
 
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
 
Json::Value do_rpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
 
std::shared_ptr< STTx const > st(JTx const &jt)
Create a STTx from a JTx The framework requires that JSON is valid.
 
void enableFeature(uint256 const feature)
 
Account const & lookup(AccountID const &id) const
Returns the Account given the AccountID.
 
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
 
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...
 
beast::Journal const journal
 
ManualTimeKeeper & timeKeeper()
 
virtual void submit(JTx const &jt)
Submit an existing JTx.
 
Env & apply(JsonValue &&jv, FN const &... fN)
Apply funclets and submit.
 
bool close()
Close and advance the ledger.
 
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
 
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
 
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
 
void memoize(Account const &account)
Associate AccountID with account.
 
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
 
Match clear account flags.
 
Check a set of conditions.
 
Set the expected result code for a JTx The test will fail if the code doesn't match.
 
Set the regular signature on a JTx.
 
A namespace for easy access to logging severity values.
 
Severity
Severity level / threshold of a Journal message.
 
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
 
Keylet line(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
 
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
 
Keylet account(AccountID const &id) noexcept
AccountID root.
 
void fill_seq(Json::Value &jv, ReadView const &view)
Set the sequence number automatically.
 
static autofill_t const autofill
 
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.
 
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
 
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
 
void sign(Json::Value &jv, Account const &account, Json::Value &sigObject)
Sign automatically into a specific Json field of the jv object.
 
STObject parse(Json::Value const &jv)
Convert JSON to STObject.
 
XRP_t const XRP
Converts to XRP Issue or STAmount.
 
void fill_fee(Json::Value &jv, ReadView const &view)
Set the fee automatically.
 
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.
 
std::string transHuman(TER code)
 
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
 
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.
 
bool isXRP(AccountID const &c)
 
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)
 
std::string transToken(TER code)
 
constexpr std::uint32_t asfDefaultRipple
 
beast::Journal debugLog()
Returns a debug journal.
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
std::unique_ptr< beast::Journal::Sink > setDebugLogSink(std::unique_ptr< beast::Journal::Sink > sink)
Set the sink for the debug journal.
 
void Rethrow()
Rethrow the exception currently being handled.
 
A pair of SHAMap key and LedgerEntryType.
 
std::unique_ptr< Application > owned
 
ManualTimeKeeper * timeKeeper
 
std::unique_ptr< AbstractClient > client
 
Used by parseResult() and postConditions()
 
std::optional< error_code_i > rpcCode
 
Execution context for applying a JSON transaction.
 
std::vector< std::function< void(Env &, JTx &)> > postSigners
 
std::optional< std::pair< error_code_i, std::string > > rpcCode
 
std::shared_ptr< STTx const  > stx
 
std::optional< std::pair< std::string, std::optional< std::string > > > rpcException
 
std::vector< std::function< void(Env &, JTx &)> > mainSigners
 
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
 
Set the sequence number on a JTx.
 
A signer in a SignerList.