Skip to content

Commit a219814

Browse files
committed
adds BLockDeposit flagsto VaultSet
1 parent c808c46 commit a219814

File tree

6 files changed

+155
-2
lines changed

6 files changed

+155
-2
lines changed

include/xrpl/protocol/TxFlags.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ constexpr std::uint32_t const tfLoanManageMask = ~(tfUniversal | tfLoanDefault |
296296
// VaultSet flags:
297297
constexpr std::uint32_t const tfVaultDepositBlock = 0x00010000;
298298
constexpr std::uint32_t const tfVaultDepositUnblock = 0x00020000;
299-
constexpr std::uint32_t const tfVaultManageMask = ~(tfUniversal | tfVaultDepositBlock | tfVaultDepositUnblock);
299+
constexpr std::uint32_t const tfVaultSetMask = ~(tfUniversal | tfVaultDepositBlock | tfVaultDepositUnblock);
300300

301301
// clang-format on
302302

src/test/app/Vault_test.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4990,6 +4990,97 @@ class Vault_test : public beast::unit_test::suite
49904990
}
49914991
}
49924992

4993+
void
4994+
testVaultSetVaultDepositFlagValidation()
4995+
{
4996+
using namespace test::jtx;
4997+
4998+
auto const all = testable_amendments();
4999+
5000+
{
5001+
testcase("VaultSet VaultDepositBlock fixLendingProtocolV1_1 disabled");
5002+
Env env{*this, all - fixLendingProtocolV1_1};
5003+
5004+
Account owner{"owner"};
5005+
env.fund(XRP(1'000'000), owner);
5006+
env.close();
5007+
5008+
PrettyAsset asset = xrpIssue();
5009+
Vault vault{env};
5010+
5011+
auto const [tx, keylet] = vault.create({.owner = owner, .asset = asset, .flags = tfVaultPrivate});
5012+
env(tx, ter(tesSUCCESS), THISLINE);
5013+
env.close();
5014+
5015+
env(vault.set({.owner = owner, .id = keylet.key, .flags = tfVaultDepositBlock}),
5016+
ter(temDISABLED),
5017+
THISLINE);
5018+
env.close();
5019+
}
5020+
5021+
{
5022+
std::string const prefix = "VaultSet(VaultDepositBlock): ";
5023+
Env env{*this, all | fixLendingProtocolV1_1};
5024+
5025+
Account owner{"owner"};
5026+
env.fund(XRP(1'000'000), owner);
5027+
env.close();
5028+
5029+
PrettyAsset asset = xrpIssue();
5030+
Vault vault{env};
5031+
5032+
auto const [tx, keylet] = vault.create({.owner = owner, .asset = asset, .flags = tfVaultPrivate});
5033+
env(tx, ter(tesSUCCESS), THISLINE);
5034+
env.close();
5035+
5036+
{
5037+
testcase(prefix + "invalid flags");
5038+
env(vault.set({.owner = owner, .id = keylet.key, .flags = tfVaultDepositBlock | tfVaultDepositUnblock}),
5039+
ter(temMALFORMED),
5040+
THISLINE);
5041+
env.close();
5042+
}
5043+
5044+
{
5045+
testcase(prefix + "unblock already unblocked vault");
5046+
// Cannot unblock an already unblocked vault
5047+
env(vault.set({.owner = owner, .id = keylet.key, .flags = tfVaultDepositUnblock}),
5048+
ter(tecNO_PERMISSION),
5049+
THISLINE);
5050+
}
5051+
5052+
{
5053+
testcase(prefix + "set and clear vault flag");
5054+
env(vault.set({.owner = owner, .id = keylet.key, .flags = tfVaultDepositBlock}),
5055+
ter(tesSUCCESS),
5056+
THISLINE);
5057+
5058+
auto sleVault = env.le(keylet);
5059+
if (!BEAST_EXPECT(sleVault))
5060+
return;
5061+
5062+
if (!BEAST_EXPECT(sleVault->isFlag(lsfVaultDepositBlocked)))
5063+
return;
5064+
5065+
// Cannot block an already blocked vault
5066+
env(vault.set({.owner = owner, .id = keylet.key, .flags = tfVaultDepositBlock}),
5067+
ter(tecNO_PERMISSION),
5068+
THISLINE);
5069+
5070+
// Cannot unblock an already unblocked vault
5071+
env(vault.set({.owner = owner, .id = keylet.key, .flags = tfVaultDepositUnblock}),
5072+
ter(tesSUCCESS),
5073+
THISLINE);
5074+
5075+
sleVault = env.le(keylet);
5076+
if (!BEAST_EXPECT(sleVault))
5077+
return;
5078+
5079+
BEAST_EXPECT(!sleVault->isFlag(lsfVaultDepositBlocked));
5080+
}
5081+
}
5082+
}
5083+
49935084
public:
49945085
void
49955086
run() override
@@ -5011,6 +5102,7 @@ class Vault_test : public beast::unit_test::suite
50115102
testVaultClawbackBurnShares();
50125103
testVaultClawbackAssets();
50135104
testAssetsMaximum();
5105+
testVaultSetVaultDepositFlagValidation();
50145106
}
50155107
};
50165108

