1#include <test/jtx/TestHelpers.h>
3#include <test/jtx/Account.h>
4#include <test/jtx/Env.h>
5#include <test/jtx/amount.h>
6#include <test/jtx/balance.h>
7#include <test/jtx/envconfig.h>
8#include <test/jtx/mpt.h>
9#include <test/jtx/offer.h>
10#include <test/jtx/owners.h>
11#include <test/jtx/rate.h>
12#include <test/jtx/trust.h>
14#include <xrpld/core/Config.h>
15#include <xrpld/rpc/RPCHandler.h>
16#include <xrpld/rpc/Role.h>
18#include <xrpl/basics/Number.h>
19#include <xrpl/basics/Slice.h>
20#include <xrpl/basics/base_uint.h>
21#include <xrpl/basics/chrono.h>
22#include <xrpl/basics/contract.h>
23#include <xrpl/basics/strHex.h>
24#include <xrpl/beast/unit_test/suite.h>
25#include <xrpl/beast/utility/instrumentation.h>
26#include <xrpl/core/Job.h>
27#include <xrpl/core/ServiceRegistry.h>
28#include <xrpl/json/json_value.h>
29#include <xrpl/json/to_string.h>
30#include <xrpl/ledger/ReadView.h>
31#include <xrpl/ledger/helpers/DirectoryHelpers.h>
32#include <xrpl/protocol/AccountID.h>
33#include <xrpl/protocol/ApiVersion.h>
34#include <xrpl/protocol/Book.h>
35#include <xrpl/protocol/Indexes.h>
36#include <xrpl/protocol/Issue.h>
37#include <xrpl/protocol/LedgerFormats.h>
38#include <xrpl/protocol/MPTIssue.h>
39#include <xrpl/protocol/PathAsset.h>
40#include <xrpl/protocol/PublicKey.h>
41#include <xrpl/protocol/Quality.h>
42#include <xrpl/protocol/SField.h>
43#include <xrpl/protocol/STAmount.h>
44#include <xrpl/protocol/STParsedJSON.h>
45#include <xrpl/protocol/STPathSet.h>
46#include <xrpl/protocol/UintTypes.h>
47#include <xrpl/protocol/XRPAmount.h>
48#include <xrpl/protocol/jss.h>
49#include <xrpl/resource/Charge.h>
50#include <xrpl/resource/Consumer.h>
51#include <xrpl/resource/Fees.h>
52#include <xrpl/tx/paths/detail/Steps.h>
74 return env.
rpc(
"json",
"account_offers",
to_string(jv))[jss::result];
82 return env.
rpc(
"json",
"account_lines",
to_string(jv))[jss::result];
124 [&]<
typename TAsset>(TAsset
const& asset) {
135 jv[jss::mpt_issuance_id] =
to_string(asset);
150 jv[jss::command] =
"ripple_path_find";
151 jv[jss::source_account] =
toBase58(src);
152 jv[jss::destination_account] =
toBase58(dst);
175 cfg->pathSearchOld = 7;
177 cfg->pathSearchMax = 10;
195 auto& app = env.
app();
202 .loadType = loadType,
203 .netOps = app.getOPs(),
204 .ledgerMaster = app.getLedgerMaster(),
214 params[jss::command] =
"ripple_path_find";
215 params[jss::source_account] =
toBase58(src);
216 params[jss::destination_account] =
toBase58(dst);
230 params[jss::domain] =
to_string(*domain);
234 app.getJobQueue().postCoro(
JtClient,
"RPC-Client", [&](
auto const& coro) {
235 context.
params = std::move(params);
241 using namespace std::chrono_literals;
259 findPathsRequest(env, src, dst, saDstAmount, saSendMax, srcAsset, srcIssuer, domain);
264 if (result.
isMember(jss::destination_amount))
269 if (result.
isMember(jss::alternatives))
271 auto const& alts = result[jss::alternatives];
274 auto const&
path = alts[0u];
276 if (
path.isMember(jss::source_amount))
279 if (
path.isMember(jss::destination_amount))
282 if (
path.isMember(jss::paths_computed))
285 p[
"Paths"] =
path[jss::paths_computed];
288 paths = po.
object->getFieldPathSet(sfPaths);
293 return std::make_tuple(std::move(paths), std::move(sa), std::move(da));
309 srcElement.
has_value(),
"xrpl::test::jtx::findPathsByElement::srcElement : nullptr");
318 srcElement->getPathAsset(),
328 return env.
current()->fees().base * n;
334 auto feeDrops = env.
current()->fees().base;
344 bool const accountLow = account < issue.
account;
346 bool expectDefaultTrustLine =
true;
355 expectDefaultTrustLine =
356 sle->getFieldAmount(sfLowLimit) == low && sle->getFieldAmount(sfHighLimit) == high;
359 auto amount = sle->getFieldAmount(sfBalance);
360 amount.get<
Issue>().account = value.getIssuer();
363 return amount == value && expectDefaultTrustLine;
384 [&](
auto const& issue) {
return expectHolding(env, account, value, issue); },
385 value.asset.value());
393 return mptToken && (*mptToken)[sfMPTAmount] == value.mpt().value();
408 if (sle->getType() == ltOFFER)
411 if (std::ranges::find_if(toMatch, [&](auto const& a) {
412 return a.in == sle->getFieldAmount(sfTakerPays) &&
413 a.out == sle->getFieldAmount(sfTakerGets);
419 return size == cnt && ((toMatch.empty() && size != 0) || (matched == toMatch.size()));
426 jvParams[jss::ledger_index] =
"current";
427 jvParams[jss::account_root] = acct.
human();
428 return env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
435 jvParams[jss::ledger_index] =
"current";
436 jvParams[jss::ripple_state][jss::currency] = currency;
438 jvParams[jss::ripple_state][jss::accounts].
append(acctA.
human());
439 jvParams[jss::ripple_state][jss::accounts].
append(acctB.
human());
440 return env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
447 jvParams[jss::offer][jss::account] = acct.
human();
448 jvParams[jss::offer][jss::seq] = offerSeq;
449 return env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
456 jvParams[jss::mptoken][jss::account] = acct.
human();
457 jvParams[jss::mptoken][jss::mpt_issuance_id] =
to_string(mptID);
458 return env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
465 jvbp[jss::ledger_index] =
"current";
466 takerPays.
setJson(jvbp[jss::taker_pays]);
467 takerGets.
setJson(jvbp[jss::taker_gets]);
468 return env.
rpc(
"json",
"book_offers",
to_string(jvbp))[jss::result];
475 return jrr[jss::node][sfBalance.fieldName];
499 jv[jss::TransactionType] = jss::PaymentChannelCreate;
503 jv[jss::SettleDelay] = settleDelay.
count();
506 jv[sfCancelAfter.fieldName] = cancelAfter->time_since_epoch().count();
508 jv[sfDestinationTag.fieldName] = *dstTag;
520 jv[jss::TransactionType] = jss::PaymentChannelFund;
525 jv[sfExpiration.fieldName] = expiration->time_since_epoch().count();
539 jv[jss::TransactionType] = jss::PaymentChannelClaim;
547 jv[
"Signature"] =
strHex(*signature);
549 jv[
"PublicKey"] =
strHex(pk->slice());
563 auto const slep = view.
read({ltPAYCHAN, chan});
566 return (*slep)[sfBalance];
572 auto const slep = view.
read({ltPAYCHAN, chan});
584 auto const ownerCount = env.
le(account)->getFieldU32(sfOwnerCount);
587 env(
offer(account, in, out));
604 [](
MPTID const& mpt) {
620 [](
Issue const& issue) {
690 auto const tfee = 1. + (
static_cast<double>(args.
transferFee) / 100'000);
693 for (
auto const& account : args.
holders)
711 .maxAmt = args.
limit});
734 jv[sfTransactionType] = jss::LoanBrokerSet;
745 jv[sfTransactionType] = jss::LoanBrokerDelete;
747 jv[sfLoanBrokerID] =
to_string(brokerID);
760 jv[sfTransactionType] = jss::LoanBrokerCoverDeposit;
762 jv[sfLoanBrokerID] =
to_string(brokerID);
776 jv[sfTransactionType] = jss::LoanBrokerCoverWithdraw;
778 jv[sfLoanBrokerID] =
to_string(brokerID);
788 jv[sfTransactionType] = jss::LoanBrokerCoverClawback;
803 Number principalRequested,
807 jv[sfTransactionType] = jss::LoanSet;
809 jv[sfLoanBrokerID] =
to_string(loanBrokerID);
810 jv[sfPrincipalRequested] =
to_string(principalRequested);
819 jv[sfTransactionType] = jss::LoanManage;
830 jv[sfTransactionType] = jss::LoanDelete;
841 jv[sfTransactionType] = jss::LoanPay;
844 jv[sfAmount] = amount.
getJson();
Value & append(Value const &value)
Append value to array at the end.
UInt size() const
Number of values in array or object.
bool isMember(char const *key) const
Return true if the object has a member named key.
void setJson(json::Value &jv) const
constexpr auto visit(Visitors &&... visitors) const -> decltype(auto)
AccountID const & getIssuer() const
A currency issued by an account.
AccountID const & getIssuer() const
constexpr MPTID const & getMptID() const
std::chrono::duration< rep, period > duration
Number is a floating point type that can represent a wide range of values.
constexpr auto visit(Visitors &&... visitors) const -> decltype(auto)
constexpr std::variant< Currency, MPTID > const & value() const
Slice slice() const noexcept
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
An endpoint that consumes resources.
constexpr TIss const & get() const
json::Value getJson(JsonOptions=JsonOptions::Values::None) const override
AccountID const & getIssuer() const
std::shared_ptr< STLedgerEntry const > const & const_ref
Holds the serialized result of parsing an input JSON object.
std::optional< STObject > object
The STObject if the parse was successful.
void pushBack(STPathElement const &e)
Immutable cryptographic account descriptor.
std::string const & human() const
Returns the human readable public key.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
SLE::const_pointer le(Account const &account) const
Return an account root.
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
beast::Journal const journal
void require(Args const &... args)
Check a set of requirements.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
bool waitFor(std::chrono::duration< Rep, Period > const &relTime)
Converts to IOU Issue or STAmount.
Test helper for creating, mutating, and asserting MPT and confidential MPT ledger state.
Converts to MPT Issue or STAmount.
Match the number of items in the account's owner directory.
@ Array
array value (ordered list)
@ Object
object value (collection of name/value pairs).
static constexpr auto kApiVersionIfUnspecified
Status doCommand(RPC::JsonContext &context, json::Value &result)
Execute an RPC command and store the results in a json::Value.
Charge const kFeeReferenceRpc
Keylet mptokenIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Keylet payChannel(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Keylet trustLine(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
MPT issueHelperMPT(IssuerArgs const &args)
IOU issueHelperIOU(IssuerArgs const &args)
json::Value set(AccountID const &account, uint256 const &vaultId, uint32_t flags)
json::Value coverWithdraw(AccountID const &account, uint256 const &brokerID, STAmount const &amount, uint32_t flags)
json::Value coverDeposit(AccountID const &account, uint256 const &brokerID, STAmount const &amount, uint32_t flags)
json::Value coverClawback(AccountID const &account, std::uint32_t flags)
json::Value del(AccountID const &account, uint256 const &brokerID, uint32_t flags)
json::Value set(AccountID const &account, uint256 const &loanBrokerID, Number principalRequested, std::uint32_t flags)
json::Value manage(AccountID const &account, uint256 const &loanID, std::uint32_t flags)
json::Value del(AccountID const &account, uint256 const &loanID, std::uint32_t flags)
json::Value pay(AccountID const &account, uint256 const &loanID, STAmount const &amount, std::uint32_t flags)
json::Value fund(AccountID const &account, uint256 const &channel, STAmount const &amount, std::optional< NetClock::time_point > const &expiration)
STAmount channelBalance(ReadView const &view, uint256 const &chan)
json::Value create(AccountID const &account, AccountID const &to, STAmount const &amount, NetClock::duration const &settleDelay, PublicKey const &pk, std::optional< NetClock::time_point > const &cancelAfter, std::optional< std::uint32_t > const &dstTag)
uint256 channel(AccountID const &account, AccountID const &dst, std::uint32_t seqProxyValue)
json::Value claim(AccountID const &account, uint256 const &channel, std::optional< STAmount > const &balance, std::optional< STAmount > const &amount, std::optional< Slice > const &signature, std::optional< PublicKey > const &pk)
bool channelExists(ReadView const &view, uint256 const &chan)
void nOffers(Env &env, std::size_t n, Account const &account, STAmount const &in, STAmount const &out)
json::Value findPathsRequest(jtx::Env &env, jtx::Account const &src, jtx::Account const &dst, STAmount const &saDstAmount, std::optional< STAmount > const &saSendMax, std::optional< PathAsset > const &srcAsset, std::optional< AccountID > const &srcIssuer, std::optional< uint256 > const &domain)
jtx::Env pathTestEnv(beast::unit_test::Suite &suite)
json::Value ledgerEntryMPT(jtx::Env &env, jtx::Account const &acct, MPTID const &mptID)
bool expectLedgerEntryRoot(Env &env, Account const &acct, STAmount const &expectedValue)
bool expectMPT(Env &env, AccountID const &account, STAmount const &value)
PrettyAmount xrpMinusFee(Env const &env, std::int64_t xrpAmount)
bool expectOffers(Env &env, AccountID const &account, std::uint16_t size, std::vector< Amounts > const &toMatch)
STPathElement allPathElements(AccountID const &a, Asset const &asset)
bool expectHolding(Env &env, AccountID const &account, STAmount const &value, bool defaultLimits)
static void addSourceAsset(json::Value &jv, PathAsset const &srcAsset, std::optional< AccountID > const &srcIssuer)
constexpr XRPAmount kJtxDropsPerXrp
json::Value getBookOffers(jtx::Env &env, Asset const &takerPays, Asset const &takerGets)
std::uint32_t ownerCount(Env const &env, Account const &account)
XRPAmount txFee(Env const &env, std::uint16_t n)
std::tuple< STPathSet, STAmount, STAmount > findPaths(jtx::Env &env, jtx::Account const &src, jtx::Account const &dst, STAmount const &saDstAmount, std::optional< STAmount > const &saSendMax, std::optional< PathAsset > const &srcAsset, std::optional< AccountID > const &srcIssuer, std::optional< uint256 > const &domain)
json::Value rpf(jtx::Account const &src, jtx::Account const &dst, STAmount const &dstAmount, std::optional< STAmount > const &sendMax, std::optional< PathAsset > const &srcAsset, std::optional< AccountID > const &srcIssuer)
STPathElement cpe(PathAsset const &pa)
std::tuple< STPathSet, STAmount, STAmount > findPathsByElement(jtx::Env &env, jtx::Account const &src, jtx::Account const &dst, STAmount const &saDstAmount, std::optional< STAmount > const &saSendMax, std::optional< STPathElement > const &srcElement, std::optional< AccountID > const &srcIssuer, std::optional< uint256 > const &domain)
STPathElement ipe(Asset const &asset)
json::Value ledgerEntryState(Env &env, Account const &acctA, Account const &acctB, std::string const ¤cy)
bool equal(STAmount const &sa1, STAmount const &sa2)
STPathElement iape(AccountID const &account)
json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
json::Value ledgerEntryRoot(Env &env, Account const &acct)
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
void stpathAppendOne(STPath &st, Account const &account)
json::Value accountBalance(Env &env, Account const &acct)
json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
json::Value getAccountLines(Env &env, AccountID const &acctId)
bool checkArraySize(json::Value const &val, unsigned int size)
json::Value ledgerEntryOffer(jtx::Env &env, jtx::Account const &acct, std::uint32_t offerSeq)
STPathElement ape(AccountID const &a)
json::Value getAccountOffers(Env &env, AccountID const &acct, bool current)
bool bookStepEqual(Step const &step, xrpl::Book const &book)
bool xrpEndpointStepEqual(Step const &step, AccountID const &acc)
bool mptEndpointStepEqual(Step const &step, AccountID const &src, AccountID const &dst, MPTID const &mptid)
bool directStepEqual(Step const &step, AccountID const &src, AccountID const &dst, Currency const ¤cy)
constexpr XRPAmount
Convert XRP to drops (integral types).
std::string strHex(FwdIt begin, FwdIt end)
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
BaseUInt< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Currency const & xrpCurrency()
XRP currency.
std::string to_string(BaseUInt< Bits, Tag > const &a)
BaseUInt< 192 > MPTID
MPTID is a 192-bit value representing MPT Issuance ID, which is a concatenation of a 32-bit sequence ...
STAmount amountFromJson(SField const &name, json::Value const &v)
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
void forEachItem(ReadView const &view, Keylet const &root, std::function< void(SLE::const_ref)> const &f)
Iterate all items in the given directory.
AccountID const & xrpAccount()
Compute AccountID from public key.
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
std::shared_ptr< JobQueue::Coro > coro
std::optional< std::uint64_t > limit
std::uint16_t transferFee
std::vector< jtx::Account > holders
Represents an XRP, IOU, or MPT quantity This customizes the string conversion and supports XRP conver...