Merge branch 'develop' into ximinez/vault-test

This commit is contained in:
Ed Hennis
2026-05-07 13:28:55 -04:00
committed by GitHub
55 changed files with 528 additions and 283 deletions

View File

@@ -73,7 +73,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
and build_type == "Debug"
and build_type == "Release"
and architecture["platform"] == "linux/amd64"
):
skip = False
@@ -91,8 +91,9 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
):
unittest_args = f"{unittest_args} --unittest-fee=1000"
skip = False
elif os["distro_version"] == "trixie":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-22"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
@@ -189,8 +190,9 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# We skip all clang 20+ on arm64 due to Boost build error.
if (
f"{os['compiler_name']}-{os['compiler_version']}"
in ["clang-20", "clang-21"]
os["compiler_name"] == "clang"
and os["compiler_version"].isdigit()
and int(os["compiler_version"]) >= 20
and architecture["platform"] == "linux/arm64"
):
continue
@@ -239,13 +241,14 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# Add Address and UB sanitizers as separate configurations for specific
# bookworm distros. Thread sanitizer is currently disabled (see below).
# GCC-Asan xrpld-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
if os[
"distro_version"
] == "bookworm" and f"{os['compiler_name']}-{os['compiler_version']}" in [
"gcc-15",
"clang-20",
]:
# Add ASAN configuration.
if (
os["distro_version"] == "bookworm"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
) or (
os["distro_version"] == "trixie"
and f"{os['compiler_name']}-{os['compiler_version']}" == "clang-22"
):
# Add ASAN and UBSAN configurations for both gcc-15 and clang-22
configurations.append(
{
"config_name": config_name + "-asan",
@@ -259,7 +262,6 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
"sanitizers": "address",
}
)
# Add UBSAN configuration.
configurations.append(
{
"config_name": config_name + "-ubsan",

View File

@@ -15,196 +15,203 @@
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "15",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "16",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "17",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "18",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "19",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "20",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "gcc",
"compiler_version": "15",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "20",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "21",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "22",
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "8",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "8",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "jammy",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "16",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "17",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "18",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "19",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
}
],
"build_type": ["Debug", "Release"],

View File

@@ -62,7 +62,7 @@ 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.");
@@ -160,7 +160,7 @@ private:
explicit VoidHelper() = default;
};
explicit BaseUint(void const* data, VoidHelper)
explicit BaseUInt(void const* data, VoidHelper)
{
memcpy(data_.data(), data, kBYTES);
}
@@ -244,15 +244,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 +260,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,11 +270,11 @@ 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)
{
XRPL_ASSERT(
c.size() * sizeof(typename Container::value_type) == size(),
"xrpl::base_uint::base_uint(Container auto) : input size match");
"xrpl::BaseUInt::BaseUInt(Container auto) : input size match");
std::memcpy(data_.data(), c.data(), size());
}
@@ -282,12 +282,12 @@ public:
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 +295,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())
@@ -328,10 +328,10 @@ public:
return *this == beast::kZERO;
}
constexpr BaseUint
constexpr BaseUInt
operator~() const
{
BaseUint ret;
BaseUInt ret;
for (int i = 0; i < kWIDTH; i++)
ret.data_[i] = ~data_[i];
@@ -339,7 +339,7 @@ public:
return ret;
}
BaseUint&
BaseUInt&
operator=(std::uint64_t uHost)
{
*this = beast::kZERO;
@@ -357,8 +357,8 @@ public:
return *this;
}
BaseUint&
operator^=(BaseUint const& b)
BaseUInt&
operator^=(BaseUInt const& b)
{
for (int i = 0; i < kWIDTH; i++)
data_[i] ^= b.data_[i];
@@ -366,8 +366,8 @@ public:
return *this;
}
BaseUint&
operator&=(BaseUint const& b)
BaseUInt&
operator&=(BaseUInt const& b)
{
for (int i = 0; i < kWIDTH; i++)
data_[i] &= b.data_[i];
@@ -375,8 +375,8 @@ public:
return *this;
}
BaseUint&
operator|=(BaseUint const& b)
BaseUInt&
operator|=(BaseUInt const& b)
{
for (int i = 0; i < kWIDTH; i++)
data_[i] |= b.data_[i];
@@ -384,7 +384,7 @@ public:
return *this;
}
BaseUint&
BaseUInt&
operator++()
{
// prefix operator
@@ -398,17 +398,17 @@ 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)
@@ -423,32 +423,32 @@ 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;
@@ -466,7 +466,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_));
@@ -509,7 +509,7 @@ public:
return kBYTES;
}
BaseUint<Bits, Tag>&
BaseUInt<Bits, Tag>&
operator=(beast::Zero)
{
data_.fill(0);
@@ -534,14 +534,14 @@ public:
}
};
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 +562,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 +570,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 +650,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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -19,14 +19,10 @@ 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
[[nodiscard]] TER
deleteSLE(ApplyView& view, std::shared_ptr<SLE> const& sleCredential, beast::Journal j);
// Amendment and parameters checks for sfCredentialIDs field

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

View File

@@ -16,7 +16,7 @@ class STBitString final : public STBase, public CountedObject<STBitString<Bits>>
static_assert(Bits > 0, "Number of bits must be positive");
public:
using value_type = BaseUint<Bits>;
using value_type = BaseUInt<Bits>;
private:
value_type value_{};
@@ -46,7 +46,7 @@ public:
template <typename Tag>
void
setValue(BaseUint<Bits, Tag> const& v);
setValue(BaseUInt<Bits, Tag> const& v);
[[nodiscard]] value_type const&
value() const;
@@ -157,7 +157,7 @@ STBitString<Bits>::add(Serializer& s) const
template <int Bits>
template <typename Tag>
void
STBitString<Bits>::setValue(BaseUint<Bits, Tag> const& v)
STBitString<Bits>::setValue(BaseUInt<Bits, Tag> const& v)
{
value_ = v;
}

View File

@@ -381,7 +381,7 @@ public:
template <class Tag>
void
setFieldH160(SField const& field, BaseUint<160, Tag> const& v);
setFieldH160(SField const& field, BaseUInt<160, Tag> const& v);
STObject&
peekFieldObject(SField const& field);
@@ -1143,7 +1143,7 @@ STObject::at(OptionaledField<T> const& of) -> OptionalProxy<T>
template <class Tag>
void
STObject::setFieldH160(SField const& field, BaseUint<160, Tag> const& v)
STObject::setFieldH160(SField const& field, BaseUInt<160, Tag> const& v)
{
STBase* rf = getPField(field, true);

View File

@@ -102,7 +102,7 @@ public:
template <std::size_t Bits, class Tag>
int
addBitString(BaseUint<Bits, Tag> const& v)
addBitString(BaseUInt<Bits, Tag> const& v)
{
return addRaw(v.data(), v.size());
}
@@ -151,7 +151,7 @@ public:
template <std::size_t Bits, typename Tag = void>
bool
getBitString(BaseUint<Bits, Tag>& data, int offset) const
getBitString(BaseUInt<Bits, Tag>& data, int offset) const
{
auto success = (offset + (Bits / 8)) <= data_.size();
if (success)
@@ -369,7 +369,7 @@ public:
geti64();
template <std::size_t Bits, class Tag = void>
BaseUint<Bits, Tag>
BaseUInt<Bits, Tag>
getBitString();
uint128
@@ -428,7 +428,7 @@ public:
};
template <std::size_t Bits, class Tag>
BaseUint<Bits, Tag>
BaseUInt<Bits, Tag>
SerialIter::getBitString()
{
auto const n = Bits / 8;
@@ -442,7 +442,7 @@ SerialIter::getBitString()
used_ += n;
remain_ -= n;
return BaseUint<Bits, Tag>::fromVoid(x);
return BaseUInt<Bits, Tag>::fromVoid(x);
}
} // namespace xrpl

