158 auto const id = ctx.
tx[sfAccount];
164 bool const bSetAuth = ctx.
tx.
isFlag(tfSetfAuth);
166 if (bSetAuth && !sle->isFlag(lsfRequireAuth))
168 JLOG(ctx.
j.
trace()) <<
"Retry: Auth not required.";
172 auto const saLimitAmount = ctx.
tx[sfLimitAmount];
174 auto const currency = saLimitAmount.get<
Issue>().currency;
175 auto const uDstAccountID = saLimitAmount.
getIssuer();
177 if (
id == uDstAccountID)
188 if (sleDst && sleDst->isFlag(lsfDisallowIncomingTrustline) &&
202 if (sleDst->isFieldPresent(sfAMMID))
208 else if (
auto const ammSle = ctx.
view.
read({ltAMM, sleDst->getFieldH256(sfAMMID)}))
210 auto const lpTokens = ammSle->getFieldAmount(sfLPTokenBalance);
225 else if (sleDst->isFieldPresent(sfVaultID) || sleDst->isFieldPresent(sfLoanBrokerID))
240 bool const bNoFreeze = sle->isFlag(lsfNoFreeze);
241 bool const bSetFreeze = ctx.
tx.
isFlag(tfSetFreeze);
242 bool const bSetDeepFreeze = ctx.
tx.
isFlag(tfSetDeepFreeze);
244 if (bNoFreeze && (bSetFreeze || bSetDeepFreeze))
250 bool const bClearFreeze = ctx.
tx.
isFlag(tfClearFreeze);
251 bool const bClearDeepFreeze = ctx.
tx.
isFlag(tfClearDeepFreeze);
252 if ((bSetFreeze || bSetDeepFreeze) && (bClearFreeze || bClearDeepFreeze))
259 bool const bHigh =
id > uDstAccountID;
262 std::uint32_t uFlags = sleRippleState ? sleRippleState->getFieldU32(sfFlags) : 0u;
264 uFlags = computeFreezeFlags(
265 uFlags, bHigh, bNoFreeze, bSetFreeze, bClearFreeze, bSetDeepFreeze, bClearDeepFreeze);
267 auto const frozen = uFlags & (bHigh ? lsfHighFreeze : lsfLowFreeze);
268 auto const deepFrozen = uFlags & (bHigh ? lsfHighDeepFreeze : lsfLowDeepFreeze);
273 if ((deepFrozen != 0u) && (frozen == 0u))
287 STAmount const saLimitAmount(
ctx_.tx.getFieldAmount(sfLimitAmount));
288 bool const bQualityIn(
ctx_.tx.isFieldPresent(sfQualityIn));
289 bool const bQualityOut(
ctx_.tx.isFieldPresent(sfQualityOut));
295 bool const bHigh =
accountID_ > uDstAccountID;
321 return sponsorExp.error();
322 auto const sponsorSle = *sponsorExp;
324 auto getSponsor = [&sponsorSle,
this](
AccountID const& account) {
331 bool const freeTrustLine = !sponsorSle && (
ownerCount(sle,
j_) < 2);
337 std::uint32_t const uQualityIn(bQualityIn ?
ctx_.tx.getFieldU32(sfQualityIn) : 0);
340 if (bQualityOut && QUALITY_ONE == uQualityOut)
343 bool const bSetAuth =
ctx_.tx.isFlag(tfSetfAuth);
344 bool const bSetNoRipple =
ctx_.tx.isFlag(tfSetNoRipple);
345 bool const bClearNoRipple =
ctx_.tx.isFlag(tfClearNoRipple);
346 bool const bSetFreeze =
ctx_.tx.isFlag(tfSetFreeze);
347 bool const bClearFreeze =
ctx_.tx.isFlag(tfClearFreeze);
348 bool const bSetDeepFreeze =
ctx_.tx.isFlag(tfSetDeepFreeze);
349 bool const bClearDeepFreeze =
ctx_.tx.isFlag(tfClearDeepFreeze);
351 auto viewJ =
ctx_.registry.get().getJournal(
"View");
357 JLOG(
j_.trace()) <<
"Delay transaction: Destination account does not exist.";
361 STAmount saLimitAllow = saLimitAmount;
377 auto const& uLowAccountID = !bHigh ?
accountID_ : uDstAccountID;
378 auto const& uHighAccountID = bHigh ?
accountID_ : uDstAccountID;
379 SLE::ref sleLowAccount = !bHigh ? sle : sleDst;
380 SLE::ref sleHighAccount = bHigh ? sle : sleDst;
386 saLowBalance = sleRippleState->getFieldAmount(sfBalance);
387 saHighBalance = -saLowBalance;
393 sleRippleState->setFieldAmount(!bHigh ? sfLowLimit : sfHighLimit, saLimitAllow);
395 saLowLimit = !bHigh ? saLimitAllow : sleRippleState->getFieldAmount(sfLowLimit);
396 saHighLimit = bHigh ? saLimitAllow : sleRippleState->getFieldAmount(sfHighLimit);
406 uLowQualityIn = sleRippleState->getFieldU32(sfLowQualityIn);
407 uHighQualityIn = sleRippleState->getFieldU32(sfHighQualityIn);
409 else if (uQualityIn != 0u)
413 sleRippleState->setFieldU32(!bHigh ? sfLowQualityIn : sfHighQualityIn, uQualityIn);
415 uLowQualityIn = !bHigh ? uQualityIn : sleRippleState->getFieldU32(sfLowQualityIn);
416 uHighQualityIn = bHigh ? uQualityIn : sleRippleState->getFieldU32(sfHighQualityIn);
422 sleRippleState->makeFieldAbsent(!bHigh ? sfLowQualityIn : sfHighQualityIn);
424 uLowQualityIn = !bHigh ? 0 : sleRippleState->getFieldU32(sfLowQualityIn);
425 uHighQualityIn = bHigh ? 0 : sleRippleState->getFieldU32(sfHighQualityIn);
428 if (QUALITY_ONE == uLowQualityIn)
431 if (QUALITY_ONE == uHighQualityIn)
442 uLowQualityOut = sleRippleState->getFieldU32(sfLowQualityOut);
443 uHighQualityOut = sleRippleState->getFieldU32(sfHighQualityOut);
445 else if (uQualityOut != 0u)
449 sleRippleState->setFieldU32(!bHigh ? sfLowQualityOut : sfHighQualityOut, uQualityOut);
451 uLowQualityOut = !bHigh ? uQualityOut : sleRippleState->getFieldU32(sfLowQualityOut);
452 uHighQualityOut = bHigh ? uQualityOut : sleRippleState->getFieldU32(sfHighQualityOut);
458 sleRippleState->makeFieldAbsent(!bHigh ? sfLowQualityOut : sfHighQualityOut);
460 uLowQualityOut = !bHigh ? 0 : sleRippleState->getFieldU32(sfLowQualityOut);
461 uHighQualityOut = bHigh ? 0 : sleRippleState->getFieldU32(sfHighQualityOut);
464 std::uint32_t const uFlagsIn(sleRippleState->getFieldU32(sfFlags));
467 if (bSetNoRipple && !bClearNoRipple)
469 if ((bHigh ? saHighBalance : saLowBalance) >=
beast::kZero)
471 uFlagsOut |= (bHigh ? lsfHighNoRipple : lsfLowNoRipple);
479 else if (bClearNoRipple && !bSetNoRipple)
481 uFlagsOut &= ~(bHigh ? lsfHighNoRipple : lsfLowNoRipple);
485 bool const bNoFreeze = sle->isFlag(lsfNoFreeze);
486 uFlagsOut = computeFreezeFlags(
495 if (QUALITY_ONE == uLowQualityOut)
498 if (QUALITY_ONE == uHighQualityOut)
501 bool const bLowDefRipple = sleLowAccount->isFlag(lsfDefaultRipple);
502 bool const bHighDefRipple = sleHighAccount->isFlag(lsfDefaultRipple);
504 bool const bLowReserveSet = (uLowQualityIn != 0u) || (uLowQualityOut != 0u) ||
505 ((uFlagsOut & lsfLowNoRipple) == 0) != bLowDefRipple ||
506 ((uFlagsOut & lsfLowFreeze) != 0u) || saLowLimit || saLowBalance >
beast::kZero;
507 bool const bLowReserveClear = !bLowReserveSet;
509 bool const bHighReserveSet = (uHighQualityIn != 0u) || (uHighQualityOut != 0u) ||
510 ((uFlagsOut & lsfHighNoRipple) == 0) != bHighDefRipple ||
511 ((uFlagsOut & lsfHighFreeze) != 0u) || saHighLimit || saHighBalance >
beast::kZero;
512 bool const bHighReserveClear = !bHighReserveSet;
514 bool const bDefault = bLowReserveClear && bHighReserveClear;
516 bool const bLowReserved = sleRippleState->isFlag(lsfLowReserve);
517 bool const bHighReserved = sleRippleState->isFlag(lsfHighReserve);
519 bool bReserveIncrease =
false;
521 auto const currentHighSponsor =
523 auto const currentLowSponsor =
528 uFlagsOut |= (bHigh ? lsfHighAuth : lsfLowAuth);
531 if (bLowReserveSet && !bLowReserved)
533 SLE::pointer const lowSponsor = getSponsor(uLowAccountID);
535 if (
view().rules().enabled(featureSponsor))
538 ctx_.getApplyViewContext(),
542 {.ownerCountDelta = 1},
553 uFlagsOut |= lsfLowReserve;
558 bReserveIncrease =
true;
561 if (bLowReserveClear && bLowReserved)
565 uFlagsOut &= ~lsfLowReserve;
570 if (bHighReserveSet && !bHighReserved)
572 SLE::pointer const highSponsor = getSponsor(uHighAccountID);
577 if (
view().rules().enabled(featureSponsor))
580 ctx_.getApplyViewContext(),
584 {.ownerCountDelta = 1},
595 uFlagsOut |= lsfHighReserve;
600 bReserveIncrease =
true;
603 if (bHighReserveClear && bHighReserved)
607 uFlagsOut &= ~lsfHighReserve;
612 if (uFlagsIn != uFlagsOut)
613 sleRippleState->setFieldU32(sfFlags, uFlagsOut);
615 if (
view().rules().enabled(featureSponsor))
622 trustDelete(
view(), sleRippleState, uLowAccountID, uHighAccountID, viewJ);
627 ctx_.getApplyViewContext(),
634 !freeTrustLine && bReserveIncrease && !
isTesSuccess(ret))
636 JLOG(
j_.trace()) <<
"Delay transaction: Insufficent reserve to "
647 JLOG(
j_.trace()) <<
"Modify ripple line";
657 trustDelete(
view(), sleRippleState, uLowAccountID, uHighAccountID, viewJ);
662 JLOG(
j_.trace()) <<
"Delay transaction: Insufficent reserve to "
673 JLOG(
j_.trace()) <<
"Modify ripple line";
680 (!bQualityIn || (uQualityIn == 0u)) &&
682 (!bQualityOut || (uQualityOut == 0u)) &&
686 JLOG(
j_.trace()) <<
"Redundant: Setting non-existent ripple line to defaults.";
692 JLOG(
j_.trace()) <<
"Delay transaction: Line does not exist. "
693 "Insufficent reserve to create line.";
701 ctx_.getApplyViewContext(),
705 {.ownerCountDelta = 1},
708 view().rules().enabled(featureSponsor) && !freeTrustLine &&
711 JLOG(
j_.trace()) <<
"Delay transaction: Line does not exist. "
712 "Insufficent reserve to create line.";
725 JLOG(
j_.trace()) <<
"doTrustSet: Creating ripple line: " <<
to_string(k.key);
736 bSetNoRipple && !bClearNoRipple,
737 bSetFreeze && !bClearFreeze,