src/test/jtx/impl/vault.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Vault::set(SetArgs const& args)
3131
jv[jss::TransactionType] = jss::VaultSet;
3232
jv[jss::Account] = args.owner.human();
3333
jv[sfVaultID] = to_string(args.id);
34+
if (args.flags)
35+
jv[jss::Flags] = *args.flags;
3436
return jv;
3537
}
3638

src/test/jtx/vault.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct Vault
3636
{
3737
Account owner;
3838
uint256 id;
39+
std::optional<std::uint32_t> flags{};
3940
};
4041

4142
Json::Value

src/xrpld/app/tx/detail/VaultSet.cpp

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,34 @@ VaultSet::checkExtraFeatures(PreflightContext const& ctx)
2121
return true;
2222
}
2323

24+
std::uint32_t
25+
VaultSet::getFlagsMask(PreflightContext const& ctx)
26+
{
27+
return tfVaultSetMask;
28+
}
29+
30+
static bool
31+
isValidVaultUpdate(PreflightContext const& ctx)
32+
{
33+
auto const checkFlags = ctx.rules.enabled(fixLendingProtocolV1_1);
34+
35+
auto const atLeastOneFieldPresent =
36+
ctx.tx.isFieldPresent(sfDomainID) || ctx.tx.isFieldPresent(sfAssetsMaximum) || ctx.tx.isFieldPresent(sfData);
37+
38+
return atLeastOneFieldPresent ||
39+
(checkFlags && (ctx.tx.isFlag(tfVaultDepositBlock) || ctx.tx.isFlag(tfVaultDepositUnblock)));
40+
}
41+
2442
NotTEC
2543
VaultSet::preflight(PreflightContext const& ctx)
2644
{
45+
if ((ctx.tx.isFlag(tfVaultDepositBlock) || ctx.tx.isFlag(tfVaultDepositUnblock)) &&
46+
!ctx.rules.enabled(fixLendingProtocolV1_1))
47+
{
48+
JLOG(ctx.j.debug()) << "VaultSet: flags not supported without fixLendingProtocolV1_1.";
49+
return temDISABLED;
50+
}
51+
2752
if (ctx.tx[sfVaultID] == beast::zero)
2853
{
2954
JLOG(ctx.j.debug()) << "VaultSet: zero/empty vault ID.";
@@ -48,12 +73,18 @@ VaultSet::preflight(PreflightContext const& ctx)
4873
}
4974
}
5075

51-
if (!ctx.tx.isFieldPresent(sfDomainID) && !ctx.tx.isFieldPresent(sfAssetsMaximum) && !ctx.tx.isFieldPresent(sfData))
76+
if (!isValidVaultUpdate(ctx))
5277
{
5378
JLOG(ctx.j.debug()) << "VaultSet: nothing is being updated.";
5479
return temMALFORMED;
5580
}
5681

82+
if (ctx.tx.isFlag(tfVaultDepositBlock) && ctx.tx.isFlag(tfVaultDepositUnblock))
83+
{
84+
JLOG(ctx.j.debug()) << "VaultSet: cannot set tfVaultDepositBlock and tfVaultDepositUnblock simultaneously.";
85+
return temMALFORMED;
86+
}
87+
5788
return tesSUCCESS;
5889
}
5990

@@ -107,6 +138,21 @@ VaultSet::preclaim(PreclaimContext const& ctx)
107138
}
108139
}
109140

141+
if (ctx.view.rules().enabled(fixLendingProtocolV1_1))
142+
{
143+
if (vault->isFlag(lsfVaultDepositBlocked) && ctx.tx.isFlag(tfVaultDepositBlock))
144+
{
145+
JLOG(ctx.j.debug()) << "VaultSet: vault deposit is already blocked";
146+
return tecNO_PERMISSION;
147+
}
148+
149+
if (!vault->isFlag(lsfVaultDepositBlocked) && ctx.tx.isFlag(tfVaultDepositUnblock))
150+
{
151+
JLOG(ctx.j.debug()) << "VaultSet: vault deposit is already unblocked";
152+
return tecNO_PERMISSION;
153+
}
154+
}
155+
110156
return tesSUCCESS;
111157
}
112158

@@ -164,6 +210,15 @@ VaultSet::doApply()
164210
view().update(sleIssuance);
165211
}
166212

213+
if (view().rules().enabled(fixLendingProtocolV1_1))
214+
{
215+
if (tx.isFlag(tfVaultDepositBlock))
216+
vault->setFlag(lsfVaultDepositBlocked);
217+
218+
if (tx.isFlag(tfVaultDepositUnblock))
219+
vault->clearFlag(lsfVaultDepositBlocked);
220+
}
221+
167222
// Note, we must update Vault object even if only DomainID is being updated
168223
// in Issuance object. Otherwise it's really difficult for Vault invariants
169224
// to verify the operation.

src/xrpld/app/tx/detail/VaultSet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ class VaultSet : public Transactor
1313
{
1414
}
1515

16+
static std::uint32_t
17+
getFlagsMask(PreflightContext const& ctx);
18+
1619
static bool
1720
checkExtraFeatures(PreflightContext const& ctx);
1821

0 commit comments

Comments
 (0)