1#include <xrpl/basics/Log.h> 
    2#include <xrpl/beast/utility/instrumentation.h> 
    3#include <xrpl/json/to_string.h> 
    4#include <xrpl/ledger/detail/ApplyStateTable.h> 
    5#include <xrpl/protocol/Feature.h> 
    6#include <xrpl/protocol/st.h> 
   15    for (
auto const& item : 
items_)
 
   17        auto const& sle = item.second.second;
 
   18        switch (item.second.first)
 
 
   41        switch (item.second.first)
 
 
   65        switch (item.second.first)
 
   76                func(item.first, 
false, 
nullptr, item.second.second);
 
 
  108    if (!to.
open() || isDryRun)
 
  119            switch (item.second.first)
 
  125                    type = &sfDeletedNode;
 
  128                    type = &sfCreatedNode;
 
  131                    type = &sfModifiedNode;
 
  135            auto curNode = item.second.second;
 
  136            if ((type == &sfModifiedNode) && (*curNode == *origNode))
 
  139                ? curNode->getFieldU16(sfLedgerEntryType)
 
  140                : origNode->getFieldU16(sfLedgerEntryType);
 
  142            if (type == &sfDeletedNode)
 
  146                    "ripple::detail::ApplyStateTable::apply : valid nodes for " 
  151                for (
auto const& obj : *origNode)
 
  156                        !curNode->hasMatchingEntry(obj))
 
  165                for (
auto const& obj : *curNode)
 
  168                    if (obj.getFName().shouldMeta(
 
  177            else if (type == &sfModifiedNode)
 
  181                    "ripple::detail::ApplyStateTable::apply : valid nodes for " 
  184                if (curNode->isThreadedType(
 
  190                for (
auto const& obj : *origNode)
 
  194                        !curNode->hasMatchingEntry(obj))
 
  203                for (
auto const& obj : *curNode)
 
  206                    if (obj.getFName().shouldMeta(
 
  215            else if (type == &sfCreatedNode)  
 
  218                    curNode && !origNode,
 
  219                    "ripple::detail::ApplyStateTable::apply : valid nodes for " 
  223                if (curNode->isThreadedType(
 
  228                for (
auto const& obj : *curNode)
 
  231                    if (!obj.isDefault() &&
 
  232                        obj.getFName().shouldMeta(
 
  245                    "ripple::detail::ApplyStateTable::apply : unsupported " 
  254            for (
auto const& mod : newMod)
 
 
  284    auto const& item = iter->second;
 
  285    auto const& sle = item.second;
 
 
  307    items_t::const_iterator iter;
 
  312        next = base.succ(*next, last);
 
  315        iter = items_.find(*next);
 
  316    } 
while (iter != items_.end() && iter->second.first == Action::erase);
 
  318    for (iter = items_.upper_bound(key); iter != items_.end(); ++iter)
 
  320        if (iter->second.first != Action::erase)
 
  323            if (!next || next > iter->first)
 
  330    if (last && next >= last)
 
 
  341    auto const& item = iter->second;
 
  342    auto const& sle = item.second;
 
 
  363        auto const sle = base.
read(k);
 
  371            forward_as_tuple(sle->key()),
 
  373        return iter->
second.second;
 
  375    auto const& item = iter->second;
 
  376    auto const& sle = item.second;
 
 
  396        LogicError(
"ApplyStateTable::erase: missing key");
 
  397    auto& item = iter->second;
 
  398    if (item.second != sle)
 
  399        LogicError(
"ApplyStateTable::erase: unknown SLE");
 
  403            LogicError(
"ApplyStateTable::erase: double erase");
 
 
  421        forward_as_tuple(sle->key()),
 
  425    auto& item = result.
first->second;
 
  429            LogicError(
"ApplyStateTable::rawErase: double erase");
 
 
  452            forward_as_tuple(sle->key()),
 
  456    auto& item = iter->
second;
 
  460            LogicError(
"ApplyStateTable::insert: already cached");
 
  462            LogicError(
"ApplyStateTable::insert: already inserted");
 
  464            LogicError(
"ApplyStateTable::insert: already modified");
 
 
  482            forward_as_tuple(sle->key()),
 
  486    auto& item = iter->
second;
 
  490            LogicError(
"ApplyStateTable::replace: already erased");
 
 
  506        LogicError(
"ApplyStateTable::update: missing key");
 
  507    auto& item = iter->second;
 
  508    if (item.second != sle)
 
  509        LogicError(
"ApplyStateTable::update: unknown SLE");
 
  513            LogicError(
"ApplyStateTable::update: erased");
 
 
  546        if (node.getFieldIndex(sfPreviousTxnID) == -1)
 
  549                node.getFieldIndex(sfPreviousTxnLgrSeq) == -1,
 
  550                "ripple::ApplyStateTable::threadItem : previous ledger is not " 
  552            node.setFieldH256(sfPreviousTxnID, prevTxID);
 
  553            node.setFieldU32(sfPreviousTxnLgrSeq, prevLgrID);
 
  557            node.getFieldH256(sfPreviousTxnID) == prevTxID,
 
  558            "ripple::ApplyStateTable::threadItem : previous transaction is a " 
  561            node.getFieldU32(sfPreviousTxnLgrSeq) == prevLgrID,
 
  562            "ripple::ApplyStateTable::threadItem : previous ledger is a match");
 
 
  574        auto miter = mods.
find(key);
 
  575        if (miter != mods.
end())
 
  579                "ripple::ApplyStateTable::getForMod : non-null result");
 
  580            return miter->second;
 
  587            auto const& item = iter->
second;
 
  593                JLOG(j.
warn()) << 
"Trying to thread to deleted node";
 
  609        JLOG(j.
warn()) << 
"ApplyStateTable::getForMod: key not found";
 
 
  631        JLOG(j.
warn()) << 
"Threading to non-existent account: " << 
toBase58(to);
 
  636        sle->isThreadedType(base.
rules()),
 
  637        "ripple::ApplyStateTable::threadTx : SLE is threaded");
 
 
  652        case ltACCOUNT_ROOT: {
 
  656        case ltRIPPLE_STATE: {
 
  657            threadTx(base, meta, (*sle)[sfLowLimit].getIssuer(), mods, j);
 
  658            threadTx(base, meta, (*sle)[sfHighLimit].getIssuer(), mods, j);
 
  663            if (
auto const optSleAcct{(*sle)[~sfAccount]})
 
  664                threadTx(base, meta, *optSleAcct, mods, j);
 
  667            if (
auto const optSleDest{(*sle)[~sfDestination]})
 
  668                threadTx(base, meta, *optSleDest, mods, j);
 
 
A generic endpoint for log messages.
 
Stream trace() const
Severity stream access functions.
 
Writable ledger view that accumulates state and tx changes.
 
std::size_t txCount() const
Return the number of tx inserted since creation.
 
Rules const & rules() const override
Returns the tx processing rules.
 
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
 
void rawTxInsert(key_type const &key, std::shared_ptr< Serializer const > const &txn, std::shared_ptr< Serializer const > const &metaData) override
Add a transaction to the tx map.
 
void rawReplace(std::shared_ptr< SLE > const &sle) override
Unconditionally replace a state item.
 
bool open() const override
Returns true if this reflects an open ledger.
 
Interface for ledger entry changes.
 
virtual void rawInsert(std::shared_ptr< SLE > const &sle)=0
Unconditionally insert a state item.
 
virtual void rawDestroyXRP(XRPAmount const &fee)=0
Destroy XRP.
 
virtual void rawReplace(std::shared_ptr< SLE > const &sle)=0
Unconditionally replace a state item.
 
virtual void rawErase(std::shared_ptr< SLE > const &sle)=0
Delete an existing state item.
 
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
 
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 Rules const & rules() const =0
Returns the tx processing rules.
 
void add(Serializer &s) const override
 
std::size_t emplace_back(Args &&... args)
 
uint256 getTransactionID() const
 
std::shared_ptr< SLE > peek(ReadView const &base, Keylet const &k)
 
void rawErase(ReadView const &base, std::shared_ptr< SLE > const &sle)
 
void threadTx(ReadView const &base, TxMeta &meta, AccountID const &to, Mods &mods, beast::Journal j)
 
std::shared_ptr< SLE const > read(ReadView const &base, Keylet const &k) const
 
void update(ReadView const &base, std::shared_ptr< SLE > const &sle)
 
bool exists(ReadView const &base, Keylet const &k) const
 
void visit(ReadView const &base, std::function< void(uint256 const &key, bool isDelete, std::shared_ptr< SLE const > const &before, std::shared_ptr< SLE const > const &after)> const &func) const
 
static void threadItem(TxMeta &meta, std::shared_ptr< SLE > const &to)
 
std::shared_ptr< SLE > getForMod(ReadView const &base, key_type const &key, Mods &mods, beast::Journal j)
 
void threadOwners(ReadView const &base, TxMeta &meta, std::shared_ptr< SLE const > const &sle, Mods &mods, beast::Journal j)
 
void apply(RawView &to) const
 
std::optional< key_type > succ(ReadView const &base, key_type const &key, std::optional< key_type > const &last) const
 
void replace(ReadView const &base, std::shared_ptr< SLE > const &sle)
 
void destroyXRP(XRPAmount const &fee)
 
XRPAmount dropsDestroyed_
 
T emplace_hint(T... args)
 
Keylet account(AccountID const &id) noexcept
AccountID root.
 
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
 
LedgerEntryType
Identifiers for on-ledger objects.
 
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
 
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
 
A pair of SHAMap key and LedgerEntryType.
 
bool check(STLedgerEntry const &) const
Returns true if the SLE matches the type.