Skip to content

Commit 71bb08c

Browse files
committed
Review feedback from @Tapanito, @gregtatcam, and @shawnxie999
- Created a common doWithdraw function for VaultWithdraw and LoanBrokerCoverWithdraw. Added verifyDepositPreauth to it, so that both transactions will get the check. - Add a missing null check to LoanBrokerSet, and add log messages to the existing checks.
1 parent 25e72d7 commit 71bb08c

File tree

5 files changed

+100
-80
lines changed

5 files changed

+100
-80
lines changed

include/xrpl/ledger/View.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,17 @@ canWithdraw(
753753
[[nodiscard]] TER
754754
canWithdraw(ReadView const& view, STTx const& tx);
755755

756+
[[nodiscard]] TER
757+
doWithdraw(
758+
ApplyView& view,
759+
STTx const& tx,
760+
AccountID const& senderAcct,
761+
AccountID const& dstAcct,
762+
AccountID const& sourceAcct,
763+
XRPAmount priorBalance,
764+
STAmount const& amount,
765+
beast::Journal j);
766+
756767
/// Any transactors that call addEmptyHolding() in doApply must call
757768
/// canAddHolding() in preflight with the same View and Asset
758769
[[nodiscard]] TER

src/libxrpl/ledger/View.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,55 @@ canWithdraw(ReadView const& view, STTx const& tx)
13861386
return canWithdraw(from, view, to, tx.isFieldPresent(sfDestinationTag));
13871387
}
13881388

1389+
TER
1390+
doWithdraw(
1391+
ApplyView& view,
1392+
STTx const& tx,
1393+
AccountID const& senderAcct,
1394+
AccountID const& dstAcct,
1395+
AccountID const& sourceAcct,
1396+
XRPAmount priorBalance,
1397+
STAmount const& amount,
1398+
beast::Journal j)
1399+
{
1400+
// Create trust line or MPToken for the receiving account
1401+
if (dstAcct == senderAcct)
1402+
{
1403+
if (auto const ter = addEmptyHolding(
1404+
view, senderAcct, priorBalance, amount.asset(), j);
1405+
!isTesSuccess(ter) && ter != tecDUPLICATE)
1406+
return ter;
1407+
}
1408+
else
1409+
{
1410+
auto dstSle = view.peek(keylet::account(dstAcct));
1411+
if (auto err =
1412+
verifyDepositPreauth(tx, view, senderAcct, dstAcct, dstSle, j))
1413+
return err;
1414+
}
1415+
1416+
// Sanity check
1417+
if (accountHolds(
1418+
view,
1419+
sourceAcct,
1420+
amount.asset(),
1421+
FreezeHandling::fhIGNORE_FREEZE,
1422+
AuthHandling::ahIGNORE_AUTH,
1423+
j) < amount)
1424+
{
1425+
// LCOV_EXCL_START
1426+
JLOG(j.error()) << "LoanBrokerCoverWithdraw: negative balance of "
1427+
"broker cover assets.";
1428+
return tefINTERNAL;
1429+
// LCOV_EXCL_STOP
1430+
}
1431+
1432+
// Move the funds directly from the broker's pseudo-account to the
1433+
// dstAcct
1434+
return accountSend(
1435+
view, sourceAcct, dstAcct, amount, j, WaiveTransferFee::Yes);
1436+
}
1437+
13891438
[[nodiscard]] TER
13901439
addEmptyHolding(
13911440
ApplyView& view,

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

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -157,41 +157,15 @@ LoanBrokerCoverWithdraw::doApply()
157157
broker->at(sfCoverAvailable) -= amount;
158158
view().update(broker);
159159

160-
// Create trust line or MPToken for the receiving account
161-
if (dstAcct == account_)
162-
{
163-
if (auto const ter = addEmptyHolding(
164-
view(), account_, mPriorBalance, amount.asset(), j_);
165-
!isTesSuccess(ter) && ter != tecDUPLICATE)
166-
return ter;
167-
}
168-
else
169-
{
170-
auto dstSle = view().peek(keylet::account(dstAcct));
171-
if (auto err =
172-
verifyDepositPreauth(tx, view(), account_, dstAcct, dstSle, j_))
173-
return err;
174-
}
175-
176-
// Sanity check
177-
if (accountHolds(
178-
view(),
179-
brokerPseudoID,
180-
amount.asset(),
181-
FreezeHandling::fhIGNORE_FREEZE,
182-
AuthHandling::ahIGNORE_AUTH,
183-
j_) < amount)
184-
{
185-
// LCOV_EXCL_START
186-
JLOG(j_.error()) << "LoanBrokerCoverWithdraw: negative balance of "
187-
"broker cover assets.";
188-
return tefINTERNAL;
189-
// LCOV_EXCL_STOP
190-
}
191-
192-
// Move the funds directly from the broker's pseudo-account to the dstAcct
193-
return accountSend(
194-
view(), brokerPseudoID, dstAcct, amount, j_, WaiveTransferFee::Yes);
160+
return doWithdraw(
161+
view(),
162+
tx,
163+
account_,
164+
dstAcct,
165+
brokerPseudoID,
166+
mPriorBalance,
167+
amount,
168+
j_);
195169
}
196170

