Skip to content

Commit b195011

Browse files
Bronekvvysokikh1
authored andcommitted
fix: Apply object reserve for Vault pseudo-account (#5954)
1 parent cd00aa5 commit b195011

File tree

5 files changed

+47
-21
lines changed

5 files changed

+47
-21
lines changed

src/test/app/Vault_test.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,7 @@ class Vault_test : public beast::unit_test::suite
13481348
Vault& vault) {
13491349
auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
13501350
testcase("insufficient fee");
1351-
env(tx, fee(env.current()->fees().base), ter(telINSUF_FEE_P));
1351+
env(tx, fee(env.current()->fees().base - 1), ter(telINSUF_FEE_P));
13521352
});
13531353

13541354
testCase([this](
@@ -2093,6 +2093,10 @@ class Vault_test : public beast::unit_test::suite
20932093
auto const sleMPT = env.le(mptoken);
20942094
BEAST_EXPECT(sleMPT == nullptr);
20952095

2096+
// Use one reserve so the next transaction fails
2097+
env(ticket::create(owner, 1));
2098+
env.close();
2099+
20962100
// No reserve to create MPToken for asset in VaultWithdraw
20972101
tx = vault.withdraw(
20982102
{.depositor = owner,
@@ -2110,7 +2114,7 @@ class Vault_test : public beast::unit_test::suite
21102114
}
21112115
},
21122116
{.requireAuth = false,
2113-
.initialXRP = acctReserve + incReserve * 4 - 1});
2117+
.initialXRP = acctReserve + incReserve * 4 + 1});
21142118

21152119
testCase([this](
21162120
Env& env,
@@ -2999,6 +3003,9 @@ class Vault_test : public beast::unit_test::suite
29993003
env.le(keylet::line(owner, asset.raw().get<Issue>()));
30003004
BEAST_EXPECT(trustline == nullptr);
30013005

3006+
env(ticket::create(owner, 1));
3007+
env.close();
3008+
30023009
// Fail because not enough reserve to create trust line
30033010
tx = vault.withdraw(
30043011
{.depositor = owner,
@@ -3014,7 +3021,7 @@ class Vault_test : public beast::unit_test::suite
30143021
env(tx);
30153022
env.close();
30163023
},
3017-
CaseArgs{.initialXRP = acctReserve + incReserve * 4 - 1});
3024+
CaseArgs{.initialXRP = acctReserve + incReserve * 4 + 1});
30183025

30193026
testCase(
30203027
[&, this](
@@ -3035,8 +3042,7 @@ class Vault_test : public beast::unit_test::suite
30353042
env(pay(owner, charlie, asset(100)));
30363043
env.close();
30373044

3038-
// Use up some reserve on tickets
3039-
env(ticket::create(charlie, 2));
3045+
env(ticket::create(charlie, 3));
30403046
env.close();
30413047

30423048
// Fail because not enough reserve to create MPToken for shares
@@ -3054,7 +3060,7 @@ class Vault_test : public beast::unit_test::suite
30543060
env(tx);
30553061
env.close();
30563062
},
3057-
CaseArgs{.initialXRP = acctReserve + incReserve * 4 - 1});
3063+
CaseArgs{.initialXRP = acctReserve + incReserve * 4 + 1});
30583064

30593065
testCase([&, this](
30603066
Env& env,

src/test/jtx/impl/vault.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ Vault::create(CreateArgs const& args)
3838
jv[jss::TransactionType] = jss::VaultCreate;
3939
jv[jss::Account] = args.owner.human();
4040
jv[jss::Asset] = to_json(args.asset);
41-
jv[jss::Fee] = STAmount(env.current()->fees().increment).getJson();
4241
if (args.flags)
4342
jv[jss::Flags] = *args.flags;
4443
return {jv, keylet};

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,6 @@ VaultCreate::preflight(PreflightContext const& ctx)
9898
return tesSUCCESS;
9999
}
100100

101-
XRPAmount
102-
VaultCreate::calculateBaseFee(ReadView const& view, STTx const& tx)
103-
{
104-
// One reserve increment is typically much greater than one base fee.
105-
return calculateOwnerReserveFee(view, tx);
106-
}
107-
108101
TER
109102
VaultCreate::preclaim(PreclaimContext const& ctx)
110103
{
@@ -161,8 +154,9 @@ VaultCreate::doApply()
161154

162155
if (auto ter = dirLink(view(), account_, vault))
163156
return ter;
164-
adjustOwnerCount(view(), owner, 1, j_);
165-
auto ownerCount = owner->at(sfOwnerCount);
157+
// We will create Vault and PseudoAccount, hence increase OwnerCount by 2
158+
adjustOwnerCount(view(), owner, 2, j_);
159+
auto const ownerCount = owner->at(sfOwnerCount);
166160
if (mPriorBalance < view().fees().accountReserve(ownerCount))
167161
return tecINSUFFICIENT_RESERVE;
168162

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ class VaultCreate : public Transactor
4242
static NotTEC
4343
preflight(PreflightContext const& ctx);
4444

45-
static XRPAmount
46-
calculateBaseFee(ReadView const& view, STTx const& tx);
47-
4845
static TER
4946
preclaim(PreclaimContext const& ctx);
5047

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

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,35 @@ VaultDelete::doApply()
165165
return tecHAS_OBLIGATIONS; // LCOV_EXCL_LINE
166166

167167
// Destroy the pseudo-account.
168-
view().erase(view().peek(keylet::account(pseudoID)));
168+
auto vaultPseudoSLE = view().peek(keylet::account(pseudoID));
169+
if (!vaultPseudoSLE || vaultPseudoSLE->at(~sfVaultID) != vault->key())
170+
return tefBAD_LEDGER; // LCOV_EXCL_LINE
171+
172+
// Making the payment and removing the empty holding should have deleted any
173+
// obligations associated with the vault or vault pseudo-account.
174+
if (*vaultPseudoSLE->at(sfBalance))
175+
{
176+
// LCOV_EXCL_START
177+
JLOG(j_.error()) << "VaultDelete: pseudo-account has a balance";
178+
return tecHAS_OBLIGATIONS;
179+
// LCOV_EXCL_STOP
180+
}
181+
if (vaultPseudoSLE->at(sfOwnerCount) != 0)
182+
{
183+
// LCOV_EXCL_START
184+
JLOG(j_.error()) << "VaultDelete: pseudo-account still owns objects";
185+
return tecHAS_OBLIGATIONS;
186+
// LCOV_EXCL_STOP
187+
}
188+
if (view().exists(keylet::ownerDir(pseudoID)))
189+
{
190+
// LCOV_EXCL_START
191+
JLOG(j_.error()) << "VaultDelete: pseudo-account has a directory";
192+
return tecHAS_OBLIGATIONS;
193+
// LCOV_EXCL_STOP
194+
}
195+
196+
view().erase(vaultPseudoSLE);
169197

170198
// Remove the vault from its owner's directory.
171199
auto const ownerID = vault->at(sfOwner);
@@ -189,7 +217,9 @@ VaultDelete::doApply()
189217
return tefBAD_LEDGER;
190218
// LCOV_EXCL_STOP
191219
}
192-
adjustOwnerCount(view(), owner, -1, j_);
220+
221+
// We are destroying Vault and PseudoAccount, hence decrease by 2
222+
adjustOwnerCount(view(), owner, -2, j_);
193223

194224
// Destroy the vault.
195225
view().erase(vault);

0 commit comments

Comments
 (0)