1#include <test/jtx/Account.h>
2#include <test/jtx/Env.h>
3#include <test/jtx/amount.h>
4#include <test/jtx/balance.h>
5#include <test/jtx/flags.h>
6#include <test/jtx/multisign.h>
7#include <test/jtx/noop.h>
8#include <test/jtx/owners.h>
9#include <test/jtx/pay.h>
10#include <test/jtx/rate.h>
11#include <test/jtx/regkey.h>
12#include <test/jtx/sendmax.h>
13#include <test/jtx/sig.h>
14#include <test/jtx/tags.h>
15#include <test/jtx/ter.h>
16#include <test/jtx/ticket.h>
17#include <test/jtx/token.h>
19#include <xrpl/basics/Slice.h>
20#include <xrpl/basics/base_uint.h>
21#include <xrpl/basics/strHex.h>
22#include <xrpl/beast/unit_test/suite.h>
23#include <xrpl/beast/utility/Journal.h>
24#include <xrpl/core/ServiceRegistry.h>
25#include <xrpl/ledger/ApplyView.h>
26#include <xrpl/ledger/OpenView.h>
27#include <xrpl/ledger/helpers/DirectoryHelpers.h>
28#include <xrpl/protocol/AmountConversions.h>
29#include <xrpl/protocol/Feature.h>
30#include <xrpl/protocol/Indexes.h>
31#include <xrpl/protocol/KeyType.h>
32#include <xrpl/protocol/Quality.h>
33#include <xrpl/protocol/Rate.h>
34#include <xrpl/protocol/SField.h>
35#include <xrpl/protocol/STAmount.h>
36#include <xrpl/protocol/STTx.h>
37#include <xrpl/protocol/SecretKey.h>
38#include <xrpl/protocol/TER.h>
39#include <xrpl/protocol/TxFlags.h>
40#include <xrpl/protocol/jss.h>
41#include <xrpl/tx/apply.h>
64 env.fund(XRP(10000), noripple(alice));
66 auto const jrr = env.le(alice);
67 BEAST_EXPECT(jrr && jrr->at(sfFlags) == 0u);
78 Env env(*
this, testableAmendments());
79 env.fund(XRP(10000), noripple(alice));
84 env(regkey(alice, alie));
87 auto testFlags = [
this, &alice, &alie, &env](
90 for (
std::uint32_t flag{1u}; flag < std::numeric_limits<std::uint32_t>::digits; ++flag)
92 if (flag == asfNoFreeze)
99 if (flag == asfAuthorizedNFTokenMinter)
107 if (flag == asfDisallowIncomingCheck || flag == asfDisallowIncomingPayChan ||
108 flag == asfDisallowIncomingNFTokenOffer || flag == asfDisallowIncomingTrustline)
114 if (flag == asfAllowTrustLineClawback)
120 if (flag == asfAllowTrustLineLocking)
130 env.require(Nflags(alice, flag));
131 env(fset(alice, flag), Sig(alice));
133 env.require(Flags(alice, flag));
134 env(fclear(alice, flag), Sig(alie));
136 env.require(Nflags(alice, flag));
138 BEAST_EXPECT(nowFlags == origFlags);
143 BEAST_EXPECT((*env.le(alice))[sfFlags] == origFlags);
144 env(fset(alice, flag), Sig(alice));
146 BEAST_EXPECT((*env.le(alice))[sfFlags] == origFlags);
147 env(fclear(alice, flag), Sig(alie));
149 BEAST_EXPECT((*env.le(alice))[sfFlags] == origFlags);
166 testcase(
"Set and reset AccountTxnID");
171 env.fund(XRP(10000), noripple(alice));
177 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfAccountTxnID));
178 env(fset(alice, asfAccountTxnID), Sig(alice));
179 BEAST_EXPECT(env.le(alice)->isFieldPresent(sfAccountTxnID));
180 env(fclear(alice, asfAccountTxnID));
181 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfAccountTxnID));
183 BEAST_EXPECT(nowFlags == origFlags);
194 env.fund(XRP(10000), noripple(alice));
196 env(regkey(alice,
"eric"));
198 env.require(Nflags(alice, asfNoFreeze));
200 env(fset(alice, asfNoFreeze), Sig(alice));
201 env.require(Flags(alice, asfNoFreeze));
202 env(fclear(alice, asfNoFreeze), Sig(alice));
204 env.require(Flags(alice, asfNoFreeze));
215 env.fund(XRP(10000), alice);
216 auto jt = noop(alice);
224 jt[sfDomain.fieldName] =
strHex(domain);
226 BEAST_EXPECT((*env.le(alice))[sfDomain] ==
makeSlice(domain));
228 jt[sfDomain.fieldName] =
"";
230 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfDomain));
236 for (
std::size_t len = maxLength - 1; len <= maxLength + 1; ++len)
240 BEAST_EXPECT(domain2.
length() == len);
242 jt[sfDomain.fieldName] =
strHex(domain2);
244 if (len <= maxLength)
247 BEAST_EXPECT((*env.le(alice))[sfDomain] ==
makeSlice(domain2));
264 env.fund(XRP(10000), alice);
265 auto jt = noop(alice);
268 jt[sfMessageKey.fieldName] =
strHex(rkp.first.slice());
270 BEAST_EXPECT(
strHex((*env.le(alice))[sfMessageKey]) ==
strHex(rkp.first.slice()));
272 jt[sfMessageKey.fieldName] =
"";
274 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfMessageKey));
276 using namespace std::string_literals;
277 jt[sfMessageKey.fieldName] =
strHex(
"NOT_REALLY_A_PUBKEY"s);
289 env.fund(XRP(10000), alice);
290 auto jt = noop(alice);
293 "9633EC8AF54F16B5286DB1D7B519EF49EEFC050C0C8AC4384F1D88ACD1BFDF05";
294 jt[sfWalletLocator.fieldName] = locator;
296 BEAST_EXPECT(
to_string((*env.le(alice))[sfWalletLocator]) == locator);
298 jt[sfWalletLocator.fieldName] =
"";
300 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfWalletLocator));
311 env.fund(XRP(10000), alice);
312 auto jt = noop(alice);
314 std::string const mh(
"5F31A79367DC3137FADA860C05742EE6");
315 jt[sfEmailHash.fieldName] = mh;
317 BEAST_EXPECT(
to_string((*env.le(alice))[sfEmailHash]) == mh);
319 jt[sfEmailHash.fieldName] =
"";
321 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfEmailHash));
339 Env env(*
this, features);
342 env.fund(XRP(10000), alice);
344 for (
auto const& r : testData)
346 env(rate(alice, r.set), Ter(r.code));
350 if (!(*env.le(alice))[~sfTransferRate])
352 BEAST_EXPECT(r.get == 1.0);
356 BEAST_EXPECT(*(*env.le(alice))[~sfTransferRate] == r.get * QUALITY_ONE);
362 testableAmendments(),
363 {{.set = 1.0, .code =
tesSUCCESS, .get = 1.0},
382 auto const usd = gw[
"USD"];
389 env.fund(XRP(10000), gw, alice, bob);
391 env.trust(usd(10), alice, bob);
396 auto const amount = usd(1);
400 env(pay(gw, alice, usd(10)));
402 env(pay(alice, bob, usd(1)), Sendmax(usd(10)));
405 env.require(Balance(alice, usd(10) - amountWithRate));
406 env.require(Balance(bob, usd(1)));
420 env.fund(XRP(10000), gw, alice, bob);
422 env.trust(usd(10), alice, bob);
436 uint256 const nftId0{token::getNextID(env, gw, 0u)};
437 env(token::mint(gw, 0u));
440 env(token::burn(gw, nftId0));
456 (*replacement)[sfTransferRate] =
462 auto const amount = usd(1);
463 auto const amountWithRate =
466 env(pay(gw, alice, usd(10)));
467 env(pay(alice, bob, amount), Sendmax(usd(10)));
469 env.require(Balance(alice, usd(10) - amountWithRate));
470 env.require(Balance(bob, amount));
482 env.fund(XRP(10000), alice);
484 auto jt = fset(alice, asfDisallowXRP);
485 jt[jss::ClearFlag] = asfDisallowXRP;
488 jt = fset(alice, asfRequireAuth);
489 jt[jss::ClearFlag] = asfRequireAuth;
492 jt = fset(alice, asfRequireDest);
493 jt[jss::ClearFlag] = asfRequireDest;
496 jt = fset(alice, asfDisallowXRP);
497 jt[sfFlags.fieldName] = tfAllowXRP;
500 jt = fset(alice, asfRequireAuth);
501 jt[sfFlags.fieldName] = tfOptionalAuth;
504 jt = fset(alice, asfRequireDest);
505 jt[sfFlags.fieldName] = tfOptionalDestTag;
508 jt = fset(alice, asfRequireDest);
509 jt[sfFlags.fieldName] = tfAccountSetMask;
525 env.fund(XRP(10000), alice);
532 env(signers(alice, 1, {{bob, 1}}));
536 env(fset(alice, asfRequireAuth), Ter(
tecOWNERS));
543 env(fset(alice, asfRequireAuth));
553 env.fund(XRP(10000), alice);
557 env(ticket::create(alice, 1));
559 env.require(Owners(alice, 1), tickets(alice, 1));
562 env(noop(alice), ticket::Use(ticketSeq + 1), Ter(
terPRE_TICKET));
564 env.require(Owners(alice, 1), tickets(alice, 1));
569 env(noop(alice), ticket::Use(ticketSeq));
571 env.require(Owners(alice, 0), tickets(alice, 0));
572 BEAST_EXPECT(aliceSeq == env.seq(alice));
575 env(noop(alice), ticket::Use(ticketSeq), Ter(
tefNO_TICKET));
587 env.fund(XRP(10000), alice);
591 if (!BEAST_EXPECT(jtx.stx))
599 BEAST_EXPECT(!result.applied);
600 return result.applied;
A generic endpoint for log messages.
TestcaseT testcase
Memberspace for declaring test cases.
void testRequireAuthWithDir()
void testNullAccountSet()
void testSetAndResetAccountTxnID()
void run() override
Runs the suite.
Writable ledger view that accumulates state and tx changes.
SLE::const_pointer read(Keylet const &k) const override
Return the state item associated with a key.
void rawReplace(SLE::ref sle) override
Unconditionally replace a state item.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet account(AccountID const &id) noexcept
AccountID root.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool set(T &target, std::string const &name, Section const §ion)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
bool dirIsEmpty(ReadView const &view, Keylet const &k)
Returns true if the directory is empty.
ApplyResult apply(ServiceRegistry ®istry, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
T get(Section const §ion, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
std::string strHex(FwdIt begin, FwdIt end)
BEAST_DEFINE_TESTSUITE_PRIO(AccountSet, app, xrpl, 1)
std::string to_string(BaseUInt< Bits, Tag > const &a)
Slice makeSlice(std::array< T, N > const &a)
Rate transferRate(ReadView const &view, AccountID const &issuer)
Returns IOU issuer transfer fee as Rate.
TERSubset< CanCvtToTER > TER
STAmount multiply(STAmount const &amount, Number const &frac, Number::RoundingMode rm)
STAmount toAmount< STAmount >(STAmount const &amt)
Represents a transfer rate.