197171
//------------------------------------------------------------------------------

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,13 @@ LoanBrokerSet::doApply()
120120
// Modify an existing LoanBroker
121121
auto broker = view.peek(keylet::loanbroker(*brokerID));
122122
if (!broker)
123-
return tefBAD_LEDGER; // LCOV_EXCL_LINE
123+
{
124+
// This should be impossible
125+
// LCOV_EXCL_START
126+
JLOG(j_.fatal()) << "LoanBroker does not exist.";
127+
return tefBAD_LEDGER;
128+
// LCOV_EXCL_STOP
129+
}
124130

125131
if (auto const data = tx[~sfData])
126132
broker->at(sfData) = *data;
@@ -134,12 +140,26 @@ LoanBrokerSet::doApply()
134140
// Create a new LoanBroker pointing back to the given Vault
135141
auto const vaultID = tx[sfVaultID];
136142
auto const sleVault = view.read(keylet::vault(vaultID));
143+
if (!sleVault)
144+
{
145+
// This should be impossible
146+
// LCOV_EXCL_START
147+
JLOG(j_.fatal()) << "Vault does not exist.";
148+
return tefBAD_LEDGER;
149+
// LCOV_EXCL_STOP
150+
}
137151
auto const vaultPseudoID = sleVault->at(sfAccount);
138152
auto const sequence = tx.getSeqValue();
139153

140154
auto owner = view.peek(keylet::account(account_));
141155
if (!owner)
142-
return tefBAD_LEDGER; // LCOV_EXCL_LINE
156+
{
157+
// This should be impossible
158+
// LCOV_EXCL_START
159+
JLOG(j_.fatal()) << "Account does not exist.";
160+
return tefBAD_LEDGER;
161+
// LCOV_EXCL_STOP
162+
}
143163
auto broker =
144164
std::make_shared<SLE>(keylet::loanbroker(account_, sequence));
145165

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

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -237,49 +237,15 @@ VaultWithdraw::doApply()
237237

238238
auto const dstAcct = ctx_.tx[~sfDestination].value_or(account_);
239239

240-
// Create trust line or MPToken for the receiving account
241-
if (dstAcct == account_)
242-
{
243-
if (auto const ter = addEmptyHolding(
244-
view(), account_, mPriorBalance, vaultAsset, j_);
245-
!isTesSuccess(ter) && ter != tecDUPLICATE)
246-
return ter;
247-
}
248-
else
249-
{
250-
auto dstSle = view().peek(keylet::account(dstAcct));
251-
if (auto err = verifyDepositPreauth(
252-
ctx_.tx, view(), account_, dstAcct, dstSle, j_))
253-
return err;
254-
}
255-
256-
// Transfer assets from vault to depositor or destination account.
257-
if (auto const ter = accountSend(
258-
view(),
259-
vaultAccount,
260-
dstAcct,
261-
assetsWithdrawn,
262-
j_,
263-
WaiveTransferFee::Yes);
264-
!isTesSuccess(ter))
265-
return ter;
266-
267-
// Sanity check
268-
if (accountHolds(
269-
view(),
270-
vaultAccount,
271-
assetsWithdrawn.asset(),
272-
FreezeHandling::fhIGNORE_FREEZE,
273-
AuthHandling::ahIGNORE_AUTH,
274-
j_) < beast::zero)
275-
{
276-
// LCOV_EXCL_START
277-
JLOG(j_.error()) << "VaultWithdraw: negative balance of vault assets.";
278-
return tefINTERNAL;
279-
// LCOV_EXCL_STOP
280-
}
281-
282-
return tesSUCCESS;
240+
return doWithdraw(
241+
view(),
242+
ctx_.tx,
243+
account_,
244+
dstAcct,
245+
vaultAccount,
246+
mPriorBalance,
247+
assetsWithdrawn,
248+
j_);
283249
}
284250

285251
} // namespace ripple

0 commit comments

Comments
 (0)