20#include <xrpld/ledger/ReadView.h>
21#include <xrpld/ledger/View.h>
22#include <xrpl/basics/Log.h>
23#include <xrpl/basics/chrono.h>
24#include <xrpl/basics/contract.h>
25#include <xrpl/beast/utility/instrumentation.h>
26#include <xrpl/protocol/Feature.h>
27#include <xrpl/protocol/Protocol.h>
28#include <xrpl/protocol/Quality.h>
29#include <xrpl/protocol/st.h>
40 std::is_same_v<std::remove_cv_t<N>,
SLE> &&
41 std::is_base_of_v<ReadView, V>>>
50 auto const& svIndexes = page->getFieldV256(sfIndexes);
52 index <= svIndexes.size(),
53 "ripple::detail::internalDirNext : index inside range");
55 if (index >= svIndexes.size())
57 auto const next = page->getFieldU64(sfIndexNext);
65 if constexpr (std::is_const_v<N>)
70 XRPL_ASSERT(page,
"ripple::detail::internalDirNext : non-null root");
80 entry = svIndexes[index++];
88 std::is_same_v<std::remove_cv_t<N>,
SLE> &&
89 std::is_base_of_v<ReadView, V>>>
98 if constexpr (std::is_const_v<N>)
195 if constexpr (std::is_same_v<TIss, Issue>)
212 if (issuer != account)
249 if (issuer != account)
282 if (issuer == account)
324 auto const allowBalance = [&]() {
332 if (
isFrozen(view, account, currency, issuer) ||
347 else if (sleIssuer->isFieldPresent(sfAMMID))
356 (*sleAmm)[sfAsset].get<Issue>(),
357 (*sleAmm)[sfAsset2].get<Issue>()))
370 amount = sle->getFieldAmount(sfBalance);
371 if (account > issuer)
383 JLOG(j.
trace()) <<
"accountHolds:" <<
" account=" <<
to_string(account)
415 amount.
clear(mptIssue);
418 amount.
clear(mptIssue);
421 amount =
STAmount{mptIssue, sleMpt->getFieldU64(sfMPTAmount)};
427 auto const sleIssuance =
434 amount.
clear(mptIssue);
483 <<
"Account " << *
id <<
" owner count exceeds max!";
496 <<
"Account " << *
id <<
" owner count set below 0!";
499 XRPL_ASSERT(!
id,
"ripple::confineOwnerCount : id is not set");
518 view.
ownerCountHook(
id, sle->getFieldU32(sfOwnerCount)), ownerCountAdj);
521 auto const reserve = sle->isFieldPresent(sfAMMID)
525 auto const fullBalance = sle->getFieldAmount(sfBalance);
530 (balance < reserve) ?
STAmount{0} : balance - reserve;
532 JLOG(j.
trace()) <<
"accountHolds:"
535 <<
" fullBalance=" << fullBalance.getFullText()
536 <<
" balance=" << balance.getFullText()
537 <<
" reserve=" << reserve <<
" ownerCount=" << ownerCount
538 <<
" ownerCountAdj=" << ownerCountAdj;
550 root.type == ltDIR_NODE,
"ripple::forEachItem : valid root type");
552 if (
root.type != ltDIR_NODE)
559 auto sle = view.
read(pos);
562 for (
auto const& key : sle->getFieldV256(sfIndexes))
564 auto const next = sle->getFieldU64(sfIndexNext);
581 root.type == ltDIR_NODE,
"ripple::forEachItemAfter : valid root type");
583 if (
root.type != ltDIR_NODE)
586 auto currentIndex =
root;
589 if (
after.isNonZero())
593 if (
auto hintDir = view.
read(hintIndex))
595 for (
auto const& key : hintDir->getFieldV256(sfIndexes))
600 currentIndex = hintIndex;
609 auto const ownerDir = view.
read(currentIndex);
612 for (
auto const& key : ownerDir->getFieldV256(sfIndexes))
625 auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext);
635 auto const ownerDir = view.
read(currentIndex);
638 for (
auto const& key : ownerDir->getFieldV256(sfIndexes))
641 auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext);
654 if (sle && sle->isFieldPresent(sfTransferRate))
655 return Rate{sle->getFieldU32(sfTransferRate)};
667 sle && sle->isFieldPresent(sfTransferFee))
668 return Rate{1'000'000'000u + 10'000 * sle->getFieldU16(sfTransferFee)};
689 if (hash && (*hash != validLedger.
info().
hash))
691 JLOG(s) << reason <<
" incompatible with valid ledger";
693 JLOG(s) <<
"Hash(VSeq): " <<
to_string(*hash);
705 if (hash && (*hash != testLedger.
info().
hash))
707 JLOG(s) << reason <<
" incompatible preceding ledger";
709 JLOG(s) <<
"Hash(NSeq): " <<
to_string(*hash);
719 JLOG(s) << reason <<
" incompatible ledger";
726 JLOG(s) <<
"Val: " << validLedger.
info().
seq <<
" "
729 JLOG(s) <<
"New: " << testLedger.
info().
seq <<
" "
746 if (testLedger.
info().
seq > validIndex)
753 if (hash && (*hash != validHash))
755 JLOG(s) << reason <<
" incompatible following ledger";
756 JLOG(s) <<
"Hash(VSeq): " <<
to_string(*hash);
762 (validIndex == testLedger.
info().
seq) &&
763 (testLedger.
info().
hash != validHash))
765 JLOG(s) << reason <<
" incompatible ledger";
772 JLOG(s) <<
"Val: " << validIndex <<
" " <<
to_string(validHash);
774 JLOG(s) <<
"New: " << testLedger.
info().
seq <<
" "
784 auto const sleNode = view.
read(k);
787 if (!sleNode->getFieldV256(sfIndexes).empty())
792 return sleNode->getFieldU64(sfIndexNext) == 0;
802 if (sle->isFieldPresent(sfAmendments))
804 auto const& v = sle->getFieldV256(sfAmendments);
805 amendments.insert(v.begin(), v.end());
819 if (sle->isFieldPresent(sfMajorities))
822 using d = tp::duration;
824 auto const majorities = sle->getFieldArray(sfMajorities);
826 for (
auto const& m : majorities)
827 ret[m.getFieldH256(sfAmendment)] =
828 tp(d(m.getFieldU32(sfCloseTime)));
839 if (seq > ledger.
seq())
842 <<
"Can't get seq " << seq <<
" from " << ledger.
seq() <<
" future";
845 if (seq == ledger.
seq())
847 if (seq == (ledger.
seq() - 1))
850 if (
int diff = ledger.
seq() - seq; diff <= 256)
857 hashIndex->getFieldU32(sfLastLedgerSequence) ==
859 "ripple::hashOfSeq : matching ledger sequence");
860 STVector256 vec = hashIndex->getFieldV256(sfHashes);
861 if (vec.
size() >= diff)
862 return vec[vec.
size() - diff];
864 <<
"Ledger " << ledger.
seq() <<
" missing hash for " << seq
865 <<
" (" << vec.
size() <<
"," << diff <<
")";
870 <<
"Ledger " << ledger.
seq() <<
":" << ledger.
info().
hash
871 <<
" missing normal list";
875 if ((seq & 0xff) != 0)
877 JLOG(journal.
debug())
878 <<
"Can't get seq " << seq <<
" from " << ledger.
seq() <<
" past";
886 auto const lastSeq = hashIndex->getFieldU32(sfLastLedgerSequence);
887 XRPL_ASSERT(lastSeq >= seq,
"ripple::hashOfSeq : minimum last ledger");
889 (lastSeq & 0xff) == 0,
"ripple::hashOfSeq : valid last ledger");
890 auto const diff = (lastSeq - seq) >> 8;
891 STVector256 vec = hashIndex->getFieldV256(sfHashes);
892 if (vec.
size() > diff)
893 return vec[vec.
size() - diff - 1];
895 JLOG(journal.
warn()) <<
"Can't get seq " << seq <<
" from " << ledger.
seq()
915 XRPL_ASSERT(amount,
"ripple::adjustOwnerCount : nonzero amount input");
920 sle->setFieldU32(sfOwnerCount, adjusted);
928 (*sle)[sfOwner] = account;
941 const bool bNoRipple,
952 JLOG(j.
trace()) <<
"trustCreate: " <<
to_string(uSrcAccountID) <<
", "
956 auto const& uLowAccountID = !bSrcHigh ? uSrcAccountID : uDstAccountID;
957 auto const& uHighAccountID = bSrcHigh ? uSrcAccountID : uDstAccountID;
959 auto const sleRippleState = std::make_shared<SLE>(ltRIPPLE_STATE, uIndex);
960 view.
insert(sleRippleState);
964 sleRippleState->
key(),
972 sleRippleState->
key(),
978 const bool bSetDst = saLimit.
getIssuer() == uDstAccountID;
979 const bool bSetHigh = bSrcHigh ^ bSetDst;
981 XRPL_ASSERT(sleAccount,
"ripple::trustCreate : non-null SLE");
987 (bSetHigh ? uHighAccountID : uLowAccountID),
988 "ripple::trustCreate : matching account ID");
995 sleRippleState->setFieldU64(sfLowNode, *lowNode);
996 sleRippleState->setFieldU64(sfHighNode, *highNode);
998 sleRippleState->setFieldAmount(
999 bSetHigh ? sfHighLimit : sfLowLimit, saLimit);
1000 sleRippleState->setFieldAmount(
1001 bSetHigh ? sfLowLimit : sfHighLimit,
1003 saBalance.
getCurrency(), bSetDst ? uSrcAccountID : uDstAccountID}));
1006 sleRippleState->setFieldU32(
1007 bSetHigh ? sfHighQualityIn : sfLowQualityIn, uQualityIn);
1010 sleRippleState->setFieldU32(
1011 bSetHigh ? sfHighQualityOut : sfLowQualityOut, uQualityOut);
1038 sleRippleState->setFieldU32(sfFlags, uFlags);
1042 sleRippleState->setFieldAmount(
1043 sfBalance, bSetHigh ? -saBalance : saBalance);
1046 uSrcAccountID, uDstAccountID, saBalance, saBalance.
zeroed());
1060 std::uint64_t uLowNode = sleRippleState->getFieldU64(sfLowNode);
1061 std::uint64_t uHighNode = sleRippleState->getFieldU64(sfHighNode);
1063 JLOG(j.
trace()) <<
"trustDelete: Deleting ripple line: low";
1068 sleRippleState->key(),
1074 JLOG(j.
trace()) <<
"trustDelete: Deleting ripple line: high";
1079 sleRippleState->key(),
1085 JLOG(j.
trace()) <<
"trustDelete: Deleting ripple line: state";
1086 view.
erase(sleRippleState);
1096 auto offerIndex = sle->key();
1097 auto owner = sle->getAccountID(sfAccount);
1100 uint256 uDirectory = sle->getFieldH256(sfBookDirectory);
1104 sle->getFieldU64(sfOwnerNode),
1113 sle->getFieldU64(sfBookNode),
1145 !bCheckIssuer || uSenderID == issuer || uReceiverID == issuer,
1146 "ripple::rippleCreditIOU : matching issuer or don't care");
1151 uSenderID != uReceiverID,
1152 "ripple::rippleCreditIOU : sender is not receiver");
1154 bool const bSenderHigh = uSenderID > uReceiverID;
1155 auto const index =
keylet::line(uSenderID, uReceiverID, currency);
1159 "ripple::rippleCreditIOU : sender is not XRP");
1162 "ripple::rippleCreditIOU : receiver is not XRP");
1165 if (
auto const sleRippleState = view.
peek(index))
1167 STAmount saBalance = sleRippleState->getFieldAmount(sfBalance);
1172 view.
creditHook(uSenderID, uReceiverID, saAmount, saBalance);
1174 STAmount const saBefore = saBalance;
1176 saBalance -= saAmount;
1178 JLOG(j.
trace()) <<
"rippleCreditIOU: " <<
to_string(uSenderID) <<
" -> "
1184 std::uint32_t const uFlags(sleRippleState->getFieldU32(sfFlags));
1185 bool bDelete =
false;
1189 if (saBefore > beast::zero
1191 && saBalance <= beast::zero
1202 !sleRippleState->getFieldAmount(
1203 !bSenderHigh ? sfLowLimit : sfHighLimit)
1205 && !sleRippleState->getFieldU32(
1206 !bSenderHigh ? sfLowQualityIn : sfHighQualityIn)
1208 && !sleRippleState->getFieldU32(
1209 !bSenderHigh ? sfLowQualityOut : sfHighQualityOut))
1217 sleRippleState->setFieldU32(
1222 bDelete = !saBalance
1231 sleRippleState->setFieldAmount(sfBalance, saBalance);
1239 bSenderHigh ? uReceiverID : uSenderID,
1240 !bSenderHigh ? uReceiverID : uSenderID,
1244 view.
update(sleRippleState);
1248 STAmount const saReceiverLimit(
Issue{currency, uReceiverID});
1253 JLOG(j.
debug()) <<
"rippleCreditIOU: "
1295 auto const issuer = saAmount.
getIssuer();
1299 "ripple::rippleSendIOU : neither sender nor receiver is XRP");
1301 uSenderID != uReceiverID,
1302 "ripple::rippleSendIOU : sender is not receiver");
1304 if (uSenderID == issuer || uReceiverID == issuer || issuer ==
noAccount())
1311 saActual = saAmount;
1323 JLOG(j.
debug()) <<
"rippleSendIOU> " <<
to_string(uSenderID) <<
" - > "
1332 terResult =
rippleCreditIOU(view, uSenderID, issuer, saActual,
true, j);
1357 "ripple::accountSendIOU : minimum amount and not MPT");
1363 if (!saAmount || (uSenderID == uReceiverID))
1370 JLOG(j.
trace()) <<
"accountSendIOU: " <<
to_string(uSenderID) <<
" -> "
1375 view, uSenderID, uReceiverID, saAmount, saActual, j, waiveFee);
1392 if (
auto stream = j.
trace())
1403 stream <<
"accountSendIOU> " <<
to_string(uSenderID) <<
" ("
1404 << sender_bal <<
") -> " <<
to_string(uReceiverID) <<
" ("
1405 << receiver_bal <<
") : " << saAmount.
getFullText();
1438 if (
auto stream = j.
trace())
1449 stream <<
"accountSendIOU< " <<
to_string(uSenderID) <<
" ("
1450 << sender_bal <<
") -> " <<
to_string(uReceiverID) <<
" ("
1451 << receiver_bal <<
") : " << saAmount.
getFullText();
1466 auto const issuer = saAmount.
getIssuer();
1467 auto sleIssuance = view.
peek(mptID);
1470 if (uSenderID == issuer)
1472 (*sleIssuance)[sfOutstandingAmount] += saAmount.
mpt().
value();
1473 view.
update(sleIssuance);
1478 if (
auto sle = view.
peek(mptokenID))
1480 auto const amt = sle->getFieldU64(sfMPTAmount);
1481 auto const pay = saAmount.
mpt().
value();
1484 (*sle)[sfMPTAmount] = amt - pay;
1491 if (uReceiverID == issuer)
1493 auto const outstanding = sleIssuance->getFieldU64(sfOutstandingAmount);
1494 auto const redeem = saAmount.
mpt().
value();
1495 if (outstanding >= redeem)
1497 sleIssuance->setFieldU64(sfOutstandingAmount, outstanding - redeem);
1498 view.
update(sleIssuance);
1506 if (
auto sle = view.
peek(mptokenID))
1508 (*sle)[sfMPTAmount] += saAmount.
mpt().
value();
1528 uSenderID != uReceiverID,
1529 "ripple::rippleSendMPT : sender is not receiver");
1532 auto const issuer = saAmount.
getIssuer();
1539 if (uSenderID == issuer || uReceiverID == issuer)
1543 if (uSenderID == issuer)
1545 auto const sendAmount = saAmount.
mpt().
value();
1546 auto const maximumAmount =
1548 if (sendAmount > maximumAmount ||
1549 sle->getFieldU64(sfOutstandingAmount) >
1550 maximumAmount - sendAmount)
1559 saActual = saAmount;
1570 JLOG(j.
debug()) <<
"rippleSendMPT> " <<
to_string(uSenderID) <<
" - > "
1575 if (
auto const terResult =
1594 "ripple::accountSendMPT : minimum amount and MPT");
1599 if (!saAmount || (uSenderID == uReceiverID))
1605 view, uSenderID, uReceiverID, saAmount, saActual, j, waiveFee);
1619 if constexpr (std::is_same_v<TIss, Issue>)
1621 view, uSenderID, uReceiverID, saAmount, j, waiveFee);
1624 view, uSenderID, uReceiverID, saAmount, j, waiveFee);
1648 if (before > beast::zero
1650 &&
after <= beast::zero
1654 &&
static_cast<bool>(
1660 && !state->
getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn)
1663 !state->
getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut))
1692 "ripple::issueIOU : neither account nor issuer is XRP");
1695 XRPL_ASSERT(issue == amount.
issue(),
"ripple::issueIOU : matching issue");
1699 issue.
account != account,
"ripple::issueIOU : not issuer account");
1704 bool bSenderHigh = issue.
account > account;
1708 if (
auto state = view.
peek(index))
1710 STAmount final_balance = state->getFieldAmount(sfBalance);
1715 STAmount const start_balance = final_balance;
1717 final_balance -= amount;
1736 state->setFieldAmount(sfBalance, final_balance);
1741 bSenderHigh ? account : issue.
account,
1742 bSenderHigh ? issue.
account : account,
1759 if (!receiverAccount)
1792 "ripple::redeemIOU : neither account nor issuer is XRP");
1795 XRPL_ASSERT(issue == amount.
issue(),
"ripple::redeemIOU : matching issue");
1799 issue.
account != account,
"ripple::redeemIOU : not issuer account");
1804 bool bSenderHigh = account > issue.
account;
1809 STAmount final_balance = state->getFieldAmount(sfBalance);
1814 STAmount const start_balance = final_balance;
1816 final_balance -= amount;
1819 view, state, bSenderHigh, account, start_balance, final_balance, j);
1829 state->setFieldAmount(sfBalance, final_balance);
1836 bSenderHigh ? issue.
account : account,
1837 bSenderHigh ? account : issue.
account,
1850 <<
" but no trust line exists!";
1864 from != beast::zero,
"ripple::transferXRP : nonzero from account");
1865 XRPL_ASSERT(to != beast::zero,
"ripple::transferXRP : nonzero to account");
1866 XRPL_ASSERT(from != to,
"ripple::transferXRP : sender is not receiver");
1867 XRPL_ASSERT(amount.
native(),
"ripple::transferXRP : amount is XRP");
1871 if (!sender || !receiver)
1906 if (
auto const trustLine =
1908 return ((*trustLine)[sfFlags] &
1925 auto const sleIssuance = view.
read(mptID);
1930 auto const mptIssuer = sleIssuance->getAccountID(sfIssuer);
1933 if (mptIssuer == account)
1937 auto const sleToken = view.
read(mptokenID);
1959 auto const sleIssuance = view.
read(mptID);
1965 if (from != (*sleIssuance)[sfIssuer] && to != (*sleIssuance)[sfIssuer])
1974 Keylet const& ownerDirKeylet,
1981 unsigned int uDirEntry{0};
1982 uint256 dirEntry{beast::zero};
1985 if (view.
exists(ownerDirKeylet) &&
1986 dirFirst(view, ownerDirKeylet.
key, sleDirNode, uDirEntry, dirEntry))
1990 if (maxNodesToDelete && ++deleted > *maxNodesToDelete)
1999 <<
"DeleteAccount: Directory node in ledger " << view.
seq()
2000 <<
" has index to object that is missing: "
2006 sleItem->getFieldU16(sfLedgerEntryType))};
2010 auto const [ter, skipEntry] = deleter(nodeType, dirEntry, sleItem);
2032 "ripple::cleanupOnAccountDelete : minimum dir entries");
2036 <<
"DeleteAccount iterator re-validation failed.";
2043 dirNext(view, ownerDirKeylet.
key, sleDirNode, uDirEntry, dirEntry));
2056 if (!sleState || sleState->getType() != ltRIPPLE_STATE)
2060 sleState->getFieldAmount(sfLowLimit).getIssuer(),
2061 sleState->getFieldAmount(sfHighLimit).getIssuer());
2064 if (!sleLow || !sleHigh)
2066 bool const ammLow = sleLow->isFieldPresent(sfAMMID);
2067 bool const ammHigh = sleHigh->isFieldPresent(sfAMMID);
2070 if (ammLow && ammHigh)
2074 if (!ammLow && !ammHigh)
2081 if (
auto const ter =
trustDelete(view, sleState, low, high, j);
2085 <<
"deleteAMMTrustLine: failed to delete the trustline.";
2090 if (!(sleState->getFlags() & uFlags))
2109 if constexpr (std::is_same_v<TIss, Issue>)
2112 view, uSenderID, uReceiverID, saAmount, bCheckIssuer, j);
2118 "ripple::rippleCredit : not checking issuer");
2120 view, uSenderID, uReceiverID, saAmount, j);
Provide a light-weight way to check active() before string formatting.
A generic endpoint for log messages.
static Sink & getNullSink()
Returns a Sink which does nothing.
Stream trace() const
Severity stream access functions.
Writeable view to a ledger, for applying a transaction.
virtual void creditHook(AccountID const &from, AccountID const &to, STAmount const &amount, STAmount const &preCreditBalance)
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
virtual void adjustOwnerCountHook(AccountID const &account, std::uint32_t cur, std::uint32_t next)
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
constexpr value_type const & value() const
A currency issued by an account.
constexpr value_type value() const
Returns the underlying value.
MPTID const & getMptID() const
std::chrono::time_point< NetClock > time_point
std::chrono::duration< rep, period > duration
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
NetClock::time_point parentCloseTime() const
Returns the close time of the previous ledger.
virtual std::uint32_t ownerCountHook(AccountID const &account, std::uint32_t count) const
virtual STAmount balanceHook(AccountID const &account, AccountID const &issuer, STAmount const &amount) const
virtual bool open() const =0
Returns true if this reflects an open ledger.
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
LedgerIndex seq() const
Returns the sequence number of the base ledger.
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
virtual Rules const & rules() const =0
Returns the tx processing rules.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
constexpr bool holds() const noexcept
Asset const & asset() const
constexpr TIss const & get() const
void setIssuer(AccountID const &uIssuer)
Currency const & getCurrency() const
AccountID const & getIssuer() const
Issue const & issue() const
std::string getFullText() const override
bool native() const noexcept
STAmount zeroed() const
Returns a zero value with the same issuer and currency.
const std::shared_ptr< STLedgerEntry > & ref
std::shared_ptr< STLedgerEntry > pointer
AccountID getAccountID(SField const &field) const
std::uint32_t getFieldU32(SField const &field) const
void setFieldAmount(SField const &field, STAmount const &)
STAmount const & getFieldAmount(SField const &field) const
void setFieldU32(SField const &field, std::uint32_t)
bool internalDirFirst(V &view, uint256 const &root, std::shared_ptr< N > &page, unsigned int &index, uint256 &entry)
bool internalDirNext(V &view, uint256 const &root, std::shared_ptr< N > &page, unsigned int &index, uint256 &entry)
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Keylet amm(Asset const &issue1, Asset const &issue2) noexcept
AMM entry.
Keylet line(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
Keylet const & amendments() noexcept
The index of the amendment table.
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet const & skip() noexcept
The index of the "short" skip list.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
AccountID const & noAccount()
A placeholder for empty accounts.
static bool updateTrustLine(ApplyView &view, SLE::pointer state, bool bSenderHigh, AccountID const &sender, STAmount const &before, STAmount const &after, beast::Journal j)
STAmount accountFunds(ReadView const &view, AccountID const &id, STAmount const &saDefault, FreezeHandling freezeHandling, beast::Journal j)
FreezeHandling
Controls the treatment of frozen account balances.
bool cdirFirst(ReadView const &view, uint256 const &root, std::shared_ptr< SLE const > &page, unsigned int &index, uint256 &entry)
Returns the first entry in the directory, advancing the index.
bool isXRP(AccountID const &c)
AccountID const & xrpAccount()
Compute AccountID from public key.
bool isIndividualFrozen(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer)
TER deleteAMMTrustLine(ApplyView &view, std::shared_ptr< SLE > sleState, std::optional< AccountID > const &ammAccountID, beast::Journal j)
Delete trustline to AMM.
static TER rippleSendMPT(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, STAmount &saActual, beast::Journal j, WaiveTransferFee waiveFee)
bool dirFirst(ApplyView &view, uint256 const &root, std::shared_ptr< SLE > &page, unsigned int &index, uint256 &entry)
bool dirNext(ApplyView &view, uint256 const &root, std::shared_ptr< SLE > &page, unsigned int &index, uint256 &entry)
TER requireAuth(ReadView const &view, Issue const &issue, AccountID const &account)
Check if the account lacks required authorization.
bool isDeepFrozen(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer)
std::optional< uint256 > hashOfSeq(ReadView const &ledger, LedgerIndex seq, beast::Journal journal)
Return the hash of a ledger by sequence.
Rate transferRate(ReadView const &view, AccountID const &issuer)
Returns IOU issuer transfer fee as Rate.
std::uint64_t constexpr maxMPTokenAmount
The maximum amount of MPTokenIssuance.
TER redeemIOU(ApplyView &view, AccountID const &account, STAmount const &amount, Issue const &issue, beast::Journal j)
STAmount multiply(STAmount const &amount, Rate const &rate)
AuthHandling
Controls the treatment of unauthorized MPT balances.
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
TER transferXRP(ApplyView &view, AccountID const &from, AccountID const &to, STAmount const &amount, beast::Journal j)
@ current
This was a new validation and was added.
TER offerDelete(ApplyView &view, std::shared_ptr< SLE > const &sle, beast::Journal j)
Delete an offer.
bool isFrozen(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer)
std::set< uint256 > getEnabledAmendments(ReadView const &view)
TER canTransfer(ReadView const &view, MPTIssue const &mptIssue, AccountID const &from, AccountID const &to)
Check if the destination account is allowed to receive MPT.
AccountID ammAccountID(std::uint16_t prefix, uint256 const &parentHash, uint256 const &ammID)
Calculate AMM account ID.
static std::uint32_t confineOwnerCount(std::uint32_t current, std::int32_t adjustment, std::optional< AccountID > const &id=std::nullopt, beast::Journal j=beast::Journal{beast::Journal::getNullSink()})
static TER rippleCreditIOU(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, bool bCheckIssuer, beast::Journal j)
static bool adjustOwnerCount(ApplyContext &ctx, int count)
TER issueIOU(ApplyView &view, AccountID const &account, STAmount const &amount, Issue const &issue, beast::Journal j)
static TER accountSendIOU(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, beast::Journal j, WaiveTransferFee waiveFee)
std::map< uint256, NetClock::time_point > majorityAmendments_t
TER trustCreate(ApplyView &view, const bool bSrcHigh, AccountID const &uSrcAccountID, AccountID const &uDstAccountID, uint256 const &uIndex, SLE::ref sleAccount, const bool bAuth, const bool bNoRipple, const bool bFreeze, bool bDeepFreeze, STAmount const &saBalance, STAmount const &saLimit, std::uint32_t uQualityIn, std::uint32_t uQualityOut, beast::Journal j)
Create a trust line.
bool cdirNext(ReadView const &view, uint256 const &root, std::shared_ptr< SLE const > &page, unsigned int &index, uint256 &entry)
Returns the next entry in the directory, advancing the index.
TER trustDelete(ApplyView &view, std::shared_ptr< SLE > const &sleRippleState, AccountID const &uLowAccountID, AccountID const &uHighAccountID, beast::Journal j)
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
bool isLPTokenFrozen(ReadView const &view, AccountID const &account, Issue const &asset, Issue const &asset2)
majorityAmendments_t getMajorityAmendments(ReadView const &view)
std::string to_string(base_uint< Bits, Tag > const &a)
LedgerEntryType
Identifiers for on-ledger objects.
bool forEachItemAfter(ReadView const &view, Keylet const &root, uint256 const &after, std::uint64_t const hint, unsigned int limit, std::function< bool(std::shared_ptr< SLE const > const &)> const &f)
Iterate all items after an item in the given directory.
TER cleanupOnAccountDelete(ApplyView &view, Keylet const &ownerDirKeylet, EntryDeleter const &deleter, beast::Journal j, std::optional< uint16_t > maxNodesToDelete)
void forEachItem(ReadView const &view, Keylet const &root, std::function< void(std::shared_ptr< SLE const > const &)> const &f)
Iterate all items in the given directory.
Number root(Number f, unsigned d)
bool hasExpired(ReadView const &view, std::optional< std::uint32_t > const &exp)
Determines whether the given expiration time has passed.
static TER rippleSendIOU(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, STAmount &saActual, beast::Journal j, WaiveTransferFee waiveFee)
TER rippleCredit(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, bool bCheckIssuer, beast::Journal j)
Calls static rippleCreditIOU if saAmount represents Issue.
TERSubset< CanCvtToTER > TER
bool areCompatible(ReadView const &validLedger, ReadView const &testLedger, beast::Journal::Stream &s, const char *reason)
Return false if the test ledger is provably incompatible with the valid ledger, that is,...
static bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
static TER rippleCreditMPT(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, beast::Journal j)
bool dirIsEmpty(ReadView const &view, Keylet const &k)
Returns true if the directory is empty.
TER accountSend(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, beast::Journal j, WaiveTransferFee waiveFee)
Calls static accountSendIOU if saAmount represents Issue.
static TER accountSendMPT(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, beast::Journal j, WaiveTransferFee waiveFee)
Rate const parityRate
A transfer rate signifying a 1:1 exchange.
XRPAmount xrpLiquid(ReadView const &view, AccountID const &id, std::int32_t ownerCountAdj, beast::Journal j)
bool isGlobalFrozen(ReadView const &view, AccountID const &issuer)
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
A pair of SHAMap key and LedgerEntryType.
Represents a transfer rate.