2#include <test/jtx/Account.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/amount.h>
5#include <test/jtx/balance.h>
6#include <test/jtx/flags.h>
7#include <test/jtx/multisign.h>
8#include <test/jtx/noop.h>
9#include <test/jtx/owners.h>
10#include <test/jtx/pay.h>
11#include <test/jtx/rate.h>
12#include <test/jtx/regkey.h>
13#include <test/jtx/sendmax.h>
14#include <test/jtx/sig.h>
15#include <test/jtx/tags.h>
16#include <test/jtx/ter.h>
17#include <test/jtx/ticket.h>
18#include <test/jtx/token.h>
20#include <xrpl/basics/Slice.h>
21#include <xrpl/basics/base_uint.h>
22#include <xrpl/basics/strHex.h>
23#include <xrpl/beast/unit_test/suite.h>
24#include <xrpl/beast/utility/Journal.h>
25#include <xrpl/core/ServiceRegistry.h>
26#include <xrpl/ledger/ApplyView.h>
27#include <xrpl/ledger/OpenView.h>
28#include <xrpl/ledger/helpers/DirectoryHelpers.h>
29#include <xrpl/protocol/AmountConversions.h>
30#include <xrpl/protocol/Feature.h>
31#include <xrpl/protocol/Indexes.h>
32#include <xrpl/protocol/KeyType.h>
33#include <xrpl/protocol/Quality.h>
34#include <xrpl/protocol/Rate.h>
35#include <xrpl/protocol/SField.h>
36#include <xrpl/protocol/STAmount.h>
37#include <xrpl/protocol/STTx.h>
38#include <xrpl/protocol/SecretKey.h>
39#include <xrpl/protocol/TER.h>
40#include <xrpl/protocol/TxFlags.h>
41#include <xrpl/protocol/jss.h>
42#include <xrpl/tx/apply.h>
65 env.fund(XRP(10000), noripple(alice));
67 auto const jrr = env.le(alice);
68 BEAST_EXPECT(jrr && jrr->at(sfFlags) == 0u);
79 Env env(*
this, testableAmendments());
80 env.fund(XRP(10000), noripple(alice));
85 env(regkey(alice, alie));
88 auto testFlags = [
this, &alice, &alie, &env](
91 for (
std::uint32_t flag{1u}; flag < std::numeric_limits<std::uint32_t>::digits; ++flag)
93 if (flag == asfNoFreeze)
100 if (flag == asfAuthorizedNFTokenMinter)
108 if (flag == asfDisallowIncomingCheck || flag == asfDisallowIncomingPayChan ||
109 flag == asfDisallowIncomingNFTokenOffer || flag == asfDisallowIncomingTrustline)
115 if (flag == asfAllowTrustLineClawback)
121 if (flag == asfAllowTrustLineLocking)
131 env.require(Nflags(alice, flag));
132 env(fset(alice, flag), Sig(alice));
134 env.require(Flags(alice, flag));
135 env(fclear(alice, flag), Sig(alie));
137 env.require(Nflags(alice, flag));
139 BEAST_EXPECT(nowFlags == origFlags);
144 BEAST_EXPECT((*env.le(alice))[sfFlags] == origFlags);
145 env(fset(alice, flag), Sig(alice));
147 BEAST_EXPECT((*env.le(alice))[sfFlags] == origFlags);
148 env(fclear(alice, flag), Sig(alie));
150 BEAST_EXPECT((*env.le(alice))[sfFlags] == origFlags);
167 testcase(
"Set and reset AccountTxnID");
172 env.fund(XRP(10000), noripple(alice));
178 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfAccountTxnID));
179 env(fset(alice, asfAccountTxnID), Sig(alice));
180 BEAST_EXPECT(env.le(alice)->isFieldPresent(sfAccountTxnID));
181 env(fclear(alice, asfAccountTxnID));
182 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfAccountTxnID));
184 BEAST_EXPECT(nowFlags == origFlags);
195 env.fund(XRP(10000), noripple(alice));
197 env(regkey(alice,
"eric"));
199 env.require(Nflags(alice, asfNoFreeze));
201 env(fset(alice, asfNoFreeze), Sig(alice));
202 env.require(Flags(alice, asfNoFreeze));
203 env(fclear(alice, asfNoFreeze), Sig(alice));
205 env.require(Flags(alice, asfNoFreeze));
216 env.fund(XRP(10000), alice);
217 auto jt = noop(alice);
225 jt[sfDomain.fieldName] =
strHex(domain);
227 BEAST_EXPECT((*env.le(alice))[sfDomain] ==
makeSlice(domain));
229 jt[sfDomain.fieldName] =
"";
231 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfDomain));
237 for (
std::size_t len = maxLength - 1; len <= maxLength + 1; ++len)
241 BEAST_EXPECT(domain2.
length() == len);
243 jt[sfDomain.fieldName] =
strHex(domain2);
245 if (len <= maxLength)
248 BEAST_EXPECT((*env.le(alice))[sfDomain] ==
makeSlice(domain2));
265 env.fund(XRP(10000), alice);
266 auto jt = noop(alice);
269 jt[sfMessageKey.fieldName] =
strHex(rkp.first.slice());
271 BEAST_EXPECT(
strHex((*env.le(alice))[sfMessageKey]) ==
strHex(rkp.first.slice()));
273 jt[sfMessageKey.fieldName] =
"";
275 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfMessageKey));
277 using namespace std::string_literals;
278 jt[sfMessageKey.fieldName] =
strHex(
"NOT_REALLY_A_PUBKEY"s);
290 env.fund(XRP(10000), alice);
291 auto jt = noop(alice);
294 "9633EC8AF54F16B5286DB1D7B519EF49EEFC050C0C8AC4384F1D88ACD1BFDF05";
295 jt[sfWalletLocator.fieldName] = locator;
297 BEAST_EXPECT(
to_string((*env.le(alice))[sfWalletLocator]) == locator);
299 jt[sfWalletLocator.fieldName] =
"";
301 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfWalletLocator));
312 env.fund(XRP(10000), alice);
313 auto jt = noop(alice);
315 std::string const mh(
"5F31A79367DC3137FADA860C05742EE6");
316 jt[sfEmailHash.fieldName] = mh;
318 BEAST_EXPECT(
to_string((*env.le(alice))[sfEmailHash]) == mh);
320 jt[sfEmailHash.fieldName] =
"";
322 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfEmailHash));
340 Env env(*
this, features);
343 env.fund(XRP(10000), alice);
345 for (
auto const& r : testData)
347 env(rate(alice, r.set), Ter(r.code));
351 if (!(*env.le(alice))[~sfTransferRate])
353 BEAST_EXPECT(r.get == 1.0);
357 BEAST_EXPECT(*(*env.le(alice))[~sfTransferRate] == r.get * QUALITY_ONE);
363 testableAmendments(),
364 {{.set = 1.0, .code =
tesSUCCESS, .get = 1.0},
383 auto const usd = gw[
"USD"];
390 env.fund(XRP(10000), gw, alice, bob);
392 env.trust(usd(10), alice, bob);
397 auto const amount = usd(1);
401 env(pay(gw, alice, usd(10)));
403 env(pay(alice, bob, usd(1)), Sendmax(usd(10)));
406 env.require(Balance(alice, usd(10) - amountWithRate));
407 env.require(Balance(bob, usd(1)));
421 env.fund(XRP(10000), gw, alice, bob);
423 env.trust(usd(10), alice, bob);
437 uint256 const nftId0{token::getNextID(env, gw, 0u)};
438 env(token::mint(gw, 0u));
441 env(token::burn(gw, nftId0));
457 (*replacement)[sfTransferRate] =
463 auto const amount = usd(1);
464 auto const amountWithRate =
467 env(pay(gw, alice, usd(10)));
468 env(pay(alice, bob, amount), Sendmax(usd(10)));
470 env.require(Balance(alice, usd(10) - amountWithRate));
471 env.require(Balance(bob, amount));
483 env.fund(XRP(10000), alice);
485 auto jt = fset(alice, asfDisallowXRP);
486 jt[jss::ClearFlag] = asfDisallowXRP;
489 jt = fset(alice, asfRequireAuth);
490 jt[jss::ClearFlag] = asfRequireAuth;
493 jt = fset(alice, asfRequireDest);
494 jt[jss::ClearFlag] = asfRequireDest;
497 jt = fset(alice, asfDisallowXRP);
498 jt[sfFlags.fieldName] = tfAllowXRP;
501 jt = fset(alice, asfRequireAuth);
502 jt[sfFlags.fieldName] = tfOptionalAuth;
505 jt = fset(alice, asfRequireDest);
506 jt[sfFlags.fieldName] = tfOptionalDestTag;
509 jt = fset(alice, asfRequireDest);
510 jt[sfFlags.fieldName] = tfAccountSetMask;
526 env.fund(XRP(10000), alice);
533 env(signers(alice, 1, {{bob, 1}}));
537 env(fset(alice, asfRequireAuth), Ter(
tecOWNERS));
544 env(fset(alice, asfRequireAuth));
554 env.fund(XRP(10000), alice);
558 env(ticket::create(alice, 1));
560 env.require(Owners(alice, 1), tickets(alice, 1));
563 env(noop(alice), ticket::Use(ticketSeq + 1), Ter(
terPRE_TICKET));
565 env.require(Owners(alice, 1), tickets(alice, 1));
570 env(noop(alice), ticket::Use(ticketSeq));
572 env.require(Owners(alice, 0), tickets(alice, 0));
573 BEAST_EXPECT(aliceSeq == env.seq(alice));
576 env(noop(alice), ticket::Use(ticketSeq), Ter(
tefNO_TICKET));
588 env.fund(XRP(10000), alice);
592 if (!BEAST_EXPECT(jtx.stx))
600 BEAST_EXPECT(!result.applied);
601 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)
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)
std::enable_if_t< std::is_same_v< T, char >||std::is_same_v< T, unsigned char >, Slice > makeSlice(std::array< T, N > const &a)
STAmount toAmount< STAmount >(STAmount const &amt)
Represents a transfer rate.