Merge remote-tracking branch 'upstream/develop' into sponsor

This commit is contained in:
tequ
2026-01-29 11:22:42 +09:00
1026 changed files with 27864 additions and 68510 deletions

View File

@@ -22,8 +22,7 @@ class Delegate_test : public beast::unit_test::suite
env.fund(XRP(1000000), gw, alice, bob);
env.close();
auto res = features[featurePermissionDelegationV1_1] ? ter(tesSUCCESS)
: ter(temDISABLED);
auto res = features[featurePermissionDelegationV1_1] ? ter(tesSUCCESS) : ter(temDISABLED);
// can not set Delegate when feature disabled
env(delegate::set(gw, alice, {"Payment"}), res);
@@ -52,61 +51,42 @@ class Delegate_test : public beast::unit_test::suite
auto const entry = delegate::entry(env, gw, alice);
BEAST_EXPECT(entry[jss::result][jss::error] == "entryNotFound");
auto const permissions = std::vector<std::string>{
"Payment",
"EscrowCreate",
"EscrowFinish",
"TrustlineAuthorize",
"CheckCreate"};
auto const permissions =
std::vector<std::string>{"Payment", "EscrowCreate", "EscrowFinish", "TrustlineAuthorize", "CheckCreate"};
env(delegate::set(gw, alice, permissions));
env.close();
// this lambda function is used to compare the json value of ledger
// entry response with the given vector of permissions.
auto comparePermissions =
[&](Json::Value const& jle,
std::vector<std::string> const& permissions,
Account const& account,
Account const& authorize) {
BEAST_EXPECT(
!jle[jss::result].isMember(jss::error) &&
jle[jss::result].isMember(jss::node));
BEAST_EXPECT(
jle[jss::result][jss::node]["LedgerEntryType"] ==
jss::Delegate);
BEAST_EXPECT(
jle[jss::result][jss::node][jss::Account] ==
account.human());
BEAST_EXPECT(
jle[jss::result][jss::node][sfAuthorize.jsonName] ==
authorize.human());
auto comparePermissions = [&](Json::Value const& jle,
std::vector<std::string> const& permissions,
Account const& account,
Account const& authorize) {
BEAST_EXPECT(!jle[jss::result].isMember(jss::error) && jle[jss::result].isMember(jss::node));
BEAST_EXPECT(jle[jss::result][jss::node]["LedgerEntryType"] == jss::Delegate);
BEAST_EXPECT(jle[jss::result][jss::node][jss::Account] == account.human());
BEAST_EXPECT(jle[jss::result][jss::node][sfAuthorize.jsonName] == authorize.human());
auto const& jPermissions =
jle[jss::result][jss::node][sfPermissions.jsonName];
unsigned i = 0;
for (auto const& permission : permissions)
{
BEAST_EXPECT(
jPermissions[i][sfPermission.jsonName]
[sfPermissionValue.jsonName] == permission);
i++;
}
};
auto const& jPermissions = jle[jss::result][jss::node][sfPermissions.jsonName];
unsigned i = 0;
for (auto const& permission : permissions)
{
BEAST_EXPECT(jPermissions[i][sfPermission.jsonName][sfPermissionValue.jsonName] == permission);
i++;
}
};
// get ledger entry with valid parameter
comparePermissions(
delegate::entry(env, gw, alice), permissions, gw, alice);
comparePermissions(delegate::entry(env, gw, alice), permissions, gw, alice);
// gw updates permission
auto const newPermissions = std::vector<std::string>{
"Payment", "AMMCreate", "AMMDeposit", "AMMWithdraw"};
auto const newPermissions = std::vector<std::string>{"Payment", "AMMCreate", "AMMDeposit", "AMMWithdraw"};
env(delegate::set(gw, alice, newPermissions));
env.close();
// get ledger entry again, permissions should be updated to
// newPermissions
comparePermissions(
delegate::entry(env, gw, alice), newPermissions, gw, alice);
comparePermissions(delegate::entry(env, gw, alice), newPermissions, gw, alice);
// gw deletes all permissions delegated to alice, this will delete
// the
@@ -119,8 +99,7 @@ class Delegate_test : public beast::unit_test::suite
// alice can delegate permissions to gw as well
env(delegate::set(alice, gw, permissions));
env.close();
comparePermissions(
delegate::entry(env, alice, gw), permissions, alice, gw);
comparePermissions(delegate::entry(env, alice, gw), permissions, alice, gw);
auto const response = delegate::entry(env, gw, alice);
// alice has not been granted any permissions by gw
BEAST_EXPECT(response[jss::result][jss::error] == "entryNotFound");
@@ -199,8 +178,7 @@ class Delegate_test : public beast::unit_test::suite
// when authorizing account which does not exist, should return
// tecNO_TARGET
{
env(delegate::set(gw, Account("unknown"), {"Payment"}),
ter(tecNO_TARGET));
env(delegate::set(gw, Account("unknown"), {"Payment"}), ter(tecNO_TARGET));
}
// non-delegable transaction
@@ -209,8 +187,7 @@ class Delegate_test : public beast::unit_test::suite
env(delegate::set(gw, alice, {"AccountSet"}), ter(temMALFORMED));
env(delegate::set(gw, alice, {"SignerListSet"}), ter(temMALFORMED));
env(delegate::set(gw, alice, {"DelegateSet"}), ter(temMALFORMED));
env(delegate::set(gw, alice, {"EnableAmendment"}),
ter(temMALFORMED));
env(delegate::set(gw, alice, {"EnableAmendment"}), ter(temMALFORMED));
env(delegate::set(gw, alice, {"UNLModify"}), ter(temMALFORMED));
env(delegate::set(gw, alice, {"SetFee"}), ter(temMALFORMED));
env(delegate::set(gw, alice, {"Batch"}), ter(temMALFORMED));
@@ -231,13 +208,11 @@ class Delegate_test : public beast::unit_test::suite
Account carol{"carol"};
env.fund(drops(env.current()->fees().accountReserve(0)), alice);
env.fund(
drops(env.current()->fees().accountReserve(1)), bob, carol);
env.fund(drops(env.current()->fees().accountReserve(1)), bob, carol);
env.close();
// alice does not have enough reserve to create Delegate
env(delegate::set(alice, bob, {"Payment"}),
ter(tecINSUFFICIENT_RESERVE));
env(delegate::set(alice, bob, {"Payment"}), ter(tecINSUFFICIENT_RESERVE));
// bob has enough reserve
env(delegate::set(bob, alice, {"Payment"}));
@@ -245,8 +220,7 @@ class Delegate_test : public beast::unit_test::suite
// now bob create another Delegate, he does not have
// enough reserve
env(delegate::set(bob, carol, {"Payment"}),
ter(tecINSUFFICIENT_RESERVE));
env(delegate::set(bob, carol, {"Payment"}), ter(tecINSUFFICIENT_RESERVE));
}
// test reserve when sending transaction on behalf of other account
@@ -265,10 +239,7 @@ class Delegate_test : public beast::unit_test::suite
// bob set DID on behalf of alice, but alice does not have enough
// reserve
env(did::set(alice),
did::uri("uri"),
delegate::as(bob),
ter(tecINSUFFICIENT_RESERVE));
env(did::set(alice), did::uri("uri"), delegate::as(bob), ter(tecINSUFFICIENT_RESERVE));
// bob can set DID for himself because he has enough reserve
env(did::set(bob), did::uri("uri"));
@@ -295,10 +266,7 @@ class Delegate_test : public beast::unit_test::suite
auto bobBalance = env.balance(bob);
auto carolBalance = env.balance(carol);
env(pay(alice, carol, XRP(100)),
fee(XRP(2000)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(pay(alice, carol, XRP(100)), fee(XRP(2000)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env.close();
BEAST_EXPECT(env.balance(alice) == aliceBalance);
BEAST_EXPECT(env.balance(bob) == bobBalance);
@@ -329,10 +297,7 @@ class Delegate_test : public beast::unit_test::suite
auto bobBalance = env.balance(bob);
auto carolBalance = env.balance(carol);
env(pay(alice, carol, XRP(100)),
fee(XRP(2000)),
delegate::as(bob),
ter(terINSUF_FEE_B));
env(pay(alice, carol, XRP(100)), fee(XRP(2000)), delegate::as(bob), ter(terINSUF_FEE_B));
env.close();
BEAST_EXPECT(env.balance(alice) == aliceBalance);
BEAST_EXPECT(env.balance(bob) == bobBalance);
@@ -347,10 +312,7 @@ class Delegate_test : public beast::unit_test::suite
auto carolBalance = env.balance(carol);
auto const feeAmt = XRP(10);
env(pay(alice, carol, XRP(20000)),
fee(feeAmt),
delegate::as(bob),
ter(tecUNFUNDED_PAYMENT));
env(pay(alice, carol, XRP(20000)), fee(feeAmt), delegate::as(bob), ter(tecUNFUNDED_PAYMENT));
env.close();
BEAST_EXPECT(env.balance(alice) == aliceBalance);
BEAST_EXPECT(env.balance(bob) == bobBalance - feeAmt);
@@ -425,8 +387,7 @@ class Delegate_test : public beast::unit_test::suite
env(delegate::set(alice, bob, {"Payment"}));
env.close();
BEAST_EXPECT(
env.closed()->exists(keylet::delegate(alice.id(), bob.id())));
BEAST_EXPECT(env.closed()->exists(keylet::delegate(alice.id(), bob.id())));
for (std::uint32_t i = 0; i < 256; ++i)
env.close();
@@ -443,8 +404,7 @@ class Delegate_test : public beast::unit_test::suite
BEAST_EXPECT(!env.closed()->exists(keylet::ownerDir(alice.id())));
BEAST_EXPECT(env.balance(bob) == bobBalance + aliceBalance - deleteFee);
BEAST_EXPECT(
!env.closed()->exists(keylet::delegate(alice.id(), bob.id())));
BEAST_EXPECT(!env.closed()->exists(keylet::delegate(alice.id(), bob.id())));
}
void
@@ -503,14 +463,10 @@ class Delegate_test : public beast::unit_test::suite
env.close();
// bob does not have permission to create check
env(check::create(alice, bob, XRP(10)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(check::create(alice, bob, XRP(10)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
// carol does not have permission to create check
env(check::create(alice, bob, XRP(10)),
delegate::as(carol),
ter(terNO_DELEGATE_PERMISSION));
env(check::create(alice, bob, XRP(10)), delegate::as(carol), ter(terNO_DELEGATE_PERMISSION));
}
void
@@ -543,9 +499,7 @@ class Delegate_test : public beast::unit_test::suite
auto gw2Balance = env.balance(gw2, XRP);
// delegate ledger object is not created yet
env(pay(gw, alice, USD(50)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(pay(gw, alice, USD(50)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env.require(balance(bob, bobBalance));
// gw gives bob burn permission
@@ -555,9 +509,7 @@ class Delegate_test : public beast::unit_test::suite
gwBalance = env.balance(gw, XRP);
// bob sends a payment transaction on behalf of gw
env(pay(gw, alice, USD(50)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(pay(gw, alice, USD(50)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env.close();
env.require(balance(bob, bobBalance));
@@ -571,9 +523,7 @@ class Delegate_test : public beast::unit_test::suite
gwBalance = env.balance(gw, XRP);
// can not send XRP
env(pay(gw, alice, XRP(50)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(pay(gw, alice, XRP(50)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env.close();
env.require(balance(bob, bobBalance));
@@ -658,9 +608,7 @@ class Delegate_test : public beast::unit_test::suite
// bob can not mint on behalf of gw because he only has burn
// permission
env(pay(gw, alice, USD(50)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(pay(gw, alice, USD(50)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env.close();
env.require(balance(bob, bobBalance));
@@ -767,8 +715,7 @@ class Delegate_test : public beast::unit_test::suite
Account const gw{"gateway"};
MPTTester mpt(env, gw, {.holders = {alice, bob}});
mpt.create(
{.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer});
mpt.create({.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer});
mpt.authorize({.account = alice});
mpt.authorize({.account = bob});
@@ -804,8 +751,7 @@ class Delegate_test : public beast::unit_test::suite
// Grant both granular permissions and tx level permission.
{
env(delegate::set(
alice, bob, {"PaymentBurn", "PaymentMint", "Payment"}));
env(delegate::set(alice, bob, {"PaymentBurn", "PaymentMint", "Payment"}));
env.close();
env(pay(alice, gw, MPT(50)), delegate::as(bob));
BEAST_EXPECT(env.balance(alice, MPT) == aliceMPT - MPT(50));
@@ -838,9 +784,7 @@ class Delegate_test : public beast::unit_test::suite
env.close();
// bob can not create trustline on behalf of alice because he only
// has unfreeze permission
env(trust(alice, gw["USD"](50)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(alice, gw["USD"](50)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env.close();
// alice creates trustline by herself
@@ -852,70 +796,45 @@ class Delegate_test : public beast::unit_test::suite
env.close();
// unsupported flags
env(trust(alice, gw["USD"](50), tfSetNoRipple),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(alice, gw["USD"](50), tfClearNoRipple),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, gw["USD"](0), alice, tfSetDeepFreeze),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, gw["USD"](0), alice, tfClearDeepFreeze),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(alice, gw["USD"](50), tfSetNoRipple), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env(trust(alice, gw["USD"](50), tfClearNoRipple), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, gw["USD"](0), alice, tfSetDeepFreeze), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, gw["USD"](0), alice, tfClearDeepFreeze), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env.close();
// supported flags with wrong permission
env(trust(gw, gw["USD"](0), alice, tfSetfAuth),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, gw["USD"](0), alice, tfSetFreeze),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, gw["USD"](0), alice, tfSetfAuth), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, gw["USD"](0), alice, tfSetFreeze), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env.close();
env(delegate::set(gw, bob, {"TrustlineAuthorize"}));
env.close();
env(trust(gw, gw["USD"](0), alice, tfClearFreeze),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, gw["USD"](0), alice, tfClearFreeze), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env.close();
// although trustline authorize is granted, bob can not change the
// limit number
env(trust(gw, gw["USD"](50), alice, tfSetfAuth),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, gw["USD"](50), alice, tfSetfAuth), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env.close();
// supported flags with correct permission
env(trust(gw, gw["USD"](0), alice, tfSetfAuth), delegate::as(bob));
env.close();
env(delegate::set(
gw, bob, {"TrustlineAuthorize", "TrustlineFreeze"}));
env(delegate::set(gw, bob, {"TrustlineAuthorize", "TrustlineFreeze"}));
env.close();
env(trust(gw, gw["USD"](0), alice, tfSetFreeze), delegate::as(bob));
env.close();
env(delegate::set(
gw, bob, {"TrustlineAuthorize", "TrustlineUnfreeze"}));
env(delegate::set(gw, bob, {"TrustlineAuthorize", "TrustlineUnfreeze"}));
env.close();
env(trust(gw, gw["USD"](0), alice, tfClearFreeze),
delegate::as(bob));
env(trust(gw, gw["USD"](0), alice, tfClearFreeze), delegate::as(bob));
env.close();
// but bob can not freeze trustline because he no longer has freeze
// permission
env(trust(gw, gw["USD"](0), alice, tfSetFreeze),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, gw["USD"](0), alice, tfSetFreeze), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
// cannot update LimitAmount with granular permission, both high and
// low account
env(trust(alice, gw["USD"](100)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, alice["USD"](100)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(alice, gw["USD"](100)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env(trust(gw, alice["USD"](100)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
// can not set QualityIn or QualityOut
auto tx = trust(alice, gw["USD"](50));
@@ -956,53 +875,34 @@ class Delegate_test : public beast::unit_test::suite
env.close();
// bob does not have permission
env(trust(alice, gw["USD"](50)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(delegate::set(
alice, bob, {"TrustlineUnfreeze", "NFTokenCreateOffer"}));
env(trust(alice, gw["USD"](50)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env(delegate::set(alice, bob, {"TrustlineUnfreeze", "NFTokenCreateOffer"}));
env.close();
// bob still does not have permission
env(trust(alice, gw["USD"](50)),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(trust(alice, gw["USD"](50)), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
// add TrustSet permission and some unrelated permission
env(delegate::set(
alice,
bob,
{"TrustlineUnfreeze",
"NFTokenCreateOffer",
"TrustSet",
"AccountTransferRateSet"}));
alice, bob, {"TrustlineUnfreeze", "NFTokenCreateOffer", "TrustSet", "AccountTransferRateSet"}));
env.close();
env(trust(alice, gw["USD"](50)), delegate::as(bob));
env.close();
env(delegate::set(
gw,
bob,
{"TrustlineUnfreeze",
"NFTokenCreateOffer",
"TrustSet",
"AccountTransferRateSet"}));
gw, bob, {"TrustlineUnfreeze", "NFTokenCreateOffer", "TrustSet", "AccountTransferRateSet"}));
env.close();
// since bob has TrustSet permission, he does not need
// TrustlineFreeze granular permission to freeze the trustline
env(trust(gw, gw["USD"](0), alice, tfSetFreeze), delegate::as(bob));
env(trust(gw, gw["USD"](0), alice, tfClearFreeze),
delegate::as(bob));
env(trust(gw, gw["USD"](0), alice, tfClearFreeze), delegate::as(bob));
// bob can perform all the operations regarding TrustSet
env(trust(gw, gw["USD"](0), alice, tfSetFreeze), delegate::as(bob));
env(trust(gw, gw["USD"](0), alice, tfSetDeepFreeze),
delegate::as(bob));
env(trust(gw, gw["USD"](0), alice, tfClearDeepFreeze),
delegate::as(bob));
env(trust(gw, gw["USD"](0), alice, tfSetDeepFreeze), delegate::as(bob));
env(trust(gw, gw["USD"](0), alice, tfClearDeepFreeze), delegate::as(bob));
env(trust(gw, gw["USD"](0), alice, tfSetfAuth), delegate::as(bob));
env(trust(alice, gw["USD"](50), tfSetNoRipple), delegate::as(bob));
env(trust(alice, gw["USD"](50), tfClearNoRipple),
delegate::as(bob));
env(trust(alice, gw["USD"](50), tfClearNoRipple), delegate::as(bob));
}
// tfFullyCanonicalSig won't block delegated transaction
@@ -1019,9 +919,7 @@ class Delegate_test : public beast::unit_test::suite
env(delegate::set(gw, bob, {"TrustlineAuthorize"}));
env.close();
env(trust(
gw, gw["USD"](0), alice, tfSetfAuth | tfFullyCanonicalSig),
delegate::as(bob));
env(trust(gw, gw["USD"](0), alice, tfSetfAuth | tfFullyCanonicalSig), delegate::as(bob));
}
}
@@ -1055,8 +953,7 @@ class Delegate_test : public beast::unit_test::suite
// add granular permission related to AccountSet but is not the
// correct permission for domain set
env(delegate::set(
alice, bob, {"TrustlineUnfreeze", "AccountEmailHashSet"}));
env(delegate::set(alice, bob, {"TrustlineUnfreeze", "AccountEmailHashSet"}));
env.close();
env(jt, ter(terNO_DELEGATE_PERMISSION));
@@ -1089,8 +986,7 @@ class Delegate_test : public beast::unit_test::suite
env(jt, ter(terNO_DELEGATE_PERMISSION));
// alice give granular permission of AccountEmailHashSet to bob
env(delegate::set(
alice, bob, {"AccountDomainSet", "AccountEmailHashSet"}));
env(delegate::set(alice, bob, {"AccountDomainSet", "AccountEmailHashSet"}));
env.close();
env(jt);
BEAST_EXPECT(to_string((*env.le(alice))[sfEmailHash]) == mh);
@@ -1102,36 +998,24 @@ class Delegate_test : public beast::unit_test::suite
env(jt, ter(terNO_DELEGATE_PERMISSION));
// alice give granular permission of AccountMessageKeySet to bob
env(delegate::set(
alice,
bob,
{"AccountDomainSet",
"AccountEmailHashSet",
"AccountMessageKeySet"}));
env(delegate::set(alice, bob, {"AccountDomainSet", "AccountEmailHashSet", "AccountMessageKeySet"}));
env.close();
// bob can set message key for alice
env(jt);
BEAST_EXPECT(
strHex((*env.le(alice))[sfMessageKey]) ==
strHex(rkp.first.slice()));
BEAST_EXPECT(strHex((*env.le(alice))[sfMessageKey]) == strHex(rkp.first.slice()));
jt[sfMessageKey] = "";
env(jt);
BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfMessageKey));
// bob does not have permission to set transfer rate for alice
env(rate(alice, 2.0),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(rate(alice, 2.0), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
// alice give granular permission of AccountTransferRateSet to bob
env(delegate::set(
alice,
bob,
{"AccountDomainSet",
"AccountEmailHashSet",
"AccountMessageKeySet",
"AccountTransferRateSet"}));
{"AccountDomainSet", "AccountEmailHashSet", "AccountMessageKeySet", "AccountTransferRateSet"}));
env.close();
auto jtRate = rate(alice, 2.0);
jtRate[sfDelegate] = bob.human();
@@ -1156,18 +1040,14 @@ class Delegate_test : public beast::unit_test::suite
BEAST_EXPECT((*env.le(alice))[sfTickSize] == 8);
// can not set asfRequireAuth flag for alice
env(fset(alice, asfRequireAuth),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(fset(alice, asfRequireAuth), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
// reset Delegate will delete the Delegate
// object
env(delegate::set(alice, bob, {}));
// bib still does not have permission to set asfRequireAuth for
// alice
env(fset(alice, asfRequireAuth),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(fset(alice, asfRequireAuth), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
// alice can set for herself
env(fset(alice, asfRequireAuth));
env.require(flags(alice, asfRequireAuth));
@@ -1177,12 +1057,7 @@ class Delegate_test : public beast::unit_test::suite
jt[sfTickSize] = 7;
env(jt, ter(terNO_DELEGATE_PERMISSION));
env(delegate::set(
alice,
bob,
{"AccountDomainSet",
"AccountEmailHashSet",
"AccountMessageKeySet"}));
env(delegate::set(alice, bob, {"AccountDomainSet", "AccountEmailHashSet", "AccountMessageKeySet"}));
env.close();
// bob does not have permission to set wallet locater for alice
@@ -1206,17 +1081,13 @@ class Delegate_test : public beast::unit_test::suite
auto testSetClearFlag = [&](std::uint32_t flag) {
// bob can not set flag on behalf of alice
env(fset(alice, flag),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(fset(alice, flag), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
// alice set by herself
env(fset(alice, flag));
env.close();
env.require(flags(alice, flag));
// bob can not clear on behalf of alice
env(fclear(alice, flag),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(fclear(alice, flag), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
};
// testSetClearFlag(asfNoFreeze);
@@ -1224,12 +1095,7 @@ class Delegate_test : public beast::unit_test::suite
testSetClearFlag(asfAllowTrustLineClawback);
// alice gives some granular permissions to bob
env(delegate::set(
alice,
bob,
{"AccountDomainSet",
"AccountEmailHashSet",
"AccountMessageKeySet"}));
env(delegate::set(alice, bob, {"AccountDomainSet", "AccountEmailHashSet", "AccountMessageKeySet"}));
env.close();
testSetClearFlag(asfDefaultRipple);
@@ -1243,15 +1109,11 @@ class Delegate_test : public beast::unit_test::suite
testSetClearFlag(asfGlobalFreeze);
// bob can not set asfAccountTxnID on behalf of alice
env(fset(alice, asfAccountTxnID),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(fset(alice, asfAccountTxnID), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env(fset(alice, asfAccountTxnID));
env.close();
BEAST_EXPECT(env.le(alice)->isFieldPresent(sfAccountTxnID));
env(fclear(alice, asfAccountTxnID),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(fclear(alice, asfAccountTxnID), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
// bob can not set asfAuthorizedNFTokenMinter on behalf of alice
Json::Value jt = fset(alice, asfAuthorizedNFTokenMinter);
@@ -1260,36 +1122,24 @@ class Delegate_test : public beast::unit_test::suite
env(jt, ter(terNO_DELEGATE_PERMISSION));
// bob gives alice some permissions
env(delegate::set(
bob,
alice,
{"AccountDomainSet",
"AccountEmailHashSet",
"AccountMessageKeySet"}));
env(delegate::set(bob, alice, {"AccountDomainSet", "AccountEmailHashSet", "AccountMessageKeySet"}));
env.close();
// since we can not set asfNoFreeze if asfAllowTrustLineClawback is
// set, which can not be clear either. Test alice set asfNoFreeze on
// behalf of bob.
env(fset(alice, asfNoFreeze),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(fset(alice, asfNoFreeze), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
env(fset(bob, asfNoFreeze));
env.close();
env.require(flags(bob, asfNoFreeze));
// alice can not clear on behalf of bob
env(fclear(alice, asfNoFreeze),
delegate::as(bob),
ter(terNO_DELEGATE_PERMISSION));
env(fclear(alice, asfNoFreeze), delegate::as(bob), ter(terNO_DELEGATE_PERMISSION));
// bob can not set asfDisableMaster on behalf of alice
Account const bobKey{"bobKey", KeyType::secp256k1};
env(regkey(bob, bobKey));
env.close();
env(fset(alice, asfDisableMaster),
delegate::as(bob),
sig(bob),
ter(terNO_DELEGATE_PERMISSION));
env(fset(alice, asfDisableMaster), delegate::as(bob), sig(bob), ter(terNO_DELEGATE_PERMISSION));
}
// tfFullyCanonicalSig won't block delegated transaction
@@ -1300,8 +1150,7 @@ class Delegate_test : public beast::unit_test::suite
env.fund(XRP(10000), alice, bob);
env.close();
env(delegate::set(
alice, bob, {"AccountDomainSet", "AccountEmailHashSet"}));
env(delegate::set(alice, bob, {"AccountDomainSet", "AccountEmailHashSet"}));
env.close();
std::string const domain = "example.com";
@@ -1335,34 +1184,21 @@ class Delegate_test : public beast::unit_test::suite
env.close();
// delegate ledger object is not created yet
mpt.set(
{.account = alice,
.flags = tfMPTLock,
.delegate = bob,
.err = terNO_DELEGATE_PERMISSION});
mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob, .err = terNO_DELEGATE_PERMISSION});
// alice gives granular permission to bob of MPTokenIssuanceUnlock
env(delegate::set(alice, bob, {"MPTokenIssuanceUnlock"}));
env.close();
// bob does not have lock permission
mpt.set(
{.account = alice,
.flags = tfMPTLock,
.delegate = bob,
.err = terNO_DELEGATE_PERMISSION});
mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob, .err = terNO_DELEGATE_PERMISSION});
// bob now has lock permission, but does not have unlock permission
env(delegate::set(alice, bob, {"MPTokenIssuanceLock"}));
env.close();
mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
mpt.set(
{.account = alice,
.flags = tfMPTUnlock,
.delegate = bob,
.err = terNO_DELEGATE_PERMISSION});
mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob, .err = terNO_DELEGATE_PERMISSION});
// now bob can lock and unlock
env(delegate::set(
alice, bob, {"MPTokenIssuanceLock", "MPTokenIssuanceUnlock"}));
env(delegate::set(alice, bob, {"MPTokenIssuanceLock", "MPTokenIssuanceUnlock"}));
env.close();
mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob});
mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
@@ -1387,34 +1223,17 @@ class Delegate_test : public beast::unit_test::suite
env.close();
mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
// bob does not have unlock permission
mpt.set(
{.account = alice,
.flags = tfMPTUnlock,
.delegate = bob,
.err = terNO_DELEGATE_PERMISSION});
mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob, .err = terNO_DELEGATE_PERMISSION});
// alice gives bob some unrelated permission with
// MPTokenIssuanceLock
env(delegate::set(
alice,
bob,
{"NFTokenMint", "MPTokenIssuanceLock", "NFTokenBurn"}));
env(delegate::set(alice, bob, {"NFTokenMint", "MPTokenIssuanceLock", "NFTokenBurn"}));
env.close();
// bob can not unlock
mpt.set(
{.account = alice,
.flags = tfMPTUnlock,
.delegate = bob,
.err = terNO_DELEGATE_PERMISSION});
mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob, .err = terNO_DELEGATE_PERMISSION});
// alice add MPTokenIssuanceSet to permissions
env(delegate::set(
alice,
bob,
{"NFTokenMint",
"MPTokenIssuanceLock",
"NFTokenBurn",
"MPTokenIssuanceSet"}));
env(delegate::set(alice, bob, {"NFTokenMint", "MPTokenIssuanceLock", "NFTokenBurn", "MPTokenIssuanceSet"}));
mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob});
// alice can lock by herself
mpt.set({.account = alice, .flags = tfMPTLock});
@@ -1438,10 +1257,7 @@ class Delegate_test : public beast::unit_test::suite
// alice gives granular permission to bob of MPTokenIssuanceLock
env(delegate::set(alice, bob, {"MPTokenIssuanceLock"}));
env.close();
mpt.set(
{.account = alice,
.flags = tfMPTLock | tfFullyCanonicalSig,
.delegate = bob});
mpt.set({.account = alice, .flags = tfMPTLock | tfFullyCanonicalSig, .delegate = bob});
}
}
@@ -1465,10 +1281,7 @@ class Delegate_test : public beast::unit_test::suite
auto bobBalance = env.balance(bob);
auto carolBalance = env.balance(carol);
env(pay(alice, carol, XRP(100)),
fee(XRP(10)),
delegate::as(bob),
sig(bob));
env(pay(alice, carol, XRP(100)), fee(XRP(10)), delegate::as(bob), sig(bob));
env.close();
BEAST_EXPECT(env.balance(alice) == aliceBalance - XRP(100));
BEAST_EXPECT(env.balance(bob) == bobBalance - XRP(10));
@@ -1496,11 +1309,7 @@ class Delegate_test : public beast::unit_test::suite
auto bobBalance = env.balance(bob);
auto carolBalance = env.balance(carol);
env(pay(alice, carol, XRP(100)),
fee(XRP(10)),
delegate::as(bob),
sig(alice),
ter(tefBAD_AUTH));
env(pay(alice, carol, XRP(100)), fee(XRP(10)), delegate::as(bob), sig(alice), ter(tefBAD_AUTH));
env.close();
BEAST_EXPECT(env.balance(alice) == aliceBalance);
BEAST_EXPECT(env.balance(bob) == bobBalance);
@@ -1600,10 +1409,7 @@ class Delegate_test : public beast::unit_test::suite
auto dariaBalance = env.balance(daria);
auto edwardBalance = env.balance(edward);
env(pay(alice, carol, XRP(100)),
fee(XRP(10)),
delegate::as(bob),
msig(daria, edward));
env(pay(alice, carol, XRP(100)), fee(XRP(10)), delegate::as(bob), msig(daria, edward));
env.close();
BEAST_EXPECT(env.balance(alice) == aliceBalance - XRP(100));
BEAST_EXPECT(env.balance(bob) == bobBalance - XRP(10));
@@ -1640,11 +1446,7 @@ class Delegate_test : public beast::unit_test::suite
auto dariaBalance = env.balance(daria);
auto edwardBalance = env.balance(edward);
env(pay(alice, carol, XRP(100)),
fee(XRP(10)),
delegate::as(bob),
msig(daria, edward),
ter(tefBAD_QUORUM));
env(pay(alice, carol, XRP(100)), fee(XRP(10)), delegate::as(bob), msig(daria, edward), ter(tefBAD_QUORUM));
env.close();
BEAST_EXPECT(env.balance(alice) == aliceBalance);
BEAST_EXPECT(env.balance(bob) == bobBalance);
@@ -1746,8 +1548,7 @@ class Delegate_test : public beast::unit_test::suite
// Can not delegate tx if any required feature disabled.
{
auto txAmendmentDisabled = [&](FeatureBitset features,
std::string const& tx) {
auto txAmendmentDisabled = [&](FeatureBitset features, std::string const& tx) {
BEAST_EXPECT(txRequiredFeatures.contains(tx));
Env env(*this, features - txRequiredFeatures[tx]);