20 #include <ripple/app/tx/impl/SetTrust.h>
21 #include <ripple/basics/Log.h>
22 #include <ripple/protocol/Feature.h>
23 #include <ripple/protocol/Quality.h>
24 #include <ripple/protocol/Indexes.h>
25 #include <ripple/protocol/st.h>
26 #include <ripple/ledger/View.h>
45 "Malformed transaction: Invalid flags set.";
54 if (saLimitAmount.
native ())
57 "Malformed transaction: specifies native limit " <<
65 "Malformed transaction: specifies XRP as IOU";
69 if (saLimitAmount < beast::zero)
72 "Malformed transaction: Negative credit limit.";
77 auto const& issuer = saLimitAmount.
getIssuer ();
82 "Malformed transaction: no destination account.";
101 bool const bSetAuth = (uTxFlags &
tfSetfAuth);
106 "Retry: Auth not required.";
112 auto const currency = saLimitAmount.getCurrency();
113 auto const uDstAccountID = saLimitAmount.getIssuer();
115 if (
id == uDstAccountID)
120 auto const sleDelete = ctx.
view.
read(
126 "Malformed transaction: Can not extend credit to self.";
147 bool const bHigh =
account_ > uDstAccountID;
174 XRPAmount const reserveCreate ((uOwnerCount < 2)
176 :
view().fees().accountReserve(uOwnerCount + 1));
181 if (bQualityOut && QUALITY_ONE == uQualityOut)
186 bool const bSetAuth = (uTxFlags &
tfSetfAuth);
204 "Clearing redundant line.";
207 sleDelete,
account_, uDstAccountID, viewJ);
216 "Delay transaction: Destination account does not exist.";
220 STAmount saLimitAllow = saLimitAmount;
236 auto const& uLowAccountID = !bHigh ?
account_ : uDstAccountID;
237 auto const& uHighAccountID = bHigh ?
account_ : uDstAccountID;
238 SLE::ref sleLowAccount = !bHigh ? sle : sleDst;
239 SLE::ref sleHighAccount = bHigh ? sle : sleDst;
245 saLowBalance = sleRippleState->getFieldAmount (
sfBalance);
246 saHighBalance = -saLowBalance;
254 saLowLimit = !bHigh ? saLimitAllow : sleRippleState->getFieldAmount (
sfLowLimit);
255 saHighLimit = bHigh ? saLimitAllow : sleRippleState->getFieldAmount (
sfHighLimit);
274 uLowQualityIn = !bHigh ? uQualityIn : sleRippleState->getFieldU32 (
sfLowQualityIn);
275 uHighQualityIn = bHigh ? uQualityIn : sleRippleState->getFieldU32 (
sfHighQualityIn);
283 uLowQualityIn = !bHigh ? 0 : sleRippleState->getFieldU32 (
sfLowQualityIn);
284 uHighQualityIn = bHigh ? 0 : sleRippleState->getFieldU32 (
sfHighQualityIn);
287 if (QUALITY_ONE == uLowQualityIn) uLowQualityIn = 0;
289 if (QUALITY_ONE == uHighQualityIn) uHighQualityIn = 0;
302 else if (uQualityOut)
308 uLowQualityOut = !bHigh ? uQualityOut : sleRippleState->getFieldU32 (
sfLowQualityOut);
309 uHighQualityOut = bHigh ? uQualityOut : sleRippleState->getFieldU32 (
sfHighQualityOut);
317 uLowQualityOut = !bHigh ? 0 : sleRippleState->getFieldU32 (
sfLowQualityOut);
318 uHighQualityOut = bHigh ? 0 : sleRippleState->getFieldU32 (
sfHighQualityOut);
324 if (bSetNoRipple && !bClearNoRipple)
326 if ((bHigh ? saHighBalance : saLowBalance) >= beast::zero)
333 else if (bClearNoRipple && !bSetNoRipple)
338 if (bSetFreeze && !bClearFreeze && !sle->isFlag (
lsfNoFreeze))
342 else if (bClearFreeze && !bSetFreeze)
347 if (QUALITY_ONE == uLowQualityOut) uLowQualityOut = 0;
349 if (QUALITY_ONE == uHighQualityOut) uHighQualityOut = 0;
354 bool const bLowReserveSet = uLowQualityIn || uLowQualityOut ||
357 saLowLimit || saLowBalance > beast::zero;
358 bool const bLowReserveClear = !bLowReserveSet;
360 bool const bHighReserveSet = uHighQualityIn || uHighQualityOut ||
363 saHighLimit || saHighBalance > beast::zero;
364 bool const bHighReserveClear = !bHighReserveSet;
366 bool const bDefault = bLowReserveClear && bHighReserveClear;
371 bool bReserveIncrease =
false;
378 if (bLowReserveSet && !bLowReserved)
382 sleLowAccount, 1, viewJ);
386 bReserveIncrease =
true;
389 if (bLowReserveClear && bLowReserved)
393 sleLowAccount, -1, viewJ);
397 if (bHighReserveSet && !bHighReserved)
401 sleHighAccount, 1, viewJ);
405 bReserveIncrease =
true;
408 if (bHighReserveClear && bHighReserved)
412 sleHighAccount, -1, viewJ);
416 if (uFlagsIn != uFlagsOut)
417 sleRippleState->setFieldU32 (
sfFlags, uFlagsOut);
424 sleRippleState, uLowAccountID, uHighAccountID, viewJ);
430 "Delay transaction: Insufficent reserve to add trust line.";
440 JLOG(
j_.
trace()) <<
"Modify ripple line";
444 else if (! saLimitAmount &&
445 (! bQualityIn || ! uQualityIn) &&
446 (! bQualityOut || ! uQualityOut) &&
450 "Redundant: Setting non-existent ripple line to defaults.";
456 "Delay transaction: Line does not exist. Insufficent reserve to create line.";
467 account_, uDstAccountID, currency));
470 "doTrustSet: Creating ripple line: " <<
481 bSetNoRipple && !bClearNoRipple,
482 bSetFreeze && !bClearFreeze,