Files
rippled/src/libxrpl/protocol/STLedgerEntry.cpp
Bart 1d42c4f6de refactor: Remove unnecessary copyright notices already covered by LICENSE.md (#5929)
Per XLS-0095, we are taking steps to rename ripple(d) to xrpl(d).

This change specifically removes all copyright notices referencing Ripple, XRPLF, and certain affiliated contributors upon mutual agreement, so the notice in the LICENSE.md file applies throughout. Copyright notices referencing external contributions remain as-is. Duplicate verbiage is also removed.
2025-11-04 08:33:42 +00:00

172 lines
4.4 KiB
C++

#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/to_string.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/jss.h>
#include <boost/format/free_funcs.hpp>
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <string>
#include <utility>
namespace ripple {
STLedgerEntry::STLedgerEntry(Keylet const& k)
: STObject(sfLedgerEntry), key_(k.key), type_(k.type)
{
auto const format = LedgerFormats::getInstance().findByType(type_);
if (format == nullptr)
Throw<std::runtime_error>(
"Attempt to create a SLE of unknown type " +
std::to_string(safe_cast<std::uint16_t>(k.type)));
set(format->getSOTemplate());
setFieldU16(sfLedgerEntryType, static_cast<std::uint16_t>(type_));
}
STLedgerEntry::STLedgerEntry(SerialIter& sit, uint256 const& index)
: STObject(sfLedgerEntry), key_(index)
{
set(sit);
setSLEType();
}
STLedgerEntry::STLedgerEntry(STObject const& object, uint256 const& index)
: STObject(object), key_(index)
{
setSLEType();
}
void
STLedgerEntry::setSLEType()
{
auto format = LedgerFormats::getInstance().findByType(
safe_cast<LedgerEntryType>(getFieldU16(sfLedgerEntryType)));
if (format == nullptr)
Throw<std::runtime_error>("invalid ledger entry type");
type_ = format->getType();
applyTemplate(format->getSOTemplate()); // May throw
}
std::string
STLedgerEntry::getFullText() const
{
auto const format = LedgerFormats::getInstance().findByType(type_);
if (format == nullptr)
Throw<std::runtime_error>("invalid ledger entry type");
std::string ret = "\"";
ret += to_string(key_);
ret += "\" = { ";
ret += format->getName();
ret += ", ";
ret += STObject::getFullText();
ret += "}";
return ret;
}
STBase*
STLedgerEntry::copy(std::size_t n, void* buf) const
{
return emplace(n, buf, *this);
}
STBase*
STLedgerEntry::move(std::size_t n, void* buf)
{
return emplace(n, buf, std::move(*this));
}
SerializedTypeID
STLedgerEntry::getSType() const
{
return STI_LEDGERENTRY;
}
std::string
STLedgerEntry::getText() const
{
return str(
boost::format("{ %s, %s }") % to_string(key_) % STObject::getText());
}
Json::Value
STLedgerEntry::getJson(JsonOptions options) const
{
Json::Value ret(STObject::getJson(options));
ret[jss::index] = to_string(key_);
if (getType() == ltMPTOKEN_ISSUANCE)
ret[jss::mpt_issuance_id] = to_string(
makeMptID(getFieldU32(sfSequence), getAccountID(sfIssuer)));
return ret;
}
bool
STLedgerEntry::isThreadedType(Rules const& rules) const
{
static constexpr std::array<LedgerEntryType, 5> newPreviousTxnIDTypes = {
ltDIR_NODE, ltAMENDMENTS, ltFEE_SETTINGS, ltNEGATIVE_UNL, ltAMM};
// Exclude PrevTxnID/PrevTxnLgrSeq if the fixPreviousTxnID amendment is not
// enabled and the ledger object type is in the above set
bool const excludePrevTxnID = !rules.enabled(fixPreviousTxnID) &&
std::count(
newPreviousTxnIDTypes.cbegin(),
newPreviousTxnIDTypes.cend(),
type_);
return !excludePrevTxnID && getFieldIndex(sfPreviousTxnID) != -1;
}
bool
STLedgerEntry::thread(
uint256 const& txID,
std::uint32_t ledgerSeq,
uint256& prevTxID,
std::uint32_t& prevLedgerID)
{
uint256 oldPrevTxID = getFieldH256(sfPreviousTxnID);
JLOG(debugLog().info()) << "Thread Tx:" << txID << " prev:" << oldPrevTxID;
if (oldPrevTxID == txID)
{
// this transaction is already threaded
XRPL_ASSERT(
getFieldU32(sfPreviousTxnLgrSeq) == ledgerSeq,
"ripple::STLedgerEntry::thread : ledger sequence match");
return false;
}
prevTxID = oldPrevTxID;
prevLedgerID = getFieldU32(sfPreviousTxnLgrSeq);
setFieldH256(sfPreviousTxnID, txID);
setFieldU32(sfPreviousTxnLgrSeq, ledgerSeq);
return true;
}
} // namespace ripple