20#include <xrpld/ledger/detail/ApplyStateTable.h>
21#include <xrpl/basics/Log.h>
22#include <xrpl/beast/utility/instrumentation.h>
23#include <xrpl/json/to_string.h>
24#include <xrpl/protocol/Feature.h>
25#include <xrpl/protocol/st.h>
34 for (
auto const& item :
items_)
36 auto const& sle = item.second.second;
37 switch (item.second.first)
60 switch (item.second.first)
84 switch (item.second.first)
95 func(item.first,
false,
nullptr, item.second.second);
122 auto const sTx = std::make_shared<Serializer>();
126 if (!to.
open() || isDryRun)
135 switch (item.second.first)
141 type = &sfDeletedNode;
144 type = &sfCreatedNode;
147 type = &sfModifiedNode;
151 auto curNode = item.second.second;
152 if ((type == &sfModifiedNode) && (*curNode == *origNode))
155 ? curNode->getFieldU16(sfLedgerEntryType)
156 : origNode->getFieldU16(sfLedgerEntryType);
158 if (type == &sfDeletedNode)
162 "ripple::detail::ApplyStateTable::apply : valid nodes for "
167 for (
auto const& obj : *origNode)
172 !curNode->hasMatchingEntry(obj))
181 for (
auto const& obj : *curNode)
184 if (obj.getFName().shouldMeta(
193 else if (type == &sfModifiedNode)
197 "ripple::detail::ApplyStateTable::apply : valid nodes for "
200 if (curNode->isThreadedType(
206 for (
auto const& obj : *origNode)
210 !curNode->hasMatchingEntry(obj))
219 for (
auto const& obj : *curNode)
222 if (obj.getFName().shouldMeta(
231 else if (type == &sfCreatedNode)
234 curNode && !origNode,
235 "ripple::detail::ApplyStateTable::apply : valid nodes for "
239 if (curNode->isThreadedType(
244 for (
auto const& obj : *curNode)
247 if (!obj.isDefault() &&
248 obj.getFName().shouldMeta(
260 "ripple::detail::ApplyStateTable::apply : unsupported "
268 for (
auto const& mod : newMod)
272 sMeta = std::make_shared<Serializer>();
298 auto const& item = iter->second;
299 auto const& sle = item.second;
321 items_t::const_iterator iter;
326 next = base.succ(*next, last);
329 iter = items_.find(*next);
330 }
while (iter != items_.end() && iter->second.first == Action::erase);
332 for (iter = items_.upper_bound(key); iter != items_.end(); ++iter)
334 if (iter->second.first != Action::erase)
337 if (!next || next > iter->first)
344 if (last && next >= last)
355 auto const& item = iter->second;
356 auto const& sle = item.second;
377 auto const sle = base.
read(k);
385 forward_as_tuple(sle->key()),
387 return iter->
second.second;
389 auto const& item = iter->second;
390 auto const& sle = item.second;
410 LogicError(
"ApplyStateTable::erase: missing key");
411 auto& item = iter->second;
412 if (item.second != sle)
413 LogicError(
"ApplyStateTable::erase: unknown SLE");
417 LogicError(
"ApplyStateTable::erase: double erase");
435 forward_as_tuple(sle->key()),
439 auto& item = result.
first->second;
443 LogicError(
"ApplyStateTable::rawErase: double erase");
466 forward_as_tuple(sle->key()),
470 auto& item = iter->
second;
474 LogicError(
"ApplyStateTable::insert: already cached");
476 LogicError(
"ApplyStateTable::insert: already inserted");
478 LogicError(
"ApplyStateTable::insert: already modified");
496 forward_as_tuple(sle->key()),
500 auto& item = iter->
second;
504 LogicError(
"ApplyStateTable::replace: already erased");
520 LogicError(
"ApplyStateTable::update: missing key");
521 auto& item = iter->second;
522 if (item.second != sle)
523 LogicError(
"ApplyStateTable::update: unknown SLE");
527 LogicError(
"ApplyStateTable::update: erased");
560 if (node.getFieldIndex(sfPreviousTxnID) == -1)
563 node.getFieldIndex(sfPreviousTxnLgrSeq) == -1,
564 "ripple::ApplyStateTable::threadItem : previous ledger is not "
566 node.setFieldH256(sfPreviousTxnID, prevTxID);
567 node.setFieldU32(sfPreviousTxnLgrSeq, prevLgrID);
571 node.getFieldH256(sfPreviousTxnID) == prevTxID,
572 "ripple::ApplyStateTable::threadItem : previous transaction is a "
575 node.getFieldU32(sfPreviousTxnLgrSeq) == prevLgrID,
576 "ripple::ApplyStateTable::threadItem : previous ledger is a match");
588 auto miter = mods.
find(key);
589 if (miter != mods.
end())
593 "ripple::ApplyStateTable::getForMod : non-null result");
594 return miter->second;
601 auto const& item = iter->
second;
607 JLOG(j.
warn()) <<
"Trying to thread to deleted node";
623 JLOG(j.
warn()) <<
"ApplyStateTable::getForMod: key not found";
626 auto sle = std::make_shared<SLE>(*c);
645 JLOG(j.
warn()) <<
"Threading to non-existent account: " <<
toBase58(to);
650 sle->isThreadedType(base.
rules()),
651 "ripple::ApplyStateTable::threadTx : SLE is threaded");
666 case ltACCOUNT_ROOT: {
670 case ltRIPPLE_STATE: {
671 threadTx(base, meta, (*sle)[sfLowLimit].getIssuer(), mods, j);
672 threadTx(base, meta, (*sle)[sfHighLimit].getIssuer(), mods, j);
677 if (
auto const optSleAcct{(*sle)[~sfAccount]})
678 threadTx(base, meta, *optSleAcct, mods, j);
682 if (ledgerType == ltCHECK &&
687 if (
auto const optSleDest{(*sle)[~sfDestination]})
688 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.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
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.
static 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.