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/SeqProxy.h>
47#include <xrpl/protocol/UintTypes.h>
48#include <xrpl/protocol/XRPAmount.h>
49#include <xrpl/protocol/jss.h>
50#include <xrpl/resource/Charge.h>
51#include <xrpl/resource/Consumer.h>
52#include <xrpl/resource/Fees.h>
53#include <xrpl/tx/paths/detail/Steps.h>
75 return env.
rpc(
"json",
"account_offers",
to_string(jv))[jss::result];
83 return env.
rpc(
"json",
"account_lines",
to_string(jv))[jss::result];
143 [&]<
typename TAsset>(TAsset
const& asset) {
154 jv[jss::mpt_issuance_id] =
to_string(asset);
169 jv[jss::command] =
"ripple_path_find";
170 jv[jss::source_account] =
toBase58(src);
171 jv[jss::destination_account] =
toBase58(dst);
194 cfg->pathSearchOld = 7;
196 cfg->pathSearchMax = 10;
214 auto& app = env.
app();
221 .loadType = loadType,
222 .netOps = app.getOPs(),
223 .ledgerMaster = app.getLedgerMaster(),
233 params[jss::command] =
"ripple_path_find";
234 params[jss::source_account] =
toBase58(src);
235 params[jss::destination_account] =
toBase58(dst);
249 params[jss::domain] =
to_string(*domain);
253 app.getJobQueue().postCoro(
JtClient,
"RPC-Client", [&](
auto const& coro) {
254 context.
params = std::move(params);
260 using namespace std::chrono_literals;
278 findPathsRequest(env, src, dst, saDstAmount, saSendMax, srcAsset, srcIssuer, domain);
283 if (result.
isMember(jss::destination_amount))
288 if (result.
isMember(jss::alternatives))
290 auto const& alts = result[jss::alternatives];
293 auto const&
path = alts[0u];
295 if (
path.isMember(jss::source_amount))
298 if (
path.isMember(jss::destination_amount))
301 if (
path.isMember(jss::paths_computed))
304 p[
"Paths"] =
path[jss::paths_computed];
307 paths = po.
object->getFieldPathSet(sfPaths);
312 return std::make_tuple(std::move(paths), std::move(sa), std::move(da));
328 srcElement.
has_value(),
"xrpl::test::jtx::findPathsByElement::srcElement : nullptr");
337 srcElement->getPathAsset(),
347 return env.
current()->fees().base * n;
353 auto feeDrops = env.
current()->fees().base;
363 bool const accountLow = account < issue.
account;
365 bool expectDefaultTrustLine =
true;
374 expectDefaultTrustLine =
375 sle->getFieldAmount(sfLowLimit) == low && sle->getFieldAmount(sfHighLimit) == high;
378 auto amount = sle->getFieldAmount(sfBalance);
379 amount.get<
Issue>().account = value.getIssuer();
382 return amount == value && expectDefaultTrustLine;
403 [&](
auto const& issue) {
return expectHolding(env, account, value, issue); },
404 value.asset.value());
412 return mptToken && (*mptToken)[sfMPTAmount] == value.mpt().value();
427 if (sle->getType() == ltOFFER)
430 if (std::ranges::find_if(toMatch, [&](auto const& a) {
431 return a.in == sle->getFieldAmount(sfTakerPays) &&
432 a.out == sle->getFieldAmount(sfTakerGets);
438 return size == cnt && ((toMatch.empty() && size != 0) || (matched == toMatch.size()));
445 jvParams[jss::ledger_index] =
"current";
446 jvParams[jss::account_root] = acct.
human();
447 return env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
454 jvParams[jss::ledger_index] =
"current";
455 jvParams[jss::ripple_state][jss::currency] = currency;
457 jvParams[jss::ripple_state][jss::accounts].
append(acctA.
human());
458 jvParams[jss::ripple_state][jss::accounts].
append(acctB.
human());
459 return env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
466 jvParams[jss::offer][jss::account] = acct.
human();
467 jvParams[jss::offer][jss::seq] = offerSeq;
468 return env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
475 jvParams[jss::mptoken][jss::account] = acct.
human();
476 jvParams[jss::mptoken][jss::mpt_issuance_id] =
to_string(mptID);
477 return env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
484 jvbp[jss::ledger_index] =
"current";
485 takerPays.
setJson(jvbp[jss::taker_pays]);
486 takerGets.
setJson(jvbp[jss::taker_gets]);
487 return env.
rpc(
"json",
"book_offers",
to_string(jvbp))[jss::result];
494 return jrr[jss::node][sfBalance.fieldName];
518 jv[jss::TransactionType] = jss::PaymentChannelCreate;
522 jv[jss::SettleDelay] = settleDelay.
count();
525 jv[sfCancelAfter.fieldName] = cancelAfter->time_since_epoch().count();
527 jv[sfDestinationTag.fieldName] = *dstTag;
539 jv[jss::TransactionType] = jss::PaymentChannelFund;
544 jv[sfExpiration.fieldName] = expiration->time_since_epoch().count();
558 jv[jss::TransactionType] = jss::PaymentChannelClaim;
566 jv[
"Signature"] =
strHex(*signature);
568 jv[
"PublicKey"] =
strHex(pk->slice());
583 auto const slep = view.
read({ltPAYCHAN, chan});
586 return (*slep)[sfBalance];
592 auto const slep = view.
read({ltPAYCHAN, chan});
604 auto const ownerCount = env.
le(account)->getFieldU32(sfOwnerCount);
607 env(
offer(account, in, out));
624 [](
MPTID const& mpt) {
640 [](
Issue const& issue) {
710 auto const tfee = 1. + (
static_cast<double>(args.
transferFee) / 100'000);
713 for (
auto const& account : args.
holders)
731 .maxAmt = args.
limit});
754 jv[sfTransactionType] = jss::LoanBrokerSet;
765 jv[sfTransactionType] = jss::LoanBrokerDelete;
767 jv[sfLoanBrokerID] =
to_string(brokerID);
780 jv[sfTransactionType] = jss::LoanBrokerCoverDeposit;
782 jv[sfLoanBrokerID] =
to_string(brokerID);
796 jv[sfTransactionType] = jss::LoanBrokerCoverWithdraw;
798 jv[sfLoanBrokerID] =
to_string(brokerID);
808 jv[sfTransactionType] = jss::LoanBrokerCoverClawback;
823 Number principalRequested,
827 jv[sfTransactionType] = jss::LoanSet;
829 jv[sfLoanBrokerID] =
to_string(loanBrokerID);
830 jv[sfPrincipalRequested] =
to_string(principalRequested);
839 jv[sfTransactionType] = jss::LoanManage;
850 jv[sfTransactionType] = jss::LoanDelete;
861 jv[sfTransactionType] = jss::LoanPay;
864 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.
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)
static constexpr SeqProxy rawSequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
An endpoint that consumes resources.
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.
std::uint32_t sponsoringAccountCount(Account const &account) const
Return the number of sponsoring accounts owned by an account.
std::uint32_t sponsoringOwnerCount(Account const &account) const
Return the number of sponsoring objects owned by an account.
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.
std::uint32_t sponsoredOwnerCount(Account const &account) const
Return the number of sponsored objects owned by an account.
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).
Keylet payChannel(AccountID const &src, AccountID const &dst, SeqProxy const &seq) noexcept
A PaymentChannel.
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Keylet mptokenIssuance(MPTID const &issuanceID) noexcept
Keylet trustLine(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
Charge const kFeeReferenceRpc
static constexpr auto kApiVersionIfUnspecified
Status doCommand(rpc::JsonContext &context, json::Value &result)
Execute an RPC command and store the results in a json::Value.
MPT issueHelperMPT(IssuerArgs const &args)
IOU issueHelperIOU(IssuerArgs const &args)
json::Value set(AccountID const &account, uint256 const &vaultId, 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 coverWithdraw(AccountID const &account, uint256 const &brokerID, STAmount const &amount, 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 sponsoringAccountCount(Env const &env, Account const &account)
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)
std::uint32_t sponsoringOwnerCount(Env const &env, Account const &account)
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.
std::uint32_t sponsoredOwnerCount(Env const &env, Account const &account)
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)
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
json::Value accountBalance(Env &env, Account const &acct)
json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
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...