1#include <test/jtx/Account.h>
2#include <test/jtx/Env.h>
3#include <test/jtx/PathSet.h>
4#include <test/jtx/TestHelpers.h>
5#include <test/jtx/amount.h>
6#include <test/jtx/balance.h>
7#include <test/jtx/jtx_json.h>
8#include <test/jtx/offer.h>
9#include <test/jtx/pay.h>
10#include <test/jtx/sig.h>
11#include <test/jtx/sponsor.h>
12#include <test/jtx/ter.h>
13#include <test/jtx/trust.h>
14#include <test/jtx/txflags.h>
16#include <xrpl/beast/unit_test/suite.h>
17#include <xrpl/beast/utility/Zero.h>
18#include <xrpl/ledger/ApplyView.h>
19#include <xrpl/ledger/ApplyViewImpl.h>
20#include <xrpl/ledger/OwnerCounts.h>
21#include <xrpl/ledger/PaymentSandbox.h>
22#include <xrpl/ledger/ReadView.h>
23#include <xrpl/ledger/helpers/RippleStateHelpers.h>
24#include <xrpl/ledger/helpers/TokenHelpers.h>
25#include <xrpl/protocol/AccountID.h>
26#include <xrpl/protocol/AmountConversions.h>
27#include <xrpl/protocol/Feature.h>
28#include <xrpl/protocol/Indexes.h>
29#include <xrpl/protocol/Issue.h>
30#include <xrpl/protocol/SField.h>
31#include <xrpl/protocol/STAmount.h>
32#include <xrpl/protocol/TER.h>
33#include <xrpl/protocol/TxFlags.h>
34#include <xrpl/protocol/UintTypes.h>
35#include <xrpl/protocol/XRPAmount.h>
74 Env env(*
this, features);
80 env.
fund(
XRP(10000), snd, rcv, gw1, gw2);
82 auto const usdGw1 = gw1[
"USD"];
83 auto const usdGw2 = gw2[
"USD"];
85 env.
trust(usdGw1(10), snd);
86 env.
trust(usdGw2(10), snd);
87 env.
trust(usdGw1(100), rcv);
88 env.
trust(usdGw2(100), rcv);
90 env(
pay(gw1, snd, usdGw1(2)));
91 env(
pay(gw2, snd, usdGw2(4)));
93 env(
offer(snd, usdGw1(2), usdGw2(2)),
Txflags(tfPassive));
94 env(
offer(snd, usdGw2(2), usdGw1(2)),
Txflags(tfPassive));
98 env(
pay(snd, rcv,
kAny(usdGw1(4))),
100 Txflags(tfNoRippleDirect | tfPartialPayment));
112 Env env(*
this, features);
117 env.
fund(
XRP(10000), alice, gw1, gw2);
121 auto const usdGw1 = gw1[
"USD"];
122 auto const usdGw2 = gw2[
"USD"];
124 env.
trust(usdGw1(100), alice);
125 env.
trust(usdGw2(100), alice);
127 env(
pay(gw1, alice, usdGw1(50)));
128 env(
pay(gw2, alice, usdGw2(50)));
130 STAmount const toCredit(usdGw1(30));
136 auto const iss = usdGw1;
137 auto const startingAmount =
146 startingAmount + toCredit);
154 startingAmount + toCredit - toDebit);
161 auto const iss = usdGw1;
162 auto const startingAmount =
169 startingAmount + toCredit);
175 startingAmount + toCredit - toDebit);
183 auto const iss = usdGw1;
184 auto const startingAmount =
203 startingAmount - toDebit);
211 auto const iss = usdGw1;
212 auto const startingAmount =
227 auto const iss = usdGw1;
228 auto const startingAmount =
235 startingAmount - toDebit);
243 auto const iss = usdGw1;
244 auto const startingAmount =
259 auto const iss = usdGw1;
260 auto const startingAmount =
279 auto r =
accountSend(pv2, gw1, alice, toCredit, j);
295 startingAmount - toDebit);
310 Env const env(*
this, features);
314 auto const usd = gw[
"USD"];
316 auto const issue = usd;
334 auto accountFundsXRP =
341 return env.
current()->fees().accountReserve(count, 1);
344 Env env(*
this, features);
377 Env const env(*
this, features);
380 auto const usd = gw[
"USD"];
397 BEAST_EXPECT(balance.
getIssuer() == usd.account.id());
408 Env env(*
this, features);
421 BEAST_EXPECT(aliceSle);
432 BEAST_EXPECT(retrieved.
owner == updated.
owner);
440 BEAST_EXPECT(sponsorSle);
444 sponsorUpdated.
owner = sponsorInitial.
owner + 1;
450 BEAST_EXPECT(sponsorRetrieved.
owner == sponsorUpdated.
owner);
467 BEAST_EXPECT(retrieved.
owner >= further.
owner);
494 (features[featureSponsor] ?
" with sponsor" :
" without sponsor"));
499 return env.
current()->fees().accountReserve(count, 1);
502 Env env(*
this, features);
508 auto const usd = gw[
"USD"];
520 env(
trust(alice, usd(1000)));
527 env(
trust(bob, usd(1000)));
528 env(
pay(gw, alice, usd(100)));
531 auto const aliceOfferSeq = env.
seq(alice);
532 env(
offer(alice, usd(50),
XRP(50)));
539 if (features[featureSponsor])
542 BEAST_EXPECT(env.
le(trustId));
559 BEAST_EXPECT(aliceSle);
561 auto const aliceBalance = aliceSle->getFieldAmount(sfBalance);
563 auto const aliceReserve =
reserve(env, features[featureSponsor] ? 1 : 2);
566 auto const available = aliceBalance.xrp() - aliceReserve;
567 if (features[featureSponsor])
570 BEAST_EXPECT(available >
XRP(150));
574 BEAST_EXPECT(available <
XRP(150));
578 auto const tooMuch = aliceBalance.xrp() -
XRP(1);
592 if (features[featureSponsor])
601 auto const aliceBalance2 = aliceSle2->getFieldAmount(sfBalance);
604 auto const aliceReserve2 =
reserve(env, features[featureSponsor] ? 0 : 1);
605 auto const available2 = aliceBalance2.xrp() - aliceReserve2;
608 BEAST_EXPECT(available2 > available);
625 testAll(sa - featurePermissionedDEX);
A generic endpoint for log messages.
TestcaseT testcase
Memberspace for declaring test cases.
Editable, discardable view that can build metadata for one tx.
A currency issued by an account.
A wrapper which makes credits unavailable to balances.
STAmount balanceHookIOU(AccountID const &account, AccountID const &issuer, STAmount const &amount) const override
void creditHookIOU(AccountID const &from, AccountID const &to, STAmount const &amount, STAmount const &preCreditBalance) override
void adjustOwnerCountHook(AccountID const &account, OwnerCounts const &cur, OwnerCounts const &next) override
OwnerCounts ownerCountHook(AccountID const &account, OwnerCounts const &count) const override
static constexpr int kMinOffset
AccountID const & getIssuer() const
static constexpr std::uint64_t kMinValue
static constexpr std::uint64_t kMaxValue
static constexpr int kMaxOffset
virtual beast::Journal getJournal(std::string const &name)=0
SLE::pointer peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
void testBalanceHook(FeatureBitset features)
void run() override
Runs the suite.
void testOwnerCountHook(FeatureBitset features)
void testSubtractCredits(FeatureBitset features)
void testOwnerCountWithTransaction(FeatureBitset features)
void testReserve(FeatureBitset features)
void testTinyBalance(FeatureBitset features)
void testSelfFunding(FeatureBitset features)
Immutable cryptographic account descriptor.
AccountID id() const
Returns the Account ID.
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.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
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.
Set the regular signature on a JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet trustLine(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
json::Value offerCancel(Account const &account, std::uint32_t offerSeq)
Cancel an offer.
XrpT const XRP
Converts to XRP Issue or STAmount.
std::uint32_t ownerCount(Env const &env, Account const &account)
std::uint32_t sponsoringOwnerCount(Env const &env, Account const &account)
FeatureBitset testableAmendments()
AnyT const kAny
Returns an amount representing "any issuer".
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 trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
static XRPAmount reserve(jtx::Env &env, std::uint32_t count)
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
constexpr XRPAmount
Convert XRP to drops (integral types).
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
TER accountSend(ApplyView &view, AccountID const &from, AccountID const &to, STAmount const &saAmount, beast::Journal j, SLE::ref sponsorSle={}, WaiveTransferFee waiveFee=WaiveTransferFee::No, AllowMPTOverflow allowOverflow=AllowMPTOverflow::No)
Calls static accountSendIOU if saAmount represents Issue.
Currency const & xrpCurrency()
XRP currency.
XRPAmount toAmount< XRPAmount >(STAmount const &amt)
TER issueIOU(ApplyView &view, AccountID const &account, STAmount const &amount, Issue const &issue, SLE::ref sponsorSle, beast::Journal j)
TER directSendNoFee(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, bool bCheckIssuer, beast::Journal j)
Calls static directSendNoFeeIOU if saAmount represents Issue.
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
TER redeemIOU(ApplyView &view, AccountID const &account, STAmount const &amount, Issue const &issue, beast::Journal j)
bool isTesSuccess(TER x) noexcept
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
AccountID const & xrpAccount()
Compute AccountID from public key.
constexpr FlagValue spfSponsorReserve
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j, SpendableHandling includeFullBalance=SpendableHandling::SimpleBalance)