19#include <test/jtx/delegate.h>
21#include <xrpl/protocol/Feature.h>
22#include <xrpl/protocol/Permissions.h>
31 testcase(
"test featurePermissionDelegation not enabled");
38 env.fund(
XRP(1000000), gw, alice, bob);
51 testcase(
"test valid request creating, updating, deleting permissions");
57 env.
fund(
XRP(100000), gw, alice);
65 BEAST_EXPECT(entry[jss::result][jss::error] ==
"entryNotFound");
78 auto comparePermissions =
84 !jle[jss::result].isMember(jss::error) &&
85 jle[jss::result].isMember(jss::node));
87 jle[jss::result][jss::node][
"LedgerEntryType"] ==
90 jle[jss::result][jss::node][jss::Account] ==
93 jle[jss::result][jss::node][sfAuthorize.jsonName] ==
96 auto const& jPermissions =
97 jle[jss::result][jss::node][sfPermissions.jsonName];
99 for (
auto const& permission : permissions)
102 jPermissions[i][sfPermission.jsonName]
103 [sfPermissionValue.jsonName] == permission);
114 "Payment",
"AMMCreate",
"AMMDeposit",
"AMMWithdraw"};
129 BEAST_EXPECT(jle[jss::result][jss::error] ==
"entryNotFound");
138 BEAST_EXPECT(response[jss::result][jss::error] ==
"entryNotFound");
144 testcase(
"test invalid DelegateSet");
151 env.
fund(
XRP(100000), gw, alice, bob);
182 jv[jss::TransactionType] = jss::DelegateSet;
183 jv[jss::Account] = gw.human();
184 jv[sfAuthorize.jsonName] = alice.human();
187 permissionValue[sfPermissionValue.jsonName] =
"Payment";
189 permissionObj[sfPermission.jsonName] = permissionValue;
190 permissionsJson.
append(permissionObj);
191 jv[sfPermissions.jsonName] = permissionsJson;
192 jv[sfFee.jsonName] = -1;
205 "TrustlineAuthorize",
207 "TrustlineAuthorize"}),
253 drops(env.
current()->fees().accountReserve(1)), bob, carol);
307 env.
fund(
XRP(10000), alice, carol);
316 auto aliceBalance = env.
balance(alice);
317 auto bobBalance = env.
balance(bob);
318 auto carolBalance = env.
balance(carol);
320 env(
pay(alice, carol,
XRP(100)),
325 BEAST_EXPECT(env.
balance(alice) == aliceBalance);
326 BEAST_EXPECT(env.
balance(bob) == bobBalance);
327 BEAST_EXPECT(env.
balance(carol) == carolBalance);
335 auto aliceBalance = env.
balance(alice);
336 auto bobBalance = env.
balance(bob);
337 auto carolBalance = env.
balance(carol);
339 auto const sendAmt =
XRP(100);
340 auto const feeAmt =
XRP(10);
343 BEAST_EXPECT(env.
balance(alice) == aliceBalance - sendAmt);
344 BEAST_EXPECT(env.
balance(bob) == bobBalance - feeAmt);
345 BEAST_EXPECT(env.
balance(carol) == carolBalance + sendAmt);
350 auto aliceBalance = env.
balance(alice);
351 auto bobBalance = env.
balance(bob);
352 auto carolBalance = env.
balance(carol);
354 env(
pay(alice, carol,
XRP(100)),
359 BEAST_EXPECT(env.
balance(alice) == aliceBalance);
360 BEAST_EXPECT(env.
balance(bob) == bobBalance);
361 BEAST_EXPECT(env.
balance(carol) == carolBalance);
367 auto aliceBalance = env.
balance(alice);
368 auto bobBalance = env.
balance(bob);
369 auto carolBalance = env.
balance(carol);
370 auto const feeAmt =
XRP(10);
372 env(
pay(alice, carol,
XRP(20000)),
377 BEAST_EXPECT(env.
balance(alice) == aliceBalance);
378 BEAST_EXPECT(env.
balance(bob) == bobBalance - feeAmt);
379 BEAST_EXPECT(env.
balance(carol) == carolBalance);
393 env.
fund(
XRP(10000), alice, bob, carol);
396 auto aliceSeq = env.
seq(alice);
397 auto bobSeq = env.
seq(bob);
401 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
402 BEAST_EXPECT(env.
seq(bob) == bobSeq + 1);
403 aliceSeq = env.
seq(alice);
404 bobSeq = env.
seq(bob);
406 for (
auto i = 0; i < 20; ++i)
411 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
412 BEAST_EXPECT(env.
seq(bob) == bobSeq);
413 aliceSeq = env.
seq(alice);
417 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
418 BEAST_EXPECT(env.
seq(bob) == bobSeq + 1);
419 bobSeq = env.
seq(bob);
424 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
425 BEAST_EXPECT(env.
seq(bob) == bobSeq + 1);
426 bobSeq = env.
seq(bob);
430 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
431 BEAST_EXPECT(env.
seq(bob) == bobSeq);
432 aliceSeq = env.
seq(alice);
445 env.
fund(
XRP(100000), alice, bob);
456 auto const aliceBalance = env.
balance(alice);
457 auto const bobBalance = env.
balance(bob);
460 auto const deleteFee =
drops(env.
current()->fees().increment);
466 BEAST_EXPECT(env.
balance(bob) == bobBalance + aliceBalance - deleteFee);
475 testcase(
"test delegate transaction");
551 auto const USD = gw[
"USD"];
552 auto const EUR = gw2[
"EUR"];
557 env.
trust(USD(200), alice);
558 env.
trust(EUR(400), gw);
568 env(
pay(gw, alice, USD(50)),
581 env(
pay(gw, alice, USD(50)),
598 env(
pay(gw, alice,
XRP(50)),
612 BEAST_EXPECT(env.
balance(bob, USD) == USD(0));
622 BEAST_EXPECT(env.
balance(bob, USD) == USD(0));
640 env(
pay(gw2, gw, EUR(200)));
664 auto const USD = gw[
"USD"];
669 env.
trust(USD(200), alice);
686 env(
pay(gw, alice, USD(50)),
707 BEAST_EXPECT(env.
balance(bob, USD) == USD(0));
714 testcase(
"test TrustSet granular permissions");
723 env.
fund(
XRP(10000), gw, alice, bob);
731 env(
trust(alice, gw[
"USD"](50)),
737 env(
trust(alice, gw[
"USD"](50)));
785 gw, bob, {
"TrustlineAuthorize",
"TrustlineFreeze"}));
790 gw, bob, {
"TrustlineAuthorize",
"TrustlineUnfreeze"}));
803 env(
trust(alice, gw[
"USD"](100)),
806 env(
trust(gw, alice[
"USD"](100)),
811 auto tx =
trust(alice, gw[
"USD"](50));
812 tx[
"QualityIn"] =
"1000";
814 auto tx2 =
trust(alice, gw[
"USD"](50));
815 tx2[
"QualityOut"] =
"1000";
817 auto tx3 =
trust(gw, alice[
"USD"](50));
818 tx3[
"QualityIn"] =
"1000";
820 auto tx4 =
trust(gw, alice[
"USD"](50));
821 tx4[
"QualityOut"] =
"1000";
827 auto tx5 =
trust(gw, alice[
"USD"](50));
828 tx5[
"QualityOut"] =
"1000";
830 auto tx6 =
trust(alice, gw[
"USD"](50));
831 tx6[
"QualityOut"] =
"1000";
844 env.
fund(
XRP(10000), gw, alice, bob);
849 env(
trust(alice, gw[
"USD"](50)),
853 alice, bob, {
"TrustlineUnfreeze",
"NFTokenCreateOffer"}));
856 env(
trust(alice, gw[
"USD"](50)),
864 {
"TrustlineUnfreeze",
865 "NFTokenCreateOffer",
867 "AccountTransferRateSet"}));
875 {
"TrustlineUnfreeze",
876 "NFTokenCreateOffer",
878 "AccountTransferRateSet"}));
904 env.
fund(
XRP(10000), gw, alice, bob);
907 env(
trust(alice, gw[
"USD"](50)));
921 testcase(
"test AccountSet granular permissions");
929 auto const alice =
Account{
"alice"};
930 auto const bob =
Account{
"bob"};
931 env.
fund(
XRP(10000), alice, bob);
942 auto jt =
noop(alice);
944 jt[sfDelegate] = bob.human();
949 alice, bob, {
"TrustlineUnfreeze",
"AccountEmailHashSet"}));
964 BEAST_EXPECT(!env.
le(alice)->isFieldPresent(sfDomain));
967 std::string const failDomain =
"fail_domain_update";
969 jt[sfDomain] =
strHex(failDomain);
977 std::string const mh(
"5F31A79367DC3137FADA860C05742EE6");
978 jt[sfEmailHash] = mh;
983 alice, bob, {
"AccountDomainSet",
"AccountEmailHashSet"}));
986 BEAST_EXPECT(
to_string((*env.
le(alice))[sfEmailHash]) == mh);
991 jt[sfMessageKey] =
strHex(rkp.first.slice());
999 "AccountEmailHashSet",
1000 "AccountMessageKeySet"}));
1006 strHex((*env.
le(alice))[sfMessageKey]) ==
1007 strHex(rkp.first.slice()));
1008 jt[sfMessageKey] =
"";
1010 BEAST_EXPECT(!env.
le(alice)->isFieldPresent(sfMessageKey));
1013 env(
rate(alice, 2.0),
1021 {
"AccountDomainSet",
1022 "AccountEmailHashSet",
1023 "AccountMessageKeySet",
1024 "AccountTransferRateSet"}));
1026 auto jtRate =
rate(alice, 2.0);
1027 jtRate[sfDelegate] = bob.human();
1029 BEAST_EXPECT((*env.
le(alice))[sfTransferRate] == 2000000000);
1039 {
"AccountDomainSet",
1040 "AccountEmailHashSet",
1041 "AccountMessageKeySet",
1042 "AccountTransferRateSet",
1043 "AccountTickSizeSet"}));
1046 BEAST_EXPECT((*env.
le(alice))[sfTickSize] == 8);
1073 {
"AccountDomainSet",
1074 "AccountEmailHashSet",
1075 "AccountMessageKeySet"}));
1080 "9633EC8AF54F16B5286DB1D7B519EF49EEFC050C0C8AC4384F1D88ACD1BFDF"
1082 auto jv2 =
noop(alice);
1084 jv2[sfDelegate] = bob.human();
1085 jv2[sfWalletLocator] = locator;
1092 auto const alice =
Account{
"alice"};
1093 auto const bob =
Account{
"bob"};
1094 env.
fund(
XRP(10000), alice, bob);
1099 env(
fset(alice, flag),
1103 env(
fset(alice, flag));
1120 {
"AccountDomainSet",
1121 "AccountEmailHashSet",
1122 "AccountMessageKeySet"}));
1141 BEAST_EXPECT(env.
le(alice)->isFieldPresent(sfAccountTxnID));
1148 jt[sfDelegate] = bob.human();
1149 jt[sfNFTokenMinter] = bob.human();
1156 {
"AccountDomainSet",
1157 "AccountEmailHashSet",
1158 "AccountMessageKeySet"}));
1177 env(
regkey(bob, bobKey));
1190 env.
fund(
XRP(10000), alice, bob);
1194 alice, bob, {
"AccountDomainSet",
"AccountEmailHashSet"}));
1198 auto jt =
noop(alice);
1200 jt[sfDelegate] = bob.human();
1211 testcase(
"test MPTokenIssuanceSet granular");
1212 using namespace jtx;
1219 env.
fund(
XRP(100000), alice, bob);
1246 mpt.set({.account = alice, .flags =
tfMPTLock, .delegate = bob});
1255 alice, bob, {
"MPTokenIssuanceLock",
"MPTokenIssuanceUnlock"}));
1257 mpt.set({.account = alice, .flags =
tfMPTUnlock, .delegate = bob});
1258 mpt.set({.account = alice, .flags =
tfMPTLock, .delegate = bob});
1267 env.
fund(
XRP(100000), alice, bob);
1278 mpt.set({.account = alice, .flags =
tfMPTLock, .delegate = bob});
1291 {
"NFTokenMint",
"MPTokenIssuanceLock",
"NFTokenBurn"}));
1305 "MPTokenIssuanceLock",
1307 "MPTokenIssuanceSet"}));
1308 mpt.set({.account = alice, .flags =
tfMPTUnlock, .delegate = bob});
1310 mpt.set({.account = alice, .flags =
tfMPTLock});
1311 mpt.set({.account = alice, .flags =
tfMPTUnlock, .delegate = bob});
1312 mpt.set({.account = alice, .flags =
tfMPTLock, .delegate = bob});
1320 env.
fund(
XRP(100000), alice, bob);
1342 using namespace jtx;
1348 env.
fund(
XRP(100000), alice, bob, carol);
1354 auto aliceBalance = env.
balance(alice);
1355 auto bobBalance = env.
balance(bob);
1356 auto carolBalance = env.
balance(carol);
1358 env(
pay(alice, carol,
XRP(100)),
1363 BEAST_EXPECT(env.
balance(alice) == aliceBalance -
XRP(100));
1364 BEAST_EXPECT(env.
balance(bob) == bobBalance -
XRP(10));
1365 BEAST_EXPECT(env.
balance(carol) == carolBalance +
XRP(100));
1371 testcase(
"test single sign with bad secret");
1372 using namespace jtx;
1378 env.
fund(
XRP(100000), alice, bob, carol);
1384 auto aliceBalance = env.
balance(alice);
1385 auto bobBalance = env.
balance(bob);
1386 auto carolBalance = env.
balance(carol);
1388 env(
pay(alice, carol,
XRP(100)),
1394 BEAST_EXPECT(env.
balance(alice) == aliceBalance);
1395 BEAST_EXPECT(env.
balance(bob) == bobBalance);
1396 BEAST_EXPECT(env.
balance(carol) == carolBalance);
1403 using namespace jtx;
1411 env.
fund(
XRP(100000), alice, bob, carol, daria, edward);
1414 env(
signers(bob, 2, {{daria, 1}, {edward, 1}}));
1420 auto aliceBalance = env.
balance(alice);
1421 auto bobBalance = env.
balance(bob);
1422 auto carolBalance = env.
balance(carol);
1423 auto dariaBalance = env.
balance(daria);
1424 auto edwardBalance = env.
balance(edward);
1426 env(
pay(alice, carol,
XRP(100)),
1429 msig(daria, edward));
1431 BEAST_EXPECT(env.
balance(alice) == aliceBalance -
XRP(100));
1432 BEAST_EXPECT(env.
balance(bob) == bobBalance -
XRP(10));
1433 BEAST_EXPECT(env.
balance(carol) == carolBalance +
XRP(100));
1434 BEAST_EXPECT(env.
balance(daria) == dariaBalance);
1435 BEAST_EXPECT(env.
balance(edward) == edwardBalance);
1441 testcase(
"test multi sign which does not meet quorum");
1442 using namespace jtx;
1451 env.
fund(
XRP(100000), alice, bob, carol, daria, edward, fred);
1454 env(
signers(bob, 3, {{daria, 1}, {edward, 1}, {fred, 1}}));
1460 auto aliceBalance = env.
balance(alice);
1461 auto bobBalance = env.
balance(bob);
1462 auto carolBalance = env.
balance(carol);
1463 auto dariaBalance = env.
balance(daria);
1464 auto edwardBalance = env.
balance(edward);
1466 env(
pay(alice, carol,
XRP(100)),
1469 msig(daria, edward),
1472 BEAST_EXPECT(env.
balance(alice) == aliceBalance);
1473 BEAST_EXPECT(env.
balance(bob) == bobBalance);
1474 BEAST_EXPECT(env.
balance(carol) == carolBalance);
1475 BEAST_EXPECT(env.
balance(daria) == dariaBalance);
1476 BEAST_EXPECT(env.
balance(edward) == edwardBalance);
1500BEAST_DEFINE_TESTSUITE(Delegate, app,
ripple);
Value & append(Value const &value)
Append value to array at the end.
testcase_t testcase
Memberspace for declaring test cases.
void testFeatureDisabled()
void testTrustSetGranular()
void run() override
Runs the suite.
void testMPTokenIssuanceSetGranular()
void testInvalidRequest()
void testPaymentGranular()
void testSingleSignBadSecret()
void testDelegateTransaction()
void testMultiSignQuorumNotMet()
void testAccountSetGranular()
Immutable cryptographic account descriptor.
A transaction testing environment.
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
void require(Args const &... args)
Check a set of requirements.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Sets the optional URI on a DIDSet.
Set a multisignature on a JTx.
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.
@ arrayValue
array value (ordered list)
Keylet delegate(AccountID const &account, AccountID const &authorizedAccount) noexcept
A keylet for Delegate object.
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Json::Value create(A const &account, A const &dest, STAmount const &sendMax)
Create a check.
Json::Value entry(jtx::Env &env, jtx::Account const &account, jtx::Account const &authorize)
Json::Value set(jtx::Account const &account, jtx::Account const &authorize, std::vector< std::string > const &permissions)
Json::Value set(jtx::Account const &account)
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
Json::Value regkey(Account const &account, disabled_t)
Disable the regular key.
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
FeatureBitset testable_amendments()
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
Json::Value acctdelete(Account const &account, Account const &dest)
Delete account.
XRP_t const XRP
Converts to XRP Issue or STAmount.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t asfGlobalFreeze
constexpr std::uint32_t asfDepositAuth
constexpr std::uint32_t asfDisallowIncomingNFTokenOffer
constexpr std::uint32_t tfSetDeepFreeze
constexpr std::uint32_t asfRequireDest
constexpr std::uint32_t const tfMPTUnlock
constexpr std::uint32_t asfAuthorizedNFTokenMinter
constexpr std::uint32_t asfNoFreeze
constexpr std::uint32_t asfDisableMaster
constexpr std::uint32_t asfDisallowIncomingTrustline
constexpr std::uint32_t tfClearNoRipple
std::string strHex(FwdIt begin, FwdIt end)
constexpr std::uint32_t tfSetfAuth
constexpr std::uint32_t asfAccountTxnID
constexpr std::uint32_t asfDefaultRipple
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
constexpr std::uint32_t asfDisallowIncomingCheck
constexpr std::uint32_t tfClearFreeze
constexpr std::uint32_t tfRequireAuth
@ tecNO_DELEGATE_PERMISSION
@ tecINSUFFICIENT_RESERVE
constexpr std::uint32_t const tfMPTLock
constexpr std::uint32_t tfClearDeepFreeze
std::string to_string(base_uint< Bits, Tag > const &a)
constexpr std::uint32_t asfDisallowIncomingPayChan
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
constexpr std::uint32_t tfFullyCanonicalSig
Transaction flags.
constexpr std::uint32_t asfAllowTrustLineClawback
constexpr std::uint32_t asfRequireAuth
constexpr std::uint32_t tfSetFreeze
constexpr std::uint32_t tfSetNoRipple
constexpr std::uint32_t const tfMPTCanLock
constexpr std::uint32_t asfDisallowXRP