View File

@@ -30,21 +30,21 @@ public:
/** Directory is an index into the directory of offer books.
The last 64 bits of this are the quality. */
using Directory = BaseUint<256, detail::DirectoryTag>;
using Directory = BaseUInt<256, detail::DirectoryTag>;
/** Currency is a hash representing a specific currency. */
using Currency = BaseUint<160, detail::CurrencyTag>;
using Currency = BaseUInt<160, detail::CurrencyTag>;
/** NodeID is a 160-bit hash representing one node. */
using NodeID = BaseUint<160, detail::NodeIDTag>;
using NodeID = BaseUInt<160, detail::NodeIDTag>;
/** MPTID is a 192-bit value representing MPT Issuance ID,
* which is a concatenation of a 32-bit sequence (big endian)
* and a 160-bit account */
using MPTID = BaseUint<192>;
using MPTID = BaseUInt<192>;
/** Domain is a 256-bit hash representing a specific domain. */
using Domain = BaseUint<256>;
using Domain = BaseUInt<256>;
/** XRP currency. */
Currency const&

View File

@@ -30,7 +30,7 @@ namespace xrpl {
/** Represents an active connection. */
template <class Handler, class Impl>
class BaseHTTPPeer : public IoList::Work, public Session
class BaseHTTPPeer : public IOList::Work, public Session
{
protected:
using clock_type = std::chrono::system_clock;

View File

@@ -17,7 +17,7 @@ namespace xrpl {
// Common part of all peers
template <class Handler, class Impl>
class BasePeer : public IoList::Work
class BasePeer : public IOList::Work
{
protected:
using clock_type = std::chrono::system_clock;

View File

@@ -39,7 +39,7 @@ namespace xrpl {
/** A listening socket. */
template <class Handler>
class Door : public IoList::Work, public std::enable_shared_from_this<Door<Handler>>
class Door : public IOList::Work, public std::enable_shared_from_this<Door<Handler>>
{
private:
using clock_type = std::chrono::steady_clock;
@@ -53,7 +53,7 @@ private:
using stream_type = boost::beast::tcp_stream;
// Detects SSL on a socket
class Detector : public IoList::Work, public std::enable_shared_from_this<Detector>
class Detector : public IOList::Work, public std::enable_shared_from_this<Detector>
{
private:
Port const& port_;

View File

@@ -78,7 +78,7 @@ private:
int high_ = 0;
std::array<std::size_t, 64> hist_{};
IoList ios_;
IOList ios_;
public:
ServerImpl(Handler& handler, boost::asio::io_context& ioContext, beast::Journal journal);
@@ -97,7 +97,7 @@ public:
void
close() override;
IoList&
IOList&
ios()
{
return ios_;

View File

@@ -12,7 +12,7 @@
namespace xrpl {
/** Manages a set of objects performing asynchronous I/O. */
class IoList final
class IOList final
{
public:
class Work
@@ -21,8 +21,8 @@ public:
void
destroy();
friend class IoList;
IoList* ios_ = nullptr;
friend class IOList;
IOList* ios_ = nullptr;
public:
virtual ~Work()
@@ -30,13 +30,13 @@ public:
destroy();
}
/** Return the IoList associated with the work.
/** Return the IOList associated with the work.
Requirements:
The call to IoList::emplace to
The call to IOList::emplace to
create the work has already returned.
*/
IoList&
IOList&
ios()
{
return *ios_;
@@ -59,17 +59,17 @@ private:
std::function<void(void)> f_;
public:
IoList() = default;
IOList() = default;
/** Destroy the list.
Effects:
Closes the IoList if it was not previously
Closes the IOList if it was not previously
closed. No finisher is invoked in this case.
Blocks until all work is destroyed.
*/
~IoList()
~IOList()
{
destroy();
}
@@ -159,7 +159,7 @@ public:
template <class>
void
IoList::Work::destroy()
IOList::Work::destroy()
{
if (!ios_)
return;
@@ -179,7 +179,7 @@ IoList::Work::destroy()
template <class>
void
IoList::destroy()
IOList::destroy()
{
close();
join();
@@ -187,9 +187,9 @@ IoList::destroy()
template <class T, class... Args>
std::shared_ptr<T>
IoList::emplace(Args&&... args)
IOList::emplace(Args&&... args)
{
static_assert(std::is_base_of_v<Work, T>, "T must derive from IoList::Work");
static_assert(std::is_base_of_v<Work, T>, "T must derive from IOList::Work");
if (closed_)
return nullptr;
auto sp = std::make_shared<T>(std::forward<Args>(args)...);
@@ -211,7 +211,7 @@ IoList::emplace(Args&&... args)
template <class Finisher>
void
IoList::close(Finisher&& f)
IOList::close(Finisher&& f)
{
std::unique_lock<std::mutex> lock(m_);
if (closed_)
@@ -237,7 +237,7 @@ IoList::close(Finisher&& f)
template <class>
void
IoList::join()
IOList::join()
{
std::unique_lock<std::mutex> lock(m_);
cv_.wait(lock, [&] { return closed_ && n_ == 0; });

View File

@@ -624,7 +624,7 @@ private:
inline SHAMap::ConstIterator::ConstIterator(SHAMap const* map) : map_(map)
{
XRPL_ASSERT(map_, "xrpl::SHAMap::const_iterator::const_iterator : non-null input");
XRPL_ASSERT(map_, "xrpl::SHAMap::ConstIterator::ConstIterator : non-null input");
if (auto temp = map_->peekFirstItem(stack_))
item_ = temp->peekItem().get();

View File

@@ -139,7 +139,7 @@ inline boost::intrusive_ptr<SHAMapItem>
makeShamapitem(uint256 const& tag, Slice data)
{
XRPL_ASSERT(
data.size() <= megabytes<std::size_t>(16), "xrpl::make_shamapitem : maximum input size");
data.size() <= megabytes<std::size_t>(16), "xrpl::makeShamapitem : maximum input size");
// NOLINTNEXTLINE(misc-const-correctness)
std::uint8_t* raw = detail::gSlabber.allocate(data.size());

View File

@@ -273,7 +273,7 @@ Logs::toString(LogSeverity s)
return "Fatal";
// LCOV_EXCL_START
default:
UNREACHABLE("xrpl::Logs::to_string : invalid severity");
UNREACHABLE("xrpl::Logs::toString : invalid severity");
return "Unknown";
// LCOV_EXCL_STOP
}

View File

@@ -231,7 +231,7 @@ public:
void
doStop(CompletionCounter)
{
XRPL_ASSERT(stop_called == true, "xrpl::ResolverAsioImpl::do_stop : stopping");
XRPL_ASSERT(stop_called == true, "xrpl::ResolverAsioImpl::doStop : stopping");
if (!stopped.exchange(true))
{
@@ -369,7 +369,7 @@ public:
void
doResolve(std::vector<std::string> const& names, HandlerType const& handler, CompletionCounter)
{
XRPL_ASSERT(!names.empty(), "xrpl::ResolverAsioImpl::do_resolve : names non-empty");
XRPL_ASSERT(!names.empty(), "xrpl::ResolverAsioImpl::doResolve : names non-empty");
if (!stop_called)
{

View File

@@ -40,7 +40,7 @@ static_assert(std::atomic<std::chrono::steady_clock::rep>::is_always_lock_free);
SecondsClockThread::~SecondsClockThread()
{
XRPL_ASSERT(
thread_.joinable(), "beast::seconds_clock_thread::~seconds_clock_thread : thread joinable");
thread_.joinable(), "beast::SecondsClockThread::~SecondsClockThread : thread joinable");
{
std::scoped_lock const lock(mut_);
stop_ = true;

View File

@@ -54,14 +54,14 @@ const_iterator::operator==(ConstIterator const& other) const
XRPL_ASSERT(
view_ == other.view_ && root_.key == other.root_.key,
"xrpl::const_iterator::operator== : views and roots are matching");
"xrpl::Dir::ConstIterator::operator== : views and roots are matching");
return page_.key == other.page_.key && index_ == other.index_;
}
const_iterator::reference
const_iterator::operator*() const
{
XRPL_ASSERT(index_ != beast::kZERO, "xrpl::const_iterator::operator* : nonzero index");
XRPL_ASSERT(index_ != beast::kZERO, "xrpl::Dir::ConstIterator::operator* : nonzero index");
if (!cache_)
cache_ = view_->read(keylet::child(index_));
return *cache_;
@@ -70,7 +70,7 @@ const_iterator::operator*() const
const_iterator&
const_iterator::operator++()
{
XRPL_ASSERT(index_ != beast::kZERO, "xrpl::const_iterator::operator++ : nonzero index");
XRPL_ASSERT(index_ != beast::kZERO, "xrpl::Dir::ConstIterator::operator++ : nonzero index");
if (++it_ != std::end(*indexes_))
{
index_ = *it_;
@@ -84,7 +84,8 @@ const_iterator::operator++()
const_iterator
const_iterator::operator++(int)
{
XRPL_ASSERT(index_ != beast::kZERO, "xrpl::const_iterator::operator++(int) : nonzero index");
XRPL_ASSERT(
index_ != beast::kZERO, "xrpl::Dir::ConstIterator::operator++(int) : nonzero index");
ConstIterator tmp(*this);
++(*this);
return tmp;
@@ -103,7 +104,7 @@ const_iterator::nextPage()
{
page_ = keylet::page(root_, next);
sle_ = view_->read(page_);
XRPL_ASSERT(sle_, "xrpl::const_iterator::next_page : non-null SLE");
XRPL_ASSERT(sle_, "xrpl::Dir::ConstIterator::nextPage : non-null SLE");
indexes_ = &sle_->getFieldV256(sfIndexes);
if (indexes_->empty())
{

View File

@@ -1,5 +1,6 @@
#include <xrpl/ledger/helpers/CredentialHelpers.h>
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/base_uint.h>
@@ -9,6 +10,7 @@
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/Protocol.h>
@@ -33,15 +35,16 @@ namespace xrpl {
namespace credentials {
bool
checkExpired(std::shared_ptr<SLE const> const& sleCredential, NetClock::time_point const& closed)
checkExpired(SLE const& sleCredential, NetClock::time_point const& closed)
{
std::uint32_t const exp =
(*sleCredential)[~sfExpiration].value_or(std::numeric_limits<std::uint32_t>::max());
sleCredential[~sfExpiration].value_or(std::numeric_limits<std::uint32_t>::max());
std::uint32_t const now = closed.time_since_epoch().count();
return now > exp;
}
bool
[[nodiscard]]
static Expected<bool, TER>
removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j)
{
auto const closeTime = view.header().parentCloseTime;
@@ -53,11 +56,13 @@ removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j)
auto const k = keylet::credential(h);
auto const sleCred = view.peek(k);
if (sleCred && checkExpired(sleCred, closeTime))
if (sleCred && checkExpired(*sleCred, closeTime))
{
JLOG(j.trace()) << "Credentials are expired. Cred: " << sleCred->getText();
// delete expired credentials even if the transaction failed
deleteSLE(view, sleCred, j);
auto const err = deleteSLE(view, sleCred, j);
if (view.rules().enabled(fixSecurity3_1_3) && !isTesSuccess(err))
return Unexpected(err);
foundExpired = true;
}
}
@@ -205,7 +210,7 @@ validDomain(ReadView const& view, uint256 domainID, AccountID const& subject)
// allows expired credentials to be deleted by any transaction.
if (sleCredential)
{
if (checkExpired(sleCredential, closeTime))
if (checkExpired(*sleCredential, closeTime))
{
foundExpired = true;
continue;
@@ -324,7 +329,10 @@ verifyValidDomain(ApplyView& view, AccountID const& account, uint256 domainID, b
credentials.pushBack(keyletCredential.key);
}
bool const foundExpired = credentials::removeExpired(view, credentials, j);
auto const foundExpired = credentials::removeExpired(view, credentials, j);
if (!foundExpired.has_value())
return foundExpired.error();
for (auto const& h : credentials)
{
auto sleCredential = view.read(keylet::credential(h));
@@ -335,7 +343,7 @@ verifyValidDomain(ApplyView& view, AccountID const& account, uint256 domainID, b
return tesSUCCESS;
}
return foundExpired ? tecEXPIRED : tecNO_PERMISSION;
return *foundExpired ? tecEXPIRED : tecNO_PERMISSION;
}
TER
@@ -355,8 +363,15 @@ verifyDepositPreauth(
bool const credentialsPresent = tx.isFieldPresent(sfCredentialIDs);
if (credentialsPresent && credentials::removeExpired(view, tx.getFieldV256(sfCredentialIDs), j))
return tecEXPIRED;
if (credentialsPresent)
{
auto const foundExpired =
credentials::removeExpired(view, tx.getFieldV256(sfCredentialIDs), j);
if (!foundExpired.has_value())
return foundExpired.error();
if (*foundExpired)
return tecEXPIRED;
}
if (sleDst && ((sleDst->getFlags() & lsfDepositAuth) != 0u))
{

View File

@@ -35,7 +35,7 @@ accountInDomain(ReadView const& view, AccountID const& account, Domain const& do
if (!sleCred || !sleCred->isFlag(lsfAccepted))
return false;
return !credentials::checkExpired(sleCred, view.header().parentCloseTime);
return !credentials::checkExpired(*sleCred, view.header().parentCloseTime);
});
return inDomain;

View File

@@ -287,7 +287,7 @@ quality(Keylet const& k, std::uint64_t q) noexcept
Keylet
NextT::operator()(Keylet const& k) const
{
XRPL_ASSERT(k.type == ltDIR_NODE, "xrpl::keylet::next_t::operator() : valid input type");
XRPL_ASSERT(k.type == ltDIR_NODE, "xrpl::keylet::NextT::operator() : valid input type");
return {ltDIR_NODE, getQualityNext(k.key)};
}

View File

@@ -62,10 +62,10 @@ ceilInImpl(Amounts const& amount, STAmount const& limit, bool roundUp, Quality c
// Clamp out
if (result.out > amount.out)
result.out = amount.out;
XRPL_ASSERT(result.in == limit, "xrpl::ceil_in_impl : result matches limit");
XRPL_ASSERT(result.in == limit, "xrpl::ceilInImpl : result matches limit");
return result;
}
XRPL_ASSERT(amount.in <= limit, "xrpl::ceil_in_impl : result inside limit");
XRPL_ASSERT(amount.in <= limit, "xrpl::ceilInImpl : result inside limit");
return amount;
}
@@ -91,10 +91,10 @@ ceilOutImpl(Amounts const& amount, STAmount const& limit, bool roundUp, Quality
// Clamp in
if (result.in > amount.in)
result.in = amount.in;
XRPL_ASSERT(result.out == limit, "xrpl::ceil_out_impl : result matches limit");
XRPL_ASSERT(result.out == limit, "xrpl::ceilOutImpl : result matches limit");
return result;
}
XRPL_ASSERT(amount.out <= limit, "xrpl::ceil_out_impl : result inside limit");
XRPL_ASSERT(amount.out <= limit, "xrpl::ceilOutImpl : result inside limit");
return amount;
}
@@ -114,10 +114,10 @@ Quality
composedQuality(Quality const& lhs, Quality const& rhs)
{
STAmount const lhsRate(lhs.rate());
XRPL_ASSERT(lhsRate != beast::kZERO, "xrpl::composed_quality : nonzero left input");
XRPL_ASSERT(lhsRate != beast::kZERO, "xrpl::composedQuality : nonzero left input");
STAmount const rhsRate(rhs.rate());
XRPL_ASSERT(rhsRate != beast::kZERO, "xrpl::composed_quality : nonzero right input");
XRPL_ASSERT(rhsRate != beast::kZERO, "xrpl::composedQuality : nonzero right input");
STAmount const rate(mulRound(lhsRate, rhsRate, lhsRate.asset(), true));
@@ -125,7 +125,7 @@ composedQuality(Quality const& lhs, Quality const& rhs)
std::uint64_t const storedMantissa(rate.mantissa());
XRPL_ASSERT(
(storedExponent > 0) && (storedExponent <= 255), "xrpl::composed_quality : valid exponent");
(storedExponent > 0) && (storedExponent <= 255), "xrpl::composedQuality : valid exponent");
return Quality((storedExponent << (64 - 8)) | storedMantissa);
}

View File

@@ -61,7 +61,7 @@ operator<<(std::ostream& os, Port const& p)
if (!p.secure_gateway_nets_v4.empty() || !p.secure_gateway_nets_v6.empty())
{
os << "secureGateway nets:";
os << "secure_gateway nets:";
for (auto const& net : p.secure_gateway_nets_v4)
{
os << net.to_string();
@@ -287,7 +287,7 @@ parsePort(ParsedPort& port, Section const& section, std::ostream& log)
populate(section, "admin", log, port.admin_nets_v4, port.admin_nets_v6);
populate(
section, "secureGateway", log, port.secure_gateway_nets_v4, port.secure_gateway_nets_v6);
section, "secure_gateway", log, port.secure_gateway_nets_v4, port.secure_gateway_nets_v6);
set(port.user, "user", section);
set(port.password, "password", section);

View File

@@ -1010,7 +1010,14 @@ removeExpiredCredentials(ApplyView& view, std::vector<uint256> const& creds, bea
for (auto const& index : creds)
{
if (auto const sle = view.peek(keylet::credential(index)))
credentials::deleteSLE(view, sle, viewJ);
{
if (auto const ter = credentials::deleteSLE(view, sle, viewJ); !isTesSuccess(ter))
{
JLOG(viewJ.error())
<< "removeExpiredCredentials: failed to delete expired credential. Err: "
<< transToken(ter);
}
}
}
}

View File

@@ -158,7 +158,7 @@ invokePreflight(PreflightContext const& ctx)
// Should never happen
// LCOV_EXCL_START
JLOG(ctx.j.fatal()) << "Unknown transaction type in preflight: " << e.txnType;
UNREACHABLE("xrpl::invoke_preflight : unknown transaction type");
UNREACHABLE("xrpl::invokePreflight : unknown transaction type");
return {temUNKNOWN, TxConsequences{temUNKNOWN}};
// LCOV_EXCL_STOP
}
@@ -217,7 +217,7 @@ invokePreclaim(PreclaimContext const& ctx)
// Should never happen
// LCOV_EXCL_START
JLOG(ctx.j.fatal()) << "Unknown transaction type in preclaim: " << e.txnType;
UNREACHABLE("xrpl::invoke_preclaim : unknown transaction type");
UNREACHABLE("xrpl::invokePreclaim : unknown transaction type");
return temUNKNOWN;
// LCOV_EXCL_STOP
}
@@ -307,7 +307,7 @@ invokeApply(ApplyContext& ctx)
// Should never happen
// LCOV_EXCL_START
JLOG(ctx.journal.fatal()) << "Unknown transaction type in apply: " << e.txnType;
UNREACHABLE("xrpl::invoke_apply : unknown transaction type");
UNREACHABLE("xrpl::invokeApply : unknown transaction type");
return {temUNKNOWN, false};
// LCOV_EXCL_STOP
}

View File

@@ -105,8 +105,10 @@ CredentialAccept::doApply()
auto const credType(ctx_.tx[sfCredentialType]);
Keylet const credentialKey = keylet::credential(account_, issuer, credType);
auto const sleCred = view().peek(credentialKey); // Checked in preclaim()
if (!sleCred)
return tefINTERNAL; // LCOV_EXCL_LINE
if (checkExpired(sleCred, view().header().parentCloseTime))
if (checkExpired(*sleCred, view().header().parentCloseTime))
{
JLOG(j_.trace()) << "Credential is expired: " << sleCred->getText();
// delete expired credentials even if the transaction failed

View File

@@ -87,7 +87,7 @@ CredentialDelete::doApply()
return tefINTERNAL; // LCOV_EXCL_LINE
if ((subject != account_) && (issuer != account_) &&
!checkExpired(sleCred, ctx_.view().header().parentCloseTime))
!checkExpired(*sleCred, ctx_.view().header().parentCloseTime))
{
JLOG(j_.trace()) << "Can't delete non-expired credential.";
return tecNO_PERMISSION;

View File

@@ -141,6 +141,23 @@ LoanPay::calculateBaseFee(ReadView const& view, STTx const& tx)
NumberRoundModeGuard const mg(
tx.isFlag(tfLoanOverpayment) ? Number::RoundingMode::Upward
: Number::RoundingMode::Downward);
static_assert(kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION % kLOAN_PAYMENTS_PER_FEE_INCREMENT == 0);
std::int64_t constexpr kMAX_FEE_INCREMENTS =
kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION / kLOAN_PAYMENTS_PER_FEE_INCREMENT;
if (view.rules().enabled(fixSecurity3_1_3) &&
amount >= regularPayment * kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION)
{
// The payment handler will never process more than
// loanMaximumPaymentsPerTransaction payments (including overpayments),
// and one fee increment is charged for every
// loanPaymentsPerFeeIncrement, so don't charge more than
// loanMaximumPaymentsPerTransaction / loanPaymentsPerFeeIncrement fee
// increments.
return kMAX_FEE_INCREMENTS * normalCost;
}
// Estimate how many payments will be made
Number const numPaymentEstimate = static_cast<std::int64_t>(amount / regularPayment);
@@ -149,6 +166,10 @@ LoanPay::calculateBaseFee(ReadView const& view, STTx const& tx)
auto const feeIncrements = std::max(
std::int64_t(1),
static_cast<std::int64_t>(numPaymentEstimate / kLOAN_PAYMENTS_PER_FEE_INCREMENT));
XRPL_ASSERT(
!view.rules().enabled(fixSecurity3_1_3) || feeIncrements <= kMAX_FEE_INCREMENTS,
"xrpl::LoanPay::calculateBaseFee : number of fee increments is in "
"range");
return feeIncrements * normalCost;
}

View File

@@ -5,9 +5,12 @@
#include <test/jtx/acctdelete.h>
#include <test/jtx/amount.h>
#include <test/jtx/credentials.h>
#include <test/jtx/deposit.h>
#include <test/jtx/directory.h>
#include <test/jtx/fee.h>
#include <test/jtx/noop.h>
#include <test/jtx/pay.h>
#include <test/jtx/permissioned_domains.h>
#include <test/jtx/ter.h>
#include <test/jtx/ticket.h>
#include <test/jtx/txflags.h>
@@ -24,11 +27,13 @@
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/protocol/jss.h>
#include <cstdint>
#include <cstring>
#include <memory>
#include <string_view>
@@ -1028,6 +1033,121 @@ struct Credentials_test : public beast::unit_test::Suite
}
}
void
testRemoveExpiredCorruption(FeatureBitset features)
{
bool const fixEnabled = features[fixSecurity3_1_3];
testcase(
"removeExpired ignores deleteSLE failure " +
(fixEnabled ? std::string(" after fix") : std::string(" before fix")));
using namespace test::jtx;
char const credType[] = "abcde";
Account const issuer{"issuer"};
Account const subject{"subject"};
Account const becky{"becky"};
Env env{*this, features};
env.fund(XRP(10000), issuer, subject, becky);
env.close();
// Create credential with short expiration
auto jv = credentials::create(subject, issuer, credType);
uint32_t const expiration =
env.current()->header().parentCloseTime.time_since_epoch().count() + 40;
jv[sfExpiration.jsonName] = expiration;
env(jv);
env.close();
auto const credLE = credentials::ledgerEntry(env, subject, issuer, credType);
std::string const credIdx = credLE[jss::result][jss::index].asString();
// Subject accepts the credential
env(credentials::accept(subject, issuer, credType));
env.close();
// Build the credential keylet
auto const credKeylet =
keylet::credential(subject.id(), issuer.id(), Slice(credType, std::strlen(credType)));
// Verify credential exists and is accepted
{
auto const sleCred = env.current()->read(credKeylet);
BEAST_EXPECT(sleCred && sleCred->getFlags() & lsfAccepted);
}
// Create DepositPreauth
env(deposit::authCredentials(becky, {{subject, credType}}));
env.close();
// env();
auto jtx = env.jt(pay(subject, becky, XRP(100)), credentials::Ids({credIdx}));
if (!BEAST_EXPECT(jtx.stx))
return;
auto const stx = std::make_shared<STTx>(*jtx.stx);
// Create PermissionedDomain
env(pdomain::setTx(becky, {{issuer, credType}}));
env.close();
auto const objects = pdomain::getObjects(becky, env);
if (!BEAST_EXPECT(!objects.empty()))
return;
auto const domain = objects.begin()->first;
using namespace std::chrono_literals;
env.close(50s);
// Verify time has advanced past expiration
{
auto const sleCred = env.current()->read(credKeylet);
BEAST_EXPECT(
sleCred &&
xrpl::credentials::checkExpired(*sleCred, env.current()->header().parentCloseTime));
}
// Create an ApplyViewImpl on top of the current closed ledger
// and corrupt it by erasing the issuer's account SLE
auto const open = env.current();
ApplyViewImpl av(&*open, TapNone);
// Erase the issuer's account to simulate ledger corruption
auto sleIssuer = av.peek(keylet::account(issuer.id()));
if (!BEAST_EXPECT(sleIssuer))
return;
av.erase(sleIssuer);
BEAST_EXPECT(!av.exists(keylet::account(issuer.id())));
// Credential still exists before removeExpired
BEAST_EXPECT(av.exists(credKeylet));
// Call removeExpired on the corrupted view
STVector256 credHashes;
credHashes.pushBack(credKeylet.key);
beast::Journal const j{beast::Journal::getNullSink()};
auto const dpTer = xrpl::verifyDepositPreauth(*stx, av, subject, becky, {}, j);
auto sleCredAfter = av.read(credKeylet);
BEAST_EXPECT(sleCredAfter && (sleCredAfter->getFlags() & lsfAccepted));
auto const domTer = xrpl::verifyValidDomain(av, subject.id(), domain, j);
sleCredAfter = av.read(credKeylet);
BEAST_EXPECT(sleCredAfter && (sleCredAfter->getFlags() & lsfAccepted));
if (fixEnabled)
{
// removeExpired returns error, cred wasn't deleted
BEAST_EXPECT(dpTer == tecINTERNAL);
BEAST_EXPECT(domTer == tecINTERNAL);
}
else
{
// removeExpired returns true (claims it found & deleted expired
// creds)
BEAST_EXPECT(dpTer == tecEXPIRED);
BEAST_EXPECT(isTesSuccess(domTer));
}
}
void
run() override
{
@@ -1043,6 +1163,9 @@ struct Credentials_test : public beast::unit_test::Suite
testFlags(all - fixInvalidTxFlags);
testFlags(all);
testRPC();
testRemoveExpiredCorruption(all - fixSecurity3_1_3);
testRemoveExpiredCorruption(all | fixSecurity3_1_3);
}
};

View File

@@ -2797,8 +2797,8 @@ protected:
pseudoAcct,
tfLoanOverpayment,
[&](Keylet const& loanKeylet, VerifyLoanStatus const& verifyLoanStatus) {
// Estimate optimal values for loanPaymentsPerFeeIncrement and
// loanMaximumPaymentsPerTransaction.
// Estimate optimal values for kLOAN_PAYMENTS_PER_FEE_INCREMENT and
// kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION.
using namespace loan;
auto const state = getCurrentState(env, broker, verifyLoanStatus.keylet);
@@ -2816,7 +2816,8 @@ protected:
// Make all but the final payment
auto const numPayments = (state.paymentRemaining - 2);
STAmount const bigPayment{broker.asset, totalDue * numPayments};
XRPAmount const bigFee{baseFee * (numPayments / loanPaymentsPerFeeIncrement + 1)};
XRPAmount const bigFee{
baseFee * (numPayments / kLOAN_PAYMENTS_PER_FEE_INCREMENT + 1)};
time("ten payments", [&]() {
env(pay(borrower, loanKeylet.key, bigPayment), Fee(bigFee));
});
@@ -4753,15 +4754,17 @@ protected:
}
void
testDosLoanPay()
testDosLoanPay(FeatureBitset features)
{
bool const feeCapped = features[fixSecurity3_1_3];
// From FIND-005
testcase << "DoS LoanPay";
testcase << "DoS LoanPay: fee calculation " << (feeCapped ? "capped" : "uncapped");
using namespace jtx;
using namespace std::chrono_literals;
using namespace Lending;
Env env(*this, all_);
Env env(*this, features);
Account const issuer{"issuer"};
Account const lender{"lender"};
@@ -4770,6 +4773,8 @@ protected:
env.fund(XRP(1'000'000), issuer, lender, borrower);
env.close();
BEAST_EXPECT(feeCapped == env.current()->rules().enabled(fixSecurity3_1_3));
PrettyAsset const iouAsset = issuer[iouCurrency_];
env(trust(lender, iouAsset(100'000'000)));
env(trust(borrower, iouAsset(100'000'000)));
@@ -4782,52 +4787,117 @@ protected:
using namespace loan;
auto const loanSetFee = Fee(env.current()->fees().base * 2);
Number const principalRequest{1, 3};
Number const principalRequest{3959'37, -2};
auto const baseFee = env.current()->fees().base;
auto createJson = env.json(
auto const createJson = env.json(
set(borrower, broker.brokerID, principalRequest),
Fee(loanSetFee),
Json(sfCounterpartySignature, json::ObjectValue));
createJson["ClosePaymentFee"] = "0";
createJson["GracePeriod"] = 60;
createJson["InterestRate"] = 20930;
createJson["LateInterestRate"] = 77049;
createJson["LatePaymentFee"] = "0";
createJson["LoanServiceFee"] = "0";
createJson["OverpaymentFee"] = 7;
createJson["OverpaymentInterestRate"] = 66653;
createJson["PaymentInterval"] = 60;
createJson["PaymentTotal"] = 3239184;
createJson["PrincipalRequested"] = "3959.37";
Json(sfCounterpartySignature, json::ObjectValue),
kCLOSE_PAYMENT_FEE(0),
kGRACE_PERIOD(60),
kINTEREST_RATE(TenthBips32(20930)),
kLATE_INTEREST_RATE(TenthBips32(77049)),
kLATE_PAYMENT_FEE(0),
kLOAN_SERVICE_FEE(0),
kOVERPAYMENT_FEE(TenthBips32(7)),
kOVERPAYMENT_INTEREST_RATE(TenthBips32(66653)),
kPAYMENT_INTERVAL(60),
kPAYMENT_TOTAL(3239184));
// There are enough payments due on this loan that it only needs to be
// created once, and can be paid on multiple times. Just don't create a
// gazillion test cases.
auto const brokerStateBefore = env.le(keylet::loanbroker(broker.brokerID));
auto const loanSequence = brokerStateBefore->at(sfLoanSequence);
auto const keylet = keylet::loan(broker.brokerID, loanSequence);
createJson = env.json(createJson, Sig(sfCounterpartySignature, lender));
env(createJson, Ter(tesSUCCESS));
env(createJson, Sig(sfCounterpartySignature, lender));
env.close();
auto const stateBefore = getCurrentState(env, broker, keylet);
BEAST_EXPECT(stateBefore.paymentRemaining == 3239184);
BEAST_EXPECT(stateBefore.paymentRemaining > kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION);
auto const roundedPayment = [&]() {
auto const stateBefore = getCurrentState(env, broker, keylet);
BEAST_EXPECT(stateBefore.paymentRemaining == 3239184);
BEAST_EXPECT(stateBefore.paymentRemaining > kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION);
auto loanPayTx = env.json(pay(borrower, keylet.key, STAmount{broker.asset, Number{}}));
Number const amount{395937, -2};
loanPayTx["Amount"]["value"] = to_string(amount);
XRPAmount const payFee{
baseFee *
std::int64_t(
amount / stateBefore.periodicPayment / kLOAN_PAYMENTS_PER_FEE_INCREMENT + 1)};
env(loanPayTx, Ter(tesSUCCESS), Fee(payFee));
env.close();
return roundToAsset(
iouAsset,
stateBefore.periodicPayment,
stateBefore.loanScale,
Number::RoundingMode::Upward);
}();
auto const stateAfter = getCurrentState(env, broker, keylet);
BEAST_EXPECT(
stateAfter.paymentRemaining ==
stateBefore.paymentRemaining - kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION);
auto test = [&](int const payFactor,
int const feeFactor,
TER const expectedTer = tesSUCCESS) {
auto const stateBefore = getCurrentState(env, broker, keylet);
BEAST_EXPECT(stateBefore.paymentRemaining <= 3239184);
BEAST_EXPECT(stateBefore.paymentRemaining > kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION);
Number const amount = roundedPayment * payFactor;
auto loanPayTx = env.json(pay(borrower, keylet.key, STAmount{broker.asset, amount}));
XRPAmount const payFee{baseFee * feeFactor};
env(loanPayTx, Ter(expectedTer), Fee(payFee));
env.close();
auto const expectedChange = isTesSuccess(expectedTer)
? std::min(kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION, payFactor)
: 0;
auto const stateAfter = getCurrentState(env, broker, keylet);
BEAST_EXPECT(
stateAfter.paymentRemaining == stateBefore.paymentRemaining - expectedChange);
};
std::int64_t constexpr kMAX_FEE_INCREMENTS =
kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION / kLOAN_PAYMENTS_PER_FEE_INCREMENT;
TER const failWithoutFix = feeCapped ? (TER)tesSUCCESS : (TER)telINSUF_FEE_P;
// * Amount well above threshold -> capped fee
// The original test case - way over the limit - more fee is always ok
test(1819878, 363976);
// The capped fee is only sufficient if the amendment is enabled.
test(1819878, kMAX_FEE_INCREMENTS, failWithoutFix);
// * Amount exactly at threshold -> capped fee
test(kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION, kMAX_FEE_INCREMENTS);
// More fee is always ok
test(kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION, kMAX_FEE_INCREMENTS + 10);
// * Amount below threshold -> normal calculation
test(1, 1);
test(kLOAN_PAYMENTS_PER_FEE_INCREMENT * 2, 2);
test(0, 0, temBAD_AMOUNT);
test(0, 1, temBAD_AMOUNT);
// Fee difference rounds evenly
test(
kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION - 10,
((kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION - 10) / kLOAN_PAYMENTS_PER_FEE_INCREMENT) - 1,
telINSUF_FEE_P);
test(
kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION - 10,
((kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION - 10) / kLOAN_PAYMENTS_PER_FEE_INCREMENT));
// More fee is always ok
test(
kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION - 10,
((kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION - 10) / kLOAN_PAYMENTS_PER_FEE_INCREMENT) + 3);
// Fee rounds up
for (int under = 1; under < kLOAN_PAYMENTS_PER_FEE_INCREMENT; ++under)
{
test(
kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION - under,
kMAX_FEE_INCREMENTS - 1,
telINSUF_FEE_P);
test(kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION - under, kMAX_FEE_INCREMENTS);
}
// Only when you get one less fee increment can you pay less
test(
kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION - kLOAN_PAYMENTS_PER_FEE_INCREMENT,
kMAX_FEE_INCREMENTS - 1);
// And again, more fee is always ok.
test(
kLOAN_MAXIMUM_PAYMENTS_PER_TRANSACTION - kLOAN_PAYMENTS_PER_FEE_INCREMENT,
kMAX_FEE_INCREMENTS);
}
void
@@ -7248,7 +7318,8 @@ public:
testLoanPayDebtDecreaseInvariant();
testWrongMaxDebtBehavior();
testLoanPayComputePeriodicPaymentValidTotalInterestInvariant();
testDosLoanPay();
testDosLoanPay(all | fixSecurity3_1_3);
testDosLoanPay(all - fixSecurity3_1_3);
testLoanPayComputePeriodicPaymentValidTotalPrincipalPaidInvariant();
testLoanPayComputePeriodicPaymentValidTotalInterestPaidInvariant();
testLoanNextPaymentDueDateOverflow();

View File

@@ -1420,8 +1420,8 @@ public:
uint8_t tag2[] = "hello world some ascii 32b long"; // including 1 byte for NUL
uint256 bogieTag = xrpl::BaseUint<256>::fromVoid(tag1);
uint256 demonTag = xrpl::BaseUint<256>::fromVoid(tag2);
uint256 bogieTag = xrpl::BaseUInt<256>::fromVoid(tag1);
uint256 demonTag = xrpl::BaseUInt<256>::fromVoid(tag2);
// Attach phantom signers to alice and use them for a transaction.
env(signers(alice, 1, {{bogie_, 1, bogieTag}, {demon_, 1, demonTag}}));

View File

@@ -206,7 +206,7 @@ class Vault_test : public beast::unit_test::Suite
{
testcase(prefix + " fail to set domain on public vault");
auto tx = vault.set({.owner = owner, .id = keylet.key});
tx[sfDomainID] = to_string(BaseUint<256>(42ul));
tx[sfDomainID] = to_string(BaseUInt<256>(42ul));
env(tx, Ter{tecNO_PERMISSION});
env.close();
}
@@ -678,14 +678,14 @@ class Vault_test : public beast::unit_test::Suite
env(tx);
tx[sfFlags] = tx[sfFlags].asUInt() | tfVaultPrivate;
tx[sfDomainID] = to_string(BaseUint<256>(42ul));
tx[sfDomainID] = to_string(BaseUInt<256>(42ul));
env(tx, Ter{temDISABLED});
{
auto tx = vault.set({.owner = owner, .id = keylet.key});
env(tx, kDATA("Test"));
tx[sfDomainID] = to_string(BaseUint<256>(13ul));
tx[sfDomainID] = to_string(BaseUInt<256>(13ul));
env(tx, Ter{temDISABLED});
}
},
@@ -786,12 +786,12 @@ class Vault_test : public beast::unit_test::Suite
testcase("disabled permissioned domain");
auto [tx, keylet] = vault.create({.owner = owner, .asset = xrpIssue()});
tx[sfDomainID] = to_string(BaseUint<256>(42ul));
tx[sfDomainID] = to_string(BaseUInt<256>(42ul));
env(tx, Ter{temDISABLED});
{
auto tx = vault.set({.owner = owner, .id = keylet.key});
tx[sfDomainID] = to_string(BaseUint<256>(42ul));
tx[sfDomainID] = to_string(BaseUInt<256>(42ul));
env(tx, Ter{temDISABLED});
}
@@ -1079,7 +1079,7 @@ class Vault_test : public beast::unit_test::Suite
{
auto tx = tx1;
tx[sfDomainID] = to_string(BaseUint<256>(42ul));
tx[sfDomainID] = to_string(BaseUInt<256>(42ul));
env(tx, Ter{temMALFORMED});
}
@@ -1238,7 +1238,7 @@ class Vault_test : public beast::unit_test::Suite
Vault& vault) {
auto [tx, keylet] = vault.create({.owner = owner, .asset = asset});
tx[sfFlags] = tfVaultPrivate;
tx[sfDomainID] = to_string(BaseUint<256>(42ul));
tx[sfDomainID] = to_string(BaseUInt<256>(42ul));
testcase("non-existing domain");
env(tx, Ter{tecOBJECT_NOT_FOUND});
});
@@ -3065,7 +3065,7 @@ class Vault_test : public beast::unit_test::Suite
{
testcase("private vault cannot set non-existing domain");
auto tx = vault.set({.owner = owner, .id = keylet.key});
tx[sfDomainID] = to_string(BaseUint<256>(42ul));
tx[sfDomainID] = to_string(BaseUInt<256>(42ul));
env(tx, Ter{tecOBJECT_NOT_FOUND});
}

View File

@@ -49,7 +49,7 @@ struct Nonhash
struct base_uint_test : beast::unit_test::Suite
{
using test96 = BaseUint<96>;
using test96 = BaseUInt<96>;
static_assert(std::is_copy_constructible_v<test96>);
static_assert(std::is_copy_assignable_v<test96>);
@@ -68,7 +68,7 @@ struct base_uint_test : beast::unit_test::Suite
for (auto const& arg : kTEST_ARGS)
{
xrpl::BaseUint<64> const u{arg.first}, v{arg.second};
xrpl::BaseUInt<64> const u{arg.first}, v{arg.second};
BEAST_EXPECT(u < v);
BEAST_EXPECT(u <= v);
BEAST_EXPECT(u != v);
@@ -99,7 +99,7 @@ struct base_uint_test : beast::unit_test::Suite
for (auto const& arg : kTEST_ARGS)
{
xrpl::BaseUint<96> const u{arg.first}, v{arg.second};
xrpl::BaseUInt<96> const u{arg.first}, v{arg.second};
BEAST_EXPECT(u < v);
BEAST_EXPECT(u <= v);
BEAST_EXPECT(u != v);
@@ -327,16 +327,16 @@ struct base_uint_test : beast::unit_test::Suite
// Verify that constexpr base_uints interpret a string the same
// way parseHex() does.
struct StrBaseUint
struct StrBaseUInt
{
char const* const str;
test96 tst;
constexpr StrBaseUint(char const* s) : str(s), tst(s)
constexpr StrBaseUInt(char const* s) : str(s), tst(s)
{
}
};
constexpr StrBaseUint kTEST_CASES[] = {
constexpr StrBaseUInt kTEST_CASES[] = {
"000000000000000000000000",
"000000000000000000000001",
"fedcba9876543210ABCDEF91",
@@ -344,7 +344,7 @@ struct base_uint_test : beast::unit_test::Suite
"800000000000000000000000",
"fFfFfFfFfFfFfFfFfFfFfFfF"};
for (StrBaseUint const& t : kTEST_CASES)
for (StrBaseUInt const& t : kTEST_CASES)
{
test96 t96;
BEAST_EXPECT(t96.parseHex(t.str));

View File

@@ -112,7 +112,7 @@ class io_latency_probe_test : public beast::unit_test::Suite, public beast::test
struct TestSampler
{
beast::IoLatencyProbe<std::chrono::steady_clock> probe;
beast::IOLatencyProbe<std::chrono::steady_clock> probe;
std::vector<std::chrono::steady_clock::duration> durations;
TestSampler(std::chrono::milliseconds interval, boost::asio::io_context& ios)

View File

@@ -72,7 +72,7 @@ secureGateway(std::unique_ptr<Config> cfg)
{
(*cfg)[PORT_RPC].set("admin", "");
(*cfg)[PORT_WS].set("admin", "");
(*cfg)[PORT_RPC].set("secureGateway", getEnvLocalhostAddr());
(*cfg)[PORT_RPC].set("secure_gateway", getEnvLocalhostAddr());
return cfg;
}
@@ -89,8 +89,8 @@ secureGatewayLocalnet(std::unique_ptr<Config> cfg)
{
(*cfg)[PORT_RPC].set("admin", "");
(*cfg)[PORT_WS].set("admin", "");
(*cfg)[PORT_RPC].set("secureGateway", "127.0.0.0/8");
(*cfg)[PORT_WS].set("secureGateway", "127.0.0.0/8");
(*cfg)[PORT_RPC].set("secure_gateway", "127.0.0.0/8");
(*cfg)[PORT_WS].set("secure_gateway", "127.0.0.0/8");
return cfg;
}
std::unique_ptr<Config>
@@ -127,7 +127,7 @@ addGrpcConfigWithSecureGateway(std::unique_ptr<Config> cfg, std::string const& s
// Check https://man7.org/linux/man-pages/man7/ip.7.html
// "ip_local_port_range" section for using 0 ports
(*cfg)[SECTION_PORT_GRPC].set("port", "0");
(*cfg)[SECTION_PORT_GRPC].set("secureGateway", secureGateway);
(*cfg)[SECTION_PORT_GRPC].set("secure_gateway", secureGateway);
return cfg;
}

View File

@@ -55,7 +55,7 @@ public:
auto const data =
"00000000000000000000000055534400000000000000000000000000000000"
"000000000000000000";
BaseUint<320> uint;
BaseUInt<320> uint;
(void)uint.parseHex(data);
SerialIter iter(Slice(uint.data(), uint.size()));
STIssue const stissue(iter, sfAsset);
@@ -89,7 +89,7 @@ public:
auto const data =
"0000000000000000000000005553440000000000ae123a8556f3cf91154711"
"376afb0f894f832b3d";
BaseUint<320> uint;
BaseUInt<320> uint;
(void)uint.parseHex(data);
SerialIter iter(Slice(uint.data(), uint.size()));
STIssue const stissue(iter, sfAsset);
@@ -103,7 +103,7 @@ public:
try
{
auto const data = "0000000000000000000000000000000000000000";
BaseUint<160> uint;
BaseUInt<160> uint;
(void)uint.parseHex(data);
SerialIter iter(Slice(uint.data(), uint.size()));
STIssue const stissue(iter, sfAsset);

View File

@@ -141,16 +141,16 @@ fixConfigPorts(Config& config, Endpoints const& endpoints);
class ApplicationImp : public Application, public BasicApp
{
private:
class IoLatencySampler
class IOLatencySampler
{
private:
beast::insight::Event event_;
beast::Journal journal_;
beast::IoLatencyProbe<std::chrono::steady_clock> probe_;
beast::IOLatencyProbe<std::chrono::steady_clock> probe_;
std::atomic<std::chrono::milliseconds> lastSample_;
public:
IoLatencySampler(
IOLatencySampler(
beast::insight::Event ev,
beast::Journal journal,
std::chrono::milliseconds interval,
@@ -272,7 +272,7 @@ public:
std::unique_ptr<ResolverAsio> resolver_;
IoLatencySampler io_latency_sampler_;
IOLatencySampler io_latency_sampler_;
std::unique_ptr<GRPCServer> grpcServer_;
// NOLINTEND(readability-identifier-naming)

View File

@@ -361,7 +361,7 @@ GRPCServerImpl::GRPCServerImpl(Application& app)
Throw<std::runtime_error>("Error setting grpc server address");
}
auto const optSecureGateway = section.get("secureGateway");
auto const optSecureGateway = section.get("secure_gateway");
if (optSecureGateway)
{
try
@@ -376,8 +376,8 @@ GRPCServerImpl::GRPCServerImpl(Application& app)
if (addr.is_unspecified())
{
JLOG(journal_.error()) << "Can't pass unspecified IP in "
<< "secureGateway section of port_grpc";
Throw<std::runtime_error>("Unspecified IP in secureGateway section");
<< "secure_gateway section of port_grpc";
Throw<std::runtime_error>("Unspecified IP in secure_gateway section");
}
secureGatewayIPs_.emplace_back(addr);
@@ -386,7 +386,7 @@ GRPCServerImpl::GRPCServerImpl(Application& app)
catch (std::exception const&)
{
JLOG(journal_.error()) << "Error parsing secure gateway IPs for grpc server";
Throw<std::runtime_error>("Error parsing secureGateway section");
Throw<std::runtime_error>("Error parsing secure_gateway section");
}
}

View File

@@ -87,7 +87,7 @@ toString(TableType type)
return "AccountTransactions";
// LCOV_EXCL_START
default:
UNREACHABLE("xrpl::detail::to_string : invalid TableType");
UNREACHABLE("xrpl::detail::toString : invalid TableType");
return "Unknown";
// LCOV_EXCL_STOP
}

View File

@@ -132,7 +132,7 @@ makeFeaturesResponseHeader(
this topic, see https://github.com/openssl/openssl/issues/5509 and
https://github.com/XRPLF/rippled/issues/2413.
*/
static std::optional<BaseUint<512>>
static std::optional<BaseUInt<512>>
hashLastMessage(SSL const* ssl, size_t (*get)(const SSL*, void*, size_t))
{
constexpr std::size_t kSSL_MINIMUM_FINISHED_LENGTH = 12;
@@ -145,7 +145,7 @@ hashLastMessage(SSL const* ssl, size_t (*get)(const SSL*, void*, size_t))
sha512_hasher const h;
BaseUint<512> cookie;
BaseUInt<512> cookie;
SHA512(buf, len, cookie.data());
return cookie;
}

View File

@@ -475,14 +475,14 @@ OverlayImpl::addActive(std::shared_ptr<PeerImp> const& peer)
{
auto const result = peers_.emplace(peer->slot(), peer);
XRPL_ASSERT(result.second, "xrpl::OverlayImpl::add_active : peer is inserted");
XRPL_ASSERT(result.second, "xrpl::OverlayImpl::addActive : peer is inserted");
(void)result.second;
}
{
auto const result = ids_.emplace(
std::piecewise_construct, std::make_tuple(peer->id()), std::make_tuple(peer));
XRPL_ASSERT(result.second, "xrpl::OverlayImpl::add_active : peer ID is inserted");
XRPL_ASSERT(result.second, "xrpl::OverlayImpl::addActive : peer ID is inserted");
(void)result.second;
}

View File

@@ -143,7 +143,7 @@ Bootcache::onSuccess(beast::IP::Endpoint const& endpoint)
++entry.valence();
map_.erase(result.first);
result = map_.insert(value_type(endpoint, entry));
XRPL_ASSERT(result.second, "xrpl::PeerFinder::Bootcache::on_success : endpoint inserted");
XRPL_ASSERT(result.second, "xrpl::PeerFinder::Bootcache::onSuccess : endpoint inserted");
}
Entry const& entry(result.first->right);
JLOG(journal_.info()) << beast::Leftw(18) << "Bootcache connect " << endpoint << " with "
@@ -166,7 +166,7 @@ Bootcache::onFailure(beast::IP::Endpoint const& endpoint)
--entry.valence();
map_.erase(result.first);
result = map_.insert(value_type(endpoint, entry));
XRPL_ASSERT(result.second, "xrpl::PeerFinder::Bootcache::on_failure : endpoint inserted");
XRPL_ASSERT(result.second, "xrpl::PeerFinder::Bootcache::onFailure : endpoint inserted");
}
Entry const& entry(result.first->right);
auto const n(std::abs(entry.valence()));

View File

@@ -23,7 +23,7 @@ template <class Target, class HopContainer>
std::size_t
handoutOne(Target& t, HopContainer& h)
{
XRPL_ASSERT(!t.full(), "xrpl::PeerFinder::detail::handout_one : target is not full");
XRPL_ASSERT(!t.full(), "xrpl::PeerFinder::detail::handoutOne : target is not full");
for (auto it = h.begin(); it != h.end(); ++it)
{
auto const& e = *it;

View File

@@ -499,7 +499,7 @@ Livecache<Allocator>::HopsT::insert(Element& e)
{
XRPL_ASSERT(
e.endpoint.hops <= Tuning::kMAX_HOPS + 1,
"xrpl::PeerFinder::Livecache::hops_t::insert : maximum input hops");
"xrpl::PeerFinder::Livecache::HopsT::insert : maximum input hops");
// This has security implications without a shuffle
lists_[e.endpoint.hops].push_front(e);
++hist_[e.endpoint.hops];
@@ -511,7 +511,7 @@ Livecache<Allocator>::HopsT::reinsert(Element& e, std::uint32_t numHops)
{
XRPL_ASSERT(
numHops <= Tuning::kMAX_HOPS + 1,
"xrpl::PeerFinder::Livecache::hops_t::reinsert : maximum hops input");
"xrpl::PeerFinder::Livecache::HopsT::reinsert : maximum hops input");
auto& list = lists_[e.endpoint.hops];
list.erase(list.iterator_to(e));

View File

@@ -745,12 +745,12 @@ public:
// The object must exist in our table
XRPL_ASSERT(
slots.contains(slot->remoteEndpoint()),
"xrpl::PeerFinder::Logic::on_endpoints : valid slot input");
"xrpl::PeerFinder::Logic::onEndpoints : valid slot input");
// Must be handshaked!
XRPL_ASSERT(
slot->state() == Slot::State::Active,
"xrpl::PeerFinder::Logic::on_endpoints : valid slot state");
"xrpl::PeerFinder::Logic::onEndpoints : valid slot state");
clock_type::time_point const now(clock.now());
@@ -762,7 +762,7 @@ public:
for (auto const& ep : list)
{
XRPL_ASSERT(ep.hops, "xrpl::PeerFinder::Logic::on_endpoints : nonzero hops");
XRPL_ASSERT(ep.hops, "xrpl::PeerFinder::Logic::onEndpoints : nonzero hops");
slot->recent.insert(ep.address, ep.hops);

View File

@@ -141,7 +141,7 @@ doDepositAuthorized(RPC::JsonContext& context)
return result;
}
if (credentials::checkExpired(sleCred, ledger->header().parentCloseTime))
if (credentials::checkExpired(*sleCred, ledger->header().parentCloseTime))
{
RPC::injectError(RpcBadCredentials, "credentials are expired", result);
return result;