Merge develop into confidential MPT

This commit is contained in:
Peter Chen
2026-06-02 13:01:46 -04:00
parent dacd108657
commit 7471bfb182
1051 changed files with 27649 additions and 16775 deletions

View File

@@ -148,17 +148,23 @@ public:
}
[[nodiscard]] constexpr E const&
error() const
error() const&
{
return Base::error();
}
constexpr E&
error()
[[nodiscard]] constexpr E&
error() &
{
return Base::error();
}
[[nodiscard]] constexpr E&&
error() &&
{
return std::move(Base::error());
}
constexpr explicit
operator bool() const
{
@@ -215,17 +221,23 @@ public:
}
[[nodiscard]] constexpr E const&
error() const
error() const&
{
return Base::error();
}
constexpr E&
error()
[[nodiscard]] constexpr E&
error() &
{
return Base::error();
}
[[nodiscard]] constexpr E&&
error() &&
{
return std::move(Base::error());
}
constexpr explicit
operator bool() const
{

View File

@@ -406,8 +406,8 @@ private:
// pointer. The low bit must be masked to zero when converting back to a
// pointer. If the low bit is '1', this is a weak pointer.
std::uintptr_t tp_{0};
static constexpr std::uintptr_t kTAG_MASK = 1;
static constexpr std::uintptr_t kPTR_MASK = ~kTAG_MASK;
static constexpr std::uintptr_t kTagMask = 1;
static constexpr std::uintptr_t kPtrMask = ~kTagMask;
private:
/** Return the raw pointer held by this object.

View File

@@ -567,14 +567,14 @@ template <class T>
bool
SharedWeakUnion<T>::isStrong() const
{
return (tp_ & kTAG_MASK) == 0u;
return (tp_ & kTagMask) == 0u;
}
template <class T>
bool
SharedWeakUnion<T>::isWeak() const
{
return (tp_ & kTAG_MASK) != 0u;
return (tp_ & kTagMask) != 0u;
}
template <class T>
@@ -641,7 +641,7 @@ template <class T>
T*
SharedWeakUnion<T>::unsafeGetRawPtr() const
{
return reinterpret_cast<T*>(tp_ & kPTR_MASK);
return reinterpret_cast<T*>(tp_ & kPtrMask);
}
template <class T>
@@ -650,7 +650,7 @@ SharedWeakUnion<T>::unsafeSetRawPtr(T* p, RefStrength rs)
{
tp_ = reinterpret_cast<std::uintptr_t>(p);
if (tp_ && rs == RefStrength::Weak)
tp_ |= kTAG_MASK;
tp_ |= kTagMask;
}
template <class T>

View File

@@ -98,11 +98,11 @@ private:
// enough for strong pointers and 14 bit counts are enough for weak
// pointers. Use type aliases to make it easy to switch types.
using CountType = std::uint16_t;
static constexpr size_t kSTRONG_COUNT_NUM_BITS = sizeof(CountType) * 8;
static constexpr size_t kWEAK_COUNT_NUM_BITS = kSTRONG_COUNT_NUM_BITS - 2;
static constexpr size_t kStrongCountNumBits = sizeof(CountType) * 8;
static constexpr size_t kWeakCountNumBits = kStrongCountNumBits - 2;
using FieldType = std::uint32_t;
static constexpr size_t kFIELD_TYPE_BITS = sizeof(FieldType) * 8;
static constexpr FieldType kONE = 1;
static constexpr size_t kFieldTypeBits = sizeof(FieldType) * 8;
static constexpr FieldType kOne = 1;
/** `refCounts` consists of four fields that are treated atomically:
@@ -137,21 +137,21 @@ private:
*/
mutable std::atomic<FieldType> refCounts_{kSTRONG_DELTA};
mutable std::atomic<FieldType> refCounts_{kStrongDelta};
/** Amount to change the strong count when adding or releasing a reference
Note: The strong count is stored in the low `StrongCountNumBits` bits
of refCounts
*/
static constexpr FieldType kSTRONG_DELTA = 1;
static constexpr FieldType kStrongDelta = 1;
/** Amount to change the weak count when adding or releasing a reference
Note: The weak count is stored in the high `WeakCountNumBits` bits of
refCounts
*/
static constexpr FieldType kWEAK_DELTA = (kONE << kSTRONG_COUNT_NUM_BITS);
static constexpr FieldType kWeakDelta = (kOne << kStrongCountNumBits);
/** Flag that is set when the partialDestroy function has started running
(or is about to start running).
@@ -159,34 +159,33 @@ private:
See description of the `refCounts` field for a fuller description of
this field.
*/
static constexpr FieldType kPARTIAL_DESTROY_STARTED_MASK = (kONE << (kFIELD_TYPE_BITS - 1));
static constexpr FieldType kPartialDestroyStartedMask = (kOne << (kFieldTypeBits - 1));
/** Flag that is set when the partialDestroy function has finished running
See description of the `refCounts` field for a fuller description of
this field.
*/
static constexpr FieldType kPARTIAL_DESTROY_FINISHED_MASK = (kONE << (kFIELD_TYPE_BITS - 2));
static constexpr FieldType kPartialDestroyFinishedMask = (kOne << (kFieldTypeBits - 2));
/** Mask that will zero out all the `count` bits and leave the tag bits
unchanged.
*/
static constexpr FieldType kTAG_MASK =
kPARTIAL_DESTROY_STARTED_MASK | kPARTIAL_DESTROY_FINISHED_MASK;
static constexpr FieldType kTagMask = kPartialDestroyStartedMask | kPartialDestroyFinishedMask;
/** Mask that will zero out the `tag` bits and leave the count bits
unchanged.
*/
static constexpr FieldType kVALUE_MASK = ~kTAG_MASK;
static constexpr FieldType kValueMask = ~kTagMask;
/** Mask that will zero out everything except the strong count.
*/
static constexpr FieldType kSTRONG_MASK = ((kONE << kSTRONG_COUNT_NUM_BITS) - 1) & kVALUE_MASK;
static constexpr FieldType kStrongMask = ((kOne << kStrongCountNumBits) - 1) & kValueMask;
/** Mask that will zero out everything except the weak count.
*/
static constexpr FieldType kWEAK_MASK =
(((kONE << kWEAK_COUNT_NUM_BITS) - 1) << kSTRONG_COUNT_NUM_BITS) & kVALUE_MASK;
static constexpr FieldType kWeakMask =
(((kOne << kWeakCountNumBits) - 1) << kStrongCountNumBits) & kValueMask;
/** Unpack the count and tag fields from the packed atomic integer form. */
struct RefCountPair
@@ -211,29 +210,29 @@ private:
[[nodiscard]] FieldType
combinedValue() const noexcept;
static constexpr CountType kMAX_STRONG_VALUE =
static_cast<CountType>((kONE << kSTRONG_COUNT_NUM_BITS) - 1);
static constexpr CountType kMAX_WEAK_VALUE =
static_cast<CountType>((kONE << kWEAK_COUNT_NUM_BITS) - 1);
static constexpr CountType kMaxStrongValue =
static_cast<CountType>((kOne << kStrongCountNumBits) - 1);
static constexpr CountType kMaxWeakValue =
static_cast<CountType>((kOne << kWeakCountNumBits) - 1);
/** Put an extra margin to detect when running up against limits.
This is only used in debug code, and is useful if we reduce the
number of bits in the strong and weak counts (to 16 and 14 bits).
*/
static constexpr CountType kCHECK_STRONG_MAX_VALUE = kMAX_STRONG_VALUE - 32;
static constexpr CountType kCHECK_WEAK_MAX_VALUE = kMAX_WEAK_VALUE - 32;
static constexpr CountType kCheckStrongMaxValue = kMaxStrongValue - 32;
static constexpr CountType kCheckWeakMaxValue = kMaxWeakValue - 32;
};
};
inline void
IntrusiveRefCounts::addStrongRef() const noexcept
{
refCounts_.fetch_add(kSTRONG_DELTA, std::memory_order_acq_rel);
refCounts_.fetch_add(kStrongDelta, std::memory_order_acq_rel);
}
inline void
IntrusiveRefCounts::addWeakRef() const noexcept
{
refCounts_.fetch_add(kWEAK_DELTA, std::memory_order_acq_rel);
refCounts_.fetch_add(kWeakDelta, std::memory_order_acq_rel);
}
inline ReleaseStrongRefAction
@@ -252,10 +251,10 @@ IntrusiveRefCounts::releaseStrongRef() const
{
RefCountPair const prevVal{prevIntVal};
XRPL_ASSERT(
(prevVal.strong >= kSTRONG_DELTA),
(prevVal.strong >= kStrongDelta),
"xrpl::IntrusiveRefCounts::releaseStrongRef : previous ref "
"higher than new");
auto nextIntVal = prevIntVal - kSTRONG_DELTA;
auto nextIntVal = prevIntVal - kStrongDelta;
ReleaseStrongRefAction action = NoOp;
if (prevVal.strong == 1)
{
@@ -265,7 +264,7 @@ IntrusiveRefCounts::releaseStrongRef() const
}
else
{
nextIntVal |= kPARTIAL_DESTROY_STARTED_MASK;
nextIntVal |= kPartialDestroyStartedMask;
action = PartialDestroy;
}
}
@@ -276,7 +275,7 @@ IntrusiveRefCounts::releaseStrongRef() const
// count to zero can start a partial destroy, and that can't happen
// twice.
XRPL_ASSERT(
(action == NoOp) || !(prevIntVal & kPARTIAL_DESTROY_STARTED_MASK),
(action == NoOp) || !(prevIntVal & kPartialDestroyStartedMask),
"xrpl::IntrusiveRefCounts::releaseStrongRef : not in partial "
"destroy");
return action;
@@ -289,8 +288,8 @@ IntrusiveRefCounts::addWeakReleaseStrongRef() const
{
using enum ReleaseStrongRefAction;
static_assert(kWEAK_DELTA > kSTRONG_DELTA);
auto constexpr kDELTA = kWEAK_DELTA - kSTRONG_DELTA;
static_assert(kWeakDelta > kStrongDelta);
static constexpr auto kDelta = kWeakDelta - kStrongDelta;
auto prevIntVal = refCounts_.load(std::memory_order_acquire);
// This loop will almost always run once. The loop is needed to atomically
// change the counts and flags (the count could be atomically changed, but
@@ -312,7 +311,7 @@ IntrusiveRefCounts::addWeakReleaseStrongRef() const
"xrpl::IntrusiveRefCounts::addWeakReleaseStrongRef : not in "
"partial destroy");
auto nextIntVal = prevIntVal + kDELTA;
auto nextIntVal = prevIntVal + kDelta;
ReleaseStrongRefAction action = NoOp;
if (prevVal.strong == 1)
{
@@ -322,14 +321,14 @@ IntrusiveRefCounts::addWeakReleaseStrongRef() const
}
else
{
nextIntVal |= kPARTIAL_DESTROY_STARTED_MASK;
nextIntVal |= kPartialDestroyStartedMask;
action = PartialDestroy;
}
}
if (refCounts_.compare_exchange_weak(prevIntVal, nextIntVal, std::memory_order_acq_rel))
{
XRPL_ASSERT(
(!(prevIntVal & kPARTIAL_DESTROY_STARTED_MASK)),
(!(prevIntVal & kPartialDestroyStartedMask)),
"xrpl::IntrusiveRefCounts::addWeakReleaseStrongRef : not "
"started partial destroy");
return action;
@@ -340,7 +339,7 @@ IntrusiveRefCounts::addWeakReleaseStrongRef() const
inline ReleaseWeakRefAction
IntrusiveRefCounts::releaseWeakRef() const
{
auto prevIntVal = refCounts_.fetch_sub(kWEAK_DELTA, std::memory_order_acq_rel);
auto prevIntVal = refCounts_.fetch_sub(kWeakDelta, std::memory_order_acq_rel);
RefCountPair prev = prevIntVal;
if (prev.weak == 1 && prev.strong == 0)
{
@@ -357,7 +356,7 @@ IntrusiveRefCounts::releaseWeakRef() const
{
// partial destroy MUST finish before running a full destroy (when
// using weak pointers)
refCounts_.wait(prevIntVal - kWEAK_DELTA, std::memory_order_acquire);
refCounts_.wait(prevIntVal - kWeakDelta, std::memory_order_acquire);
}
return ReleaseWeakRefAction::Destroy;
}
@@ -376,7 +375,7 @@ IntrusiveRefCounts::checkoutStrongRefFromWeak() const noexcept
if (prev.strong == 0u)
return false;
desiredValue = curValue + kSTRONG_DELTA;
desiredValue = curValue + kStrongDelta;
}
return true;
}
@@ -400,23 +399,22 @@ inline IntrusiveRefCounts::~IntrusiveRefCounts() noexcept
#ifndef NDEBUG
auto v = refCounts_.load(std::memory_order_acquire);
XRPL_ASSERT(
(!(v & kVALUE_MASK)), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero");
auto t = v & kTAG_MASK;
XRPL_ASSERT(
(!t || t == kTAG_MASK), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag");
(!(v & kValueMask)), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero");
auto t = v & kTagMask;
XRPL_ASSERT((!t || t == kTagMask), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag");
#endif
}
//------------------------------------------------------------------------------
inline IntrusiveRefCounts::RefCountPair::RefCountPair(IntrusiveRefCounts::FieldType v) noexcept
: strong{static_cast<CountType>(v & kSTRONG_MASK)}
, weak{static_cast<CountType>((v & kWEAK_MASK) >> kSTRONG_COUNT_NUM_BITS)}
, partialDestroyStartedBit{v & kPARTIAL_DESTROY_STARTED_MASK}
, partialDestroyFinishedBit{v & kPARTIAL_DESTROY_FINISHED_MASK}
: strong{static_cast<CountType>(v & kStrongMask)}
, weak{static_cast<CountType>((v & kWeakMask) >> kStrongCountNumBits)}
, partialDestroyStartedBit{v & kPartialDestroyStartedMask}
, partialDestroyFinishedBit{v & kPartialDestroyFinishedMask}
{
XRPL_ASSERT(
(strong < kCHECK_STRONG_MAX_VALUE && weak < kCHECK_WEAK_MAX_VALUE),
(strong < kCheckStrongMaxValue && weak < kCheckWeakMaxValue),
"xrpl::IntrusiveRefCounts::RefCountPair(FieldType) : inputs inside "
"range");
}
@@ -427,7 +425,7 @@ inline IntrusiveRefCounts::RefCountPair::RefCountPair(
: strong{s}, weak{w}
{
XRPL_ASSERT(
(strong < kCHECK_STRONG_MAX_VALUE && weak < kCHECK_WEAK_MAX_VALUE),
(strong < kCheckStrongMaxValue && weak < kCheckWeakMaxValue),
"xrpl::IntrusiveRefCounts::RefCountPair(CountType, CountType) : "
"inputs inside range");
}
@@ -436,11 +434,11 @@ inline IntrusiveRefCounts::FieldType
IntrusiveRefCounts::RefCountPair::combinedValue() const noexcept
{
XRPL_ASSERT(
(strong < kCHECK_STRONG_MAX_VALUE && weak < kCHECK_WEAK_MAX_VALUE),
(strong < kCheckStrongMaxValue && weak < kCheckWeakMaxValue),
"xrpl::IntrusiveRefCounts::RefCountPair::combinedValue : inputs "
"inside range");
return (static_cast<IntrusiveRefCounts::FieldType>(weak)
<< IntrusiveRefCounts::kSTRONG_COUNT_NUM_BITS) |
<< IntrusiveRefCounts::kStrongCountNumBits) |
static_cast<IntrusiveRefCounts::FieldType>(strong) | partialDestroyStartedBit |
partialDestroyFinishedBit;
}
@@ -451,7 +449,7 @@ partialDestructorFinished(T** o)
{
T& self = **o;
IntrusiveRefCounts::RefCountPair const p =
self.refCounts_.fetch_or(IntrusiveRefCounts::kPARTIAL_DESTROY_FINISHED_MASK);
self.refCounts_.fetch_or(IntrusiveRefCounts::kPartialDestroyFinishedMask);
XRPL_ASSERT(
(!p.partialDestroyFinishedBit && p.partialDestroyStartedBit && !p.strong),
"xrpl::partialDestructorFinished : not a weak ref");

View File

@@ -55,8 +55,8 @@ template <class = void>
boost::thread_specific_ptr<detail::LocalValues>&
getLocalValues()
{
static boost::thread_specific_ptr<detail::LocalValues> kTSP(&detail::LocalValues::cleanup);
return kTSP;
static boost::thread_specific_ptr<detail::LocalValues> kTsp(&detail::LocalValues::cleanup);
return kTsp;
}
} // namespace detail

View File

@@ -10,24 +10,11 @@
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <utility>
namespace xrpl {
// DEPRECATED use beast::severities::Severity instead
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum LogSeverity {
LSInvalid = -1, // used to indicate an invalid severity
LSTrace = 0, // Very low-level progress information, details inside
// an operation
LSDebug = 1, // Function-level progress information, operations
LSInfo = 2, // Server-level progress information, major operations
LSWarning = 3, // Conditions that warrant human attention, may indicate
// a problem
LSError = 4, // A condition that indicates a problem
LSFatal = 5 // A severe condition that indicates a server problem
};
/** Manages partitions for logging. */
class Logs
{
@@ -39,17 +26,17 @@ private:
std::string partition_;
public:
Sink(std::string partition, beast::severities::Severity thresh, Logs& logs);
Sink(std::string partition, beast::Severity thresh, Logs& logs);
Sink(Sink const&) = delete;
Sink&
operator=(Sink const&) = delete;
void
write(beast::severities::Severity level, std::string const& text) override;
write(beast::Severity level, std::string const& text) override;
void
writeAlways(beast::severities::Severity level, std::string const& text) override;
writeAlways(beast::Severity level, std::string const& text) override;
};
/** Manages a system file containing logged output.
@@ -136,12 +123,12 @@ private:
std::mutex mutable mutex_;
std::map<std::string, std::unique_ptr<beast::Journal::Sink>, boost::beast::iless> sinks_;
beast::severities::Severity thresh_;
beast::Severity thresh_;
File file_;
bool silent_ = false;
public:
Logs(beast::severities::Severity level);
Logs(beast::Severity level);
Logs(Logs const&) = delete;
Logs&
@@ -161,18 +148,18 @@ public:
beast::Journal
journal(std::string const& name);
beast::severities::Severity
beast::Severity
threshold() const;
void
threshold(beast::severities::Severity thresh);
threshold(beast::Severity thresh);
std::vector<std::pair<std::string, std::string>>
partitionSeverities() const;
void
write(
beast::severities::Severity level,
beast::Severity level,
std::string const& partition,
std::string const& text,
bool console);
@@ -192,36 +179,25 @@ public:
}
virtual std::unique_ptr<beast::Journal::Sink>
makeSink(std::string const& partition, beast::severities::Severity startingLevel);
makeSink(std::string const& partition, beast::Severity startingLevel);
public:
static LogSeverity
fromSeverity(beast::severities::Severity level);
static beast::severities::Severity
toSeverity(LogSeverity level);
static std::string
toString(LogSeverity s);
toString(beast::Severity s);
static LogSeverity
static std::optional<beast::Severity>
fromString(std::string const& s);
private:
// Need to be named before converting
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum {
// Maximum line length for log messages.
// If the message exceeds this length it will be truncated with
// ellipses.
MaximumMessageCharacters = 12 * 1024
};
// Maximum line length for log messages.
// If the message exceeds this length it will be truncated with ellipses.
static constexpr auto kMaximumMessageCharacters = 12 * 1024;
static void
format(
std::string& output,
std::string const& message,
beast::severities::Severity severity,
beast::Severity severity,
std::string const& partition);
};

View File

@@ -2,12 +2,16 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <array>
#include <cstdint>
#include <functional>
#include <limits>
#include <optional>
#include <ostream>
#include <set>
#include <stdexcept>
#include <string>
#include <unordered_map>
namespace xrpl {
@@ -38,17 +42,58 @@ isPowerOfTen(T value)
return logTen(value).has_value();
}
namespace detail {
/** Builds a table of the powers of 10
*
* This function is marked consteval, so it can only be run in
* a constexpr context. This assures that it is and can only be run at
* compile time. Doing it at runtime would be pretty wasteful and
* inefficient.
*/
constexpr std::size_t kInt64Digits = 20;
consteval std::array<std::uint64_t, kInt64Digits>
buildPowersOfTen()
{
std::array<std::uint64_t, kInt64Digits> result{};
std::uint64_t power = 1;
std::size_t exponent = 0;
// end the loop early so it doesn't overflow;
for (; exponent < result.size() - 1; ++exponent, power *= 10)
{
result[exponent] = power;
if (power > std::numeric_limits<std::uint64_t>::max() / 10)
throw std::logic_error("Power of 10 table is too big");
}
result[exponent] = power;
if (power < std::numeric_limits<std::uint64_t>::max() / 10)
throw std::logic_error("Power of 10 table is not big enough for the uint64_t type");
return result;
}
} // namespace detail
constexpr std::array<std::uint64_t, detail::kInt64Digits> kPowerOfTen = detail::buildPowersOfTen();
static_assert(kPowerOfTen[0] == 1);
static_assert(kPowerOfTen[1] == 10);
static_assert(kPowerOfTen[10] == 10'000'000'000);
static_assert(
isPowerOfTen(kPowerOfTen.back()) && *logTen(kPowerOfTen.back()) == detail::kInt64Digits - 1);
/** MantissaRange defines a range for the mantissa of a normalized Number.
*
* The mantissa is in the range [min, max], where
* * min is a power of 10, and
* * max = min * 10 - 1.
*
* The mantissa_scale enum indicates whether the range is "small" or "large".
* This intentionally restricts the number of MantissaRanges that can be
* instantiated to two: one for each scale.
* The MantissaScale enum indicates properties of the range: size, and some behavioral
* options. This intentionally restricts the number of unique MantissaRanges that can
* be instantiated: one for each scale.
*
* The "small" scale is based on the behavior of STAmount for IOUs. It has a min
* The "Small" scale is based on the behavior of STAmount for IOUs. It has a min
* value of 10^15, and a max value of 10^16-1. This was sufficient for
* uses before Lending Protocol was implemented, mostly related to AMM.
*
@@ -59,46 +104,100 @@ isPowerOfTen(T value)
* STNumber field type, and for internal calculations. That necessitated the
* "large" scale.
*
* The "large" scale is intended to represent all values that can be represented
* The "Large" scales are intended to represent all values that can be represented
* by an STAmount - IOUs, XRP, and MPTs. It has a min value of 10^18, and a max
* value of 10^19-1.
* value of 10^19-1. "LargeLegacy" is like "Large", but preserves
* a rounding error when a computation results in a mantissa of
* Number::kMaxRep that needs to be rounded up, but rounds down
* instead. It will maintain consistent behavior until the fixCleanup3_2_0
* amendment is enabled.
*
* Note that if the mentioned amendments are eventually retired, this class
* should be left in place, but the "small" scale option should be removed. This
* should be left in place, but the "Small" scale option should be removed. This
* will allow for future expansion beyond 64-bits if it is ever needed.
*/
struct MantissaRange
struct MantissaRange final
{
using rep = std::uint64_t;
enum class MantissaScale { Small, Large };
explicit constexpr MantissaRange(MantissaScale scale)
: min(getMin(scale)), log(logTen(min).value_or(-1)), scale(scale)
enum class MantissaScale {
Small,
// LargeLegacy can be removed when fixCleanup3_2_0 is retired
LargeLegacy,
Large,
};
// This entire enum can be removed when fixCleanup3_2_0 is retired
enum class CuspRoundingFix : bool {
Disabled = false,
Enabled = true,
};
explicit constexpr MantissaRange(MantissaScale sc) : scale(sc)
{
}
rep min;
rep max{(min * 10) - 1};
int log;
MantissaScale scale;
MantissaScale const scale;
int const log{getExponent(scale)};
rep const min{getMin(scale, log)};
rep const max{(min * 10) - 1};
CuspRoundingFix const cuspRoundingFixEnabled{isCuspFixEnabled(scale)};
static MantissaRange const&
getMantissaRange(MantissaScale scale);
static std::set<MantissaScale> const&
getAllScales();
private:
static constexpr rep
getMin(MantissaScale scale)
static constexpr int
getExponent(MantissaScale scale)
{
switch (scale)
{
case MantissaScale::Small:
return 1'000'000'000'000'000ULL;
return 15;
case MantissaScale::LargeLegacy:
case MantissaScale::Large:
return 1'000'000'000'000'000'000ULL;
return 18;
// LCOV_EXCL_START
default:
// Since this can never be called outside a non-constexpr
// context, this throw assures that the build fails if an
// If called in a constexpr context, this throw assures that the build fails if an
// invalid scale is used.
throw std::runtime_error("Unknown mantissa scale");
// LCOV_EXCL_STOP
}
}
// Keep this function for future use with different ways to compute
// the ranges.
static constexpr rep
getMin(MantissaScale scale, int exponent)
{
if (exponent < 0 || exponent >= kPowerOfTen.size())
throw std::runtime_error("Invalid exponent"); // LCOV_EXCL_LINE
return kPowerOfTen[exponent];
}
static constexpr CuspRoundingFix
isCuspFixEnabled(MantissaScale scale)
{
switch (scale)
{
case MantissaScale::Small:
case MantissaScale::LargeLegacy:
return CuspRoundingFix::Disabled;
case MantissaScale::Large:
return CuspRoundingFix::Enabled;
default:
// If called in a constexpr context, this throw assures that the build fails if an
// invalid scale is used.
throw std::runtime_error("Unknown mantissa scale"); // LCOV_EXCL_LINE
}
}
static std::unordered_map<MantissaScale, MantissaRange> const&
getRanges();
};
// Like std::integral, but only 64-bit integral types.
@@ -203,7 +302,7 @@ concept Integral64 = std::is_same_v<T, std::int64_t> || std::is_same_v<T, std::u
* amendments are enabled to determine which result to expect.
*
*/
class Number
class Number final
{
using rep = std::int64_t;
using internalrep = MantissaRange::rep;
@@ -214,12 +313,12 @@ class Number
public:
// The range for the exponent when normalized
constexpr static int kMIN_EXPONENT = -32768;
constexpr static int kMAX_EXPONENT = 32768;
static constexpr int kMinExponent = -32768;
static constexpr int kMaxExponent = 32768;
constexpr static internalrep kMAX_REP = std::numeric_limits<rep>::max();
static_assert(kMAX_REP == 9'223'372'036'854'775'807);
static_assert(-kMAX_REP == std::numeric_limits<rep>::min() + 1);
static constexpr internalrep kMaxRep = std::numeric_limits<rep>::max();
static_assert(kMaxRep == 9'223'372'036'854'775'807);
static_assert(-kMaxRep == std::numeric_limits<rep>::min() + 1);
// May need to make unchecked private
struct Unchecked
@@ -409,69 +508,48 @@ public:
static internalrep
minMantissa()
{
return kRANGE.get().min;
return kRange.get().min;
}
static internalrep
maxMantissa()
{
return kRANGE.get().max;
return kRange.get().max;
}
static int
mantissaLog()
{
return kRANGE.get().log;
return kRange.get().log;
}
/// oneSmall is needed because the ranges are private
constexpr static Number
oneSmall();
/// oneLarge is needed because the ranges are private
constexpr static Number
oneLarge();
// And one is needed because it needs to choose between oneSmall and
// oneLarge based on the current range
static Number
one();
template <Integral64 T>
template <
auto MinMantissa,
auto MaxMantissa,
Integral64 T = std::decay_t<decltype(MinMantissa)>>
[[nodiscard]]
std::pair<T, int>
normalizeToRange(T minMantissa, T maxMantissa) const;
normalizeToRange() const;
private:
static thread_local RoundingMode mode;
// The available ranges for mantissa
constexpr static MantissaRange kSMALL_RANGE{MantissaRange::MantissaScale::Small};
static_assert(isPowerOfTen(kSMALL_RANGE.min));
static_assert(kSMALL_RANGE.min == 1'000'000'000'000'000LL);
static_assert(kSMALL_RANGE.max == 9'999'999'999'999'999LL);
static_assert(kSMALL_RANGE.log == 15);
static_assert(kSMALL_RANGE.min < kMAX_REP);
static_assert(kSMALL_RANGE.max < kMAX_REP);
constexpr static MantissaRange kLARGE_RANGE{MantissaRange::MantissaScale::Large};
static_assert(isPowerOfTen(kLARGE_RANGE.min));
static_assert(kLARGE_RANGE.min == 1'000'000'000'000'000'000ULL);
static_assert(kLARGE_RANGE.max == internalrep(9'999'999'999'999'999'999ULL));
static_assert(kLARGE_RANGE.log == 18);
static_assert(kLARGE_RANGE.min < kMAX_REP);
static_assert(kLARGE_RANGE.max > kMAX_REP);
// The range for the mantissa when normalized.
// Use reference_wrapper to avoid making copies, and prevent accidentally
// changing the values inside the range.
static thread_local std::reference_wrapper<MantissaRange const> kRANGE;
static thread_local std::reference_wrapper<MantissaRange const> kRange;
void
normalize();
normalize(MantissaRange const& range);
/** Normalize Number components to an arbitrary range.
*
* min/maxMantissa are parameters because this function is used by both
* normalize(), which reads from kRANGE, and by normalizeToRange,
* normalize(), which reads from kRange, and by normalizeToRange,
* which is public and can accept an arbitrary range from the caller.
*/
template <class T>
@@ -481,7 +559,8 @@ private:
T& mantissa,
int& exponent,
internalrep const& minMantissa,
internalrep const& maxMantissa);
internalrep const& maxMantissa,
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled);
template <class T>
friend void
@@ -490,7 +569,9 @@ private:
T& mantissa,
int& exponent,
MantissaRange::rep const& minMantissa,
MantissaRange::rep const& maxMantissa);
MantissaRange::rep const& maxMantissa,
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled,
bool dropped);
[[nodiscard]] bool
isnormal() const noexcept;
@@ -521,12 +602,12 @@ constexpr Number::Number(internalrep mantissa, int exponent, Unchecked) noexcept
{
}
constexpr static Number kNUM_ZERO{};
static constexpr Number kNumZero{};
inline Number::Number(bool negative, internalrep mantissa, int exponent, Normalized)
: Number(negative, mantissa, exponent, Unchecked{})
{
normalize();
normalize(kRange);
}
inline Number::Number(internalrep mantissa, int exponent, Normalized)
@@ -552,10 +633,10 @@ constexpr Number::rep
Number::mantissa() const noexcept
{
auto m = mantissa_;
if (m > kMAX_REP)
if (m > kMaxRep)
{
XRPL_ASSERT_PARTS(
!isnormal() || (m % 10 == 0 && m / 10 <= kMAX_REP),
!isnormal() || (m % 10 == 0 && m / 10 <= kMaxRep),
"xrpl::Number::mantissa",
"large normalized mantissa has no remainder");
m /= 10;
@@ -573,10 +654,10 @@ constexpr int
Number::exponent() const noexcept
{
auto e = exponent_;
if (mantissa_ > kMAX_REP)
if (mantissa_ > kMaxRep)
{
XRPL_ASSERT_PARTS(
!isnormal() || (mantissa_ % 10 == 0 && mantissa_ / 10 <= kMAX_REP),
!isnormal() || (mantissa_ % 10 == 0 && mantissa_ / 10 <= kMaxRep),
"xrpl::Number::exponent",
"large normalized mantissa has no remainder");
++e;
@@ -671,35 +752,46 @@ operator/(Number const& x, Number const& y)
inline Number
Number::min() noexcept
{
return Number{false, kRANGE.get().min, kMIN_EXPONENT, Unchecked{}};
return Number{false, kRange.get().min, kMinExponent, Unchecked{}};
}
inline Number
Number::max() noexcept
{
return Number{false, std::min(kRANGE.get().max, kMAX_REP), kMAX_EXPONENT, Unchecked{}};
return Number{false, std::min(kRange.get().max, kMaxRep), kMaxExponent, Unchecked{}};
}
inline Number
Number::lowest() noexcept
{
return Number{true, std::min(kRANGE.get().max, kMAX_REP), kMAX_EXPONENT, Unchecked{}};
return Number{true, std::min(kRange.get().max, kMaxRep), kMaxExponent, Unchecked{}};
}
inline bool
Number::isnormal() const noexcept
{
MantissaRange const& range = kRANGE;
MantissaRange const& range = kRange;
auto const absM = mantissa_;
return *this == Number{} ||
(range.min <= absM && absM <= range.max && (absM <= kMAX_REP || absM % 10 == 0) &&
kMIN_EXPONENT <= exponent_ && exponent_ <= kMAX_EXPONENT);
(range.min <= absM && absM <= range.max && (absM <= kMaxRep || absM % 10 == 0) &&
kMinExponent <= exponent_ && exponent_ <= kMaxExponent);
}
template <Integral64 T>
template <auto MinMantissa, auto MaxMantissa, Integral64 T>
std::pair<T, int>
Number::normalizeToRange(T minMantissa, T maxMantissa) const
Number::normalizeToRange() const
{
static_assert(std::is_same_v<T, std::uint64_t> || std::is_same_v<T, std::int64_t>);
static_assert(std::is_same_v<T, std::decay_t<decltype(MinMantissa)>>);
static_assert(std::is_same_v<T, std::decay_t<decltype(MaxMantissa)>>);
auto constexpr kMIN = static_cast<T>(MinMantissa);
auto constexpr kMAX = static_cast<T>(MaxMantissa);
static_assert(kMIN > 0);
static_assert(kMIN % 10 == 0);
static_assert(isPowerOfTen(kMIN));
static_assert(kMAX % 10 == 9);
static_assert((kMAX + 1) / 10 == kMIN);
bool negative = negative_;
internalrep mantissa = mantissa_;
int exponent = exponent_;
@@ -711,7 +803,10 @@ Number::normalizeToRange(T minMantissa, T maxMantissa) const
"xrpl::Number::normalizeToRange",
"Number is non-negative for unsigned range.");
}
Number::normalize(negative, mantissa, exponent, minMantissa, maxMantissa);
// Don't need to worry about the cuspRounding fix because rounding up will never take the
// mantissa over maxMantissa with a ones digit value other than 0. 0 can safely be truncated.
Number::normalize(
negative, mantissa, exponent, kMIN, kMAX, MantissaRange::CuspRoundingFix::Disabled);
auto const sign = negative ? -1 : 1;
return std::make_pair(static_cast<T>(sign * mantissa), exponent);
@@ -763,6 +858,8 @@ to_string(MantissaRange::MantissaScale const& scale)
{
case MantissaRange::MantissaScale::Small:
return "small";
case MantissaRange::MantissaScale::LargeLegacy:
return "largeLegacy";
case MantissaRange::MantissaScale::Large:
return "large";
default:

View File

@@ -21,12 +21,12 @@ public:
}
[[nodiscard]] uint256 const&
asUint256() const
asUInt256() const
{
return hash_;
}
uint256&
asUint256()
asUInt256()
{
return hash_;
}
@@ -93,7 +93,7 @@ template <>
inline std::size_t
extract(SHAMapHash const& key)
{
return *reinterpret_cast<std::size_t const*>(key.asUint256().data());
return *reinterpret_cast<std::size_t const*>(key.asUInt256().data());
}
} // namespace xrpl

View File

@@ -57,10 +57,10 @@ template <class T>
std::shared_ptr<T> const&
SharedWeakCachePointer<T>::getStrong() const
{
static std::shared_ptr<T> const kEMPTY;
static std::shared_ptr<T> const kEmpty;
if (auto p = std::get_if<std::shared_ptr<T>>(&combo_))
return *p;
return kEMPTY;
return kEmpty;
}
template <class T>

View File

@@ -7,9 +7,11 @@
#include <boost/utility/string_view.hpp>
#include <array>
#include <concepts>
#include <cstdint>
#include <optional>
#include <string>
#include <type_traits>
namespace xrpl {
@@ -26,28 +28,39 @@ namespace xrpl {
std::string
sqlBlobLiteral(Blob const& blob);
namespace detail {
template <typename T>
concept SomeChar = std::same_as<std::remove_cvref_t<T>, int8_t> ||
std::same_as<std::remove_cvref_t<T>, char> || std::same_as<std::remove_cvref_t<T>, uint8_t>;
inline constexpr std::array<std::optional<int>, 256> const kDigitLookupTable = []() {
std::array<std::optional<int>, 256> t{};
for (int i = 0; i < 10; ++i)
t['0' + i] = i;
for (int i = 0; i < 6; ++i)
{
t['A' + i] = 10 + i;
t['a' + i] = 10 + i;
}
return t;
}();
inline std::optional<int>
hexCharToInt(SomeChar auto hexChar)
{
return kDigitLookupTable[static_cast<uint8_t>(hexChar)];
}
} // namespace detail
template <class Iterator>
std::optional<Blob>
strUnHex(std::size_t strSize, Iterator begin, Iterator end)
{
static constexpr std::array<int, 256> const kDIGIT_LOOKUP_TABLE = []() {
std::array<int, 256> t{};
for (auto& x : t)
x = -1;
for (int i = 0; i < 10; ++i)
t['0' + i] = i;
for (int i = 0; i < 6; ++i)
{
t['A' + i] = 10 + i;
t['a' + i] = 10 + i;
}
return t;
}();
Blob out;
out.reserve((strSize + 1) / 2);
@@ -56,27 +69,26 @@ strUnHex(std::size_t strSize, Iterator begin, Iterator end)
if (strSize & 1)
{
int c = kDIGIT_LOOKUP_TABLE[*iter++];
if (c < 0)
auto const c = detail::hexCharToInt(*iter++);
if (!c.has_value())
return {};
out.push_back(c);
out.push_back(static_cast<unsigned char>(*c));
}
while (iter != end)
{
int const cHigh = kDIGIT_LOOKUP_TABLE[*iter++];
auto const cHigh = detail::hexCharToInt(*iter++);
if (cHigh < 0)
if (!cHigh.has_value())
return {};
int const cLow = kDIGIT_LOOKUP_TABLE[*iter++];
auto const cLow = detail::hexCharToInt(*iter++);
if (cLow < 0)
if (!cLow.has_value())
return {};
out.push_back(static_cast<unsigned char>((cHigh << 4) | cLow));
out.push_back(static_cast<unsigned char>((*cHigh << 4) | *cLow));
}
return {std::move(out)};
@@ -120,7 +132,7 @@ std::string
trimWhitespace(std::string str);
std::optional<std::uint64_t>
toUint64(std::string const& s);
toUInt64(std::string const& s);
/** Determines if the given string looks like a TOML-file hosting domain.

View File

@@ -157,7 +157,7 @@ public:
/** Fetch an item from the cache.
If the digest was not found, Handler
will be called with this signature:
std::shared_ptr<SLE const>(void)
SLE::const_pointer(void)
*/
template <class Handler>
SharedPointerType
@@ -181,14 +181,14 @@ private:
beast::insight::Collector::ptr const& collector)
: hook(collector->makeHook(handler))
, size(collector->makeGauge(prefix, "size"))
, hit_rate(collector->makeGauge(prefix, "hit_rate"))
, hitRate(collector->makeGauge(prefix, "hit_rate"))
{
}
beast::insight::Hook hook;
beast::insight::Gauge size;
beast::insight::Gauge hit_rate;
beast::insight::Gauge hitRate;
std::size_t hits{0};
std::size_t misses{0};
@@ -197,16 +197,16 @@ private:
class KeyOnlyEntry
{
public:
clock_type::time_point last_access;
clock_type::time_point lastAccess;
explicit KeyOnlyEntry(clock_type::time_point const& lastAccess) : last_access(lastAccess)
explicit KeyOnlyEntry(clock_type::time_point const& lastAccess) : lastAccess(lastAccess)
{
}
void
touch(clock_type::time_point const& now)
{
last_access = now;
lastAccess = now;
}
};
@@ -214,10 +214,10 @@ private:
{
public:
shared_weak_combo_pointer_type ptr;
clock_type::time_point last_access;
clock_type::time_point lastAccess;
ValueEntry(clock_type::time_point const& lastAccess, shared_pointer_type const& ptr)
: ptr(ptr), last_access(lastAccess)
: ptr(ptr), lastAccess(lastAccess)
{
}
@@ -246,7 +246,7 @@ private:
void
touch(clock_type::time_point const& now)
{
last_access = now;
lastAccess = now;
}
};
@@ -286,13 +286,13 @@ private:
std::string name_;
// Desired number of cache entries (0 = ignore)
int const target_size_;
int const targetSize_;
// Desired maximum cache age
clock_type::duration const target_age_;
clock_type::duration const targetAge_;
// Number of items cached
int cache_count_{0};
int cacheCount_{0};
cache_type cache_; // Hold strong reference to recent objects
std::uint64_t hits_{0};
std::uint64_t misses_{0};

View File

@@ -34,8 +34,8 @@ inline TaggedCache<
, clock_(clock)
, stats_(name, std::bind(&TaggedCache::collectMetrics, this), collector)
, name_(name)
, target_size_(size)
, target_age_(expiration)
, targetSize_(size)
, targetAge_(expiration)
{
}
@@ -86,7 +86,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
getCacheSize() const
{
std::scoped_lock const lock(mutex_);
return cache_count_;
return cacheCount_;
}
template <
@@ -139,7 +139,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
{
std::scoped_lock const lock(mutex_);
cache_.clear();
cache_count_ = 0;
cacheCount_ = 0;
}
template <
@@ -157,7 +157,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
{
std::scoped_lock const lock(mutex_);
cache_.clear();
cache_count_ = 0;
cacheCount_ = 0;
hits_ = 0;
misses_ = 0;
}
@@ -213,21 +213,21 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
{
std::scoped_lock const lock(mutex_);
if (target_size_ == 0 || (static_cast<int>(cache_.size()) <= target_size_))
if (targetSize_ == 0 || (static_cast<int>(cache_.size()) <= targetSize_))
{
whenExpire = now - target_age_;
whenExpire = now - targetAge_;
}
else
{
whenExpire = now - (target_age_ * target_size_ / cache_.size());
whenExpire = now - (targetAge_ * targetSize_ / cache_.size());
clock_type::duration const minimumAge(std::chrono::seconds(1));
if (whenExpire > (now - minimumAge))
whenExpire = now - minimumAge;
JLOG(journal_.trace())
<< name_ << " is growing fast " << cache_.size() << " of " << target_size_
<< " aging at " << (now - whenExpire).count() << " of " << target_age_.count();
<< name_ << " is growing fast " << cache_.size() << " of " << targetSize_
<< " aging at " << (now - whenExpire).count() << " of " << targetAge_.count();
}
std::vector<std::thread> workers;
@@ -242,7 +242,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
for (std::thread& worker : workers)
worker.join();
cache_count_ -= allRemovals;
cacheCount_ -= allRemovals;
}
// At this point allStuffToSweep will go out of scope outside the lock
// and decrement the reference count on each strong pointer.
@@ -280,7 +280,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
if (entry.isCached())
{
--cache_count_;
--cacheCount_;
entry.ptr.convertToWeak();
ret = true;
}
@@ -317,7 +317,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
std::piecewise_construct,
std::forward_as_tuple(key),
std::forward_as_tuple(clock_.now(), data));
++cache_count_;
++cacheCount_;
return false;
}
@@ -366,12 +366,12 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
data = cachedData;
}
++cache_count_;
++cacheCount_;
return true;
}
entry.ptr = data;
++cache_count_;
++cacheCount_;
return false;
}
@@ -477,7 +477,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
auto [it, inserted] = cache_.emplace(
std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(now));
if (!inserted)
it->second.last_access = now;
it->second.lastAccess = now;
return inserted;
}
@@ -626,7 +626,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
if (entry.isCached())
{
// independent of cache size, so not counted as a hit
++cache_count_;
++cacheCount_;
entry.touch(clock_.now());
return entry.ptr.getStrong();
}
@@ -658,7 +658,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
if (total != 0)
hitRate = (hits_ * 100) / total;
}
stats_.hit_rate.set(hitRate);
stats_.hitRate.set(hitRate);
}
}
@@ -706,7 +706,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
++cit;
}
}
else if (cit->second.last_access <= whenExpire)
else if (cit->second.lastAccess <= whenExpire)
{
// strong, expired
++cacheRemovals;
@@ -773,12 +773,12 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
auto cit = partition.begin();
while (cit != partition.end())
{
if (cit->second.last_access > now)
if (cit->second.lastAccess > now)
{
cit->second.last_access = now;
cit->second.lastAccess = now;
++cit;
}
else if (cit->second.last_access <= whenExpire)
else if (cit->second.lastAccess <= whenExpire)
{
cit = partition.erase(cit);
}

View File

@@ -30,8 +30,8 @@ public:
now(); // seconds since xrpld program start
private:
static std::atomic<rep> kNOW;
static std::atomic<bool> kSTOP;
static std::atomic<rep> kNow;
static std::atomic<bool> kStop;
struct UpdateThread : private std::thread
{

View File

@@ -46,6 +46,11 @@ struct IsContiguousContainer<Slice> : std::true_type
{
};
template <typename...>
struct AlwaysFalseT : std::bool_constant<false>
{
};
} // namespace detail
/** Integers of any length that is a multiple of 32-bits
@@ -62,18 +67,18 @@ struct IsContiguousContainer<Slice> : std::true_type
number of bits.
*/
template <std::size_t Bits, class Tag = void>
class BaseUint
class BaseUInt
{
static_assert((Bits % 32) == 0, "The length of a base_uint in bits must be a multiple of 32.");
static_assert(Bits >= 64, "The length of a base_uint in bits must be at least 64.");
static constexpr std::size_t kWIDTH = Bits / 32;
static constexpr std::size_t kWidth = Bits / 32;
// This is really big-endian in byte order.
// We sometimes use std::uint32_t for speed.
std::array<std::uint32_t, kWIDTH> data_;
std::array<std::uint32_t, kWidth> data_;
public:
//--------------------------------------------------------------------------
@@ -81,8 +86,8 @@ public:
// STL Container Interface
//
static std::size_t constexpr kBYTES = Bits / 8;
static_assert(sizeof(data_) == kBYTES, "");
static constexpr std::size_t kBytes = Bits / 8;
static_assert(sizeof(data_) == kBytes, "");
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
@@ -116,7 +121,7 @@ public:
iterator
end()
{
return data() + kBYTES;
return data() + kBytes;
}
[[nodiscard]] const_iterator
begin() const
@@ -126,7 +131,7 @@ public:
[[nodiscard]] const_iterator
end() const
{
return data() + kBYTES;
return data() + kBytes;
}
[[nodiscard]] const_iterator
cbegin() const
@@ -136,7 +141,7 @@ public:
[[nodiscard]] const_iterator
cend() const
{
return data() + kBYTES;
return data() + kBytes;
}
/** Value hashing function.
@@ -160,9 +165,9 @@ private:
explicit VoidHelper() = default;
};
explicit BaseUint(void const* data, VoidHelper)
explicit BaseUInt(void const* data, VoidHelper)
{
memcpy(data_.data(), data, kBYTES);
memcpy(data_.data(), data, kBytes);
}
// Helper function to initialize a base_uint from a std::string_view.
@@ -244,15 +249,15 @@ private:
}
public:
constexpr BaseUint() : data_{}
constexpr BaseUInt() : data_{}
{
}
constexpr BaseUint(beast::Zero) : data_{}
constexpr BaseUInt(beast::Zero) : data_{}
{
}
explicit BaseUint(std::uint64_t b)
explicit BaseUInt(std::uint64_t b)
{
*this = b;
}
@@ -260,7 +265,7 @@ public:
// This constructor is intended to be used at compile time since it might
// throw at runtime. Consider declaring this constructor consteval once
// we get to C++23.
explicit constexpr BaseUint(std::string_view sv) noexcept(false)
explicit constexpr BaseUInt(std::string_view sv) noexcept(false)
: data_(parseFromStringViewThrows(sv))
{
}
@@ -270,24 +275,42 @@ public:
class = std::enable_if_t<
detail::IsContiguousContainer<Container>::value &&
std::is_trivially_copyable_v<typename Container::value_type>>>
explicit BaseUint(Container const& c)
explicit BaseUInt(Container const& c)
{
// Use AlwaysFalseT so the static_assert condition is dependent
// and only triggers when this constructor template is instantiated.
static_assert(
detail::AlwaysFalseT<Container>::value,
"This constructor is not intended to be used and will be soon removed. "
"Use base_uint::fromRaw instead.");
}
template <
class Container,
class = std::enable_if_t<
detail::IsContiguousContainer<Container>::value &&
std::is_trivially_copyable_v<typename Container::value_type>>>
static BaseUInt
fromRaw(Container const& c)
{
BaseUInt result;
XRPL_ASSERT(
c.size() * sizeof(typename Container::value_type) == size(),
"xrpl::base_uint::base_uint(Container auto) : input size match");
std::memcpy(data_.data(), c.data(), size());
"xrpl::BaseUInt::fromRaw(Container auto) : input size match");
std::memcpy(result.data_.data(), c.data(), size());
return result;
}
template <class Container>
std::enable_if_t<
detail::IsContiguousContainer<Container>::value &&
std::is_trivially_copyable_v<typename Container::value_type>,
BaseUint&>
BaseUInt&>
operator=(Container const& c)
{
XRPL_ASSERT(
c.size() * sizeof(typename Container::value_type) == size(),
"xrpl::base_uint::operator=(Container auto) : input size match");
"xrpl::BaseUInt::operator=(Container auto) : input size match");
std::memcpy(data_.data(), c.data(), size());
return *this;
}
@@ -295,14 +318,14 @@ public:
/* Construct from a raw pointer.
The buffer pointed to by `data` must be at least Bits/8 bytes.
*/
static BaseUint
static BaseUInt
fromVoid(void const* data)
{
return BaseUint(data, VoidHelper());
return BaseUInt(data, VoidHelper());
}
template <class T>
static std::optional<BaseUint>
static std::optional<BaseUInt>
fromVoidChecked(T const& from)
{
if (from.size() != size())
@@ -313,7 +336,7 @@ public:
[[nodiscard]] constexpr int
signum() const
{
for (int i = 0; i < kWIDTH; i++)
for (int i = 0; i < kWidth; i++)
{
if (data_[i] != 0)
return 1;
@@ -325,24 +348,24 @@ public:
bool
operator!() const
{
return *this == beast::kZERO;
return *this == beast::kZero;
}
constexpr BaseUint
constexpr BaseUInt
operator~() const
{
BaseUint ret;
BaseUInt ret;
for (int i = 0; i < kWIDTH; i++)
for (int i = 0; i < kWidth; i++)
ret.data_[i] = ~data_[i];
return ret;
}
BaseUint&
BaseUInt&
operator=(std::uint64_t uHost)
{
*this = beast::kZERO;
*this = beast::kZero;
// NOLINTBEGIN(cppcoreguidelines-pro-type-member-init)
union
{
@@ -352,43 +375,43 @@ public:
// NOLINTEND(cppcoreguidelines-pro-type-member-init)
// Put in least significant bits.
ul = boost::endian::native_to_big(uHost);
data_[kWIDTH - 2] = u[0];
data_[kWIDTH - 1] = u[1];
data_[kWidth - 2] = u[0];
data_[kWidth - 1] = u[1];
return *this;
}
BaseUint&
operator^=(BaseUint const& b)
BaseUInt&
operator^=(BaseUInt const& b)
{
for (int i = 0; i < kWIDTH; i++)
for (int i = 0; i < kWidth; i++)
data_[i] ^= b.data_[i];
return *this;
}
BaseUint&
operator&=(BaseUint const& b)
BaseUInt&
operator&=(BaseUInt const& b)
{
for (int i = 0; i < kWIDTH; i++)
for (int i = 0; i < kWidth; i++)
data_[i] &= b.data_[i];
return *this;
}
BaseUint&
operator|=(BaseUint const& b)
BaseUInt&
operator|=(BaseUInt const& b)
{
for (int i = 0; i < kWIDTH; i++)
for (int i = 0; i < kWidth; i++)
data_[i] |= b.data_[i];
return *this;
}
BaseUint&
BaseUInt&
operator++()
{
// prefix operator
for (int i = kWIDTH - 1; i >= 0; --i)
for (int i = kWidth - 1; i >= 0; --i)
{
data_[i] = boost::endian::native_to_big(boost::endian::big_to_native(data_[i]) + 1);
if (data_[i] != 0)
@@ -398,20 +421,20 @@ public:
return *this;
}
BaseUint
BaseUInt
operator++(int)
{
// postfix operator
BaseUint const ret = *this;
BaseUInt const ret = *this;
++(*this);
return ret;
}
BaseUint&
BaseUInt&
operator--()
{
for (int i = kWIDTH - 1; i >= 0; --i)
for (int i = kWidth - 1; i >= 0; --i)
{
auto prev = data_[i];
data_[i] = boost::endian::native_to_big(boost::endian::big_to_native(data_[i]) - 1);
@@ -423,36 +446,36 @@ public:
return *this;
}
BaseUint
BaseUInt
operator--(int)
{
// postfix operator
BaseUint const ret = *this;
BaseUInt const ret = *this;
--(*this);
return ret;
}
[[nodiscard]] BaseUint
[[nodiscard]] BaseUInt
next() const
{
auto ret = *this;
return ++ret;
}
[[nodiscard]] BaseUint
[[nodiscard]] BaseUInt
prev() const
{
auto ret = *this;
return --ret;
}
BaseUint&
operator+=(BaseUint const& b)
BaseUInt&
operator+=(BaseUInt const& b)
{
std::uint64_t carry = 0;
for (int i = kWIDTH - 1; i >= 0; i--)
for (int i = kWidth - 1; i >= 0; i--)
{
std::uint64_t const n = carry + boost::endian::big_to_native(data_[i]) +
boost::endian::big_to_native(b.data_[i]);
@@ -466,7 +489,7 @@ public:
template <class Hasher>
friend void
hash_append(Hasher& h, BaseUint const& a) noexcept
hash_append(Hasher& h, BaseUInt const& a) noexcept
{
// Do not allow any endian transformations on this memory
h(a.data_.data(), sizeof(a.data_));
@@ -503,13 +526,13 @@ public:
return parseHex(std::string_view{str});
}
constexpr static std::size_t
static constexpr std::size_t
size()
{
return kBYTES;
return kBytes;
}
BaseUint<Bits, Tag>&
BaseUInt<Bits, Tag>&
operator=(beast::Zero)
{
data_.fill(0);
@@ -520,28 +543,28 @@ public:
[[nodiscard]] bool
isZero() const
{
return *this == beast::kZERO;
return *this == beast::kZero;
}
[[nodiscard]] bool
isNonZero() const
{
return *this != beast::kZERO;
return *this != beast::kZero;
}
void
zero()
{
*this = beast::kZERO;
*this = beast::kZero;
}
};
using uint128 = BaseUint<128>;
using uint160 = BaseUint<160>;
using uint256 = BaseUint<256>;
using uint192 = BaseUint<192>;
using uint128 = BaseUInt<128>;
using uint160 = BaseUInt<160>;
using uint256 = BaseUInt<256>;
using uint192 = BaseUInt<192>;
template <std::size_t Bits, class Tag>
[[nodiscard]] constexpr std::strong_ordering
operator<=>(BaseUint<Bits, Tag> const& lhs, BaseUint<Bits, Tag> const& rhs)
operator<=>(BaseUInt<Bits, Tag> const& lhs, BaseUInt<Bits, Tag> const& rhs)
{
// This comparison might seem wrong on a casual inspection because it
// compares data internally stored as std::uint32_t byte-by-byte. But
@@ -562,7 +585,7 @@ operator<=>(BaseUint<Bits, Tag> const& lhs, BaseUint<Bits, Tag> const& rhs)
template <std::size_t Bits, typename Tag>
[[nodiscard]] constexpr bool
operator==(BaseUint<Bits, Tag> const& lhs, BaseUint<Bits, Tag> const& rhs)
operator==(BaseUInt<Bits, Tag> const& lhs, BaseUInt<Bits, Tag> const& rhs)
{
return (lhs <=> rhs) == 0;
}
@@ -570,59 +593,59 @@ operator==(BaseUint<Bits, Tag> const& lhs, BaseUint<Bits, Tag> const& rhs)
//------------------------------------------------------------------------------
template <std::size_t Bits, class Tag>
constexpr bool
operator==(BaseUint<Bits, Tag> const& a, std::uint64_t b)
operator==(BaseUInt<Bits, Tag> const& a, std::uint64_t b)
{
return a == BaseUint<Bits, Tag>(b);
return a == BaseUInt<Bits, Tag>(b);
}
//------------------------------------------------------------------------------
template <std::size_t Bits, class Tag>
constexpr BaseUint<Bits, Tag>
operator^(BaseUint<Bits, Tag> const& a, BaseUint<Bits, Tag> const& b)
constexpr BaseUInt<Bits, Tag>
operator^(BaseUInt<Bits, Tag> const& a, BaseUInt<Bits, Tag> const& b)
{
return BaseUint<Bits, Tag>(a) ^= b;
return BaseUInt<Bits, Tag>(a) ^= b;
}
template <std::size_t Bits, class Tag>
constexpr BaseUint<Bits, Tag>
operator&(BaseUint<Bits, Tag> const& a, BaseUint<Bits, Tag> const& b)
constexpr BaseUInt<Bits, Tag>
operator&(BaseUInt<Bits, Tag> const& a, BaseUInt<Bits, Tag> const& b)
{
return BaseUint<Bits, Tag>(a) &= b;
return BaseUInt<Bits, Tag>(a) &= b;
}
template <std::size_t Bits, class Tag>
constexpr BaseUint<Bits, Tag>
operator|(BaseUint<Bits, Tag> const& a, BaseUint<Bits, Tag> const& b)
constexpr BaseUInt<Bits, Tag>
operator|(BaseUInt<Bits, Tag> const& a, BaseUInt<Bits, Tag> const& b)
{
return BaseUint<Bits, Tag>(a) |= b;
return BaseUInt<Bits, Tag>(a) |= b;
}
template <std::size_t Bits, class Tag>
constexpr BaseUint<Bits, Tag>
operator+(BaseUint<Bits, Tag> const& a, BaseUint<Bits, Tag> const& b)
constexpr BaseUInt<Bits, Tag>
operator+(BaseUInt<Bits, Tag> const& a, BaseUInt<Bits, Tag> const& b)
{
return BaseUint<Bits, Tag>(a) += b;
return BaseUInt<Bits, Tag>(a) += b;
}
//------------------------------------------------------------------------------
template <std::size_t Bits, class Tag>
inline std::string
to_string(BaseUint<Bits, Tag> const& a)
to_string(BaseUInt<Bits, Tag> const& a)
{
return strHex(a.cbegin(), a.cend());
}
template <std::size_t Bits, class Tag>
inline std::string
toShortString(BaseUint<Bits, Tag> const& a)
toShortString(BaseUInt<Bits, Tag> const& a)
{
static_assert(BaseUint<Bits, Tag>::kBYTES > 4, "For 4 bytes or less, use a native type");
static_assert(BaseUInt<Bits, Tag>::kBytes > 4, "For 4 bytes or less, use a native type");
return strHex(a.cbegin(), a.cbegin() + 4) + "...";
}
template <std::size_t Bits, class Tag>
inline std::ostream&
operator<<(std::ostream& out, BaseUint<Bits, Tag> const& u)
operator<<(std::ostream& out, BaseUInt<Bits, Tag> const& u)
{
return out << to_string(u);
}
@@ -650,7 +673,7 @@ static_assert(sizeof(uint256) == 256 / 8, "There should be no padding bytes");
namespace beast {
template <std::size_t Bits, class Tag>
struct IsUniquelyRepresented<xrpl::BaseUint<Bits, Tag>> : public std::true_type
struct IsUniquelyRepresented<xrpl::BaseUInt<Bits, Tag>> : public std::true_type
{
explicit IsUniquelyRepresented() = default;
};

View File

@@ -30,10 +30,10 @@ using weeks = std::chrono::duration<int, std::ratio_multiply<days::period, std::
= seconds(946684800)
*/
constexpr static std::chrono::seconds kEPOCH_OFFSET =
static constexpr std::chrono::seconds kEpochOffset =
date::sys_days{date::year{2000} / 1 / 1} - date::sys_days{date::year{1970} / 1 / 1};
static_assert(kEPOCH_OFFSET.count() == 946684800);
static_assert(kEpochOffset.count() == 946684800);
class NetClock
{
@@ -60,7 +60,7 @@ to_string(NetClock::time_point tp)
{
// 2000-01-01 00:00:00 UTC is 946684800s from 1970-01-01 00:00:00 UTC
using namespace std::chrono;
return to_string(system_clock::time_point{tp.time_since_epoch() + kEPOCH_OFFSET});
return to_string(system_clock::time_point{tp.time_since_epoch() + kEpochOffset});
}
template <class Duration>
@@ -77,7 +77,7 @@ toStringIso(NetClock::time_point tp)
// 2000-01-01 00:00:00 UTC is 946684800s from 1970-01-01 00:00:00 UTC
// Note, NetClock::duration is seconds, as checked by static_assert
static_assert(std::is_same_v<NetClock::duration::period, std::ratio<1>>);
return toStringIso(date::sys_time<NetClock::duration>{tp.time_since_epoch() + kEPOCH_OFFSET});
return toStringIso(date::sys_time<NetClock::duration>{tp.time_since_epoch() + kEpochOffset});
}
/** A clock for measuring elapsed time.

View File

@@ -31,9 +31,9 @@ makeSeedPair() noexcept
// state_t(state_t const&) = delete;
// state_t& operator=(state_t const&) = delete;
};
static StateT kSTATE;
std::scoped_lock const lock(kSTATE.mutex);
return {kSTATE.dist(kSTATE.gen), kSTATE.dist(kSTATE.gen)};
static StateT kState;
std::scoped_lock const lock(kState.mutex);
return {kState.dist(kState.gen), kState.dist(kState.gen)};
}
} // namespace detail

View File

@@ -5,7 +5,7 @@
#include <optional>
namespace xrpl {
auto constexpr kMULDIV_MAX = std::numeric_limits<std::uint64_t>::max();
constexpr auto kMuldivMax = std::numeric_limits<std::uint64_t>::max();
/** Return value*mul/div accurately.
Computes the result of the multiplication and division in

View File

@@ -236,7 +236,7 @@ public:
map_.resize(partitions_);
XRPL_ASSERT(
partitions_,
"xrpl::partitioned_unordered_map::partitioned_unordered_map : "
"xrpl::PartitionedUnorderedMap::PartitionedUnorderedMap : "
"nonzero partitions");
}

View File

@@ -47,7 +47,7 @@ inline beast::xor_shift_engine&
defaultPrng()
{
// This is used to seed the thread-specific PRNGs on demand
static beast::xor_shift_engine kSEEDER = [] {
static beast::xor_shift_engine kSeeder = [] {
std::random_device rng;
std::uniform_int_distribution<std::uint64_t> distribution{1};
return beast::xor_shift_engine(distribution(rng));
@@ -57,17 +57,17 @@ defaultPrng()
static std::mutex kM;
// The thread-specific PRNGs:
thread_local beast::xor_shift_engine kENGINE = [] {
thread_local beast::xor_shift_engine kEngine = [] {
std::uint64_t seed = 0;
{
std::scoped_lock const lk(kM);
std::uniform_int_distribution<std::uint64_t> distribution{1};
seed = distribution(kSEEDER);
seed = distribution(kSeeder);
}
return beast::xor_shift_engine{seed};
}();
return kENGINE;
return kEngine;
}
/** Return a uniformly distributed random integer.
@@ -94,7 +94,7 @@ template <class Engine, class Integral>
std::enable_if_t<std::is_integral_v<Integral> && detail::is_engine<Engine>::value, Integral>
randInt(Engine& engine, Integral min, Integral max)
{
XRPL_ASSERT(max > min, "xrpl::rand_int : max over min inputs");
XRPL_ASSERT(max > min, "xrpl::randInt : max over min inputs");
// This should have no state and constructing it should
// be very cheap. If that turns out not to be the case

View File

@@ -22,9 +22,9 @@ safeCast(Src s) noexcept
{
static_assert(
std::is_signed_v<Dest> || std::is_unsigned_v<Src>, "Cannot cast signed to unsigned");
constexpr unsigned kNOT_SAME = std::is_signed_v<Dest> != std::is_signed_v<Src>;
constexpr unsigned kNotSame = std::is_signed_v<Dest> != std::is_signed_v<Src>;
static_assert(
sizeof(Dest) >= sizeof(Src) + kNOT_SAME,
sizeof(Dest) >= sizeof(Src) + kNotSame,
"Destination is too small to hold all values of source");
return static_cast<Dest>(s);
}
@@ -81,7 +81,7 @@ safeDowncast(Src* s) noexcept
return static_cast<Dest>(s); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
#else
auto* result = dynamic_cast<Dest>(s);
XRPL_ASSERT(result != nullptr, "xrpl::safe_downcast : pointer downcast is valid");
XRPL_ASSERT(result != nullptr, "xrpl::safeDowncast : pointer downcast is valid");
return result;
#endif
}
@@ -94,7 +94,7 @@ safeDowncast(Src& s) noexcept
#ifndef NDEBUG
XRPL_ASSERT(
dynamic_cast<std::add_pointer_t<std::remove_reference_t<Dest>>>(&s) != nullptr,
"xrpl::safe_downcast : reference downcast is valid");
"xrpl::safeDowncast : reference downcast is valid");
#endif
return static_cast<Dest>(s); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
}

View File

@@ -24,20 +24,20 @@ namespace xrpl {
template <class EF>
class ScopeExit
{
EF exit_function_;
bool execute_on_destruction_{true};
EF exitFunction_;
bool executeOnDestruction_{true};
public:
~ScopeExit()
{
if (execute_on_destruction_)
exit_function_();
if (executeOnDestruction_)
exitFunction_();
}
ScopeExit(ScopeExit&& rhs) noexcept(
std::is_nothrow_move_constructible_v<EF> || std::is_nothrow_copy_constructible_v<EF>)
: exit_function_{std::forward<EF>(rhs.exit_function_)}
, execute_on_destruction_{rhs.execute_on_destruction_}
: exitFunction_{std::forward<EF>(rhs.exitFunction_)}
, executeOnDestruction_{rhs.executeOnDestruction_}
{
rhs.release();
}
@@ -51,7 +51,7 @@ public:
std::enable_if_t<
!std::is_same_v<std::remove_cv_t<EFP>, ScopeExit> &&
std::is_constructible_v<EF, EFP>>* = 0) noexcept
: exit_function_{std::forward<EFP>(f)}
: exitFunction_{std::forward<EFP>(f)}
{
static_assert(std::is_nothrow_constructible_v<EF, decltype(std::forward<EFP>(f))>);
}
@@ -59,7 +59,7 @@ public:
void
release() noexcept
{
execute_on_destruction_ = false;
executeOnDestruction_ = false;
}
};
@@ -69,22 +69,22 @@ ScopeExit(EF) -> ScopeExit<EF>;
template <class EF>
class ScopeFail
{
EF exit_function_;
bool execute_on_destruction_{true};
int uncaught_on_creation_{std::uncaught_exceptions()};
EF exitFunction_;
bool executeOnDestruction_{true};
int uncaughtOnCreation_{std::uncaught_exceptions()};
public:
~ScopeFail()
{
if (execute_on_destruction_ && std::uncaught_exceptions() > uncaught_on_creation_)
exit_function_();
if (executeOnDestruction_ && std::uncaught_exceptions() > uncaughtOnCreation_)
exitFunction_();
}
ScopeFail(ScopeFail&& rhs) noexcept(
std::is_nothrow_move_constructible_v<EF> || std::is_nothrow_copy_constructible_v<EF>)
: exit_function_{std::forward<EF>(rhs.exit_function_)}
, execute_on_destruction_{rhs.execute_on_destruction_}
, uncaught_on_creation_{rhs.uncaught_on_creation_}
: exitFunction_{std::forward<EF>(rhs.exitFunction_)}
, executeOnDestruction_{rhs.executeOnDestruction_}
, uncaughtOnCreation_{rhs.uncaughtOnCreation_}
{
rhs.release();
}
@@ -98,7 +98,7 @@ public:
std::enable_if_t<
!std::is_same_v<std::remove_cv_t<EFP>, ScopeFail> &&
std::is_constructible_v<EF, EFP>>* = 0) noexcept
: exit_function_{std::forward<EFP>(f)}
: exitFunction_{std::forward<EFP>(f)}
{
static_assert(std::is_nothrow_constructible_v<EF, decltype(std::forward<EFP>(f))>);
}
@@ -106,7 +106,7 @@ public:
void
release() noexcept
{
execute_on_destruction_ = false;
executeOnDestruction_ = false;
}
};
@@ -116,22 +116,22 @@ ScopeFail(EF) -> ScopeFail<EF>;
template <class EF>
class ScopeSuccess
{
EF exit_function_;
bool execute_on_destruction_{true};
int uncaught_on_creation_{std::uncaught_exceptions()};
EF exitFunction_;
bool executeOnDestruction_{true};
int uncaughtOnCreation_{std::uncaught_exceptions()};
public:
~ScopeSuccess() noexcept(noexcept(exit_function_()))
~ScopeSuccess() noexcept(noexcept(exitFunction_()))
{
if (execute_on_destruction_ && std::uncaught_exceptions() <= uncaught_on_creation_)
exit_function_();
if (executeOnDestruction_ && std::uncaught_exceptions() <= uncaughtOnCreation_)
exitFunction_();
}
ScopeSuccess(ScopeSuccess&& rhs) noexcept(
std::is_nothrow_move_constructible_v<EF> || std::is_nothrow_copy_constructible_v<EF>)
: exit_function_{std::forward<EF>(rhs.exit_function_)}
, execute_on_destruction_{rhs.execute_on_destruction_}
, uncaught_on_creation_{rhs.uncaught_on_creation_}
: exitFunction_{std::forward<EF>(rhs.exitFunction_)}
, executeOnDestruction_{rhs.executeOnDestruction_}
, uncaughtOnCreation_{rhs.uncaughtOnCreation_}
{
rhs.release();
}
@@ -146,14 +146,14 @@ public:
!std::is_same_v<std::remove_cv_t<EFP>, ScopeSuccess> &&
std::is_constructible_v<EF, EFP>>* =
0) noexcept(std::is_nothrow_constructible_v<EF, EFP> || std::is_nothrow_constructible_v<EF, EFP&>)
: exit_function_{std::forward<EFP>(f)}
: exitFunction_{std::forward<EFP>(f)}
{
}
void
release() noexcept
{
execute_on_destruction_ = false;
executeOnDestruction_ = false;
}
};
@@ -205,7 +205,7 @@ class ScopeUnlock
public:
explicit ScopeUnlock(std::unique_lock<Mutex>& lock) noexcept(true) : plock_(&lock)
{
XRPL_ASSERT(plock_->owns_lock(), "xrpl::scope_unlock::scope_unlock : mutex must be locked");
XRPL_ASSERT(plock_->owns_lock(), "xrpl::ScopeUnlock::ScopeUnlock : mutex must be locked");
plock_->unlock();
}

View File

@@ -103,7 +103,7 @@ public:
{
XRPL_ASSERT(
index >= 0 && (mask_ != 0),
"xrpl::packed_spinlock::packed_spinlock : valid index and mask");
"xrpl::PackedSpinlock::PackedSpinlock : valid index and mask");
}
[[nodiscard]] bool

View File

@@ -15,7 +15,7 @@ namespace beast {
/** Measures handler latency on an io_context queue. */
template <class Clock>
class IoLatencyProbe
class IOLatencyProbe
{
private:
using duration = typename Clock::duration;
@@ -30,12 +30,12 @@ private:
bool cancel_{false};
public:
IoLatencyProbe(duration const& period, boost::asio::io_context& ios)
IOLatencyProbe(duration const& period, boost::asio::io_context& ios)
: period_(period), ios_(ios), timer_(ios_)
{
}
~IoLatencyProbe()
~IOLatencyProbe()
{
std::unique_lock<decltype(mutex_)> lock(mutex_);
cancel(lock, true);
@@ -85,7 +85,7 @@ public:
{
std::scoped_lock const lock(mutex_);
if (cancel_)
throw std::logic_error("io_latency_probe is canceled");
throw std::logic_error("IOLatencyProbe is canceled");
boost::asio::post(
ios_, SampleOp<Handler>(std::forward<Handler>(handler), Clock::now(), false, this));
}
@@ -100,7 +100,7 @@ public:
{
std::scoped_lock const lock(mutex_);
if (cancel_)
throw std::logic_error("io_latency_probe is canceled");
throw std::logic_error("IOLatencyProbe is canceled");
boost::asio::post(
ios_, SampleOp<Handler>(std::forward<Handler>(handler), Clock::now(), true, this));
}
@@ -140,18 +140,18 @@ private:
Handler handler;
time_point start;
bool repeat;
IoLatencyProbe* probe;
IOLatencyProbe* probe;
SampleOp(
Handler const& handler,
time_point const& start,
bool repeat,
IoLatencyProbe* probe)
IOLatencyProbe* probe)
: handler(handler), start(start), repeat(repeat), probe(probe)
{
XRPL_ASSERT(
probe,
"beast::io_latency_probe::sample_op::sample_op : non-null "
"beast::IOLatencyProbe::SampleOp::SampleOp : non-null "
"probe input");
probe->addref();
}
@@ -164,7 +164,7 @@ private:
{
XRPL_ASSERT(
probe,
"beast::io_latency_probe::sample_op::sample_op(sample_op&&) : "
"beast::IOLatencyProbe::SampleOp::SampleOp(SampleOp&&) : "
"non-null probe input");
from.probe = nullptr;
}

View File

@@ -83,8 +83,8 @@ template <class Facade, class Clock = Facade>
AbstractClock<Facade>&
getAbstractClock()
{
static detail::AbstractClockWrapper<Facade, Clock> kCLOCK;
return kCLOCK;
static detail::AbstractClockWrapper<Facade, Clock> kClock;
return kClock;
}
} // namespace beast

View File

@@ -1370,7 +1370,7 @@ private:
buck_.resize(size() + additional, cont_);
XRPL_ASSERT(
loadFactor() <= maxLoadFactor(),
"beast::detail::AgedUnorderedContainer::maybe_rehash : maximum "
"beast::detail::AgedUnorderedContainer::maybeRehash : maximum "
"load factor");
}

View File

@@ -21,7 +21,7 @@ setCurrentThreadName(std::string_view newThreadName);
// On Linux, thread names are limited to 16 bytes including the null terminator.
// Maximum number of characters is therefore 15.
constexpr std::size_t kMAX_THREAD_NAME_LENGTH = 15;
constexpr std::size_t kMaxThreadNameLength = 15;
/** Sets the name of the caller thread with compile-time size checking.
@tparam N The size of the string literal including null terminator
@@ -34,7 +34,7 @@ template <std::size_t N>
void
setCurrentThreadName(char const (&newThreadName)[N])
{
static_assert(N <= kMAX_THREAD_NAME_LENGTH + 1, "Thread name cannot exceed 15 characters");
static_assert(N <= kMaxThreadNameLength + 1, "Thread name cannot exceed 15 characters");
setCurrentThreadName(std::string_view(newThreadName, N - 1));
}

View File

@@ -53,7 +53,7 @@ inline void
maybeReverseBytes(T& t, Hasher&)
{
maybeReverseBytes(
t, std::integral_constant<bool, Hasher::kENDIAN != boost::endian::order::native>{});
t, std::integral_constant<bool, Hasher::kEndian != boost::endian::order::native>{});
}
} // namespace detail
@@ -154,7 +154,7 @@ struct IsContiguouslyHashable
: public std::integral_constant<
bool,
IsUniquelyRepresented<T>::value &&
(sizeof(T) == 1 || HashAlgorithm::kENDIAN == boost::endian::order::native)>
(sizeof(T) == 1 || HashAlgorithm::kEndian == boost::endian::order::native)>
{
explicit IsContiguouslyHashable() = default;
};

View File

@@ -21,9 +21,9 @@ private:
static_assert(sizeof(std::size_t) == 8, "requires 64-bit std::size_t");
// Have an internal buffer to avoid the streaming API
// A 64-byte buffer should to be big enough for us
static constexpr std::size_t kINTERNAL_BUFFER_SIZE = 64;
static constexpr std::size_t kInternalBufferSize = 64;
alignas(64) std::array<std::uint8_t, kINTERNAL_BUFFER_SIZE> buffer_{};
alignas(64) std::array<std::uint8_t, kInternalBufferSize> buffer_{};
std::span<std::uint8_t> readBuffer_;
std::span<std::uint8_t> writeBuffer_;
@@ -102,7 +102,7 @@ private:
}
public:
static constexpr auto const kENDIAN = boost::endian::order::native;
static constexpr auto kEndian = boost::endian::order::native;
Xxhasher(Xxhasher const&) = delete;
Xxhasher&

View File

@@ -62,9 +62,7 @@ private:
{
using run_time = std::pair<std::string, typename clock_type::duration>;
// Need to be named before converting
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum { MaxTop = 10 };
static constexpr auto kMaxTop = 10;
std::size_t suites = 0;
std::size_t cases = 0;
@@ -79,8 +77,8 @@ private:
std::ostream& os_;
Results results_;
SuiteResults suite_results_;
CaseResults case_results_;
SuiteResults suiteResults_;
CaseResults caseResults_;
public:
Reporter(Reporter const&) = delete;
@@ -148,11 +146,11 @@ Reporter<Unused>::Results::add(SuiteResults const& r)
});
if (iter != top.end())
{
if (top.size() == MaxTop)
if (top.size() == kMaxTop)
top.resize(top.size() - 1);
top.emplace(iter, r.name, elapsed);
}
else if (top.size() < MaxTop)
else if (top.size() < kMaxTop)
{
top.emplace_back(r.name, elapsed);
}
@@ -198,22 +196,22 @@ template <class Unused>
void
Reporter<Unused>::onSuiteBegin(SuiteInfo const& info)
{
suite_results_ = SuiteResults{info.fullName()};
suiteResults_ = SuiteResults{info.fullName()};
}
template <class Unused>
void
Reporter<Unused>::onSuiteEnd()
{
results_.add(suite_results_);
results_.add(suiteResults_);
}
template <class Unused>
void
Reporter<Unused>::onCaseBegin(std::string const& name)
{
case_results_ = CaseResults(name);
os_ << suite_results_.name << (case_results_.name.empty() ? "" : (" " + case_results_.name))
caseResults_ = CaseResults(name);
os_ << suiteResults_.name << (caseResults_.name.empty() ? "" : (" " + caseResults_.name))
<< std::endl;
}
@@ -221,23 +219,23 @@ template <class Unused>
void
Reporter<Unused>::onCaseEnd()
{
suite_results_.add(case_results_);
suiteResults_.add(caseResults_);
}
template <class Unused>
void
Reporter<Unused>::onPass()
{
++case_results_.total;
++caseResults_.total;
}
template <class Unused>
void
Reporter<Unused>::onFail(std::string const& reason)
{
++case_results_.failed;
++case_results_.total;
os_ << "#" << case_results_.total << " failed" << (reason.empty() ? "" : ": ") << reason
++caseResults_.failed;
++caseResults_.total;
os_ << "#" << caseResults_.total << " failed" << (reason.empty() ? "" : ": ") << reason
<< std::endl;
}

View File

@@ -299,8 +299,8 @@ private:
static Suite**
pThisSuite()
{
static Suite* kP_TS = nullptr; // NOLINT TODO
return &kP_TS;
static Suite* kPTs = nullptr; // NOLINT TODO
return &kPTs;
}
/** Runs the suite. */

View File

@@ -2,29 +2,25 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <cstdint>
#include <sstream>
namespace beast {
/** A namespace for easy access to logging severity values. */
namespace severities {
/** Severity level / threshold of a Journal message. */
// Hundreds of usages via logging macros
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum Severity {
KAll = 0,
enum class Severity : std::uint8_t {
All = 0,
KTrace = KAll,
KDebug = 1,
KInfo = 2,
KWarning = 3,
KError = 4,
KFatal = 5,
Trace = All,
Debug = 1,
Info = 2,
Warning = 3,
Error = 4,
Fatal = 5,
KDisabled = 6,
KNone = KDisabled
Disabled = 6,
None = Disabled
};
} // namespace severities
/** A generic endpoint for log messages.
@@ -44,9 +40,6 @@ public:
class Sink;
private:
// Severity level / threshold of a Journal message.
using Severity = severities::Severity;
// Invariant: sink_ always points to a valid Sink
Sink* sink_;
@@ -183,7 +176,7 @@ public:
{
public:
/** Create a stream which produces no output. */
explicit Stream() : sink_(getNullSink()), level_(severities::KDisabled)
explicit Stream() : sink_(getNullSink()), level_(Severity::Disabled)
{
}
@@ -194,7 +187,7 @@ public:
Stream(Sink& sink, Severity level) : sink_(sink), level_(level)
{
XRPL_ASSERT(
level_ < severities::KDisabled, "beast::Journal::Stream::Stream : maximum level");
level_ < Severity::Disabled, "beast::Journal::Stream::Stream : maximum level");
}
/** Construct or copy another Stream. */
@@ -297,37 +290,37 @@ public:
[[nodiscard]] Stream
trace() const
{
return {*sink_, severities::KTrace};
return {*sink_, Severity::Trace};
}
[[nodiscard]] Stream
debug() const
{
return {*sink_, severities::KDebug};
return {*sink_, Severity::Debug};
}
[[nodiscard]] Stream
info() const
{
return {*sink_, severities::KInfo};
return {*sink_, Severity::Info};
}
[[nodiscard]] Stream
warn() const
{
return {*sink_, severities::KWarning};
return {*sink_, Severity::Warning};
}
[[nodiscard]] Stream
error() const
{
return {*sink_, severities::KError};
return {*sink_, Severity::Error};
}
[[nodiscard]] Stream
fatal() const
{
return {*sink_, severities::KFatal};
return {*sink_, Severity::Fatal};
}
/** @} */
};

View File

@@ -36,7 +36,7 @@ public:
}
[[nodiscard]] bool
active(beast::severities::Severity level) const override
active(beast::Severity level) const override
{
return sink_.active(level);
}
@@ -53,27 +53,27 @@ public:
sink_.console(output);
}
[[nodiscard]] beast::severities::Severity
[[nodiscard]] beast::Severity
threshold() const override
{
return sink_.threshold();
}
void
threshold(beast::severities::Severity thresh) override
threshold(beast::Severity thresh) override
{
sink_.threshold(thresh);
}
void
write(beast::severities::Severity level, std::string const& text) override
write(beast::Severity level, std::string const& text) override
{
using beast::Journal;
sink_.write(level, prefix_ + text);
}
void
writeAlways(severities::Severity level, std::string const& text) override
writeAlways(Severity level, std::string const& text) override
{
using beast::Journal;
sink_.writeAlways(level, prefix_ + text);

View File

@@ -27,7 +27,7 @@ struct Zero
};
namespace {
constexpr Zero kZERO{};
constexpr Zero kZero{};
} // namespace
/** Default implementation of signum calls the method on the class. */
@@ -102,42 +102,42 @@ template <typename T>
bool
operator==(Zero, T const& t)
{
return t == kZERO;
return t == kZero;
}
template <typename T>
bool
operator!=(Zero, T const& t)
{
return t != kZERO;
return t != kZero;
}
template <typename T>
bool
operator<(Zero, T const& t)
{
return t > kZERO;
return t > kZero;
}
template <typename T>
bool
operator>(Zero, T const& t)
{
return t < kZERO;
return t < kZero;
}
template <typename T>
bool
operator>=(Zero, T const& t)
{
return t <= kZERO;
return t <= kZero;
}
template <typename T>
bool
operator<=(Zero, T const& t)
{
return t >= kZERO;
return t >= kZero;
}
} // namespace beast

View File

@@ -14,23 +14,23 @@ void
rngfill(void* const buffer, std::size_t const bytes, Generator& g)
{
using result_type = typename Generator::result_type;
constexpr std::size_t kRESULT_SIZE = sizeof(result_type);
constexpr std::size_t kResultSize = sizeof(result_type);
std::uint8_t* const bufferStart = static_cast<std::uint8_t*>(buffer);
std::size_t const completeIterations = bytes / kRESULT_SIZE;
std::size_t const bytesRemaining = bytes % kRESULT_SIZE;
std::size_t const completeIterations = bytes / kResultSize;
std::size_t const bytesRemaining = bytes % kResultSize;
for (std::size_t count = 0; count < completeIterations; ++count)
{
result_type const v = g();
std::size_t const offset = count * kRESULT_SIZE;
std::memcpy(bufferStart + offset, &v, kRESULT_SIZE);
std::size_t const offset = count * kResultSize;
std::memcpy(bufferStart + offset, &v, kResultSize);
}
if (bytesRemaining > 0)
{
result_type const v = g();
std::size_t const offset = completeIterations * kRESULT_SIZE;
std::size_t const offset = completeIterations * kResultSize;
std::memcpy(bufferStart + offset, &v, bytesRemaining);
}
}

View File

@@ -26,12 +26,14 @@ public:
result_type
operator()();
static result_type constexpr min()
static constexpr result_type
min()
{
return std::numeric_limits<result_type>::min();
}
static result_type constexpr max()
static constexpr result_type
max()
{
return std::numeric_limits<result_type>::max();
}

View File

@@ -27,7 +27,7 @@ public:
that were previously considered valid to no longer
be allowed.
*/
static constexpr std::size_t kMAX_SERIALIZED_CONDITION = 128;
static constexpr std::size_t kMaxSerializedCondition = 128;
/** Load a condition from its binary form

View File

@@ -16,7 +16,7 @@ public:
that were previously considered valid to no longer
be allowed.
*/
static constexpr std::size_t kMAX_SERIALIZED_FULFILLMENT = 256;
static constexpr std::size_t kMaxSerializedFulfillment = 256;
/** Load a fulfillment from its binary form

View File

@@ -23,7 +23,7 @@ public:
While future versions of this code will never lower
this limit, they may opt to raise it.
*/
static constexpr std::size_t kMAX_PREIMAGE_LENGTH = 128;
static constexpr std::size_t kMaxPreimageLength = 128;
/** Parse the payload for a PreimageSha256 condition
@@ -65,7 +65,7 @@ public:
return {};
}
if (s.size() > kMAX_PREIMAGE_LENGTH)
if (s.size() > kMaxPreimageLength)
{
ec = Error::PreimageTooLong;
return {};

View File

@@ -6,7 +6,7 @@ namespace xrpl {
/// Coroutine stack size (1.5 MB). Increased from 1 MB because
/// ASAN-instrumented deep call stacks exceeded the original limit.
constexpr std::size_t kCORO_STACK_SIZE = 1536 * 1024;
constexpr std::size_t kCoroStackSize = 1536 * 1024;
template <class F>
JobQueue::Coro::Coro(CoroCreateT, JobQueue& jq, JobType type, std::string name, F&& f)
@@ -14,7 +14,7 @@ JobQueue::Coro::Coro(CoroCreateT, JobQueue& jq, JobType type, std::string name,
, type_(type)
, name_(std::move(name))
, coro_(
boost::context::protected_fixedsize_stack(kCORO_STACK_SIZE),
boost::context::protected_fixedsize_stack(kCoroStackSize),
[this, fn = std::forward<F>(f)](boost::coroutines2::coroutine<void>::push_type& doYield) {
yield_ = &doYield;
yield();
@@ -47,7 +47,7 @@ inline bool
JobQueue::Coro::post()
{
{
std::scoped_lock const lk(mutex_run_);
std::scoped_lock const lk(mutexRun_);
running_ = true;
}
@@ -58,7 +58,7 @@ JobQueue::Coro::post()
}
// The coroutine will not run. Clean up running_.
std::scoped_lock const lk(mutex_run_);
std::scoped_lock const lk(mutexRun_);
running_ = false;
cv_.notify_all();
return false;
@@ -68,7 +68,7 @@ inline void
JobQueue::Coro::resume()
{
{
std::scoped_lock const lk(mutex_run_);
std::scoped_lock const lk(mutexRun_);
running_ = true;
}
{
@@ -92,7 +92,7 @@ JobQueue::Coro::resume()
}
detail::getLocalValues().release();
detail::getLocalValues().reset(saved);
std::scoped_lock const lk(mutex_run_);
std::scoped_lock const lk(mutexRun_);
running_ = false;
cv_.notify_all();
}
@@ -127,7 +127,7 @@ JobQueue::Coro::expectEarlyExit()
inline void
JobQueue::Coro::join()
{
std::unique_lock<std::mutex> lk(mutex_run_);
std::unique_lock<std::mutex> lk(mutexRun_);
cv_.wait(lk, [this]() { return !running_; });
}

View File

@@ -127,7 +127,7 @@ private:
std::function<void()> job_;
std::shared_ptr<LoadEvent> loadEvent_;
std::string name_;
clock_type::time_point queue_time_;
clock_type::time_point queueTime_;
};
using JobCounter = ClosureCounter<void>;

View File

@@ -52,7 +52,7 @@ public:
std::string name_;
bool running_{false};
std::mutex mutex_;
std::mutex mutex_run_;
std::mutex mutexRun_;
std::condition_variable cv_;
boost::coroutines2::coroutine<void>::push_type* yield_{};
boost::coroutines2::coroutine<void>::pull_type coro_;
@@ -246,7 +246,7 @@ private:
// Statistics tracking
perf::PerfLog& perfLog_;
beast::insight::Collector::ptr collector_;
beast::insight::Gauge job_count_;
beast::insight::Gauge jobCount_;
beast::insight::Hook hook_;
std::condition_variable cv_;

View File

@@ -101,8 +101,8 @@ public:
static JobTypes const&
instance()
{
static JobTypes const kTYPES;
return kTYPES;
static JobTypes const kTypes;
return kTypes;
}
static std::string const&

View File

@@ -5,7 +5,7 @@
namespace xrpl {
/** A PropertyStream::Sink which produces a json::Value of type objectValue. */
/** A PropertyStream::Sink which produces a json::Value of type ValueType::Object. */
class JsonPropertyStream : public beast::PropertyStream
{
public:

View File

@@ -161,7 +161,7 @@ public:
* While the JSON spec doesn't explicitly disallow this, you should avoid
* calling this method twice with the same tag for the same object.
*
* If CHECK_JSON_WRITER is defined, this function throws an exception if if
* If CHECK_JSON_WRITER is defined, this function throws an exception if
* the tag you use has already been used in this object.
*/
template <typename Type>

View File

@@ -67,27 +67,25 @@ public:
[[nodiscard]] std::string
getFormattedErrorMessages() const;
static constexpr unsigned kNEST_LIMIT{25};
static constexpr unsigned kNestLimit{25};
private:
// 53 files, protocol-wide
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum TokenType {
TokenEndOfStream = 0,
TokenObjectBegin,
TokenObjectEnd,
TokenArrayBegin,
TokenArrayEnd,
TokenString,
TokenInteger,
TokenDouble,
TokenTrue,
TokenFalse,
TokenNull,
TokenArraySeparator,
TokenMemberSeparator,
TokenComment,
TokenError
enum class TokenType {
EndOfStream = 0,
ObjectBegin,
ObjectEnd,
ArrayBegin,
ArrayEnd,
String,
Integer,
Double,
True,
False,
Null,
ArraySeparator,
MemberSeparator,
Comment,
Error
};
class Token

View File

@@ -15,22 +15,20 @@ namespace json {
/** \brief Type of the value held by a Value object.
*/
// Used throughout JSON layer
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum ValueType {
NullValue = 0, ///< 'null' value
IntValue, ///< signed integer value
UintValue, ///< unsigned integer value
RealValue, ///< double value
StringValue, ///< UTF-8 string value
BooleanValue, ///< bool value
ArrayValue, ///< array value (ordered list)
ObjectValue ///< object value (collection of name/value pairs).
enum class ValueType {
Null = 0, ///< 'null' value
Int, ///< signed integer value
UInt, ///< unsigned integer value
Real, ///< double value
String, ///< UTF-8 string value
Boolean, ///< bool value
Array, ///< array value (ordered list)
Object ///< object value (collection of name/value pairs).
};
/** \brief Lightweight wrapper to tag static string.
*
* Value constructor and objectValue member assignment takes advantage of the
* Value constructor and ValueType::Object member assignment takes advantage of the
* StaticString and avoid the cost of string duplication when storing the
* string or the member name.
*
@@ -104,8 +102,8 @@ operator!=(StaticString x, std::string const& y)
/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
*
* This class is a discriminated union wrapper that can represent a:
* - signed integer [range: Value::minInt - Value::maxInt]
* - unsigned integer (range: 0 - Value::maxUInt)
* - signed integer [range: Value::kMinInt - Value::kMaxInt]
* - unsigned integer (range: 0 - Value::kMaxUInt)
* - double
* - UTF-8 string
* - boolean
@@ -116,16 +114,16 @@ operator!=(StaticString x, std::string const& y)
* The type of the held value is represented by a #ValueType and
* can be obtained using type().
*
* values of an #objectValue or #arrayValue can be accessed using operator[]()
* methods. Non const methods will automatically create the a #nullValue element
* values of an ValueType::Object or ValueType::Array can be accessed using operator[]()
* methods. Non const methods will automatically create the a ValueType::Null element
* if it does not exist.
* The sequence of an #arrayValue will be automatically resize and initialized
* with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
* The sequence of an ValueType::Array will be automatically resize and initialized
* with ValueType::Null. resize() can be used to enlarge or truncate an ValueType::Array.
*
* The get() methods can be used to obtain a default value in the case the
* required element does not exist.
*
* It is possible to iterate over the list of a #objectValue values using
* It is possible to iterate over the list of a ValueType::Object values using
* the getMemberNames() method.
*/
class Value
@@ -140,18 +138,16 @@ public:
using Int = json::Int;
using ArrayIndex = UInt;
static Value const kNULL;
static constexpr Int kMIN_INT = std::numeric_limits<Int>::min();
static constexpr Int kMAX_INT = std::numeric_limits<Int>::max();
static constexpr UInt kMAX_U_INT = std::numeric_limits<UInt>::max();
static Value const kNull;
static constexpr Int kMinInt = std::numeric_limits<Int>::min();
static constexpr Int kMaxInt = std::numeric_limits<Int>::max();
static constexpr UInt kMaxUInt = std::numeric_limits<UInt>::max();
private:
class CZString
{
public:
// Stored as int field, implicit conversion
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum DuplicationPolicy { NoDuplication = 0, Duplicate, DuplicateOnCopy };
enum class DuplicationPolicy { NoDuplication = 0, Duplicate, DuplicateOnCopy };
CZString(int index);
CZString(char const* cstr, DuplicationPolicy allocate);
@@ -182,19 +178,19 @@ public:
/** \brief Create a default Value of the given type.
This is a very useful constructor.
To create an empty array, pass arrayValue.
To create an empty object, pass objectValue.
To create an empty array, pass ValueType::Array.
To create an empty object, pass ValueType::Object.
Another Value can then be set to this one by assignment.
This is useful since clear() and resize() will not alter types.
Examples:
\code
json::Value null_value; // null
json::Value arr_value(json::arrayValue); // []
json::Value obj_value(json::objectValue); // {}
json::Value arr_value(json::ValueType::Array); // []
json::Value obj_value(json::ValueType::Object); // {}
\endcode
*/
Value(ValueType type = NullValue);
Value(ValueType type = ValueType::Null);
Value(Int value);
Value(UInt value);
Value(double value);
@@ -290,7 +286,7 @@ public:
operator bool() const;
/// Remove all object members and array elements.
/// \pre type() is arrayValue, objectValue, or nullValue
/// \pre type() is ValueType::Array, ValueType::Object, or ValueType::Null
/// \post type() is unchanged
void
clear();
@@ -367,7 +363,7 @@ public:
///
/// Do nothing if it did not exist.
/// \return the removed Value, or null.
/// \pre type() is objectValue or nullValue
/// \pre type() is ValueType::Object or ValueType::Null
/// \post type() is unchanged
Value
removeMember(char const* key);
@@ -388,8 +384,8 @@ public:
/// \brief Return a list of the member names.
///
/// If null, return an empty list.
/// \pre type() is objectValue or nullValue
/// \post if type() was nullValue, it remains nullValue
/// \pre type() is ValueType::Object or ValueType::Null
/// \post if type() was ValueType::Null, it remains ValueType::Null
[[nodiscard]] Members
getMemberNames() const;
@@ -469,16 +465,14 @@ operator>=(Value const& x, Value const& y)
* string value memory management done by Value.
*
* - makeMemberName() and releaseMemberName() are called to respectively
* duplicate and free an json::objectValue member name.
* duplicate and free an json::ValueType::Object member name.
* - duplicateStringValue() and releaseStringValue() are called similarly to
* duplicate and free a json::stringValue value.
* duplicate and free a json::ValueType::String value.
*/
class ValueAllocator
{
public:
// Need to be named before converting
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum { Unknown = (unsigned)-1 };
static constexpr auto kUnknown = (unsigned)-1;
virtual ~ValueAllocator() = default;
@@ -487,7 +481,7 @@ public:
virtual void
releaseMemberName(char* memberName) = 0;
virtual char*
duplicateStringValue(char const* value, unsigned int length = Unknown) = 0;
duplicateStringValue(char const* value, unsigned int length = kUnknown) = 0;
virtual void
releaseStringValue(char* value) = 0;
};
@@ -523,12 +517,12 @@ public:
[[nodiscard]] Value
key() const;
/// Return the index of the referenced Value. -1 if it is not an arrayValue.
/// Return the index of the referenced Value. -1 if it is not an ValueType::Array.
[[nodiscard]] UInt
index() const;
/// Return the member name of the referenced Value. "" if it is not an
/// objectValue.
/// ValueType::Object.
[[nodiscard]] char const*
memberName() const;

View File

@@ -204,31 +204,31 @@ writeValue(Write const& write, Value const& value)
{
switch (value.type())
{
case NullValue:
case ValueType::Null:
write("null", 4);
break;
case IntValue:
case ValueType::Int:
writeString(write, valueToString(value.asInt()));
break;
case UintValue:
case ValueType::UInt:
writeString(write, valueToString(value.asUInt()));
break;
case RealValue:
case ValueType::Real:
writeString(write, valueToString(value.asDouble()));
break;
case StringValue:
case ValueType::String:
writeString(write, valueToQuotedString(value.asCString()));
break;
case BooleanValue:
case ValueType::Boolean:
writeString(write, valueToString(value.asBool()));
break;
case ArrayValue: {
case ValueType::Array: {
write("[", 1);
int const size = value.size();
for (int index = 0; index < size; ++index)
@@ -241,7 +241,7 @@ writeValue(Write const& write, Value const& value)
break;
}
case ObjectValue: {
case ValueType::Object: {
Value::Members const members = value.getMemberNames();
write("{", 1);
for (auto it = members.begin(); it != members.end(); ++it)

View File

@@ -67,7 +67,7 @@ public:
[[nodiscard]] virtual json::Value
getJson(bool isAdmin) const = 0;
/** Returns a json::objectValue. */
/** Returns a json::ValueType::Object. */
[[nodiscard]] virtual json::Value
getJson(uint256 const& amendment, bool isAdmin) const = 0;

View File

@@ -123,7 +123,7 @@ private:
bool preserveOrder,
Keylet const& directory,
uint256 const& key,
std::function<void(std::shared_ptr<SLE> const&)> const& describe);
std::function<void(SLE::ref)> const& describe);
public:
ApplyView() = default;
@@ -153,7 +153,7 @@ public:
@return `nullptr` if the key is not present
*/
virtual std::shared_ptr<SLE>
virtual SLE::pointer
peek(Keylet const& k) = 0;
/** Remove a peeked SLE.
@@ -168,7 +168,7 @@ public:
The key is no longer associated with the SLE.
*/
virtual void
erase(std::shared_ptr<SLE> const& sle) = 0;
erase(SLE::ref sle) = 0;
/** Insert a new state SLE
@@ -189,7 +189,7 @@ public:
@note The key is taken from the SLE
*/
virtual void
insert(std::shared_ptr<SLE> const& sle) = 0;
insert(SLE::ref sle) = 0;
/** Indicate changes to a peeked SLE
@@ -208,7 +208,7 @@ public:
*/
/** @{ */
virtual void
update(std::shared_ptr<SLE> const& sle) = 0;
update(SLE::ref sle) = 0;
//--------------------------------------------------------------------------
@@ -301,7 +301,7 @@ public:
dirAppend(
Keylet const& directory,
Keylet const& key,
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
std::function<void(SLE::ref)> const& describe)
{
if (key.type != ltOFFER)
{
@@ -340,7 +340,7 @@ public:
dirInsert(
Keylet const& directory,
uint256 const& key,
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
std::function<void(SLE::ref)> const& describe)
{
return dirAdd(false, directory, key, describe);
}
@@ -349,7 +349,7 @@ public:
dirInsert(
Keylet const& directory,
Keylet const& key,
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
std::function<void(SLE::ref)> const& describe)
{
return dirAdd(false, directory, key.key, describe);
}
@@ -411,7 +411,7 @@ createRoot(
ApplyView& view,
Keylet const& directory,
uint256 const& key,
std::function<void(std::shared_ptr<SLE> const&)> const& describe);
std::function<void(SLE::ref)> const& describe);
auto
findPreviousPage(ApplyView& view, Keylet const& directory, SLE::ref start);
@@ -434,7 +434,7 @@ insertPage(
SLE::ref next,
uint256 const& key,
Keylet const& directory,
std::function<void(std::shared_ptr<SLE> const&)> const& describe);
std::function<void(SLE::ref)> const& describe);
} // namespace directory
} // namespace xrpl

View File

@@ -67,8 +67,8 @@ public:
std::function<void(
uint256 const& key,
bool isDelete,
std::shared_ptr<SLE const> const& before,
std::shared_ptr<SLE const> const& after)> const& func);
SLE::const_ref before,
SLE::const_ref after)> const& func);
private:
std::optional<STAmount> deliver_;

View File

@@ -9,15 +9,15 @@ class BookDirs
private:
ReadView const* view_ = nullptr;
uint256 const root_;
uint256 const next_quality_;
uint256 const nextQuality_;
uint256 const key_;
std::shared_ptr<SLE const> sle_ = nullptr;
SLE::const_pointer sle_ = nullptr;
unsigned int entry_ = 0;
uint256 index_;
public:
class const_iterator; // NOLINT(readability-identifier-naming)
using value_type = std::shared_ptr<SLE const>;
using value_type = SLE::const_pointer;
BookDirs(ReadView const&, Book const&);
@@ -67,16 +67,16 @@ private:
friend class BookDirs;
const_iterator(ReadView const& view, uint256 const& root, uint256 const& dirKey)
: view_(&view), root_(root), key_(dirKey), cur_key_(dirKey)
: view_(&view), root_(root), key_(dirKey), curKey_(dirKey)
{
}
ReadView const* view_ = nullptr;
uint256 root_;
uint256 next_quality_;
uint256 nextQuality_;
uint256 key_;
uint256 cur_key_;
std::shared_ptr<SLE const> sle_;
uint256 curKey_;
SLE::const_pointer sle_;
unsigned int entry_ = 0;
uint256 index_;
std::optional<value_type> mutable cache_;

View File

@@ -36,7 +36,7 @@ public:
bool
exists(Keylet const& k) const override;
std::shared_ptr<SLE const>
SLE::const_pointer
read(Keylet const& k) const override;
bool

View File

@@ -22,12 +22,12 @@ class Dir
private:
ReadView const* view_ = nullptr;
Keylet root_;
std::shared_ptr<SLE const> sle_;
SLE::const_pointer sle_;
STVector256 const* indexes_ = nullptr;
public:
class ConstIterator;
using value_type = std::shared_ptr<SLE const>;
using value_type = SLE::const_pointer;
Dir(ReadView const&, Keylet const&);
@@ -102,7 +102,7 @@ private:
Keylet page_;
uint256 index_;
std::optional<value_type> mutable cache_;
std::shared_ptr<SLE const> sle_;
SLE::const_pointer sle_;
STVector256 const* indexes_ = nullptr;
std::vector<uint256>::const_iterator it_;
};

View File

@@ -24,7 +24,7 @@ struct CreateGenesisT
{
explicit CreateGenesisT() = default;
};
extern CreateGenesisT const kCREATE_GENESIS;
extern CreateGenesisT const kCreateGenesis;
/** Holds a ledger.
@@ -166,7 +166,7 @@ public:
std::optional<uint256>
succ(uint256 const& key, std::optional<uint256> const& last = std::nullopt) const override;
std::shared_ptr<SLE const>
SLE::const_pointer
read(Keylet const& k) const override;
std::unique_ptr<SlesType::iter_base>
@@ -202,16 +202,16 @@ public:
//
void
rawErase(std::shared_ptr<SLE> const& sle) override;
rawErase(SLE::ref sle) override;
void
rawInsert(std::shared_ptr<SLE> const& sle) override;
rawInsert(SLE::ref sle) override;
void
rawErase(uint256 const& key);
void
rawReplace(std::shared_ptr<SLE> const& sle) override;
rawReplace(SLE::ref sle) override;
void
rawDestroyXRP(XRPAmount const& fee) override
@@ -361,7 +361,7 @@ public:
bool
isVotingLedger() const;
std::shared_ptr<SLE>
SLE::pointer
peek(Keylet const& k) const;
private:

View File

@@ -12,7 +12,7 @@ namespace xrpl {
Values should not be duplicated.
@see getNextLedgerTimeResolution
*/
std::chrono::seconds constexpr kLEDGER_POSSIBLE_TIME_RESOLUTIONS[] = {
constexpr std::chrono::seconds kLedgerPossibleTimeResolutions[] = {
std::chrono::seconds{10},
std::chrono::seconds{20},
std::chrono::seconds{30},
@@ -21,16 +21,16 @@ std::chrono::seconds constexpr kLEDGER_POSSIBLE_TIME_RESOLUTIONS[] = {
std::chrono::seconds{120}};
//! Initial resolution of ledger close time.
auto constexpr kLEDGER_DEFAULT_TIME_RESOLUTION = kLEDGER_POSSIBLE_TIME_RESOLUTIONS[2];
constexpr auto kLedgerDefaultTimeResolution = kLedgerPossibleTimeResolutions[2];
//! Close time resolution in genesis ledger
auto constexpr kLEDGER_GENESIS_TIME_RESOLUTION = kLEDGER_POSSIBLE_TIME_RESOLUTIONS[0];
constexpr auto kLedgerGenesisTimeResolution = kLedgerPossibleTimeResolutions[0];
//! How often we increase the close time resolution (in numbers of ledgers)
auto constexpr kINCREASE_LEDGER_TIME_RESOLUTION_EVERY = 8;
constexpr auto kIncreaseLedgerTimeResolutionEvery = 8;
//! How often we decrease the close time resolution (in numbers of ledgers)
auto constexpr kDECREASE_LEDGER_TIME_RESOLUTION_EVERY = 1;
constexpr auto kDecreaseLedgerTimeResolutionEvery = 1;
/** Calculates the close time resolution for the specified ledger.
@@ -46,7 +46,7 @@ auto constexpr kDECREASE_LEDGER_TIME_RESOLUTION_EVERY = 1;
@param ledgerSeq the sequence number of the new ledger
@pre previousResolution must be a valid bin
from @ref kLEDGER_POSSIBLE_TIME_RESOLUTIONS
from @ref kLedgerPossibleTimeResolutions
@tparam Rep Type representing number of ticks in std::chrono::duration
@tparam Period An std::ratio representing tick period in
@@ -67,30 +67,30 @@ getNextLedgerTimeResolution(
using namespace std::chrono;
// Find the current resolution:
auto iter = std::find(
std::begin(kLEDGER_POSSIBLE_TIME_RESOLUTIONS),
std::end(kLEDGER_POSSIBLE_TIME_RESOLUTIONS),
std::begin(kLedgerPossibleTimeResolutions),
std::end(kLedgerPossibleTimeResolutions),
previousResolution);
XRPL_ASSERT(
iter != std::end(kLEDGER_POSSIBLE_TIME_RESOLUTIONS),
iter != std::end(kLedgerPossibleTimeResolutions),
"xrpl::getNextLedgerTimeResolution : found time resolution");
// This should never happen, but just as a precaution
if (iter == std::end(kLEDGER_POSSIBLE_TIME_RESOLUTIONS))
if (iter == std::end(kLedgerPossibleTimeResolutions))
return previousResolution;
// If we did not previously agree, we try to decrease the resolution to
// improve the chance that we will agree now.
if (!previousAgree && (ledgerSeq % Seq{kDECREASE_LEDGER_TIME_RESOLUTION_EVERY} == Seq{0}))
if (!previousAgree && (ledgerSeq % Seq{kDecreaseLedgerTimeResolutionEvery} == Seq{0}))
{
if (++iter != std::end(kLEDGER_POSSIBLE_TIME_RESOLUTIONS))
if (++iter != std::end(kLedgerPossibleTimeResolutions))
return *iter;
}
// If we previously agreed, we try to increase the resolution to determine
// if we can continue to agree.
if (previousAgree && (ledgerSeq % Seq{kINCREASE_LEDGER_TIME_RESOLUTION_EVERY} == Seq{0}))
if (previousAgree && (ledgerSeq % Seq{kIncreaseLedgerTimeResolutionEvery} == Seq{0}))
{
if (iter-- != std::begin(kLEDGER_POSSIBLE_TIME_RESOLUTIONS))
if (iter-- != std::begin(kLedgerPossibleTimeResolutions))
return *iter;
}

View File

@@ -23,7 +23,7 @@ namespace xrpl {
inline constexpr struct OpenLedgerT
{
explicit constexpr OpenLedgerT() = default;
} kOPEN_LEDGER{};
} kOpenLedger{};
/** Batch view construction tag.
@@ -33,7 +33,7 @@ inline constexpr struct OpenLedgerT
inline constexpr struct BatchViewT
{
explicit constexpr BatchViewT() = default;
} kBATCH_VIEW{};
} kBatchView{};
//------------------------------------------------------------------------------
@@ -47,7 +47,7 @@ private:
// Initial size for the monotonic_buffer_resource used for allocations
// The size was chosen from the old `qalloc` code (which this replaces).
// It is unclear how the size initially chosen in qalloc.
static constexpr size_t kINITIAL_BUFFER_SIZE = kilobytes(256);
static constexpr size_t kInitialBufferSize = kilobytes(256);
class TxsIterImpl;
@@ -76,7 +76,7 @@ private:
// monotonic_resource_ must outlive `items_`. Make a pointer so it may be
// easily moved.
std::unique_ptr<boost::container::pmr::monotonic_buffer_resource> monotonic_resource_;
std::unique_ptr<boost::container::pmr::monotonic_buffer_resource> monotonicResource_;
txs_map txs_;
Rules rules_;
LedgerHeader header_;
@@ -139,7 +139,7 @@ public:
std::shared_ptr<void const> hold = nullptr);
OpenView(OpenLedgerT, Rules const& rules, std::shared_ptr<ReadView const> const& base)
: OpenView(kOPEN_LEDGER, &*base, rules, base)
: OpenView(kOpenLedger, &*base, rules, base)
{
}
@@ -197,7 +197,7 @@ public:
std::optional<key_type>
succ(key_type const& key, std::optional<key_type> const& last = std::nullopt) const override;
std::shared_ptr<SLE const>
SLE::const_pointer
read(Keylet const& k) const override;
std::unique_ptr<SlesType::iter_base>
@@ -224,13 +224,13 @@ public:
// RawView
void
rawErase(std::shared_ptr<SLE> const& sle) override;
rawErase(SLE::ref sle) override;
void
rawInsert(std::shared_ptr<SLE> const& sle) override;
rawInsert(SLE::ref sle) override;
void
rawReplace(std::shared_ptr<SLE> const& sle) override;
rawReplace(SLE::ref sle) override;
void
rawDestroyXRP(XRPAmount const& fee) override;

View File

@@ -25,7 +25,7 @@ public:
can calculate metadata.
*/
virtual void
rawErase(std::shared_ptr<SLE> const& sle) = 0;
rawErase(SLE::ref sle) = 0;
/** Unconditionally insert a state item.
@@ -39,7 +39,7 @@ public:
@note The key is taken from the SLE
*/
virtual void
rawInsert(std::shared_ptr<SLE> const& sle) = 0;
rawInsert(SLE::ref sle) = 0;
/** Unconditionally replace a state item.
@@ -54,7 +54,7 @@ public:
@note The key is taken from the SLE
*/
virtual void
rawReplace(std::shared_ptr<SLE> const& sle) = 0;
rawReplace(SLE::ref sle) = 0;
/** Destroy XRP.

View File

@@ -34,9 +34,9 @@ public:
using key_type = uint256;
using mapped_type = std::shared_ptr<SLE const>;
using mapped_type = SLE::const_pointer;
struct SlesType : detail::ReadViewFwdRange<std::shared_ptr<SLE const>>
struct SlesType : detail::ReadViewFwdRange<SLE::const_pointer>
{
explicit SlesType(ReadView const& view);
[[nodiscard]] Iterator
@@ -143,7 +143,7 @@ public:
@return `nullptr` if the key is not present or
if the type does not match.
*/
[[nodiscard]] virtual std::shared_ptr<SLE const>
[[nodiscard]] virtual SLE::const_pointer
read(Keylet const& k) const = 0;
// Accounts in a payment are not allowed to use assets acquired during that

View File

@@ -12,7 +12,6 @@
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <utility>
@@ -57,7 +56,7 @@ isVaultPseudoAccountFrozen(
ReadView const& view,
AccountID const& account,
MPTIssue const& mptShare,
int depth);
std::uint8_t depth);
[[nodiscard]] bool
isLPTokenFrozen(
@@ -135,7 +134,7 @@ areCompatible(
dirLink(
ApplyView& view,
AccountID const& owner,
std::shared_ptr<SLE>& object,
SLE::pointer& object,
SF_UINT64 const& node = sfOwnerNode);
/** Checks that can withdraw funds from an object to itself or a destination.
@@ -215,8 +214,8 @@ doWithdraw(
* (if should not be skipped) and if the entry should be skipped. The status
* is always tesSUCCESS if the entry should be skipped.
*/
using EntryDeleter = std::function<
std::pair<TER, SkipEntry>(LedgerEntryType, uint256 const&, std::shared_ptr<SLE>&)>;
using EntryDeleter =
std::function<std::pair<TER, SkipEntry>(LedgerEntryType, uint256 const&, SLE::pointer&)>;
/** Cleanup owner directory entries on account delete.
* Used for a regular and AMM accounts deletion. The caller
* has to provide the deleter function, which handles details of

View File

@@ -8,8 +8,6 @@
#include <xrpl/protocol/TxMeta.h>
#include <xrpl/protocol/XRPAmount.h>
#include <memory>
namespace xrpl::detail {
// Helper class that buffers modifications
@@ -26,7 +24,7 @@ private:
Modify,
};
using items_t = std::map<key_type, std::pair<Action, std::shared_ptr<SLE>>>;
using items_t = std::map<key_type, std::pair<Action, SLE::pointer>>;
items_t items_;
XRPAmount dropsDestroyed_{0};
@@ -60,10 +58,10 @@ public:
[[nodiscard]] std::optional<key_type>
succ(ReadView const& base, key_type const& key, std::optional<key_type> const& last) const;
[[nodiscard]] std::shared_ptr<SLE const>
[[nodiscard]] SLE::const_pointer
read(ReadView const& base, Keylet const& k) const;
std::shared_ptr<SLE>
SLE::pointer
peek(ReadView const& base, Keylet const& k);
[[nodiscard]] std::size_t
@@ -75,23 +73,23 @@ public:
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;
SLE::const_ref before,
SLE::const_ref after)> const& func) const;
void
erase(ReadView const& base, std::shared_ptr<SLE> const& sle);
erase(ReadView const& base, SLE::ref sle);
void
rawErase(ReadView const& base, std::shared_ptr<SLE> const& sle);
rawErase(ReadView const& base, SLE::ref sle);
void
insert(ReadView const& base, std::shared_ptr<SLE> const& sle);
insert(ReadView const& base, SLE::ref sle);
void
update(ReadView const& base, std::shared_ptr<SLE> const& sle);
update(ReadView const& base, SLE::ref sle);
void
replace(ReadView const& base, std::shared_ptr<SLE> const& sle);
replace(ReadView const& base, SLE::ref sle);
void
destroyXRP(XRPAmount const& fee);
@@ -104,12 +102,12 @@ public:
}
private:
using Mods = hash_map<key_type, std::shared_ptr<SLE>>;
using Mods = hash_map<key_type, SLE::pointer>;
static void
threadItem(TxMeta& meta, std::shared_ptr<SLE> const& to);
threadItem(TxMeta& meta, SLE::ref to);
std::shared_ptr<SLE>
SLE::pointer
getForMod(ReadView const& base, key_type const& key, Mods& mods, beast::Journal j);
void
@@ -119,7 +117,7 @@ private:
threadOwners(
ReadView const& base,
TxMeta& meta,
std::shared_ptr<SLE const> const& sle,
SLE::const_ref sle,
Mods& mods,
beast::Journal j);
};

View File

@@ -40,7 +40,7 @@ public:
[[nodiscard]] std::optional<key_type>
succ(key_type const& key, std::optional<key_type> const& last = std::nullopt) const override;
[[nodiscard]] std::shared_ptr<SLE const>
[[nodiscard]] SLE::const_pointer
read(Keylet const& k) const override;
[[nodiscard]] std::unique_ptr<SlesType::iter_base>
@@ -69,28 +69,28 @@ public:
[[nodiscard]] ApplyFlags
flags() const override;
std::shared_ptr<SLE>
SLE::pointer
peek(Keylet const& k) override;
void
erase(std::shared_ptr<SLE> const& sle) override;
erase(SLE::ref sle) override;
void
insert(std::shared_ptr<SLE> const& sle) override;
insert(SLE::ref sle) override;
void
update(std::shared_ptr<SLE> const& sle) override;
update(SLE::ref sle) override;
// RawView
void
rawErase(std::shared_ptr<SLE> const& sle) override;
rawErase(SLE::ref sle) override;
void
rawInsert(std::shared_ptr<SLE> const& sle) override;
rawInsert(SLE::ref sle) override;
void
rawReplace(std::shared_ptr<SLE> const& sle) override;
rawReplace(SLE::ref sle) override;
void
rawDestroyXRP(XRPAmount const& feeDrops) override;

View File

@@ -19,17 +19,17 @@ public:
// Initial size for the monotonic_buffer_resource used for allocations
// The size was chosen from the old `qalloc` code (which this replaces).
// It is unclear how the size initially chosen in qalloc.
static constexpr size_t kINITIAL_BUFFER_SIZE = kilobytes(256);
static constexpr size_t kInitialBufferSize = kilobytes(256);
RawStateTable()
: monotonic_resource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
kINITIAL_BUFFER_SIZE)}
, items_{monotonic_resource_.get()} {};
: monotonicResource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
kInitialBufferSize)}
, items_{monotonicResource_.get()} {};
RawStateTable(RawStateTable const& rhs)
: monotonic_resource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
kINITIAL_BUFFER_SIZE)}
, items_{rhs.items_, monotonic_resource_.get()}
: monotonicResource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
kInitialBufferSize)}
, items_{rhs.items_, monotonicResource_.get()}
, dropsDestroyed_{rhs.dropsDestroyed_} {};
RawStateTable(RawStateTable&&) = default;
@@ -49,15 +49,15 @@ public:
succ(ReadView const& base, key_type const& key, std::optional<key_type> const& last) const;
void
erase(std::shared_ptr<SLE> const& sle);
erase(SLE::ref sle);
void
insert(std::shared_ptr<SLE> const& sle);
insert(SLE::ref sle);
void
replace(std::shared_ptr<SLE> const& sle);
replace(SLE::ref sle);
[[nodiscard]] std::shared_ptr<SLE const>
[[nodiscard]] SLE::const_pointer
read(ReadView const& base, Keylet const& k) const;
void
@@ -84,10 +84,10 @@ private:
struct SleAction
{
Action action;
std::shared_ptr<SLE> sle;
SLE::pointer sle;
// Constructor needed for emplacement in std::map
SleAction(Action action, std::shared_ptr<SLE> const& sle) : action(action), sle(sle)
SleAction(Action action, SLE::pointer sle) : action(action), sle(std::move(sle))
{
}
};
@@ -101,7 +101,7 @@ private:
boost::container::pmr::polymorphic_allocator<std::pair<key_type const, SleAction>>>;
// monotonic_resource_ must outlive `items_`. Make a pointer so it may be
// easily moved.
std::unique_ptr<boost::container::pmr::monotonic_buffer_resource> monotonic_resource_;
std::unique_ptr<boost::container::pmr::monotonic_buffer_resource> monotonicResource_;
items_t items_;
XRPAmount dropsDestroyed_{0};

View File

@@ -25,11 +25,11 @@ namespace detail {
Number
reduceOffer(auto const& amount)
{
static Number const kREDUCED_OFFER_PCT(9999, -4);
static Number const kReducedOfferPct(9999, -4);
// Make sure the result is always less than amount or zero.
NumberRoundModeGuard const mg(Number::RoundingMode::TowardsZero);
return amount * kREDUCED_OFFER_PCT;
return amount * kReducedOfferPct;
}
} // namespace detail
@@ -177,7 +177,7 @@ getAMMOfferStartWithTakerGets(
Quality const& targetQuality,
std::uint16_t const& tfee)
{
if (targetQuality.rate() == beast::kZERO)
if (targetQuality.rate() == beast::kZero)
return std::nullopt;
NumberRoundModeGuard const mg(Number::RoundingMode::ToNearest);
@@ -244,7 +244,7 @@ getAMMOfferStartWithTakerPays(
Quality const& targetQuality,
std::uint16_t tfee)
{
if (targetQuality.rate() == beast::kZERO)
if (targetQuality.rate() == beast::kZero)
return std::nullopt;
NumberRoundModeGuard const mg(Number::RoundingMode::ToNearest);
@@ -792,7 +792,7 @@ deleteAMMAccount(Sandbox& view, Asset const& asset, Asset const& asset2, beast::
void
initializeFeeAuctionVote(
ApplyView& view,
std::shared_ptr<SLE>& ammSle,
SLE::pointer& ammSle,
AccountID const& account,
Asset const& lptAsset,
std::uint16_t tfee);
@@ -812,7 +812,7 @@ Expected<bool, TER>
verifyAndAdjustLPTokenBalance(
Sandbox& sb,
STAmount const& lpTokens,
std::shared_ptr<SLE>& ammSle,
SLE::pointer& ammSle,
AccountID const& account);
} // namespace xrpl

View File

@@ -9,7 +9,6 @@
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/TER.h>
#include <memory>
#include <set>
#include <vector>
@@ -36,11 +35,7 @@ xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj,
/** Adjust the owner count up or down. */
void
adjustOwnerCount(
ApplyView& view,
std::shared_ptr<SLE> const& sle,
std::int32_t amount,
beast::Journal j);
adjustOwnerCount(ApplyView& view, SLE::ref sle, std::int32_t amount, beast::Journal j);
/** Returns IOU issuer transfer fee as Rate. Rate specifies
* the fee as fractions of 1 billion. For example, 1% transfer rate
@@ -76,9 +71,7 @@ getPseudoAccountFields();
- null pointer
*/
[[nodiscard]] bool
isPseudoAccount(
std::shared_ptr<SLE const> sleAcct,
std::set<SField const*> const& pseudoFieldFilter = {});
isPseudoAccount(SLE::const_pointer sleAcct, std::set<SField const*> const& pseudoFieldFilter = {});
/** Convenience overload that reads the account from the view. */
[[nodiscard]] inline bool
@@ -98,7 +91,7 @@ isPseudoAccount(
* before using a field. The amendment check is **not** performed in
* createPseudoAccount.
*/
[[nodiscard]] Expected<std::shared_ptr<SLE>, TER>
[[nodiscard]] Expected<SLE::pointer, TER>
createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const& ownerField);
/** Checks the destination and tag.

View File

@@ -19,15 +19,11 @@ namespace credentials {
// Check if credential sfExpiration field has passed ledger's parentCloseTime
bool
checkExpired(std::shared_ptr<SLE const> const& sleCredential, NetClock::time_point const& closed);
// Return true if any expired credential was found in arr (and deleted)
bool
removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j);
checkExpired(SLE const& sleCredential, NetClock::time_point const& closed);
// Actually remove a credentials object from the ledger
TER
deleteSLE(ApplyView& view, std::shared_ptr<SLE> const& sleCredential, beast::Journal j);
[[nodiscard]] TER
deleteSLE(ApplyView& view, SLE::ref sleCredential, beast::Journal j);
// Amendment and parameters checks for sfCredentialIDs field
NotTEC
@@ -88,7 +84,7 @@ verifyDepositPreauth(
ApplyView& view,
AccountID const& src,
AccountID const& dst,
std::shared_ptr<SLE const> const& sleDst,
SLE::const_ref sleDst,
beast::Journal j);
} // namespace xrpl

View File

@@ -15,7 +15,7 @@ namespace xrpl {
* if not.
*/
NotTEC
checkTxPermission(std::shared_ptr<SLE const> const& delegate, STTx const& tx);
checkTxPermission(SLE::const_ref delegate, STTx const& tx);
/**
* Load the granular permissions granted to the delegate account for the
@@ -28,7 +28,7 @@ checkTxPermission(std::shared_ptr<SLE const> const& delegate, STTx const& tx);
*/
void
loadGranularPermission(
std::shared_ptr<SLE const> const& delegate,
SLE::const_ref delegate,
TxType const& type,
std::unordered_set<GranularPermissionType>& granularPermissions);

View File

@@ -115,7 +115,7 @@ bool
cdirFirst(
ReadView const& view,
uint256 const& root,
std::shared_ptr<SLE const>& page,
SLE::const_pointer& page,
unsigned int& index,
uint256& entry);
@@ -123,7 +123,7 @@ bool
dirFirst(
ApplyView& view,
uint256 const& root,
std::shared_ptr<SLE>& page,
SLE::pointer& page,
unsigned int& index,
uint256& entry);
/** @} */
@@ -147,7 +147,7 @@ bool
cdirNext(
ReadView const& view,
uint256 const& root,
std::shared_ptr<SLE const>& page,
SLE::const_pointer& page,
unsigned int& index,
uint256& entry);
@@ -155,17 +155,14 @@ bool
dirNext(
ApplyView& view,
uint256 const& root,
std::shared_ptr<SLE>& page,
SLE::pointer& page,
unsigned int& index,
uint256& entry);
/** @} */
/** Iterate all items in the given directory. */
void
forEachItem(
ReadView const& view,
Keylet const& root,
std::function<void(std::shared_ptr<SLE const> const&)> const& f);
forEachItem(ReadView const& view, Keylet const& root, std::function<void(SLE::const_ref)> const& f);
/** Iterate all items after an item in the given directory.
@param after The key of the item to start after
@@ -180,14 +177,11 @@ forEachItemAfter(
uint256 const& after,
std::uint64_t const hint,
unsigned int limit,
std::function<bool(std::shared_ptr<SLE const> const&)> const& f);
std::function<bool(SLE::const_ref)> const& f);
/** Iterate all items in an account's owner directory. */
inline void
forEachItem(
ReadView const& view,
AccountID const& id,
std::function<void(std::shared_ptr<SLE const> const&)> const& f)
forEachItem(ReadView const& view, AccountID const& id, std::function<void(SLE::const_ref)> const& f)
{
forEachItem(view, keylet::ownerDir(id), f);
}
@@ -205,7 +199,7 @@ forEachItemAfter(
uint256 const& after,
std::uint64_t const hint,
unsigned int limit,
std::function<bool(std::shared_ptr<SLE const> const&)> const& f)
std::function<bool(SLE::const_ref)> const& f)
{
return forEachItemAfter(view, keylet::ownerDir(id), after, hint, limit, f);
}

View File

@@ -18,7 +18,7 @@ TER
escrowUnlockApplyHelper(
ApplyView& view,
Rate lockedRate,
std::shared_ptr<SLE> const& sleDest,
SLE::ref sleDest,
STAmount const& xrpBalance,
STAmount const& amount,
AccountID const& issuer,
@@ -32,7 +32,7 @@ inline TER
escrowUnlockApplyHelper<Issue>(
ApplyView& view,
Rate lockedRate,
std::shared_ptr<SLE> const& sleDest,
SLE::ref sleDest,
STAmount const& xrpBalance,
STAmount const& amount,
AccountID const& issuer,
@@ -70,21 +70,21 @@ escrowUnlockApplyHelper<Issue>(
initialBalance.get<Issue>().account = noAccount();
if (TER const ter = trustCreate(
view, // payment sandbox
recvLow, // is dest low?
issuer, // source
receiver, // destination
trustLineKey.key, // ledger index
sleDest, // Account to add to
false, // authorize account
(sleDest->getFlags() & lsfDefaultRipple) == 0, //
false, // freeze trust line
false, // deep freeze trust line
initialBalance, // zero initial balance
Issue(currency, receiver), // limit of zero
0, // quality in
0, // quality out
journal); // journal
view, // payment sandbox
recvLow, // is dest low?
issuer, // source
receiver, // destination
trustLineKey.key, // ledger index
sleDest, // Account to add to
false, // authorize account
!sleDest->isFlag(lsfDefaultRipple), //
false, // freeze trust line
false, // deep freeze trust line
initialBalance, // zero initial balance
Issue(currency, receiver), // limit of zero
0, // quality in
0, // quality out
journal); // journal
!isTesSuccess(ter))
{
return ter; // LCOV_EXCL_LINE
@@ -111,7 +111,7 @@ escrowUnlockApplyHelper<Issue>(
// whereas in a normal payment, the transfer fee is taken on top of the
// sending amount.
auto finalAmt = amount;
if ((!senderIssuer && !receiverIssuer) && lockedRate != kPARITY_RATE)
if ((!senderIssuer && !receiverIssuer) && lockedRate != kParityRate)
{
// compute transfer fee, if any
auto const xferFee =
@@ -162,7 +162,7 @@ inline TER
escrowUnlockApplyHelper<MPTIssue>(
ApplyView& view,
Rate lockedRate,
std::shared_ptr<SLE> const& sleDest,
SLE::ref sleDest,
STAmount const& xrpBalance,
STAmount const& amount,
AccountID const& issuer,
@@ -211,7 +211,7 @@ escrowUnlockApplyHelper<MPTIssue>(
// whereas in a normal payment, the transfer fee is taken on top of the
// sending amount.
auto finalAmt = amount;
if ((!senderIssuer && !receiverIssuer) && lockedRate != kPARITY_RATE)
if ((!senderIssuer && !receiverIssuer) && lockedRate != kParityRate)
{
// compute transfer fee, if any
auto const xferFee = amount.value() - divideRound(amount, lockedRate, amount.asset(), true);

View File

@@ -4,13 +4,43 @@
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/st.h>
#include <string_view>
namespace xrpl {
/**
* Broker cover preclaim precision guard (fixCleanup3_2_0).
*
* Prevents a "silent sub-ULP no-op" where a deposit, withdrawal, or clawback
* amount is so small that it rounds to zero at `sfCoverAvailable`'s scale.
* Without this guard, both the pseudo trust-line and `sfCoverAvailable` would
* identically absorb the rounded zero, resulting in a successful transaction
* (tesSUCCESS) where no funds actually moved.
*
* @param view Read view (rules used for amendment gating).
* @param sleBroker The loan broker SLE (read-only).
* @param vaultAsset The underlying vault asset (the broker's cover asset).
* @param amount The effective subtraction/addition amount.
* @param j Journal for logging.
* @param logPrefix Transactor name for log diagnostics.
*
* @return `tecPRECISION_LOSS` if the request rounds to zero at cover scale.
* `tesSUCCESS` if the amendment is disabled or the request is safely supra-ULP.
*/
[[nodiscard]] TER
canApplyToBrokerCover(
ReadView const& view,
SLE::const_ref sleBroker,
Asset const& vaultAsset,
STAmount const& amount,
beast::Journal j,
std::string_view logPrefix);
// Lending protocol has dependencies, so capture them here.
bool
checkLendingProtocolDependencies(Rules const& rules, STTx const& tx);
static constexpr std::uint32_t kSECONDS_IN_YEAR = 365 * 24 * 60 * 60;
static constexpr std::uint32_t kSecondsInYear = 365 * 24 * 60 * 60;
Number
loanPeriodicRate(TenthBips32 interestRate, std::uint32_t paymentInterval);
@@ -42,14 +72,14 @@ struct LoanPaymentParts
// The amount of principal paid that reduces the loan balance.
// This amount is subtracted from sfPrincipalOutstanding in the Loan object
// and paid to the Vault
Number principalPaid = kNUM_ZERO;
Number principalPaid = kNumZero;
// The total amount of interest paid to the Vault.
// This includes:
// - Tracked interest from the amortization schedule
// - Untracked interest (e.g., late payment penalty interest)
// This value is always non-negative.
Number interestPaid = kNUM_ZERO;
Number interestPaid = kNumZero;
// The change in the loan's total value outstanding.
// - If valueChange < 0: Loan value decreased
@@ -62,7 +92,7 @@ struct LoanPaymentParts
// - Late payments add penalty interest to the loan value
// - Early full payment may increase or decrease the loan value based on
// terms
Number valueChange = kNUM_ZERO;
Number valueChange = kNumZero;
/* The total amount of fees paid to the Broker.
* This includes:
@@ -70,7 +100,7 @@ struct LoanPaymentParts
* - Untracked fees (e.g., late payment fees, service fees, origination
* fees) This value is always non-negative.
*/
Number feePaid = kNUM_ZERO;
Number feePaid = kNumZero;
LoanPaymentParts&
operator+=(LoanPaymentParts const& other);
@@ -161,7 +191,7 @@ adjustImpreciseNumber(
{
value = roundToAsset(asset, value + adjustment, vaultScale);
if (*value < beast::kZERO)
if (*value < beast::kZero)
value = 0;
}
@@ -169,10 +199,25 @@ inline int
getAssetsTotalScale(SLE::const_ref vaultSle)
{
if (!vaultSle)
return Number::kMIN_EXPONENT - 1; // LCOV_EXCL_LINE
return Number::kMinExponent - 1; // LCOV_EXCL_LINE
return scale(vaultSle->at(sfAssetsTotal), vaultSle->at(sfAsset));
}
// Compute the minimum required broker cover, rounded consistently.
// DebtTotal is a broker-level aggregate maintained at vault scale, so the
// rounding must also use vault scale — never an individual loan's scale.
inline Number
minimumBrokerCover(Number const& debtTotal, TenthBips32 coverRateMinimum, SLE::const_ref vaultSle)
{
XRPL_ASSERT(
vaultSle && vaultSle->getType() == ltVAULT, "xrpl::minimumBrokerCover : valid Vault sle");
NumberRoundModeGuard const mg(Number::RoundingMode::Upward);
return roundToAsset(
vaultSle->at(sfAsset),
tenthBipsOfValue(debtTotal, coverRateMinimum),
getAssetsTotalScale(vaultSle));
}
TER
checkLoanGuards(
Asset const& vaultAsset,
@@ -184,6 +229,7 @@ checkLoanGuards(
LoanState
computeTheoreticalLoanState(
Rules const& rules,
Number const& periodicPayment,
Number const& periodicRate,
std::uint32_t const paymentRemaining,
@@ -310,7 +356,7 @@ struct ExtendedPaymentComponents : public PaymentComponents
// borrower is sufficient to cover all components of the payment.
Number totalDue;
ExtendedPaymentComponents(PaymentComponents const& p, Number fee, Number interest = kNUM_ZERO)
ExtendedPaymentComponents(PaymentComponents const& p, Number fee, Number interest = kNumZero)
: PaymentComponents(p)
, untrackedManagementFee(fee)
, untrackedInterest(interest)
@@ -353,6 +399,7 @@ struct LoanStateDeltas
Expected<std::pair<LoanPaymentParts, LoanProperties>, TER>
tryOverpayment(
Rules const& rules,
Asset const& asset,
std::int32_t loanScale,
ExtendedPaymentComponents const& overpaymentComponents,
@@ -363,11 +410,17 @@ tryOverpayment(
TenthBips16 const managementFeeRate,
beast::Journal j);
Number
computeRaisedRate(Number const& periodicRate, std::uint32_t paymentsRemaining);
[[nodiscard]] Number
computePowerMinusOne(Number const& periodicRate, std::uint32_t paymentsRemaining);
Number
computePaymentFactor(Number const& periodicRate, std::uint32_t paymentsRemaining);
[[nodiscard]] Number
computePowerMinusOneHybrid(Number const& periodicRate, std::uint32_t paymentsRemaining);
[[nodiscard]] Number
computePaymentFactor(
Rules const& rules,
Number const& periodicRate,
std::uint32_t paymentsRemaining);
std::pair<Number, Number>
computeInterestAndFeeParts(
@@ -378,12 +431,14 @@ computeInterestAndFeeParts(
Number
loanPeriodicPayment(
Rules const& rules,
Number const& principalOutstanding,
Number const& periodicRate,
std::uint32_t paymentsRemaining);
Number
loanPrincipalFromPeriodicPayment(
Rules const& rules,
Number const& periodicPayment,
Number const& periodicRate,
std::uint32_t paymentsRemaining);
@@ -406,6 +461,7 @@ loanAccruedInterest(
ExtendedPaymentComponents
computeOverpaymentComponents(
Rules const& rules,
Asset const& asset,
int32_t const loanScale,
Number const& overpayment,
@@ -415,6 +471,7 @@ computeOverpaymentComponents(
PaymentComponents
computePaymentComponents(
Rules const& rules,
Asset const& asset,
std::int32_t scale,
Number const& totalValueOutstanding,
@@ -438,6 +495,7 @@ operator+(LoanState const& lhs, detail::LoanStateDeltas const& rhs);
LoanProperties
computeLoanProperties(
Rules const& rules,
Asset const& asset,
Number const& principalOutstanding,
TenthBips32 interestRate,
@@ -448,6 +506,7 @@ computeLoanProperties(
LoanProperties
computeLoanProperties(
Rules const& rules,
Asset const& asset,
Number const& principalOutstanding,
Number const& periodicRate,

View File

@@ -27,14 +27,18 @@ isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue);
isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue);
[[nodiscard]] bool
isFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue, int depth = 0);
isFrozen(
ReadView const& view,
AccountID const& account,
MPTIssue const& mptIssue,
std::uint8_t depth = 0);
[[nodiscard]] bool
isAnyFrozen(
ReadView const& view,
std::initializer_list<AccountID> const& accounts,
MPTIssue const& mptIssue,
int depth = 0);
std::uint8_t depth = 0);
//------------------------------------------------------------------------------
//
@@ -88,7 +92,7 @@ requireAuth(
MPTIssue const& mptIssue,
AccountID const& account,
AuthType authType = AuthType::Legacy,
int depth = 0);
std::uint8_t depth = 0);
/** Enforce account has MPToken to match its authorization.
*
@@ -104,22 +108,77 @@ enforceMPTokenAuthorization(
XRPAmount const& priorBalance,
beast::Journal j);
/** Check if the destination account is allowed
* to receive MPT. Return tecNO_AUTH if it doesn't
* and tesSUCCESS otherwise.
/** Resolve the underlying asset of a vault share.
*
* Reads sfReferenceHolding from @p sleShareIssuance to determine which
* asset the vault wraps. @p sleHolding must be the SLE that
* sfReferenceHolding points to — either an ltMPTOKEN (returns its
* MPTIssue) or an ltRIPPLE_STATE (returns its low/high Issue).
*
* @pre Both SLEs must exist and @p sleHolding must be of type ltMPTOKEN
* or ltRIPPLE_STATE. Passing any other type is undefined behaviour.
* @param sleShareIssuance MPTokenIssuance SLE for the vault share token.
* @param sleHolding SLE referenced by sfReferenceHolding.
* @return The underlying Asset (MPTIssue or Issue).
*/
[[nodiscard]] Asset
assetOfHolding(SLE const& sleShareIssuance, SLE const& sleHolding);
/** Check whether @p to may receive the given MPT from @p from.
*
* The check passes when any of the following is true:
* - @p waive is WaiveMPTCanTransfer::Yes (recovery-path exemption), or
* - @p from or @p to is the issuer, or
* - lsfMPTCanTransfer is set on the MPTokenIssuance.
*
* For vault shares (MPTokenIssuances that carry sfReferenceHolding) the
* check recurses into the underlying asset's transferability. This
* recursion is defensive; vault-of-vault-shares is rejected at vault
* creation, so in practice depth never exceeds 1.
*
* @param view Ledger state to read from.
* @param mptIssue The MPT issuance being transferred.
* @param from Sending account.
* @param to Receiving account.
* @param waive WaiveMPTCanTransfer::Yes skips the lsfMPTCanTransfer
* check. Use for recovery paths (e.g. unwinding SAV or
* Lending Protocol positions after an issuer revokes
* transferability).
* @param depth Recursion depth; bounded at kMaxAssetCheckDepth.
* @return tesSUCCESS if the transfer is allowed, tecNO_AUTH otherwise.
*/
[[nodiscard]] TER
canTransfer(
ReadView const& view,
MPTIssue const& mptIssue,
AccountID const& from,
AccountID const& to);
AccountID const& to,
WaiveMPTCanTransfer waive = WaiveMPTCanTransfer::No,
std::uint8_t depth = 0);
/** Check if Asset can be traded on DEX. return tecNO_PERMISSION
* if it doesn't and tesSUCCESS otherwise.
/** Check whether @p asset may be traded on the DEX.
*
* For IOU assets the check delegates to the existing offer/AMM freeze
* logic. For MPT assets it checks lsfMPTCanTrade on the MPTokenIssuance.
* Vault shares recurse into the underlying asset's tradability via
* sfReferenceHolding; depth is bounded at kMaxAssetCheckDepth.
*
* @param view Ledger state to read from.
* @param asset The asset to check.
* @param depth Recursion depth; bounded at kMaxAssetCheckDepth.
* @return tesSUCCESS if trading is allowed, tecNO_PERMISSION otherwise.
*/
[[nodiscard]] TER
canTrade(ReadView const& view, Asset const& asset);
canTrade(ReadView const& view, Asset const& asset, std::uint8_t depth = 0);
/** Convenience to combine canTrade/Transfer. Returns tesSUCCESS if Asset is Issue.
*/
[[nodiscard]] TER
canMPTTradeAndTransfer(
ReadView const& v,
Asset const& asset,
AccountID const& from,
AccountID const& to);
//------------------------------------------------------------------------------
//
@@ -227,17 +286,4 @@ issuerFundsToSelfIssue(ReadView const& view, MPTIssue const& issue);
void
issuerSelfDebitHookMPT(ApplyView& view, MPTIssue const& issue, std::uint64_t amount);
//------------------------------------------------------------------------------
//
// MPT DEX
//
//------------------------------------------------------------------------------
/* Return true if a transaction is allowed for the specified MPT/account. The
* function checks MPTokenIssuance and MPToken objects flags to determine if the
* transaction is allowed.
*/
TER
checkMPTTxAllowed(ReadView const& v, TxType tx, Asset const& asset, AccountID const& accountID);
} // namespace xrpl

View File

@@ -28,10 +28,9 @@ findToken(ReadView const& view, AccountID const& owner, uint256 const& nftokenID
struct TokenAndPage
{
STObject token;
std::shared_ptr<SLE> page;
SLE::pointer page;
TokenAndPage(STObject token, std::shared_ptr<SLE> page)
: token(std::move(token)), page(std::move(page))
TokenAndPage(STObject token, SLE::pointer page) : token(std::move(token)), page(std::move(page))
{
}
};
@@ -47,11 +46,7 @@ TER
removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID);
TER
removeToken(
ApplyView& view,
AccountID const& owner,
uint256 const& nftokenID,
std::shared_ptr<SLE> const& page);
removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID, SLE::ref page);
/** Deletes the given token offer.
@@ -63,7 +58,7 @@ removeToken(
The offer also consumes one incremental reserve.
*/
bool
deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer);
deleteTokenOffer(ApplyView& view, SLE::ref offer);
/** Repairs the links in an NFTokenPage directory.

View File

@@ -5,8 +5,6 @@
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/TER.h>
#include <memory>
namespace xrpl {
/** Delete an offer.
@@ -23,6 +21,6 @@ namespace xrpl {
*/
// [[nodiscard]] // nodiscard commented out so Flow, BookTip and others compile.
TER
offerDelete(ApplyView& view, std::shared_ptr<SLE> const& sle, beast::Journal j);
offerDelete(ApplyView& view, SLE::ref sle, beast::Journal j);
} // namespace xrpl

View File

@@ -8,10 +8,6 @@
namespace xrpl {
TER
closeChannel(
std::shared_ptr<SLE> const& slep,
ApplyView& view,
uint256 const& key,
beast::Journal j);
closeChannel(SLE::ref slep, ApplyView& view, uint256 const& key, beast::Journal j);
} // namespace xrpl

View File

@@ -93,7 +93,7 @@ isFrozen(ReadView const& view, AccountID const& account, Issue const& issue)
// Overload with depth parameter for uniformity with MPTIssue version.
// The depth parameter is ignored for IOUs since they don't have vault recursion.
[[nodiscard]] inline bool
isFrozen(ReadView const& view, AccountID const& account, Issue const& issue, int /*depth*/)
isFrozen(ReadView const& view, AccountID const& account, Issue const& issue, std::uint8_t /*depth*/)
{
return isFrozen(view, account, issue);
}
@@ -110,7 +110,7 @@ isDeepFrozen(
ReadView const& view,
AccountID const& account,
Issue const& issue,
int = 0 /*ignored*/)
std::uint8_t = 0 /*ignored*/)
{
return isDeepFrozen(view, account, issue.currency, issue.account);
}
@@ -154,7 +154,7 @@ trustCreate(
[[nodiscard]] TER
trustDelete(
ApplyView& view,
std::shared_ptr<SLE> const& sleRippleState,
SLE::ref sleRippleState,
AccountID const& uLowAccountID,
AccountID const& uHighAccountID,
beast::Journal j);
@@ -248,7 +248,7 @@ removeEmptyHolding(
[[nodiscard]] TER
deleteAMMTrustLine(
ApplyView& view,
std::shared_ptr<SLE> sleState,
SLE::pointer sleState,
std::optional<AccountID> const& ammAccountID,
beast::Journal j);
@@ -258,7 +258,7 @@ deleteAMMTrustLine(
[[nodiscard]] TER
deleteAMMMPToken(
ApplyView& view,
std::shared_ptr<SLE> sleMPT,
SLE::pointer sleMPT,
AccountID const& ammAccountID,
beast::Journal j);

View File

@@ -34,6 +34,15 @@ enum class WaiveTransferFee : bool { No = false, Yes };
/** Controls whether accountSend is allowed to overflow OutstandingAmount **/
enum class AllowMPTOverflow : bool { No = false, Yes };
/** Controls whether canTransfer enforces lsfMPTCanTransfer on MPTs.
*
* Default is No (enforce). Use Yes at call sites that must remain available
* even when an MPT issuer has cleared lsfMPTCanTransfer - for example,
* unwinding existing positions in SAV or the Lending Protocol. Has no
* effect on the IOU branch of canTransfer.
*/
enum class WaiveMPTCanTransfer : bool { No = false, Yes };
/* Check if MPToken (for MPT) or trust line (for IOU) exists:
* - StrongAuth - before checking if authorization is required
* - WeakAuth
@@ -54,16 +63,26 @@ enum class AuthType { StrongAuth, WeakAuth, Legacy };
[[nodiscard]] bool
isGlobalFrozen(ReadView const& view, Asset const& asset);
[[nodiscard]] TER
checkGlobalFrozen(ReadView const& view, Asset const& asset);
[[nodiscard]] bool
isIndividualFrozen(ReadView const& view, AccountID const& account, Asset const& asset);
[[nodiscard]] TER
checkIndividualFrozen(ReadView const& view, AccountID const& account, Asset const& asset);
/**
* isFrozen check is recursive for MPT shares in a vault, descending to
* assets in the vault, up to maxAssetCheckDepth recursion depth. This is
* purely defensive, as we currently do not allow such vaults to be created.
*/
[[nodiscard]] bool
isFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth = 0);
isFrozen(
ReadView const& view,
AccountID const& account,
Asset const& asset,
std::uint8_t depth = 0);
[[nodiscard]] TER
checkFrozen(ReadView const& view, AccountID const& account, Issue const& issue);
@@ -85,14 +104,14 @@ isAnyFrozen(
ReadView const& view,
std::initializer_list<AccountID> const& accounts,
Asset const& asset,
int depth = 0);
std::uint8_t depth = 0);
[[nodiscard]] bool
isDeepFrozen(
ReadView const& view,
AccountID const& account,
MPTIssue const& mptIssue,
int depth = 0);
std::uint8_t depth = 0);
/**
* isFrozen check is recursive for MPT shares in a vault, descending to
@@ -100,7 +119,11 @@ isDeepFrozen(
* purely defensive, as we currently do not allow such vaults to be created.
*/
[[nodiscard]] bool
isDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth = 0);
isDeepFrozen(
ReadView const& view,
AccountID const& account,
Asset const& asset,
std::uint8_t depth = 0);
[[nodiscard]] TER
checkDeepFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue);
@@ -234,7 +257,13 @@ requireAuth(
AuthType authType = AuthType::Legacy);
[[nodiscard]] TER
canTransfer(ReadView const& view, Asset const& asset, AccountID const& from, AccountID const& to);
canTransfer(
ReadView const& view,
Asset const& asset,
AccountID const& from,
AccountID const& to,
WaiveMPTCanTransfer waive = WaiveMPTCanTransfer::No,
std::uint8_t depth = 0);
//------------------------------------------------------------------------------
//

View File

@@ -1,9 +1,10 @@
#pragma once
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <memory>
#include <optional>
namespace xrpl {
@@ -19,10 +20,7 @@ namespace xrpl {
@return The number of shares, or nullopt on error.
*/
[[nodiscard]] std::optional<STAmount>
assetsToSharesDeposit(
std::shared_ptr<SLE const> const& vault,
std::shared_ptr<SLE const> const& issuance,
STAmount const& assets);
assetsToSharesDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const& assets);
/** From the perspective of a vault, return the number of assets to take from
depositor when they receive a fixed amount of shares. Note, since shares are
@@ -35,14 +33,19 @@ assetsToSharesDeposit(
@return The number of assets, or nullopt on error.
*/
[[nodiscard]] std::optional<STAmount>
sharesToAssetsDeposit(
std::shared_ptr<SLE const> const& vault,
std::shared_ptr<SLE const> const& issuance,
STAmount const& shares);
sharesToAssetsDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const& shares);
/** Controls whether to truncate shares instead of rounding. */
enum class TruncateShares : bool { No = false, Yes = true };
/** Controls whether the withdraw conversion helpers
(assetsToSharesWithdraw and sharesToAssetsWithdraw) subtract
sfLossUnrealized from sfAssetsTotal before computing the exchange rate.
The default (No) applies the standard discounted rate; Yes is used when
the redeemer is the sole remaining shareholder.
*/
enum class WaiveUnrealizedLoss : bool { No = false, Yes = true };
/** From the perspective of a vault, return the number of shares to demand from
the depositor when they ask to withdraw a fixed amount of assets. Since
shares are MPT this number is integral, and it will be rounded to nearest
@@ -52,15 +55,18 @@ enum class TruncateShares : bool { No = false, Yes = true };
@param issuance The MPTokenIssuance SLE for the vault's shares.
@param assets The amount of assets to convert.
@param truncate Whether to truncate instead of rounding.
@param waive Whether to waive the unrealized-loss discount when computing
the exchange rate.
@return The number of shares, or nullopt on error.
*/
[[nodiscard]] std::optional<STAmount>
assetsToSharesWithdraw(
std::shared_ptr<SLE const> const& vault,
std::shared_ptr<SLE const> const& issuance,
SLE::const_ref vault,
SLE::const_ref issuance,
STAmount const& assets,
TruncateShares truncate = TruncateShares::No);
TruncateShares truncate = TruncateShares::No,
WaiveUnrealizedLoss waive = WaiveUnrealizedLoss::No);
/** From the perspective of a vault, return the number of assets to give the
depositor when they redeem a fixed amount of shares. Note, since shares are
@@ -69,13 +75,28 @@ assetsToSharesWithdraw(
@param vault The vault SLE.
@param issuance The MPTokenIssuance SLE for the vault's shares.
@param shares The amount of shares to convert.
@param waive Whether to waive (i.e. not subtract) the vault's unrealized
loss when computing the exchange rate.
@return The number of assets, or nullopt on error.
*/
[[nodiscard]] std::optional<STAmount>
sharesToAssetsWithdraw(
std::shared_ptr<SLE const> const& vault,
std::shared_ptr<SLE const> const& issuance,
STAmount const& shares);
SLE::const_ref vault,
SLE::const_ref issuance,
STAmount const& shares,
WaiveUnrealizedLoss waive = WaiveUnrealizedLoss::No);
/** Returns true iff `account` holds all of the vault's outstanding shares —
i.e. is the sole remaining shareholder. Returns false if the account
holds no shares or fewer than the total outstanding.
@param view The ledger view.
@param account The candidate sole shareholder.
@param issuance The MPTokenIssuance SLE for the vault's shares; provides
both the share MPTID and the outstanding-amount total.
*/
[[nodiscard]] bool
isSoleShareholder(ReadView const& view, AccountID const& account, SLE::const_ref issuance);
} // namespace xrpl

View File

@@ -20,7 +20,7 @@ class HTTPClient
public:
explicit HTTPClient() = default;
static constexpr auto kMAX_CLIENT_HEADER_BYTES = kilobytes(32);
static constexpr auto kMaxClientHeaderBytes = kilobytes(32);
static void
initializeSSLContext(

View File

@@ -21,13 +21,13 @@ public:
bool sslVerify,
beast::Journal j,
boost::asio::ssl::context_base::method method = boost::asio::ssl::context::sslv23)
: ssl_context_{method}, j_(j), verify_{sslVerify}
: sslContext_{method}, j_(j), verify_{sslVerify}
{
boost::system::error_code ec;
if (sslVerifyFile.empty())
{
registerSSLCerts(ssl_context_, ec, j_);
registerSSLCerts(sslContext_, ec, j_);
if (ec && sslVerifyDir.empty())
{
@@ -37,12 +37,12 @@ public:
}
else
{
ssl_context_.load_verify_file(sslVerifyFile);
sslContext_.load_verify_file(sslVerifyFile);
}
if (!sslVerifyDir.empty())
{
ssl_context_.add_verify_path(sslVerifyDir, ec);
sslContext_.add_verify_path(sslVerifyDir, ec);
if (ec)
{
@@ -55,7 +55,7 @@ public:
boost::asio::ssl::context&
context()
{
return ssl_context_;
return sslContext_;
}
[[nodiscard]] bool
@@ -153,7 +153,7 @@ public:
}
private:
boost::asio::ssl::context ssl_context_;
boost::asio::ssl::context sslContext_;
beast::Journal const j_;
bool const verify_;
};

View File

@@ -83,10 +83,6 @@ public:
virtual Status
fetch(uint256 const& hash, std::shared_ptr<NodeObject>* pObject) = 0;
/** Fetch a batch synchronously. */
virtual std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
fetchBatch(std::vector<uint256> const& hashes) = 0;
/** Store a single object.
Depending on the implementation this may happen immediately
or deferred using a scheduled task.

View File

@@ -131,6 +131,10 @@ public:
std::uint32_t ledgerSeq,
std::function<void(std::shared_ptr<NodeObject> const&)>&& callback);
/** Remove expired entries from the positive and negative caches. */
virtual void
sweep() = 0;
/** Gather statistics pertaining to read and write activities.
*
* @param obj Json object reference into which to place counters.

View File

@@ -29,7 +29,7 @@ enum class NodeObjectType : std::uint32_t {
class NodeObject : public CountedObject<NodeObject>
{
public:
static constexpr std::size_t kKEY_BYTES = 32;
static constexpr std::size_t kKeyBytes = 32;
private:
// This hack is used to make the constructor effectively private

View File

@@ -6,20 +6,16 @@
namespace xrpl::NodeStore {
// Need to be named before converting
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum {
// This is only used to pre-allocate the array for
// batch objects and does not affect the amount written.
//
BatchWritePreallocationSize = 256,
// This is only used to pre-allocate the array for
// batch objects and does not affect the amount written.
//
static constexpr auto kBatchWritePreallocationSize = 256;
// This sets a limit on the maximum number of writes
// in a batch. Actual usage can be twice this since
// we have a new batch growing as we write the old.
//
BatchWriteLimitSize = 65536
};
// This sets a limit on the maximum number of writes
// in a batch. Actual usage can be twice this since
// we have a new batch growing as we write the old.
//
static constexpr auto kBatchWriteLimitSize = 65536;
/** Return codes from Backend operations. */
enum class Status {

View File

@@ -22,6 +22,32 @@ public:
beast::Journal j)
: Database(scheduler, readThreads, config, j), backend_(std::move(backend))
{
std::optional<int> cacheSize, cacheAge;
if (config.exists("cache_size"))
{
cacheSize = get<int>(config, "cache_size");
if (cacheSize.value() < 0)
Throw<std::runtime_error>("Specified negative value for cache_size");
}
if (config.exists("cache_age"))
{
cacheAge = get<int>(config, "cache_age");
if (cacheAge.value() < 0)
Throw<std::runtime_error>("Specified negative value for cache_age");
}
if (cacheSize.has_value() || cacheAge.has_value())
{
cache_ = std::make_shared<TaggedCache<uint256, NodeObject>>(
"DatabaseNodeImp",
cacheSize.value_or(0),
std::chrono::minutes(cacheAge.value_or(0)),
stopwatch(),
j);
}
XRPL_ASSERT(
backend_,
"xrpl::NodeStore::DatabaseNodeImp::DatabaseNodeImp : non-null "
@@ -67,16 +93,19 @@ public:
backend_->sync();
}
std::vector<std::shared_ptr<NodeObject>>
fetchBatch(std::vector<uint256> const& hashes);
void
asyncFetch(
uint256 const& hash,
std::uint32_t ledgerSeq,
std::function<void(std::shared_ptr<NodeObject> const&)>&& callback) override;
void
sweep() override;
private:
// Cache for database objects. This cache is not always initialized. Check
// for null before using.
std::shared_ptr<TaggedCache<uint256, NodeObject>> cache_;
// Persistent key/value storage
std::shared_ptr<Backend> backend_;

View File

@@ -55,6 +55,9 @@ public:
void
sync() override;
void
sweep() override;
private:
std::shared_ptr<Backend> writableBackend_;
std::shared_ptr<Backend> archiveBackend_;

View File

@@ -55,7 +55,7 @@ lz4Compress(void const* in, std::size_t inSize, BufferFactory&& bf)
using std::runtime_error;
using namespace nudb::detail;
std::pair<void const*, std::size_t> result;
std::array<std::uint8_t, varint_traits<std::size_t>::kMAX> vi{};
std::array<std::uint8_t, varint_traits<std::size_t>::kMax> vi{};
auto const n = writeVarint(vi.data(), inSize);
auto const outMax = LZ4_compressBound(inSize);
std::uint8_t* out = reinterpret_cast<std::uint8_t*>(bf(n + outMax));
@@ -254,12 +254,12 @@ nodeobjectCompress(void const* in, std::size_t inSize, BufferFactory&& bf)
}
}
std::array<std::uint8_t, varint_traits<std::size_t>::kMAX> vi{};
std::array<std::uint8_t, varint_traits<std::size_t>::kMax> vi{};
constexpr std::size_t kCODEC_TYPE = 1;
auto const vn = writeVarint(vi.data(), kCODEC_TYPE);
static constexpr std::size_t kCodecType = 1;
auto const vn = writeVarint(vi.data(), kCodecType);
std::pair<void const*, std::size_t> result;
switch (kCODEC_TYPE)
switch (kCodecType)
{
// case 0 was uncompressed data; we always compress now.
case 1: // lz4
@@ -275,7 +275,7 @@ nodeobjectCompress(void const* in, std::size_t inSize, BufferFactory&& bf)
break;
}
default:
Throw<std::logic_error>("nodeobject codec: unknown=" + std::to_string(kCODEC_TYPE));
Throw<std::logic_error>("nodeobject codec: unknown=" + std::to_string(kCodecType));
};
return result;
}

View File

@@ -25,7 +25,7 @@ struct varint_traits<T, true>
{
explicit varint_traits() = default;
static std::size_t constexpr kMAX = (8 * sizeof(T) + 6) / 7;
static constexpr std::size_t kMax = (8 * sizeof(T) + 6) / 7;
};
// Returns: Number of bytes consumed or 0 on error,

View File

@@ -8,21 +8,21 @@
namespace xrpl {
std::uint16_t constexpr kTRADING_FEE_THRESHOLD = 1000; // 1%
constexpr std::uint16_t kTradingFeeThreshold = 1000; // 1%
// Auction slot
std::uint32_t constexpr kTOTAL_TIME_SLOT_SECS = 24 * 3600;
std::uint16_t constexpr kAUCTION_SLOT_TIME_INTERVALS = 20;
std::uint16_t constexpr kAUCTION_SLOT_MAX_AUTH_ACCOUNTS = 4;
std::uint32_t constexpr kAUCTION_SLOT_FEE_SCALE_FACTOR = 100000;
std::uint32_t constexpr kAUCTION_SLOT_DISCOUNTED_FEE_FRACTION = 10;
std::uint32_t constexpr kAUCTION_SLOT_MIN_FEE_FRACTION = 25;
std::uint32_t constexpr kAUCTION_SLOT_INTERVAL_DURATION =
kTOTAL_TIME_SLOT_SECS / kAUCTION_SLOT_TIME_INTERVALS;
constexpr std::uint32_t kTotalTimeSlotSecs = 24 * 3600;
constexpr std::uint16_t kAuctionSlotTimeIntervals = 20;
constexpr std::uint16_t kAuctionSlotMaxAuthAccounts = 4;
constexpr std::uint32_t kAuctionSlotFeeScaleFactor = 100000;
constexpr std::uint32_t kAuctionSlotDiscountedFeeFraction = 10;
constexpr std::uint32_t kAuctionSlotMinFeeFraction = 25;
constexpr std::uint32_t kAuctionSlotIntervalDuration =
kTotalTimeSlotSecs / kAuctionSlotTimeIntervals;
// Votes
std::uint16_t constexpr kVOTE_MAX_SLOTS = 8;
std::uint32_t constexpr kVOTE_WEIGHT_SCALE_FACTOR = 100000;
constexpr std::uint16_t kVoteMaxSlots = 8;
constexpr std::uint32_t kVoteWeightScaleFactor = 100000;
class STObject;
class STAmount;
@@ -77,7 +77,7 @@ ammEnabled(Rules const&);
inline Number
getFee(std::uint16_t tfee)
{
return Number{tfee} / kAUCTION_SLOT_FEE_SCALE_FACTOR;
return Number{tfee} / kAuctionSlotFeeScaleFactor;
}
/** Get fee multiplier (1 - tfee)

View File

@@ -25,7 +25,7 @@ public:
} // namespace detail
/** A 160-bit unsigned that uniquely identifies an account. */
using AccountID = BaseUint<160, detail::AccountIDTag>;
using AccountID = BaseUInt<160, detail::AccountIDTag>;
/** Convert AccountID to base58 checked string */
std::string
@@ -69,7 +69,7 @@ toIssuer(AccountID&, std::string const&);
inline bool
isXRP(AccountID const& c)
{
return c == beast::kZERO;
return c == beast::kZero;
}
// DEPRECATED

View File

@@ -96,9 +96,9 @@ inline MPTAmount
toAmount<MPTAmount>(STAmount const& amt)
{
XRPL_ASSERT(
amt.holds<MPTIssue>() && amt.mantissa() <= kMAX_MP_TOKEN_AMOUNT && amt.exponent() == 0,
amt.holds<MPTIssue>() && amt.mantissa() <= kMaxMpTokenAmount && amt.exponent() == 0,
"xrpl::toAmount<MPTAmount> : maximum mantissa");
if (amt.mantissa() > kMAX_MP_TOKEN_AMOUNT || amt.exponent() != 0)
if (amt.mantissa() > kMaxMpTokenAmount || amt.exponent() != 0)
Throw<std::runtime_error>("toAmount<MPTAmount>: invalid mantissa or exponent");
bool const isNeg = amt.negative();
std::int64_t const sMant = isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
@@ -167,8 +167,8 @@ toAmount(Asset const& asset, Number const& n, Number::RoundingMode mode = Number
}
else
{
constexpr bool kALWAYS_FALSE = !std::is_same_v<T, T>;
static_assert(kALWAYS_FALSE, "Unsupported type for toAmount");
static constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
static_assert(kAlwaysFalse, "Unsupported type for toAmount");
}
}
@@ -178,30 +178,30 @@ toMaxAmount(Asset const& asset)
{
if constexpr (std::is_same_v<IOUAmount, T>)
{
return IOUAmount(STAmount::kMAX_VALUE, STAmount::kMAX_OFFSET);
return IOUAmount(STAmount::kMaxValue, STAmount::kMaxOffset);
}
else if constexpr (std::is_same_v<XRPAmount, T>)
{
return XRPAmount(static_cast<std::int64_t>(STAmount::kMAX_NATIVE_N));
return XRPAmount(static_cast<std::int64_t>(STAmount::kMaxNativeN));
}
else if constexpr (std::is_same_v<MPTAmount, T>)
{
return MPTAmount(kMAX_MP_TOKEN_AMOUNT);
return MPTAmount(kMaxMpTokenAmount);
}
else if constexpr (std::is_same_v<STAmount, T>)
{
return asset.visit(
[](Issue const& issue) {
if (isXRP(issue))
return STAmount(issue, static_cast<std::int64_t>(STAmount::kMAX_NATIVE_N));
return STAmount(issue, STAmount::kMAX_VALUE, STAmount::kMAX_OFFSET);
return STAmount(issue, static_cast<std::int64_t>(STAmount::kMaxNativeN));
return STAmount(issue, STAmount::kMaxValue, STAmount::kMaxOffset);
},
[](MPTIssue const& issue) { return STAmount(issue, kMAX_MP_TOKEN_AMOUNT); });
[](MPTIssue const& issue) { return STAmount(issue, kMaxMpTokenAmount); });
}
else
{
constexpr bool kALWAYS_FALSE = !std::is_same_v<T, T>;
static_assert(kALWAYS_FALSE, "Unsupported type for toMaxAmount");
static constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
static_assert(kAlwaysFalse, "Unsupported type for toMaxAmount");
}
}
@@ -233,8 +233,8 @@ getAsset(T const& amt)
}
else
{
constexpr bool kALWAYS_FALSE = !std::is_same_v<T, T>;
static_assert(kALWAYS_FALSE, "Unsupported type for getIssue");
static constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
static_assert(kAlwaysFalse, "Unsupported type for getIssue");
}
}
@@ -260,8 +260,8 @@ get(STAmount const& a)
}
else
{
constexpr bool kALWAYS_FALSE = !std::is_same_v<T, T>;
static_assert(kALWAYS_FALSE, "Unsupported type for get");
constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
static_assert(kAlwaysFalse, "Unsupported type for get");
}
}

View File

@@ -35,49 +35,49 @@ namespace xrpl {
namespace RPC {
template <unsigned int Version>
constexpr static std::integral_constant<unsigned, Version> kAPI_VERSION = {};
static constexpr std::integral_constant<unsigned, Version> kApiVersion = {};
constexpr static auto kAPI_INVALID_VERSION = kAPI_VERSION<0>;
constexpr static auto kAPI_MINIMUM_SUPPORTED_VERSION = kAPI_VERSION<1>;
constexpr static auto kAPI_MAXIMUM_SUPPORTED_VERSION = kAPI_VERSION<2>;
constexpr static auto kAPI_VERSION_IF_UNSPECIFIED = kAPI_VERSION<1>;
constexpr static auto kAPI_COMMAND_LINE_VERSION = kAPI_VERSION<1>; // TODO Bump to 2 later
constexpr static auto kAPI_BETA_VERSION = kAPI_VERSION<3>;
constexpr static auto kAPI_MAXIMUM_VALID_VERSION = kAPI_BETA_VERSION;
static constexpr auto kApiInvalidVersion = kApiVersion<0>;
static constexpr auto kApiMinimumSupportedVersion = kApiVersion<1>;
static constexpr auto kApiMaximumSupportedVersion = kApiVersion<2>;
static constexpr auto kApiVersionIfUnspecified = kApiVersion<1>;
static constexpr auto kApiCommandLineVersion = kApiVersion<1>; // TODO Bump to 2 later
static constexpr auto kApiBetaVersion = kApiVersion<3>;
static constexpr auto kApiMaximumValidVersion = kApiBetaVersion;
static_assert(kAPI_INVALID_VERSION < kAPI_MINIMUM_SUPPORTED_VERSION);
static_assert(kApiInvalidVersion < kApiMinimumSupportedVersion);
static_assert(
kAPI_VERSION_IF_UNSPECIFIED >= kAPI_MINIMUM_SUPPORTED_VERSION &&
kAPI_VERSION_IF_UNSPECIFIED <= kAPI_MAXIMUM_SUPPORTED_VERSION);
kApiVersionIfUnspecified >= kApiMinimumSupportedVersion &&
kApiVersionIfUnspecified <= kApiMaximumSupportedVersion);
static_assert(
kAPI_COMMAND_LINE_VERSION >= kAPI_MINIMUM_SUPPORTED_VERSION &&
kAPI_COMMAND_LINE_VERSION <= kAPI_MAXIMUM_SUPPORTED_VERSION);
static_assert(kAPI_MAXIMUM_SUPPORTED_VERSION >= kAPI_MINIMUM_SUPPORTED_VERSION);
static_assert(kAPI_BETA_VERSION >= kAPI_MAXIMUM_SUPPORTED_VERSION);
static_assert(kAPI_MAXIMUM_VALID_VERSION >= kAPI_MAXIMUM_SUPPORTED_VERSION);
kApiCommandLineVersion >= kApiMinimumSupportedVersion &&
kApiCommandLineVersion <= kApiMaximumSupportedVersion);
static_assert(kApiMaximumSupportedVersion >= kApiMinimumSupportedVersion);
static_assert(kApiBetaVersion >= kApiMaximumSupportedVersion);
static_assert(kApiMaximumValidVersion >= kApiMaximumSupportedVersion);
inline void
setVersion(json::Value& parent, unsigned int apiVersion, bool betaEnabled)
{
XRPL_ASSERT(apiVersion != kAPI_INVALID_VERSION, "xrpl::RPC::setVersion : input is valid");
XRPL_ASSERT(apiVersion != kApiInvalidVersion, "xrpl::RPC::setVersion : input is valid");
auto& retObj = parent[jss::version] = json::ObjectValue;
auto& retObj = parent[jss::version] = json::ValueType::Object;
if (apiVersion == kAPI_VERSION_IF_UNSPECIFIED)
if (apiVersion == kApiVersionIfUnspecified)
{
// API version numbers used in API version 1
static beast::SemanticVersion const kFIRST_VERSION{"1.0.0"};
static beast::SemanticVersion const kGOOD_VERSION{"1.0.0"};
static beast::SemanticVersion const kLAST_VERSION{"1.0.0"};
static beast::SemanticVersion const kFirstVersion{"1.0.0"};
static beast::SemanticVersion const kGoodVersion{"1.0.0"};
static beast::SemanticVersion const kLastVersion{"1.0.0"};
retObj[jss::first] = kFIRST_VERSION.print();
retObj[jss::good] = kGOOD_VERSION.print();
retObj[jss::last] = kLAST_VERSION.print();
retObj[jss::first] = kFirstVersion.print();
retObj[jss::good] = kGoodVersion.print();
retObj[jss::last] = kLastVersion.print();
}
else
{
retObj[jss::first] = kAPI_MINIMUM_SUPPORTED_VERSION.value;
retObj[jss::last] = betaEnabled ? kAPI_BETA_VERSION : kAPI_MAXIMUM_SUPPORTED_VERSION;
retObj[jss::first] = kApiMinimumSupportedVersion.value;
retObj[jss::last] = betaEnabled ? kApiBetaVersion : kApiMaximumSupportedVersion;
}
}
@@ -98,9 +98,9 @@ setVersion(json::Value& parent, unsigned int apiVersion, bool betaEnabled)
inline unsigned int
getAPIVersionNumber(json::Value const& jv, bool betaEnabled)
{
static json::Value const kMIN_VERSION(RPC::kAPI_MINIMUM_SUPPORTED_VERSION);
static json::Value const kMinVersion(RPC::kApiMinimumSupportedVersion);
json::Value const maxVersion(
betaEnabled ? RPC::kAPI_BETA_VERSION : RPC::kAPI_MAXIMUM_SUPPORTED_VERSION);
betaEnabled ? RPC::kApiBetaVersion : RPC::kApiMaximumSupportedVersion);
if (jv.isObject())
{
@@ -109,18 +109,18 @@ getAPIVersionNumber(json::Value const& jv, bool betaEnabled)
auto const specifiedVersion = jv[jss::api_version];
if (!specifiedVersion.isInt() && !specifiedVersion.isUInt())
{
return RPC::kAPI_INVALID_VERSION;
return RPC::kApiInvalidVersion;
}
auto const specifiedVersionInt = specifiedVersion.asInt();
if (specifiedVersionInt < kMIN_VERSION || specifiedVersionInt > maxVersion)
if (specifiedVersionInt < kMinVersion || specifiedVersionInt > maxVersion)
{
return RPC::kAPI_INVALID_VERSION;
return RPC::kApiInvalidVersion;
}
return specifiedVersionInt;
}
}
return RPC::kAPI_VERSION_IF_UNSPECIFIED;
return RPC::kApiVersionIfUnspecified;
}
} // namespace RPC
@@ -128,33 +128,33 @@ getAPIVersionNumber(json::Value const& jv, bool betaEnabled)
template <unsigned MinVer, unsigned MaxVer, typename Fn, typename... Args>
void
forApiVersions(Fn const& fn, Args&&... args)
requires //
(MaxVer >= MinVer) && //
(MinVer >= RPC::kAPI_MINIMUM_SUPPORTED_VERSION) && //
(RPC::kAPI_MAXIMUM_VALID_VERSION >= MaxVer) && requires {
requires //
(MaxVer >= MinVer) && //
(MinVer >= RPC::kApiMinimumSupportedVersion) && //
(RPC::kApiMaximumValidVersion >= MaxVer) && requires {
fn(std::integral_constant<unsigned int, MinVer>{}, std::forward<Args>(args)...);
fn(std::integral_constant<unsigned int, MaxVer>{}, std::forward<Args>(args)...);
}
{
constexpr auto kSIZE = MaxVer + 1 - MinVer;
static constexpr auto kSize = MaxVer + 1 - MinVer;
[&]<std::size_t... Offset>(std::index_sequence<Offset...>) {
// NOLINTBEGIN(bugprone-use-after-move)
(((void)fn(
std::integral_constant<unsigned int, MinVer + Offset>{}, std::forward<Args>(args)...)),
...);
// NOLINTEND(bugprone-use-after-move)
}(std::make_index_sequence<kSIZE>{});
}(std::make_index_sequence<kSize>{});
}
template <typename Fn, typename... Args>
void
forAllApiVersions(Fn const& fn, Args&&... args)
requires requires {
forApiVersions<RPC::kAPI_MINIMUM_SUPPORTED_VERSION, RPC::kAPI_MAXIMUM_VALID_VERSION>(
forApiVersions<RPC::kApiMinimumSupportedVersion, RPC::kApiMaximumValidVersion>(
fn, std::forward<Args>(args)...);
}
{
forApiVersions<RPC::kAPI_MINIMUM_SUPPORTED_VERSION, RPC::kAPI_MAXIMUM_VALID_VERSION>(
forApiVersions<RPC::kApiMinimumSupportedVersion, RPC::kApiMaximumValidVersion>(
fn, std::forward<Args>(args)...);
}

View File

@@ -148,10 +148,10 @@ public:
};
template <ValidIssueType TIss>
constexpr bool kIS_ISSUE_V = std::is_same_v<TIss, Issue>;
constexpr bool kIsIssueV = std::is_same_v<TIss, Issue>;
template <ValidIssueType TIss>
constexpr bool kIS_MPTISSUE_V = std::is_same_v<TIss, MPTIssue>;
constexpr bool kIsMptissueV = std::is_same_v<TIss, MPTIssue>;
inline json::Value
toJson(Asset const& asset)
@@ -242,7 +242,7 @@ operator<=>(Asset const& lhs, Asset const& rhs)
{
return std::weak_ordering(lhs <=> rhs);
}
else if constexpr (kIS_ISSUE_V<TLhs> && kIS_MPTISSUE_V<TRhs>)
else if constexpr (kIsIssueV<TLhs> && kIsMptissueV<TRhs>)
{
return std::weak_ordering::greater;
}

View File

@@ -140,8 +140,8 @@ private:
using issue_hasher = std::hash<xrpl::Issue>;
using mptissue_hasher = std::hash<xrpl::MPTIssue>;
issue_hasher m_issue_hasher_;
mptissue_hasher m_mptissue_hasher_;
issue_hasher mIssueHasher_;
mptissue_hasher mMptissueHasher_;
public:
explicit hash() = default;
@@ -151,11 +151,11 @@ public:
{
return asset.visit(
[&](xrpl::Issue const& issue) {
value_type const result(m_issue_hasher_(issue));
value_type const result(mIssueHasher_(issue));
return result;
},
[&](xrpl::MPTIssue const& issue) {
value_type const result(m_mptissue_hasher_(issue));
value_type const result(mMptissueHasher_(issue));
return result;
});
}
@@ -170,8 +170,8 @@ private:
using asset_hasher = std::hash<xrpl::Asset>;
using uint256_hasher = xrpl::uint256::hasher;
asset_hasher issue_hasher_;
uint256_hasher uint256_hasher_;
asset_hasher issueHasher_;
uint256_hasher uint256Hasher_;
public:
hash() = default;
@@ -182,11 +182,11 @@ public:
value_type
operator()(argument_type const& value) const
{
value_type result(issue_hasher_(value.in));
boost::hash_combine(result, issue_hasher_(value.out));
value_type result(issueHasher_(value.in));
boost::hash_combine(result, issueHasher_(value.out));
if (value.domain)
boost::hash_combine(result, uint256_hasher_(*value.domain));
boost::hash_combine(result, uint256Hasher_(*value.domain));
return result;
}

View File

@@ -172,24 +172,24 @@ struct ErrorInfo
{
// Default ctor needed to produce an empty std::array during constexpr eval.
constexpr ErrorInfo()
: code(RpcUnknown), token("unknown"), message("An unknown error code."), http_status(200)
: code(RpcUnknown), token("unknown"), message("An unknown error code."), httpStatus(200)
{
}
constexpr ErrorInfo(ErrorCodeI code, char const* token, char const* message)
: code(code), token(token), message(message), http_status(200)
: code(code), token(token), message(message), httpStatus(200)
{
}
constexpr ErrorInfo(ErrorCodeI code, char const* token, char const* message, int httpStatus)
: code(code), token(token), message(message), http_status(httpStatus)
: code(code), token(token), message(message), httpStatus(httpStatus)
{
}
ErrorCodeI code;
json::StaticString token;
json::StaticString message;
int http_status;
int httpStatus;
};
/** Returns an ErrorInfo that reflects the error code. */

View File

@@ -65,11 +65,11 @@
namespace xrpl {
// Feature names must not exceed this length (in characters, excluding the null terminator).
static constexpr std::size_t kMAX_FEATURE_NAME_SIZE = 63;
static constexpr std::size_t kMaxFeatureNameSize = 63;
// Reserve this exact feature-name length (in characters/bytes, excluding the null terminator)
// so that a 32-byte uint256 (for example, in WASM or other interop contexts) can be used
// as a compact, fixed-size feature selector without conflicting with human-readable names.
static constexpr std::size_t kRESERVED_FEATURE_NAME_SIZE = 32;
static constexpr std::size_t kReservedFeatureNameSize = 32;
// Both validFeatureNameSize and validFeatureName are consteval functions that can be used in
// static_asserts to validate feature names at compile time. They are only used inside
@@ -81,14 +81,14 @@ validFeatureNameSize(auto fn) -> bool
{
constexpr char const* kN = fn();
// Note, std::strlen is not constexpr, we need to implement our own here.
constexpr std::size_t kLEN = [](auto n) {
constexpr std::size_t kLen = [](auto n) {
std::size_t ret = 0;
for (auto ptr = n; *ptr != '\0'; ret++, ++ptr)
;
return ret;
}(kN);
return kLEN != kRESERVED_FEATURE_NAME_SIZE && //
kLEN <= kMAX_FEATURE_NAME_SIZE;
return kLen != kReservedFeatureNameSize && //
kLen <= kMaxFeatureNameSize;
}
consteval auto
@@ -136,7 +136,7 @@ namespace detail {
// Feature.cpp. Because it's only used to reserve storage, and determine how
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
// the actual number of amendments. A LogicError on startup will verify this.
static constexpr std::size_t kNUM_FEATURES =
static constexpr std::size_t kNumFeatures =
(0 +
#include <xrpl/protocol/detail/features.macro>
);
@@ -184,9 +184,9 @@ bitsetIndexToFeature(size_t i);
std::string
featureToName(uint256 const& f);
class FeatureBitset : private std::bitset<detail::kNUM_FEATURES>
class FeatureBitset : private std::bitset<detail::kNumFeatures>
{
using base = std::bitset<detail::kNUM_FEATURES>;
using base = std::bitset<detail::kNumFeatures>;
template <class... Fs>
void

View File

@@ -6,7 +6,7 @@ namespace xrpl {
// Deprecated constant for backwards compatibility with pre-XRPFees amendment.
// This was the reference fee units used in the old fee calculation.
inline constexpr std::uint32_t kFEE_UNITS_DEPRECATED = 10;
inline constexpr std::uint32_t kFeeUnitsDeprecated = 10;
/** Reflects the fee settings for a particular ledger.

View File

@@ -92,7 +92,7 @@ public:
inline IOUAmount::IOUAmount(beast::Zero)
{
*this = beast::kZERO;
*this = beast::kZero;
}
inline IOUAmount::IOUAmount(mantissa_type mantissa, exponent_type exponent)

View File

@@ -82,7 +82,7 @@ struct BookT
Keylet
operator()(Book const& b) const;
};
static BookT const kBOOK{};
static BookT const kBook{};
/** The index of a trust line for a given currency
@@ -126,7 +126,7 @@ struct NextT
Keylet
operator()(Keylet const& k) const;
};
static NextT const kNEXT{};
static NextT const kNext{};
/** A ticket belonging to an account */
struct TicketT
@@ -145,7 +145,7 @@ struct TicketT
return {ltTICKET, key};
}
};
static TicketT const kTICKET{};
static TicketT const kTicket{};
/** A SignerList */
Keylet
@@ -373,7 +373,7 @@ struct KeyletDesc
// This list should include all of the keylet functions that take a single
// AccountID parameter.
std::array<KeyletDesc<AccountID const&>, 6> const kDIRECT_ACCOUNT_KEYLETS{
std::array<KeyletDesc<AccountID const&>, 6> const kDirectAccountKeylets{
{{.function = &keylet::account, .expectedLEName = jss::AccountRoot, .includeInTests = false},
{.function = &keylet::ownerDir, .expectedLEName = jss::DirectoryNode, .includeInTests = true},
{.function = &keylet::signers, .expectedLEName = jss::SignerList, .includeInTests = true},

View File

@@ -96,16 +96,16 @@ operator<=>(Issue const& lhs, Issue const& rhs)
inline Issue const&
xrpIssue()
{
static Issue const kISSUE{xrpCurrency(), xrpAccount()};
return kISSUE;
static Issue const kIssue{xrpCurrency(), xrpAccount()};
return kIssue;
}
/** Returns an asset specifier that represents no account and currency. */
inline Issue const&
noIssue()
{
static Issue const kISSUE{noCurrency(), noAccount()};
return kISSUE;
static Issue const kIssue{noCurrency(), noAccount()};
return kIssue;
}
inline bool

View File

@@ -26,12 +26,12 @@ struct LedgerHeader
//
// Closed means "tx set already determined"
uint256 hash = beast::kZERO;
uint256 txHash = beast::kZERO;
uint256 accountHash = beast::kZERO;
uint256 parentHash = beast::kZERO;
uint256 hash = beast::kZero;
uint256 txHash = beast::kZero;
uint256 accountHash = beast::kZero;
uint256 parentHash = beast::kZero;
XRPAmount drops = beast::kZERO;
XRPAmount drops = beast::kZero;
// If validated is false, it means "not yet validated."
// Once validated is true, it will never be set false at a later time.
@@ -53,12 +53,12 @@ struct LedgerHeader
};
// ledger close flags
static std::uint32_t const kS_LCF_NO_CONSENSUS_TIME = 0x01;
static std::uint32_t const kSLcfNoConsensusTime = 0x01;
inline bool
getCloseAgree(LedgerHeader const& info)
{
return (info.closeFlags & kS_LCF_NO_CONSENSUS_TIME) == 0;
return (info.closeFlags & kSLcfNoConsensusTime) == 0;
}
void

View File

@@ -88,7 +88,7 @@ constexpr MPTAmount::MPTAmount(value_type value) : value_(value)
constexpr MPTAmount::MPTAmount(beast::Zero)
{
*this = beast::kZERO;
*this = beast::kZero;
}
constexpr MPTAmount&

Some files were not shown because too many files have changed in this diff Show More