Merge branch 'pratik/otel-phase8-log-correlation' into pratik/otel-phase9-metric-gap-fill

Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
This commit is contained in:
Pratik Mankawde
2026-06-01 14:56:09 +01:00
1650 changed files with 81102 additions and 65833 deletions

View File

@@ -28,7 +28,7 @@ void
Section::append(std::vector<std::string> const& lines)
{
// <key> '=' <value>
static boost::regex const re1(
static boost::regex const kRe1(
"^" // start of line
"(?:\\s*)" // whitespace (optional)
"([a-zA-Z][_a-zA-Z0-9]*)" // <key>
@@ -43,8 +43,8 @@ Section::append(std::vector<std::string> const& lines)
lines_.reserve(lines_.size() + lines.size());
for (auto line : lines)
{
auto remove_comment = [](std::string& val) -> bool {
bool removed_trailing = false;
auto removeComment = [](std::string& val) -> bool {
bool removedTrailing = false;
auto comment = val.find('#');
while (comment != std::string::npos)
{
@@ -65,24 +65,24 @@ Section::append(std::vector<std::string> const& lines)
{
// this must be a real comment. Extract the value
// as a substring and stop looking.
val = trim_whitespace(val.substr(0, comment));
removed_trailing = true;
val = trimWhitespace(val.substr(0, comment));
removedTrailing = true;
break;
}
comment = val.find('#', comment);
}
return removed_trailing;
return removedTrailing;
};
if (remove_comment(line) && !line.empty())
had_trailing_comments_ = true;
if (removeComment(line) && !line.empty())
hadTrailingComments_ = true;
if (line.empty())
continue;
boost::smatch match;
if (boost::regex_match(line, match, re1))
if (boost::regex_match(line, match, kRe1))
{
set(match[1], match[2]);
}
@@ -126,10 +126,10 @@ BasicConfig::section(std::string const& name)
Section const&
BasicConfig::section(std::string const& name) const
{
static Section const none("");
static Section const kNone("");
auto const iter = map_.find(name);
if (iter == map_.end())
return none;
return kNone;
return iter->second;
}

View File

@@ -7,12 +7,12 @@ namespace xrpl {
CountedObjects&
CountedObjects::getInstance() noexcept
{
static CountedObjects instance;
static CountedObjects kInstance;
return instance;
return kInstance;
}
CountedObjects::CountedObjects() noexcept : m_count(0), m_head(nullptr)
CountedObjects::CountedObjects() noexcept : count_(0), head_(nullptr)
{
}
@@ -23,9 +23,9 @@ CountedObjects::getCounts(int minimumThreshold) const
// When other operations are concurrent, the count
// might be temporarily less than the actual count.
counts.reserve(m_count.load());
counts.reserve(count_.load());
for (auto* ctr = m_head.load(); ctr != nullptr; ctr = ctr->getNext())
for (auto* ctr = head_.load(); ctr != nullptr; ctr = ctr->getNext())
{
if (ctr->getCount() >= minimumThreshold)
counts.emplace_back(ctr->getName(), ctr->getCount());

View File

@@ -19,19 +19,20 @@
#include <iostream>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <utility>
#include <vector>
namespace xrpl {
Logs::Sink::Sink(std::string partition, beast::severities::Severity thresh, Logs& logs)
Logs::Sink::Sink(std::string partition, beast::Severity thresh, Logs& logs)
: beast::Journal::Sink(thresh, false), logs_(logs), partition_(std::move(partition))
{
}
void
Logs::Sink::write(beast::severities::Severity level, std::string const& text)
Logs::Sink::write(beast::Severity level, std::string const& text)
{
if (level < threshold())
return;
@@ -40,21 +41,21 @@ Logs::Sink::write(beast::severities::Severity level, std::string const& text)
}
void
Logs::Sink::writeAlways(beast::severities::Severity level, std::string const& text)
Logs::Sink::writeAlways(beast::Severity level, std::string const& text)
{
logs_.write(level, partition_, text, console());
}
//------------------------------------------------------------------------------
Logs::File::File() : m_stream(nullptr)
Logs::File::File() : stream_(nullptr)
{
}
bool
Logs::File::isOpen() const noexcept
{
return m_stream != nullptr;
return stream_ != nullptr;
}
bool
@@ -69,9 +70,9 @@ Logs::File::open(boost::filesystem::path const& path)
if (stream->good())
{
m_path = path;
path_ = path;
m_stream = std::move(stream);
stream_ = std::move(stream);
wasOpened = true;
}
@@ -84,35 +85,35 @@ Logs::File::closeAndReopen()
{
close();
return open(m_path);
return open(path_);
}
void
Logs::File::close()
{
m_stream = nullptr;
stream_ = nullptr;
}
void
Logs::File::write(char const* text)
{
if (m_stream != nullptr)
(*m_stream) << text;
if (stream_ != nullptr)
(*stream_) << text;
}
void
Logs::File::writeln(char const* text)
{
if (m_stream != nullptr)
if (stream_ != nullptr)
{
(*m_stream) << text;
(*m_stream) << std::endl;
(*stream_) << text;
(*stream_) << std::endl;
}
}
//------------------------------------------------------------------------------
Logs::Logs(beast::severities::Severity thresh) : thresh_(thresh) // default severity
Logs::Logs(beast::Severity thresh) : thresh_(thresh) // default severity
{
}
@@ -125,7 +126,7 @@ Logs::open(boost::filesystem::path const& pathToLogFile)
beast::Journal::Sink&
Logs::get(std::string const& name)
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
auto const result = sinks_.emplace(name, makeSink(name, thresh_));
return *result.first->second;
}
@@ -142,42 +143,42 @@ Logs::journal(std::string const& name)
return beast::Journal(get(name));
}
beast::severities::Severity
beast::Severity
Logs::threshold() const
{
return thresh_;
}
void
Logs::threshold(beast::severities::Severity thresh)
Logs::threshold(beast::Severity thresh)
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
thresh_ = thresh;
for (auto& sink : sinks_)
sink.second->threshold(thresh);
}
std::vector<std::pair<std::string, std::string>>
Logs::partition_severities() const
Logs::partitionSeverities() const
{
std::vector<std::pair<std::string, std::string>> list;
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
list.reserve(sinks_.size());
for (auto const& [name, sink] : sinks_)
list.emplace_back(name, toString(fromSeverity(sink->threshold())));
list.emplace_back(name, toString(sink->threshold()));
return list;
}
void
Logs::write(
beast::severities::Severity level,
beast::Severity level,
std::string const& partition,
std::string const& text,
bool console)
{
std::string s;
format(s, text, level, partition);
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
file_.writeln(s);
if (!silent_)
std::cerr << s << '\n';
@@ -189,7 +190,7 @@ Logs::write(
std::string
Logs::rotate()
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
bool const wasOpened = file_.closeAndReopen();
if (wasOpened)
return "The log file was closed and reopened.";
@@ -197,84 +198,27 @@ Logs::rotate()
}
std::unique_ptr<beast::Journal::Sink>
Logs::makeSink(std::string const& name, beast::severities::Severity threshold)
Logs::makeSink(std::string const& name, beast::Severity threshold)
{
return std::make_unique<Sink>(name, threshold, *this);
}
LogSeverity
Logs::fromSeverity(beast::severities::Severity level)
{
using namespace beast::severities;
switch (level)
{
case kTrace:
return lsTRACE;
case kDebug:
return lsDEBUG;
case kInfo:
return lsINFO;
case kWarning:
return lsWARNING;
case kError:
return lsERROR;
// LCOV_EXCL_START
default:
UNREACHABLE("xrpl::Logs::fromSeverity : invalid severity");
[[fallthrough]];
// LCOV_EXCL_STOP
case kFatal:
break;
}
return lsFATAL;
}
beast::severities::Severity
Logs::toSeverity(LogSeverity level)
{
using namespace beast::severities;
switch (level)
{
case lsTRACE:
return kTrace;
case lsDEBUG:
return kDebug;
case lsINFO:
return kInfo;
case lsWARNING:
return kWarning;
case lsERROR:
return kError;
// LCOV_EXCL_START
default:
UNREACHABLE("xrpl::Logs::toSeverity : invalid severity");
[[fallthrough]];
// LCOV_EXCL_STOP
case lsFATAL:
break;
}
return kFatal;
}
std::string
Logs::toString(LogSeverity s)
Logs::toString(beast::Severity s)
{
switch (s)
{
case lsTRACE:
case beast::Severity::Trace:
return "Trace";
case lsDEBUG:
case beast::Severity::Debug:
return "Debug";
case lsINFO:
case beast::Severity::Info:
return "Info";
case lsWARNING:
case beast::Severity::Warning:
return "Warning";
case lsERROR:
case beast::Severity::Error:
return "Error";
case lsFATAL:
case beast::Severity::Fatal:
return "Fatal";
// LCOV_EXCL_START
default:
@@ -284,61 +228,61 @@ Logs::toString(LogSeverity s)
}
}
LogSeverity
std::optional<beast::Severity>
Logs::fromString(std::string const& s)
{
if (boost::iequals(s, "trace"))
return lsTRACE;
return beast::Severity::Trace;
if (boost::iequals(s, "debug"))
return lsDEBUG;
return beast::Severity::Debug;
if (boost::iequals(s, "info") || boost::iequals(s, "information"))
return lsINFO;
return beast::Severity::Info;
if (boost::iequals(s, "warn") || boost::iequals(s, "warning") || boost::iequals(s, "warnings"))
return lsWARNING;
return beast::Severity::Warning;
if (boost::iequals(s, "error") || boost::iequals(s, "errors"))
return lsERROR;
return beast::Severity::Error;
if (boost::iequals(s, "fatal") || boost::iequals(s, "fatals"))
return lsFATAL;
return beast::Severity::Fatal;
return lsINVALID;
return std::nullopt;
}
void
Logs::format(
std::string& output,
std::string const& message,
beast::severities::Severity severity,
beast::Severity severity,
std::string const& partition)
{
output.reserve(message.size() + partition.size() + 100);
output = to_string(std::chrono::system_clock::now());
output = xrpl::to_string(std::chrono::system_clock::now());
output += " ";
if (!partition.empty())
output += partition + ":";
using namespace beast::severities;
using beast::Severity;
switch (severity)
{
case kTrace:
case Severity::Trace:
output += "TRC ";
break;
case kDebug:
case Severity::Debug:
output += "DBG ";
break;
case kInfo:
case Severity::Info:
output += "NFO ";
break;
case kWarning:
case Severity::Warning:
output += "WRN ";
break;
case kError:
case Severity::Error:
output += "ERR ";
break;
// LCOV_EXCL_START
@@ -346,7 +290,7 @@ Logs::format(
UNREACHABLE("xrpl::Logs::format : invalid severity");
[[fallthrough]];
// LCOV_EXCL_STOP
case kFatal:
case Severity::Fatal:
output += "FTL ";
break;
}
@@ -382,9 +326,9 @@ Logs::format(
output += message;
// Limit the maximum length of the output
if (output.size() > maximumMessageCharacters)
if (output.size() > kMaximumMessageCharacters)
{
output.resize(maximumMessageCharacters - 3);
output.resize(kMaximumMessageCharacters - 3);
output += "...";
}
@@ -427,7 +371,7 @@ class DebugSink
private:
std::reference_wrapper<beast::Journal::Sink> sink_;
std::unique_ptr<beast::Journal::Sink> holder_;
std::mutex m_;
std::mutex mtx_;
public:
DebugSink() : sink_(beast::Journal::getNullSink())
@@ -445,7 +389,7 @@ public:
std::unique_ptr<beast::Journal::Sink>
set(std::unique_ptr<beast::Journal::Sink> sink)
{
std::lock_guard const _(m_);
std::scoped_lock const _(mtx_);
using std::swap;
swap(holder_, sink);
@@ -465,7 +409,7 @@ public:
beast::Journal::Sink&
get()
{
std::lock_guard const _(m_);
std::scoped_lock const _(mtx_);
return sink_.get();
}
};
@@ -473,8 +417,8 @@ public:
static DebugSink&
debugSink()
{
static DebugSink _;
return _;
static DebugSink kInst;
return kInst;
}
std::unique_ptr<beast::Journal::Sink>

View File

@@ -86,7 +86,7 @@ mallocTrim(std::string_view tag, beast::Journal journal)
// Keep glibc malloc_trim padding at 0 (default): 12h Mainnet tests across 0/256KB/1MB/16MB
// showed no clear, consistent benefit from custom padding—0 provided the best overall balance
// of RSS reduction and trim-latency stability without adding a tuning surface.
constexpr std::size_t TRIM_PAD = 0;
static constexpr std::size_t kTrimPad = 0;
report.supported = true;
@@ -110,16 +110,16 @@ mallocTrim(std::string_view tag, beast::Journal journal)
long const rssBeforeKB = detail::parseStatmRSSkB(statmBefore);
struct rusage ru0{};
bool const have_ru0 = getRusageThread(ru0);
bool const haveRu0 = getRusageThread(ru0);
auto const t0 = std::chrono::steady_clock::now();
report.trimResult = detail::mallocTrimWithPad(TRIM_PAD);
report.trimResult = detail::mallocTrimWithPad(kTrimPad);
auto const t1 = std::chrono::steady_clock::now();
struct rusage ru1{};
bool const have_ru1 = getRusageThread(ru1);
bool const haveRu1 = getRusageThread(ru1);
auto const statmAfter = readFile(statmPath);
long const rssAfterKB = detail::parseStatmRSSkB(statmAfter);
@@ -129,7 +129,7 @@ mallocTrim(std::string_view tag, beast::Journal journal)
report.rssAfterKB = rssAfterKB;
report.durationUs = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0);
if (have_ru0 && have_ru1)
if (haveRu0 && haveRu1)
{
report.minfltDelta = ru1.ru_minflt - ru0.ru_minflt;
report.majfltDelta = ru1.ru_majflt - ru0.ru_majflt;
@@ -140,7 +140,7 @@ mallocTrim(std::string_view tag, beast::Journal journal)
: (static_cast<std::int64_t>(rssAfterKB) - static_cast<std::int64_t>(rssBeforeKB));
JLOG(journal.debug()) << "malloc_trim tag=" << tagStr << " result=" << report.trimResult
<< " pad=" << TRIM_PAD << " bytes"
<< " pad=" << kTrimPad << " bytes"
<< " rss_before=" << rssBeforeKB << "kB"
<< " rss_after=" << rssAfterKB << "kB"
<< " delta=" << deltaKB << "kB"
@@ -150,7 +150,7 @@ mallocTrim(std::string_view tag, beast::Journal journal)
}
else
{
report.trimResult = detail::mallocTrimWithPad(TRIM_PAD);
report.trimResult = detail::mallocTrimWithPad(kTrimPad);
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -40,7 +40,7 @@ namespace xrpl {
template <class Derived>
class AsyncObject
{
AsyncObject() : m_pending(0)
AsyncObject() : pending_(0)
{
}
@@ -48,7 +48,7 @@ public:
~AsyncObject()
{
// Destroying the object with I/O pending? Not a clean exit!
XRPL_ASSERT(m_pending.load() == 0, "xrpl::AsyncObject::~AsyncObject : nothing pending");
XRPL_ASSERT(pending_.load() == 0, "xrpl::AsyncObject::~AsyncObject : nothing pending");
}
/** RAII container that maintains the count of pending I/O.
@@ -58,45 +58,45 @@ public:
class CompletionCounter
{
public:
explicit CompletionCounter(Derived* owner) : m_owner(owner)
explicit CompletionCounter(Derived* owner) : owner_(owner)
{
++m_owner->m_pending;
++owner_->pending_;
}
CompletionCounter(CompletionCounter const& other) : m_owner(other.m_owner)
CompletionCounter(CompletionCounter const& other) : owner_(other.owner_)
{
++m_owner->m_pending;
++owner_->pending_;
}
~CompletionCounter()
{
if (--m_owner->m_pending == 0)
m_owner->asyncHandlersComplete();
if (--owner_->pending_ == 0)
owner_->asyncHandlersComplete();
}
CompletionCounter&
operator=(CompletionCounter const&) = delete;
private:
Derived* m_owner;
Derived* owner_;
};
void
addReference()
{
++m_pending;
++pending_;
}
void
removeReference()
{
if (--m_pending == 0)
if (--pending_ == 0)
(static_cast<Derived*>(this))->asyncHandlersComplete();
}
private:
// The number of handlers pending.
std::atomic<int> m_pending;
std::atomic<int> pending_;
friend Derived;
};
@@ -106,18 +106,18 @@ class ResolverAsioImpl : public ResolverAsio, public AsyncObject<ResolverAsioImp
public:
using HostAndPort = std::pair<std::string, std::string>;
beast::Journal m_journal;
beast::Journal journal;
boost::asio::io_context& m_io_context;
boost::asio::strand<boost::asio::io_context::executor_type> m_strand;
boost::asio::ip::tcp::resolver m_resolver;
boost::asio::io_context& ioContext;
boost::asio::strand<boost::asio::io_context::executor_type> strand;
boost::asio::ip::tcp::resolver resolver;
std::condition_variable m_cv;
std::mutex m_mut;
bool m_asyncHandlersCompleted{true};
std::condition_variable cv;
std::mutex mut;
bool asyncHandlersCompleted{true};
std::atomic<bool> m_stop_called;
std::atomic<bool> m_stopped;
std::atomic<bool> stopCalled;
std::atomic<bool> stopped;
// Represents a unit of work for the resolver to do
struct Work
@@ -126,30 +126,30 @@ public:
HandlerType handler;
template <class StringSequence>
Work(StringSequence const& names_, HandlerType handler_) : handler(std::move(handler_))
Work(StringSequence const& inNames, HandlerType handler) : handler(std::move(handler))
{
names.reserve(names_.size());
names.reserve(inNames.size());
std::reverse_copy(names_.begin(), names_.end(), std::back_inserter(names));
std::reverse_copy(inNames.begin(), inNames.end(), std::back_inserter(names));
}
};
std::deque<Work> m_work;
std::deque<Work> work;
ResolverAsioImpl(boost::asio::io_context& io_context, beast::Journal journal)
: m_journal(journal)
, m_io_context(io_context)
, m_strand(boost::asio::make_strand(io_context))
, m_resolver(io_context)
, m_stop_called(false)
, m_stopped(true)
ResolverAsioImpl(boost::asio::io_context& ioContext, beast::Journal journal)
: journal(journal)
, ioContext(ioContext)
, strand(boost::asio::make_strand(ioContext))
, resolver(ioContext)
, stopCalled(false)
, stopped(true)
{
}
~ResolverAsioImpl() override
{
XRPL_ASSERT(m_work.empty(), "xrpl::ResolverAsioImpl::~ResolverAsioImpl : no pending work");
XRPL_ASSERT(m_stopped, "xrpl::ResolverAsioImpl::~ResolverAsioImpl : stopped");
XRPL_ASSERT(work.empty(), "xrpl::ResolverAsioImpl::~ResolverAsioImpl : no pending work");
XRPL_ASSERT(stopped, "xrpl::ResolverAsioImpl::~ResolverAsioImpl : stopped");
}
//-------------------------------------------------------------------------
@@ -157,9 +157,9 @@ public:
void
asyncHandlersComplete()
{
std::unique_lock<std::mutex> const lk{m_mut};
m_asyncHandlersCompleted = true;
m_cv.notify_all();
std::unique_lock<std::mutex> const lk{mut};
asyncHandlersCompleted = true;
cv.notify_all();
}
//--------------------------------------------------------------------------
@@ -171,80 +171,79 @@ public:
void
start() override
{
XRPL_ASSERT(m_stopped == true, "xrpl::ResolverAsioImpl::start : stopped");
XRPL_ASSERT(m_stop_called == false, "xrpl::ResolverAsioImpl::start : not stopping");
XRPL_ASSERT(stopped == true, "xrpl::ResolverAsioImpl::start : stopped");
XRPL_ASSERT(stopCalled == false, "xrpl::ResolverAsioImpl::start : not stopping");
if (m_stopped.exchange(false))
if (stopped.exchange(false))
{
{
std::lock_guard const lk{m_mut};
m_asyncHandlersCompleted = false;
std::scoped_lock const lk{mut};
asyncHandlersCompleted = false;
}
addReference();
}
}
void
stop_async() override
stopAsync() override
{
if (!m_stop_called.exchange(true))
if (!stopCalled.exchange(true))
{
boost::asio::dispatch(
m_io_context,
ioContext,
boost::asio::bind_executor(
m_strand,
std::bind(&ResolverAsioImpl::do_stop, this, CompletionCounter(this))));
strand, std::bind(&ResolverAsioImpl::doStop, this, CompletionCounter(this))));
JLOG(m_journal.debug()) << "Queued a stop request";
JLOG(journal.debug()) << "Queued a stop request";
}
}
void
stop() override
{
stop_async();
stopAsync();
JLOG(m_journal.debug()) << "Waiting to stop";
std::unique_lock<std::mutex> lk{m_mut};
m_cv.wait(lk, [this] { return m_asyncHandlersCompleted; });
JLOG(journal.debug()) << "Waiting to stop";
std::unique_lock<std::mutex> lk{mut};
cv.wait(lk, [this] { return asyncHandlersCompleted; });
lk.unlock();
JLOG(m_journal.debug()) << "Stopped";
JLOG(journal.debug()) << "Stopped";
}
void
resolve(std::vector<std::string> const& names, HandlerType const& handler) override
{
XRPL_ASSERT(m_stop_called == false, "xrpl::ResolverAsioImpl::resolve : not stopping");
XRPL_ASSERT(stopCalled == false, "xrpl::ResolverAsioImpl::resolve : not stopping");
XRPL_ASSERT(!names.empty(), "xrpl::ResolverAsioImpl::resolve : names non-empty");
// TODO NIKB use rvalue references to construct and move
// reducing cost.
boost::asio::dispatch(
m_io_context,
ioContext,
boost::asio::bind_executor(
m_strand,
strand,
std::bind(
&ResolverAsioImpl::do_resolve, this, names, handler, CompletionCounter(this))));
&ResolverAsioImpl::doResolve, this, names, handler, CompletionCounter(this))));
}
//-------------------------------------------------------------------------
// Resolver
void
do_stop(CompletionCounter)
doStop(CompletionCounter)
{
XRPL_ASSERT(m_stop_called == true, "xrpl::ResolverAsioImpl::do_stop : stopping");
XRPL_ASSERT(stopCalled == true, "xrpl::ResolverAsioImpl::doStop : stopping");
if (!m_stopped.exchange(true))
if (!stopped.exchange(true))
{
m_work.clear();
m_resolver.cancel();
work.clear();
resolver.cancel();
removeReference();
}
}
void
do_finish(
doFinish(
std::string name,
boost::system::error_code const& ec,
HandlerType handler,
@@ -263,7 +262,7 @@ public:
{
while (iter != results.end())
{
addresses.push_back(beast::IPAddressConversion::from_asio(*iter));
addresses.push_back(beast::IPAddressConversion::fromAsio(*iter));
++iter;
}
}
@@ -271,9 +270,9 @@ public:
handler(name, addresses);
boost::asio::post(
m_io_context,
ioContext,
boost::asio::bind_executor(
m_strand, std::bind(&ResolverAsioImpl::do_work, this, CompletionCounter(this))));
strand, std::bind(&ResolverAsioImpl::doWork, this, CompletionCounter(this))));
}
static HostAndPort
@@ -282,7 +281,7 @@ public:
// first attempt to parse as an endpoint (IP addr + port).
// If that doesn't succeed, fall back to generic name + port parsing
if (auto const result = beast::IP::Endpoint::from_string_checked(str))
if (auto const result = beast::IP::Endpoint::fromStringChecked(str))
{
return make_pair(result->address().to_string(), std::to_string(result->port()));
}
@@ -292,20 +291,20 @@ public:
// a port separator
// Attempt to find the first and last non-whitespace
auto const find_whitespace =
auto const findWhitespace =
std::bind(&std::isspace<std::string::value_type>, std::placeholders::_1, std::locale());
auto host_first = std::ranges::find_if_not(str, find_whitespace);
auto hostFirst = std::ranges::find_if_not(str, findWhitespace);
auto port_last =
std::ranges::find_if_not(std::ranges::reverse_view(str), find_whitespace).base();
auto portLast =
std::ranges::find_if_not(std::ranges::reverse_view(str), findWhitespace).base();
// This should only happen for all-whitespace strings
if (host_first >= port_last)
if (hostFirst >= portLast)
return std::make_pair(std::string(), std::string());
// Attempt to find the first and last valid port separators
auto const find_port_separator = [](char const c) -> bool {
auto const findPortSeparator = [](char const c) -> bool {
if (std::isspace(static_cast<unsigned char>(c)))
return true;
@@ -315,51 +314,50 @@ public:
return false;
};
auto host_last = std::find_if(host_first, port_last, find_port_separator);
auto hostLast = std::find_if(hostFirst, portLast, findPortSeparator);
auto port_first = std::find_if_not(host_last, port_last, find_port_separator);
auto portFirst = std::find_if_not(hostLast, portLast, findPortSeparator);
return make_pair(std::string(host_first, host_last), std::string(port_first, port_last));
return make_pair(std::string(hostFirst, hostLast), std::string(portFirst, portLast));
}
void
do_work(CompletionCounter)
doWork(CompletionCounter)
{
if (m_stop_called)
if (stopCalled)
return;
// We don't have any work to do at this time
if (m_work.empty())
if (work.empty())
return;
std::string const name(m_work.front().names.back());
HandlerType const handler(m_work.front().handler);
std::string const name(work.front().names.back());
HandlerType const handler(work.front().handler);
m_work.front().names.pop_back();
work.front().names.pop_back();
if (m_work.front().names.empty())
m_work.pop_front();
if (work.front().names.empty())
work.pop_front();
auto const [host, port] = parseName(name);
if (host.empty())
{
JLOG(m_journal.error()) << "Unable to parse '" << name << "'";
JLOG(journal.error()) << "Unable to parse '" << name << "'";
boost::asio::post(
m_io_context,
ioContext,
boost::asio::bind_executor(
m_strand,
std::bind(&ResolverAsioImpl::do_work, this, CompletionCounter(this))));
strand, std::bind(&ResolverAsioImpl::doWork, this, CompletionCounter(this))));
return;
}
m_resolver.async_resolve(
resolver.async_resolve(
host,
port,
std::bind(
&ResolverAsioImpl::do_finish,
&ResolverAsioImpl::doFinish,
this,
name,
std::placeholders::_1,
@@ -369,24 +367,24 @@ public:
}
void
do_resolve(std::vector<std::string> const& names, HandlerType const& handler, CompletionCounter)
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 (!m_stop_called)
if (!stopCalled)
{
m_work.emplace_back(names, handler);
work.emplace_back(names, handler);
JLOG(m_journal.debug()) << "Queued new job with " << names.size() << " tasks. "
<< m_work.size() << " jobs outstanding.";
JLOG(journal.debug()) << "Queued new job with " << names.size() << " tasks. "
<< work.size() << " jobs outstanding.";
if (!m_work.empty())
if (!work.empty())
{
boost::asio::post(
m_io_context,
ioContext,
boost::asio::bind_executor(
m_strand,
std::bind(&ResolverAsioImpl::do_work, this, CompletionCounter(this))));
strand,
std::bind(&ResolverAsioImpl::doWork, this, CompletionCounter(this))));
}
}
}
@@ -395,9 +393,9 @@ public:
//-----------------------------------------------------------------------------
std::unique_ptr<ResolverAsio>
ResolverAsio::New(boost::asio::io_context& io_context, beast::Journal journal)
ResolverAsio::make(boost::asio::io_context& ioContext, beast::Journal journal)
{
return std::make_unique<ResolverAsioImpl>(io_context, journal);
return std::make_unique<ResolverAsioImpl>(ioContext, journal);
}
//-----------------------------------------------------------------------------

View File

@@ -34,10 +34,10 @@ sqlBlobLiteral(Blob const& blob)
}
bool
parseUrl(parsedURL& pUrl, std::string const& strUrl)
parseUrl(ParsedUrl& pUrl, std::string const& strUrl)
{
// scheme://username:password@hostname:port/rest
static boost::regex const reUrl(
static boost::regex const kReUrl(
"(?i)\\`\\s*"
// required scheme
"([[:alpha:]][-+.[:alpha:][:digit:]]*?):"
@@ -58,7 +58,7 @@ parseUrl(parsedURL& pUrl, std::string const& strUrl)
// Bail if there is no match.
try
{
if (!boost::regex_match(strUrl, smMatch, reUrl))
if (!boost::regex_match(strUrl, smMatch, kReUrl))
return false;
}
catch (...)
@@ -74,7 +74,7 @@ parseUrl(parsedURL& pUrl, std::string const& strUrl)
// We need to use Endpoint to parse the domain to
// strip surrounding brackets from IPv6 addresses,
// e.g. [::1] => ::1.
auto const result = beast::IP::Endpoint::from_string_checked(domain);
auto const result = beast::IP::Endpoint::fromStringChecked(domain);
pUrl.domain = result ? result->address().to_string() : domain;
std::string const port = smMatch[5];
if (!port.empty())
@@ -94,14 +94,14 @@ parseUrl(parsedURL& pUrl, std::string const& strUrl)
}
std::string
trim_whitespace(std::string str)
trimWhitespace(std::string str)
{
boost::trim(str);
return str;
}
std::optional<std::uint64_t>
to_uint64(std::string const& s)
toUInt64(std::string const& s)
{
std::uint64_t result = 0;
if (beast::lexicalCastChecked(result, s))
@@ -120,7 +120,7 @@ isProperlyFormedTomlDomain(std::string_view domain)
// obviously wrong domain names but it isn't perfect. It does not
// really support IDNs. If this turns out to be an issue, a more
// thorough regex can be used or this check can just be removed.
static boost::regex const re(
static boost::regex const kRE(
"^" // Beginning of line
"(" // Beginning of a segment
"(?!-)" // - must not begin with '-'
@@ -133,7 +133,7 @@ isProperlyFormedTomlDomain(std::string_view domain)
,
boost::regex_constants::optimize);
return boost::regex_match(domain.begin(), domain.end(), re);
return boost::regex_match(domain.begin(), domain.end(), kRE);
}
} // namespace xrpl

View File

@@ -1,3 +1,4 @@
#include <xrpl/basics/UptimeClock.h>
#include <atomic>
@@ -6,15 +7,15 @@
namespace xrpl {
std::atomic<UptimeClock::rep> UptimeClock::now_{0}; // seconds since start
std::atomic<bool> UptimeClock::stop_{false}; // stop update thread
std::atomic<UptimeClock::rep> UptimeClock::kNow{0}; // seconds since start
std::atomic<bool> UptimeClock::kStop{false}; // stop update thread
// On xrpld shutdown, cancel and wait for the update thread
UptimeClock::update_thread::~update_thread()
UptimeClock::UpdateThread::~UpdateThread()
{
if (joinable())
{
stop_ = true;
kStop = true;
// This join() may take up to a 1s, but happens only
// once at xrpld shutdown.
join();
@@ -22,20 +23,20 @@ UptimeClock::update_thread::~update_thread()
}
// Launch the update thread
UptimeClock::update_thread
UptimeClock::start_clock()
UptimeClock::UpdateThread
UptimeClock::startClock()
{
return update_thread{[] {
return UpdateThread{[] {
using namespace std;
using namespace std::chrono;
// Wake up every second and update now_
// Wake up every second and update kNow
auto next = system_clock::now() + 1s;
while (!stop_)
while (!kStop)
{
this_thread::sleep_until(next);
next += 1s;
++now_;
++kNow;
}
}};
}
@@ -48,10 +49,10 @@ UptimeClock::time_point
UptimeClock::now()
{
// start the update thread on first use
static auto const init = start_clock();
static auto const kInit = startClock();
// Return the number of seconds since xrpld start
return time_point{duration{now_}};
return time_point{duration{kNow}};
}
} // namespace xrpl

View File

@@ -45,17 +45,17 @@ namespace xrpl {
namespace base64 {
inline char const*
get_alphabet()
getAlphabet()
{
static char constexpr tab[] = {
static constexpr char kTab[] = {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"};
return &tab[0];
return &kTab[0];
}
inline signed char const*
get_inverse()
getInverse()
{
static signed char constexpr tab[] = {
static constexpr signed char kTab[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
@@ -73,17 +73,19 @@ get_inverse()
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
};
return &tab[0];
return &kTab[0];
}
/// Returns max chars needed to encode a base64 string
std::size_t constexpr encoded_size(std::size_t n)
constexpr std::size_t
encodedSize(std::size_t n)
{
return 4 * ((n + 2) / 3);
}
/// Returns max bytes needed to decode a base64 string
std::size_t constexpr decoded_size(std::size_t n)
constexpr std::size_t
decodedSize(std::size_t n)
{
return ((n / 4) * 3) + 2;
}
@@ -105,7 +107,7 @@ encode(void* dest, void const* src, std::size_t len)
{
char* out = static_cast<char*>(dest); // NOLINT(misc-const-correctness)
char const* in = static_cast<char const*>(src);
auto const tab = base64::get_alphabet();
auto const tab = base64::getAlphabet();
for (auto n = len / 3; n > 0; --n)
{
@@ -160,7 +162,7 @@ decode(void* dest, char const* src, std::size_t len)
int i = 0;
int j = 0;
auto const inverse = base64::get_inverse();
auto const inverse = base64::getInverse();
while (((len--) != 0u) && *in != '=')
{
@@ -197,19 +199,19 @@ decode(void* dest, char const* src, std::size_t len)
} // namespace base64
std::string
base64_encode(std::uint8_t const* data, std::size_t len)
base64Encode(std::uint8_t const* data, std::size_t len)
{
std::string dest;
dest.resize(base64::encoded_size(len));
dest.resize(base64::encodedSize(len));
dest.resize(base64::encode(&dest[0], data, len));
return dest;
}
std::string
base64_decode(std::string_view data)
base64Decode(std::string_view data)
{
std::string dest;
dest.resize(base64::decoded_size(data.size()));
dest.resize(base64::decodedSize(data.size()));
auto const result = base64::decode(&dest[0], data.data(), data.size());
dest.resize(result.first);
return dest;

View File

@@ -10,13 +10,13 @@
namespace xrpl {
void
LogThrow(std::string const& title)
logThrow(std::string const& title)
{
JLOG(debugLog().warn()) << title;
}
[[noreturn]] void
LogicError(std::string const& s) noexcept
logicError(std::string const& s) noexcept
{
// LCOV_EXCL_START
JLOG(debugLog().fatal()) << s;

View File

@@ -46,7 +46,7 @@ namespace openssl::detail {
@note If you increase the number of bits you need to generate new
default DH parameters and update defaultDH accordingly.
* */
int defaultRSAKeyBits = 2048;
int gDefaultRsaKeyBits = 2048;
/** The default DH parameters.
@@ -60,7 +60,7 @@ int defaultRSAKeyBits = 2048;
@note If you increase the number of bits you need to update
defaultRSAKeyBits accordingly.
*/
static constexpr char const defaultDH[] =
static constexpr char kDefaultDh[] =
"-----BEGIN DH PARAMETERS-----\n"
"MIIBCAKCAQEApKSWfR7LKy0VoZ/SDCObCvJ5HKX2J93RJ+QN8kJwHh+uuA8G+t8Q\n"
"MDRjL5HanlV/sKN9HXqBc7eqHmmbqYwIXKUt9MUZTLNheguddxVlc2IjdP5i9Ps8\n"
@@ -84,52 +84,52 @@ static constexpr char const defaultDH[] =
global or per-port basis, using the `ssl_ciphers` directive in the
config file.
*/
std::string const defaultCipherList = "TLSv1.2:!CBC:!DSS:!PSK:!eNULL:!aNULL";
std::string const kDefaultCipherList = "TLSv1.2:!CBC:!DSS:!PSK:!eNULL:!aNULL";
static void
initAnonymous(boost::asio::ssl::context& context)
{
using namespace openssl;
static auto defaultRSA = []() {
static auto kDefaultRsa = []() {
BIGNUM* bn = BN_new();
BN_set_word(bn, RSA_F4);
auto rsa = RSA_new();
if (!rsa)
LogicError("RSA_new failed");
logicError("RSA_new failed");
if (RSA_generate_key_ex(rsa, defaultRSAKeyBits, bn, nullptr) != 1)
LogicError("RSA_generate_key_ex failure");
if (RSA_generate_key_ex(rsa, gDefaultRsaKeyBits, bn, nullptr) != 1)
logicError("RSA_generate_key_ex failure");
BN_clear_free(bn);
return rsa;
}();
static auto defaultEphemeralPrivateKey = []() {
static auto kDefaultEphemeralPrivateKey = []() {
auto pkey = EVP_PKEY_new();
if (!pkey)
LogicError("EVP_PKEY_new failed");
logicError("EVP_PKEY_new failed");
// We need to up the reference count of here, since we are retaining a
// copy of the key for (potential) reuse.
if (RSA_up_ref(defaultRSA) != 1)
LogicError("EVP_PKEY_assign_RSA: incrementing reference count failed");
if (RSA_up_ref(kDefaultRsa) != 1)
logicError("EVP_PKEY_assign_RSA: incrementing reference count failed");
if (!EVP_PKEY_assign_RSA(pkey, defaultRSA))
LogicError("EVP_PKEY_assign_RSA failed");
if (!EVP_PKEY_assign_RSA(pkey, kDefaultRsa))
logicError("EVP_PKEY_assign_RSA failed");
return pkey;
}();
static auto defaultCert = []() {
static auto kDefaultCert = []() {
auto x509 = X509_new();
if (x509 == nullptr)
LogicError("X509_new failed");
logicError("X509_new failed");
// According to the standards (X.509 et al), the value should be one
// less than the actually certificate version we want. Since we want
@@ -147,7 +147,7 @@ initAnonymous(boost::asio::ssl::context& context)
buf[ret] = 0;
if (ASN1_TIME_set_string_X509(X509_get_notBefore(x509), buf) != 1)
LogicError("Unable to set certificate validity date");
logicError("Unable to set certificate validity date");
// And make it valid for two years
X509_gmtime_adj(X509_get_notAfter(x509), 2 * 365 * 24 * 60 * 60);
@@ -205,61 +205,61 @@ initAnonymous(boost::asio::ssl::context& context)
}
// And a private key
X509_set_pubkey(x509, defaultEphemeralPrivateKey);
X509_set_pubkey(x509, kDefaultEphemeralPrivateKey);
if (!X509_sign(x509, defaultEphemeralPrivateKey, EVP_sha256()))
LogicError("X509_sign failed");
if (!X509_sign(x509, kDefaultEphemeralPrivateKey, EVP_sha256()))
logicError("X509_sign failed");
return x509;
}();
SSL_CTX* const ctx = context.native_handle();
if (SSL_CTX_use_certificate(ctx, defaultCert) <= 0)
LogicError("SSL_CTX_use_certificate failed");
if (SSL_CTX_use_certificate(ctx, kDefaultCert) <= 0)
logicError("SSL_CTX_use_certificate failed");
if (SSL_CTX_use_PrivateKey(ctx, defaultEphemeralPrivateKey) <= 0)
LogicError("SSL_CTX_use_PrivateKey failed");
if (SSL_CTX_use_PrivateKey(ctx, kDefaultEphemeralPrivateKey) <= 0)
logicError("SSL_CTX_use_PrivateKey failed");
}
static void
initAuthenticated(
boost::asio::ssl::context& context,
std::string const& key_file,
std::string const& cert_file,
std::string const& chain_file)
std::string const& keyFile,
std::string const& certFile,
std::string const& chainFile)
{
auto fmt_error = [](boost::system::error_code ec) -> std::string {
auto fmtError = [](boost::system::error_code ec) -> std::string {
return " [" + std::to_string(ec.value()) + ": " + ec.message() + "]";
};
SSL_CTX* const ssl = context.native_handle();
bool cert_set = false;
bool certSet = false;
if (!cert_file.empty())
if (!certFile.empty())
{
boost::system::error_code ec;
// NOLINTNEXTLINE(bugprone-unused-return-value)
context.use_certificate_file(cert_file, boost::asio::ssl::context::pem, ec);
context.use_certificate_file(certFile, boost::asio::ssl::context::pem, ec);
if (ec)
LogicError("Problem with SSL certificate file" + fmt_error(ec));
logicError("Problem with SSL certificate file" + fmtError(ec));
cert_set = true;
certSet = true;
}
if (!chain_file.empty())
if (!chainFile.empty())
{
// VFALCO Replace fopen() with RAII
FILE* f = fopen(chain_file.c_str(), "r");
FILE* f = fopen(chainFile.c_str(), "r");
if (f == nullptr)
{
LogicError(
logicError(
"Problem opening SSL chain file" +
fmt_error(boost::system::error_code(errno, boost::system::generic_category())));
fmtError(boost::system::error_code(errno, boost::system::generic_category())));
}
try
@@ -271,21 +271,21 @@ initAuthenticated(
if (x == nullptr)
break;
if (!cert_set)
if (!certSet)
{
if (SSL_CTX_use_certificate(ssl, x) != 1)
{
LogicError(
logicError(
"Problem retrieving SSL certificate from chain "
"file.");
}
cert_set = true;
certSet = true;
}
else if (SSL_CTX_add_extra_chain_cert(ssl, x) != 1)
{
X509_free(x);
LogicError("Problem adding SSL chain certificate.");
logicError("Problem adding SSL chain certificate.");
}
}
@@ -294,32 +294,32 @@ initAuthenticated(
catch (std::exception const& ex)
{
fclose(f);
LogicError(
logicError(
std::string("Reading the SSL chain file generated an exception: ") + ex.what());
}
}
if (!key_file.empty())
if (!keyFile.empty())
{
boost::system::error_code ec;
// NOLINTNEXTLINE(bugprone-unused-return-value)
context.use_private_key_file(key_file, boost::asio::ssl::context::pem, ec);
context.use_private_key_file(keyFile, boost::asio::ssl::context::pem, ec);
if (ec)
{
LogicError("Problem using the SSL private key file" + fmt_error(ec));
logicError("Problem using the SSL private key file" + fmtError(ec));
}
}
if (SSL_CTX_check_private_key(ssl) != 1)
{
LogicError("Invalid key in SSL private key file.");
logicError("Invalid key in SSL private key file.");
}
}
std::shared_ptr<boost::asio::ssl::context>
get_context(std::string cipherList)
getContext(std::string cipherList)
{
auto c = std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23);
@@ -330,12 +330,12 @@ get_context(std::string cipherList)
boost::asio::ssl::context::no_compression);
if (cipherList.empty())
cipherList = defaultCipherList;
cipherList = kDefaultCipherList;
if (auto result = SSL_CTX_set_cipher_list(c->native_handle(), cipherList.c_str()); result != 1)
LogicError("SSL_CTX_set_cipher_list failed");
logicError("SSL_CTX_set_cipher_list failed");
c->use_tmp_dh({std::addressof(detail::defaultDH), sizeof(defaultDH)});
c->use_tmp_dh({std::addressof(detail::kDefaultDh), sizeof(kDefaultDh)});
// Disable all renegotiation support in TLS v1.2. This can help prevent
// exploitation of the bug described in CVE-2021-3499 (for details see
@@ -350,9 +350,9 @@ get_context(std::string cipherList)
//------------------------------------------------------------------------------
std::shared_ptr<boost::asio::ssl::context>
make_SSLContext(std::string const& cipherList)
makeSslContext(std::string const& cipherList)
{
auto context = openssl::detail::get_context(cipherList);
auto context = openssl::detail::getContext(cipherList);
openssl::detail::initAnonymous(*context);
// VFALCO NOTE, It seems the WebSocket context never has
// set_verify_mode called, for either setting of WEBSOCKET_SECURE
@@ -361,13 +361,13 @@ make_SSLContext(std::string const& cipherList)
}
std::shared_ptr<boost::asio::ssl::context>
make_SSLContextAuthed(
makeSslContextAuthed(
std::string const& keyFile,
std::string const& certFile,
std::string const& chainFile,
std::string const& cipherList)
{
auto context = openssl::detail::get_context(cipherList);
auto context = openssl::detail::getContext(cipherList);
openssl::detail::initAuthenticated(*context, keyFile, certFile, chainFile);
return context;
}

View File

@@ -15,7 +15,7 @@ mulDiv(std::uint64_t value, std::uint64_t mul, std::uint64_t div)
result /= div;
if (result > xrpl::muldiv_max)
if (result > xrpl::kMuldivMax)
return std::nullopt;
return static_cast<std::uint64_t>(result);

View File

@@ -13,9 +13,9 @@ namespace beast {
namespace {
// Updates the clock
class seconds_clock_thread
class SecondsClockThread
{
using Clock = basic_seconds_clock::Clock;
using Clock = BasicSecondsClock::Clock;
bool stop_{false};
std::mutex mut_;
@@ -24,8 +24,8 @@ class seconds_clock_thread
std::atomic<Clock::time_point::rep> tp_;
public:
~seconds_clock_thread();
seconds_clock_thread();
~SecondsClockThread();
SecondsClockThread();
Clock::time_point
now();
@@ -37,31 +37,31 @@ private:
static_assert(std::atomic<std::chrono::steady_clock::rep>::is_always_lock_free);
seconds_clock_thread::~seconds_clock_thread()
SecondsClockThread::~SecondsClockThread()
{
XRPL_ASSERT(
thread_.joinable(), "beast::seconds_clock_thread::~seconds_clock_thread : thread joinable");
thread_.joinable(), "beast::SecondsClockThread::~SecondsClockThread : thread joinable");
{
std::lock_guard const lock(mut_);
std::scoped_lock const lock(mut_);
stop_ = true;
} // publish stop_ asap so if waiting thread times-out, it will see it
cv_.notify_one();
thread_.join();
}
seconds_clock_thread::seconds_clock_thread() : tp_{Clock::now().time_since_epoch().count()}
SecondsClockThread::SecondsClockThread() : tp_{Clock::now().time_since_epoch().count()}
{
thread_ = std::thread(&seconds_clock_thread::run, this);
thread_ = std::thread(&SecondsClockThread::run, this);
}
seconds_clock_thread::Clock::time_point
seconds_clock_thread::now()
SecondsClockThread::Clock::time_point
SecondsClockThread::now()
{
return Clock::time_point{Clock::duration{tp_.load()}};
}
void
seconds_clock_thread::run()
SecondsClockThread::run()
{
std::unique_lock lock(mut_);
while (true)
@@ -78,11 +78,11 @@ seconds_clock_thread::run()
} // unnamed namespace
basic_seconds_clock::time_point
basic_seconds_clock::now()
BasicSecondsClock::time_point
BasicSecondsClock::now()
{
static seconds_clock_thread clk;
return clk.now();
static SecondsClockThread kClk;
return kClk.now();
}
} // namespace beast

View File

@@ -80,21 +80,19 @@ inline void
setCurrentThreadNameImpl(std::string_view name)
{
// truncate and set the thread name.
char boundedName[maxThreadNameLength + 1];
std::snprintf(
boundedName,
sizeof(boundedName),
"%.*s",
static_cast<int>(maxThreadNameLength),
name.data()); // NOLINT(bugprone-suspicious-stringview-data-usage)
char boundedName[kMaxThreadNameLength + 1];
auto const boundedSize =
name.size() < kMaxThreadNameLength ? name.size() : kMaxThreadNameLength;
name.copy(boundedName, boundedSize);
boundedName[boundedSize] = '\0';
pthread_setname_np(pthread_self(), boundedName);
#ifdef TRUNCATED_THREAD_NAME_LOGS
if (name.size() > maxThreadNameLength)
if (name.size() > kMaxThreadNameLength)
{
std::cerr << "WARNING: Thread name \"" << name << "\" (length " << name.size()
<< ") exceeds maximum of " << maxThreadNameLength << " characters on Linux.\n";
<< ") exceeds maximum of " << kMaxThreadNameLength << " characters on Linux.\n";
}
#endif
}
@@ -105,19 +103,19 @@ setCurrentThreadNameImpl(std::string_view name)
namespace beast {
namespace detail {
thread_local std::string threadName;
thread_local std::string gThreadName;
} // namespace detail
std::string
getCurrentThreadName()
{
return detail::threadName;
return detail::gThreadName;
}
void
setCurrentThreadName(std::string_view name)
{
detail::threadName = name;
detail::gThreadName = name;
detail::setCurrentThreadNameImpl(name);
}

View File

@@ -15,7 +15,7 @@
namespace beast {
std::string
print_identifiers(SemanticVersion::identifier_list const& list)
printIdentifiers(SemanticVersion::identifier_list const& list)
{
std::string ret;
@@ -61,10 +61,10 @@ chopUInt(int& value, int limit, std::string& input)
if (input.empty())
return false;
auto left_iter = std::ranges::find_if_not(
auto leftIter = std::ranges::find_if_not(
input, [](std::string::value_type c) { return std::isdigit(c, std::locale::classic()); });
std::string const item(input.begin(), left_iter);
std::string const item(input.begin(), leftIter);
// Must not be empty
if (item.empty())
@@ -84,14 +84,14 @@ chopUInt(int& value, int limit, std::string& input)
if (n < 0 || n > limit)
return false;
input.erase(input.begin(), left_iter);
input.erase(input.begin(), leftIter);
value = n;
return true;
}
bool
extract_identifier(std::string& value, bool allowLeadingZeroes, std::string& input)
extractIdentifier(std::string& value, bool allowLeadingZeroes, std::string& input)
{
// Must not be empty
if (input.empty())
@@ -114,7 +114,7 @@ extract_identifier(std::string& value, bool allowLeadingZeroes, std::string& inp
}
bool
extract_identifiers(
extractIdentifiers(
SemanticVersion::identifier_list& identifiers,
bool allowLeadingZeroes,
std::string& input)
@@ -126,7 +126,7 @@ extract_identifiers(
{
std::string s;
if (!extract_identifier(s, allowLeadingZeroes, input))
if (!extractIdentifier(s, allowLeadingZeroes, input))
return false;
identifiers.push_back(s);
} while (chop(".", input));
@@ -150,19 +150,19 @@ bool
SemanticVersion::parse(std::string_view input)
{
// May not have leading or trailing whitespace
auto left_iter = std::ranges::find_if_not(
auto leftIter = std::ranges::find_if_not(
input, [](std::string::value_type c) { return std::isspace(c, std::locale::classic()); });
auto right_iter =
auto rightIter =
std::ranges::find_if_not(std::ranges::reverse_view(input), [](std::string::value_type c) {
return std::isspace(c, std::locale::classic());
}).base();
// Must not be empty!
if (left_iter >= right_iter)
if (leftIter >= rightIter)
return false;
std::string version(left_iter, right_iter);
std::string version(leftIter, rightIter);
// May not have leading or trailing whitespace
if (version != input)
@@ -187,7 +187,7 @@ SemanticVersion::parse(std::string_view input)
// May have pre-release identifier list
if (chop("-", version))
{
if (!extract_identifiers(preReleaseIdentifiers, false, version))
if (!extractIdentifiers(preReleaseIdentifiers, false, version))
return false;
// Must not be empty
@@ -198,7 +198,7 @@ SemanticVersion::parse(std::string_view input)
// May have metadata identifier list
if (chop("+", version))
{
if (!extract_identifiers(metaData, true, version))
if (!extractIdentifiers(metaData, true, version))
return false;
// Must not be empty
@@ -220,13 +220,13 @@ SemanticVersion::print() const
if (!preReleaseIdentifiers.empty())
{
s += "-";
s += print_identifiers(preReleaseIdentifiers);
s += printIdentifiers(preReleaseIdentifiers);
}
if (!metaData.empty())
{
s += "+";
s += print_identifiers(metaData);
s += printIdentifiers(metaData);
}
return s;

View File

@@ -21,12 +21,12 @@ namespace detail {
class GroupImp : public std::enable_shared_from_this<GroupImp>, public Group
{
public:
std::string const m_name;
Collector::ptr m_collector;
std::string const name_;
Collector::ptr collector_;
GroupImp(std::string name_, Collector::ptr collector)
: m_name(std::move(name_)), m_collector(std::move(collector))
public:
GroupImp(std::string name, Collector::ptr collector)
: name_(std::move(name)), collector_(std::move(collector))
{
}
@@ -35,43 +35,43 @@ public:
std::string const&
name() const override
{
return m_name;
return name_;
}
std::string
make_name(std::string const& name)
makeName(std::string const& name)
{
return m_name + "." + name;
return name_ + "." + name;
}
Hook
make_hook(HookImpl::HandlerType const& handler) override
makeHook(HookImpl::HandlerType const& handler) override
{
return m_collector->make_hook(handler);
return collector_->makeHook(handler);
}
Counter
make_counter(std::string const& name) override
makeCounter(std::string const& name) override
{
return m_collector->make_counter(make_name(name));
return collector_->makeCounter(makeName(name));
}
Event
make_event(std::string const& name) override
makeEvent(std::string const& name) override
{
return m_collector->make_event(make_name(name));
return collector_->makeEvent(makeName(name));
}
Gauge
make_gauge(std::string const& name) override
makeGauge(std::string const& name) override
{
return m_collector->make_gauge(make_name(name));
return collector_->makeGauge(makeName(name));
}
Meter
make_meter(std::string const& name) override
makeMeter(std::string const& name) override
{
return m_collector->make_meter(make_name(name));
return collector_->makeMeter(makeName(name));
}
GroupImp&
@@ -83,12 +83,12 @@ public:
class GroupsImp : public Groups
{
public:
using Items = std::unordered_map<std::string, std::shared_ptr<Group>, uhash<>>;
using Items = std::unordered_map<std::string, std::shared_ptr<Group>, Uhash<>>;
Collector::ptr m_collector;
Items m_items;
Collector::ptr collector;
Items items;
explicit GroupsImp(Collector::ptr collector) : m_collector(std::move(collector))
explicit GroupsImp(Collector::ptr collector) : collector(std::move(collector))
{
}
@@ -97,10 +97,10 @@ public:
Group::ptr const&
get(std::string const& name) override
{
std::pair<Items::iterator, bool> const result(m_items.emplace(name, Group::ptr()));
std::pair<Items::iterator, bool> const result(items.emplace(name, Group::ptr()));
Group::ptr& group(result.first->second);
if (result.second)
group = std::make_shared<GroupImp>(name, m_collector);
group = std::make_shared<GroupImp>(name, collector);
return group;
}
};
@@ -112,7 +112,7 @@ public:
Groups::~Groups() = default;
std::unique_ptr<Groups>
make_Groups(Collector::ptr const& collector)
makeGroups(Collector::ptr const& collector)
{
return std::make_unique<detail::GroupsImp>(collector);
}

View File

@@ -108,31 +108,31 @@ public:
~NullCollectorImp() override = default;
Hook
make_hook(HookImpl::HandlerType const&) override
makeHook(HookImpl::HandlerType const&) override
{
return Hook(std::make_shared<detail::NullHookImpl>());
}
Counter
make_counter(std::string const&) override
makeCounter(std::string const&) override
{
return Counter(std::make_shared<detail::NullCounterImpl>());
}
Event
make_event(std::string const&) override
makeEvent(std::string const&) override
{
return Event(std::make_shared<detail::NullEventImpl>());
}
Gauge
make_gauge(std::string const&) override
makeGauge(std::string const&) override
{
return Gauge(std::make_shared<detail::NullGaugeImpl>());
}
Meter
make_meter(std::string const&) override
makeMeter(std::string const&) override
{
return Meter(std::make_shared<detail::NullMeterImpl>());
}
@@ -143,7 +143,7 @@ public:
//------------------------------------------------------------------------------
std::shared_ptr<Collector>
NullCollector::New()
NullCollector::make()
{
return std::make_shared<detail::NullCollectorImp>();
}

View File

@@ -268,7 +268,7 @@ private:
opentelemetry::nostd::shared_ptr<metrics_api::ObservableInstrument> m_gauge;
/** Owning collector, used to invoke hooks before reading gauge values. */
std::shared_ptr<OTelCollectorImp> m_collector;
std::shared_ptr<OTelCollectorImp> collector_;
};
//------------------------------------------------------------------------------
@@ -578,9 +578,9 @@ OTelGaugeImpl::OTelGaugeImpl(
std::string const& name,
opentelemetry::nostd::shared_ptr<metrics_api::Meter> const& meter,
std::shared_ptr<OTelCollectorImp> const& collector)
: m_gauge(meter->CreateInt64ObservableGauge(name)), m_collector(collector)
: m_gauge(meter->CreateInt64ObservableGauge(name)), collector_(collector)
{
m_collector->addGauge(this);
collector_->addGauge(this);
m_gauge->AddCallback(gaugeCallback, this);
}
@@ -588,7 +588,7 @@ void
OTelGaugeImpl::gaugeCallback(opentelemetry::metrics::ObserverResult result, void* state)
{
auto* self = static_cast<OTelGaugeImpl*>(state);
self->m_collector->callHooks();
self->collector_->callHooks();
if (auto intResult = opentelemetry::nostd::get_if<
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::ObserverResultT<int64_t>>>(
&result))
@@ -600,7 +600,7 @@ OTelGaugeImpl::gaugeCallback(opentelemetry::metrics::ObserverResult result, void
OTelGaugeImpl::~OTelGaugeImpl()
{
m_gauge->RemoveCallback(gaugeCallback, this);
m_collector->removeGauge(this);
collector_->removeGauge(this);
}
void

View File

@@ -53,7 +53,7 @@ class StatsDMetricBase : public List<StatsDMetricBase>::Node
{
public:
virtual void
do_process() = 0;
doProcess() = 0;
virtual ~StatsDMetricBase() = default;
StatsDMetricBase() = default;
StatsDMetricBase(StatsDMetricBase const&) = delete;
@@ -71,14 +71,14 @@ public:
~StatsDHookImpl() override;
void
do_process() override;
doProcess() override;
StatsDHookImpl&
operator=(StatsDHookImpl const&) = delete;
private:
std::shared_ptr<StatsDCollectorImp> m_impl;
HandlerType m_handler;
std::shared_ptr<StatsDCollectorImp> impl_;
HandlerType handler_;
};
//------------------------------------------------------------------------------
@@ -96,18 +96,18 @@ public:
void
flush();
void
do_increment(CounterImpl::value_type amount);
doIncrement(CounterImpl::value_type amount);
void
do_process() override;
doProcess() override;
StatsDCounterImpl&
operator=(StatsDCounterImpl const&) = delete;
private:
std::shared_ptr<StatsDCollectorImp> m_impl;
std::string m_name;
CounterImpl::value_type m_value{0};
bool m_dirty{false};
std::shared_ptr<StatsDCollectorImp> impl_;
std::string name_;
CounterImpl::value_type value_{0};
bool dirty_{false};
};
//------------------------------------------------------------------------------
@@ -123,16 +123,16 @@ public:
notify(EventImpl::value_type const& value) override;
void
do_notify(EventImpl::value_type const& value);
doNotify(EventImpl::value_type const& value);
void
do_process();
doProcess();
private:
StatsDEventImpl&
operator=(StatsDEventImpl const&);
std::shared_ptr<StatsDCollectorImp> m_impl;
std::string m_name;
std::shared_ptr<StatsDCollectorImp> impl_;
std::string name_;
};
//------------------------------------------------------------------------------
@@ -152,21 +152,21 @@ public:
void
flush();
void
do_set(GaugeImpl::value_type value);
doSet(GaugeImpl::value_type value);
void
do_increment(GaugeImpl::difference_type amount);
doIncrement(GaugeImpl::difference_type amount);
void
do_process() override;
doProcess() override;
StatsDGaugeImpl&
operator=(StatsDGaugeImpl const&) = delete;
private:
std::shared_ptr<StatsDCollectorImp> m_impl;
std::string m_name;
GaugeImpl::value_type m_last_value{0};
GaugeImpl::value_type m_value{0};
bool m_dirty{true};
std::shared_ptr<StatsDCollectorImp> impl_;
std::string name_;
GaugeImpl::value_type lastValue_{0};
GaugeImpl::value_type value_{0};
bool dirty_{true};
};
//------------------------------------------------------------------------------
@@ -184,18 +184,18 @@ public:
void
flush();
void
do_increment(MeterImpl::value_type amount);
doIncrement(MeterImpl::value_type amount);
void
do_process() override;
doProcess() override;
StatsDMeterImpl&
operator=(StatsDMeterImpl const&) = delete;
private:
std::shared_ptr<StatsDCollectorImp> m_impl;
std::string m_name;
MeterImpl::value_type m_value{0};
bool m_dirty{false};
std::shared_ptr<StatsDCollectorImp> impl_;
std::string name_;
MeterImpl::value_type value_{0};
bool dirty_{false};
};
//------------------------------------------------------------------------------
@@ -204,42 +204,39 @@ class StatsDCollectorImp : public StatsDCollector,
public std::enable_shared_from_this<StatsDCollectorImp>
{
private:
enum {
// max_packet_size = 484
max_packet_size = 1472
};
static constexpr auto kMaxPacketSize = 1472;
Journal m_journal;
IP::Endpoint m_address;
std::string m_prefix;
boost::asio::io_context m_io_context;
std::optional<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> m_work;
boost::asio::strand<boost::asio::io_context::executor_type> m_strand;
boost::asio::basic_waitable_timer<std::chrono::steady_clock> m_timer;
boost::asio::ip::udp::socket m_socket;
std::deque<std::string> m_data;
Journal journal_;
IP::Endpoint address_;
std::string prefix_;
boost::asio::io_context ioContext_;
std::optional<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> work_;
boost::asio::strand<boost::asio::io_context::executor_type> strand_;
boost::asio::basic_waitable_timer<std::chrono::steady_clock> timer_;
boost::asio::ip::udp::socket socket_;
std::deque<std::string> data_;
std::recursive_mutex metricsLock_;
List<StatsDMetricBase> metrics_;
// Must come last for order of init
std::thread m_thread;
std::thread thread_;
static boost::asio::ip::udp::endpoint
to_endpoint(IP::Endpoint const& ep)
toEndpoint(IP::Endpoint const& ep)
{
return boost::asio::ip::udp::endpoint(ep.address(), ep.port());
}
public:
StatsDCollectorImp(IP::Endpoint address, std::string prefix, Journal journal)
: m_journal(journal)
, m_address(std::move(address))
, m_prefix(std::move(prefix))
, m_work(boost::asio::make_work_guard(m_io_context))
, m_strand(boost::asio::make_strand(m_io_context))
, m_timer(m_io_context)
, m_socket(m_io_context)
, m_thread(&StatsDCollectorImp::run, this)
: journal_(journal)
, address_(std::move(address))
, prefix_(std::move(prefix))
, work_(boost::asio::make_work_guard(ioContext_))
, strand_(boost::asio::make_strand(ioContext_))
, timer_(ioContext_)
, socket_(ioContext_)
, thread_(&StatsDCollectorImp::run, this)
{
}
@@ -247,43 +244,43 @@ public:
{
try
{
m_timer.cancel();
timer_.cancel();
}
catch (boost::system::system_error const&) // NOLINT(bugprone-empty-catch)
{
// ignored
}
m_work.reset();
m_thread.join();
work_.reset();
thread_.join();
}
Hook
make_hook(HookImpl::HandlerType const& handler) override
makeHook(HookImpl::HandlerType const& handler) override
{
return Hook(std::make_shared<detail::StatsDHookImpl>(handler, shared_from_this()));
}
Counter
make_counter(std::string const& name) override
makeCounter(std::string const& name) override
{
return Counter(std::make_shared<detail::StatsDCounterImpl>(name, shared_from_this()));
}
Event
make_event(std::string const& name) override
makeEvent(std::string const& name) override
{
return Event(std::make_shared<detail::StatsDEventImpl>(name, shared_from_this()));
}
Gauge
make_gauge(std::string const& name) override
makeGauge(std::string const& name) override
{
return Gauge(std::make_shared<detail::StatsDGaugeImpl>(name, shared_from_this()));
}
Meter
make_meter(std::string const& name) override
makeMeter(std::string const& name) override
{
return Meter(std::make_shared<detail::StatsDMeterImpl>(name, shared_from_this()));
}
@@ -293,50 +290,50 @@ public:
void
add(StatsDMetricBase& metric)
{
std::lock_guard const _(metricsLock_);
metrics_.push_back(metric);
std::scoped_lock const _(metricsLock_);
metrics_.pushBack(metric);
}
void
remove(StatsDMetricBase& metric)
{
std::lock_guard const _(metricsLock_);
metrics_.erase(metrics_.iterator_to(metric));
std::scoped_lock const _(metricsLock_);
metrics_.erase(metrics_.iteratorTo(metric));
}
//--------------------------------------------------------------------------
boost::asio::io_context&
get_io_context()
getIoContext()
{
return m_io_context;
return ioContext_;
}
std::string const&
prefix() const
{
return m_prefix;
return prefix_;
}
void
do_post_buffer(std::string const& buffer)
doPostBuffer(std::string const& buffer)
{
m_data.emplace_back(buffer);
data_.emplace_back(buffer);
}
void
post_buffer(std::string&& buffer)
postBuffer(std::string&& buffer)
{
boost::asio::dispatch(
m_io_context,
ioContext_,
boost::asio::bind_executor(
m_strand, std::bind(&StatsDCollectorImp::do_post_buffer, this, std::move(buffer))));
strand_, std::bind(&StatsDCollectorImp::doPostBuffer, this, std::move(buffer))));
}
// The keepAlive parameter makes sure the buffers sent to
// boost::asio::async_send do not go away until the call is finished
void
on_send(
onSend(
std::shared_ptr<std::deque<std::string>> /*keepAlive*/,
boost::system::error_code ec,
std::size_t)
@@ -346,7 +343,7 @@ public:
if (ec)
{
if (auto stream = m_journal.error())
if (auto stream = journal_.error())
stream << "async_send failed: " << ec.message();
return;
}
@@ -368,35 +365,35 @@ public:
// Send what we have
void
send_buffers()
sendBuffers()
{
if (m_data.empty())
if (data_.empty())
return;
// Break up the array of strings into blocks
// that each fit into one UDP packet.
//
std::vector<boost::asio::const_buffer> buffers;
buffers.reserve(m_data.size());
buffers.reserve(data_.size());
std::size_t size(0);
auto keepAlive = std::make_shared<std::deque<std::string>>(std::move(m_data));
m_data.clear();
auto keepAlive = std::make_shared<std::deque<std::string>>(std::move(data_));
data_.clear();
for (auto const& s : *keepAlive)
{
std::size_t const length(s.size());
XRPL_ASSERT(
!s.empty(),
"beast::insight::detail::StatsDCollectorImp::send_buffers : "
"beast::insight::detail::StatsDCollectorImp::sendBuffers : "
"non-empty payload");
if (!buffers.empty() && (size + length) > max_packet_size)
if (!buffers.empty() && (size + length) > kMaxPacketSize)
{
log(buffers);
m_socket.async_send(
socket_.async_send(
buffers,
std::bind(
&StatsDCollectorImp::on_send,
&StatsDCollectorImp::onSend,
this,
keepAlive,
std::placeholders::_1,
@@ -412,10 +409,10 @@ public:
if (!buffers.empty())
{
log(buffers);
m_socket.async_send(
socket_.async_send(
buffers,
std::bind(
&StatsDCollectorImp::on_send,
&StatsDCollectorImp::onSend,
this,
keepAlive,
std::placeholders::_1,
@@ -424,34 +421,34 @@ public:
}
void
set_timer()
setTimer()
{
using namespace std::chrono_literals;
m_timer.expires_after(1s);
m_timer.async_wait(std::bind(&StatsDCollectorImp::on_timer, this, std::placeholders::_1));
timer_.expires_after(1s);
timer_.async_wait(std::bind(&StatsDCollectorImp::onTimer, this, std::placeholders::_1));
}
void
on_timer(boost::system::error_code ec)
onTimer(boost::system::error_code ec)
{
if (ec == boost::asio::error::operation_aborted)
return;
if (ec)
{
if (auto stream = m_journal.error())
stream << "on_timer failed: " << ec.message();
if (auto stream = journal_.error())
stream << "onTimer failed: " << ec.message();
return;
}
std::lock_guard const _(metricsLock_);
std::scoped_lock const _(metricsLock_);
for (auto& m : metrics_)
m.do_process();
m.doProcess();
send_buffers();
sendBuffers();
set_timer();
setTimer();
}
void
@@ -459,43 +456,43 @@ public:
{
boost::system::error_code ec;
if (m_socket.connect(to_endpoint(m_address), ec))
if (socket_.connect(toEndpoint(address_), ec))
{
if (auto stream = m_journal.error())
if (auto stream = journal_.error())
stream << "Connect failed: " << ec.message();
return;
}
set_timer();
setTimer();
m_io_context.run();
ioContext_.run();
// NOLINTNEXTLINE(bugprone-unused-return-value)
m_socket.shutdown(boost::asio::ip::udp::socket::shutdown_send, ec);
socket_.shutdown(boost::asio::ip::udp::socket::shutdown_send, ec);
m_socket.close();
socket_.close();
m_io_context.poll();
ioContext_.poll();
}
};
//------------------------------------------------------------------------------
StatsDHookImpl::StatsDHookImpl(HandlerType handler, std::shared_ptr<StatsDCollectorImp> const& impl)
: m_impl(impl), m_handler(std::move(handler))
: impl_(impl), handler_(std::move(handler))
{
m_impl->add(*this);
impl_->add(*this);
}
StatsDHookImpl::~StatsDHookImpl()
{
m_impl->remove(*this);
impl_->remove(*this);
}
void
StatsDHookImpl::do_process()
StatsDHookImpl::doProcess()
{
m_handler();
handler_();
}
//------------------------------------------------------------------------------
@@ -503,23 +500,23 @@ StatsDHookImpl::do_process()
StatsDCounterImpl::StatsDCounterImpl(
std::string name,
std::shared_ptr<StatsDCollectorImp> const& impl)
: m_impl(impl), m_name(std::move(name))
: impl_(impl), name_(std::move(name))
{
m_impl->add(*this);
impl_->add(*this);
}
StatsDCounterImpl::~StatsDCounterImpl()
{
m_impl->remove(*this);
impl_->remove(*this);
}
void
StatsDCounterImpl::increment(CounterImpl::value_type amount)
{
boost::asio::dispatch(
m_impl->get_io_context(),
impl_->getIoContext(),
std::bind(
&StatsDCounterImpl::do_increment,
&StatsDCounterImpl::doIncrement,
std::static_pointer_cast<StatsDCounterImpl>(shared_from_this()),
amount));
}
@@ -527,26 +524,26 @@ StatsDCounterImpl::increment(CounterImpl::value_type amount)
void
StatsDCounterImpl::flush()
{
if (m_dirty)
if (dirty_)
{
m_dirty = false;
dirty_ = false;
std::stringstream ss;
ss << m_impl->prefix() << "." << m_name << ":" << m_value << "|c"
ss << impl_->prefix() << "." << name_ << ":" << value_ << "|c"
<< "\n";
m_value = 0;
m_impl->post_buffer(ss.str());
value_ = 0;
impl_->postBuffer(ss.str());
}
}
void
StatsDCounterImpl::do_increment(CounterImpl::value_type amount)
StatsDCounterImpl::doIncrement(CounterImpl::value_type amount)
{
m_value += amount;
m_dirty = true;
value_ += amount;
dirty_ = true;
}
void
StatsDCounterImpl::do_process()
StatsDCounterImpl::doProcess()
{
flush();
}
@@ -554,7 +551,7 @@ StatsDCounterImpl::do_process()
//------------------------------------------------------------------------------
StatsDEventImpl::StatsDEventImpl(std::string name, std::shared_ptr<StatsDCollectorImp> const& impl)
: m_impl(impl), m_name(std::move(name))
: impl_(impl), name_(std::move(name))
{
}
@@ -562,45 +559,45 @@ void
StatsDEventImpl::notify(EventImpl::value_type const& value)
{
boost::asio::dispatch(
m_impl->get_io_context(),
impl_->getIoContext(),
std::bind(
&StatsDEventImpl::do_notify,
&StatsDEventImpl::doNotify,
std::static_pointer_cast<StatsDEventImpl>(shared_from_this()),
value));
}
void
StatsDEventImpl::do_notify(EventImpl::value_type const& value)
StatsDEventImpl::doNotify(EventImpl::value_type const& value)
{
std::stringstream ss;
ss << m_impl->prefix() << "." << m_name << ":" << value.count() << "|ms"
ss << impl_->prefix() << "." << name_ << ":" << value.count() << "|ms"
<< "\n";
m_impl->post_buffer(ss.str());
impl_->postBuffer(ss.str());
}
//------------------------------------------------------------------------------
StatsDGaugeImpl::StatsDGaugeImpl(std::string name, std::shared_ptr<StatsDCollectorImp> const& impl)
: m_impl(impl), m_name(std::move(name))
: impl_(impl), name_(std::move(name))
{
// Start dirty so the initial value (0) is emitted on the first flush.
// Without this, gauges whose value never changes from 0 would never
// appear in downstream metric stores (e.g. Prometheus via StatsD).
m_impl->add(*this);
impl_->add(*this);
}
StatsDGaugeImpl::~StatsDGaugeImpl()
{
m_impl->remove(*this);
impl_->remove(*this);
}
void
StatsDGaugeImpl::set(GaugeImpl::value_type value)
{
boost::asio::dispatch(
m_impl->get_io_context(),
impl_->getIoContext(),
std::bind(
&StatsDGaugeImpl::do_set,
&StatsDGaugeImpl::doSet,
std::static_pointer_cast<StatsDGaugeImpl>(shared_from_this()),
value));
}
@@ -609,9 +606,9 @@ void
StatsDGaugeImpl::increment(GaugeImpl::difference_type amount)
{
boost::asio::dispatch(
m_impl->get_io_context(),
impl_->getIoContext(),
std::bind(
&StatsDGaugeImpl::do_increment,
&StatsDGaugeImpl::doIncrement,
std::static_pointer_cast<StatsDGaugeImpl>(shared_from_this()),
amount));
}
@@ -619,38 +616,38 @@ StatsDGaugeImpl::increment(GaugeImpl::difference_type amount)
void
StatsDGaugeImpl::flush()
{
if (m_dirty)
if (dirty_)
{
m_dirty = false;
dirty_ = false;
std::stringstream ss;
ss << m_impl->prefix() << "." << m_name << ":" << m_value << "|g"
ss << impl_->prefix() << "." << name_ << ":" << value_ << "|g"
<< "\n";
m_impl->post_buffer(ss.str());
impl_->postBuffer(ss.str());
}
}
void
StatsDGaugeImpl::do_set(GaugeImpl::value_type value)
StatsDGaugeImpl::doSet(GaugeImpl::value_type value)
{
m_value = value;
value_ = value;
if (m_value != m_last_value)
if (value_ != lastValue_)
{
m_last_value = m_value;
m_dirty = true;
lastValue_ = value_;
dirty_ = true;
}
}
void
StatsDGaugeImpl::do_increment(GaugeImpl::difference_type amount)
StatsDGaugeImpl::doIncrement(GaugeImpl::difference_type amount)
{
GaugeImpl::value_type value(m_value);
GaugeImpl::value_type value(value_);
if (amount > 0)
{
GaugeImpl::value_type const d(static_cast<GaugeImpl::value_type>(amount));
value += (d >= std::numeric_limits<GaugeImpl::value_type>::max() - m_value)
? std::numeric_limits<GaugeImpl::value_type>::max() - m_value
value += (d >= std::numeric_limits<GaugeImpl::value_type>::max() - value_)
? std::numeric_limits<GaugeImpl::value_type>::max() - value_
: d;
}
else if (amount < 0)
@@ -659,11 +656,11 @@ StatsDGaugeImpl::do_increment(GaugeImpl::difference_type amount)
value = (d >= value) ? 0 : value - d;
}
do_set(value);
doSet(value);
}
void
StatsDGaugeImpl::do_process()
StatsDGaugeImpl::doProcess()
{
flush();
}
@@ -671,23 +668,23 @@ StatsDGaugeImpl::do_process()
//------------------------------------------------------------------------------
StatsDMeterImpl::StatsDMeterImpl(std::string name, std::shared_ptr<StatsDCollectorImp> const& impl)
: m_impl(impl), m_name(std::move(name))
: impl_(impl), name_(std::move(name))
{
m_impl->add(*this);
impl_->add(*this);
}
StatsDMeterImpl::~StatsDMeterImpl()
{
m_impl->remove(*this);
impl_->remove(*this);
}
void
StatsDMeterImpl::increment(MeterImpl::value_type amount)
{
boost::asio::dispatch(
m_impl->get_io_context(),
impl_->getIoContext(),
std::bind(
&StatsDMeterImpl::do_increment,
&StatsDMeterImpl::doIncrement,
std::static_pointer_cast<StatsDMeterImpl>(shared_from_this()),
amount));
}
@@ -695,26 +692,26 @@ StatsDMeterImpl::increment(MeterImpl::value_type amount)
void
StatsDMeterImpl::flush()
{
if (m_dirty)
if (dirty_)
{
m_dirty = false;
dirty_ = false;
std::stringstream ss;
ss << m_impl->prefix() << "." << m_name << ":" << m_value << "|m"
ss << impl_->prefix() << "." << name_ << ":" << value_ << "|m"
<< "\n";
m_value = 0;
m_impl->post_buffer(ss.str());
value_ = 0;
impl_->postBuffer(ss.str());
}
}
void
StatsDMeterImpl::do_increment(MeterImpl::value_type amount)
StatsDMeterImpl::doIncrement(MeterImpl::value_type amount)
{
m_value += amount;
m_dirty = true;
value_ += amount;
dirty_ = true;
}
void
StatsDMeterImpl::do_process()
StatsDMeterImpl::doProcess()
{
flush();
}
@@ -724,7 +721,7 @@ StatsDMeterImpl::do_process()
//------------------------------------------------------------------------------
std::shared_ptr<StatsDCollector>
StatsDCollector::New(IP::Endpoint const& address, std::string const& prefix, Journal journal)
StatsDCollector::make(IP::Endpoint const& address, std::string const& prefix, Journal journal)
{
return std::make_shared<detail::StatsDCollectorImp>(address, prefix, journal);
}

View File

@@ -8,25 +8,25 @@
namespace beast::IP {
Endpoint
from_asio(boost::asio::ip::address const& address)
fromAsio(boost::asio::ip::address const& address)
{
return Endpoint{address};
}
Endpoint
from_asio(boost::asio::ip::tcp::endpoint const& endpoint)
fromAsio(boost::asio::ip::tcp::endpoint const& endpoint)
{
return Endpoint{endpoint.address(), endpoint.port()};
}
boost::asio::ip::address
to_asio_address(Endpoint const& endpoint)
toAsioAddress(Endpoint const& endpoint)
{
return endpoint.address();
}
boost::asio::ip::tcp::endpoint
to_asio_endpoint(Endpoint const& endpoint)
toAsioEndpoint(Endpoint const& endpoint)
{
return boost::asio::ip::tcp::endpoint{endpoint.address(), endpoint.port()};
}

View File

@@ -3,7 +3,7 @@
namespace beast::IP {
bool
is_private(AddressV4 const& addr)
isPrivate(AddressV4 const& addr)
{
return ((addr.to_uint() & 0xff000000) == 0x0a000000) || // Prefix /8, 10. #.#.#
((addr.to_uint() & 0xfff00000) == 0xac100000) || // Prefix /12 172. 16.#.# - 172.31.#.#
@@ -12,16 +12,54 @@ is_private(AddressV4 const& addr)
}
bool
is_public(AddressV4 const& addr)
isPublic(AddressV4 const& addr)
{
return !is_private(addr) && !addr.is_multicast();
if (isPrivate(addr))
return false;
if (addr.is_multicast())
return false;
auto const ip = addr.to_uint();
// 0.0.0.0/8 "This network"
if ((ip & 0xff000000) == 0x00000000)
return false;
// 100.64.0.0/10 Shared Address Space (CGNAT) - RFC 6598
if ((ip & 0xffc00000) == 0x64400000)
return false;
// 169.254.0.0/16 Link-local
if ((ip & 0xffff0000) == 0xa9fe0000)
return false;
// 192.0.0.0/24 IETF Protocol Assignments - RFC 6890
if ((ip & 0xffffff00) == 0xc0000000)
return false;
// 192.0.2.0/24 TEST-NET-1 (documentation) - RFC 5737
if ((ip & 0xffffff00) == 0xc0000200)
return false;
// 192.88.99.0/24 6to4 Relay Anycast (deprecated) - RFC 7526
if ((ip & 0xffffff00) == 0xc0586300)
return false;
// 198.18.0.0/15 Benchmarking - RFC 2544
if ((ip & 0xfffe0000) == 0xc6120000)
return false;
// 198.51.100.0/24 TEST-NET-2 (documentation) - RFC 5737
if ((ip & 0xffffff00) == 0xc6336400)
return false;
// 203.0.113.0/24 TEST-NET-3 (documentation) - RFC 5737
if ((ip & 0xffffff00) == 0xcb007100)
return false;
// 240.0.0.0/4 Reserved for future use - RFC 1112
if ((ip & 0xf0000000) == 0xf0000000)
return false;
return true;
}
char
get_class(AddressV4 const& addr)
getClass(AddressV4 const& addr)
{
static char const* table = "AAAABBCD"; // cspell:disable-line
return table[(addr.to_uint() & 0xE0000000) >> 29];
static char const* kTable = "AAAABBCD"; // cspell:disable-line
return kTable[(addr.to_uint() & 0xE0000000) >> 29];
}
} // namespace beast::IP

View File

@@ -7,19 +7,55 @@
namespace beast::IP {
bool
is_private(AddressV6 const& addr)
isPrivate(AddressV6 const& addr)
{
return (
((addr.to_bytes()[0] & 0xfd) != 0) || // TODO fc00::/8 too ?
(addr.is_v4_mapped() &&
is_private(boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, addr))));
// fc00::/7 - Unique Local Address (ULA), covers fc00:: and fd00::
if ((addr.to_bytes()[0] & 0xfe) == 0xfc)
return true;
if (addr.is_v4_mapped())
return isPrivate(boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, addr));
return false;
}
bool
is_public(AddressV6 const& addr)
isPublic(AddressV6 const& addr)
{
// TODO is this correct?
return !is_private(addr) && !addr.is_multicast();
if (addr.is_loopback())
return false;
if (addr.is_v4_mapped())
return isPublic(boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, addr));
if (isPrivate(addr))
return false;
if (addr.is_multicast())
return false;
if (addr.is_unspecified())
return false;
auto const b = addr.to_bytes();
// fe80::/10 - Link-local
if (b[0] == 0xfe && (b[1] & 0xc0) == 0x80)
return false;
// 100::/64 - Discard prefix (RFC 6666)
if (b[0] == 0x01 && b[1] == 0x00 && b[2] == 0 && b[3] == 0 && b[4] == 0 && b[5] == 0 &&
b[6] == 0 && b[7] == 0)
return false;
// 2001:db8::/32 - Documentation (RFC 3849)
if (b[0] == 0x20 && b[1] == 0x01 && b[2] == 0x0d && b[3] == 0xb8)
return false;
// 2001::/32 - IETF Protocol Assignments / Teredo (RFC 4380)
if (b[0] == 0x20 && b[1] == 0x01 && b[2] == 0x00 && b[3] == 0x00)
return false;
// 2001:20::/28 - ORCHIDv2 (RFC 7343)
// 28-bit prefix: 0x2001002 => b[0]=0x20, b[1]=0x01, b[2]=0x00,
// top nibble of b[3]=0x2
if (b[0] == 0x20 && b[1] == 0x01 && b[2] == 0x00 && (b[3] & 0xf0) == 0x20)
return false;
// 2002::/16 - 6to4 (RFC 3056, deprecated by RFC 7526)
if (b[0] == 0x20 && b[1] == 0x02)
return false;
return true;
}
} // namespace beast::IP

View File

@@ -16,16 +16,16 @@
namespace beast::IP {
Endpoint::Endpoint() : m_port(0)
Endpoint::Endpoint() : port_(0)
{
}
Endpoint::Endpoint(Address addr, Port port) : m_addr(std::move(addr)), m_port(port)
Endpoint::Endpoint(Address addr, Port port) : addr_(std::move(addr)), port_(port)
{
}
std::optional<Endpoint>
Endpoint::from_string_checked(std::string const& s)
Endpoint::fromStringChecked(std::string const& s)
{
if (s.size() <= 64)
{
@@ -39,15 +39,15 @@ Endpoint::from_string_checked(std::string const& s)
}
Endpoint
Endpoint::from_string(std::string const& s)
Endpoint::fromString(std::string const& s)
{
if (std::optional<Endpoint> const result = from_string_checked(s))
if (std::optional<Endpoint> const result = fromStringChecked(s))
return *result;
return Endpoint{};
}
std::string
Endpoint::to_string() const
Endpoint::toString() const
{
std::string s;
s.reserve(

View File

@@ -12,14 +12,14 @@ namespace beast {
class NullJournalSink : public Journal::Sink
{
public:
NullJournalSink() : Sink(severities::kDisabled, false)
NullJournalSink() : Sink(Severity::Disabled, false)
{
}
~NullJournalSink() override = default;
[[nodiscard]] bool
active(severities::Severity) const override
active(Severity) const override
{
return false;
}
@@ -35,24 +35,24 @@ public:
{
}
[[nodiscard]] severities::Severity
[[nodiscard]] Severity
threshold() const override
{
return severities::kDisabled;
return Severity::Disabled;
}
void
threshold(severities::Severity) override
threshold(Severity) override
{
}
void
write(severities::Severity, std::string const&) override
write(Severity, std::string const&) override
{
}
void
writeAlways(severities::Severity, std::string const&) override
writeAlways(Severity, std::string const&) override
{
}
};
@@ -62,13 +62,13 @@ public:
Journal::Sink&
Journal::getNullSink()
{
static NullJournalSink sink;
return sink;
static NullJournalSink kSink;
return kSink;
}
//------------------------------------------------------------------------------
Journal::Sink::Sink(Severity thresh, bool console) : thresh_(thresh), m_console(console)
Journal::Sink::Sink(Severity thresh, bool console) : thresh_(thresh), console_(console)
{
}
@@ -83,16 +83,16 @@ Journal::Sink::active(Severity level) const
bool
Journal::Sink::console() const
{
return m_console;
return console_;
}
void
Journal::Sink::console(bool output)
{
m_console = output;
console_ = output;
}
severities::Severity
Severity
Journal::Sink::threshold() const
{
return thresh_;
@@ -106,30 +106,30 @@ Journal::Sink::threshold(Severity thresh)
//------------------------------------------------------------------------------
Journal::ScopedStream::ScopedStream(Sink& sink, Severity level) : m_sink(sink), m_level(level)
Journal::ScopedStream::ScopedStream(Sink& sink, Severity level) : sink_(sink), level_(level)
{
// Modifiers applied from all ctors
m_ostream << std::boolalpha << std::showbase;
ostream_ << std::boolalpha << std::showbase;
}
Journal::ScopedStream::ScopedStream(Stream const& stream, std::ostream& manip(std::ostream&))
: ScopedStream(stream.sink(), stream.level())
{
m_ostream << manip;
ostream_ << manip;
}
Journal::ScopedStream::~ScopedStream()
{
std::string const& s(m_ostream.str());
std::string const& s(ostream_.str());
if (!s.empty())
{
if (s == "\n")
{
m_sink.write(m_level, "");
sink_.write(level_, "");
}
else
{
m_sink.write(m_level, s);
sink_.write(level_, s);
}
}
}
@@ -137,7 +137,7 @@ Journal::ScopedStream::~ScopedStream()
std::ostream&
Journal::ScopedStream::operator<<(std::ostream& manip(std::ostream&)) const
{
return m_ostream << manip;
return ostream_ << manip;
}
//------------------------------------------------------------------------------

View File

@@ -16,14 +16,14 @@ namespace beast {
//
//------------------------------------------------------------------------------
PropertyStream::Item::Item(Source* source) : m_source(source)
PropertyStream::Item::Item(Source* source) : source_(source)
{
}
PropertyStream::Source&
PropertyStream::Item::source() const
{
return *m_source;
return *source_;
}
PropertyStream::Source*
@@ -44,25 +44,25 @@ PropertyStream::Item::operator*() const
//
//------------------------------------------------------------------------------
PropertyStream::Proxy::Proxy(Map const& map, std::string key) : m_map(&map), m_key(std::move(key))
PropertyStream::Proxy::Proxy(Map const& map, std::string key) : map_(&map), key_(std::move(key))
{
}
PropertyStream::Proxy::Proxy(Proxy const& other) : m_map(other.m_map), m_key(other.m_key)
PropertyStream::Proxy::Proxy(Proxy const& other) : map_(other.map_), key_(other.key_)
{
}
PropertyStream::Proxy::~Proxy()
{
std::string const s(m_ostream.str());
std::string const s(ostream_.str());
if (!s.empty())
m_map->add(m_key, s);
map_->add(key_, s);
}
std::ostream&
PropertyStream::Proxy::operator<<(std::ostream& manip(std::ostream&)) const
{
return m_ostream << manip;
return ostream_ << manip;
}
//------------------------------------------------------------------------------
@@ -71,40 +71,40 @@ PropertyStream::Proxy::operator<<(std::ostream& manip(std::ostream&)) const
//
//------------------------------------------------------------------------------
PropertyStream::Map::Map(PropertyStream& stream) : m_stream(stream)
PropertyStream::Map::Map(PropertyStream& stream) : stream_(stream)
{
}
PropertyStream::Map::Map(Set& parent) : m_stream(parent.stream())
PropertyStream::Map::Map(Set& parent) : stream_(parent.stream())
{
m_stream.map_begin();
stream_.mapBegin();
}
PropertyStream::Map::Map(std::string const& key, Map& map) : m_stream(map.stream())
PropertyStream::Map::Map(std::string const& key, Map& map) : stream_(map.stream())
{
m_stream.map_begin(key);
stream_.mapBegin(key);
}
PropertyStream::Map::Map(std::string const& key, PropertyStream& stream) : m_stream(stream)
PropertyStream::Map::Map(std::string const& key, PropertyStream& stream) : stream_(stream)
{
m_stream.map_begin(key);
stream_.mapBegin(key);
}
PropertyStream::Map::~Map()
{
m_stream.map_end();
stream_.mapEnd();
}
PropertyStream&
PropertyStream::Map::stream()
{
return m_stream;
return stream_;
}
PropertyStream const&
PropertyStream::Map::stream() const
{
return m_stream;
return stream_;
}
PropertyStream::Proxy
@@ -119,31 +119,31 @@ PropertyStream::Map::operator[](std::string const& key)
//
//------------------------------------------------------------------------------
PropertyStream::Set::Set(std::string const& key, Map& map) : m_stream(map.stream())
PropertyStream::Set::Set(std::string const& key, Map& map) : stream_(map.stream())
{
m_stream.array_begin(key);
stream_.arrayBegin(key);
}
PropertyStream::Set::Set(std::string const& key, PropertyStream& stream) : m_stream(stream)
PropertyStream::Set::Set(std::string const& key, PropertyStream& stream) : stream_(stream)
{
m_stream.array_begin(key);
stream_.arrayBegin(key);
}
PropertyStream::Set::~Set()
{
m_stream.array_end();
stream_.arrayEnd();
}
PropertyStream&
PropertyStream::Set::stream()
{
return m_stream;
return stream_;
}
PropertyStream const&
PropertyStream::Set::stream() const
{
return m_stream;
return stream_;
}
//------------------------------------------------------------------------------
@@ -152,13 +152,13 @@ PropertyStream::Set::stream() const
//
//------------------------------------------------------------------------------
PropertyStream::Source::Source(std::string name) : m_name(std::move(name)), item_(this)
PropertyStream::Source::Source(std::string name) : name_(std::move(name)), item_(this)
{
}
PropertyStream::Source::~Source()
{
std::lock_guard const _(lock_);
std::scoped_lock const _(lock_);
if (parent_ != nullptr)
parent_->remove(*this);
removeAll();
@@ -167,42 +167,38 @@ PropertyStream::Source::~Source()
std::string const&
PropertyStream::Source::name() const
{
return m_name;
return name_;
}
void
PropertyStream::Source::add(Source& source)
{
std::lock(lock_, source.lock_);
std::lock_guard const lk1(lock_, std::adopt_lock);
std::lock_guard const lk2(source.lock_, std::adopt_lock);
std::scoped_lock const lock(lock_, source.lock_);
XRPL_ASSERT(
source.parent_ == nullptr, "beast::PropertyStream::Source::add : null source parent");
children_.push_back(source.item_);
children_.pushBack(source.item_);
source.parent_ = this;
}
void
PropertyStream::Source::remove(Source& child)
{
std::lock(lock_, child.lock_);
std::lock_guard const lk1(lock_, std::adopt_lock);
std::lock_guard const lk2(child.lock_, std::adopt_lock);
std::scoped_lock const lock(lock_, child.lock_);
XRPL_ASSERT(
child.parent_ == this, "beast::PropertyStream::Source::remove : child parent match");
children_.erase(children_.iterator_to(child.item_));
children_.erase(children_.iteratorTo(child.item_));
child.parent_ = nullptr;
}
void
PropertyStream::Source::removeAll()
{
std::lock_guard const _(lock_);
std::scoped_lock const _(lock_);
for (auto iter = children_.begin(); iter != children_.end();)
{
std::lock_guard const _cl((*iter)->lock_);
std::scoped_lock const cl((*iter)->lock_);
remove(*(*iter));
}
}
@@ -210,19 +206,19 @@ PropertyStream::Source::removeAll()
//------------------------------------------------------------------------------
void
PropertyStream::Source::write_one(PropertyStream& stream)
PropertyStream::Source::writeOne(PropertyStream& stream)
{
Map map(m_name, stream);
Map map(name_, stream);
onWrite(map);
}
void
PropertyStream::Source::write(PropertyStream& stream)
{
Map map(m_name, stream);
Map map(name_, stream);
onWrite(map);
std::lock_guard const _(lock_);
std::scoped_lock const _(lock_);
for (auto& child : children_)
child.source().write(stream);
@@ -242,32 +238,32 @@ PropertyStream::Source::write(PropertyStream& stream, std::string const& path)
}
else
{
result.first->write_one(stream);
result.first->writeOne(stream);
}
}
std::pair<PropertyStream::Source*, bool>
PropertyStream::Source::find(std::string path)
{
bool const deep(peel_trailing_slashstar(&path));
bool const rooted(peel_leading_slash(&path));
bool const deep(peelTrailingSlashstar(&path));
bool const rooted(peelLeadingSlash(&path));
Source* source(this);
if (!path.empty())
{
if (!rooted)
{
std::string const name(peel_name(&path));
source = find_one_deep(name);
std::string const name(peelName(&path));
source = findOneDeep(name);
if (source == nullptr)
return std::make_pair(nullptr, deep);
}
source = source->find_path(path);
source = source->findPath(path);
}
return std::make_pair(source, deep);
}
bool
PropertyStream::Source::peel_leading_slash(std::string* path)
PropertyStream::Source::peelLeadingSlash(std::string* path)
{
if (!path->empty() && path->front() == '/')
{
@@ -278,7 +274,7 @@ PropertyStream::Source::peel_leading_slash(std::string* path)
}
bool
PropertyStream::Source::peel_trailing_slashstar(std::string* path)
PropertyStream::Source::peelTrailingSlashstar(std::string* path)
{
bool found(false);
if (path->empty())
@@ -294,7 +290,7 @@ PropertyStream::Source::peel_trailing_slashstar(std::string* path)
}
std::string
PropertyStream::Source::peel_name(std::string* path)
PropertyStream::Source::peelName(std::string* path)
{
if (path->empty())
return "";
@@ -318,16 +314,16 @@ PropertyStream::Source::peel_name(std::string* path)
// Recursive search through the whole tree until name is found
PropertyStream::Source*
PropertyStream::Source::find_one_deep(std::string const& name)
PropertyStream::Source::findOneDeep(std::string const& name)
{
Source* found = find_one(name); // NOLINT(misc-const-correctness)
Source* found = findOne(name); // NOLINT TODO
if (found != nullptr)
return found;
std::lock_guard const _(lock_);
std::scoped_lock const _(lock_);
for (auto& s : children_)
{
found = s.source().find_one_deep(name);
found = s.source().findOneDeep(name);
if (found != nullptr)
return found;
}
@@ -335,17 +331,17 @@ PropertyStream::Source::find_one_deep(std::string const& name)
}
PropertyStream::Source*
PropertyStream::Source::find_path(std::string path)
PropertyStream::Source::findPath(std::string path)
{
if (path.empty())
return this;
Source* source(this);
do
{
std::string const name(peel_name(&path));
std::string const name(peelName(&path));
if (name.empty())
break;
source = source->find_one(name);
source = source->findOne(name);
} while (source != nullptr);
return source;
}
@@ -353,12 +349,12 @@ PropertyStream::Source::find_path(std::string path)
// This function only looks at immediate children
// If no immediate children match, then return nullptr
PropertyStream::Source*
PropertyStream::Source::find_one(std::string const& name)
PropertyStream::Source::findOne(std::string const& name)
{
std::lock_guard const _(lock_);
std::scoped_lock const _(lock_);
for (auto& s : children_)
{
if (s.source().m_name == name)
if (s.source().name_ == name)
return &s.source();
}
return nullptr;
@@ -391,85 +387,85 @@ PropertyStream::add(std::string const& key, bool value)
void
PropertyStream::add(std::string const& key, char value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, signed char value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, unsigned char value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, short value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, unsigned short value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, int value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, unsigned int value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, long value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, unsigned long value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, long long value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, unsigned long long value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, float value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, double value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
PropertyStream::add(std::string const& key, long double value)
{
lexical_add(key, value);
lexicalAdd(key, value);
}
void
@@ -488,85 +484,85 @@ PropertyStream::add(bool value)
void
PropertyStream::add(char value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(signed char value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(unsigned char value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(short value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(unsigned short value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(int value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(unsigned int value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(long value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(unsigned long value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(long long value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(unsigned long long value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(float value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(double value)
{
lexical_add(value);
lexicalAdd(value);
}
void
PropertyStream::add(long double value)
{
lexical_add(value);
lexicalAdd(value);
}
} // namespace beast

View File

@@ -52,7 +52,7 @@ namespace detail {
// ed25519Sha256 (4)
// }
constexpr std::size_t fingerprintSize = 32;
constexpr std::size_t kFingerprintSize = 32;
std::unique_ptr<Condition>
loadSimpleSha256(Type type, Slice s, std::error_code& ec)
@@ -66,19 +66,19 @@ loadSimpleSha256(Type type, Slice s, std::error_code& ec)
if (!isPrimitive(p) || !isContextSpecific(p))
{
ec = error::incorrect_encoding;
ec = Error::IncorrectEncoding;
return {};
}
if (p.tag != 0)
{
ec = error::unexpected_tag;
ec = Error::UnexpectedTag;
return {};
}
if (p.length != fingerprintSize)
if (p.length != kFingerprintSize)
{
ec = error::fingerprint_size;
ec = Error::FingerprintSize;
return {};
}
@@ -94,13 +94,13 @@ loadSimpleSha256(Type type, Slice s, std::error_code& ec)
if (!isPrimitive(p) || !isContextSpecific(p))
{
ec = error::malformed_encoding;
ec = Error::MalformedEncoding;
return {};
}
if (p.tag != 1)
{
ec = error::unexpected_tag;
ec = Error::UnexpectedTag;
return {};
}
@@ -111,16 +111,16 @@ loadSimpleSha256(Type type, Slice s, std::error_code& ec)
if (!s.empty())
{
ec = error::trailing_garbage;
ec = Error::TrailingGarbage;
return {};
}
switch (type)
{
case Type::preimageSha256:
if (cost > PreimageSha256::maxPreimageLength)
case Type::PreimageSha256:
if (cost > PreimageSha256::kMaxPreimageLength)
{
ec = error::preimage_too_long;
ec = Error::PreimageTooLong;
return {};
}
break;
@@ -149,7 +149,7 @@ Condition::deserialize(Slice s, std::error_code& ec)
// }
if (s.empty())
{
ec = error::buffer_empty;
ec = Error::BufferEmpty;
return {};
}
@@ -163,19 +163,19 @@ Condition::deserialize(Slice s, std::error_code& ec)
// types
if (!isConstructed(p) || !isContextSpecific(p))
{
ec = error::malformed_encoding;
ec = Error::MalformedEncoding;
return {};
}
if (p.length > s.size())
{
ec = error::buffer_underfull;
ec = Error::BufferUnderfull;
return {};
}
if (s.size() > maxSerializedCondition)
if (s.size() > kMaxSerializedCondition)
{
ec = error::large_size;
ec = Error::LargeSize;
return {};
}
@@ -184,35 +184,35 @@ Condition::deserialize(Slice s, std::error_code& ec)
switch (p.tag)
{
case 0: // PreimageSha256
c = detail::loadSimpleSha256(Type::preimageSha256, Slice(s.data(), p.length), ec);
c = detail::loadSimpleSha256(Type::PreimageSha256, Slice(s.data(), p.length), ec);
if (!ec)
s += p.length;
break;
case 1: // PrefixSha256
ec = error::unsupported_type;
ec = Error::UnsupportedType;
return {};
case 2: // ThresholdSha256
ec = error::unsupported_type;
ec = Error::UnsupportedType;
return {};
case 3: // RsaSha256
ec = error::unsupported_type;
ec = Error::UnsupportedType;
return {};
case 4: // Ed25519Sha256
ec = error::unsupported_type;
ec = Error::UnsupportedType;
return {};
default:
ec = error::unknown_type;
ec = Error::UnknownType;
return {};
}
if (!s.empty())
{
ec = error::trailing_garbage;
ec = Error::TrailingGarbage;
return {};
}

View File

@@ -53,7 +53,7 @@ Fulfillment::deserialize(Slice s, std::error_code& ec)
if (s.empty())
{
ec = error::buffer_empty;
ec = Error::BufferEmpty;
return nullptr;
}
@@ -66,25 +66,25 @@ Fulfillment::deserialize(Slice s, std::error_code& ec)
// All fulfillments are context-specific, constructed types
if (!isConstructed(p) || !isContextSpecific(p))
{
ec = error::malformed_encoding;
ec = Error::MalformedEncoding;
return nullptr;
}
if (p.length > s.size())
{
ec = error::buffer_underfull;
ec = Error::BufferUnderfull;
return {};
}
if (p.length < s.size())
{
ec = error::buffer_overfull;
ec = Error::BufferOverfull;
return {};
}
if (p.length > maxSerializedFulfillment)
if (p.length > kMaxSerializedFulfillment)
{
ec = error::large_size;
ec = Error::LargeSize;
return {};
}
@@ -93,40 +93,40 @@ Fulfillment::deserialize(Slice s, std::error_code& ec)
using TagType = decltype(p.tag);
switch (p.tag)
{
case safe_cast<TagType>(Type::preimageSha256):
case safeCast<TagType>(Type::PreimageSha256):
f = PreimageSha256::deserialize(Slice(s.data(), p.length), ec);
if (ec)
return {};
s += p.length;
break;
case safe_cast<TagType>(Type::prefixSha256):
ec = error::unsupported_type;
case safeCast<TagType>(Type::PrefixSha256):
ec = Error::UnsupportedType;
return {};
break;
case safe_cast<TagType>(Type::thresholdSha256):
ec = error::unsupported_type;
case safeCast<TagType>(Type::ThresholdSha256):
ec = Error::UnsupportedType;
return {};
break;
case safe_cast<TagType>(Type::rsaSha256):
ec = error::unsupported_type;
case safeCast<TagType>(Type::RsaSha256):
ec = Error::UnsupportedType;
return {};
break;
case safe_cast<TagType>(Type::ed25519Sha256):
ec = error::unsupported_type;
case safeCast<TagType>(Type::Ed25519Sha256):
ec = Error::UnsupportedType;
return {};
default:
ec = error::unknown_type;
ec = Error::UnknownType;
return {};
}
if (!s.empty())
{
ec = error::trailing_garbage;
ec = Error::TrailingGarbage;
return {};
}

View File

@@ -9,10 +9,10 @@
namespace xrpl::cryptoconditions {
namespace detail {
class cryptoconditions_error_category : public std::error_category
class CryptoconditionsErrorCategory : public std::error_category
{
public:
explicit cryptoconditions_error_category() = default;
explicit CryptoconditionsErrorCategory() = default;
[[nodiscard]] char const*
name() const noexcept override
@@ -23,57 +23,57 @@ public:
[[nodiscard]] std::string
message(int ev) const override
{
switch (safe_cast<error>(ev))
switch (safeCast<Error>(ev))
{
case error::unsupported_type:
case Error::UnsupportedType:
return "Specification: Requested type not supported.";
case error::unsupported_subtype:
case Error::UnsupportedSubtype:
return "Specification: Requested subtype not supported.";
case error::unknown_type:
case Error::UnknownType:
return "Specification: Requested type not recognized.";
case error::unknown_subtype:
case Error::UnknownSubtype:
return "Specification: Requested subtypes not recognized.";
case error::fingerprint_size:
case Error::FingerprintSize:
return "Specification: Incorrect fingerprint size.";
case error::incorrect_encoding:
case Error::IncorrectEncoding:
return "Specification: Incorrect encoding.";
case error::trailing_garbage:
case Error::TrailingGarbage:
return "Bad buffer: contains trailing garbage.";
case error::buffer_empty:
case Error::BufferEmpty:
return "Bad buffer: no data.";
case error::buffer_overfull:
case Error::BufferOverfull:
return "Bad buffer: overfull.";
case error::buffer_underfull:
case Error::BufferUnderfull:
return "Bad buffer: underfull.";
case error::malformed_encoding:
case Error::MalformedEncoding:
return "Malformed DER encoding.";
case error::unexpected_tag:
case Error::UnexpectedTag:
return "Malformed DER encoding: Unexpected tag.";
case error::short_preamble:
case Error::ShortPreamble:
return "Malformed DER encoding: Short preamble.";
case error::long_tag:
case Error::LongTag:
return "Implementation limit: Overlong tag.";
case error::large_size:
case Error::LargeSize:
return "Implementation limit: Large payload.";
case error::preimage_too_long:
case Error::PreimageTooLong:
return "Implementation limit: Specified preimage is too long.";
case error::generic:
case Error::Generic:
default:
return "generic error";
}
@@ -99,20 +99,19 @@ public:
};
inline std::error_category const&
get_cryptoconditions_error_category()
getCryptoconditionsErrorCategory()
{
static cryptoconditions_error_category const cat{};
return cat;
static CryptoconditionsErrorCategory const kCat{};
return kCat;
}
} // namespace detail
std::error_code
make_error_code(error ev)
make_error_code(Error ev)
{
return std::error_code{
safe_cast<std::underlying_type_t<error>>(ev),
detail::get_cryptoconditions_error_category()};
safeCast<std::underlying_type_t<Error>>(ev), detail::getCryptoconditionsErrorCategory()};
}
} // namespace xrpl::cryptoconditions

View File

@@ -34,7 +34,7 @@ HashRouter::emplace(uint256 const& key) -> std::pair<Entry&, bool>
void
HashRouter::addSuppression(uint256 const& key)
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
emplace(key);
}
@@ -48,7 +48,7 @@ HashRouter::addSuppressionPeer(uint256 const& key, PeerShortID peer)
std::pair<bool, std::optional<Stopwatch::time_point>>
HashRouter::addSuppressionPeerWithStatus(uint256 const& key, PeerShortID peer)
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
auto result = emplace(key);
result.first.addPeer(peer);
@@ -58,7 +58,7 @@ HashRouter::addSuppressionPeerWithStatus(uint256 const& key, PeerShortID peer)
bool
HashRouter::addSuppressionPeer(uint256 const& key, PeerShortID peer, HashRouterFlags& flags)
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
auto [s, created] = emplace(key);
s.addPeer(peer);
@@ -71,21 +71,21 @@ HashRouter::shouldProcess(
uint256 const& key,
PeerShortID peer,
HashRouterFlags& flags,
std::chrono::seconds tx_interval)
std::chrono::seconds txInterval)
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
auto result = emplace(key);
auto& s = result.first;
s.addPeer(peer);
flags = s.getFlags();
return s.shouldProcess(suppressionMap_.clock().now(), tx_interval);
return s.shouldProcess(suppressionMap_.clock().now(), txInterval);
}
HashRouterFlags
HashRouter::getFlags(uint256 const& key)
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
return emplace(key).first.getFlags();
}
@@ -95,7 +95,7 @@ HashRouter::setFlags(uint256 const& key, HashRouterFlags flags)
{
XRPL_ASSERT(static_cast<bool>(flags), "xrpl::HashRouter::setFlags : valid input");
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
auto& s = emplace(key).first;
@@ -109,7 +109,7 @@ HashRouter::setFlags(uint256 const& key, HashRouterFlags flags)
auto
HashRouter::shouldRelay(uint256 const& key) -> std::optional<std::set<PeerShortID>>
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
auto& s = emplace(key).first;

View File

@@ -11,11 +11,11 @@
namespace xrpl {
Job::Job() : mType(jtINVALID), mJobIndex(0)
Job::Job() : type_(JtInvalid), jobIndex_(0)
{
}
Job::Job(JobType type, std::uint64_t index) : mType(type), mJobIndex(index)
Job::Job(JobType type, std::uint64_t index) : type_(type), jobIndex_(index)
{
}
@@ -25,83 +25,83 @@ Job::Job(
std::uint64_t index,
LoadMonitor& lm,
std::function<void()> const& job)
: mType(type), mJobIndex(index), mJob(job), mName(name), m_queue_time(clock_type::now())
: type_(type), jobIndex_(index), job_(job), name_(name), queueTime_(clock_type::now())
{
m_loadEvent = std::make_shared<LoadEvent>(std::ref(lm), name, false);
loadEvent_ = std::make_shared<LoadEvent>(std::ref(lm), name, false);
}
JobType
Job::getType() const
{
return mType;
return type_;
}
Job::clock_type::time_point const&
Job::queue_time() const
Job::queueTime() const
{
return m_queue_time;
return queueTime_;
}
void
Job::doJob()
{
beast::setCurrentThreadName("j:" + mName);
m_loadEvent->start();
m_loadEvent->setName(mName);
beast::setCurrentThreadName("j:" + name_);
loadEvent_->start();
loadEvent_->setName(name_);
mJob();
job_();
// Destroy the lambda, otherwise we won't include
// its duration in the time measurement
mJob = nullptr;
job_ = nullptr;
}
bool
Job::operator>(Job const& j) const
{
if (mType < j.mType)
if (type_ < j.type_)
return true;
if (mType > j.mType)
if (type_ > j.type_)
return false;
return mJobIndex > j.mJobIndex;
return jobIndex_ > j.jobIndex_;
}
bool
Job::operator>=(Job const& j) const
{
if (mType < j.mType)
if (type_ < j.type_)
return true;
if (mType > j.mType)
if (type_ > j.type_)
return false;
return mJobIndex >= j.mJobIndex;
return jobIndex_ >= j.jobIndex_;
}
bool
Job::operator<(Job const& j) const
{
if (mType < j.mType)
if (type_ < j.type_)
return false;
if (mType > j.mType)
if (type_ > j.type_)
return true;
return mJobIndex < j.mJobIndex;
return jobIndex_ < j.jobIndex_;
}
bool
Job::operator<=(Job const& j) const
{
if (mType < j.mType)
if (type_ < j.type_)
return false;
if (mType > j.mType)
if (type_ > j.type_)
return true;
return mJobIndex <= j.mJobIndex;
return jobIndex_ <= j.jobIndex_;
}
} // namespace xrpl

View File

@@ -27,29 +27,29 @@ JobQueue::JobQueue(
beast::Journal journal,
Logs& logs,
perf::PerfLog& perfLog)
: m_journal(journal)
, m_invalidJobData(JobTypes::instance().getInvalid(), collector, logs)
, m_workers(*this, &perfLog, "JobQueue", threadCount)
: journal_(journal)
, invalidJobData_(JobTypes::instance().getInvalid(), collector, logs)
, workers_(*this, &perfLog, "JobQueue", threadCount)
, perfLog_(perfLog)
, m_collector(collector)
, collector_(collector)
{
JLOG(m_journal.info()) << "Using " << threadCount << " threads";
JLOG(journal_.info()) << "Using " << threadCount << " threads";
hook = m_collector->make_hook(std::bind(&JobQueue::collect, this));
job_count = m_collector->make_gauge("job_count");
hook_ = collector_->makeHook(std::bind(&JobQueue::collect, this));
jobCount_ = collector_->makeGauge("job_count");
{
std::lock_guard const lock(m_mutex);
std::scoped_lock const lock(mutex_);
for (auto const& x : JobTypes::instance())
{
JobTypeInfo const& jt = x.second;
// And create dynamic information for all jobs
auto const result(m_jobData.emplace(
auto const result(jobData_.emplace(
std::piecewise_construct,
std::forward_as_tuple(jt.type()),
std::forward_as_tuple(jt, m_collector, logs)));
std::forward_as_tuple(jt, collector_, logs)));
XRPL_ASSERT(result.second == true, "xrpl::JobQueue::JobQueue : jobs added");
(void)result.second;
}
@@ -59,52 +59,52 @@ JobQueue::JobQueue(
JobQueue::~JobQueue()
{
// Must unhook before destroying
hook = beast::insight::Hook();
hook_ = beast::insight::Hook();
}
void
JobQueue::collect()
{
std::lock_guard const lock(m_mutex);
job_count = m_jobSet.size();
std::scoped_lock const lock(mutex_);
jobCount_ = jobSet_.size();
}
bool
JobQueue::addRefCountedJob(JobType type, std::string const& name, JobFunction const& func)
{
XRPL_ASSERT(type != jtINVALID, "xrpl::JobQueue::addRefCountedJob : valid input job type");
XRPL_ASSERT(type != JtInvalid, "xrpl::JobQueue::addRefCountedJob : valid input job type");
auto iter(m_jobData.find(type));
auto iter(jobData_.find(type));
XRPL_ASSERT(
iter != m_jobData.end(), "xrpl::JobQueue::addRefCountedJob : job type found in jobs");
if (iter == m_jobData.end())
iter != jobData_.end(), "xrpl::JobQueue::addRefCountedJob : job type found in jobs");
if (iter == jobData_.end())
return false;
JLOG(m_journal.debug()) << __func__ << " : Adding job : " << name << " : " << type;
JLOG(journal_.debug()) << __func__ << " : Adding job : " << name << " : " << type;
JobTypeData& data(iter->second);
// FIXME: Workaround incorrect client shutdown ordering
// do not add jobs to a queue with no threads
XRPL_ASSERT(
(type >= jtCLIENT && type <= jtCLIENT_WEBSOCKET) || m_workers.getNumberOfThreads() > 0,
(type >= JtClient && type <= JtClientWebsocket) || workers_.getNumberOfThreads() > 0,
"xrpl::JobQueue::addRefCountedJob : threads available or job "
"requires no threads");
{
std::lock_guard const lock(m_mutex);
auto result = m_jobSet.emplace(type, name, ++m_lastJob, data.load(), func);
std::scoped_lock const lock(mutex_);
auto result = jobSet_.emplace(type, name, ++lastJob_, data.load(), func);
auto const& job = *result.first;
JobType const type(job.getType());
XRPL_ASSERT(type != jtINVALID, "xrpl::JobQueue::addRefCountedJob : has valid job type");
XRPL_ASSERT(m_jobSet.contains(job), "xrpl::JobQueue::addRefCountedJob : job found");
XRPL_ASSERT(type != JtInvalid, "xrpl::JobQueue::addRefCountedJob : has valid job type");
XRPL_ASSERT(jobSet_.contains(job), "xrpl::JobQueue::addRefCountedJob : job found");
perfLog_.jobQueue(type);
JobTypeData& data(getJobTypeData(type));
if (data.waiting + data.running < getJobLimit(type))
{
m_workers.addTask();
workers_.addTask();
}
else
{
@@ -119,21 +119,21 @@ JobQueue::addRefCountedJob(JobType type, std::string const& name, JobFunction co
int
JobQueue::getJobCount(JobType t) const
{
std::lock_guard const lock(m_mutex);
std::scoped_lock const lock(mutex_);
JobDataMap::const_iterator const c = m_jobData.find(t);
JobDataMap::const_iterator const c = jobData_.find(t);
return (c == m_jobData.end()) ? 0 : c->second.waiting;
return (c == jobData_.end()) ? 0 : c->second.waiting;
}
int
JobQueue::getJobCountTotal(JobType t) const
{
std::lock_guard const lock(m_mutex);
std::scoped_lock const lock(mutex_);
JobDataMap::const_iterator const c = m_jobData.find(t);
JobDataMap::const_iterator const c = jobData_.find(t);
return (c == m_jobData.end()) ? 0 : (c->second.waiting + c->second.running);
return (c == jobData_.end()) ? 0 : (c->second.waiting + c->second.running);
}
int
@@ -142,9 +142,9 @@ JobQueue::getJobCountGE(JobType t) const
// return the number of jobs at this priority level or greater
int ret = 0;
std::lock_guard const lock(m_mutex);
std::scoped_lock const lock(mutex_);
for (auto const& x : m_jobData)
for (auto const& x : jobData_)
{
if (x.first >= t)
ret += x.second.waiting;
@@ -156,10 +156,10 @@ JobQueue::getJobCountGE(JobType t) const
std::unique_ptr<LoadEvent>
JobQueue::makeLoadEvent(JobType t, std::string const& name)
{
JobDataMap::iterator const iter(m_jobData.find(t));
XRPL_ASSERT(iter != m_jobData.end(), "xrpl::JobQueue::makeLoadEvent : valid job type input");
JobDataMap::iterator const iter(jobData_.find(t));
XRPL_ASSERT(iter != jobData_.end(), "xrpl::JobQueue::makeLoadEvent : valid job type input");
if (iter == m_jobData.end())
if (iter == jobData_.end())
return {};
return std::make_unique<LoadEvent>(iter->second.load(), name, true);
@@ -169,36 +169,36 @@ void
JobQueue::addLoadEvents(JobType t, int count, std::chrono::milliseconds elapsed)
{
if (isStopped())
LogicError("JobQueue::addLoadEvents() called after JobQueue stopped");
logicError("JobQueue::addLoadEvents() called after JobQueue stopped");
JobDataMap::iterator const iter(m_jobData.find(t));
XRPL_ASSERT(iter != m_jobData.end(), "xrpl::JobQueue::addLoadEvents : valid job type input");
JobDataMap::iterator const iter(jobData_.find(t));
XRPL_ASSERT(iter != jobData_.end(), "xrpl::JobQueue::addLoadEvents : valid job type input");
iter->second.load().addSamples(count, elapsed);
}
bool
JobQueue::isOverloaded()
{
return std::ranges::any_of(m_jobData, [](auto& entry) { return entry.second.load().isOver(); });
return std::ranges::any_of(jobData_, [](auto& entry) { return entry.second.load().isOver(); });
}
Json::Value
json::Value
JobQueue::getJson(int c)
{
using namespace std::chrono_literals;
Json::Value ret(Json::objectValue);
json::Value ret(json::ValueType::Object);
ret["threads"] = m_workers.getNumberOfThreads();
ret["threads"] = workers_.getNumberOfThreads();
Json::Value priorities = Json::arrayValue;
json::Value priorities = json::ValueType::Array;
std::lock_guard const lock(m_mutex);
std::scoped_lock const lock(mutex_);
for (auto& x : m_jobData)
for (auto& x : jobData_)
{
XRPL_ASSERT(x.first != jtINVALID, "xrpl::JobQueue::getJson : valid job type");
XRPL_ASSERT(x.first != JtInvalid, "xrpl::JobQueue::getJson : valid job type");
if (x.first == jtGENERIC)
if (x.first == JtGeneric)
continue;
JobTypeData& data(x.second);
@@ -210,7 +210,7 @@ JobQueue::getJson(int c)
if ((stats.count != 0) || (waiting != 0) || (stats.latencyPeak != 0ms) || (running != 0))
{
Json::Value& pri = priorities.append(Json::objectValue);
json::Value& pri = priorities.append(json::ValueType::Object);
pri["job_type"] = data.name();
@@ -242,20 +242,20 @@ JobQueue::getJson(int c)
void
JobQueue::rendezvous()
{
std::unique_lock<std::mutex> lock(m_mutex);
cv_.wait(lock, [this] { return m_processCount == 0 && m_jobSet.empty(); });
std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [this] { return processCount_ == 0 && jobSet_.empty(); });
}
JobTypeData&
JobQueue::getJobTypeData(JobType type)
{
JobDataMap::iterator const c(m_jobData.find(type));
XRPL_ASSERT(c != m_jobData.end(), "xrpl::JobQueue::getJobTypeData : valid job type input");
JobDataMap::iterator const c(jobData_.find(type));
XRPL_ASSERT(c != jobData_.end(), "xrpl::JobQueue::getJobTypeData : valid job type input");
// NIKB: This is ugly and I hate it. We must remove jtINVALID completely
// NIKB: This is ugly and I hate it. We must remove JtInvalid completely
// and use something sane.
if (c == m_jobData.end())
return m_invalidJobData;
if (c == jobData_.end())
return invalidJobData_;
return c->second;
}
@@ -265,17 +265,17 @@ JobQueue::stop()
{
stopping_ = true;
using namespace std::chrono_literals;
jobCounter_.join("JobQueue", 1s, m_journal);
jobCounter_.join("JobQueue", 1s, journal_);
{
// After the JobCounter is joined, all jobs have finished executing
// (i.e. returned from `Job::doJob`) and no more are being accepted,
// but there may still be some threads between the return of
// `Job::doJob` and the return of `JobQueue::processTask`. That is why
// we must wait on the condition variable to make these assertions.
std::unique_lock<std::mutex> lock(m_mutex);
cv_.wait(lock, [this] { return m_processCount == 0 && m_jobSet.empty(); });
XRPL_ASSERT(m_processCount == 0, "xrpl::JobQueue::stop : all processes completed");
XRPL_ASSERT(m_jobSet.empty(), "xrpl::JobQueue::stop : all jobs completed");
std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [this] { return processCount_ == 0 && jobSet_.empty(); });
XRPL_ASSERT(processCount_ == 0, "xrpl::JobQueue::stop : all processes completed");
XRPL_ASSERT(jobSet_.empty(), "xrpl::JobQueue::stop : all jobs completed");
XRPL_ASSERT(nSuspend_ == 0, "xrpl::JobQueue::stop : no coros suspended");
stopped_ = true;
}
@@ -290,13 +290,13 @@ JobQueue::isStopped() const
void
JobQueue::getNextJob(Job& job)
{
XRPL_ASSERT(!m_jobSet.empty(), "xrpl::JobQueue::getNextJob : non-empty jobs");
XRPL_ASSERT(!jobSet_.empty(), "xrpl::JobQueue::getNextJob : non-empty jobs");
std::set<Job>::const_iterator iter;
for (iter = m_jobSet.begin(); iter != m_jobSet.end(); ++iter)
for (iter = jobSet_.begin(); iter != jobSet_.end(); ++iter)
{
JobType const type = iter->getType();
XRPL_ASSERT(type != jtINVALID, "xrpl::JobQueue::getNextJob : valid job type");
XRPL_ASSERT(type != JtInvalid, "xrpl::JobQueue::getNextJob : valid job type");
JobTypeData& data(getJobTypeData(type));
XRPL_ASSERT(
@@ -312,15 +312,15 @@ JobQueue::getNextJob(Job& job)
}
}
XRPL_ASSERT(iter != m_jobSet.end(), "xrpl::JobQueue::getNextJob : found next job");
XRPL_ASSERT(iter != jobSet_.end(), "xrpl::JobQueue::getNextJob : found next job");
job = *iter;
m_jobSet.erase(iter);
jobSet_.erase(iter);
}
void
JobQueue::finishJob(JobType type)
{
XRPL_ASSERT(type != jtINVALID, "xrpl::JobQueue::finishJob : valid input job type");
XRPL_ASSERT(type != JtInvalid, "xrpl::JobQueue::finishJob : valid input job type");
JobTypeData& data = getJobTypeData(type);
@@ -332,7 +332,7 @@ JobQueue::finishJob(JobType type)
"xrpl::JobQueue::finishJob : job limit");
--data.deferred;
m_workers.addTask();
workers_.addTask();
}
--data.running;
@@ -341,47 +341,47 @@ JobQueue::finishJob(JobType type)
void
JobQueue::processTask(int instance)
{
JobType type = jtINVALID;
JobType type = JtInvalid;
{
using namespace std::chrono;
Job::clock_type::time_point const start_time(Job::clock_type::now());
Job::clock_type::time_point const startTime(Job::clock_type::now());
{
Job job;
{
std::lock_guard const lock(m_mutex);
std::scoped_lock const lock(mutex_);
getNextJob(job);
++m_processCount;
++processCount_;
}
type = job.getType();
JobTypeData const& data(getJobTypeData(type));
JLOG(m_journal.trace()) << "Doing " << data.name() << "job";
JLOG(journal_.trace()) << "Doing " << data.name() << "job";
// The amount of time that the job was in the queue
auto const q_time = ceil<microseconds>(start_time - job.queue_time());
perfLog_.jobStart(type, q_time, start_time, instance);
auto const qTime = ceil<microseconds>(startTime - job.queueTime());
perfLog_.jobStart(type, qTime, startTime, instance);
job.doJob();
// The amount of time it took to execute the job
auto const x_time = ceil<microseconds>(Job::clock_type::now() - start_time);
auto const xTime = ceil<microseconds>(Job::clock_type::now() - startTime);
if (x_time >= 10ms || q_time >= 10ms)
if (xTime >= 10ms || qTime >= 10ms)
{
getJobTypeData(type).dequeue.notify(q_time);
getJobTypeData(type).execute.notify(x_time);
getJobTypeData(type).dequeue.notify(qTime);
getJobTypeData(type).execute.notify(xTime);
}
perfLog_.jobFinish(type, x_time, instance);
perfLog_.jobFinish(type, xTime, instance);
}
}
{
std::lock_guard const lock(m_mutex);
std::scoped_lock const lock(mutex_);
// Job should be destroyed before stopping
// otherwise destructors with side effects can access
// parent objects that are already destroyed.
finishJob(type);
if (--m_processCount == 0 && m_jobSet.empty())
if (--processCount_ == 0 && jobSet_.empty())
cv_.notify_all();
}
@@ -393,7 +393,7 @@ int
JobQueue::getJobLimit(JobType type)
{
JobTypeInfo const& j(JobTypes::instance().get(type));
XRPL_ASSERT(j.type() != jtINVALID, "xrpl::JobQueue::getJobLimit : valid job type");
XRPL_ASSERT(j.type() != JtInvalid, "xrpl::JobQueue::getJobLimit : valid job type");
return j.limit();
}

View File

@@ -28,11 +28,11 @@ LoadMonitor::Stats::Stats() : latencyAvg(0), latencyPeak(0)
//------------------------------------------------------------------------------
LoadMonitor::LoadMonitor(beast::Journal j)
: mLatencyMSAvg(0)
, mLatencyMSPeak(0)
, mTargetLatencyAvg(0)
, mTargetLatencyPk(0)
, mLastUpdate(UptimeClock::now())
: latencyMSAvg_(0)
, latencyMSPeak_(0)
, targetLatencyAvg_(0)
, targetLatencyPk_(0)
, lastUpdate_(UptimeClock::now())
, j_(j)
{
}
@@ -48,18 +48,18 @@ LoadMonitor::update()
{
using namespace std::chrono_literals;
auto now = UptimeClock::now();
if (now == mLastUpdate) // current
if (now == lastUpdate_) // current
return;
// VFALCO TODO Why 8?
if ((now < mLastUpdate) || (now > (mLastUpdate + 8s)))
if ((now < lastUpdate_) || (now > (lastUpdate_ + 8s)))
{
// way out of date
mCounts = 0;
mLatencyEvents = 0;
mLatencyMSAvg = 0ms;
mLatencyMSPeak = 0ms;
mLastUpdate = now;
counts_ = 0;
latencyEvents_ = 0;
latencyMSAvg_ = 0ms;
latencyMSPeak_ = 0ms;
lastUpdate_ = now;
return;
}
@@ -73,12 +73,12 @@ LoadMonitor::update()
*/
do
{
mLastUpdate += 1s;
mCounts -= ((mCounts + 3) / 4);
mLatencyEvents -= ((mLatencyEvents + 3) / 4);
mLatencyMSAvg -= (mLatencyMSAvg / 4);
mLatencyMSPeak -= (mLatencyMSPeak / 4);
} while (mLastUpdate < now);
lastUpdate_ += 1s;
counts_ -= ((counts_ + 3) / 4);
latencyEvents_ -= ((latencyEvents_ + 3) / 4);
latencyMSAvg_ -= (latencyMSAvg_ / 4);
latencyMSPeak_ -= (latencyMSPeak_ / 4);
} while (lastUpdate_ < now);
}
void
@@ -108,47 +108,47 @@ LoadMonitor::addLoadSample(LoadEvent const& s)
void
LoadMonitor::addSamples(int count, std::chrono::milliseconds latency)
{
std::lock_guard const sl(mutex_);
std::scoped_lock const sl(mutex_);
update();
mCounts += count;
mLatencyEvents += count;
mLatencyMSAvg += latency;
mLatencyMSPeak += latency;
counts_ += count;
latencyEvents_ += count;
latencyMSAvg_ += latency;
latencyMSPeak_ += latency;
auto const latencyPeak = mLatencyEvents * latency * 4 / count;
auto const latencyPeak = latencyEvents_ * latency * 4 / count;
if (mLatencyMSPeak < latencyPeak)
mLatencyMSPeak = latencyPeak;
if (latencyMSPeak_ < latencyPeak)
latencyMSPeak_ = latencyPeak;
}
void
LoadMonitor::setTargetLatency(std::chrono::milliseconds avg, std::chrono::milliseconds pk)
{
mTargetLatencyAvg = avg;
mTargetLatencyPk = pk;
targetLatencyAvg_ = avg;
targetLatencyPk_ = pk;
}
bool
LoadMonitor::isOverTarget(std::chrono::milliseconds avg, std::chrono::milliseconds peak)
{
using namespace std::chrono_literals;
return (mTargetLatencyPk > 0ms && (peak > mTargetLatencyPk)) ||
(mTargetLatencyAvg > 0ms && (avg > mTargetLatencyAvg));
return (targetLatencyPk_ > 0ms && (peak > targetLatencyPk_)) ||
(targetLatencyAvg_ > 0ms && (avg > targetLatencyAvg_));
}
bool
LoadMonitor::isOver()
{
std::lock_guard const sl(mutex_);
std::scoped_lock const sl(mutex_);
update();
if (mLatencyEvents == 0)
if (latencyEvents_ == 0)
return false;
return isOverTarget(
mLatencyMSAvg / (mLatencyEvents * 4), mLatencyMSPeak / (mLatencyEvents * 4));
latencyMSAvg_ / (latencyEvents_ * 4), latencyMSPeak_ / (latencyEvents_ * 4));
}
LoadMonitor::Stats
@@ -157,21 +157,21 @@ LoadMonitor::getStats()
using namespace std::chrono_literals;
Stats stats;
std::lock_guard const sl(mutex_);
std::scoped_lock const sl(mutex_);
update();
stats.count = mCounts / 4;
stats.count = counts_ / 4;
if (mLatencyEvents == 0)
if (latencyEvents_ == 0)
{
stats.latencyAvg = 0ms;
stats.latencyPeak = 0ms;
}
else
{
stats.latencyAvg = mLatencyMSAvg / (mLatencyEvents * 4);
stats.latencyPeak = mLatencyMSPeak / (mLatencyEvents * 4);
stats.latencyAvg = latencyMSAvg_ / (latencyEvents_ * 4);
stats.latencyPeak = latencyMSPeak_ / (latencyEvents_ * 4);
}
stats.isOverloaded = isOverTarget(stats.latencyAvg, stats.latencyPeak);

View File

@@ -15,13 +15,13 @@ Workers::Workers(
perf::PerfLog* perfLog,
std::string threadNames,
int numberOfThreads)
: m_callback(callback)
: callback_(callback)
, perfLog_(perfLog)
, m_threadNames(std::move(threadNames))
, m_semaphore(0)
, m_activeCount(0)
, m_pauseCount(0)
, m_runningTaskCount(0)
, threadNames_(std::move(threadNames))
, semaphore_(0)
, activeCount_(0)
, pauseCount_(0)
, runningTaskCount_(0)
{
setNumberOfThreads(numberOfThreads);
}
@@ -30,13 +30,13 @@ Workers::~Workers()
{
stop();
deleteWorkers(m_everyone);
deleteWorkers(everyone_);
}
int
Workers::getNumberOfThreads() const noexcept
{
return m_numberOfThreads;
return numberOfThreads_;
}
// VFALCO NOTE if this function is called quickly to reduce then
@@ -46,22 +46,22 @@ Workers::getNumberOfThreads() const noexcept
void
Workers::setNumberOfThreads(int numberOfThreads)
{
static int instance{0};
if (m_numberOfThreads == numberOfThreads)
static int kInstance{0};
if (numberOfThreads_ == numberOfThreads)
return;
if (perfLog_ != nullptr)
perfLog_->resizeJobs(numberOfThreads);
if (numberOfThreads > m_numberOfThreads)
if (numberOfThreads > numberOfThreads_)
{
// Increasing the number of working threads
int const amount = numberOfThreads - m_numberOfThreads;
int const amount = numberOfThreads - numberOfThreads_;
for (int i = 0; i < amount; ++i)
{
// See if we can reuse a paused worker
Worker* worker = m_paused.pop_front();
Worker* worker = paused_.popFront();
if (worker != nullptr)
{
@@ -72,26 +72,26 @@ Workers::setNumberOfThreads(int numberOfThreads)
}
else
{
worker = new Worker(*this, m_threadNames, instance++);
m_everyone.push_front(worker);
worker = new Worker(*this, threadNames_, kInstance++);
everyone_.pushFront(worker);
}
}
}
else
{
// Decreasing the number of working threads
int const amount = m_numberOfThreads - numberOfThreads;
int const amount = numberOfThreads_ - numberOfThreads;
for (int i = 0; i < amount; ++i)
{
++m_pauseCount;
++pauseCount_;
// Pausing a thread counts as one "internal task"
m_semaphore.notify();
semaphore_.notify();
}
}
m_numberOfThreads = numberOfThreads;
numberOfThreads_ = numberOfThreads;
}
void
@@ -100,24 +100,24 @@ Workers::stop()
setNumberOfThreads(0);
// Wait until all workers have paused AND no tasks are actively running.
// Both conditions are needed because m_allPaused (mutex-protected) and
// m_runningTaskCount (atomic) are not synchronized under the same lock,
// so m_allPaused can momentarily be true while a task is still finishing.
std::unique_lock<std::mutex> lk{m_mut};
m_cv.wait(lk, [this] { return m_allPaused && numberOfCurrentlyRunningTasks() == 0; });
// Both conditions are needed because allPaused_ (mutex-protected) and
// runningTaskCount_ (atomic) are not synchronized under the same lock,
// so allPaused_ can momentarily be true while a task is still finishing.
std::unique_lock<std::mutex> lk{mut_};
cv_.wait(lk, [this] { return allPaused_ && numberOfCurrentlyRunningTasks() == 0; });
lk.unlock();
}
void
Workers::addTask()
{
m_semaphore.notify();
semaphore_.notify();
}
int
Workers::numberOfCurrentlyRunningTasks() const noexcept
{
return m_runningTaskCount.load();
return runningTaskCount_.load();
}
void
@@ -125,7 +125,7 @@ Workers::deleteWorkers(beast::LockFreeStack<Worker>& stack)
{
for (;;)
{
Worker const* const worker = stack.pop_front();
Worker const* const worker = stack.popFront();
if (worker != nullptr)
{
@@ -142,7 +142,7 @@ Workers::deleteWorkers(beast::LockFreeStack<Worker>& stack)
//------------------------------------------------------------------------------
Workers::Worker::Worker(Workers& workers, std::string threadName, int const instance)
: m_workers{workers}, threadName_{std::move(threadName)}, instance_{instance}
: workers_{workers}, threadName_{std::move(threadName)}, instance_{instance}
{
thread_ = std::thread{&Workers::Worker::run, this};
@@ -151,7 +151,7 @@ Workers::Worker::Worker(Workers& workers, std::string threadName, int const inst
Workers::Worker::~Worker()
{
{
std::lock_guard const lock{mutex_};
std::scoped_lock const lock{mutex_};
++wakeCount_;
shouldExit_ = true;
}
@@ -163,7 +163,7 @@ Workers::Worker::~Worker()
void
Workers::Worker::notify()
{
std::lock_guard const lock{mutex_};
std::scoped_lock const lock{mutex_};
++wakeCount_;
wakeup_.notify_one();
}
@@ -177,10 +177,10 @@ Workers::Worker::run()
// Increment the count of active workers, and if
// we are the first one then reset the "all paused" event
//
if (++m_workers.m_activeCount == 1)
if (++workers_.activeCount_ == 1)
{
std::lock_guard const lk{m_workers.m_mut};
m_workers.m_allPaused = false;
std::scoped_lock const lk{workers_.mut_};
workers_.allPaused_ = false;
}
for (;;)
@@ -190,17 +190,17 @@ Workers::Worker::run()
// Acquire a task or "internal task."
//
m_workers.m_semaphore.wait();
workers_.semaphore_.wait();
// See if there's a pause request. This
// counts as an "internal task."
//
int pauseCount = m_workers.m_pauseCount.load();
int pauseCount = workers_.pauseCount_.load();
if (pauseCount > 0)
{
// Try to decrement
pauseCount = --m_workers.m_pauseCount;
pauseCount = --workers_.pauseCount_;
if (pauseCount >= 0)
{
@@ -209,25 +209,25 @@ Workers::Worker::run()
}
// Undo our decrement
++m_workers.m_pauseCount;
++workers_.pauseCount_;
}
// We couldn't pause so we must have gotten
// unblocked in order to process a task.
//
++m_workers.m_runningTaskCount;
m_workers.m_callback.processTask(instance_);
++workers_.runningTaskCount_;
workers_.callback_.processTask(instance_);
// When the running task count drops to zero, wake stop() which
// may be waiting for both m_allPaused and zero running tasks.
// Locking m_mut before notify_all() prevents a lost wakeup:
// may be waiting for both allPaused_ and zero running tasks.
// Locking mut_ before notify_all() prevents a lost wakeup:
// it serializes against the predicate check inside stop()'s
// cv.wait(), ensuring the notification is not missed between
// cv_.wait(), ensuring the notification is not missed between
// the predicate evaluation and the actual sleep.
if (--m_workers.m_runningTaskCount == 0)
if (--workers_.runningTaskCount_ == 0)
{
std::lock_guard const lk{m_workers.m_mut};
m_workers.m_cv.notify_all();
std::scoped_lock const lk{workers_.mut_};
workers_.cv_.notify_all();
}
}
@@ -235,16 +235,16 @@ Workers::Worker::run()
// guarantee that it will eventually block on its
// event object.
//
m_workers.m_paused.push_front(this);
workers_.paused_.pushFront(this);
// Decrement the count of active workers, and if we
// are the last one then signal the "all paused" event.
//
if (--m_workers.m_activeCount == 0)
if (--workers_.activeCount_ == 0)
{
std::lock_guard const lk{m_workers.m_mut};
m_workers.m_allPaused = true;
m_workers.m_cv.notify_all();
std::scoped_lock const lk{workers_.mut_};
workers_.allPaused_ = true;
workers_.cv_.notify_all();
}
// Set inactive thread name.

View File

@@ -21,7 +21,7 @@ namespace xrpl {
// RFC 1751 code converted to C++/Boost.
//
char const* RFC1751::s_dictionary[2048] = {
char const* RFC1751::dictionary[2048] = {
"A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", "AGO", "AID", "AIM", "AIR", "ALL",
"ALP", "AM", "AMY", "AN", "ANA", "AND", "ANN", "ANT", "ANY", "APE", "APS", "APT",
"ARC", "ARE", "ARK", "ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK",
@@ -237,10 +237,10 @@ RFC1751::btoe(std::string& strHuman, std::string const& strData)
caBuffer[8] = char(p) << 6;
strHuman = std::string() + s_dictionary[extract(caBuffer, 0, 11)] + " " +
s_dictionary[extract(caBuffer, 11, 11)] + " " + s_dictionary[extract(caBuffer, 22, 11)] +
" " + s_dictionary[extract(caBuffer, 33, 11)] + " " +
s_dictionary[extract(caBuffer, 44, 11)] + " " + s_dictionary[extract(caBuffer, 55, 11)];
strHuman = std::string() + dictionary[extract(caBuffer, 0, 11)] + " " +
dictionary[extract(caBuffer, 11, 11)] + " " + dictionary[extract(caBuffer, 22, 11)] + " " +
dictionary[extract(caBuffer, 33, 11)] + " " + dictionary[extract(caBuffer, 44, 11)] + " " +
dictionary[extract(caBuffer, 55, 11)];
}
void
@@ -314,7 +314,7 @@ RFC1751::wsrch(std::string const& strWord, int iMin, int iMax)
{
// Have a range to search.
int const iMid = iMin + ((iMax - iMin) / 2);
int const iDir = strWord.compare(s_dictionary[iMid]);
int const iDir = strWord.compare(dictionary[iMid]);
if (iDir == 0)
{
@@ -447,7 +447,7 @@ RFC1751::getWordFromBlob(void const* blob, size_t bytes)
hash ^= (hash >> 11);
hash += (hash << 15);
return s_dictionary[hash % (sizeof(s_dictionary) / sizeof(s_dictionary[0]))];
return dictionary[hash % (sizeof(dictionary) / sizeof(dictionary[0]))];
}
} // namespace xrpl

View File

@@ -13,14 +13,14 @@
namespace xrpl {
csprng_engine::csprng_engine()
CsprngEngine::CsprngEngine()
{
// This is not strictly necessary
if (RAND_poll() != 1)
Throw<std::runtime_error>("CSPRNG: Initial polling failed");
}
csprng_engine::~csprng_engine()
CsprngEngine::~CsprngEngine()
{
// This cleanup function is not needed in newer versions of OpenSSL
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
@@ -29,7 +29,7 @@ csprng_engine::~csprng_engine()
}
void
csprng_engine::mix_entropy(void* buffer, std::size_t count)
CsprngEngine::mixEntropy(void* buffer, std::size_t count)
{
std::array<std::random_device::result_type, 128> entropy{};
@@ -43,7 +43,7 @@ csprng_engine::mix_entropy(void* buffer, std::size_t count)
e = rd();
}
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
// We add data to the pool, but we conservatively assume that
// it contributes no actual entropy.
@@ -54,13 +54,13 @@ csprng_engine::mix_entropy(void* buffer, std::size_t count)
}
void
csprng_engine::operator()(void* ptr, std::size_t count)
CsprngEngine::operator()(void* ptr, std::size_t count)
{
// RAND_bytes is thread-safe on OpenSSL 1.1.0 and later when compiled
// with thread support, so we don't need to grab a mutex.
// https://mta.openssl.org/pipermail/openssl-users/2020-November/013146.html
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || !defined(OPENSSL_THREADS)
std::lock_guard lock(mutex_);
std::scoped_lock lock(mutex_);
#endif
auto const result = RAND_bytes(reinterpret_cast<unsigned char*>(ptr), count);
@@ -69,19 +69,19 @@ csprng_engine::operator()(void* ptr, std::size_t count)
Throw<std::runtime_error>("CSPRNG: Insufficient entropy");
}
csprng_engine::result_type
csprng_engine::operator()()
CsprngEngine::result_type
CsprngEngine::operator()()
{
result_type ret = 0;
(*this)(&ret, sizeof(result_type));
return ret;
}
csprng_engine&
crypto_prng()
CsprngEngine&
cryptoPrng()
{
static csprng_engine engine;
return engine;
static CsprngEngine kEngine;
return kEngine;
}
} // namespace xrpl

View File

@@ -7,7 +7,7 @@
namespace xrpl {
void
secure_erase(void* dest, std::size_t bytes)
secureErase(void* dest, std::size_t bytes)
{
OPENSSL_cleanse(dest, bytes);
}

View File

@@ -11,21 +11,21 @@
namespace xrpl::git {
static constexpr char kGIT_COMMIT_HASH[] = GIT_COMMIT_HASH;
static constexpr char kGIT_BUILD_BRANCH[] = GIT_BUILD_BRANCH;
static constexpr char kGitCommitHash[] = GIT_COMMIT_HASH;
static constexpr char kGitBuildBranch[] = GIT_BUILD_BRANCH;
std::string const&
getCommitHash()
{
static std::string const kVALUE = kGIT_COMMIT_HASH;
return kVALUE;
static std::string const kValue = kGitCommitHash;
return kValue;
}
std::string const&
getBuildBranch()
{
static std::string const kVALUE = kGIT_BUILD_BRANCH;
return kVALUE;
static std::string const kValue = kGitBuildBranch;
return kValue;
}
} // namespace xrpl::git

View File

@@ -6,160 +6,160 @@
namespace xrpl {
JsonPropertyStream::JsonPropertyStream() : m_top(Json::objectValue)
JsonPropertyStream::JsonPropertyStream() : topValue(json::ValueType::Object)
{
m_stack.reserve(64);
m_stack.push_back(&m_top);
stack.reserve(64);
stack.push_back(&topValue);
}
Json::Value const&
json::Value const&
JsonPropertyStream::top() const
{
return m_top;
return topValue;
}
void
JsonPropertyStream::map_begin()
JsonPropertyStream::mapBegin()
{
// top is array
Json::Value& top(*m_stack.back());
Json::Value& map(top.append(Json::objectValue));
m_stack.push_back(&map);
json::Value& top(*stack.back());
json::Value& map(top.append(json::ValueType::Object));
stack.push_back(&map);
}
void
JsonPropertyStream::map_begin(std::string const& key)
JsonPropertyStream::mapBegin(std::string const& key)
{
// top is a map
Json::Value& top(*m_stack.back());
Json::Value& map(top[key] = Json::objectValue);
m_stack.push_back(&map);
json::Value& top(*stack.back());
json::Value& map(top[key] = json::ValueType::Object);
stack.push_back(&map);
}
void
JsonPropertyStream::map_end()
JsonPropertyStream::mapEnd()
{
m_stack.pop_back();
stack.pop_back();
}
void
JsonPropertyStream::add(std::string const& key, short v)
{
(*m_stack.back())[key] = v;
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, unsigned short v)
{
(*m_stack.back())[key] = v;
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, int v)
{
(*m_stack.back())[key] = v;
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, unsigned int v)
{
(*m_stack.back())[key] = v;
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, long v)
{
(*m_stack.back())[key] = int(v);
(*stack.back())[key] = int(v);
}
void
JsonPropertyStream::add(std::string const& key, float v)
{
(*m_stack.back())[key] = v;
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, double v)
{
(*m_stack.back())[key] = v;
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, std::string const& v)
{
(*m_stack.back())[key] = v;
(*stack.back())[key] = v;
}
void
JsonPropertyStream::array_begin()
JsonPropertyStream::arrayBegin()
{
// top is array
Json::Value& top(*m_stack.back());
Json::Value& vec(top.append(Json::arrayValue));
m_stack.push_back(&vec);
json::Value& top(*stack.back());
json::Value& vec(top.append(json::ValueType::Array));
stack.push_back(&vec);
}
void
JsonPropertyStream::array_begin(std::string const& key)
JsonPropertyStream::arrayBegin(std::string const& key)
{
// top is a map
Json::Value& top(*m_stack.back());
Json::Value& vec(top[key] = Json::arrayValue);
m_stack.push_back(&vec);
json::Value& top(*stack.back());
json::Value& vec(top[key] = json::ValueType::Array);
stack.push_back(&vec);
}
void
JsonPropertyStream::array_end()
JsonPropertyStream::arrayEnd()
{
m_stack.pop_back();
stack.pop_back();
}
void
JsonPropertyStream::add(short v)
{
m_stack.back()->append(v);
stack.back()->append(v);
}
void
JsonPropertyStream::add(unsigned short v)
{
m_stack.back()->append(v);
stack.back()->append(v);
}
void
JsonPropertyStream::add(int v)
{
m_stack.back()->append(v);
stack.back()->append(v);
}
void
JsonPropertyStream::add(unsigned int v)
{
m_stack.back()->append(v);
stack.back()->append(v);
}
void
JsonPropertyStream::add(long v)
{
m_stack.back()->append(int(v));
stack.back()->append(int(v));
}
void
JsonPropertyStream::add(float v)
{
m_stack.back()->append(v);
stack.back()->append(v);
}
void
JsonPropertyStream::add(double v)
{
m_stack.back()->append(v);
stack.back()->append(v);
}
void
JsonPropertyStream::add(std::string const& v)
{
m_stack.back()->append(v);
stack.back()->append(v);
}
} // namespace xrpl

View File

@@ -5,47 +5,47 @@
#include <string>
namespace Json {
namespace json {
namespace {
void
outputJson(Json::Value const& value, Writer& writer)
outputJson(Value const& value, Writer& writer)
{
switch (value.type())
{
case Json::nullValue: {
case ValueType::Null: {
writer.output(nullptr);
break;
}
case Json::intValue: {
case ValueType::Int: {
writer.output(value.asInt());
break;
}
case Json::uintValue: {
case ValueType::UInt: {
writer.output(value.asUInt());
break;
}
case Json::realValue: {
case ValueType::Real: {
writer.output(value.asDouble());
break;
}
case Json::stringValue: {
case ValueType::String: {
writer.output(value.asString());
break;
}
case Json::booleanValue: {
case ValueType::Boolean: {
writer.output(value.asBool());
break;
}
case Json::arrayValue: {
writer.startRoot(Writer::array);
case ValueType::Array: {
writer.startRoot(Writer::CollectionType::Array);
for (auto const& i : value)
{
writer.rawAppend();
@@ -55,8 +55,8 @@ outputJson(Json::Value const& value, Writer& writer)
break;
}
case Json::objectValue: {
writer.startRoot(Writer::object);
case ValueType::Object: {
writer.startRoot(Writer::CollectionType::Object);
auto members = value.getMemberNames();
for (auto const& tag : members)
{
@@ -72,14 +72,14 @@ outputJson(Json::Value const& value, Writer& writer)
} // namespace
void
outputJson(Json::Value const& value, Output const& out)
outputJson(Value const& value, Output const& out)
{
Writer writer(out);
outputJson(value, writer);
}
std::string
jsonAsString(Json::Value const& value)
jsonAsString(Value const& value)
{
std::string s;
Writer writer(stringOutput(s));
@@ -87,4 +87,4 @@ jsonAsString(Json::Value const& value)
return s;
}
} // namespace Json
} // namespace json

View File

@@ -12,11 +12,11 @@
#include <utility>
#include <vector>
namespace Json {
namespace json {
namespace {
std::map<char, char const*> jsonSpecialCharacterEscape = {
std::map<char, char const*> gJsonSpecialCharacterEscape = {
{'"', "\\\""},
{'\\', "\\\\"},
{'/', "\\/"},
@@ -26,18 +26,18 @@ std::map<char, char const*> jsonSpecialCharacterEscape = {
{'\r', "\\r"},
{'\t', "\\t"}};
size_t const jsonEscapeLength = 2;
size_t const kJsonEscapeLength = 2;
// All other JSON punctuation.
char const closeBrace = '}';
char const closeBracket = ']';
char const colon = ':';
char const comma = ',';
char const openBrace = '{';
char const openBracket = '[';
char const quote = '"';
char const kCloseBrace = '}';
char const kCloseBracket = ']';
char const kColon = ':';
char const kComma = ',';
char const kOpenBrace = '{';
char const kOpenBracket = '[';
char const kQuote = '"';
auto const integralFloatsBecomeInts = false;
auto const kIntegralFloatsBecomeInts = false;
size_t
lengthWithoutTrailingZeros(std::string const& s)
@@ -52,7 +52,7 @@ lengthWithoutTrailingZeros(std::string const& s)
if (hasDecimals)
return lastNonZero + 1;
if (integralFloatsBecomeInts || lastNonZero + 2 > s.size())
if (kIntegralFloatsBecomeInts || lastNonZero + 2 > s.size())
return lastNonZero;
return lastNonZero + 2;
@@ -81,7 +81,7 @@ public:
void
start(CollectionType ct)
{
char const ch = (ct == array) ? openBracket : openBrace;
char const ch = (ct == CollectionType::Array) ? kOpenBracket : kOpenBrace;
output({&ch, 1});
stack_.emplace(Collection{.type = ct});
}
@@ -99,24 +99,24 @@ public:
markStarted();
std::size_t position = 0, writtenUntil = 0;
output_({&quote, 1});
output_({&kQuote, 1});
auto data = bytes.data();
for (; position < bytes.size(); ++position)
{
auto i = jsonSpecialCharacterEscape.find(data[position]);
if (i != jsonSpecialCharacterEscape.end())
auto i = gJsonSpecialCharacterEscape.find(data[position]);
if (i != gJsonSpecialCharacterEscape.end())
{
if (writtenUntil < position)
{
output_({data + writtenUntil, position - writtenUntil});
}
output_({i->second, jsonEscapeLength});
output_({i->second, kJsonEscapeLength});
writtenUntil = position + 1;
};
}
if (writtenUntil < position)
output_({data + writtenUntil, position - writtenUntil});
output_({&quote, 1});
output_({&kQuote, 1});
}
void
@@ -134,7 +134,9 @@ public:
auto t = stack_.top().type;
if (t != type)
{
check(false, "Not an " + ((type == array ? "array: " : "object: ") + message));
check(
false,
"Not an " + ((type == CollectionType::Array ? "array: " : "object: ") + message));
}
if (stack_.top().isFirst)
{
@@ -142,7 +144,7 @@ public:
}
else
{
output_({&comma, 1});
output_({&kComma, 1});
}
}
@@ -157,7 +159,7 @@ public:
#endif
stringOutput(tag);
output_({&colon, 1});
output_({&kColon, 1});
}
[[nodiscard]] bool
@@ -171,8 +173,8 @@ public:
{
check(!empty(), "Empty stack in finish()");
auto isArray = stack_.top().type == array;
auto ch = isArray ? closeBracket : closeBrace;
auto isArray = stack_.top().type == CollectionType::Array;
auto ch = isArray ? kCloseBracket : kCloseBrace;
output_({&ch, 1});
stack_.pop();
}
@@ -198,7 +200,7 @@ private:
struct Collection
{
/** What type of collection are we in? */
Writer::CollectionType type = Writer::CollectionType::array;
Writer::CollectionType type = Writer::CollectionType::Array;
/** Is this the first entry in a collection?
* If false, we have to emit a , before we write the next entry. */
@@ -253,7 +255,7 @@ Writer::output(std::string const& s)
}
void
Writer::output(Json::Value const& value)
Writer::output(json::Value const& value)
{
impl_->markStarted();
outputJson(value, impl_->getOutput());
@@ -301,7 +303,7 @@ Writer::finishAll()
void
Writer::rawAppend()
{
impl_->nextCollectionEntry(array, "append");
impl_->nextCollectionEntry(CollectionType::Array, "append");
}
void
@@ -309,7 +311,7 @@ Writer::rawSet(std::string const& tag)
{
check(!tag.empty(), "Tag can't be empty");
impl_->nextCollectionEntry(object, "set");
impl_->nextCollectionEntry(CollectionType::Object, "set");
impl_->writeObjectTag(tag);
}
@@ -322,14 +324,14 @@ Writer::startRoot(CollectionType type)
void
Writer::startAppend(CollectionType type)
{
impl_->nextCollectionEntry(array, "startAppend");
impl_->nextCollectionEntry(CollectionType::Array, "startAppend");
impl_->start(type);
}
void
Writer::startSet(CollectionType type, std::string const& key)
{
impl_->nextCollectionEntry(object, "startSet");
impl_->nextCollectionEntry(CollectionType::Object, "startSet");
impl_->writeObjectTag(key);
impl_->start(type);
}
@@ -341,4 +343,4 @@ Writer::finish()
impl_->finish();
}
} // namespace Json
} // namespace json

View File

@@ -12,7 +12,7 @@
#include <stdexcept>
#include <string>
namespace Json {
namespace json {
// Implementation of class Reader
// ////////////////////////////////
@@ -102,9 +102,9 @@ Reader::parse(char const* beginDoc, char const* endDoc, Value& root)
{
// Set error location to start of doc, ideally should be first token
// found in doc
token.type_ = tokenError;
token.start_ = beginDoc;
token.end_ = endDoc;
token.type = TokenType::Error;
token.start = beginDoc;
token.end = endDoc;
addError("A valid JSON document must be either an array or an object value.", token);
return false;
}
@@ -117,41 +117,41 @@ Reader::readValue(unsigned depth)
{
Token token{};
skipCommentTokens(token);
if (depth > nest_limit)
if (depth > kNestLimit)
return addError("Syntax error: maximum nesting depth exceeded", token);
bool successful = true;
switch (token.type_)
switch (token.type)
{
case tokenObjectBegin:
case TokenType::ObjectBegin:
successful = readObject(token, depth);
break;
case tokenArrayBegin:
case TokenType::ArrayBegin:
successful = readArray(token, depth);
break;
case tokenInteger:
case TokenType::Integer:
successful = decodeNumber(token);
break;
case tokenDouble:
case TokenType::Double:
successful = decodeDouble(token);
break;
case tokenString:
case TokenType::String:
successful = decodeString(token);
break;
case tokenTrue:
case TokenType::True:
currentValue() = true;
break;
case tokenFalse:
case TokenType::False:
currentValue() = false;
break;
case tokenNull:
case TokenType::Null:
currentValue() = Value();
break;
@@ -168,7 +168,7 @@ Reader::skipCommentTokens(Token& token)
do
{
readToken(token);
} while (token.type_ == tokenComment);
} while (token.type == TokenType::Comment);
}
bool
@@ -176,7 +176,7 @@ Reader::expectToken(TokenType type, Token& token, char const* message)
{
readToken(token);
if (token.type_ != type)
if (token.type != type)
return addError(message, token);
return true;
@@ -186,35 +186,35 @@ bool
Reader::readToken(Token& token)
{
skipSpaces();
token.start_ = current_;
token.start = current_;
Char const c = getNextChar();
bool ok = true;
switch (c)
{
case '{':
token.type_ = tokenObjectBegin;
token.type = TokenType::ObjectBegin;
break;
case '}':
token.type_ = tokenObjectEnd;
token.type = TokenType::ObjectEnd;
break;
case '[':
token.type_ = tokenArrayBegin;
token.type = TokenType::ArrayBegin;
break;
case ']':
token.type_ = tokenArrayEnd;
token.type = TokenType::ArrayEnd;
break;
case '"':
token.type_ = tokenString;
token.type = TokenType::String;
ok = readString();
break;
case '/':
token.type_ = tokenComment;
token.type = TokenType::Comment;
ok = readComment();
break;
@@ -229,34 +229,34 @@ Reader::readToken(Token& token)
case '8':
case '9':
case '-':
token.type_ = readNumber();
token.type = readNumber();
break;
case 't':
token.type_ = tokenTrue;
token.type = TokenType::True;
ok = match("rue", 3);
break;
case 'f':
token.type_ = tokenFalse;
token.type = TokenType::False;
ok = match("alse", 4); // cspell:disable-line
break;
case 'n':
token.type_ = tokenNull;
token.type = TokenType::Null;
ok = match("ull", 3);
break;
case ',':
token.type_ = tokenArraySeparator;
token.type = TokenType::ArraySeparator;
break;
case ':':
token.type_ = tokenMemberSeparator;
token.type = TokenType::MemberSeparator;
break;
case 0:
token.type_ = tokenEndOfStream;
token.type = TokenType::EndOfStream;
break;
default:
@@ -265,9 +265,9 @@ Reader::readToken(Token& token)
}
if (!ok)
token.type_ = tokenError;
token.type = TokenType::Error;
token.end_ = current_;
token.end = current_;
return true;
}
@@ -352,9 +352,9 @@ Reader::readCppStyleComment()
Reader::TokenType
Reader::readNumber()
{
static char const extended_tokens[] = {'.', 'e', 'E', '+', '-'};
static char const kExtendedTokens[] = {'.', 'e', 'E', '+', '-'};
TokenType type = tokenInteger;
TokenType type = TokenType::Integer;
if (current_ != end_)
{
@@ -365,12 +365,12 @@ Reader::readNumber()
{
if (std::isdigit(static_cast<unsigned char>(*current_)) == 0)
{
auto ret = std::ranges::find(extended_tokens, *current_);
auto ret = std::ranges::find(kExtendedTokens, *current_);
if (ret == std::end(extended_tokens))
if (ret == std::end(kExtendedTokens))
break;
type = tokenDouble;
type = TokenType::Double;
}
++current_;
@@ -407,35 +407,35 @@ Reader::readObject(Token& tokenStart, unsigned depth)
{
Token tokenName{};
std::string name;
currentValue() = Value(objectValue);
currentValue() = Value(ValueType::Object);
while (readToken(tokenName))
{
bool initialTokenOk = true;
while (tokenName.type_ == tokenComment && initialTokenOk)
while (tokenName.type == TokenType::Comment && initialTokenOk)
initialTokenOk = readToken(tokenName);
if (!initialTokenOk)
break;
if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
if (tokenName.type == TokenType::ObjectEnd && name.empty()) // empty object
return true;
if (tokenName.type_ != tokenString)
if (tokenName.type != TokenType::String)
break;
name = "";
if (!decodeString(tokenName, name))
return recoverFromError(tokenObjectEnd);
return recoverFromError(TokenType::ObjectEnd);
Token colon{};
if (!readToken(colon) || colon.type_ != tokenMemberSeparator)
if (!readToken(colon) || colon.type != TokenType::MemberSeparator)
{
return addErrorAndRecover(
"Missing ':' after object member name", colon, tokenObjectEnd);
"Missing ':' after object member name", colon, TokenType::ObjectEnd);
}
// Reject duplicate names
@@ -448,34 +448,34 @@ Reader::readObject(Token& tokenStart, unsigned depth)
nodes_.pop();
if (!ok) // error already set
return recoverFromError(tokenObjectEnd);
return recoverFromError(TokenType::ObjectEnd);
Token comma{};
if (!readToken(comma) ||
(comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
comma.type_ != tokenComment))
(comma.type != TokenType::ObjectEnd && comma.type != TokenType::ArraySeparator &&
comma.type != TokenType::Comment))
{
return addErrorAndRecover(
"Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
"Missing ',' or '}' in object declaration", comma, TokenType::ObjectEnd);
}
bool finalizeTokenOk = true;
while (comma.type_ == tokenComment && finalizeTokenOk)
while (comma.type == TokenType::Comment && finalizeTokenOk)
finalizeTokenOk = readToken(comma);
if (comma.type_ == tokenObjectEnd)
if (comma.type == TokenType::ObjectEnd)
return true;
}
return addErrorAndRecover("Missing '}' or object member name", tokenName, tokenObjectEnd);
return addErrorAndRecover("Missing '}' or object member name", tokenName, TokenType::ObjectEnd);
}
bool
Reader::readArray(Token& tokenStart, unsigned depth)
{
currentValue() = Value(arrayValue);
currentValue() = Value(ValueType::Array);
skipSpaces();
if (*current_ == ']') // empty array
@@ -495,27 +495,27 @@ Reader::readArray(Token& tokenStart, unsigned depth)
nodes_.pop();
if (!ok) // error already set
return recoverFromError(tokenArrayEnd);
return recoverFromError(TokenType::ArrayEnd);
Token token{};
// Accept Comment after last item in the array.
ok = readToken(token);
while (token.type_ == tokenComment && ok)
while (token.type == TokenType::Comment && ok)
{
ok = readToken(token);
}
bool const badTokenType =
(token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
(token.type != TokenType::ArraySeparator && token.type != TokenType::ArrayEnd);
if (!ok || badTokenType)
{
return addErrorAndRecover(
"Missing ',' or ']' in array declaration", token, tokenArrayEnd);
"Missing ',' or ']' in array declaration", token, TokenType::ArrayEnd);
}
if (token.type_ == tokenArrayEnd)
if (token.type == TokenType::ArrayEnd)
break;
}
@@ -525,16 +525,16 @@ Reader::readArray(Token& tokenStart, unsigned depth)
bool
Reader::decodeNumber(Token& token)
{
Location current = token.start_;
Location current = token.start;
bool const isNegative = *current == '-';
if (isNegative)
++current;
if (current == token.end_)
if (current == token.end)
{
return addError(
"'" + std::string(token.start_, token.end_) + "' is not a valid number.", token);
"'" + std::string(token.start, token.end) + "' is not a valid number.", token);
}
// The existing Json integers are 32-bit so using a 64-bit value here avoids
@@ -542,37 +542,37 @@ Reader::decodeNumber(Token& token)
std::int64_t value = 0;
static_assert(
sizeof(value) > sizeof(Value::maxUInt),
sizeof(value) > sizeof(Value::kMaxUInt),
"The JSON integer overflow logic will need to be reworked.");
while (current < token.end_ && (value <= Value::maxUInt))
while (current < token.end && (value <= Value::kMaxUInt))
{
Char const c = *current++;
if (c < '0' || c > '9')
{
return addError(
"'" + std::string(token.start_, token.end_) + "' is not a number.", token);
"'" + std::string(token.start, token.end) + "' is not a number.", token);
}
value = (value * 10) + (c - '0');
}
// More tokens left -> input is larger than largest possible return value
if (current != token.end_)
if (current != token.end)
{
return addError(
"'" + std::string(token.start_, token.end_) + "' exceeds the allowable range.", token);
"'" + std::string(token.start, token.end) + "' exceeds the allowable range.", token);
}
if (isNegative)
{
value = -value;
if (value < Value::minInt || value > Value::maxInt)
if (value < Value::kMinInt || value > Value::kMaxInt)
{
return addError(
"'" + std::string(token.start_, token.end_) + "' exceeds the allowable range.",
"'" + std::string(token.start, token.end) + "' exceeds the allowable range.",
token);
}
@@ -580,15 +580,15 @@ Reader::decodeNumber(Token& token)
}
else
{
if (value > Value::maxUInt)
if (value > Value::kMaxUInt)
{
return addError(
"'" + std::string(token.start_, token.end_) + "' exceeds the allowable range.",
"'" + std::string(token.start, token.end) + "' exceeds the allowable range.",
token);
}
// If it's representable as a signed integer, construct it as one.
if (value <= Value::maxInt)
if (value <= Value::kMaxInt)
{
currentValue() = static_cast<Value::Int>(value);
}
@@ -607,7 +607,7 @@ Reader::decodeDouble(Token& token)
double value = 0;
int const bufferSize = 32;
int count = 0;
int const length = int(token.end_ - token.start_);
int const length = int(token.end - token.start);
// Sanity check to avoid buffer overflow exploits.
if (length < 0)
{
@@ -622,17 +622,17 @@ Reader::decodeDouble(Token& token)
if (length <= bufferSize)
{
Char buffer[bufferSize + 1];
memcpy(buffer, token.start_, length);
memcpy(buffer, token.start, length);
buffer[length] = 0;
count = sscanf(buffer, format, &value);
}
else
{
std::string const buffer(token.start_, token.end_);
std::string const buffer(token.start, token.end);
count = sscanf(buffer.c_str(), format, &value);
}
if (count != 1)
return addError("'" + std::string(token.start_, token.end_) + "' is not a number.", token);
return addError("'" + std::string(token.start, token.end) + "' is not a number.", token);
currentValue() = value;
return true;
}
@@ -652,9 +652,9 @@ Reader::decodeString(Token& token)
bool
Reader::decodeString(Token& token, std::string& decoded)
{
decoded.reserve(token.end_ - token.start_ - 2);
Location current = token.start_ + 1; // skip '"'
Location end = token.end_ - 1; // do not include '"'
decoded.reserve(token.end - token.start - 2);
Location current = token.start + 1; // skip '"'
Location end = token.end - 1; // do not include '"'
while (current != end)
{
@@ -816,9 +816,9 @@ bool
Reader::addError(std::string const& message, Token& token, Location extra)
{
ErrorInfo info;
info.token_ = token;
info.message_ = message;
info.extra_ = extra;
info.token = token;
info.message = message;
info.extra = extra;
errors_.push_back(info);
return false;
}
@@ -834,7 +834,7 @@ Reader::recoverFromError(TokenType skipUntilToken)
if (!readToken(skip))
errors_.resize(errorCount); // discard errors caused by recovery
if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
if (skip.type == skipUntilToken || skip.type == TokenType::EndOfStream)
break;
}
@@ -911,11 +911,11 @@ Reader::getFormattedErrorMessages() const
for (Errors::const_iterator itError = errors_.begin(); itError != errors_.end(); ++itError)
{
ErrorInfo const& error = *itError;
formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
formattedMessage += " " + error.message_ + "\n";
formattedMessage += "* " + getLocationLineAndColumn(error.token.start) + "\n";
formattedMessage += " " + error.message + "\n";
if (error.extra_ != nullptr)
formattedMessage += "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
if (error.extra != nullptr)
formattedMessage += "See " + getLocationLineAndColumn(error.extra) + " for detail.\n";
}
return formattedMessage;
@@ -924,14 +924,14 @@ Reader::getFormattedErrorMessages() const
std::istream&
operator>>(std::istream& sin, Value& root)
{
Json::Reader reader;
json::Reader reader;
bool const ok = reader.parse(sin, root);
// XRPL_ASSERT(ok, "Json::operator>>() : parse succeeded");
// XRPL_ASSERT(ok, "json::operator>>() : parse succeeded");
if (!ok)
xrpl::Throw<std::runtime_error>(reader.getFormattedErrorMessages());
return sin;
}
} // namespace Json
} // namespace json

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
#include <xrpl/json/json_forwards.h>
#include <xrpl/json/json_value.h>
namespace Json {
namespace json {
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
@@ -89,12 +89,12 @@ ValueIteratorBase::key() const
{
Value::CZString const czString = (*current_).first;
if (czString.c_str() != nullptr)
if (czString.cStr() != nullptr)
{
if (czString.isStaticString())
return Value(StaticString(czString.c_str()));
return Value(StaticString(czString.cStr()));
return Value(czString.c_str());
return Value(czString.cStr());
}
return Value(czString.index());
@@ -105,7 +105,7 @@ ValueIteratorBase::index() const
{
Value::CZString const czString = (*current_).first;
if (czString.c_str() == nullptr)
if (czString.cStr() == nullptr)
return czString.index();
return Value::UInt(-1);
@@ -114,7 +114,7 @@ ValueIteratorBase::index() const
char const*
ValueIteratorBase::memberName() const
{
char const* name = (*current_).first.c_str();
char const* name = (*current_).first.cStr();
return (name != nullptr) ? name : "";
}
@@ -164,4 +164,4 @@ ValueIterator::operator=(SelfType const& other)
return *this;
}
} // namespace Json
} // namespace json

View File

@@ -13,7 +13,7 @@
#include <string>
#include <utility>
namespace Json {
namespace json {
static bool
isControlCharacter(char ch)
@@ -59,7 +59,7 @@ valueToString(Int value)
if (isNegative)
*--current = '-';
XRPL_ASSERT(current >= buffer, "Json::valueToString(Int) : buffer check");
XRPL_ASSERT(current >= buffer, "json::valueToString(Int) : buffer check");
return current;
}
@@ -69,7 +69,7 @@ valueToString(UInt value)
char buffer[32];
char* current = buffer + sizeof(buffer); // NOLINT(misc-const-correctness)
uintToString(value, current);
XRPL_ASSERT(current >= buffer, "Json::valueToString(UInt) : buffer check");
XRPL_ASSERT(current >= buffer, "json::valueToString(UInt) : buffer check");
return current;
}
@@ -188,31 +188,31 @@ FastWriter::writeValue(Value const& value)
{
switch (value.type())
{
case nullValue:
case ValueType::Null:
document_ += "null";
break;
case intValue:
case ValueType::Int:
document_ += valueToString(value.asInt());
break;
case uintValue:
case ValueType::UInt:
document_ += valueToString(value.asUInt());
break;
case realValue:
case ValueType::Real:
document_ += valueToString(value.asDouble());
break;
case stringValue:
case ValueType::String:
document_ += valueToQuotedString(value.asCString());
break;
case booleanValue:
case ValueType::Boolean:
document_ += valueToString(value.asBool());
break;
case arrayValue: {
case ValueType::Array: {
document_ += "[";
int const size = value.size();
@@ -228,7 +228,7 @@ FastWriter::writeValue(Value const& value)
}
break;
case objectValue: {
case ValueType::Object: {
Value::Members members(value.getMemberNames());
document_ += "{";
@@ -271,35 +271,35 @@ StyledWriter::writeValue(Value const& value)
{
switch (value.type())
{
case nullValue:
case ValueType::Null:
pushValue("null");
break;
case intValue:
case ValueType::Int:
pushValue(valueToString(value.asInt()));
break;
case uintValue:
case ValueType::UInt:
pushValue(valueToString(value.asUInt()));
break;
case realValue:
case ValueType::Real:
pushValue(valueToString(value.asDouble()));
break;
case stringValue:
case ValueType::String:
pushValue(valueToQuotedString(value.asCString()));
break;
case booleanValue:
case ValueType::Boolean:
pushValue(valueToString(value.asBool()));
break;
case arrayValue:
case ValueType::Array:
writeArrayValue(value);
break;
case objectValue: {
case ValueType::Object: {
Value::Members members(value.getMemberNames());
if (members.empty())
@@ -381,7 +381,7 @@ StyledWriter::writeArrayValue(Value const& value)
{
XRPL_ASSERT(
childValues_.size() == size,
"Json::StyledWriter::writeArrayValue : child size match");
"json::StyledWriter::writeArrayValue : child size match");
document_ += "[ ";
for (unsigned index = 0; index < size; ++index)
@@ -478,7 +478,7 @@ StyledWriter::unindent()
{
XRPL_ASSERT(
int(indentString_.size()) >= indentSize_,
"Json::StyledWriter::unindent : maximum indent size");
"json::StyledWriter::unindent : maximum indent size");
indentString_.resize(indentString_.size() - indentSize_);
}
@@ -506,35 +506,35 @@ StyledStreamWriter::writeValue(Value const& value)
{
switch (value.type())
{
case nullValue:
case ValueType::Null:
pushValue("null");
break;
case intValue:
case ValueType::Int:
pushValue(valueToString(value.asInt()));
break;
case uintValue:
case ValueType::UInt:
pushValue(valueToString(value.asUInt()));
break;
case realValue:
case ValueType::Real:
pushValue(valueToString(value.asDouble()));
break;
case stringValue:
case ValueType::String:
pushValue(valueToQuotedString(value.asCString()));
break;
case booleanValue:
case ValueType::Boolean:
pushValue(valueToString(value.asBool()));
break;
case arrayValue:
case ValueType::Array:
writeArrayValue(value);
break;
case objectValue: {
case ValueType::Object: {
Value::Members members(value.getMemberNames());
if (members.empty())
@@ -616,7 +616,7 @@ StyledStreamWriter::writeArrayValue(Value const& value)
{
XRPL_ASSERT(
childValues_.size() == size,
"Json::StyledStreamWriter::writeArrayValue : child size match");
"json::StyledStreamWriter::writeArrayValue : child size match");
*document_ << "[ ";
for (unsigned index = 0; index < size; ++index)
@@ -714,16 +714,16 @@ StyledStreamWriter::unindent()
{
XRPL_ASSERT(
indentString_.size() >= indentation_.size(),
"Json::StyledStreamWriter::unindent : maximum indent size");
"json::StyledStreamWriter::unindent : maximum indent size");
indentString_.resize(indentString_.size() - indentation_.size());
}
std::ostream&
operator<<(std::ostream& sout, Value const& root)
{
Json::StyledStreamWriter writer;
json::StyledStreamWriter writer;
writer.write(sout, root);
return sout;
}
} // namespace Json
} // namespace json

View File

@@ -4,7 +4,7 @@
#include <string>
namespace Json {
namespace json {
std::string
to_string(Value const& value)
@@ -18,4 +18,4 @@ pretty(Value const& value)
return StyledWriter().write(value);
}
} // namespace Json
} // namespace json

View File

@@ -25,35 +25,35 @@ AcceptedLedgerTx::AcceptedLedgerTx(
std::shared_ptr<ReadView const> const& ledger,
std::shared_ptr<STTx const> const& txn,
std::shared_ptr<STObject const> const& met)
: mTxn(txn)
, mMeta(txn->getTransactionID(), ledger->seq(), *met)
, mAffected(mMeta.getAffectedAccounts())
: txn_(txn)
, meta_(txn->getTransactionID(), ledger->seq(), *met)
, affected_(meta_.getAffectedAccounts())
{
XRPL_ASSERT(!ledger->open(), "xrpl::AcceptedLedgerTx::AcceptedLedgerTx : valid ledger state");
Serializer s;
met->add(s);
mRawMeta = std::move(s.modData());
rawMeta_ = std::move(s.modData());
mJson = Json::objectValue;
mJson[jss::transaction] = mTxn->getJson(JsonOptions::none);
json_ = json::ValueType::Object;
json_[jss::transaction] = txn_->getJson(JsonOptions::Values::None);
mJson[jss::meta] = mMeta.getJson(JsonOptions::none);
mJson[jss::raw_meta] = strHex(mRawMeta);
json_[jss::meta] = meta_.getJson(JsonOptions::Values::None);
json_[jss::raw_meta] = strHex(rawMeta_);
mJson[jss::result] = transHuman(mMeta.getResultTER());
json_[jss::result] = transHuman(meta_.getResultTER());
if (!mAffected.empty())
if (!affected_.empty())
{
Json::Value& affected = (mJson[jss::affected] = Json::arrayValue);
for (auto const& account : mAffected)
json::Value& affected = (json_[jss::affected] = json::ValueType::Array);
for (auto const& account : affected_)
affected.append(toBase58(account));
}
if (mTxn->getTxnType() == ttOFFER_CREATE)
if (txn_->getTxnType() == ttOFFER_CREATE)
{
auto const& account = mTxn->getAccountID(sfAccount);
auto const amount = mTxn->getFieldAmount(sfTakerGets);
auto const& account = txn_->getAccountID(sfAccount);
auto const amount = txn_->getFieldAmount(sfTakerGets);
// If the offer create is not self funded then add the owner balance
if (account != amount.getIssuer())
@@ -62,10 +62,10 @@ AcceptedLedgerTx::AcceptedLedgerTx(
*ledger,
account,
amount,
fhIGNORE_FREEZE,
ahIGNORE_AUTH,
FreezeHandling::IgnoreFreeze,
AuthHandling::IgnoreAuth,
beast::Journal{beast::Journal::getNullSink()});
mJson[jss::transaction][jss::owner_funds] = ownerFunds.getText();
json_[jss::transaction][jss::owner_funds] = ownerFunds.getText();
}
}
}
@@ -73,8 +73,8 @@ AcceptedLedgerTx::AcceptedLedgerTx(
std::string
AcceptedLedgerTx::getEscMeta() const
{
XRPL_ASSERT(!mRawMeta.empty(), "xrpl::AcceptedLedgerTx::getEscMeta : metadata is set");
return sqlBlobLiteral(mRawMeta);
XRPL_ASSERT(!rawMeta_.empty(), "xrpl::AcceptedLedgerTx::getEscMeta : metadata is set");
return sqlBlobLiteral(rawMeta_);
}
} // namespace xrpl

View File

@@ -43,15 +43,15 @@ ApplyStateTable::apply(RawView& to) const
auto const& sle = item.second.second;
switch (item.second.first)
{
case Action::cache:
case Action::Cache:
break;
case Action::erase:
case Action::Erase:
to.rawErase(sle);
break;
case Action::insert:
case Action::Insert:
to.rawInsert(sle);
break;
case Action::modify:
case Action::Modify:
to.rawReplace(sle);
break;
};
@@ -66,9 +66,9 @@ ApplyStateTable::size() const
{
switch (item.second.first)
{
case Action::erase:
case Action::insert:
case Action::modify:
case Action::Erase:
case Action::Insert:
case Action::Modify:
++ret;
default:
break;
@@ -90,15 +90,15 @@ ApplyStateTable::visit(
{
switch (item.second.first)
{
case Action::erase:
case Action::Erase:
func(item.first, true, to.read(keylet::unchecked(item.first)), item.second.second);
break;
case Action::insert:
case Action::Insert:
func(item.first, false, nullptr, item.second.second);
break;
case Action::modify:
case Action::Modify:
func(item.first, false, to.read(keylet::unchecked(item.first)), item.second.second);
break;
@@ -137,15 +137,15 @@ ApplyStateTable::apply(
switch (item.second.first)
{
default:
case Action::cache:
case Action::Cache:
continue;
case Action::erase:
case Action::Erase:
type = &sfDeletedNode;
break;
case Action::insert:
case Action::Insert:
type = &sfCreatedNode;
break;
case Action::modify:
case Action::Modify:
type = &sfModifiedNode;
break;
}
@@ -169,24 +169,24 @@ ApplyStateTable::apply(
{
// go through the original node for
// modified fields saved on modification
if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) &&
if (obj.getFName().shouldMeta(SField::kSmdChangeOrig) &&
!curNode->hasMatchingEntry(obj))
prevs.emplace_back(obj);
prevs.emplaceBack(obj);
}
if (!prevs.empty())
meta.getAffectedNode(item.first).emplace_back(std::move(prevs));
meta.getAffectedNode(item.first).emplaceBack(std::move(prevs));
STObject finals(sfFinalFields);
for (auto const& obj : *curNode)
{
// go through the final node for final fields
if (obj.getFName().shouldMeta(SField::sMD_Always | SField::sMD_DeleteFinal))
finals.emplace_back(obj);
if (obj.getFName().shouldMeta(SField::kSmdAlways | SField::kSmdDeleteFinal))
finals.emplaceBack(obj);
}
if (!finals.empty())
meta.getAffectedNode(item.first).emplace_back(std::move(finals));
meta.getAffectedNode(item.first).emplaceBack(std::move(finals));
}
else if (type == &sfModifiedNode)
{
@@ -205,24 +205,24 @@ ApplyStateTable::apply(
for (auto const& obj : *origNode)
{
// search the original node for values saved on modify
if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) &&
if (obj.getFName().shouldMeta(SField::kSmdChangeOrig) &&
!curNode->hasMatchingEntry(obj))
prevs.emplace_back(obj);
prevs.emplaceBack(obj);
}
if (!prevs.empty())
meta.getAffectedNode(item.first).emplace_back(std::move(prevs));
meta.getAffectedNode(item.first).emplaceBack(std::move(prevs));
STObject finals(sfFinalFields);
for (auto const& obj : *curNode)
{
// search the final node for values saved always
if (obj.getFName().shouldMeta(SField::sMD_Always | SField::sMD_ChangeNew))
finals.emplace_back(obj);
if (obj.getFName().shouldMeta(SField::kSmdAlways | SField::kSmdChangeNew))
finals.emplaceBack(obj);
}
if (!finals.empty())
meta.getAffectedNode(item.first).emplace_back(std::move(finals));
meta.getAffectedNode(item.first).emplaceBack(std::move(finals));
}
else if (type == &sfCreatedNode) // if created, thread to owner(s)
{
@@ -240,12 +240,12 @@ ApplyStateTable::apply(
{
// save non-default values
if (!obj.isDefault() &&
obj.getFName().shouldMeta(SField::sMD_Create | SField::sMD_Always))
news.emplace_back(obj);
obj.getFName().shouldMeta(SField::kSmdCreate | SField::kSmdAlways))
news.emplaceBack(obj);
}
if (!news.empty())
meta.getAffectedNode(item.first).emplace_back(std::move(news));
meta.getAffectedNode(item.first).emplaceBack(std::move(news));
}
else
{
@@ -269,7 +269,7 @@ ApplyStateTable::apply(
// VFALCO For diagnostics do we want to show
// metadata even when the base view is open?
JLOG(j.trace()) << "metadata " << meta.getJson(JsonOptions::none);
JLOG(j.trace()) << "metadata " << meta.getJson(JsonOptions::Values::None);
metadata = meta;
}
@@ -294,11 +294,11 @@ ApplyStateTable::exists(ReadView const& base, Keylet const& k) const
auto const& sle = item.second;
switch (item.first)
{
case Action::erase:
case Action::Erase:
return false;
case Action::cache:
case Action::insert:
case Action::modify:
case Action::Cache:
case Action::Insert:
case Action::Modify:
break;
}
return k.check(*sle);
@@ -320,11 +320,11 @@ ApplyStateTable::succ(
if (!next)
break;
iter = items_.find(*next);
} while (iter != items_.end() && iter->second.first == Action::erase);
} while (iter != items_.end() && iter->second.first == Action::Erase);
// Find non-deleted successor in our list
for (iter = items_.upper_bound(key); iter != items_.end(); ++iter)
{
if (iter->second.first != Action::erase)
if (iter->second.first != Action::Erase)
{
// Found both, return the lower key
if (!next || next > iter->first)
@@ -349,11 +349,11 @@ ApplyStateTable::read(ReadView const& base, Keylet const& k) const
auto const& sle = item.second;
switch (item.first)
{
case Action::erase:
case Action::Erase:
return nullptr;
case Action::cache:
case Action::insert:
case Action::modify:
case Action::Cache:
case Action::Insert:
case Action::Modify:
break;
};
if (!k.check(*sle))
@@ -376,18 +376,18 @@ ApplyStateTable::peek(ReadView const& base, Keylet const& k)
iter,
piecewise_construct,
forward_as_tuple(sle->key()),
forward_as_tuple(Action::cache, make_shared<SLE>(*sle)));
forward_as_tuple(Action::Cache, make_shared<SLE>(*sle)));
return iter->second.second;
}
auto const& item = iter->second;
auto const& sle = item.second;
switch (item.first)
{
case Action::erase:
case Action::Erase:
return nullptr;
case Action::cache:
case Action::insert:
case Action::modify:
case Action::Cache:
case Action::Insert:
case Action::Modify:
break;
};
if (!k.check(*sle))
@@ -406,15 +406,15 @@ ApplyStateTable::erase(ReadView const& base, std::shared_ptr<SLE> const& sle)
Throw<std::logic_error>("ApplyStateTable::erase: unknown SLE");
switch (item.first)
{
case Action::erase:
case Action::Erase:
Throw<std::logic_error>("ApplyStateTable::erase: double erase");
break;
case Action::insert:
case Action::Insert:
items_.erase(iter);
break;
case Action::cache:
case Action::modify:
item.first = Action::erase;
case Action::Cache:
case Action::Modify:
item.first = Action::Erase;
break;
}
}
@@ -424,21 +424,21 @@ ApplyStateTable::rawErase(ReadView const& base, std::shared_ptr<SLE> const& sle)
{
using namespace std;
auto const result = items_.emplace(
piecewise_construct, forward_as_tuple(sle->key()), forward_as_tuple(Action::erase, sle));
piecewise_construct, forward_as_tuple(sle->key()), forward_as_tuple(Action::Erase, sle));
if (result.second)
return;
auto& item = result.first->second;
switch (item.first)
{
case Action::erase:
case Action::Erase:
Throw<std::logic_error>("ApplyStateTable::rawErase: double erase");
break;
case Action::insert:
case Action::Insert:
items_.erase(result.first);
break;
case Action::cache:
case Action::modify:
item.first = Action::erase;
case Action::Cache:
case Action::Modify:
item.first = Action::Erase;
item.second = sle;
break;
}
@@ -455,22 +455,22 @@ ApplyStateTable::insert(ReadView const& base, std::shared_ptr<SLE> const& sle)
iter,
piecewise_construct,
forward_as_tuple(sle->key()),
forward_as_tuple(Action::insert, sle));
forward_as_tuple(Action::Insert, sle));
return;
}
auto& item = iter->second;
switch (item.first)
{
case Action::cache:
case Action::Cache:
Throw<std::logic_error>("ApplyStateTable::insert: already cached");
case Action::insert:
case Action::Insert:
Throw<std::logic_error>("ApplyStateTable::insert: already inserted");
case Action::modify:
case Action::Modify:
Throw<std::logic_error>("ApplyStateTable::insert: already modified");
case Action::erase:
case Action::Erase:
break;
}
item.first = Action::modify;
item.first = Action::Modify;
item.second = sle;
}
@@ -485,19 +485,19 @@ ApplyStateTable::replace(ReadView const& base, std::shared_ptr<SLE> const& sle)
iter,
piecewise_construct,
forward_as_tuple(sle->key()),
forward_as_tuple(Action::modify, sle));
forward_as_tuple(Action::Modify, sle));
return;
}
auto& item = iter->second;
switch (item.first)
{
case Action::erase:
case Action::Erase:
Throw<std::logic_error>("ApplyStateTable::replace: already erased");
case Action::cache:
item.first = Action::modify;
case Action::Cache:
item.first = Action::Modify;
break;
case Action::insert:
case Action::modify:
case Action::Insert:
case Action::Modify:
break;
}
item.second = sle;
@@ -514,14 +514,14 @@ ApplyStateTable::update(ReadView const& base, std::shared_ptr<SLE> const& sle)
Throw<std::logic_error>("ApplyStateTable::update: unknown SLE");
switch (item.first)
{
case Action::erase:
case Action::Erase:
Throw<std::logic_error>("ApplyStateTable::update: erased");
break;
case Action::cache:
item.first = Action::modify;
case Action::Cache:
item.first = Action::Modify;
break;
case Action::insert:
case Action::modify:
case Action::Insert:
case Action::Modify:
break;
};
}
@@ -584,7 +584,7 @@ ApplyStateTable::getForMod(ReadView const& base, key_type const& key, Mods& mods
if (iter != items_.end())
{
auto const& item = iter->second;
if (item.first == Action::erase)
if (item.first == Action::Erase)
{
// The Destination of an Escrow or a PayChannel may have been
// deleted. In that case the account we're threading to will
@@ -592,7 +592,7 @@ ApplyStateTable::getForMod(ReadView const& base, key_type const& key, Mods& mods
JLOG(j.warn()) << "Trying to thread to deleted node";
return nullptr;
}
if (item.first != Action::cache)
if (item.first != Action::Cache)
return item.second;
// If it's only cached, then the node is being modified only by

View File

@@ -38,7 +38,7 @@ createRoot(
describe(newRoot);
STVector256 v;
v.push_back(key);
v.pushBack(key);
newRoot->setFieldV256(sfIndexes, v);
view.insert(newRoot);
@@ -80,7 +80,7 @@ insertKey(
if (std::ranges::find(indexes, key) != indexes.end())
Throw<std::logic_error>("dirInsert: double insertion"); // LCOV_EXCL_LINE
indexes.push_back(key);
indexes.pushBack(key);
}
else
{
@@ -125,7 +125,7 @@ insertPage(
// Check whether we're out of pages.
if (page == 0)
return std::nullopt;
if (!view.rules().enabled(fixDirectoryLimit) && page >= dirNodeMaxPages) // Old pages limit
if (!view.rules().enabled(fixDirectoryLimit) && page >= kDirNodeMaxPages) // Old pages limit
return std::nullopt;
// We are about to create a new node; we'll link it to
@@ -138,7 +138,7 @@ insertPage(
// Insert the new key:
STVector256 indexes;
indexes.push_back(key);
indexes.pushBack(key);
node = std::make_shared<SLE>(keylet::page(directory, page));
node->setFieldH256(sfRootIndex, directory.key);
@@ -179,7 +179,7 @@ ApplyView::dirAdd(
auto [page, node, indexes] = directory::findPreviousPage(*this, directory, root);
// If there's space, we use it:
if (indexes.size() < dirNodeMaxEntries)
if (indexes.size() < kDirNodeMaxEntries)
{
return directory::insertKey(*this, node, page, preserveOrder, indexes, key);
}
@@ -208,19 +208,19 @@ ApplyView::emptyDirDelete(Keylet const& directory)
if (!node->getFieldV256(sfIndexes).empty())
return false;
std::uint64_t constexpr rootPage = 0;
static constexpr std::uint64_t kRootPage = 0;
auto prevPage = node->getFieldU64(sfIndexPrevious);
auto nextPage = node->getFieldU64(sfIndexNext);
if (nextPage == rootPage && prevPage != rootPage)
if (nextPage == kRootPage && prevPage != kRootPage)
Throw<std::logic_error>("Directory chain: fwd link broken"); // LCOV_EXCL_LINE
if (prevPage == rootPage && nextPage != rootPage)
if (prevPage == kRootPage && nextPage != kRootPage)
Throw<std::logic_error>("Directory chain: rev link broken"); // LCOV_EXCL_LINE
// Older versions of the code would, in some cases, allow the last page to
// be empty. Remove such pages:
if (nextPage == prevPage && nextPage != rootPage)
// Older versions of the code would, in some cases, allow the last
// page to be empty. Remove such pages:
if (nextPage == prevPage && nextPage != kRootPage)
{
auto last = peek(keylet::page(directory, nextPage));
@@ -230,21 +230,23 @@ ApplyView::emptyDirDelete(Keylet const& directory)
if (!last->getFieldV256(sfIndexes).empty())
return false;
// Update the first page's linked list and mark it as updated.
node->setFieldU64(sfIndexNext, rootPage);
node->setFieldU64(sfIndexPrevious, rootPage);
// Update the first page's linked list and
// mark it as updated.
node->setFieldU64(sfIndexNext, kRootPage);
node->setFieldU64(sfIndexPrevious, kRootPage);
update(node);
// And erase the empty last page:
erase(last);
// Make sure our local values reflect the updated information:
nextPage = rootPage;
prevPage = rootPage;
// Make sure our local values reflect the
// updated information:
nextPage = kRootPage;
prevPage = kRootPage;
}
// If there are no other pages, erase the root:
if (nextPage == rootPage && prevPage == rootPage)
if (nextPage == kRootPage && prevPage == kRootPage)
erase(node);
return true;
@@ -258,7 +260,7 @@ ApplyView::dirRemove(Keylet const& directory, std::uint64_t page, uint256 const&
if (!node)
return false;
std::uint64_t constexpr rootPage = 0;
static constexpr std::uint64_t kRootPage = 0;
{
auto entries = node->getFieldV256(sfIndexes);
@@ -283,10 +285,11 @@ ApplyView::dirRemove(Keylet const& directory, std::uint64_t page, uint256 const&
auto prevPage = node->getFieldU64(sfIndexPrevious);
auto nextPage = node->getFieldU64(sfIndexNext);
// The first page is the directory's root node and is treated specially: it
// can never be deleted even if it is empty, unless we plan on removing the
// entire directory.
if (page == rootPage)
// The first page is the directory's root node and is
// treated specially: it can never be deleted even if
// it is empty, unless we plan on removing the entire
// directory.
if (page == kRootPage)
{
if (nextPage == page && prevPage != page)
Throw<std::logic_error>("Directory chain: fwd link broken"); // LCOV_EXCL_LINE
@@ -355,32 +358,32 @@ ApplyView::dirRemove(Keylet const& directory, std::uint64_t page, uint256 const&
// The page is no longer linked. Delete it.
erase(node);
// Check whether the next page is the last page and, if so, whether it's
// empty. If it is, delete it.
if (nextPage != rootPage && next->getFieldU64(sfIndexNext) == rootPage &&
// Check whether the next page is the last page and, if
// so, whether it's empty. If it is, delete it.
if (nextPage != kRootPage && next->getFieldU64(sfIndexNext) == kRootPage &&
next->getFieldV256(sfIndexes).empty())
{
// Since next doesn't point to the root, it can't be pointing to prev.
erase(next);
// The previous page is now the last page:
prev->setFieldU64(sfIndexNext, rootPage);
prev->setFieldU64(sfIndexNext, kRootPage);
update(prev);
// And the root points to the last page:
auto root = peek(keylet::page(directory, rootPage));
auto root = peek(keylet::page(directory, kRootPage));
if (!root)
Throw<std::logic_error>("Directory chain: root link broken."); // LCOV_EXCL_LINE
root->setFieldU64(sfIndexPrevious, prevPage);
update(root);
nextPage = rootPage;
nextPage = kRootPage;
}
// If we're not keeping the root, then check to see if it's left empty.
// If so, delete it as well.
if (!keepRoot && nextPage == rootPage && prevPage == rootPage)
// If we're not keeping the root, then check to see if
// it's left empty. If so, delete it as well.
if (!keepRoot && nextPage == kRootPage && prevPage == kRootPage)
{
if (prev->getFieldV256(sfIndexes).empty())
erase(prev);

View File

@@ -65,31 +65,31 @@ ApplyViewBase::read(Keylet const& k) const
}
auto
ApplyViewBase::slesBegin() const -> std::unique_ptr<sles_type::iter_base>
ApplyViewBase::slesBegin() const -> std::unique_ptr<SlesType::iter_base>
{
return base_->slesBegin();
}
auto
ApplyViewBase::slesEnd() const -> std::unique_ptr<sles_type::iter_base>
ApplyViewBase::slesEnd() const -> std::unique_ptr<SlesType::iter_base>
{
return base_->slesEnd();
}
auto
ApplyViewBase::slesUpperBound(uint256 const& key) const -> std::unique_ptr<sles_type::iter_base>
ApplyViewBase::slesUpperBound(uint256 const& key) const -> std::unique_ptr<SlesType::iter_base>
{
return base_->slesUpperBound(key);
}
auto
ApplyViewBase::txsBegin() const -> std::unique_ptr<txs_type::iter_base>
ApplyViewBase::txsBegin() const -> std::unique_ptr<TxsType::iter_base>
{
return base_->txsBegin();
}
auto
ApplyViewBase::txsEnd() const -> std::unique_ptr<txs_type::iter_base>
ApplyViewBase::txsEnd() const -> std::unique_ptr<TxsType::iter_base>
{
return base_->txsEnd();
}

View File

@@ -1,6 +1,5 @@
#include <xrpl/ledger/BookDirs.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/ReadView.h>
@@ -15,11 +14,11 @@ namespace xrpl {
BookDirs::BookDirs(ReadView const& view, Book const& book)
: view_(&view)
, root_(keylet::page(getBookBase(book)).key)
, next_quality_(getQualityNext(root_))
, key_(view_->succ(root_, next_quality_).value_or(beast::zero))
, nextQuality_(getQualityNext(root_))
, key_(view_->succ(root_, nextQuality_).value_or(beast::kZero))
{
XRPL_ASSERT(root_ != beast::zero, "xrpl::BookDirs::BookDirs : nonzero root");
if (key_ != beast::zero)
XRPL_ASSERT(root_ != beast::kZero, "xrpl::BookDirs::BookDirs : nonzero root");
if (key_ != beast::kZero)
{
if (!cdirFirst(*view_, key_, sle_, entry_, index_))
{
@@ -34,9 +33,9 @@ auto
BookDirs::begin() const -> BookDirs::const_iterator
{
auto it = BookDirs::const_iterator(*view_, root_, key_);
if (key_ != beast::zero)
if (key_ != beast::kZero)
{
it.next_quality_ = next_quality_;
it.nextQuality_ = nextQuality_;
it.sle_ = sle_;
it.entry_ = entry_;
it.index_ = index_;
@@ -50,8 +49,6 @@ BookDirs::end() const -> BookDirs::const_iterator
return BookDirs::const_iterator(*view_, root_, key_);
}
beast::Journal BookDirs::const_iterator::j_ = beast::Journal{beast::Journal::getNullSink()};
bool
BookDirs::const_iterator::operator==(BookDirs::const_iterator const& other) const
{
@@ -62,13 +59,14 @@ BookDirs::const_iterator::operator==(BookDirs::const_iterator const& other) cons
view_ == other.view_ && root_ == other.root_,
"xrpl::BookDirs::const_iterator::operator== : views and roots are "
"matching");
return entry_ == other.entry_ && cur_key_ == other.cur_key_ && index_ == other.index_;
return entry_ == other.entry_ && curKey_ == other.curKey_ && index_ == other.index_;
}
BookDirs::const_iterator::reference
BookDirs::const_iterator::operator*() const
{
XRPL_ASSERT(index_ != beast::zero, "xrpl::BookDirs::const_iterator::operator* : nonzero index");
XRPL_ASSERT(
index_ != beast::kZero, "xrpl::BookDirs::const_iterator::operator* : nonzero index");
if (!cache_)
cache_ = view_->read(keylet::offer(index_));
return *cache_;
@@ -77,21 +75,21 @@ BookDirs::const_iterator::operator*() const
BookDirs::const_iterator&
BookDirs::const_iterator::operator++()
{
using beast::zero;
using beast::kZero;
XRPL_ASSERT(index_ != zero, "xrpl::BookDirs::const_iterator::operator++ : nonzero index");
if (!cdirNext(*view_, cur_key_, sle_, entry_, index_))
XRPL_ASSERT(index_ != kZero, "xrpl::BookDirs::const_iterator::operator++ : nonzero index");
if (!cdirNext(*view_, curKey_, sle_, entry_, index_))
{
if (index_ == 0)
cur_key_ = view_->succ(++cur_key_, next_quality_).value_or(zero);
curKey_ = view_->succ(++curKey_, nextQuality_).value_or(kZero);
if (index_ != 0 || cur_key_ == zero)
if (index_ != 0 || curKey_ == kZero)
{
cur_key_ = key_;
curKey_ = key_;
entry_ = 0;
index_ = zero;
index_ = kZero;
}
else if (!cdirFirst(*view_, cur_key_, sle_, entry_, index_))
else if (!cdirFirst(*view_, curKey_, sle_, entry_, index_))
{
// LCOV_EXCL_START
UNREACHABLE("xrpl::BookDirs::const_iterator::operator++ : directory is empty");
@@ -107,7 +105,7 @@ BookDirs::const_iterator
BookDirs::const_iterator::operator++(int)
{
XRPL_ASSERT(
index_ != beast::zero, "xrpl::BookDirs::const_iterator::operator++(int) : nonzero index");
index_ != beast::kZero, "xrpl::BookDirs::const_iterator::operator++(int) : nonzero index");
const_iterator tmp(*this);
++(*this);
return tmp;

View File

@@ -13,24 +13,24 @@ namespace xrpl {
void
BookListeners::addSubscriber(InfoSub::ref sub)
{
std::lock_guard const sl(mLock);
mListeners[sub->getSeq()] = sub;
std::scoped_lock const sl(lock_);
listeners_[sub->getSeq()] = sub;
}
void
BookListeners::removeSubscriber(std::uint64_t seq)
{
std::lock_guard const sl(mLock);
mListeners.erase(seq);
std::scoped_lock const sl(lock_);
listeners_.erase(seq);
}
void
BookListeners::publish(MultiApiJson const& jvObj, hash_set<std::uint64_t>& havePublished)
{
std::lock_guard const sl(mLock);
auto it = mListeners.cbegin();
std::scoped_lock const sl(lock_);
auto it = listeners_.cbegin();
while (it != mListeners.cend())
while (it != listeners_.cend())
{
InfoSub::pointer p = it->second.lock();
@@ -41,13 +41,13 @@ BookListeners::publish(MultiApiJson const& jvObj, hash_set<std::uint64_t>& haveP
{
jvObj.visit(
p->getApiVersion(), //
[&](Json::Value const& jv) { p->send(jv, true); });
[&](json::Value const& jv) { p->send(jv, true); });
}
++it;
}
else
{
it = mListeners.erase(it);
it = listeners_.erase(it);
}
}
}

View File

@@ -22,15 +22,15 @@ CachedViewImpl::exists(Keylet const& k) const
std::shared_ptr<SLE const>
CachedViewImpl::read(Keylet const& k) const
{
static CountedObjects::Counter hits{"CachedView::hit"};
static CountedObjects::Counter hitsexpired{"CachedView::hitExpired"};
static CountedObjects::Counter misses{"CachedView::miss"};
static CountedObjects::Counter kHits{"CachedView::hit"};
static CountedObjects::Counter kHitsExpired{"CachedView::hitExpired"};
static CountedObjects::Counter kMisses{"CachedView::miss"};
bool cacheHit = false;
bool baseRead = false;
auto const digest = [&]() -> std::optional<uint256> {
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
auto const iter = map_.find(k.key);
if (iter != map_.end())
{
@@ -50,15 +50,15 @@ CachedViewImpl::read(Keylet const& k) const
XRPL_ASSERT(sle || baseRead, "xrpl::CachedView::read : null SLE result from base");
if (cacheHit && baseRead)
{
hitsexpired.increment();
kHitsExpired.increment();
}
else if (cacheHit)
{
hits.increment();
kHits.increment();
}
else
{
misses.increment();
kMisses.increment();
}
if (!cacheHit)
@@ -66,7 +66,7 @@ CachedViewImpl::read(Keylet const& k) const
// Avoid acquiring this lock unless necessary. It is only necessary if
// the key was not found in the map_. The lock is needed to add the key
// and digest.
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
map_.emplace(k.key, *digest);
}
if (!sle || !k.check(*sle))

View File

@@ -33,7 +33,7 @@ operator<(CanonicalTXSet::Key const& lhs, CanonicalTXSet::Key const& rhs)
uint256
CanonicalTXSet::accountKey(AccountID const& account)
{
uint256 ret = beast::zero;
uint256 ret = beast::kZero;
memcpy(ret.begin(), account.begin(), account.size());
ret ^= salt_;
return ret;
@@ -68,7 +68,7 @@ CanonicalTXSet::popAcctTransaction(std::shared_ptr<STTx const> const& tx)
uint256 const effectiveAccount{accountKey(tx->getAccountID(sfAccount))};
auto const seqProxy = tx->getSeqProxy();
Key const after(effectiveAccount, seqProxy, beast::zero);
Key const after(effectiveAccount, seqProxy, beast::kZero);
auto const itrNext{map_.lower_bound(after)};
if (itrNext != map_.end() && itrNext->first.getAccount() == effectiveAccount &&
(!itrNext->second->getSeqProxy().isSeq() ||

View File

@@ -13,7 +13,7 @@
namespace xrpl {
using const_iterator = Dir::const_iterator;
using const_iterator = Dir::ConstIterator;
Dir::Dir(ReadView const& view, Keylet const& key)
: view_(&view), root_(key), sle_(view_->read(root_))
@@ -23,9 +23,9 @@ Dir::Dir(ReadView const& view, Keylet const& key)
}
auto
Dir::begin() const -> const_iterator
Dir::begin() const -> ConstIterator
{
auto it = const_iterator(*view_, root_, root_);
auto it = ConstIterator(*view_, root_, root_);
if (sle_ != nullptr)
{
it.sle_ = sle_;
@@ -41,27 +41,27 @@ Dir::begin() const -> const_iterator
}
auto
Dir::end() const -> const_iterator
Dir::end() const -> ConstIterator
{
return const_iterator(*view_, root_, root_);
return ConstIterator(*view_, root_, root_);
}
bool
const_iterator::operator==(const_iterator const& other) const
const_iterator::operator==(ConstIterator const& other) const
{
if (view_ == nullptr || other.view_ == nullptr)
return false;
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::zero, "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::zero, "xrpl::const_iterator::operator++ : nonzero index");
XRPL_ASSERT(index_ != beast::kZero, "xrpl::Dir::ConstIterator::operator++ : nonzero index");
if (++it_ != std::end(*indexes_))
{
index_ = *it_;
@@ -78,36 +78,37 @@ const_iterator::operator++()
return *this;
}
return next_page();
return nextPage();
}
const_iterator
const_iterator::operator++(int)
{
XRPL_ASSERT(index_ != beast::zero, "xrpl::const_iterator::operator++(int) : nonzero index");
const_iterator tmp(*this);
XRPL_ASSERT(
index_ != beast::kZero, "xrpl::Dir::ConstIterator::operator++(int) : nonzero index");
ConstIterator tmp(*this);
++(*this);
return tmp;
}
const_iterator&
const_iterator::next_page()
const_iterator::nextPage()
{
auto const next = sle_->getFieldU64(sfIndexNext);
if (next == 0)
{
page_.key = root_.key;
index_ = beast::zero;
index_ = beast::kZero;
}
else
{
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())
{
index_ = beast::zero;
index_ = beast::kZero;
}
else
{
@@ -120,7 +121,7 @@ const_iterator::next_page()
}
std::size_t
const_iterator::page_size()
const_iterator::pageSize()
{
return indexes_->size();
}

View File

@@ -14,7 +14,6 @@
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Fees.h>
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/KeyType.h>
#include <xrpl/protocol/Keylet.h>
@@ -31,7 +30,6 @@
#include <xrpl/protocol/Seed.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/SystemParameters.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/shamap/Family.h>
#include <xrpl/shamap/SHAMap.h>
#include <xrpl/shamap/SHAMapItem.h>
@@ -43,42 +41,41 @@
#include <exception>
#include <memory>
#include <optional>
#include <stdexcept>
#include <utility>
#include <vector>
namespace xrpl {
create_genesis_t const create_genesis{};
CreateGenesisT const kCreateGenesis{};
//------------------------------------------------------------------------------
class Ledger::sles_iter_impl : public sles_type::iter_base
class Ledger::SlesIterImpl : public SlesType::iter_base
{
private:
SHAMap::const_iterator iter_;
SHAMap::ConstIterator iter_;
public:
sles_iter_impl() = delete;
sles_iter_impl&
operator=(sles_iter_impl const&) = delete;
SlesIterImpl() = delete;
SlesIterImpl&
operator=(SlesIterImpl const&) = delete;
sles_iter_impl(sles_iter_impl const&) = default;
SlesIterImpl(SlesIterImpl const&) = default;
sles_iter_impl(SHAMap::const_iterator iter) : iter_(iter)
SlesIterImpl(SHAMap::ConstIterator iter) : iter_(iter)
{
}
[[nodiscard]] std::unique_ptr<base_type>
copy() const override
{
return std::make_unique<sles_iter_impl>(*this);
return std::make_unique<SlesIterImpl>(*this);
}
[[nodiscard]] bool
equal(base_type const& impl) const override
{
if (auto const p = dynamic_cast<sles_iter_impl const*>(&impl))
if (auto const p = dynamic_cast<SlesIterImpl const*>(&impl))
return iter_ == p->iter_;
return false;
}
@@ -89,7 +86,7 @@ public:
++iter_;
}
[[nodiscard]] sles_type::value_type
[[nodiscard]] SlesType::value_type
dereference() const override
{
SerialIter sit(iter_->slice());
@@ -99,33 +96,33 @@ public:
//------------------------------------------------------------------------------
class Ledger::txs_iter_impl : public txs_type::iter_base
class Ledger::TxsIterImpl : public TxsType::iter_base
{
private:
bool metadata_;
SHAMap::const_iterator iter_;
SHAMap::ConstIterator iter_;
public:
txs_iter_impl() = delete;
txs_iter_impl&
operator=(txs_iter_impl const&) = delete;
TxsIterImpl() = delete;
TxsIterImpl&
operator=(TxsIterImpl const&) = delete;
txs_iter_impl(txs_iter_impl const&) = default;
TxsIterImpl(TxsIterImpl const&) = default;
txs_iter_impl(bool metadata, SHAMap::const_iterator iter) : metadata_(metadata), iter_(iter)
TxsIterImpl(bool metadata, SHAMap::ConstIterator iter) : metadata_(metadata), iter_(iter)
{
}
[[nodiscard]] std::unique_ptr<base_type>
copy() const override
{
return std::make_unique<txs_iter_impl>(*this);
return std::make_unique<TxsIterImpl>(*this);
}
[[nodiscard]] bool
equal(base_type const& impl) const override
{
if (auto const p = dynamic_cast<txs_iter_impl const*>(&impl))
if (auto const p = dynamic_cast<TxsIterImpl const*>(&impl))
return iter_ == p->iter_;
return false;
}
@@ -136,7 +133,7 @@ public:
++iter_;
}
[[nodiscard]] txs_type::value_type
[[nodiscard]] TxsType::value_type
dereference() const override
{
auto const& item = *iter_;
@@ -149,12 +146,12 @@ public:
//------------------------------------------------------------------------------
Ledger::Ledger(
create_genesis_t,
CreateGenesisT,
Rules rules,
Fees const& fees,
std::vector<uint256> const& amendments,
Family& family)
: mImmutable(false)
: immutable_(false)
, txMap_(SHAMapType::TRANSACTION, family)
, stateMap_(SHAMapType::STATE, family)
, fees_(fees)
@@ -162,15 +159,15 @@ Ledger::Ledger(
, j_(beast::Journal(beast::Journal::getNullSink()))
{
header_.seq = 1;
header_.drops = INITIAL_XRP;
header_.closeTimeResolution = ledgerGenesisTimeResolution;
header_.drops = kInitialXrp;
header_.closeTimeResolution = kLedgerGenesisTimeResolution;
static auto const id =
calcAccountID(generateKeyPair(KeyType::secp256k1, generateSeed("masterpassphrase")).first);
static auto const kID =
calcAccountID(generateKeyPair(KeyType::Secp256k1, generateSeed("masterpassphrase")).first);
{
auto const sle = std::make_shared<SLE>(keylet::account(id));
auto const sle = std::make_shared<SLE>(keylet::account(kID));
sle->setFieldU32(sfSequence, 1);
sle->setAccountID(sfAccount, id);
sle->setAccountID(sfAccount, kID);
sle->setFieldAmount(sfBalance, header_.drops);
rawInsert(sle);
}
@@ -199,12 +196,12 @@ Ledger::Ledger(
sle->at(sfReserveBase) = *f;
if (auto const f = fees.increment.dropsAs<std::uint32_t>())
sle->at(sfReserveIncrement) = *f;
sle->at(sfReferenceFeeUnits) = FEE_UNITS_DEPRECATED;
sle->at(sfReferenceFeeUnits) = kFeeUnitsDeprecated;
}
rawInsert(sle);
}
stateMap_.flushDirty(hotACCOUNT_NODE);
stateMap_.flushDirty(NodeObjectType::AccountNode);
setImmutable();
}
@@ -216,7 +213,7 @@ Ledger::Ledger(
Fees const& fees,
Family& family,
beast::Journal j)
: mImmutable(true)
: immutable_(true)
, txMap_(SHAMapType::TRANSACTION, info.txHash, family)
, stateMap_(SHAMapType::STATE, info.accountHash, family)
, fees_(fees)
@@ -255,7 +252,7 @@ Ledger::Ledger(
// Create a new ledger that follows this one
Ledger::Ledger(Ledger const& prevLedger, NetClock::time_point closeTime)
: mImmutable(false)
: immutable_(false)
, txMap_(SHAMapType::TRANSACTION, prevLedger.txMap_.family())
, stateMap_(prevLedger.stateMap_, true)
, fees_(prevLedger.fees_)
@@ -282,7 +279,7 @@ Ledger::Ledger(Ledger const& prevLedger, NetClock::time_point closeTime)
}
Ledger::Ledger(LedgerHeader const& info, Rules rules, Family& family)
: mImmutable(true)
: immutable_(true)
, txMap_(SHAMapType::TRANSACTION, info.txHash, family)
, stateMap_(SHAMapType::STATE, info.accountHash, family)
, rules_(std::move(rules))
@@ -298,7 +295,7 @@ Ledger::Ledger(
Rules rules,
Fees const& fees,
Family& family)
: mImmutable(false)
: immutable_(false)
, txMap_(SHAMapType::TRANSACTION, family)
, stateMap_(SHAMapType::STATE, family)
, fees_(fees)
@@ -307,7 +304,7 @@ Ledger::Ledger(
{
header_.seq = ledgerSeq;
header_.closeTime = closeTime;
header_.closeTimeResolution = ledgerDefaultTimeResolution;
header_.closeTimeResolution = kLedgerDefaultTimeResolution;
setup();
}
@@ -316,16 +313,16 @@ Ledger::setImmutable(bool rehash)
{
// Force update, since this is the only
// place the hash transitions to valid
if (!mImmutable && rehash)
if (!immutable_ && rehash)
{
header_.txHash = txMap_.getHash().as_uint256();
header_.accountHash = stateMap_.getHash().as_uint256();
header_.txHash = txMap_.getHash().asUInt256();
header_.accountHash = stateMap_.getHash().asUInt256();
}
if (rehash)
header_.hash = calculateLedgerHash(header_);
mImmutable = true;
immutable_ = true;
txMap_.setImmutable();
stateMap_.setImmutable();
setup();
@@ -342,7 +339,7 @@ Ledger::setAccepted(
header_.closeTime = closeTime;
header_.closeTimeResolution = closeResolution;
header_.closeFlags = correctCloseTime ? 0 : sLCF_NoConsensusTime;
header_.closeFlags = correctCloseTime ? 0 : kSLcfNoConsensusTime;
setImmutable();
}
@@ -350,8 +347,7 @@ bool
Ledger::addSLE(SLE const& sle)
{
auto const s = sle.getSerializer();
return stateMap_.addItem(
SHAMapNodeType::tnACCOUNT_STATE, make_shamapitem(sle.key(), s.slice()));
return stateMap_.addItem(SHAMapNodeType::TnAccountState, makeShamapitem(sle.key(), s.slice()));
}
//------------------------------------------------------------------------------
@@ -397,7 +393,7 @@ Ledger::exists(uint256 const& key) const
std::optional<uint256>
Ledger::succ(uint256 const& key, std::optional<uint256> const& last) const
{
auto item = stateMap_.upper_bound(key);
auto item = stateMap_.upperBound(key);
if (item == stateMap_.end())
return std::nullopt;
if (last && item->key() >= last)
@@ -408,7 +404,7 @@ Ledger::succ(uint256 const& key, std::optional<uint256> const& last) const
std::shared_ptr<SLE const>
Ledger::read(Keylet const& k) const
{
if (k.key == beast::zero)
if (k.key == beast::kZero)
{
// LCOV_EXCL_START
UNREACHABLE("xrpl::Ledger::read : zero key");
@@ -427,33 +423,33 @@ Ledger::read(Keylet const& k) const
//------------------------------------------------------------------------------
auto
Ledger::slesBegin() const -> std::unique_ptr<sles_type::iter_base>
Ledger::slesBegin() const -> std::unique_ptr<SlesType::iter_base>
{
return std::make_unique<sles_iter_impl>(stateMap_.begin());
return std::make_unique<SlesIterImpl>(stateMap_.begin());
}
auto
Ledger::slesEnd() const -> std::unique_ptr<sles_type::iter_base>
Ledger::slesEnd() const -> std::unique_ptr<SlesType::iter_base>
{
return std::make_unique<sles_iter_impl>(stateMap_.end());
return std::make_unique<SlesIterImpl>(stateMap_.end());
}
auto
Ledger::slesUpperBound(uint256 const& key) const -> std::unique_ptr<sles_type::iter_base>
Ledger::slesUpperBound(uint256 const& key) const -> std::unique_ptr<SlesType::iter_base>
{
return std::make_unique<sles_iter_impl>(stateMap_.upper_bound(key));
return std::make_unique<SlesIterImpl>(stateMap_.upperBound(key));
}
auto
Ledger::txsBegin() const -> std::unique_ptr<txs_type::iter_base>
Ledger::txsBegin() const -> std::unique_ptr<TxsType::iter_base>
{
return std::make_unique<txs_iter_impl>(!open(), txMap_.begin());
return std::make_unique<TxsIterImpl>(!open(), txMap_.begin());
}
auto
Ledger::txsEnd() const -> std::unique_ptr<txs_type::iter_base>
Ledger::txsEnd() const -> std::unique_ptr<TxsType::iter_base>
{
return std::make_unique<txs_iter_impl>(!open(), txMap_.end());
return std::make_unique<TxsIterImpl>(!open(), txMap_.end());
}
bool
@@ -484,7 +480,7 @@ Ledger::digest(key_type const& key) const -> std::optional<digest_type>
// from the NodeStore needlessly.
if (!stateMap_.peekItem(key, digest))
return std::nullopt;
return digest.as_uint256();
return digest.asUInt256();
}
//------------------------------------------------------------------------------
@@ -493,14 +489,14 @@ void
Ledger::rawErase(std::shared_ptr<SLE> const& sle)
{
if (!stateMap_.delItem(sle->key()))
Throw<std::logic_error>("Ledger::rawErase: key not found");
logicError("Ledger::rawErase: key not found");
}
void
Ledger::rawErase(uint256 const& key)
{
if (!stateMap_.delItem(key))
Throw<std::logic_error>("Ledger::rawErase: key not found");
logicError("Ledger::rawErase: key not found");
}
void
@@ -509,8 +505,10 @@ Ledger::rawInsert(std::shared_ptr<SLE> const& sle)
Serializer ss;
sle->add(ss);
if (!stateMap_.addGiveItem(
SHAMapNodeType::tnACCOUNT_STATE, make_shamapitem(sle->key(), ss.slice())))
Throw<std::logic_error>("Ledger::rawInsert: key already exists");
SHAMapNodeType::TnAccountState, makeShamapitem(sle->key(), ss.slice())))
{
logicError("Ledger::rawInsert: key already exists");
}
}
void
@@ -519,8 +517,10 @@ Ledger::rawReplace(std::shared_ptr<SLE> const& sle)
Serializer ss;
sle->add(ss);
if (!stateMap_.updateGiveItem(
SHAMapNodeType::tnACCOUNT_STATE, make_shamapitem(sle->key(), ss.slice())))
Throw<std::logic_error>("Ledger::rawReplace: key not found");
SHAMapNodeType::TnAccountState, makeShamapitem(sle->key(), ss.slice())))
{
logicError("Ledger::rawReplace: key not found");
}
}
void
@@ -535,28 +535,8 @@ Ledger::rawTxInsert(
Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
s.addVL(txn->peekData());
s.addVL(metaData->peekData());
if (!txMap_.addGiveItem(SHAMapNodeType::tnTRANSACTION_MD, make_shamapitem(key, s.slice())))
Throw<std::logic_error>("duplicate_tx: " + to_string(key));
}
uint256
Ledger::rawTxInsertWithHash(
uint256 const& key,
std::shared_ptr<Serializer const> const& txn,
std::shared_ptr<Serializer const> const& metaData)
{
XRPL_ASSERT(metaData, "xrpl::Ledger::rawTxInsertWithHash : non-null metadata input");
// low-level - just add to table
Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
s.addVL(txn->peekData());
s.addVL(metaData->peekData());
auto item = make_shamapitem(key, s.slice());
auto hash = sha512Half(HashPrefix::txNode, item->slice(), item->key());
if (!txMap_.addGiveItem(SHAMapNodeType::tnTRANSACTION_MD, std::move(item)))
Throw<std::logic_error>("duplicate_tx: " + to_string(key));
return hash;
if (!txMap_.addGiveItem(SHAMapNodeType::TnTransactionMd, makeShamapitem(key, s.slice())))
logicError("duplicate_tx: " + to_string(key));
}
bool
@@ -575,7 +555,7 @@ Ledger::setup()
catch (std::exception const& ex)
{
JLOG(j_.error()) << "Exception in " << __func__ << ": " << ex.what();
Rethrow();
rethrow();
}
try
@@ -637,7 +617,7 @@ Ledger::setup()
catch (std::exception const& ex)
{
JLOG(j_.error()) << "Exception in " << __func__ << ": " << ex.what();
Rethrow();
rethrow();
}
return ret;
@@ -730,13 +710,13 @@ Ledger::updateNegativeUNL()
if (hasToReEnable && v.isFieldPresent(sfPublicKey) &&
v.getFieldVL(sfPublicKey) == sle->getFieldVL(sfValidatorToReEnable))
continue;
newNUnl.push_back(v);
newNUnl.pushBack(v);
}
}
if (hasToDisable)
{
newNUnl.push_back(STObject::makeInnerObject(sfDisabledValidator));
newNUnl.pushBack(STObject::makeInnerObject(sfDisabledValidator));
newNUnl.back().setFieldVL(sfPublicKey, sle->getFieldVL(sfValidatorToDisable));
newNUnl.back().setFieldU32(sfFirstLedgerSequence, seq());
}
@@ -815,9 +795,9 @@ Ledger::isSensible() const
return false;
if (header_.accountHash.isZero())
return false;
if (header_.accountHash != stateMap_.getHash().as_uint256())
if (header_.accountHash != stateMap_.getHash().asUInt256())
return false;
if (header_.txHash != txMap_.getHash().as_uint256())
if (header_.txHash != txMap_.getHash().asUInt256())
return false;
return true;
}

View File

@@ -24,14 +24,14 @@
namespace xrpl {
class OpenView::txs_iter_impl : public txs_type::iter_base
class OpenView::TxsIterImpl : public TxsType::iter_base
{
private:
bool metadata_;
txs_map::const_iterator iter_;
public:
explicit txs_iter_impl(bool metadata, txs_map::const_iterator iter)
explicit TxsIterImpl(bool metadata, txs_map::const_iterator iter)
: metadata_(metadata), iter_(iter)
{
}
@@ -39,13 +39,13 @@ public:
[[nodiscard]] std::unique_ptr<base_type>
copy() const override
{
return std::make_unique<txs_iter_impl>(metadata_, iter_);
return std::make_unique<TxsIterImpl>(metadata_, iter_);
}
[[nodiscard]] bool
equal(base_type const& impl) const override
{
if (auto const p = dynamic_cast<txs_iter_impl const*>(&impl))
if (auto const p = dynamic_cast<TxsIterImpl const*>(&impl))
return iter_ == p->iter_;
return false;
}
@@ -78,9 +78,9 @@ public:
OpenView::OpenView(OpenView const& rhs)
: ReadView(rhs)
, TxsRawView(rhs)
, monotonic_resource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
initialBufferSize)}
, txs_{rhs.txs_, monotonic_resource_.get()}
, monotonicResource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
kInitialBufferSize)}
, txs_{rhs.txs_, monotonicResource_.get()}
, rules_{rhs.rules_}
, header_{rhs.header_}
, base_{rhs.base_}
@@ -88,14 +88,10 @@ OpenView::OpenView(OpenView const& rhs)
, hold_{rhs.hold_}
, open_{rhs.open_} {};
OpenView::OpenView(
open_ledger_t,
ReadView const* base,
Rules rules,
std::shared_ptr<void const> hold)
: monotonic_resource_{
std::make_unique<boost::container::pmr::monotonic_buffer_resource>(initialBufferSize)}
, txs_{monotonic_resource_.get()}
OpenView::OpenView(OpenLedgerT, ReadView const* base, Rules rules, std::shared_ptr<void const> hold)
: monotonicResource_{
std::make_unique<boost::container::pmr::monotonic_buffer_resource>(kInitialBufferSize)}
, txs_{monotonicResource_.get()}
, rules_(std::move(rules))
, header_(base->header())
, base_(base)
@@ -109,9 +105,9 @@ OpenView::OpenView(
}
OpenView::OpenView(ReadView const* base, std::shared_ptr<void const> hold)
: monotonic_resource_{
std::make_unique<boost::container::pmr::monotonic_buffer_resource>(initialBufferSize)}
, txs_{monotonic_resource_.get()}
: monotonicResource_{
std::make_unique<boost::container::pmr::monotonic_buffer_resource>(kInitialBufferSize)}
, txs_{monotonicResource_.get()}
, rules_(base->rules())
, header_(base->header())
, base_(base)
@@ -174,33 +170,33 @@ OpenView::read(Keylet const& k) const
}
auto
OpenView::slesBegin() const -> std::unique_ptr<sles_type::iter_base>
OpenView::slesBegin() const -> std::unique_ptr<SlesType::iter_base>
{
return items_.slesBegin(*base_);
}
auto
OpenView::slesEnd() const -> std::unique_ptr<sles_type::iter_base>
OpenView::slesEnd() const -> std::unique_ptr<SlesType::iter_base>
{
return items_.slesEnd(*base_);
}
auto
OpenView::slesUpperBound(uint256 const& key) const -> std::unique_ptr<sles_type::iter_base>
OpenView::slesUpperBound(uint256 const& key) const -> std::unique_ptr<SlesType::iter_base>
{
return items_.slesUpperBound(*base_, key);
}
auto
OpenView::txsBegin() const -> std::unique_ptr<txs_type::iter_base>
OpenView::txsBegin() const -> std::unique_ptr<TxsType::iter_base>
{
return std::make_unique<txs_iter_impl>(!open(), txs_.cbegin());
return std::make_unique<TxsIterImpl>(!open(), txs_.cbegin());
}
auto
OpenView::txsEnd() const -> std::unique_ptr<txs_type::iter_base>
OpenView::txsEnd() const -> std::unique_ptr<TxsType::iter_base>
{
return std::make_unique<txs_iter_impl>(!open(), txs_.cend());
return std::make_unique<TxsIterImpl>(!open(), txs_.cend());
}
bool

View File

@@ -321,7 +321,7 @@ PaymentSandbox::balanceHookIOU(
auto adjustedAmt = std::min({amount, lastBal - delta, minBal});
adjustedAmt.get<Issue>().account = amount.getIssuer();
if (isXRP(issuer) && adjustedAmt < beast::zero)
if (isXRP(issuer) && adjustedAmt < beast::kZero)
{
// A calculated negative XRP balance is not an error case. Consider a
// payment snippet that credits a large XRP amount and then debits the

View File

@@ -17,24 +17,24 @@
namespace xrpl::detail {
class RawStateTable::sles_iter_impl : public ReadView::sles_type::iter_base
class RawStateTable::SlesIterImpl : public ReadView::SlesType::iter_base
{
private:
std::shared_ptr<SLE const> sle0_;
ReadView::sles_type::iterator iter0_;
ReadView::sles_type::iterator end0_;
ReadView::SlesType::Iterator iter0_;
ReadView::SlesType::Iterator end0_;
std::shared_ptr<SLE const> sle1_;
items_t::const_iterator iter1_;
items_t::const_iterator end1_;
public:
sles_iter_impl(sles_iter_impl const&) = default;
SlesIterImpl(SlesIterImpl const&) = default;
sles_iter_impl(
SlesIterImpl(
items_t::const_iterator iter1,
items_t::const_iterator end1,
ReadView::sles_type::iterator iter0,
ReadView::sles_type::iterator end0)
ReadView::SlesType::Iterator iter0,
ReadView::SlesType::Iterator end0)
: iter0_(std::move(iter0)), end0_(std::move(end0)), iter1_(iter1), end1_(end1)
{
if (iter0_ != end0_)
@@ -49,13 +49,13 @@ public:
std::unique_ptr<base_type>
copy() const override
{
return std::make_unique<sles_iter_impl>(*this);
return std::make_unique<SlesIterImpl>(*this);
}
bool
equal(base_type const& impl) const override
{
if (auto const p = dynamic_cast<sles_iter_impl const*>(&impl))
if (auto const p = dynamic_cast<SlesIterImpl const*>(&impl))
{
XRPL_ASSERT(
end1_ == p->end1_ && end0_ == p->end0_,
@@ -151,7 +151,7 @@ private:
void
skip()
{
while (iter1_ != end1_ && iter1_->second.action == Action::erase &&
while (iter1_ != end1_ && iter1_->second.action == Action::Erase &&
sle0_->key() == sle1_->key())
{
inc1();
@@ -175,13 +175,13 @@ RawStateTable::apply(RawView& to) const
auto const& item = elem.second;
switch (item.action)
{
case Action::erase:
case Action::Erase:
to.rawErase(item.sle);
break;
case Action::insert:
case Action::Insert:
to.rawInsert(item.sle);
break;
case Action::replace:
case Action::Replace:
to.rawReplace(item.sle);
break;
}
@@ -196,7 +196,7 @@ RawStateTable::exists(ReadView const& base, Keylet const& k) const
if (iter == items_.end())
return base.exists(k);
auto const& item = iter->second;
if (item.action == Action::erase)
if (item.action == Action::Erase)
return false;
if (!k.check(*item.sle))
return false;
@@ -221,11 +221,11 @@ RawStateTable::succ(ReadView const& base, key_type const& key, std::optional<key
if (!next)
break;
iter = items_.find(*next);
} while (iter != items_.end() && iter->second.action == Action::erase);
} while (iter != items_.end() && iter->second.action == Action::Erase);
// Find non-deleted successor in our list
for (iter = items_.upper_bound(key); iter != items_.end(); ++iter)
{
if (iter->second.action != Action::erase)
if (iter->second.action != Action::Erase)
{
// Found both, return the lower key
if (!next || next > iter->first)
@@ -247,20 +247,20 @@ RawStateTable::erase(std::shared_ptr<SLE> const& sle)
auto const result = items_.emplace(
std::piecewise_construct,
std::forward_as_tuple(sle->key()),
std::forward_as_tuple(Action::erase, sle));
std::forward_as_tuple(Action::Erase, sle));
if (result.second)
return;
auto& item = result.first->second;
switch (item.action)
{
case Action::erase:
case Action::Erase:
Throw<std::logic_error>("RawStateTable::erase: already erased");
break;
case Action::insert:
case Action::Insert:
items_.erase(result.first);
break;
case Action::replace:
item.action = Action::erase;
case Action::Replace:
item.action = Action::Erase;
item.sle = sle;
break;
}
@@ -272,20 +272,20 @@ RawStateTable::insert(std::shared_ptr<SLE> const& sle)
auto const result = items_.emplace(
std::piecewise_construct,
std::forward_as_tuple(sle->key()),
std::forward_as_tuple(Action::insert, sle));
std::forward_as_tuple(Action::Insert, sle));
if (result.second)
return;
auto& item = result.first->second;
switch (item.action)
{
case Action::erase:
item.action = Action::replace;
case Action::Erase:
item.action = Action::Replace;
item.sle = sle;
break;
case Action::insert:
case Action::Insert:
Throw<std::logic_error>("RawStateTable::insert: already inserted");
break;
case Action::replace:
case Action::Replace:
Throw<std::logic_error>("RawStateTable::insert: already exists");
break;
}
@@ -297,17 +297,17 @@ RawStateTable::replace(std::shared_ptr<SLE> const& sle)
auto const result = items_.emplace(
std::piecewise_construct,
std::forward_as_tuple(sle->key()),
std::forward_as_tuple(Action::replace, sle));
std::forward_as_tuple(Action::Replace, sle));
if (result.second)
return;
auto& item = result.first->second;
switch (item.action)
{
case Action::erase:
case Action::Erase:
Throw<std::logic_error>("RawStateTable::replace: was erased");
break;
case Action::insert:
case Action::replace:
case Action::Insert:
case Action::Replace:
item.sle = sle;
break;
}
@@ -320,7 +320,7 @@ RawStateTable::read(ReadView const& base, Keylet const& k) const
if (iter == items_.end())
return base.read(k);
auto const& item = iter->second;
if (item.action == Action::erase)
if (item.action == Action::Erase)
return nullptr;
// Convert to SLE const
std::shared_ptr<SLE const> sle = item.sle;
@@ -335,25 +335,25 @@ RawStateTable::destroyXRP(XRPAmount const& fee)
dropsDestroyed_ += fee;
}
std::unique_ptr<ReadView::sles_type::iter_base>
std::unique_ptr<ReadView::SlesType::iter_base>
RawStateTable::slesBegin(ReadView const& base) const
{
return std::make_unique<sles_iter_impl>(
return std::make_unique<SlesIterImpl>(
items_.begin(), items_.end(), base.sles.begin(), base.sles.end());
}
std::unique_ptr<ReadView::sles_type::iter_base>
std::unique_ptr<ReadView::SlesType::iter_base>
RawStateTable::slesEnd(ReadView const& base) const
{
return std::make_unique<sles_iter_impl>(
return std::make_unique<SlesIterImpl>(
items_.end(), items_.end(), base.sles.end(), base.sles.end());
}
std::unique_ptr<ReadView::sles_type::iter_base>
std::unique_ptr<ReadView::SlesType::iter_base>
RawStateTable::slesUpperBound(ReadView const& base, uint256 const& key) const
{
return std::make_unique<sles_iter_impl>(
items_.upper_bound(key), items_.end(), base.sles.upper_bound(key), base.sles.end());
return std::make_unique<SlesIterImpl>(
items_.upper_bound(key), items_.end(), base.sles.upperBound(key), base.sles.end());
}
} // namespace xrpl::detail

View File

@@ -13,48 +13,48 @@
namespace xrpl {
ReadView::sles_type::sles_type(ReadView const& view) : ReadViewFwdRange(view)
ReadView::SlesType::SlesType(ReadView const& view) : ReadViewFwdRange(view)
{
}
auto
ReadView::sles_type::begin() const -> iterator
ReadView::SlesType::begin() const -> Iterator
{
return iterator(view_, view_->slesBegin());
return Iterator(view_, view_->slesBegin());
}
auto
ReadView::sles_type::end() const -> iterator
ReadView::SlesType::end() const -> Iterator
{
return iterator(view_, view_->slesEnd());
return Iterator(view_, view_->slesEnd());
}
auto
ReadView::sles_type::upper_bound(key_type const& key) const -> iterator
ReadView::SlesType::upperBound(key_type const& key) const -> Iterator
{
return iterator(view_, view_->slesUpperBound(key));
return Iterator(view_, view_->slesUpperBound(key));
}
ReadView::txs_type::txs_type(ReadView const& view) : ReadViewFwdRange(view)
ReadView::TxsType::TxsType(ReadView const& view) : ReadViewFwdRange(view)
{
}
bool
ReadView::txs_type::empty() const
ReadView::TxsType::empty() const
{
return begin() == end();
}
auto
ReadView::txs_type::begin() const -> iterator
ReadView::TxsType::begin() const -> Iterator
{
return iterator(view_, view_->txsBegin());
return Iterator(view_, view_->txsBegin());
}
auto
ReadView::txs_type::end() const -> iterator
ReadView::TxsType::end() const -> Iterator
{
return iterator(view_, view_->txsEnd());
return Iterator(view_, view_->txsEnd());
}
Rules
@@ -66,7 +66,7 @@ makeRulesGivenLedger(DigestAwareReadView const& ledger, Rules const& current)
Rules
makeRulesGivenLedger(
DigestAwareReadView const& ledger,
std::unordered_set<uint256, beast::uhash<>> const& presets)
std::unordered_set<uint256, beast::Uhash<>> const& presets)
{
Keylet const k = keylet::amendments();
std::optional const digest = ledger.digest(k.key);

View File

@@ -12,6 +12,7 @@
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/ledger/helpers/CredentialHelpers.h>
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
#include <xrpl/ledger/helpers/TokenHelpers.h>
#include <xrpl/protocol/AccountID.h>
@@ -57,19 +58,45 @@ isVaultPseudoAccountFrozen(
ReadView const& view,
AccountID const& account,
MPTIssue const& mptShare,
int depth)
std::uint8_t depth)
{
if (!view.rules().enabled(featureSingleAssetVault))
return false;
if (depth >= maxAssetCheckDepth)
return true; // LCOV_EXCL_LINE
if (depth >= kMaxAssetCheckDepth)
{
// LCOV_EXCL_START
UNREACHABLE("xrpl::View::isVaultPseudoAccountFrozen : reached asset check depth");
return true;
// LCOV_EXCL_STOP
}
auto const mptIssuance = view.read(keylet::mptIssuance(mptShare.getMptID()));
if (mptIssuance == nullptr)
return false; // zero MPToken won't block deletion of MPTokenIssuance
auto const issuer = mptIssuance->getAccountID(sfIssuer);
// Post-fixCleanup3_2_0: vault shares carry sfReferenceHolding pointing
// to the vault pseudo's MPToken or RippleState for the underlying.
// Read it to derive the underlying asset and recurse, skipping the
// issuer-account-then-vault chain. Pre-amendment shares (no field)
// fall back to the chain lookup below.
if (mptIssuance->isFieldPresent(sfReferenceHolding))
{
auto const sleHolding =
view.read(keylet::unchecked(mptIssuance->getFieldH256(sfReferenceHolding)));
if (!sleHolding)
{
// LCOV_EXCL_START
UNREACHABLE("xrpl::isVaultPseudoAccountFrozen : dangling sfReferenceHolding");
return false;
// LCOV_EXCL_STOP
}
return isAnyFrozen(
view, {issuer, account}, assetOfHolding(*mptIssuance, *sleHolding), depth + 1);
}
auto const mptIssuer = view.read(keylet::account(issuer));
if (mptIssuer == nullptr)
{
@@ -350,7 +377,7 @@ withdrawToDestExceedsLimit(
[&](Issue const& issue) -> TER {
auto const& currency = issue.currency;
auto const owed = creditBalance(view, to, issuer, currency);
if (owed <= beast::zero)
if (owed <= beast::kZero)
{
auto const limit = creditLimit(view, to, issuer, currency);
if (-owed >= limit || amount > (limit + owed))
@@ -437,8 +464,8 @@ doWithdraw(
view,
sourceAcct,
amount.asset(),
FreezeHandling::fhIGNORE_FREEZE,
AuthHandling::ahIGNORE_AUTH,
FreezeHandling::IgnoreFreeze,
AuthHandling::IgnoreAuth,
j) < amount)
{
// LCOV_EXCL_START
@@ -463,7 +490,7 @@ cleanupOnAccountDelete(
// Delete all the entries in the account directory.
std::shared_ptr<SLE> sleDirNode{};
unsigned int uDirEntry{0};
uint256 dirEntry{beast::zero};
uint256 dirEntry{beast::kZero};
std::uint32_t deleted = 0;
if (view.exists(ownerDirKeylet) &&
@@ -487,7 +514,7 @@ cleanupOnAccountDelete(
}
LedgerEntryType const nodeType{
safe_cast<LedgerEntryType>(sleItem->getFieldU16(sfLedgerEntryType))};
safeCast<LedgerEntryType>(sleItem->getFieldU16(sfLedgerEntryType))};
// Deleter handles the details of specific account-owned object
// deletion

View File

@@ -46,7 +46,8 @@ STAmount
ammLPTokens(STAmount const& asset1, STAmount const& asset2, Asset const& lptIssue)
{
// AMM invariant: sqrt(asset1 * asset2) >= LPTokensBalance
auto const rounding = isFeatureEnabled(fixAMMv1_3) ? Number::downward : Number::getround();
auto const rounding =
isFeatureEnabled(fixAMMv1_3) ? Number::RoundingMode::Downward : Number::getround();
NumberRoundModeGuard const g(rounding);
auto const tokens = root2(asset1 * asset2);
return toSTAmount(lptIssue, tokens);
@@ -77,7 +78,7 @@ lpTokensOut(
// minimize tokens out
auto const frac = (r - c) / (1 + c);
return multiply(lptAMMBalance, frac, Number::downward);
return multiply(lptAMMBalance, frac, Number::RoundingMode::Downward);
}
/* Equation 4 solves equation 3 for b:
@@ -113,7 +114,7 @@ ammAssetIn(
// maximize deposit
auto const frac = solveQuadraticEq(a, b, c);
return multiply(asset1Balance, frac, Number::upward);
return multiply(asset1Balance, frac, Number::RoundingMode::Upward);
}
/* Equation 7:
@@ -138,7 +139,7 @@ lpTokensIn(
// maximize tokens in
auto const frac = (c - root2(c * c - 4 * fr)) / 2;
return multiply(lptAMMBalance, frac, Number::upward);
return multiply(lptAMMBalance, frac, Number::RoundingMode::Upward);
}
/* Equation 8 solves equation 7 for b:
@@ -168,7 +169,7 @@ ammAssetOut(
// minimize withdraw
auto const frac = (t1 * t1 - t1 * (2 - f)) / (t1 * f - 1);
return multiply(assetBalance, frac, Number::downward);
return multiply(assetBalance, frac, Number::RoundingMode::Downward);
}
Number
@@ -182,7 +183,7 @@ adjustLPTokens(STAmount const& lptAMMBalance, STAmount const& lpTokens, IsDeposi
{
// Force rounding downward to ensure adjusted tokens are less or equal
// to requested tokens.
saveNumberRoundMode const rm(Number::setround(Number::rounding_mode::downward));
SaveNumberRoundMode const rm(Number::setround(Number::RoundingMode::Downward));
if (isDeposit == IsDeposit::Yes)
return (lptAMMBalance + lpTokens) - lptAMMBalance;
return (lpTokens - lptAMMBalance) + lptAMMBalance;
@@ -204,7 +205,7 @@ adjustAmountsByLPTokens(
auto const lpTokensActual = adjustLPTokens(lptAMMBalance, lpTokens, isDeposit);
if (lpTokensActual == beast::zero)
if (lpTokensActual == beast::kZero)
{
auto const amount2Opt = amount2 ? std::make_optional(STAmount{}) : std::nullopt;
return std::make_tuple(STAmount{}, amount2Opt, lpTokensActual);
@@ -289,7 +290,7 @@ solveQuadraticEqSmallest(Number const& a, Number const& b, Number const& c)
}
STAmount
multiply(STAmount const& amount, Number const& frac, Number::rounding_mode rm)
multiply(STAmount const& amount, Number const& frac, Number::RoundingMode rm)
{
NumberRoundModeGuard const g(rm);
auto const t = amount * frac;
@@ -570,7 +571,7 @@ getTradingFee(ReadView const& view, SLE const& ammSle, AccountID const& account)
"xrpl::getTradingFee : auction present");
if (ammSle.isFieldPresent(sfAuctionSlot))
{
auto const& auctionSlot = safe_downcast<STObject const&>(ammSle.peekAtField(sfAuctionSlot));
auto const& auctionSlot = safeDowncast<STObject const&>(ammSle.peekAtField(sfAuctionSlot));
// Not expired
if (auto const expiration = auctionSlot[~sfExpiration];
duration_cast<seconds>(view.header().parentCloseTime.time_since_epoch()).count() <
@@ -643,7 +644,7 @@ deleteAMMTrustLines(
if (nodeType == ltRIPPLE_STATE)
{
// Trustlines must have zero balance
if (sleItem->getFieldAmount(sfBalance) != beast::zero)
if (sleItem->getFieldAmount(sfBalance) != beast::kZero)
{
// LCOV_EXCL_START
JLOG(j.error()) << "deleteAMMObjects: deleting trustline with "
@@ -680,7 +681,7 @@ deleteAMMMPTokens(Sandbox& sb, AccountID const& ammAccountID, beast::Journal j)
{
// MPT must have zero balance
if (sleItem->getFieldU64(sfMPTAmount) != 0 ||
(*sleItem)[~sfLockedAmount].value_or(0) != 0)
(*sleItem)[~sfLockedAmount].valueOr(0) != 0)
{
// LCOV_EXCL_START
JLOG(j.error()) << "deleteAMMObjects: deleting MPT with "
@@ -731,7 +732,7 @@ deleteAMMAccount(Sandbox& sb, Asset const& asset, Asset const& asset2, beast::Jo
// LCOV_EXCL_STOP
}
if (auto const ter = deleteAMMTrustLines(sb, ammAccountID, maxDeletableAMMTrustLines, j);
if (auto const ter = deleteAMMTrustLines(sb, ammAccountID, kMaxDeletableAmmTrustLines, j);
!isTesSuccess(ter))
return ter;
@@ -778,9 +779,9 @@ initializeFeeAuctionVote(
STObject voteEntry = STObject::makeInnerObject(sfVoteEntry);
if (tfee != 0)
voteEntry.setFieldU16(sfTradingFee, tfee);
voteEntry.setFieldU32(sfVoteWeight, VOTE_WEIGHT_SCALE_FACTOR);
voteEntry.setFieldU32(sfVoteWeight, kVoteWeightScaleFactor);
voteEntry.setAccountID(sfAccount, account);
voteSlots.push_back(voteEntry);
voteSlots.pushBack(voteEntry);
ammSle->setFieldArray(sfVoteSlots, voteSlots);
// AMM creator gets the auction slot for free.
// AuctionSlot is created on AMMCreate and updated on AMMDeposit
@@ -796,7 +797,7 @@ initializeFeeAuctionVote(
auto const expiration = std::chrono::duration_cast<std::chrono::seconds>(
view.header().parentCloseTime.time_since_epoch())
.count() +
TOTAL_TIME_SLOT_SECS;
kTotalTimeSlotSecs;
auctionSlot.setFieldU32(sfExpiration, expiration);
auctionSlot.setFieldAmount(sfPrice, STAmount{lptAsset, 0});
// Set the fee
@@ -808,7 +809,7 @@ initializeFeeAuctionVote(
{
ammSle->makeFieldAbsent(sfTradingFee); // LCOV_EXCL_LINE
}
if (auto const dfee = tfee / AUCTION_SLOT_DISCOUNTED_FEE_FRACTION)
if (auto const dfee = tfee / kAuctionSlotDiscountedFeeFraction)
{
auctionSlot.setFieldU16(sfDiscountedFee, dfee);
}
@@ -816,6 +817,9 @@ initializeFeeAuctionVote(
{
auctionSlot.makeFieldAbsent(sfDiscountedFee); // LCOV_EXCL_LINE
}
// Clear stale auth accounts from any previous auction slot holder.
if (rules.enabled(fixCleanup3_2_0) && auctionSlot.isFieldPresent(sfAuthAccounts))
auctionSlot.makeFieldAbsent(sfAuthAccounts);
}
Expected<bool, TER>

View File

@@ -88,7 +88,7 @@ xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj,
{
auto const sle = view.read(keylet::account(id));
if (sle == nullptr)
return beast::zero;
return beast::kZero;
// Return balance minus reserve
std::uint32_t const ownerCount =
@@ -121,7 +121,7 @@ transferRate(ReadView const& view, AccountID const& issuer)
if (sle && sle->isFieldPresent(sfTransferRate))
return Rate{sle->getFieldU32(sfTransferRate)};
return parityRate;
return kParityRate;
}
void
@@ -146,17 +146,17 @@ AccountID
pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey)
{
// This number must not be changed without an amendment
constexpr std::uint16_t maxAccountAttempts = 256;
for (std::uint16_t i = 0; i < maxAccountAttempts; ++i)
static constexpr std::uint16_t kMaxAccountAttempts = 256;
for (std::uint16_t i = 0; i < kMaxAccountAttempts; ++i)
{
ripesha_hasher rsh;
RipeshaHasher rsh;
auto const hash = sha512Half(i, view.header().parentHash, pseudoOwnerKey);
rsh(hash.data(), hash.size());
AccountID const ret{static_cast<ripesha_hasher::result_type>(rsh)};
AccountID const ret = AccountID::fromRaw(static_cast<RipeshaHasher::result_type>(rsh));
if (!view.read(keylet::account(ret)))
return ret;
}
return beast::zero;
return beast::kZero;
}
// Pseudo-account designator fields MUST be maintained by including the
@@ -168,7 +168,7 @@ pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey)
[[nodiscard]] std::vector<SField const*> const&
getPseudoAccountFields()
{
static std::vector<SField const*> const pseudoFields = []() {
static std::vector<SField const*> const kPseudoFields = []() {
auto const ar = LedgerFormats::getInstance().findByType(ltACCOUNT_ROOT);
if (!ar)
{
@@ -183,12 +183,12 @@ getPseudoAccountFields()
std::vector<SField const*> pseudoFields;
for (auto const& field : soTemplate)
{
if (field.sField().shouldMeta(SField::sMD_PseudoAccount))
if (field.sField().shouldMeta(SField::kSmdPseudoAccount))
pseudoFields.emplace_back(&field.sField());
}
return pseudoFields;
}();
return pseudoFields;
return kPseudoFields;
}
[[nodiscard]] bool
@@ -221,7 +221,7 @@ createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const
"xrpl::createPseudoAccount : valid owner field");
auto const accountId = pseudoAccountAddress(view, pseudoOwnerKey);
if (accountId == beast::zero)
if (accountId == beast::kZero)
return Unexpected(tecDUPLICATE);
// Create pseudo-account.

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(fixCleanup3_1_3) && !isTesSuccess(err))
return Unexpected(err);
foundExpired = true;
}
}
@@ -100,7 +105,7 @@ deleteSLE(ApplyView& view, std::shared_ptr<SLE> const& sleCredential, beast::Jou
auto const issuer = sleCredential->getAccountID(sfIssuer);
auto const subject = sleCredential->getAccountID(sfSubject);
bool const accepted = (sleCredential->getFlags() & lsfAccepted) != 0u;
bool const accepted = sleCredential->isFlag(lsfAccepted);
auto err = delSLE(issuer, sfIssuerNode, !accepted || (subject == issuer));
if (!isTesSuccess(err))
@@ -126,7 +131,7 @@ checkFields(STTx const& tx, beast::Journal j)
return tesSUCCESS;
auto const& credentials = tx.getFieldV256(sfCredentialIDs);
if (credentials.empty() || (credentials.size() > maxCredentialsArraySize))
if (credentials.empty() || (credentials.size() > kMaxCredentialsArraySize))
{
JLOG(j.trace()) << "Malformed transaction: Credentials array size is invalid: "
<< credentials.size();
@@ -169,7 +174,7 @@ valid(STTx const& tx, ReadView const& view, AccountID const& src, beast::Journal
return tecBAD_CREDENTIALS;
}
if ((sleCred->getFlags() & lsfAccepted) == 0u)
if (!sleCred->isFlag(lsfAccepted))
{
JLOG(j.trace()) << "Credential isn't accepted. Cred: " << h;
return tecBAD_CREDENTIALS;
@@ -205,12 +210,12 @@ 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;
}
if ((sleCredential->getFlags() & lsfAccepted) != 0u)
if (sleCredential->isFlag(lsfAccepted))
{
return tesSUCCESS;
}
@@ -283,7 +288,7 @@ checkArray(STArray const& credentials, unsigned maxSize, beast::Journal j)
}
auto const ct = credential[sfCredentialType];
if (ct.empty() || (ct.size() > maxCredentialTypeLength))
if (ct.empty() || (ct.size() > kMaxCredentialTypeLength))
{
JLOG(j.trace()) << "Malformed transaction: "
"Invalid credentialType size: "
@@ -321,21 +326,24 @@ verifyValidDomain(ApplyView& view, AccountID const& account, uint256 domainID, b
auto const type = h.getFieldVL(sfCredentialType);
auto const keyletCredential = keylet::credential(account, issuer, makeSlice(type));
if (view.exists(keyletCredential))
credentials.push_back(keyletCredential.key);
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));
if (!sleCredential)
continue; // expired, i.e. deleted in credentials::removeExpired
if ((sleCredential->getFlags() & lsfAccepted) != 0u)
if (sleCredential->isFlag(lsfAccepted))
return tesSUCCESS;
}
return foundExpired ? tecEXPIRED : tecNO_PERMISSION;
return *foundExpired ? tecEXPIRED : tecNO_PERMISSION;
}
TER
@@ -355,10 +363,17 @@ 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))
if (sleDst && sleDst->isFlag(lsfDepositAuth))
{
if (src != dst)
{

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,6 @@
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/protocol/TxFormats.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/XRPAmount.h>
@@ -55,7 +54,11 @@ isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue cons
}
bool
isFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue, int depth)
isFrozen(
ReadView const& view,
AccountID const& account,
MPTIssue const& mptIssue,
std::uint8_t depth)
{
return isGlobalFrozen(view, mptIssue) || isIndividualFrozen(view, account, mptIssue) ||
isVaultPseudoAccountFrozen(view, account, mptIssue, depth);
@@ -66,7 +69,7 @@ isAnyFrozen(
ReadView const& view,
std::initializer_list<AccountID> const& accounts,
MPTIssue const& mptIssue,
int depth)
std::uint8_t depth)
{
if (isGlobalFrozen(view, mptIssue))
return true;
@@ -96,11 +99,11 @@ transferRate(ReadView const& view, MPTID const& issuanceID)
sle && sle->isFieldPresent(sfTransferFee))
{
auto const fee = sle->getFieldU16(sfTransferFee);
XRPL_ASSERT(fee <= maxTransferFee, "xrpl::transferRate : fee is too large");
XRPL_ASSERT(fee <= kMaxTransferFee, "xrpl::transferRate : fee is too large");
return Rate{1'000'000'000u + (10'000 * fee)};
}
return parityRate;
return kParityRate;
}
[[nodiscard]] TER
@@ -169,8 +172,8 @@ authorizeMPToken(
auto const mptokenKey = keylet::mptoken(mptIssuanceID, account);
auto const sleMpt = view.peek(mptokenKey);
if (!sleMpt || (*sleMpt)[sfMPTAmount] != 0 ||
(view.rules().enabled(fixSecurity3_1_3) &&
(*sleMpt)[~sfLockedAmount].value_or(0) != 0))
(view.rules().enabled(fixCleanup3_1_3) &&
(*sleMpt)[~sfLockedAmount].valueOr(0) != 0))
return tecINTERNAL; // LCOV_EXCL_LINE
if (!view.dirRemove(
@@ -194,7 +197,7 @@ authorizeMPToken(
// items. This is similar to the reserve requirements of trust lines.
std::uint32_t const uOwnerCount = sleAcct->getFieldU32(sfOwnerCount);
XRPAmount const reserveCreate(
(uOwnerCount < 2) ? XRPAmount(beast::zero)
(uOwnerCount < 2) ? XRPAmount(beast::kZero)
: view.fees().accountReserve(uOwnerCount + 1));
if (priorBalance < reserveCreate)
@@ -284,7 +287,7 @@ removeEmptyHolding(
// accounting out of balance, so fail. Since this should be impossible
// anyway, I'm not going to put any effort into it.
if (mptoken->at(sfMPTAmount) != 0 ||
(view.rules().enabled(fixSecurity3_1_3) && (*mptoken)[~sfLockedAmount].value_or(0) != 0))
(view.rules().enabled(fixCleanup3_1_3) && (*mptoken)[~sfLockedAmount].valueOr(0) != 0))
return tecHAS_OBLIGATIONS;
return authorizeMPToken(
@@ -303,7 +306,7 @@ requireAuth(
MPTIssue const& mptIssue,
AccountID const& account,
AuthType authType,
int depth)
std::uint8_t depth)
{
auto const mptID = keylet::mptIssuance(mptIssue.getMptID());
auto const sleIssuance = view.read(mptID);
@@ -320,8 +323,13 @@ requireAuth(
if (featureSAVEnabled)
{
if (depth >= maxAssetCheckDepth)
return tecINTERNAL; // LCOV_EXCL_LINE
if (depth >= kMaxAssetCheckDepth)
{
// LCOV_EXCL_START
UNREACHABLE("xrpl::MPTokenHelpers::requireAuth : reached asset check depth");
return tecINTERNAL;
// LCOV_EXCL_STOP
}
// requireAuth is recursive if the issuer is a vault pseudo-account
auto const sleIssuer = view.read(keylet::account(mptIssuer));
@@ -358,7 +366,7 @@ requireAuth(
if (maybeDomainID)
{
XRPL_ASSERT(
sleIssuance->getFieldU32(sfFlags) & lsfMPTRequireAuth,
sleIssuance->isFlag(lsfMPTRequireAuth),
"xrpl::requireAuth : issuance requires authorization");
// ter = tefINTERNAL | tecOBJECT_NOT_FOUND | tecNO_AUTH | tecEXPIRED
auto const ter = credentials::validDomain(view, *maybeDomainID, account);
@@ -374,10 +382,11 @@ requireAuth(
// belong to someone who is explicitly authorized e.g. a vault owner.
}
if (featureSAVEnabled)
bool const featureMPTV2Enabled = view.rules().enabled(featureMPTokensV2);
if (featureSAVEnabled || featureMPTV2Enabled)
{
// Implicitly authorize Vault and LoanBroker pseudo-accounts
if (isPseudoAccount(view, account, {&sfVaultID, &sfLoanBrokerID}))
// Implicitly authorize Vault, LoanBroker, and AMM pseudo-accounts
if (isPseudoAccount(view, account, {&sfVaultID, &sfLoanBrokerID, &sfAMMID}))
return tesSUCCESS;
}
@@ -489,28 +498,88 @@ enforceMPTokenAuthorization(
// LCOV_EXCL_STOP
}
[[nodiscard]] Asset
assetOfHolding(SLE const& sleShareIssuance, SLE const& sleHolding)
{
XRPL_ASSERT_PARTS(
sleHolding.getType() == ltRIPPLE_STATE || sleHolding.getType() == ltMPTOKEN,
"xrpl::assetOfHolding",
"unexpected holding type");
XRPL_ASSERT_PARTS(
sleShareIssuance.getType() == ltMPTOKEN_ISSUANCE,
"xrpl::assetOfHolding",
"not SLE MPTokenIssuance");
if (sleHolding.getType() == ltMPTOKEN)
return MPTIssue{sleHolding.getFieldH192(sfMPTokenIssuanceID)};
auto const vaultPseudo = sleShareIssuance.at(sfIssuer);
auto const lowLimit = sleHolding.getFieldAmount(sfLowLimit);
auto const highLimit = sleHolding.getFieldAmount(sfHighLimit);
auto const& iouIssuer =
(lowLimit.getIssuer() != vaultPseudo) ? lowLimit.getIssuer() : highLimit.getIssuer();
return Issue{lowLimit.get<Issue>().currency, iouIssuer};
}
TER
canTransfer(
ReadView const& view,
MPTIssue const& mptIssue,
AccountID const& from,
AccountID const& to)
AccountID const& to,
WaiveMPTCanTransfer waive,
std::uint8_t depth)
{
auto const mptID = keylet::mptIssuance(mptIssue.getMptID());
auto const sleIssuance = view.read(mptID);
if (!sleIssuance)
return tecOBJECT_NOT_FOUND;
auto const issuer = (*sleIssuance)[sfIssuer];
if (waive == WaiveMPTCanTransfer::Yes || from == issuer || to == issuer)
return tesSUCCESS;
if (!sleIssuance->isFlag(lsfMPTCanTransfer))
return TER{tecNO_AUTH};
// Post-fixCleanup3_2_0: vault shares carry sfReferenceHolding pointing
// to the vault pseudo's MPToken or RippleState for the underlying asset.
// Third-party transfers inherit the underlying's transferability.
// Issuer-involving transfers and waived callers returned tesSUCCESS above.
//
// The recursive call always passes WaiveMPTCanTransfer::No so that
// a waived outer caller does not transitively unlock the underlying.
if (view.rules().enabled(fixCleanup3_2_0) && sleIssuance->isFieldPresent(sfReferenceHolding))
{
if (from != (*sleIssuance)[sfIssuer] && to != (*sleIssuance)[sfIssuer])
return TER{tecNO_AUTH};
// Defensive depth bound on the inheritance recursion. Unreachable
// in practice (vault-of-vault-shares is forbidden at VaultCreate).
if (depth >= kMaxAssetCheckDepth)
{
// LCOV_EXCL_START
UNREACHABLE("xrpl::MPTokenHelpers::canTransfer : reached asset check depth");
return tecINTERNAL;
// LCOV_EXCL_STOP
}
auto const sleHolding =
view.read(keylet::unchecked(sleIssuance->getFieldH256(sfReferenceHolding)));
if (!sleHolding)
return tefINTERNAL; // LCOV_EXCL_LINE
return canTransfer(
view,
assetOfHolding(*sleIssuance, *sleHolding),
from,
to,
WaiveMPTCanTransfer::No,
depth + 1);
}
return tesSUCCESS;
}
TER
canTrade(ReadView const& view, Asset const& asset)
canTrade(ReadView const& view, Asset const& asset, std::uint8_t depth)
{
return asset.visit(
[&](Issue const&) -> TER { return tesSUCCESS; },
@@ -520,10 +589,51 @@ canTrade(ReadView const& view, Asset const& asset)
return tecOBJECT_NOT_FOUND;
if (!sleIssuance->isFlag(lsfMPTCanTrade))
return tecNO_PERMISSION;
// Post-fixCleanup3_2_0: vault shares inherit the underlying
// asset's tradability. A share whose underlying has been
// removed from trading cannot itself be placed on the DEX.
if (view.rules().enabled(fixCleanup3_2_0) &&
sleIssuance->isFieldPresent(sfReferenceHolding))
{
// Defensive depth bound on the inheritance recursion.
// Unreachable in practice (vault-of-vault-shares
// forbidden at VaultCreate).
if (depth >= kMaxAssetCheckDepth)
{
// LCOV_EXCL_START
UNREACHABLE("xrpl::MPTokenHelpers::canTrade : reached asset check depth");
return tecINTERNAL;
// LCOV_EXCL_STOP
}
auto const sleHolding =
view.read(keylet::unchecked(sleIssuance->getFieldH256(sfReferenceHolding)));
if (!sleHolding)
return tefINTERNAL; // LCOV_EXCL_LINE
return canTrade(view, assetOfHolding(*sleIssuance, *sleHolding), depth + 1);
}
return tesSUCCESS;
});
}
TER
canMPTTradeAndTransfer(
ReadView const& view,
Asset const& asset,
AccountID const& from,
AccountID const& to)
{
if (!asset.holds<MPTIssue>())
return tesSUCCESS;
if (auto const ter = canTrade(view, asset); !isTesSuccess(ter))
return ter;
return canTransfer(view, asset, from, to);
}
TER
lockEscrowMPT(ApplyView& view, AccountID const& sender, STAmount const& amount, beast::Journal j)
{
@@ -567,7 +677,7 @@ lockEscrowMPT(ApplyView& view, AccountID const& sender, STAmount const& amount,
(*sle)[sfMPTAmount] = amt - pay;
// Overflow check for addition
uint64_t const locked = (*sle)[~sfLockedAmount].value_or(0);
uint64_t const locked = (*sle)[~sfLockedAmount].valueOr(0);
if (!canAdd(STAmount(mptIssue, locked), STAmount(mptIssue, pay)))
{ // LCOV_EXCL_START
@@ -591,7 +701,7 @@ lockEscrowMPT(ApplyView& view, AccountID const& sender, STAmount const& amount,
// 1. Increase the Issuance EscrowedAmount
// 2. DO NOT change the Issuance OutstandingAmount
{
uint64_t const issuanceEscrowed = (*sleIssuance)[~sfLockedAmount].value_or(0);
uint64_t const issuanceEscrowed = (*sleIssuance)[~sfLockedAmount].valueOr(0);
auto const pay = amount.mpt().value();
// Overflow check for addition
@@ -839,7 +949,7 @@ checkCreateMPT(
std::int64_t
maxMPTAmount(SLE const& sleIssuance)
{
return sleIssuance[~sfMaximumAmount].value_or(maxMPTokenAmount);
return sleIssuance[~sfMaximumAmount].value_or(kMaxMpTokenAmount);
}
std::int64_t
@@ -891,65 +1001,4 @@ issuerSelfDebitHookMPT(ApplyView& view, MPTIssue const& issue, std::uint64_t amo
view.issuerSelfDebitHookMPT(issue, amount, available);
}
static TER
checkMPTAllowed(ReadView const& view, TxType txType, Asset const& asset, AccountID const& accountID)
{
if (!asset.holds<MPTIssue>())
return tesSUCCESS;
auto const& issuanceID = asset.get<MPTIssue>().getMptID();
auto const validTx = txType == ttAMM_CREATE || txType == ttAMM_DEPOSIT ||
txType == ttAMM_WITHDRAW || txType == ttOFFER_CREATE || txType == ttCHECK_CREATE ||
txType == ttCHECK_CASH || txType == ttPAYMENT;
XRPL_ASSERT(validTx, "xrpl::checkMPTAllowed : all MPT tx or DEX");
if (!validTx)
return tefINTERNAL; // LCOV_EXCL_LINE
auto const& issuer = asset.getIssuer();
if (!view.exists(keylet::account(issuer)))
return tecNO_ISSUER; // LCOV_EXCL_LINE
auto const issuanceKey = keylet::mptIssuance(issuanceID);
auto const issuanceSle = view.read(issuanceKey);
if (!issuanceSle)
return tecOBJECT_NOT_FOUND; // LCOV_EXCL_LINE
auto const flags = issuanceSle->getFlags();
if ((flags & lsfMPTLocked) != 0u)
return tecLOCKED; // LCOV_EXCL_LINE
// Offer crossing and Payment
if ((flags & lsfMPTCanTrade) == 0)
return tecNO_PERMISSION;
if (accountID != issuer)
{
if ((flags & lsfMPTCanTransfer) == 0)
return tecNO_PERMISSION;
auto const mptSle = view.read(keylet::mptoken(issuanceKey.key, accountID));
// Allow to succeed since some tx create MPToken if it doesn't exist.
// Tx's have their own check for missing MPToken.
if (!mptSle)
return tesSUCCESS;
if (mptSle->isFlag(lsfMPTLocked))
return tecLOCKED;
}
return tesSUCCESS;
}
TER
checkMPTTxAllowed(
ReadView const& view,
TxType txType,
Asset const& asset,
AccountID const& accountID)
{
// use isDEXAllowed for payment/offer crossing
XRPL_ASSERT(txType != ttPAYMENT, "xrpl::checkMPTTxAllowed : not payment");
return checkMPTAllowed(view, txType, asset, accountID);
}
} // namespace xrpl

View File

@@ -24,6 +24,7 @@
#include <xrpl/protocol/SeqProxy.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol/nft.h>
#include <xrpl/protocol/nftPageMask.h>
@@ -43,8 +44,8 @@ namespace xrpl::nft {
static std::shared_ptr<SLE const>
locatePage(ReadView const& view, AccountID const& owner, uint256 const& id)
{
auto const first = keylet::nftpage(keylet::nftpage_min(owner), id);
auto const last = keylet::nftpage_max(owner);
auto const first = keylet::nftpage(keylet::nftpageMin(owner), id);
auto const last = keylet::nftpageMax(owner);
// This NFT can only be found in the first page with a key that's strictly
// greater than `first`, so look for that, up until the maximum possible
@@ -56,8 +57,8 @@ locatePage(ReadView const& view, AccountID const& owner, uint256 const& id)
static std::shared_ptr<SLE>
locatePage(ApplyView& view, AccountID const& owner, uint256 const& id)
{
auto const first = keylet::nftpage(keylet::nftpage_min(owner), id);
auto const last = keylet::nftpage_max(owner);
auto const first = keylet::nftpage(keylet::nftpageMin(owner), id);
auto const last = keylet::nftpageMax(owner);
// This NFT can only be found in the first page with a key that's strictly
// greater than `first`, so look for that, up until the maximum possible
@@ -73,9 +74,9 @@ getPageForToken(
uint256 const& id,
std::function<void(ApplyView&, AccountID const&)> const& createCallback)
{
auto const base = keylet::nftpage_min(owner);
auto const base = keylet::nftpageMin(owner);
auto const first = keylet::nftpage(base, id);
auto const last = keylet::nftpage_max(owner);
auto const last = keylet::nftpageMax(owner);
// This NFT can only be found in the first page with a key that's strictly
// greater than `first`, so look for that, up until the maximum possible
@@ -97,7 +98,7 @@ getPageForToken(
STArray narr = cp->getFieldArray(sfNFTokens);
// The right page still has space: we're good.
if (narr.size() != dirMaxTokensPerPage)
if (narr.size() != kDirMaxTokensPerPage)
return cp;
// We need to split the page in two: the first half of the items in this
@@ -114,13 +115,13 @@ getPageForToken(
// any additional equivalent NFTs maximum room for expansion.
// Round up the boundary until there's a non-equivalent entry.
uint256 const cmp =
narr[(dirMaxTokensPerPage / 2) - 1].getFieldH256(sfNFTokenID) & nft::pageMask;
narr[(kDirMaxTokensPerPage / 2) - 1].getFieldH256(sfNFTokenID) & nft::kPageMask;
// Note that the calls to find_if_not() and (later) find_if()
// rely on the fact that narr is kept in sorted order.
auto splitIter = std::find_if_not(
narr.begin() + (dirMaxTokensPerPage / 2), narr.end(), [&cmp](STObject const& obj) {
return (obj.getFieldH256(sfNFTokenID) & nft::pageMask) == cmp;
narr.begin() + (kDirMaxTokensPerPage / 2), narr.end(), [&cmp](STObject const& obj) {
return (obj.getFieldH256(sfNFTokenID) & nft::kPageMask) == cmp;
});
// If we get all the way from the middle to the end with only
@@ -129,7 +130,7 @@ getPageForToken(
if (splitIter == narr.end())
{
splitIter = std::ranges::find_if(narr, [&cmp](STObject const& obj) {
return (obj.getFieldH256(sfNFTokenID) & nft::pageMask) == cmp;
return (obj.getFieldH256(sfNFTokenID) & nft::kPageMask) == cmp;
});
}
@@ -142,7 +143,7 @@ getPageForToken(
// equivalent tokens. This requires special handling.
if (splitIter == narr.begin())
{
auto const relation{(id & nft::pageMask) <=> cmp};
auto const relation{(id & nft::kPageMask) <=> cmp};
if (relation == 0)
{
// If the passed in id belongs exactly on this (full) page
@@ -177,8 +178,8 @@ getPageForToken(
// less than the low 96-bits of the enclosing page's index. In order to
// accommodate that requirement we use an index one higher than the
// largest NFT in the page.
uint256 const tokenIDForNewPage = narr.size() == dirMaxTokensPerPage
? narr[dirMaxTokensPerPage - 1].getFieldH256(sfNFTokenID).next()
uint256 const tokenIDForNewPage = narr.size() == kDirMaxTokensPerPage
? narr[kDirMaxTokensPerPage - 1].getFieldH256(sfNFTokenID).next()
: carr[0].getFieldH256(sfNFTokenID);
auto np = std::make_shared<SLE>(keylet::nftpage(base, tokenIDForNewPage));
@@ -216,7 +217,7 @@ compareTokens(uint256 const& a, uint256 const& b)
// 96-bits are identical we still need a fully deterministic sort.
// So we sort on the low 96-bits first. If those are equal we sort on
// the whole thing.
if (auto const lowBitsCmp{(a & nft::pageMask) <=> (b & nft::pageMask)}; lowBitsCmp != 0)
if (auto const lowBitsCmp{(a & nft::kPageMask) <=> (b & nft::kPageMask)}; lowBitsCmp != 0)
return lowBitsCmp < 0;
return a < b;
@@ -280,7 +281,7 @@ insertToken(ApplyView& view, AccountID owner, STObject&& nft)
{
auto arr = page->getFieldArray(sfNFTokens);
arr.push_back(std::move(nft));
arr.pushBack(std::move(nft));
arr.sort([](STObject const& o1, STObject const& o2) {
return compareTokens(o1.getFieldH256(sfNFTokenID), o2.getFieldH256(sfNFTokenID));
@@ -313,7 +314,7 @@ mergePages(ApplyView& view, std::shared_ptr<SLE> const& p1, std::shared_ptr<SLE>
// this it would mean that one of them can be deleted as a result of
// the merge.
if (p1arr.size() + p2arr.size() > dirMaxTokensPerPage)
if (p1arr.size() + p2arr.size() > kDirMaxTokensPerPage)
return false;
STArray x(p1arr.size() + p2arr.size());
@@ -444,7 +445,7 @@ removeToken(
// 3. Fix up the owner count.
// 4. Erase the previous page.
if (view.rules().enabled(fixNFTokenPageLinks) &&
((curr->key() & nft::pageMask) == pageMask))
((curr->key() & nft::kPageMask) == kPageMask))
{
// Copy all relevant information from prev to curr.
curr->peekFieldArray(sfNFTokens) = prev->peekFieldArray(sfNFTokens);
@@ -635,8 +636,8 @@ deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer)
auto const nftokenID = (*offer)[sfNFTokenID];
if (!view.dirRemove(
(((*offer)[sfFlags] & lsfSellNFToken) != 0u) ? keylet::nft_sells(nftokenID)
: keylet::nft_buys(nftokenID),
offer->isFlag(lsfSellNFToken) ? keylet::nftSells(nftokenID)
: keylet::nftBuys(nftokenID),
(*offer)[sfNFTokenOfferNode],
offer->key(),
false))
@@ -654,11 +655,11 @@ repairNFTokenDirectoryLinks(ApplyView& view, AccountID const& owner)
{
bool didRepair = false;
auto const last = keylet::nftpage_max(owner);
auto const last = keylet::nftpageMax(owner);
std::shared_ptr<SLE> page = view.peek(Keylet(
ltNFTOKEN_PAGE,
view.succ(keylet::nftpage_min(owner).key, last.key.next()).value_or(last.key)));
view.succ(keylet::nftpageMin(owner).key, last.key.next()).value_or(last.key)));
if (!page)
return didRepair;
@@ -787,7 +788,7 @@ tokenOfferCreatePreflight(
if (!isXRP(amount))
{
if ((nftFlags & nft::flagOnlyXRP) != 0)
if ((nftFlags & nft::kFlagOnlyXrp) != 0)
return temBAD_AMOUNT;
if (!amount)
@@ -832,7 +833,7 @@ tokenOfferCreatePreclaim(
std::optional<AccountID> const& owner,
std::uint32_t txFlags)
{
if (((nftFlags & nft::flagCreateTrustLines) == 0) && !amount.native() && (xferFee != 0u))
if (((nftFlags & nft::kFlagCreateTrustLines) == 0) && !amount.native() && (xferFee != 0u))
{
if (!view.exists(keylet::account(nftIssuer)))
return tecNO_ISSUER;
@@ -854,7 +855,7 @@ tokenOfferCreatePreclaim(
return tecFROZEN;
}
if (nftIssuer != acctID && ((nftFlags & nft::flagTransferable) == 0))
if (nftIssuer != acctID && ((nftFlags & nft::kFlagTransferable) == 0))
{
auto const root = view.read(keylet::account(nftIssuer));
XRPL_ASSERT(root, "xrpl::nft::tokenOfferCreatePreclaim : non-null account");
@@ -873,7 +874,7 @@ tokenOfferCreatePreclaim(
{
// We allow an IOU issuer to make a buy offer
// using their own currency.
if (accountFunds(view, acctID, amount, FreezeHandling::fhZERO_IF_FROZEN, j).signum() <= 0)
if (accountFunds(view, acctID, amount, FreezeHandling::ZeroIfFrozen, j).signum() <= 0)
return tecUNFUNDED_OFFER;
}
@@ -887,7 +888,7 @@ tokenOfferCreatePreclaim(
return tecNO_DST;
// check if the destination has disallowed incoming offers
if ((sleDst->getFlags() & lsfDisallowIncomingNFTokenOffer) != 0u)
if (sleDst->isFlag(lsfDisallowIncomingNFTokenOffer))
return tecNO_PERMISSION;
}
@@ -900,7 +901,7 @@ tokenOfferCreatePreclaim(
if (!sleOwner)
return tecNO_TARGET;
if ((sleOwner->getFlags() & lsfDisallowIncomingNFTokenOffer) != 0u)
if (sleOwner->isFlag(lsfDisallowIncomingNFTokenOffer))
return tecNO_PERMISSION;
}
@@ -953,7 +954,7 @@ tokenOfferCreateApply(
// Token offers are also added to the token's buy or sell offer
// directory
auto const offerNode = view.dirInsert(
isSellOffer ? keylet::nft_sells(nftokenID) : keylet::nft_buys(nftokenID),
isSellOffer ? keylet::nftSells(nftokenID) : keylet::nftBuys(nftokenID),
offerID,
[&nftokenID, isSellOffer](std::shared_ptr<SLE> const& sle) {
(*sle)[sfFlags] = isSellOffer ? lsfNFTokenSellOffers : lsfNFTokenBuyOffers;

View File

@@ -6,6 +6,7 @@
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STArray.h> // IWYU pragma: keep
#include <xrpl/protocol/STLedgerEntry.h>

View File

@@ -3,6 +3,8 @@
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/helpers/CredentialHelpers.h>
#include <xrpl/protocol/AccountID.h>
@@ -19,6 +21,16 @@ namespace xrpl::permissioned_dex {
bool
accountInDomain(ReadView const& view, AccountID const& account, Domain const& domainID)
{
// Avoid constructing a zero-key PermissionedDomain keylet.
// keylet::permissionedDomain(uint256) uses the DomainID as the ledger key.
if (view.rules().enabled(fixCleanup3_2_0) && domainID == beast::kZero)
{
// LCOV_EXCL_START
UNREACHABLE("xrpl::permissioned_dex::accountInDomain : domainID is zero");
return false;
// LCOV_EXCL_STOP
}
auto const sleDomain = view.read(keylet::permissionedDomain(domainID));
if (!sleDomain)
return false;
@@ -35,7 +47,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;
@@ -60,9 +72,9 @@ offerInDomain(
if (sleOffer->getFieldH256(sfDomainID) != domainID)
return false; // LCOV_EXCL_LINE
if (view.rules().enabled(fixSecurity3_1_3))
if (view.rules().enabled(fixCleanup3_1_3))
{
// post-fixSecurity3_1_3: a valid hybrid offer must have
// post-fixCleanup3_1_3: a valid hybrid offer must have
// sfAdditionalBooks present with exactly 1 entry
if (sleOffer->isFlag(lsfHybrid) &&
(!sleOffer->isFieldPresent(sfAdditionalBooks) ||
@@ -75,7 +87,7 @@ offerInDomain(
}
else
{
// pre-fixSecurity3_1_3: a valid hybrid offer must have
// pre-fixCleanup3_1_3: a valid hybrid offer must have
// sfAdditionalBooks present (size is not checked)
if (sleOffer->isFlag(lsfHybrid) && !sleOffer->isFieldPresent(sfAdditionalBooks))
{

View File

@@ -183,15 +183,15 @@ trustCreate(
bool const bSrcHigh,
AccountID const& uSrcAccountID,
AccountID const& uDstAccountID,
uint256 const& uIndex, // --> ripple state entry
SLE::ref sleAccount, // --> the account being set.
bool const bAuth, // --> authorize account.
bool const bNoRipple, // --> others cannot ripple through
bool const bFreeze, // --> funds cannot leave
bool bDeepFreeze, // --> can neither receive nor send funds
STAmount const& saBalance, // --> balance of account being set.
uint256 const& uIndex, // ripple state entry
SLE::ref sleAccount, // the account being set.
bool const bAuth, // authorize account.
bool const bNoRipple, // others cannot ripple through
bool const bFreeze, // funds cannot leave
bool bDeepFreeze, // can neither receive nor send funds
STAmount const& saBalance, // balance of account being set.
// Issuer should be noAccount()
STAmount const& saLimit, // --> limit for account being set.
STAmount const& saLimit, // limit for account being set.
// Issuer should be the account being set.
std::uint32_t uQualityIn,
std::uint32_t uQualityOut,
@@ -274,7 +274,7 @@ trustCreate(
uFlags |= (bSetHigh ? lsfHighDeepFreeze : lsfLowDeepFreeze);
}
if ((slePeer->getFlags() & lsfDefaultRipple) == 0)
if (!slePeer->isFlag(lsfDefaultRipple))
{
// The other side's default is no rippling
uFlags |= (bSetHigh ? lsfLowNoRipple : lsfHighNoRipple);
@@ -341,22 +341,25 @@ updateTrustLine(
{
if (!state)
return false;
std::uint32_t const flags(state->getFieldU32(sfFlags));
auto sle = view.peek(keylet::account(sender));
if (!sle)
return false;
auto const senderReserveFlag = bSenderHigh ? lsfHighReserve : lsfLowReserve;
auto const senderNoRippleFlag = bSenderHigh ? lsfHighNoRipple : lsfLowNoRipple;
auto const senderFreezeFlag = bSenderHigh ? lsfHighFreeze : lsfLowFreeze;
auto const receiverReserveFlag = bSenderHigh ? lsfLowReserve : lsfHighReserve;
// YYY Could skip this if rippling in reverse.
if (before > beast::zero
if (before > beast::kZero
// Sender balance was positive.
&& after <= beast::zero
&& after <= beast::kZero
// Sender is zero or negative.
&& ((flags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) != 0u)
&& state->isFlag(senderReserveFlag)
// Sender reserve is set.
&& static_cast<bool>(flags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) !=
static_cast<bool>(sle->getFlags() & lsfDefaultRipple) &&
((flags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) == 0u) &&
&& state->isFlag(senderNoRippleFlag) != sle->isFlag(lsfDefaultRipple) &&
!state->isFlag(senderFreezeFlag) &&
!state->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit)
// Sender trust limit is 0.
&& (state->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn) == 0u)
@@ -369,11 +372,10 @@ updateTrustLine(
adjustOwnerCount(view, sle, -1, j);
// Clear reserve flag.
state->setFieldU32(sfFlags, flags & (!bSenderHigh ? ~lsfLowReserve : ~lsfHighReserve));
state->clearFlag(senderReserveFlag);
// Balance is zero, receiver reserve is clear.
if (!after // Balance is zero.
&& ((flags & (bSenderHigh ? lsfLowReserve : lsfHighReserve)) == 0u))
if (!after && !state->isFlag(receiverReserveFlag))
return true;
}
return false;
@@ -405,28 +407,28 @@ issueIOU(
if (auto state = view.peek(index))
{
STAmount final_balance = state->getFieldAmount(sfBalance);
STAmount finalBalance = state->getFieldAmount(sfBalance);
if (bSenderHigh)
final_balance.negate(); // Put balance in sender terms.
finalBalance.negate(); // Put balance in sender terms.
STAmount const start_balance = final_balance;
STAmount const startBalance = finalBalance;
final_balance -= amount;
finalBalance -= amount;
auto const must_delete = updateTrustLine(
view, state, bSenderHigh, issue.account, start_balance, final_balance, j);
auto const mustDelete =
updateTrustLine(view, state, bSenderHigh, issue.account, startBalance, finalBalance, j);
view.creditHookIOU(issue.account, account, amount, start_balance);
view.creditHookIOU(issue.account, account, amount, startBalance);
if (bSenderHigh)
final_balance.negate();
finalBalance.negate();
// Adjust the balance on the trust line if necessary. We do this even
// if we are going to delete the line to reflect the correct balance
// at the time of deletion.
state->setFieldAmount(sfBalance, final_balance);
if (must_delete)
state->setFieldAmount(sfBalance, finalBalance);
if (mustDelete)
{
return trustDelete(
view,
@@ -445,15 +447,15 @@ issueIOU(
// this is unnecessarily inefficient as copying which could be avoided
// is now required. Consider available options.
STAmount const limit(Issue{issue.currency, account});
STAmount final_balance = amount;
STAmount finalBalance = amount;
final_balance.get<Issue>().account = noAccount();
finalBalance.get<Issue>().account = noAccount();
auto const receiverAccount = view.peek(keylet::account(account));
if (!receiverAccount)
return tefINTERNAL; // LCOV_EXCL_LINE
bool const noRipple = (receiverAccount->getFlags() & lsfDefaultRipple) == 0;
bool const noRipple = !receiverAccount->isFlag(lsfDefaultRipple);
return trustCreate(
view,
@@ -466,7 +468,7 @@ issueIOU(
noRipple,
false,
false,
final_balance,
finalBalance,
limit,
0,
0,
@@ -497,29 +499,29 @@ redeemIOU(
if (auto state = view.peek(keylet::line(account, issue.account, issue.currency)))
{
STAmount final_balance = state->getFieldAmount(sfBalance);
STAmount finalBalance = state->getFieldAmount(sfBalance);
if (bSenderHigh)
final_balance.negate(); // Put balance in sender terms.
finalBalance.negate(); // Put balance in sender terms.
STAmount const start_balance = final_balance;
STAmount const startBalance = finalBalance;
final_balance -= amount;
finalBalance -= amount;
auto const must_delete =
updateTrustLine(view, state, bSenderHigh, account, start_balance, final_balance, j);
auto const mustDelete =
updateTrustLine(view, state, bSenderHigh, account, startBalance, finalBalance, j);
view.creditHookIOU(account, issue.account, amount, start_balance);
view.creditHookIOU(account, issue.account, amount, startBalance);
if (bSenderHigh)
final_balance.negate();
finalBalance.negate();
// Adjust the balance on the trust line if necessary. We do this even
// if we are going to delete the line to reflect the correct balance
// at the time of deletion.
state->setFieldAmount(sfBalance, final_balance);
state->setFieldAmount(sfBalance, finalBalance);
if (must_delete)
if (mustDelete)
{
return trustDelete(
view,
@@ -564,12 +566,11 @@ requireAuth(ReadView const& view, Issue const& issue, AccountID const& account,
// If this is a weak or legacy check, or if the account has a line, fail if
// auth is required and not set on the line
if (auto const issuerAccount = view.read(keylet::account(issue.account));
issuerAccount && (((*issuerAccount)[sfFlags] & lsfRequireAuth) != 0u))
issuerAccount && issuerAccount->isFlag(lsfRequireAuth))
{
if (trustLine)
{
return (((*trustLine)[sfFlags] &
((account > issue.account) ? lsfLowAuth : lsfHighAuth)) != 0u)
return trustLine->isFlag((account > issue.account) ? lsfLowAuth : lsfHighAuth)
? tesSUCCESS
: TER{tecNO_AUTH};
}
@@ -698,7 +699,7 @@ removeEmptyHolding(
auto const line = view.peek(keylet::line(accountID, issue));
if (!line)
return accountIsIssuer ? (TER)tesSUCCESS : (TER)tecOBJECT_NOT_FOUND;
if (!accountIsIssuer && line->at(sfBalance)->iou() != beast::zero)
if (!accountIsIssuer && line->at(sfBalance)->iou() != beast::kZero)
return tecHAS_OBLIGATIONS;
// Adjust the owner count(s)
@@ -774,7 +775,7 @@ deleteAMMTrustLine(
}
auto const uFlags = !ammLow ? lsfLowReserve : lsfHighReserve;
if ((sleState->getFlags() & uFlags) == 0u)
if (!sleState->isFlag(uFlags))
return tecINTERNAL; // LCOV_EXCL_LINE
adjustOwnerCount(view, !ammLow ? sleLow : sleHigh, -1, j);

View File

@@ -28,6 +28,7 @@
#include <cstdint>
#include <initializer_list>
#include <limits>
#include <string>
#include <variant>
@@ -55,6 +56,14 @@ isGlobalFrozen(ReadView const& view, Asset const& asset)
[&](MPTIssue const& issue) { return isGlobalFrozen(view, issue); });
}
TER
checkGlobalFrozen(ReadView const& view, Asset const& asset)
{
if (isGlobalFrozen(view, asset))
return asset.holds<MPTIssue>() ? tecLOCKED : tecFROZEN;
return tesSUCCESS;
}
bool
isIndividualFrozen(ReadView const& view, AccountID const& account, Asset const& asset)
{
@@ -62,8 +71,16 @@ isIndividualFrozen(ReadView const& view, AccountID const& account, Asset const&
[&](auto const& issue) { return isIndividualFrozen(view, account, issue); }, asset.value());
}
TER
checkIndividualFrozen(ReadView const& view, AccountID const& account, Asset const& asset)
{
if (isIndividualFrozen(view, account, asset))
return asset.holds<MPTIssue>() ? tecLOCKED : tecFROZEN;
return tesSUCCESS;
}
bool
isFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth)
isFrozen(ReadView const& view, AccountID const& account, Asset const& asset, std::uint8_t depth)
{
return std::visit(
[&](auto const& issue) { return isFrozen(view, account, issue, depth); }, asset.value());
@@ -107,7 +124,7 @@ isAnyFrozen(
ReadView const& view,
std::initializer_list<AccountID> const& accounts,
Asset const& asset,
int depth)
std::uint8_t depth)
{
return asset.visit(
[&](Issue const& issue) { return isAnyFrozen(view, accounts, issue); },
@@ -115,7 +132,11 @@ isAnyFrozen(
}
bool
isDeepFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue, int depth)
isDeepFrozen(
ReadView const& view,
AccountID const& account,
MPTIssue const& mptIssue,
std::uint8_t depth)
{
// Unlike IOUs, frozen / locked MPTs are not allowed to send or receive
// funds, so checking "deep frozen" is the same as checking "frozen".
@@ -123,7 +144,7 @@ isDeepFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mpt
}
bool
isDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth)
isDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset, std::uint8_t depth)
{
return std::visit(
[&](auto const& issue) { return isDeepFrozen(view, account, issue, depth); },
@@ -165,7 +186,7 @@ getLineIfUsable(
return nullptr;
}
if (zeroIfFrozen == fhZERO_IF_FROZEN)
if (zeroIfFrozen == FreezeHandling::ZeroIfFrozen)
{
if (isFrozen(view, account, currency, issuer) ||
isDeepFrozen(view, account, currency, issuer))
@@ -252,12 +273,12 @@ accountHolds(
return {xrpLiquid(view, account, 0, j)};
}
bool const returnSpendable = (includeFullBalance == shFULL_BALANCE);
bool const returnSpendable = (includeFullBalance == SpendableHandling::FullBalance);
if (returnSpendable && account == issuer)
{
// If the account is the issuer, then their limit is effectively
// infinite
return STAmount{Issue{currency, issuer}, STAmount::cMaxValue, STAmount::cMaxOffset};
return STAmount{Issue{currency, issuer}, STAmount::kMaxValue, STAmount::kMaxOffset};
}
// IOU: Return balance on trust line modulo freeze
@@ -290,7 +311,7 @@ accountHolds(
beast::Journal j,
SpendableHandling includeFullBalance)
{
bool const returnSpendable = (includeFullBalance == shFULL_BALANCE);
bool const returnSpendable = (includeFullBalance == SpendableHandling::FullBalance);
STAmount amount{mptIssue};
auto const& issuer = mptIssue.getIssuer();
bool const mptokensV2 = view.rules().enabled(featureMPTokensV2);
@@ -317,7 +338,7 @@ accountHolds(
{
amount.clear(mptIssue);
}
else if (zeroIfFrozen == fhZERO_IF_FROZEN && isFrozen(view, account, mptIssue))
else if (zeroIfFrozen == FreezeHandling::ZeroIfFrozen && isFrozen(view, account, mptIssue))
{
amount.clear(mptIssue);
}
@@ -327,14 +348,14 @@ accountHolds(
// Only if auth check is needed, as it needs to do an additional read
// operation. Note featureSingleAssetVault will affect error codes.
if (zeroIfUnauthorized == ahZERO_IF_UNAUTHORIZED &&
if (zeroIfUnauthorized == AuthHandling::ZeroIfUnauthorized &&
view.rules().enabled(featureSingleAssetVault))
{
if (auto const err = requireAuth(view, mptIssue, account, AuthType::StrongAuth);
!isTesSuccess(err))
amount.clear(mptIssue);
}
else if (zeroIfUnauthorized == ahZERO_IF_UNAUTHORIZED)
else if (zeroIfUnauthorized == AuthHandling::ZeroIfUnauthorized)
{
auto const sleIssuance = view.read(keylet::mptIssuance(mptIssue.getMptID()));
@@ -401,7 +422,13 @@ accountFunds(
[&](Issue const&) { return accountFunds(view, id, saDefault, freezeHandling, j); },
[&](MPTIssue const&) {
return accountHolds(
view, id, saDefault.asset(), freezeHandling, authHandling, j, shFULL_BALANCE);
view,
id,
saDefault.asset(),
freezeHandling,
authHandling,
j,
SpendableHandling::FullBalance);
});
}
@@ -487,20 +514,26 @@ TER
requireAuth(ReadView const& view, Asset const& asset, AccountID const& account, AuthType authType)
{
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue_) {
return requireAuth(view, issue_, account, authType);
[&]<ValidIssueType TIss>(TIss const& issue) {
return requireAuth(view, issue, account, authType);
},
asset.value());
}
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,
std::uint8_t depth)
{
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) -> TER {
return canTransfer(view, issue, from, to);
return asset.visit(
[&](MPTIssue const& issue) -> TER {
return canTransfer(view, issue, from, to, waive, depth);
},
asset.value());
[&](Issue const& issue) -> TER { return canTransfer(view, issue, from, to); });
}
//------------------------------------------------------------------------------
@@ -563,39 +596,41 @@ directSendNoFeeIOU(
<< " amount=" << saAmount.getFullText()
<< " after=" << saBalance.getFullText();
std::uint32_t const uFlags(sleRippleState->getFieldU32(sfFlags));
bool bDelete = false;
auto const senderReserveFlag = bSenderHigh ? lsfHighReserve : lsfLowReserve;
auto const senderNoRippleFlag = bSenderHigh ? lsfHighNoRipple : lsfLowNoRipple;
auto const senderFreezeFlag = bSenderHigh ? lsfHighFreeze : lsfLowFreeze;
auto const receiverReserveFlag = bSenderHigh ? lsfLowReserve : lsfHighReserve;
// FIXME This NEEDS to be cleaned up and simplified. It's impossible
// for anyone to understand.
if (saBefore > beast::zero
if (saBefore > beast::kZero
// Sender balance was positive.
&& saBalance <= beast::zero
&& saBalance <= beast::kZero
// Sender is zero or negative.
&& ((uFlags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) != 0u)
&& sleRippleState->isFlag(senderReserveFlag)
// Sender reserve is set.
&& static_cast<bool>(uFlags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) !=
static_cast<bool>(
view.read(keylet::account(uSenderID))->getFlags() & lsfDefaultRipple) &&
((uFlags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) == 0u) &&
!sleRippleState->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit)
&& sleRippleState->isFlag(senderNoRippleFlag) !=
view.read(keylet::account(uSenderID))->isFlag(lsfDefaultRipple) &&
!sleRippleState->isFlag(senderFreezeFlag) &&
!sleRippleState->getFieldAmount(bSenderHigh ? sfHighLimit : sfLowLimit)
// Sender trust limit is 0.
&& (sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn) == 0u)
&& (sleRippleState->getFieldU32(bSenderHigh ? sfHighQualityIn : sfLowQualityIn) == 0u)
// Sender quality in is 0.
&&
(sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut) == 0u))
(sleRippleState->getFieldU32(bSenderHigh ? sfHighQualityOut : sfLowQualityOut) == 0u))
// Sender quality out is 0.
{
// Clear the reserve of the sender, possibly delete the line!
adjustOwnerCount(view, view.peek(keylet::account(uSenderID)), -1, j);
// Clear reserve flag.
sleRippleState->setFieldU32(
sfFlags, uFlags & (!bSenderHigh ? ~lsfLowReserve : ~lsfHighReserve));
sleRippleState->clearFlag(senderReserveFlag);
// Balance is zero, receiver reserve is clear.
bDelete = !saBalance // Balance is zero.
&& ((uFlags & (bSenderHigh ? lsfLowReserve : lsfHighReserve)) == 0u);
&& !sleRippleState->isFlag(receiverReserveFlag);
// Receiver reserve is clear.
}
@@ -612,7 +647,7 @@ directSendNoFeeIOU(
view,
sleRippleState,
bSenderHigh ? uReceiverID : uSenderID,
!bSenderHigh ? uReceiverID : uSenderID,
bSenderHigh ? uSenderID : uReceiverID,
j);
}
@@ -634,7 +669,7 @@ directSendNoFeeIOU(
if (!sleAccount)
return tefINTERNAL; // LCOV_EXCL_LINE
bool const noRipple = (sleAccount->getFlags() & lsfDefaultRipple) == 0;
bool const noRipple = !sleAccount->isFlag(lsfDefaultRipple);
return trustCreate(
view,
@@ -789,7 +824,7 @@ accountSendIOU(
{
if (view.rules().enabled(fixAMMv1_1))
{
if (saAmount < beast::zero || saAmount.holds<MPTIssue>())
if (saAmount < beast::kZero || saAmount.holds<MPTIssue>())
{
return tecINTERNAL; // LCOV_EXCL_LINE
}
@@ -798,7 +833,7 @@ accountSendIOU(
{
// LCOV_EXCL_START
XRPL_ASSERT(
saAmount >= beast::zero && !saAmount.holds<MPTIssue>(),
saAmount >= beast::kZero && !saAmount.holds<MPTIssue>(),
"xrpl::accountSendIOU : minimum amount and not MPT");
// LCOV_EXCL_STOP
}
@@ -827,24 +862,23 @@ accountSendIOU(
TER terResult(tesSUCCESS);
SLE::pointer const sender =
uSenderID != beast::zero ? view.peek(keylet::account(uSenderID)) : SLE::pointer();
uSenderID != beast::kZero ? view.peek(keylet::account(uSenderID)) : SLE::pointer();
SLE::pointer const receiver =
uReceiverID != beast::zero ? view.peek(keylet::account(uReceiverID)) : SLE::pointer();
uReceiverID != beast::kZero ? view.peek(keylet::account(uReceiverID)) : SLE::pointer();
if (auto stream = j.trace())
{
std::string sender_bal("-");
std::string receiver_bal("-");
std::string senderBal("-");
std::string receiverBal("-");
if (sender)
sender_bal = sender->getFieldAmount(sfBalance).getFullText();
senderBal = sender->getFieldAmount(sfBalance).getFullText();
if (receiver)
receiver_bal = receiver->getFieldAmount(sfBalance).getFullText();
receiverBal = receiver->getFieldAmount(sfBalance).getFullText();
stream << "accountSendIOU> " << to_string(uSenderID) << " (" << sender_bal << ") -> "
<< to_string(uReceiverID) << " (" << receiver_bal
<< ") : " << saAmount.getFullText();
stream << "accountSendIOU> " << to_string(uSenderID) << " (" << senderBal << ") -> "
<< to_string(uReceiverID) << " (" << receiverBal << ") : " << saAmount.getFullText();
}
if (sender)
@@ -880,18 +914,17 @@ accountSendIOU(
if (auto stream = j.trace())
{
std::string sender_bal("-");
std::string receiver_bal("-");
std::string senderBal("-");
std::string receiverBal("-");
if (sender)
sender_bal = sender->getFieldAmount(sfBalance).getFullText();
senderBal = sender->getFieldAmount(sfBalance).getFullText();
if (receiver)
receiver_bal = receiver->getFieldAmount(sfBalance).getFullText();
receiverBal = receiver->getFieldAmount(sfBalance).getFullText();
stream << "accountSendIOU< " << to_string(uSenderID) << " (" << sender_bal << ") -> "
<< to_string(uReceiverID) << " (" << receiver_bal
<< ") : " << saAmount.getFullText();
stream << "accountSendIOU< " << to_string(uSenderID) << " (" << senderBal << ") -> "
<< to_string(uReceiverID) << " (" << receiverBal << ") : " << saAmount.getFullText();
}
return terResult;
@@ -925,16 +958,16 @@ accountSendMultiIOU(
*/
SLE::pointer const sender =
senderID != beast::zero ? view.peek(keylet::account(senderID)) : SLE::pointer();
senderID != beast::kZero ? view.peek(keylet::account(senderID)) : SLE::pointer();
if (auto stream = j.trace())
{
std::string sender_bal("-");
std::string senderBal("-");
if (sender)
sender_bal = sender->getFieldAmount(sfBalance).getFullText();
senderBal = sender->getFieldAmount(sfBalance).getFullText();
stream << "accountSendMultiIOU> " << to_string(senderID) << " (" << sender_bal << ") -> "
stream << "accountSendMultiIOU> " << to_string(senderID) << " (" << senderBal << ") -> "
<< receivers.size() << " receivers.";
}
@@ -945,7 +978,7 @@ accountSendMultiIOU(
auto const& receiverID = r.first;
STAmount const amount{issue, r.second};
if (amount < beast::zero)
if (amount < beast::kZero)
{
return tecINTERNAL; // LCOV_EXCL_LINE
}
@@ -957,17 +990,17 @@ accountSendMultiIOU(
continue;
SLE::pointer const receiver =
receiverID != beast::zero ? view.peek(keylet::account(receiverID)) : SLE::pointer();
receiverID != beast::kZero ? view.peek(keylet::account(receiverID)) : SLE::pointer();
if (auto stream = j.trace())
{
std::string receiver_bal("-");
std::string receiverBal("-");
if (receiver)
receiver_bal = receiver->getFieldAmount(sfBalance).getFullText();
receiverBal = receiver->getFieldAmount(sfBalance).getFullText();
stream << "accountSendMultiIOU> " << to_string(senderID) << " -> "
<< to_string(receiverID) << " (" << receiver_bal
<< to_string(receiverID) << " (" << receiverBal
<< ") : " << amount.getFullText();
}
@@ -986,13 +1019,13 @@ accountSendMultiIOU(
if (auto stream = j.trace())
{
std::string receiver_bal("-");
std::string receiverBal("-");
if (receiver)
receiver_bal = receiver->getFieldAmount(sfBalance).getFullText();
receiverBal = receiver->getFieldAmount(sfBalance).getFullText();
stream << "accountSendMultiIOU< " << to_string(senderID) << " -> "
<< to_string(receiverID) << " (" << receiver_bal
<< to_string(receiverID) << " (" << receiverBal
<< ") : " << amount.getFullText();
}
}
@@ -1013,12 +1046,12 @@ accountSendMultiIOU(
if (auto stream = j.trace())
{
std::string sender_bal("-");
std::string senderBal("-");
if (sender)
sender_bal = sender->getFieldAmount(sfBalance).getFullText();
senderBal = sender->getFieldAmount(sfBalance).getFullText();
stream << "accountSendMultiIOU< " << to_string(senderID) << " (" << sender_bal << ") -> "
stream << "accountSendMultiIOU< " << to_string(senderID) << " (" << senderBal << ") -> "
<< receivers.size() << " receivers.";
}
return tesSUCCESS;
@@ -1089,6 +1122,13 @@ directSendNoFeeMPT(
auto const mptokenID = keylet::mptoken(mptID.key, uReceiverID);
if (auto sle = view.peek(mptokenID))
{
if (view.rules().enabled(featureMPTokensV2))
{
if ((*sle)[sfMPTAmount] > (std::numeric_limits<std::uint64_t>::max() - amt))
{
return tecINTERNAL; // LCOV_EXCL_LINE
}
}
view.creditHookMPT(uSenderID, uReceiverID, saAmount, (*sle)[sfMPTAmount], available);
(*sle)[sfMPTAmount] += amt;
view.update(sle);
@@ -1185,9 +1225,9 @@ directSendNoLimitMultiMPT(
// Use uint64_t, not STAmount, to keep MaximumAmount comparisons in exact
// integer arithmetic. STAmount implicitly converts to Number, whose
// small-scale mantissa (~16 digits) can lose precision for values near
// maxMPTokenAmount (19 digits).
// kMaxMpTokenAmount (19 digits).
std::uint64_t totalSendAmount{0};
std::uint64_t const maximumAmount = sle->at(~sfMaximumAmount).value_or(maxMPTokenAmount);
std::uint64_t const maximumAmount = sle->at(~sfMaximumAmount).value_or(kMaxMpTokenAmount);
std::uint64_t const outstandingAmount = sle->getFieldU64(sfOutstandingAmount);
// actual accumulates the total cost to the sender (includes transfer
@@ -1201,7 +1241,7 @@ directSendNoLimitMultiMPT(
{
STAmount const amount{mptIssue, amt};
if (amount < beast::zero)
if (amount < beast::kZero)
return tecINTERNAL; // LCOV_EXCL_LINE
if (!amount || senderID == receiverID)
@@ -1212,15 +1252,15 @@ directSendNoLimitMultiMPT(
if (senderID == issuer)
{
XRPL_ASSERT_PARTS(
takeFromSender == beast::zero,
takeFromSender == beast::kZero,
"xrpl::directSendNoLimitMultiMPT",
"sender == issuer, takeFromSender == zero");
std::uint64_t const sendAmount = amount.mpt().value();
if (view.rules().enabled(fixSecurity3_1_3))
if (view.rules().enabled(fixCleanup3_1_3))
{
// Post-fixSecurity3_1_3: aggregate MaximumAmount
// Post-fixCleanup3_1_3: aggregate MaximumAmount
// check. WARNING: the order of conditions is
// critical — each guards the subtraction in the
// next against unsigned underflow. Do not reorder.
@@ -1238,7 +1278,7 @@ directSendNoLimitMultiMPT(
}
else
{
// Pre-fixSecurity3_1_3: per-iteration MaximumAmount
// Pre-fixCleanup3_1_3: per-iteration MaximumAmount
// check. Reads sfOutstandingAmount from a stale
// view.read() snapshot — incorrect for multi-destination
// sends but retained for ledger replay compatibility.
@@ -1294,7 +1334,7 @@ accountSendMPT(
AllowMPTOverflow allowOverflow)
{
XRPL_ASSERT(
saAmount >= beast::zero && saAmount.holds<MPTIssue>(),
saAmount >= beast::kZero && saAmount.holds<MPTIssue>(),
"xrpl::accountSendMPT : minimum amount and MPT");
/* If we aren't sending anything or if the sender is the same as the
@@ -1396,8 +1436,8 @@ transferXRP(
STAmount const& amount,
beast::Journal j)
{
XRPL_ASSERT(from != beast::zero, "xrpl::transferXRP : nonzero from account");
XRPL_ASSERT(to != beast::zero, "xrpl::transferXRP : nonzero to account");
XRPL_ASSERT(from != beast::kZero, "xrpl::transferXRP : nonzero from account");
XRPL_ASSERT(to != beast::kZero, "xrpl::transferXRP : nonzero to account");
XRPL_ASSERT(from != to, "xrpl::transferXRP : sender is not receiver");
XRPL_ASSERT(amount.native(), "xrpl::transferXRP : amount is XRP");

View File

@@ -2,11 +2,16 @@
#include <xrpl/basics/Number.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STNumber.h> // IWYU pragma: keep
#include <cstdint>
#include <memory>
#include <optional>
@@ -70,7 +75,8 @@ assetsToSharesWithdraw(
std::shared_ptr<SLE const> const& vault,
std::shared_ptr<SLE const> const& issuance,
STAmount const& assets,
TruncateShares truncate)
TruncateShares truncate,
WaiveUnrealizedLoss waive)
{
XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesWithdraw : non-negative assets");
XRPL_ASSERT(
@@ -80,13 +86,14 @@ assetsToSharesWithdraw(
return std::nullopt; // LCOV_EXCL_LINE
Number assetTotal = vault->at(sfAssetsTotal);
assetTotal -= vault->at(sfLossUnrealized);
if (waive == WaiveUnrealizedLoss::No)
assetTotal -= vault->at(sfLossUnrealized);
STAmount shares{vault->at(sfShareMPTID)};
if (assetTotal == 0)
return shares;
Number const shareTotal = issuance->at(sfOutstandingAmount);
Number result = (shareTotal * assets) / assetTotal;
if (truncate == TruncateShares::yes)
if (truncate == TruncateShares::Yes)
result = result.truncate();
shares = result;
return shares;
@@ -96,7 +103,8 @@ assetsToSharesWithdraw(
sharesToAssetsWithdraw(
std::shared_ptr<SLE const> const& vault,
std::shared_ptr<SLE const> const& issuance,
STAmount const& shares)
STAmount const& shares,
WaiveUnrealizedLoss waive)
{
XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsWithdraw : non-negative shares");
XRPL_ASSERT(
@@ -106,7 +114,8 @@ sharesToAssetsWithdraw(
return std::nullopt; // LCOV_EXCL_LINE
Number assetTotal = vault->at(sfAssetsTotal);
assetTotal -= vault->at(sfLossUnrealized);
if (waive == WaiveUnrealizedLoss::No)
assetTotal -= vault->at(sfLossUnrealized);
STAmount assets{vault->at(sfAsset)};
if (assetTotal == 0)
return assets;
@@ -115,4 +124,24 @@ sharesToAssetsWithdraw(
return assets;
}
[[nodiscard]] bool
isSoleShareholder(ReadView const& view, AccountID const& account, SLE::const_ref issuance)
{
XRPL_ASSERT(
issuance && issuance->getType() == ltMPTOKEN_ISSUANCE,
"xrpl::isSoleShareholder : valid issuance SLE");
std::uint64_t const outstanding = issuance->at(sfOutstandingAmount);
if (outstanding == 0)
return false;
auto const shareMPTID =
makeMptID(issuance->getFieldU32(sfSequence), issuance->getAccountID(sfIssuer));
auto const sleToken = view.read(keylet::mptoken(shareMPTID, account));
if (!sleToken)
return false; // LCOV_EXCL_LINE
return sleToken->getFieldU64(sfMPTAmount) == outstanding;
}
} // namespace xrpl

View File

@@ -33,7 +33,7 @@
namespace xrpl {
static std::optional<HTTPClientSSLContext> httpClientSSLContext;
static std::optional<HTTPClientSSLContext> gHttpClientSslContext;
void
HTTPClient::initializeSSLContext(
@@ -42,13 +42,13 @@ HTTPClient::initializeSSLContext(
bool sslVerify,
beast::Journal j)
{
httpClientSSLContext.emplace(sslVerifyDir, sslVerifyFile, sslVerify, j);
gHttpClientSslContext.emplace(sslVerifyDir, sslVerifyFile, sslVerify, j);
}
void
HTTPClient::cleanupSSLContext()
{
httpClientSSLContext.reset();
gHttpClientSslContext.reset();
}
//------------------------------------------------------------------------------
@@ -61,18 +61,18 @@ class HTTPClientImp : public std::enable_shared_from_this<HTTPClientImp>, public
{
public:
HTTPClientImp(
boost::asio::io_context& io_context,
boost::asio::io_context& ioContext,
unsigned short const port,
std::size_t maxResponseSize,
beast::Journal& j)
: mSocket(
io_context,
httpClientSSLContext->context()) // NOLINT(bugprone-unchecked-optional-access)
, mResolver(io_context)
, mHeader(maxClientHeaderBytes)
, mPort(port)
: socket_(
ioContext,
gHttpClientSslContext->context()) // NOLINT(bugprone-unchecked-optional-access)
, resolver_(ioContext)
, header_(kMaxClientHeaderBytes)
, port_(port)
, maxResponseSize_(maxResponseSize)
, mDeadline(io_context)
, deadline_(ioContext)
, j_(j)
{
}
@@ -107,11 +107,11 @@ public:
int iStatus,
std::string const& strData)> complete)
{
mSSL = bSSL;
mDeqSites = deqSites;
mBuild = build;
mComplete = complete;
mTimeout = timeout;
ssl_ = bSSL;
deqSites_ = deqSites;
build_ = build;
complete_ = complete;
timeout_ = timeout;
httpsNext();
}
@@ -128,8 +128,8 @@ public:
int iStatus,
std::string const& strData)> complete)
{
mComplete = complete;
mTimeout = timeout;
complete_ = complete;
timeout_ = timeout;
request(
bSSL,
@@ -149,36 +149,36 @@ public:
void
httpsNext()
{
JLOG(j_.trace()) << "Fetch: " << mDeqSites[0];
JLOG(j_.trace()) << "Fetch: " << deqSites_[0];
auto query = std::make_shared<Query>(
mDeqSites[0],
std::to_string(mPort),
deqSites_[0],
std::to_string(port_),
boost::asio::ip::resolver_query_base::numeric_service);
mQuery = query;
query_ = query;
try
{
mDeadline.expires_after(mTimeout);
deadline_.expires_after(timeout_);
}
catch (boost::system::system_error const& e)
{
mShutdown = e.code();
shutdown_ = e.code();
JLOG(j_.trace()) << "expires_after: " << mShutdown.message();
mDeadline.async_wait(
JLOG(j_.trace()) << "expires_after: " << shutdown_.message();
deadline_.async_wait(
std::bind(
&HTTPClientImp::handleDeadline, shared_from_this(), std::placeholders::_1));
}
if (!mShutdown)
if (!shutdown_)
{
JLOG(j_.trace()) << "Resolving: " << mDeqSites[0];
JLOG(j_.trace()) << "Resolving: " << deqSites_[0];
mResolver.async_resolve(
mQuery->host,
mQuery->port,
mQuery->flags,
resolver_.async_resolve(
query_->host,
query_->port,
query_->flags,
std::bind(
&HTTPClientImp::handleResolve,
shared_from_this(),
@@ -186,8 +186,8 @@ public:
std::placeholders::_2));
}
if (mShutdown)
invokeComplete(mShutdown);
if (shutdown_)
invokeComplete(shutdown_);
}
void
@@ -202,7 +202,7 @@ public:
}
else if (ecResult)
{
JLOG(j_.trace()) << "Deadline error: " << mDeqSites[0] << ": " << ecResult.message();
JLOG(j_.trace()) << "Deadline error: " << deqSites_[0] << ": " << ecResult.message();
// Can't do anything sound.
std::abort();
@@ -213,14 +213,14 @@ public:
// Mark us as shutting down.
// XXX Use our own error code.
mShutdown = boost::system::error_code{
shutdown_ = boost::system::error_code{
boost::system::errc::bad_address, boost::system::system_category()};
// Cancel any resolving.
mResolver.cancel();
resolver_.cancel();
// Stop the transaction.
mSocket.async_shutdown(
socket_.asyncShutdown(
std::bind(
&HTTPClientImp::handleShutdown, shared_from_this(), std::placeholders::_1));
}
@@ -231,7 +231,7 @@ public:
{
if (ecResult)
{
JLOG(j_.trace()) << "Shutdown error: " << mDeqSites[0] << ": " << ecResult.message();
JLOG(j_.trace()) << "Shutdown error: " << deqSites_[0] << ": " << ecResult.message();
}
}
@@ -240,27 +240,27 @@ public:
boost::system::error_code const& ecResult,
boost::asio::ip::tcp::resolver::results_type result)
{
if (!mShutdown)
if (!shutdown_)
{
mShutdown = ecResult
shutdown_ = ecResult
? ecResult
// httpClientSSLContext always initialized before use
// gHttpClientSslContext always initialized before use
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
: httpClientSSLContext->preConnectVerify(mSocket.SSLSocket(), mDeqSites[0]);
: gHttpClientSslContext->preConnectVerify(socket_.sslSocket(), deqSites_[0]);
}
if (mShutdown)
if (shutdown_)
{
JLOG(j_.trace()) << "Resolve error: " << mDeqSites[0] << ": " << mShutdown.message();
JLOG(j_.trace()) << "Resolve error: " << deqSites_[0] << ": " << shutdown_.message();
invokeComplete(mShutdown);
invokeComplete(shutdown_);
}
else
{
JLOG(j_.trace()) << "Resolve complete.";
boost::asio::async_connect(
mSocket.lowest_layer(),
socket_.lowestLayer(),
result,
std::bind(
&HTTPClientImp::handleConnect, shared_from_this(), std::placeholders::_1));
@@ -270,36 +270,36 @@ public:
void
handleConnect(boost::system::error_code const& ecResult)
{
if (!mShutdown)
mShutdown = ecResult;
if (!shutdown_)
shutdown_ = ecResult;
if (mShutdown)
if (shutdown_)
{
JLOG(j_.trace()) << "Connect error: " << mShutdown.message();
JLOG(j_.trace()) << "Connect error: " << shutdown_.message();
}
if (!mShutdown)
if (!shutdown_)
{
JLOG(j_.trace()) << "Connected.";
// httpClientSSLContext always initialized before use
// gHttpClientSslContext always initialized before use
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
mShutdown = httpClientSSLContext->postConnectVerify(mSocket.SSLSocket(), mDeqSites[0]);
shutdown_ = gHttpClientSslContext->postConnectVerify(socket_.sslSocket(), deqSites_[0]);
if (mShutdown)
if (shutdown_)
{
JLOG(j_.trace()) << "postConnectVerify: " << mDeqSites[0] << ": "
<< mShutdown.message();
JLOG(j_.trace()) << "postConnectVerify: " << deqSites_[0] << ": "
<< shutdown_.message();
}
}
if (mShutdown)
if (shutdown_)
{
invokeComplete(mShutdown);
invokeComplete(shutdown_);
}
else if (mSSL)
else if (ssl_)
{
mSocket.async_handshake(
socket_.asyncHandshake(
AutoSocket::ssl_socket::client,
std::bind(
&HTTPClientImp::handleRequest, shared_from_this(), std::placeholders::_1));
@@ -313,23 +313,23 @@ public:
void
handleRequest(boost::system::error_code const& ecResult)
{
if (!mShutdown)
mShutdown = ecResult;
if (!shutdown_)
shutdown_ = ecResult;
if (mShutdown)
if (shutdown_)
{
JLOG(j_.trace()) << "Handshake error:" << mShutdown.message();
JLOG(j_.trace()) << "Handshake error:" << shutdown_.message();
invokeComplete(mShutdown);
invokeComplete(shutdown_);
}
else
{
JLOG(j_.trace()) << "Session started.";
mBuild(mRequest, mDeqSites[0]);
build_(request_, deqSites_[0]);
mSocket.async_write(
mRequest,
socket_.asyncWrite(
request_,
std::bind(
&HTTPClientImp::handleWrite,
shared_from_this(),
@@ -339,23 +339,23 @@ public:
}
void
handleWrite(boost::system::error_code const& ecResult, std::size_t bytes_transferred)
handleWrite(boost::system::error_code const& ecResult, std::size_t bytesTransferred)
{
if (!mShutdown)
mShutdown = ecResult;
if (!shutdown_)
shutdown_ = ecResult;
if (mShutdown)
if (shutdown_)
{
JLOG(j_.trace()) << "Write error: " << mShutdown.message();
JLOG(j_.trace()) << "Write error: " << shutdown_.message();
invokeComplete(mShutdown);
invokeComplete(shutdown_);
}
else
{
JLOG(j_.trace()) << "Wrote.";
mSocket.async_read_until(
mHeader,
socket_.asyncReadUntil(
header_,
"\r\n\r\n",
std::bind(
&HTTPClientImp::handleHeader,
@@ -366,20 +366,20 @@ public:
}
void
handleHeader(boost::system::error_code const& ecResult, std::size_t bytes_transferred)
handleHeader(boost::system::error_code const& ecResult, std::size_t bytesTransferred)
{
std::string strHeader{
{std::istreambuf_iterator<char>(&mHeader)}, std::istreambuf_iterator<char>()};
{std::istreambuf_iterator<char>(&header_)}, std::istreambuf_iterator<char>()};
JLOG(j_.trace()) << "Header: \"" << strHeader << "\"";
static boost::regex const reStatus{"\\`HTTP/1\\S+ (\\d{3}) .*\\'"}; // HTTP/1.1 200 OK
static boost::regex const reSize{
static boost::regex const kReStatus{"\\`HTTP/1\\S+ (\\d{3}) .*\\'"}; // HTTP/1.1 200 OK
static boost::regex const kReSize{
"\\`.*\\r\\nContent-Length:\\s+([0-9]+).*\\'", boost::regex::icase};
static boost::regex const reBody{"\\`.*\\r\\n\\r\\n(.*)\\'"};
static boost::regex const kReBody{"\\`.*\\r\\n\\r\\n(.*)\\'"};
boost::smatch smMatch;
// Match status code.
if (!boost::regex_match(strHeader, smMatch, reStatus))
if (!boost::regex_match(strHeader, smMatch, kReStatus))
{
// XXX Use our own error code.
JLOG(j_.trace()) << "No status code";
@@ -389,13 +389,13 @@ public:
return;
}
mStatus = beast::lexicalCastThrow<int>(std::string(smMatch[1]));
status_ = beast::lexicalCastThrow<int>(std::string(smMatch[1]));
if (boost::regex_match(strHeader, smMatch, reBody)) // we got some body
mBody = smMatch[1];
if (boost::regex_match(strHeader, smMatch, kReBody)) // we got some body
body_ = smMatch[1];
std::size_t const responseSize = [&] {
if (boost::regex_match(strHeader, smMatch, reSize))
if (boost::regex_match(strHeader, smMatch, kReSize))
return beast::lexicalCast<std::size_t>(std::string(smMatch[1]), maxResponseSize_);
return maxResponseSize_;
}();
@@ -412,17 +412,17 @@ public:
if (responseSize == 0)
{
// no body wanted or available
invokeComplete(ecResult, mStatus);
invokeComplete(ecResult, status_);
}
else if (mBody.size() >= responseSize)
else if (body_.size() >= responseSize)
{
// we got the whole thing
invokeComplete(ecResult, mStatus, mBody);
invokeComplete(ecResult, status_, body_);
}
else
{
mSocket.async_read(
mResponse.prepare(responseSize - mBody.size()),
socket_.asyncRead(
response_.prepare(responseSize - body_.size()),
boost::asio::transfer_all(),
std::bind(
&HTTPClientImp::handleData,
@@ -433,29 +433,29 @@ public:
}
void
handleData(boost::system::error_code const& ecResult, std::size_t bytes_transferred)
handleData(boost::system::error_code const& ecResult, std::size_t bytesTransferred)
{
if (!mShutdown)
mShutdown = ecResult;
if (!shutdown_)
shutdown_ = ecResult;
if (mShutdown && mShutdown != boost::asio::error::eof)
if (shutdown_ && shutdown_ != boost::asio::error::eof)
{
JLOG(j_.trace()) << "Read error: " << mShutdown.message();
JLOG(j_.trace()) << "Read error: " << shutdown_.message();
invokeComplete(mShutdown);
invokeComplete(shutdown_);
}
else
{
if (mShutdown)
if (shutdown_)
{
JLOG(j_.trace()) << "Complete.";
}
else
{
mResponse.commit(bytes_transferred);
response_.commit(bytesTransferred);
std::string const strBody{
{std::istreambuf_iterator<char>(&mResponse)}, std::istreambuf_iterator<char>()};
invokeComplete(ecResult, mStatus, mBody + strBody);
{std::istreambuf_iterator<char>(&response_)}, std::istreambuf_iterator<char>()};
invokeComplete(ecResult, status_, body_ + strBody);
}
}
}
@@ -470,7 +470,7 @@ public:
boost::system::error_code ecCancel;
try
{
mDeadline.cancel();
deadline_.cancel();
}
catch (boost::system::system_error const& e)
{
@@ -478,24 +478,24 @@ public:
ecCancel = e.code();
}
JLOG(j_.debug()) << "invokeComplete: Deadline popping: " << mDeqSites.size();
JLOG(j_.debug()) << "invokeComplete: Deadline popping: " << deqSites_.size();
if (!mDeqSites.empty())
if (!deqSites_.empty())
{
mDeqSites.pop_front();
deqSites_.pop_front();
}
bool bAgain = true;
if (mDeqSites.empty() || !ecResult)
if (deqSites_.empty() || !ecResult)
{
// ecResult: !0 = had an error, last entry
// iStatus: result, if no error
// strData: data, if no error
bAgain = mComplete && mComplete(ecResult ? ecResult : ecCancel, iStatus, strData);
bAgain = complete_ && complete_(ecResult ? ecResult : ecCancel, iStatus, strData);
}
if (!mDeqSites.empty() && bAgain)
if (!deqSites_.empty() && bAgain)
{
httpsNext();
}
@@ -504,9 +504,9 @@ public:
private:
using pointer = std::shared_ptr<HTTPClient>;
bool mSSL{};
AutoSocket mSocket;
boost::asio::ip::tcp::resolver mResolver;
bool ssl_{};
AutoSocket socket_;
boost::asio::ip::tcp::resolver resolver_;
struct Query
{
@@ -514,27 +514,27 @@ private:
std::string port;
boost::asio::ip::resolver_query_base::flags flags;
};
std::shared_ptr<Query> mQuery;
std::shared_ptr<Query> query_;
boost::asio::streambuf mRequest;
boost::asio::streambuf mHeader;
boost::asio::streambuf mResponse;
std::string mBody;
unsigned short const mPort;
boost::asio::streambuf request_;
boost::asio::streambuf header_;
boost::asio::streambuf response_;
std::string body_;
unsigned short const port_;
std::size_t const maxResponseSize_;
int mStatus{};
std::function<void(boost::asio::streambuf& sb, std::string const& strHost)> mBuild;
int status_{};
std::function<void(boost::asio::streambuf& sb, std::string const& strHost)> build_;
std::function<
bool(boost::system::error_code const& ecResult, int iStatus, std::string const& strData)>
mComplete;
complete_;
boost::asio::basic_waitable_timer<std::chrono::steady_clock> mDeadline;
boost::asio::basic_waitable_timer<std::chrono::steady_clock> deadline_;
// If not success, we are shutting down.
boost::system::error_code mShutdown;
boost::system::error_code shutdown_;
std::deque<std::string> mDeqSites;
std::chrono::seconds mTimeout{};
std::deque<std::string> deqSites_;
std::chrono::seconds timeout_{};
beast::Journal j_;
};
@@ -543,7 +543,7 @@ private:
void
HTTPClient::get(
bool bSSL,
boost::asio::io_context& io_context,
boost::asio::io_context& ioContext,
std::deque<std::string> deqSites,
unsigned short const port,
std::string const& strPath,
@@ -554,14 +554,14 @@ HTTPClient::get(
complete,
beast::Journal& j)
{
auto client = std::make_shared<HTTPClientImp>(io_context, port, responseMax, j);
auto client = std::make_shared<HTTPClientImp>(ioContext, port, responseMax, j);
client->get(bSSL, deqSites, strPath, timeout, complete);
}
void
HTTPClient::get(
bool bSSL,
boost::asio::io_context& io_context,
boost::asio::io_context& ioContext,
std::string strSite,
unsigned short const port,
std::string const& strPath,
@@ -574,14 +574,14 @@ HTTPClient::get(
{
std::deque<std::string> const deqSites(1, strSite);
auto client = std::make_shared<HTTPClientImp>(io_context, port, responseMax, j);
auto client = std::make_shared<HTTPClientImp>(ioContext, port, responseMax, j);
client->get(bSSL, deqSites, strPath, timeout, complete);
}
void
HTTPClient::request(
bool bSSL,
boost::asio::io_context& io_context,
boost::asio::io_context& ioContext,
std::string strSite,
unsigned short const port,
std::function<void(boost::asio::streambuf& sb, std::string const& strHost)> setRequest,
@@ -594,7 +594,7 @@ HTTPClient::request(
{
std::deque<std::string> const deqSites(1, strSite);
auto client = std::make_shared<HTTPClientImp>(io_context, port, responseMax, j);
auto client = std::make_shared<HTTPClientImp>(ioContext, port, responseMax, j);
client->request(bSSL, deqSites, setRequest, timeout, complete);
}

View File

@@ -14,9 +14,9 @@
namespace xrpl::NodeStore {
BatchWriter::BatchWriter(Callback& callback, Scheduler& scheduler)
: m_callback(callback), m_scheduler(scheduler)
: callback_(callback), scheduler_(scheduler)
{
mWriteSet.reserve(batchWritePreallocationSize);
writeSet_.reserve(kBatchWritePreallocationSize);
}
BatchWriter::~BatchWriter()
@@ -27,29 +27,29 @@ BatchWriter::~BatchWriter()
void
BatchWriter::store(std::shared_ptr<NodeObject> const& object)
{
std::unique_lock<decltype(mWriteMutex)> sl(mWriteMutex);
std::unique_lock<decltype(writeMutex_)> sl(writeMutex_);
// If the batch has reached its limit, we wait
// until the batch writer is finished
while (mWriteSet.size() >= batchWriteLimitSize)
mWriteCondition.wait(sl);
while (writeSet_.size() >= kBatchWritePreallocationSize)
writeCondition_.wait(sl);
mWriteSet.push_back(object);
writeSet_.push_back(object);
if (!mWritePending)
if (!writePending_)
{
mWritePending = true;
writePending_ = true;
m_scheduler.scheduleTask(*this);
scheduler_.scheduleTask(*this);
}
}
int
BatchWriter::getWriteLoad()
{
std::lock_guard const sl(mWriteMutex);
std::scoped_lock const sl(writeMutex_);
return std::max(mWriteLoad, static_cast<int>(mWriteSet.size()));
return std::max(writeLoad_, static_cast<int>(writeSet_.size()));
}
void
@@ -65,20 +65,20 @@ BatchWriter::writeBatch()
{
std::vector<std::shared_ptr<NodeObject>> set;
set.reserve(batchWritePreallocationSize);
set.reserve(kBatchWritePreallocationSize);
{
std::lock_guard const sl(mWriteMutex);
std::scoped_lock const sl(writeMutex_);
mWriteSet.swap(set);
writeSet_.swap(set);
XRPL_ASSERT(
mWriteSet.empty(), "xrpl::NodeStore::BatchWriter::writeBatch : writes not set");
mWriteLoad = set.size();
writeSet_.empty(), "xrpl::NodeStore::BatchWriter::writeBatch : writes not set");
writeLoad_ = set.size();
if (set.empty())
{
mWritePending = false;
mWriteCondition.notify_all();
writePending_ = false;
writeCondition_.notify_all();
// VFALCO NOTE Fix this function to not return from the middle
return;
@@ -89,22 +89,22 @@ BatchWriter::writeBatch()
report.writeCount = set.size();
auto const before = std::chrono::steady_clock::now();
m_callback.writeBatch(set);
callback_.writeBatch(set);
report.elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - before);
m_scheduler.onBatchWrite(report);
scheduler_.onBatchWrite(report);
}
}
void
BatchWriter::waitForWriting()
{
std::unique_lock<decltype(mWriteMutex)> sl(mWriteMutex);
std::unique_lock<decltype(writeMutex_)> sl(writeMutex_);
while (mWritePending)
mWriteCondition.wait(sl);
while (writePending_)
writeCondition_.wait(sl);
}
} // namespace xrpl::NodeStore

View File

@@ -38,7 +38,7 @@ Database::Database(
beast::Journal journal)
: j_(journal)
, scheduler_(scheduler)
, earliestLedgerSeq_(get<std::uint32_t>(config, "earliest_seq", XRP_LEDGER_EARLIEST_SEQ))
, earliestLedgerSeq_(get<std::uint32_t>(config, "earliest_seq", kXrpLedgerEarliestSeq))
, requestBundle_(get<int>(config, "rq_bundle", 4))
, readThreads_(std::max(1, readThreads))
{
@@ -95,7 +95,7 @@ Database::Database(
auto const& data = it->second;
auto const seqn = data[0].first;
auto obj = fetchNodeObject(hash, seqn, FetchType::async);
auto obj = fetchNodeObject(hash, seqn, FetchType::Async);
// This could be further optimized: if there are
// multiple requests for sequence numbers mapping to
@@ -107,7 +107,7 @@ Database::Database(
req.second(
(seqn == req.first) || isSameDB(req.first, seqn)
? obj
: fetchNodeObject(hash, req.first, FetchType::async));
: fetchNodeObject(hash, req.first, FetchType::Async));
}
}
@@ -143,7 +143,7 @@ void
Database::stop()
{
{
std::lock_guard const lock(readLock_);
std::scoped_lock const lock(readLock_);
if (!readStopping_.exchange(true, std::memory_order_relaxed))
{
@@ -179,7 +179,7 @@ Database::asyncFetch(
std::uint32_t ledgerSeq,
std::function<void(std::shared_ptr<NodeObject> const&)>&& cb)
{
std::lock_guard const lock(readLock_);
std::scoped_lock const lock(readLock_);
if (!isStopping())
{
@@ -192,7 +192,7 @@ void
Database::importInternal(Backend& dstBackend, Database& srcDB)
{
Batch batch;
batch.reserve(batchWritePreallocationSize);
batch.reserve(kBatchWritePreallocationSize);
auto storeBatch = [&, fname = __func__]() {
try
{
@@ -211,13 +211,13 @@ Database::importInternal(Backend& dstBackend, Database& srcDB)
batch.clear();
};
srcDB.for_each([&](std::shared_ptr<NodeObject> nodeObject) {
srcDB.forEach([&](std::shared_ptr<NodeObject> nodeObject) {
XRPL_ASSERT(nodeObject, "xrpl::NodeStore::Database::importInternal : non-null node");
if (!nodeObject) // This should never happen
return;
batch.emplace_back(std::move(nodeObject));
if (batch.size() >= batchWritePreallocationSize)
if (batch.size() >= kBatchWritePreallocationSize)
storeBatch();
});
@@ -254,13 +254,13 @@ Database::fetchNodeObject(
}
void
Database::getCountsJson(Json::Value& obj)
Database::getCountsJson(json::Value& obj)
{
XRPL_ASSERT(obj.isObject(), "xrpl::NodeStore::Database::getCountsJson : valid input type");
{
std::unique_lock<std::mutex> const lock(readLock_);
obj["read_queue"] = static_cast<Json::UInt>(read_.size());
obj["read_queue"] = static_cast<json::UInt>(read_.size());
}
obj["read_threads_total"] = readThreads_.load();

View File

@@ -4,21 +4,16 @@
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
#include <xrpl/basics/strHex.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/nodestore/Database.h>
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Types.h>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <exception>
#include <functional>
#include <memory>
#include <utility>
#include <vector>
namespace xrpl::NodeStore {
@@ -29,6 +24,13 @@ DatabaseNodeImp::store(NodeObjectType type, Blob&& data, uint256 const& hash, st
auto obj = NodeObject::createObject(type, std::move(data), hash);
backend_->store(obj);
if (cache_)
{
// After the store, replace a negative cache entry if there is one
cache_->canonicalize(hash, obj, [](std::shared_ptr<NodeObject> const& n) {
return n->getType() == NodeObjectType::Dummy;
});
}
}
void
@@ -37,9 +39,25 @@ DatabaseNodeImp::asyncFetch(
std::uint32_t ledgerSeq,
std::function<void(std::shared_ptr<NodeObject> const&)>&& callback)
{
if (cache_)
{
std::shared_ptr<NodeObject> const obj = cache_->fetch(hash);
if (obj)
{
callback(obj->getType() == NodeObjectType::Dummy ? nullptr : obj);
return;
}
}
Database::asyncFetch(hash, ledgerSeq, std::move(callback));
}
void
DatabaseNodeImp::sweep()
{
if (cache_)
cache_->sweep();
}
std::shared_ptr<NodeObject>
DatabaseNodeImp::fetchNodeObject(
uint256 const& hash,
@@ -47,32 +65,58 @@ DatabaseNodeImp::fetchNodeObject(
FetchReport& fetchReport,
bool duplicate)
{
std::shared_ptr<NodeObject> nodeObject = nullptr;
Status status = ok;
std::shared_ptr<NodeObject> nodeObject = cache_ ? cache_->fetch(hash) : nullptr;
if (!nodeObject)
{
JLOG(j_.trace()) << "fetchNodeObject " << hash << ": record not "
<< (cache_ ? "cached" : "found");
try
{
status = backend_->fetch(hash, &nodeObject);
}
catch (std::exception const& e)
{
JLOG(j_.fatal()) << "fetchNodeObject " << hash
<< ": Exception fetching from backend: " << e.what();
Rethrow();
}
Status status = Status::Ok;
try
{
status = backend_->fetch(hash, &nodeObject);
}
catch (std::exception const& e)
{
JLOG(j_.fatal()) << "fetchNodeObject " << hash
<< ": Exception fetching from backend: " << e.what();
rethrow();
}
switch (status)
switch (status)
{
case Status::Ok:
if (cache_)
{
if (nodeObject)
{
cache_->canonicalizeReplaceClient(hash, nodeObject);
}
else
{
auto notFound = NodeObject::createObject(NodeObjectType::Dummy, {}, hash);
cache_->canonicalizeReplaceClient(hash, notFound);
if (notFound->getType() != NodeObjectType::Dummy)
nodeObject = notFound;
}
}
break;
case Status::NotFound:
break;
case Status::DataCorrupt:
JLOG(j_.fatal()) << "fetchNodeObject " << hash << ": nodestore data is corrupted";
break;
default:
JLOG(j_.warn()) << "fetchNodeObject " << hash << ": backend returns unknown result "
<< static_cast<int>(status);
break;
}
}
else
{
case ok:
case notFound:
break;
case dataCorrupt:
JLOG(j_.fatal()) << "fetchNodeObject " << hash << ": nodestore data is corrupted";
break;
default:
JLOG(j_.warn()) << "fetchNodeObject " << hash << ": backend returns unknown result "
<< status;
break;
JLOG(j_.trace()) << "fetchNodeObject " << hash << ": record found in cache";
if (nodeObject->getType() == NodeObjectType::Dummy)
nodeObject.reset();
}
if (nodeObject)
@@ -81,33 +125,4 @@ DatabaseNodeImp::fetchNodeObject(
return nodeObject;
}
std::vector<std::shared_ptr<NodeObject>>
DatabaseNodeImp::fetchBatch(std::vector<uint256> const& hashes)
{
using namespace std::chrono;
auto const before = steady_clock::now();
// Get the node objects that match the hashes from the backend. To protect
// against the backends returning fewer or more results than expected, the
// container is resized to the number of hashes.
auto results = backend_->fetchBatch(hashes).first;
XRPL_ASSERT(
results.size() == hashes.size() || results.empty(),
"number of output objects either matches number of input hashes or is empty");
results.resize(hashes.size());
for (size_t i = 0; i < results.size(); ++i)
{
if (!results[i])
{
JLOG(j_.error()) << "fetchBatch - "
<< "record not found in db. hash = " << strHex(hashes[i]);
}
}
auto fetchDurationUs =
std::chrono::duration_cast<std::chrono::microseconds>(steady_clock::now() - before).count();
updateFetchMetrics(hashes.size(), 0, fetchDurationUs);
return results;
}
} // namespace xrpl::NodeStore

View File

@@ -53,7 +53,7 @@ DatabaseRotatingImp::rotate(
// deleted.
std::shared_ptr<NodeStore::Backend> oldArchiveBackend;
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
archiveBackend_->setDeletePath();
oldArchiveBackend = std::move(archiveBackend_);
@@ -70,14 +70,14 @@ DatabaseRotatingImp::rotate(
std::string
DatabaseRotatingImp::getName() const
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
return writableBackend_->getName();
}
std::int32_t
DatabaseRotatingImp::getWriteLoad() const
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
return writableBackend_->getWriteLoad();
}
@@ -85,7 +85,7 @@ void
DatabaseRotatingImp::importDatabase(Database& source)
{
auto const backend = [&] {
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
return writableBackend_;
}();
@@ -95,7 +95,7 @@ DatabaseRotatingImp::importDatabase(Database& source)
void
DatabaseRotatingImp::sync()
{
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
writableBackend_->sync();
}
@@ -105,7 +105,7 @@ DatabaseRotatingImp::store(NodeObjectType type, Blob&& data, uint256 const& hash
auto nObj = NodeObject::createObject(type, std::move(data), hash);
auto const backend = [&] {
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
return writableBackend_;
}();
@@ -113,6 +113,12 @@ DatabaseRotatingImp::store(NodeObjectType type, Blob&& data, uint256 const& hash
storeStats(1, nObj->getData().size());
}
void
DatabaseRotatingImp::sweep()
{
// Nothing to do.
}
std::shared_ptr<NodeObject>
DatabaseRotatingImp::fetchNodeObject(
uint256 const& hash,
@@ -121,7 +127,7 @@ DatabaseRotatingImp::fetchNodeObject(
bool duplicate)
{
auto fetch = [&](std::shared_ptr<Backend> const& backend) {
Status status = ok;
Status status = Status::Ok;
std::shared_ptr<NodeObject> nodeObject;
try
{
@@ -130,19 +136,19 @@ DatabaseRotatingImp::fetchNodeObject(
catch (std::exception const& e)
{
JLOG(j_.fatal()) << "Exception, " << e.what();
Rethrow();
rethrow();
}
switch (status)
{
case ok:
case notFound:
case Status::Ok:
case Status::NotFound:
break;
case dataCorrupt:
case Status::DataCorrupt:
JLOG(j_.fatal()) << "Corrupt NodeObject #" << hash;
break;
default:
JLOG(j_.warn()) << "Unknown status=" << status;
JLOG(j_.warn()) << "Unknown status=" << static_cast<int>(status);
break;
}
@@ -153,7 +159,7 @@ DatabaseRotatingImp::fetchNodeObject(
std::shared_ptr<NodeObject> nodeObject;
auto [writable, archive] = [&] {
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
return std::make_pair(writableBackend_, archiveBackend_);
}();
@@ -167,7 +173,7 @@ DatabaseRotatingImp::fetchNodeObject(
{
{
// Refresh the writable backend pointer
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
writable = writableBackend_;
}
@@ -184,18 +190,18 @@ DatabaseRotatingImp::fetchNodeObject(
}
void
DatabaseRotatingImp::for_each(std::function<void(std::shared_ptr<NodeObject>)> f)
DatabaseRotatingImp::forEach(std::function<void(std::shared_ptr<NodeObject>)> f)
{
auto [writable, archive] = [&] {
std::lock_guard const lock(mutex_);
std::scoped_lock const lock(mutex_);
return std::make_pair(writableBackend_, archiveBackend_);
}();
// Iterate the writable backend
writable->for_each(f);
writable->forEach(f);
// Iterate the archive backend
archive->for_each(f);
archive->forEach(f);
}
} // namespace xrpl::NodeStore

View File

@@ -23,34 +23,34 @@ DecodedBlob::DecodedBlob(void const* key, void const* value, int valueBytes)
9...end The body of the object data
*/
m_success = false;
m_key = key;
m_objectType = hotUNKNOWN;
m_objectData = nullptr;
m_dataBytes = std::max(0, valueBytes - 9);
success_ = false;
key_ = key;
objectType_ = NodeObjectType::Unknown;
objectData_ = nullptr;
dataBytes_ = std::max(0, valueBytes - 9);
// VFALCO NOTE What about bytes 4 through 7 inclusive?
if (valueBytes > 8)
{
unsigned char const* byte = static_cast<unsigned char const*>(value);
m_objectType = safe_cast<NodeObjectType>(byte[8]);
objectType_ = safeCast<NodeObjectType>(byte[8]);
}
if (valueBytes > 9)
{
m_objectData = static_cast<unsigned char const*>(value) + 9;
objectData_ = static_cast<unsigned char const*>(value) + 9;
switch (m_objectType)
switch (objectType_)
{
default:
break;
case hotUNKNOWN:
case hotLEDGER:
case hotACCOUNT_NODE:
case hotTRANSACTION_NODE:
m_success = true;
case NodeObjectType::Unknown:
case NodeObjectType::Ledger:
case NodeObjectType::AccountNode:
case NodeObjectType::TransactionNode:
success_ = true;
break;
}
}
@@ -59,15 +59,15 @@ DecodedBlob::DecodedBlob(void const* key, void const* value, int valueBytes)
std::shared_ptr<NodeObject>
DecodedBlob::createObject()
{
XRPL_ASSERT(m_success, "xrpl::NodeStore::DecodedBlob::createObject : valid object type");
XRPL_ASSERT(success_, "xrpl::NodeStore::DecodedBlob::createObject : valid object type");
std::shared_ptr<NodeObject> object;
if (m_success)
if (success_)
{
Blob data(m_objectData, m_objectData + m_dataBytes);
Blob data(objectData_, objectData_ + dataBytes_);
object = NodeObject::createObject(m_objectType, std::move(data), uint256::fromVoid(m_key));
object = NodeObject::createObject(objectType_, std::move(data), uint256::fromVoid(key_));
}
return object;

View File

@@ -26,12 +26,12 @@ namespace xrpl::NodeStore {
ManagerImp&
ManagerImp::instance()
{
static ManagerImp _;
return _;
static ManagerImp kInst;
return kInst;
}
void
ManagerImp::missing_backend()
ManagerImp::missingBackend()
{
Throw<std::runtime_error>(
"Your xrpld.cfg is missing a [node_db] entry, "
@@ -60,7 +60,7 @@ ManagerImp::ManagerImp()
}
std::unique_ptr<Backend>
ManagerImp::make_Backend(
ManagerImp::makeBackend(
Section const& parameters,
std::size_t burstSize,
Scheduler& scheduler,
@@ -68,26 +68,27 @@ ManagerImp::make_Backend(
{
std::string const type{get(parameters, "type")};
if (type.empty())
missing_backend();
missingBackend();
auto factory{find(type)};
if (factory == nullptr)
{
missing_backend();
missingBackend();
}
return factory->createInstance(NodeObject::keyBytes, parameters, burstSize, scheduler, journal);
return factory->createInstance(
NodeObject::kKeyBytes, parameters, burstSize, scheduler, journal);
}
std::unique_ptr<Database>
ManagerImp::make_Database(
ManagerImp::makeDatabase(
std::size_t burstSize,
Scheduler& scheduler,
int readThreads,
Section const& config,
beast::Journal journal)
{
auto backend{make_Backend(config, burstSize, scheduler, journal)};
auto backend{makeBackend(config, burstSize, scheduler, journal)};
backend->open();
return std::make_unique<DatabaseNodeImp>(
scheduler, readThreads, std::move(backend), config, journal);
@@ -96,14 +97,14 @@ ManagerImp::make_Database(
void
ManagerImp::insert(Factory& factory)
{
std::lock_guard const _(mutex_);
std::scoped_lock const _(mutex_);
list_.push_back(&factory);
}
void
ManagerImp::erase(Factory& factory)
{
std::lock_guard const _(mutex_);
std::scoped_lock const _(mutex_);
auto const iter =
std::ranges::find_if(list_, [&factory](Factory* other) { return other == &factory; });
XRPL_ASSERT(iter != list_.end(), "xrpl::NodeStore::ManagerImp::erase : valid input");
@@ -113,7 +114,7 @@ ManagerImp::erase(Factory& factory)
Factory*
ManagerImp::find(std::string const& name)
{
std::lock_guard const _(mutex_);
std::scoped_lock const _(mutex_);
auto const iter = std::ranges::find_if(
list_, [&name](Factory* other) { return boost::iequals(name, other->getName()); });
if (iter == list_.end())

View File

@@ -11,7 +11,7 @@ namespace xrpl {
//------------------------------------------------------------------------------
NodeObject::NodeObject(NodeObjectType type, Blob&& data, uint256 const& hash, PrivateAccess)
: mType(type), mHash(hash), mData(std::move(data))
: type_(type), hash_(hash), data_(std::move(data))
{
}
@@ -24,19 +24,19 @@ NodeObject::createObject(NodeObjectType type, Blob&& data, uint256 const& hash)
NodeObjectType
NodeObject::getType() const
{
return mType;
return type_;
}
uint256 const&
NodeObject::getHash() const
{
return mHash;
return hash_;
}
Blob const&
NodeObject::getData() const
{
return mData;
return data_;
}
} // namespace xrpl

View File

@@ -22,7 +22,6 @@
#include <string>
#include <tuple>
#include <utility>
#include <vector>
namespace xrpl::NodeStore {
@@ -59,7 +58,7 @@ public:
MemoryDB&
open(std::string const& path)
{
std::lock_guard const _(mutex_);
std::scoped_lock const _(mutex_);
auto const result =
map_.emplace(std::piecewise_construct, std::make_tuple(path), std::make_tuple());
MemoryDB& db = result.first->second;
@@ -69,13 +68,13 @@ public:
}
};
MemoryFactory* memoryFactory = nullptr;
MemoryFactory* gMemoryFactory = nullptr;
void
registerMemoryFactory(Manager& manager)
{
static MemoryFactory instance{manager};
memoryFactory = &instance;
static MemoryFactory kInstance{manager};
gMemoryFactory = &kInstance;
}
//------------------------------------------------------------------------------
@@ -112,7 +111,7 @@ public:
void
open(bool) override
{
db_ = &memoryFactory->open(name_);
db_ = &gMemoryFactory->open(name_);
}
bool
@@ -134,45 +133,23 @@ public:
{
XRPL_ASSERT(db_, "xrpl::NodeStore::MemoryBackend::fetch : non-null database");
std::lock_guard const _(db_->mutex);
std::scoped_lock const _(db_->mutex);
Map::iterator const iter = db_->table.find(hash);
if (iter == db_->table.end())
{
pObject->reset();
return notFound;
return Status::NotFound;
}
*pObject = iter->second;
return ok;
}
std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
fetchBatch(std::vector<uint256> const& hashes) override
{
std::vector<std::shared_ptr<NodeObject>> results;
results.reserve(hashes.size());
for (auto const& h : hashes)
{
std::shared_ptr<NodeObject> nObj;
Status const status = fetch(h, &nObj);
if (status != ok)
{
results.push_back({});
}
else
{
results.push_back(nObj);
}
}
return {results, ok};
return Status::Ok;
}
void
store(std::shared_ptr<NodeObject> const& object) override
{
XRPL_ASSERT(db_, "xrpl::NodeStore::MemoryBackend::store : non-null database");
std::lock_guard const _(db_->mutex);
std::scoped_lock const _(db_->mutex);
db_->table.emplace(object->getHash(), object);
}
@@ -189,9 +166,9 @@ public:
}
void
for_each(std::function<void(std::shared_ptr<NodeObject>)> f) override
forEach(std::function<void(std::shared_ptr<NodeObject>)> f) override
{
XRPL_ASSERT(db_, "xrpl::NodeStore::MemoryBackend::for_each : non-null database");
XRPL_ASSERT(db_, "xrpl::NodeStore::MemoryBackend::forEach : non-null database");
for (auto const& e : db_->table)
f(e.second);
}

View File

@@ -42,7 +42,6 @@
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
namespace xrpl::NodeStore {
@@ -53,16 +52,16 @@ public:
// NuDB database. We used it to identify shard databases before that code
// was removed. For now, its only use is a sanity check that the database
// was created by xrpld.
static constexpr std::uint64_t appnum = 1;
static constexpr std::uint64_t kAppNum = 1;
beast::Journal const j_;
size_t const keyBytes_;
std::size_t const burstSize_;
std::string const name_;
std::size_t const blockSize_;
nudb::store db_;
std::atomic<bool> deletePath_;
Scheduler& scheduler_;
beast::Journal const j;
size_t const keyBytes;
std::size_t const burstSize;
std::string const name;
std::size_t const blockSize;
nudb::store db;
std::atomic<bool> deletePath;
Scheduler& scheduler;
NuDBBackend(
size_t keyBytes,
@@ -70,15 +69,15 @@ public:
std::size_t burstSize,
Scheduler& scheduler,
beast::Journal journal)
: j_(journal)
, keyBytes_(keyBytes)
, burstSize_(burstSize)
, name_(get(keyValues, "path"))
, blockSize_(parseBlockSize(name_, keyValues, journal))
, deletePath_(false)
, scheduler_(scheduler)
: j(journal)
, keyBytes(keyBytes)
, burstSize(burstSize)
, name(get(keyValues, "path"))
, blockSize(parseBlockSize(name, keyValues, journal))
, deletePath(false)
, scheduler(scheduler)
{
if (name_.empty())
if (name.empty())
Throw<std::runtime_error>("nodestore: Missing path in NuDB backend");
}
@@ -89,16 +88,16 @@ public:
Scheduler& scheduler,
nudb::context& context,
beast::Journal journal)
: j_(journal)
, keyBytes_(keyBytes)
, burstSize_(burstSize)
, name_(get(keyValues, "path"))
, blockSize_(parseBlockSize(name_, keyValues, journal))
, db_(context)
, deletePath_(false)
, scheduler_(scheduler)
: j(journal)
, keyBytes(keyBytes)
, burstSize(burstSize)
, name(get(keyValues, "path"))
, blockSize(parseBlockSize(name, keyValues, journal))
, db(context)
, deletePath(false)
, scheduler(scheduler)
{
if (name_.empty())
if (name.empty())
Throw<std::runtime_error>("nodestore: Missing path in NuDB backend");
}
@@ -119,30 +118,30 @@ public:
std::string
getName() override
{
return name_;
return name;
}
[[nodiscard]] std::optional<std::size_t>
getBlockSize() const override
{
return blockSize_;
return blockSize;
}
void
open(bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt) override
{
using namespace boost::filesystem;
if (db_.is_open())
if (db.is_open())
{
// LCOV_EXCL_START
UNREACHABLE(
"xrpl::NodeStore::NuDBBackend::open : database is already "
"open");
JLOG(j_.error()) << "database is already open";
JLOG(j.error()) << "database is already open";
return;
// LCOV_EXCL_STOP
}
auto const folder = path(name_);
auto const folder = path(name);
auto const dp = (folder / "nudb.dat").string();
auto const kp = (folder / "nudb.key").string();
auto const lp = (folder / "nudb.log").string();
@@ -151,54 +150,54 @@ public:
{
create_directories(folder);
nudb::create<nudb::xxhasher>(
dp, kp, lp, appType, uid, salt, keyBytes_, blockSize_, 0.50, ec);
dp, kp, lp, appType, uid, salt, keyBytes, blockSize, 0.50, ec);
if (ec == nudb::errc::file_exists)
ec = {};
if (ec)
Throw<nudb::system_error>(ec);
}
db_.open(dp, kp, lp, ec);
db.open(dp, kp, lp, ec);
if (ec)
Throw<nudb::system_error>(ec);
if (db_.appnum() != appnum)
if (db.appnum() != kAppNum)
Throw<std::runtime_error>("nodestore: unknown appnum");
db_.set_burst(burstSize_);
db.set_burst(burstSize);
}
bool
isOpen() override
{
return db_.is_open();
return db.is_open();
}
void
open(bool createIfMissing) override
{
open(createIfMissing, appnum, nudb::make_uid(), nudb::make_salt());
open(createIfMissing, kAppNum, nudb::make_uid(), nudb::make_salt());
}
void
close() override
{
if (db_.is_open())
if (db.is_open())
{
nudb::error_code ec;
db_.close(ec);
db.close(ec);
if (ec)
{
// Log to make sure the nature of the error gets to the user.
JLOG(j_.fatal()) << "NuBD close() failed: " << ec.message();
JLOG(j.fatal()) << "NuBD close() failed: " << ec.message();
Throw<nudb::system_error>(ec);
}
if (deletePath_)
if (deletePath)
{
boost::filesystem::remove_all(name_, ec);
boost::filesystem::remove_all(name, ec);
if (ec)
{
JLOG(j_.fatal())
<< "Filesystem remove_all of " << name_ << " failed with: " << ec.message();
JLOG(j.fatal())
<< "Filesystem remove_all of " << name << " failed with: " << ec.message();
}
}
}
@@ -207,61 +206,39 @@ public:
Status
fetch(uint256 const& hash, std::shared_ptr<NodeObject>* pno) override
{
Status status = ok;
Status status = Status::Ok;
pno->reset();
nudb::error_code ec;
db_.fetch(
db.fetch(
hash.data(),
[&hash, pno, &status](void const* data, std::size_t size) {
nudb::detail::buffer bf;
auto const result = nodeobject_decompress(data, size, bf);
auto const result = nodeobjectDecompress(data, size, bf);
DecodedBlob decoded(hash.data(), result.first, result.second);
if (!decoded.wasOk())
{
status = dataCorrupt;
status = Status::DataCorrupt;
return;
}
*pno = decoded.createObject();
status = ok;
status = Status::Ok;
},
ec);
if (ec == nudb::error::key_not_found)
return notFound;
return Status::NotFound;
if (ec)
Throw<nudb::system_error>(ec);
return status;
}
std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
fetchBatch(std::vector<uint256> const& hashes) override
{
std::vector<std::shared_ptr<NodeObject>> results;
results.reserve(hashes.size());
for (auto const& h : hashes)
{
std::shared_ptr<NodeObject> nObj;
Status const status = fetch(h, &nObj);
if (status != ok)
{
results.push_back({});
}
else
{
results.push_back(nObj);
}
}
return {results, ok};
}
void
do_insert(std::shared_ptr<NodeObject> const& no)
doInsert(std::shared_ptr<NodeObject> const& no)
{
EncodedBlob const e(no);
nudb::error_code ec;
nudb::detail::buffer bf;
auto const result = nodeobject_compress(e.getData(), e.getSize(), bf);
db_.insert(e.getKey(), result.first, result.second, ec);
auto const result = nodeobjectCompress(e.getData(), e.getSize(), bf);
db.insert(e.getKey(), result.first, result.second, ec);
if (ec && ec != nudb::error::key_exists)
Throw<nudb::system_error>(ec);
}
@@ -272,10 +249,10 @@ public:
BatchWriteReport report{};
report.writeCount = 1;
auto const start = std::chrono::steady_clock::now();
do_insert(no);
doInsert(no);
report.elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start);
scheduler_.onBatchWrite(report);
scheduler.onBatchWrite(report);
}
void
@@ -285,10 +262,10 @@ public:
report.writeCount = batch.size();
auto const start = std::chrono::steady_clock::now();
for (auto const& e : batch)
do_insert(e);
doInsert(e);
report.elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start);
scheduler_.onBatchWrite(report);
scheduler.onBatchWrite(report);
}
void
@@ -297,25 +274,25 @@ public:
}
void
for_each(std::function<void(std::shared_ptr<NodeObject>)> f) override
forEach(std::function<void(std::shared_ptr<NodeObject>)> f) override
{
auto const dp = db_.dat_path();
auto const kp = db_.key_path();
auto const lp = db_.log_path();
auto const dp = db.dat_path();
auto const kp = db.key_path();
auto const lp = db.log_path();
// auto const appnum = db_.appnum();
nudb::error_code ec;
db_.close(ec);
db.close(ec);
if (ec)
Throw<nudb::system_error>(ec);
nudb::visit(
dp,
[&](void const* key,
std::size_t key_bytes,
std::size_t keyBytes,
void const* data,
std::size_t size,
nudb::error_code&) {
nudb::detail::buffer bf;
auto const result = nodeobject_decompress(data, size, bf);
auto const result = nodeobjectDecompress(data, size, bf);
DecodedBlob decoded(key, result.first, result.second);
if (!decoded.wasOk())
{
@@ -328,7 +305,7 @@ public:
ec);
if (ec)
Throw<nudb::system_error>(ec);
db_.open(dp, kp, lp, ec);
db.open(dp, kp, lp, ec);
if (ec)
Throw<nudb::system_error>(ec);
}
@@ -342,24 +319,24 @@ public:
void
setDeletePath() override
{
deletePath_ = true;
deletePath = true;
}
void
verify() override
{
auto const dp = db_.dat_path();
auto const kp = db_.key_path();
auto const lp = db_.log_path();
auto const dp = db.dat_path();
auto const kp = db.key_path();
auto const lp = db.log_path();
nudb::error_code ec;
db_.close(ec);
db.close(ec);
if (ec)
Throw<nudb::system_error>(ec);
nudb::verify_info vi;
nudb::verify<nudb::xxhasher>(vi, dp, kp, 0, nudb::no_progress{}, ec);
if (ec)
Throw<nudb::system_error>(ec);
db_.open(dp, kp, lp, ec);
db.open(dp, kp, lp, ec);
if (ec)
Throw<nudb::system_error>(ec);
}
@@ -382,7 +359,7 @@ private:
std::size_t const blockSize = defaultSize;
std::string blockSizeStr;
if (!get_if_exists(keyValues, "nudb_block_size", blockSizeStr))
if (!getIfExists(keyValues, "nudb_block_size", blockSizeStr))
{
return blockSize; // Early return with default
}
@@ -460,7 +437,7 @@ public:
void
registerNuDBFactory(Manager& manager)
{
static NuDBFactory const instance{manager};
static NuDBFactory const kInstance{manager};
}
} // namespace xrpl::NodeStore

View File

@@ -12,8 +12,6 @@
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>
namespace xrpl::NodeStore {
@@ -49,13 +47,7 @@ public:
Status
fetch(uint256 const&, std::shared_ptr<NodeObject>*) override
{
return notFound;
}
std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
fetchBatch(std::vector<uint256> const& hashes) override
{
return {};
return Status::NotFound;
}
void
@@ -74,7 +66,7 @@ public:
}
void
for_each(std::function<void(std::shared_ptr<NodeObject>)> f) override
forEach(std::function<void(std::shared_ptr<NodeObject>)> f) override
{
}
@@ -128,7 +120,7 @@ public:
void
registerNullFactory(Manager& manager)
{
static NullFactory const instance{manager};
static NullFactory const kInstance{manager};
}
} // namespace xrpl::NodeStore

View File

@@ -29,8 +29,6 @@
#include <functional>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
#if XRPL_ROCKSDB_AVAILABLE
#include <xrpl/basics/ByteUtilities.h>
@@ -57,7 +55,7 @@ public:
struct ThreadParams
{
ThreadParams(void (*f_)(void*), void* a_) : f(f_), a(a_)
ThreadParams(void (*f)(void*), void* a) : f(f), a(a)
{
}
@@ -66,7 +64,7 @@ public:
};
static void
thread_entry(void* ptr)
threadEntry(void* ptr)
{
ThreadParams const* const p(reinterpret_cast<ThreadParams*>(ptr));
auto const f = p->f;
@@ -74,8 +72,8 @@ public:
void* a(p->a);
delete p;
static std::atomic<std::size_t> n;
std::size_t const id(++n);
static std::atomic<std::size_t> kN;
std::size_t const id(++kN);
beast::setCurrentThreadName("rocksdb #" + std::to_string(id));
f(a);
@@ -85,7 +83,7 @@ public:
StartThread(void (*f)(void*), void* a) override
{
ThreadParams* const p(new ThreadParams(f, a));
EnvWrapper::StartThread(&RocksDBEnv::thread_entry, p);
EnvWrapper::StartThread(&RocksDBEnv::threadEntry, p);
}
};
@@ -94,16 +92,16 @@ public:
class RocksDBBackend : public Backend, public BatchWriter::Callback
{
private:
std::atomic<bool> m_deletePath;
std::atomic<bool> deletePath_;
public:
beast::Journal m_journal;
size_t const m_keyBytes;
BatchWriter m_batch;
std::string m_name;
std::unique_ptr<rocksdb::DB> m_db;
int fdRequired_ = 2048;
rocksdb::Options m_options;
beast::Journal journal;
size_t const keyBytes;
BatchWriter batch;
std::string name;
std::unique_ptr<rocksdb::DB> db;
int fdMinRequired = 2048;
rocksdb::Options options;
RocksDBBackend(
int keyBytes,
@@ -111,90 +109,89 @@ public:
Scheduler& scheduler,
beast::Journal journal,
RocksDBEnv* env)
: m_deletePath(false), m_journal(journal), m_keyBytes(keyBytes), m_batch(*this, scheduler)
: deletePath_(false), journal(journal), keyBytes(keyBytes), batch(*this, scheduler)
{
if (!get_if_exists(keyValues, "path", m_name))
if (!getIfExists(keyValues, "path", name))
Throw<std::runtime_error>("Missing path in RocksDBFactory backend");
rocksdb::BlockBasedTableOptions table_options;
m_options.env = env;
rocksdb::BlockBasedTableOptions tableOptions;
options.env = env;
bool const hard_set = keyValues.exists("hard_set") && get<bool>(keyValues, "hard_set");
bool const hardSet = keyValues.exists("hard_set") && get<bool>(keyValues, "hard_set");
if (keyValues.exists("cache_mb"))
{
auto size = get<int>(keyValues, "cache_mb");
if (!hard_set && size == 256)
if (!hardSet && size == 256)
size = 1024;
table_options.block_cache = rocksdb::NewLRUCache(megabytes(size));
tableOptions.block_cache = rocksdb::NewLRUCache(megabytes(size));
}
if (auto const v = get<int>(keyValues, "filter_bits"))
{
bool const filter_blocks =
bool const filterBlocks =
!keyValues.exists("filter_full") || (get<int>(keyValues, "filter_full") == 0);
table_options.filter_policy.reset(rocksdb::NewBloomFilterPolicy(v, filter_blocks));
tableOptions.filter_policy.reset(rocksdb::NewBloomFilterPolicy(v, filterBlocks));
}
if (get_if_exists(keyValues, "open_files", m_options.max_open_files))
if (getIfExists(keyValues, "open_files", options.max_open_files))
{
if (!hard_set && m_options.max_open_files == 2000)
m_options.max_open_files = 8000;
if (!hardSet && options.max_open_files == 2000)
options.max_open_files = 8000;
fdRequired_ = m_options.max_open_files + 128;
fdMinRequired = options.max_open_files + 128;
}
if (keyValues.exists("file_size_mb"))
{
auto file_size_mb = get<int>(keyValues, "file_size_mb");
auto fileSizeMb = get<int>(keyValues, "file_size_mb");
if (!hard_set && file_size_mb == 8)
file_size_mb = 256;
if (!hardSet && fileSizeMb == 8)
fileSizeMb = 256;
m_options.target_file_size_base = megabytes(file_size_mb);
m_options.max_bytes_for_level_base = 5 * m_options.target_file_size_base;
m_options.write_buffer_size = 2 * m_options.target_file_size_base;
options.target_file_size_base = megabytes(fileSizeMb);
options.max_bytes_for_level_base = 5 * options.target_file_size_base;
options.write_buffer_size = 2 * options.target_file_size_base;
}
get_if_exists(keyValues, "file_size_mult", m_options.target_file_size_multiplier);
getIfExists(keyValues, "file_size_mult", options.target_file_size_multiplier);
if (keyValues.exists("bg_threads"))
{
m_options.env->SetBackgroundThreads(
get<int>(keyValues, "bg_threads"), rocksdb::Env::LOW);
options.env->SetBackgroundThreads(get<int>(keyValues, "bg_threads"), rocksdb::Env::LOW);
}
if (keyValues.exists("high_threads"))
{
auto const highThreads = get<int>(keyValues, "high_threads");
m_options.env->SetBackgroundThreads(highThreads, rocksdb::Env::HIGH);
options.env->SetBackgroundThreads(highThreads, rocksdb::Env::HIGH);
// If we have high-priority threads, presumably we want to
// use them for background flushes
if (highThreads > 0)
m_options.max_background_flushes = highThreads;
options.max_background_flushes = highThreads;
}
m_options.compression = rocksdb::kSnappyCompression;
options.compression = rocksdb::kSnappyCompression;
get_if_exists(keyValues, "block_size", table_options.block_size);
getIfExists(keyValues, "block_size", tableOptions.block_size);
if (keyValues.exists("universal_compaction") &&
(get<int>(keyValues, "universal_compaction") != 0))
{
m_options.compaction_style = rocksdb::kCompactionStyleUniversal;
m_options.min_write_buffer_number_to_merge = 2;
m_options.max_write_buffer_number = 6;
m_options.write_buffer_size = 6 * m_options.target_file_size_base;
options.compaction_style = rocksdb::kCompactionStyleUniversal;
options.min_write_buffer_number_to_merge = 2;
options.max_write_buffer_number = 6;
options.write_buffer_size = 6 * options.target_file_size_base;
}
if (keyValues.exists("bbt_options"))
{
rocksdb::ConfigOptions const config_options;
rocksdb::ConfigOptions const configOptions;
auto const s = rocksdb::GetBlockBasedTableOptionsFromString(
config_options, table_options, get(keyValues, "bbt_options"), &table_options);
configOptions, tableOptions, get(keyValues, "bbt_options"), &tableOptions);
if (!s.ok())
{
Throw<std::runtime_error>(
@@ -202,12 +199,12 @@ public:
}
}
m_options.table_factory.reset(NewBlockBasedTableFactory(table_options));
options.table_factory.reset(NewBlockBasedTableFactory(tableOptions));
if (keyValues.exists("options"))
{
auto const s =
rocksdb::GetOptionsFromString(m_options, get(keyValues, "options"), &m_options);
rocksdb::GetOptionsFromString(options, get(keyValues, "options"), &options);
if (!s.ok())
{
Throw<std::runtime_error>(
@@ -216,10 +213,10 @@ public:
}
std::string s1, s2;
rocksdb::GetStringFromDBOptions(&s1, m_options, "; ");
rocksdb::GetStringFromColumnFamilyOptions(&s2, m_options, "; ");
JLOG(m_journal.debug()) << "RocksDB DBOptions: " << s1;
JLOG(m_journal.debug()) << "RocksDB CFOptions: " << s2;
rocksdb::GetStringFromDBOptions(&s1, options, "; ");
rocksdb::GetStringFromColumnFamilyOptions(&s2, options, "; ");
JLOG(journal.debug()) << "RocksDB DBOptions: " << s1;
JLOG(journal.debug()) << "RocksDB CFOptions: " << s2;
}
~RocksDBBackend() override
@@ -230,42 +227,42 @@ public:
void
open(bool createIfMissing) override
{
if (m_db)
if (db)
{
// LCOV_EXCL_START
UNREACHABLE(
"xrpl::NodeStore::RocksDBBackend::open : database is already "
"open");
JLOG(m_journal.error()) << "database is already open";
JLOG(journal.error()) << "database is already open";
return;
// LCOV_EXCL_STOP
}
rocksdb::DB* db = nullptr;
m_options.create_if_missing = createIfMissing;
rocksdb::Status const status = rocksdb::DB::Open(m_options, m_name, &db);
if (!status.ok() || (db == nullptr))
rocksdb::DB* localDb = nullptr;
options.create_if_missing = createIfMissing;
rocksdb::Status const status = rocksdb::DB::Open(options, name, &localDb);
if (!status.ok() || (localDb == nullptr))
{
Throw<std::runtime_error>(
std::string("Unable to open/create RocksDB: ") + status.ToString());
}
m_db.reset(db);
db.reset(localDb);
}
bool
isOpen() override
{
return static_cast<bool>(m_db);
return static_cast<bool>(db);
}
void
close() override
{
if (m_db)
if (db)
{
m_db.reset();
if (m_deletePath)
db.reset();
if (deletePath_)
{
boost::filesystem::path const dir = m_name;
boost::filesystem::path const dir = name;
boost::filesystem::remove_all(dir);
}
}
@@ -274,7 +271,7 @@ public:
std::string
getName() override
{
return m_name;
return name;
}
//--------------------------------------------------------------------------
@@ -282,17 +279,17 @@ public:
Status
fetch(uint256 const& hash, std::shared_ptr<NodeObject>* pObject) override
{
XRPL_ASSERT(m_db, "xrpl::NodeStore::RocksDBBackend::fetch : non-null database");
XRPL_ASSERT(db, "xrpl::NodeStore::RocksDBBackend::fetch : non-null database");
pObject->reset();
Status status(ok);
Status status = Status::Ok;
rocksdb::ReadOptions const options;
rocksdb::Slice const slice(std::bit_cast<char const*>(hash.data()), m_keyBytes);
rocksdb::Slice const slice(std::bit_cast<char const*>(hash.data()), keyBytes);
std::string string;
rocksdb::Status const getStatus = m_db->Get(options, slice, &string);
rocksdb::Status const getStatus = db->Get(options, slice, &string);
if (getStatus.ok())
{
@@ -306,63 +303,42 @@ public:
{
// Decoding failed, probably corrupted!
//
status = dataCorrupt;
status = Status::DataCorrupt;
}
}
else
{
if (getStatus.IsCorruption())
{
status = dataCorrupt;
status = Status::DataCorrupt;
}
else if (getStatus.IsNotFound())
{
status = notFound;
status = Status::NotFound;
}
else
{
status = Status(customCode + unsafe_cast<int>(getStatus.code()));
status = static_cast<Status>(
static_cast<int>(Status::CustomCode) + unsafeCast<int>(getStatus.code()));
JLOG(m_journal.error()) << getStatus.ToString();
JLOG(journal.error()) << getStatus.ToString();
}
}
return status;
}
std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
fetchBatch(std::vector<uint256> const& hashes) override
{
std::vector<std::shared_ptr<NodeObject>> results;
results.reserve(hashes.size());
for (auto const& h : hashes)
{
std::shared_ptr<NodeObject> nObj;
Status const status = fetch(h, &nObj);
if (status != ok)
{
results.push_back({});
}
else
{
results.push_back(nObj);
}
}
return {results, ok};
}
void
store(std::shared_ptr<NodeObject> const& object) override
{
m_batch.store(object);
batch.store(object);
}
void
storeBatch(Batch const& batch) override
{
XRPL_ASSERT(
m_db,
db,
"xrpl::NodeStore::RocksDBBackend::storeBatch : non-null "
"database");
rocksdb::WriteBatch wb;
@@ -372,13 +348,13 @@ public:
EncodedBlob const encoded(e);
wb.Put(
rocksdb::Slice(std::bit_cast<char const*>(encoded.getKey()), m_keyBytes),
rocksdb::Slice(std::bit_cast<char const*>(encoded.getKey()), keyBytes),
rocksdb::Slice(std::bit_cast<char const*>(encoded.getData()), encoded.getSize()));
}
rocksdb::WriteOptions const options;
auto ret = m_db->Write(options, &wb);
auto ret = db->Write(options, &wb);
if (!ret.ok())
Throw<std::runtime_error>("storeBatch failed: " + ret.ToString());
@@ -390,16 +366,16 @@ public:
}
void
for_each(std::function<void(std::shared_ptr<NodeObject>)> f) override
forEach(std::function<void(std::shared_ptr<NodeObject>)> f) override
{
XRPL_ASSERT(m_db, "xrpl::NodeStore::RocksDBBackend::for_each : non-null database");
XRPL_ASSERT(db, "xrpl::NodeStore::RocksDBBackend::forEach : non-null database");
rocksdb::ReadOptions const options;
std::unique_ptr<rocksdb::Iterator> it(m_db->NewIterator(options));
std::unique_ptr<rocksdb::Iterator> it(db->NewIterator(options));
for (it->SeekToFirst(); it->Valid(); it->Next())
{
if (it->key().size() == m_keyBytes)
if (it->key().size() == keyBytes)
{
DecodedBlob decoded(it->key().data(), it->value().data(), it->value().size());
@@ -410,14 +386,14 @@ public:
else
{
// Uh oh, corrupted data!
JLOG(m_journal.fatal()) << "Corrupt NodeObject #" << it->key().ToString(true);
JLOG(journal.fatal()) << "Corrupt NodeObject #" << it->key().ToString(true);
}
}
else
{
// VFALCO NOTE What does it mean to find an
// incorrectly sized key? Corruption?
JLOG(m_journal.fatal()) << "Bad key size = " << it->key().size();
JLOG(journal.fatal()) << "Bad key size = " << it->key().size();
}
}
}
@@ -425,13 +401,13 @@ public:
int
getWriteLoad() override
{
return m_batch.getWriteLoad();
return batch.getWriteLoad();
}
void
setDeletePath() override
{
m_deletePath = true;
deletePath_ = true;
}
//--------------------------------------------------------------------------
@@ -446,7 +422,7 @@ public:
[[nodiscard]] int
fdRequired() const override
{
return fdRequired_;
return fdMinRequired;
}
};
@@ -458,7 +434,7 @@ private:
Manager& manager_;
public:
RocksDBEnv m_env;
RocksDBEnv env;
RocksDBFactory(Manager& manager) : manager_(manager)
{
@@ -479,14 +455,14 @@ public:
Scheduler& scheduler,
beast::Journal journal) override
{
return std::make_unique<RocksDBBackend>(keyBytes, keyValues, scheduler, journal, &m_env);
return std::make_unique<RocksDBBackend>(keyBytes, keyValues, scheduler, journal, &env);
}
};
void
registerRocksDBFactory(Manager& manager)
{
static RocksDBFactory const instance{manager};
static RocksDBFactory const kInstance{manager};
}
} // namespace xrpl::NodeStore

View File

@@ -29,7 +29,7 @@ Currency
ammLPTCurrency(Asset const& asset1, Asset const& asset2)
{
// AMM LPToken is 0x03 plus 19 bytes of the hash
std::int32_t constexpr AMMCurrencyCode = 0x03;
static constexpr std::int32_t kAmmCurrencyCode = 0x03;
auto const& [minA, maxA] = std::minmax(asset1, asset2);
uint256 const hash = std::visit(
[](auto&& issue1, auto&& issue2) {
@@ -44,7 +44,7 @@ ammLPTCurrency(Asset const& asset1, Asset const& asset2)
minA.value(),
maxA.value());
Currency currency;
*currency.begin() = AMMCurrencyCode;
*currency.begin() = kAmmCurrencyCode;
std::copy(hash.begin(), hash.begin() + currency.size() - 1, currency.begin() + 1);
return currency;
}
@@ -60,7 +60,7 @@ invalidAMMAsset(Asset const& asset, std::optional<std::pair<Asset, Asset>> const
{
auto const err = asset.visit(
[](MPTIssue const& issue) -> std::optional<NotTEC> {
if (issue.getIssuer() == beast::zero)
if (issue.getIssuer() == beast::kZero)
return temBAD_MPT;
return std::nullopt;
},
@@ -101,7 +101,7 @@ invalidAMMAmount(
{
if (auto const res = invalidAMMAsset(amount.asset(), pair))
return res;
if (amount < beast::zero || (!validZero && amount == beast::zero))
if (amount < beast::kZero || (!validZero && amount == beast::kZero))
return temBAD_AMOUNT;
return tesSUCCESS;
}
@@ -112,14 +112,13 @@ ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot)
// It should be impossible for expiration to be < TOTAL_TIME_SLOT_SECS,
// but check just to be safe
auto const expiration = auctionSlot[sfExpiration];
XRPL_ASSERT(
expiration >= TOTAL_TIME_SLOT_SECS, "xrpl::ammAuctionTimeSlot : minimum expiration");
if (expiration >= TOTAL_TIME_SLOT_SECS)
XRPL_ASSERT(expiration >= kTotalTimeSlotSecs, "xrpl::ammAuctionTimeSlot : minimum expiration");
if (expiration >= kTotalTimeSlotSecs)
{
if (auto const start = expiration - TOTAL_TIME_SLOT_SECS; current >= start)
if (auto const start = expiration - kTotalTimeSlotSecs; current >= start)
{
if (auto const diff = current - start; diff < TOTAL_TIME_SLOT_SECS)
return diff / AUCTION_SLOT_INTERVAL_DURATION;
if (auto const diff = current - start; diff < kTotalTimeSlotSecs)
return diff / kAuctionSlotIntervalDuration;
}
}
return std::nullopt;

View File

@@ -35,7 +35,7 @@ private:
std::vector<CachedAccountID> cache_;
// We use a hash function designed to resist algorithmic complexity attacks
hardened_hash<> hasher_;
HardenedHash<> hasher_;
// 64 spinlocks, packed into a single 64-bit value
std::atomic<std::uint64_t> locks_ = 0;
@@ -53,10 +53,10 @@ public:
{
auto const index = hasher_(id) % cache_.size();
packed_spinlock sl(locks_, index % 64);
PackedSpinlock sl(locks_, index % 64);
{
std::lock_guard const lock(sl);
std::scoped_lock const lock(sl);
// The check against the first character of the encoding ensures
// that we don't mishandle the case of the all-zero account:
@@ -69,7 +69,7 @@ public:
XRPL_ASSERT(ret.size() <= 38, "xrpl::detail::AccountIdCache : maximum result size");
{
std::lock_guard const lock(sl);
std::scoped_lock const lock(sl);
cache_[index].id = id;
std::strcpy(cache_[index].encoding, ret.c_str());
}
@@ -80,20 +80,20 @@ public:
} // namespace detail
static std::unique_ptr<detail::AccountIdCache> accountIdCache;
static std::unique_ptr<detail::AccountIdCache> gAccountIdCache;
void
initAccountIdCache(std::size_t count)
{
if (!accountIdCache && count != 0)
accountIdCache = std::make_unique<detail::AccountIdCache>(count);
if (!gAccountIdCache && count != 0)
gAccountIdCache = std::make_unique<detail::AccountIdCache>(count);
}
std::string
toBase58(AccountID const& v)
{
if (accountIdCache)
return accountIdCache->toBase58(v);
if (gAccountIdCache)
return gAccountIdCache->toBase58(v);
return encodeBase58Token(TokenType::AccountID, v.data(), v.size());
}
@@ -103,9 +103,9 @@ std::optional<AccountID>
parseBase58(std::string const& s)
{
auto const result = decodeBase58Token(s, TokenType::AccountID);
if (result.size() != AccountID::bytes)
if (result.size() != AccountID::kBytes)
return std::nullopt;
return AccountID{result};
return AccountID::fromRaw(result);
}
//------------------------------------------------------------------------------
@@ -146,29 +146,29 @@ parseBase58(std::string const& s)
AccountID
calcAccountID(PublicKey const& pk)
{
static_assert(AccountID::bytes == sizeof(ripesha_hasher::result_type));
static_assert(AccountID::kBytes == sizeof(RipeshaHasher::result_type));
ripesha_hasher rsh;
RipeshaHasher rsh;
rsh(pk.data(), pk.size());
return AccountID{static_cast<ripesha_hasher::result_type>(rsh)};
return AccountID::fromRaw(static_cast<RipeshaHasher::result_type>(rsh));
}
AccountID const&
xrpAccount()
{
static AccountID const account(beast::zero);
return account;
static AccountID const kAccount(beast::kZero);
return kAccount;
}
AccountID const&
noAccount()
{
static AccountID const account(1);
return account;
static AccountID const kAccount(1);
return kAccount;
}
bool
to_issuer(AccountID& issuer, std::string const& s)
toIssuer(AccountID& issuer, std::string const& s)
{
if (issuer.parseHex(s))
return true;

View File

@@ -30,7 +30,7 @@ Asset::getText() const
}
void
Asset::setJson(Json::Value& jv) const
Asset::setJson(json::Value& jv) const
{
std::visit([&](auto&& issue) { issue.setJson(jv); }, issue_);
}
@@ -48,7 +48,7 @@ to_string(Asset const& asset)
}
bool
validJSONAsset(Json::Value const& jv)
validJSONAsset(json::Value const& jv)
{
if (jv.isMember(jss::mpt_issuance_id))
return !(jv.isMember(jss::currency) || jv.isMember(jss::issuer));
@@ -56,7 +56,7 @@ validJSONAsset(Json::Value const& jv)
}
Asset
assetFromJson(Json::Value const& v)
assetFromJson(json::Value const& v)
{
if (!v.isMember(jss::currency) && !v.isMember(jss::mpt_issuance_id))
Throw<std::runtime_error>("assetFromJson must contain currency or mpt_issuance_id");

View File

@@ -22,7 +22,8 @@ namespace {
// and follow the format described at http://semver.org/
//------------------------------------------------------------------------------
// clang-format off
char const* const versionString = "3.2.0-b0"
// NOLINTNEXTLINE(readability-identifier-naming)
char const* const versionString = "3.2.0-rc3"
// clang-format on
;
@@ -66,31 +67,31 @@ buildVersionString()
std::string const&
getVersionString()
{
static std::string const value = [] {
static std::string const kValue = [] {
std::string const s = buildVersionString();
beast::SemanticVersion v;
if (!v.parse(s) || v.print() != s)
LogicError(s + ": Bad server version string");
logicError(s + ": Bad server version string");
return s;
}();
return value;
return kValue;
}
std::string const&
getFullVersionString()
{
static std::string const value = systemName() + "-" + getVersionString();
return value;
static std::string const kValue = systemName() + "-" + getVersionString();
return kValue;
}
static constexpr std::uint64_t implementationVersionIdentifier = 0x183B'0000'0000'0000LLU;
static constexpr std::uint64_t implementationVersionIdentifierMask = 0xFFFF'0000'0000'0000LLU;
static constexpr std::uint64_t kImplementationVersionIdentifier = 0x183B'0000'0000'0000LLU;
static constexpr std::uint64_t kImplementationVersionIdentifierMask = 0xFFFF'0000'0000'0000LLU;
std::uint64_t
encodeSoftwareVersion(std::string_view versionStr)
{
std::uint64_t c = implementationVersionIdentifier;
std::uint64_t c = kImplementationVersionIdentifier;
beast::SemanticVersion v;
@@ -154,14 +155,14 @@ encodeSoftwareVersion(std::string_view versionStr)
std::uint64_t
getEncodedVersion()
{
static std::uint64_t const cookie = {encodeSoftwareVersion(getVersionString())};
return cookie;
static std::uint64_t const kCookie = {encodeSoftwareVersion(getVersionString())};
return kCookie;
}
bool
isXrpldVersion(std::uint64_t version)
{
return (version & implementationVersionIdentifierMask) == implementationVersionIdentifier;
return (version & kImplementationVersionIdentifierMask) == kImplementationVersionIdentifier;
}
bool

View File

@@ -30,78 +30,78 @@ namespace detail {
// status code.
// clang-format off
constexpr static ErrorInfo unorderedErrorInfos[]{
{rpcACT_MALFORMED, "actMalformed", "Account malformed."},
{rpcACT_NOT_FOUND, "actNotFound", "Account not found."},
{rpcALREADY_MULTISIG, "alreadyMultisig", "Already multisigned."},
{rpcALREADY_SINGLE_SIG, "alreadySingleSig", "Already single-signed."},
{rpcAMENDMENT_BLOCKED, "amendmentBlocked", "Amendment blocked, need upgrade.", 503},
{rpcEXPIRED_VALIDATOR_LIST, "unlBlocked", "Validator list expired.", 503},
{rpcATX_DEPRECATED, "deprecated", "Use the new API or specify a ledger range.", 400},
{rpcBAD_KEY_TYPE, "badKeyType", "Bad key type.", 400},
{rpcBAD_FEATURE, "badFeature", "Feature unknown or invalid.", 500},
{rpcBAD_ISSUER, "badIssuer", "Issuer account malformed.", 400},
{rpcBAD_MARKET, "badMarket", "No such market.", 404},
{rpcBAD_SECRET, "badSecret", "Secret does not match account.", 403},
{rpcBAD_SEED, "badSeed", "Disallowed seed.", 403},
{rpcBAD_SYNTAX, "badSyntax", "Syntax error.", 400},
{rpcCHANNEL_MALFORMED, "channelMalformed", "Payment channel is malformed.", 400},
{rpcCHANNEL_AMT_MALFORMED, "channelAmtMalformed", "Payment channel amount is malformed.", 400},
{rpcCOMMAND_MISSING, "commandMissing", "Missing command entry.", 400},
{rpcDB_DESERIALIZATION, "dbDeserialization", "Database deserialization error.", 502},
{rpcDST_ACT_MALFORMED, "dstActMalformed", "Destination account is malformed.", 400},
{rpcDST_ACT_MISSING, "dstActMissing", "Destination account not provided.", 400},
{rpcDST_ACT_NOT_FOUND, "dstActNotFound", "Destination account not found.", 404},
{rpcDST_AMT_MALFORMED, "dstAmtMalformed", "Destination amount/currency/issuer is malformed.", 400},
{rpcDST_AMT_MISSING, "dstAmtMissing", "Destination amount/currency/issuer is missing.", 400},
{rpcDST_ISR_MALFORMED, "dstIsrMalformed", "Destination issuer is malformed.", 400},
{rpcEXCESSIVE_LGR_RANGE, "excessiveLgrRange", "Ledger range exceeds 1000.", 400},
{rpcFORBIDDEN, "forbidden", "Bad credentials.", 403},
{rpcHIGH_FEE, "highFee", "Current transaction fee exceeds your limit.", 402},
{rpcINTERNAL, "internal", "Internal error.", 500},
{rpcINVALID_LGR_RANGE, "invalidLgrRange", "Ledger range is invalid.", 400},
{rpcINVALID_PARAMS, "invalidParams", "Invalid parameters.", 400},
{rpcINVALID_HOTWALLET, "invalidHotWallet", "Invalid hotwallet.", 400},
{rpcISSUE_MALFORMED, "issueMalformed", "Issue is malformed.", 400},
{rpcJSON_RPC, "json_rpc", "JSON-RPC transport error.", 500},
{rpcLGR_IDXS_INVALID, "lgrIdxsInvalid", "Ledger indexes invalid.", 400},
{rpcLGR_IDX_MALFORMED, "lgrIdxMalformed", "Ledger index malformed.", 400},
{rpcLGR_NOT_FOUND, "lgrNotFound", "Ledger not found.", 404},
{rpcLGR_NOT_VALIDATED, "lgrNotValidated", "Ledger not validated.", 202},
{rpcMASTER_DISABLED, "masterDisabled", "Master key is disabled.", 403},
{rpcNOT_ENABLED, "notEnabled", "Not enabled in configuration.", 501},
{rpcNOT_IMPL, "notImpl", "Not implemented.", 501},
{rpcNOT_READY, "notReady", "Not ready to handle this request.", 503},
{rpcNOT_SUPPORTED, "notSupported", "Operation not supported.", 501},
{rpcNO_CLOSED, "noClosed", "Closed ledger is unavailable.", 503},
{rpcNO_CURRENT, "noCurrent", "Current ledger is unavailable.", 503},
{rpcNOT_SYNCED, "notSynced", "Not synced to the network.", 503},
{rpcNO_EVENTS, "noEvents", "Current transport does not support events.", 405},
{rpcNO_NETWORK, "noNetwork", "Not synced to the network.", 503},
{rpcWRONG_NETWORK, "wrongNetwork", "Wrong network.", 503},
{rpcNO_PERMISSION, "noPermission", "You don't have permission for this command.", 401},
{rpcNO_PF_REQUEST, "noPathRequest", "No pathfinding request in progress.", 404},
{rpcOBJECT_NOT_FOUND, "objectNotFound", "The requested object was not found.", 404},
{rpcPUBLIC_MALFORMED, "publicMalformed", "Public key is malformed.", 400},
{rpcSENDMAX_MALFORMED, "sendMaxMalformed", "SendMax amount malformed.", 400},
{rpcSIGNING_MALFORMED, "signingMalformed", "Signing of transaction is malformed.", 400},
{rpcSLOW_DOWN, "slowDown", "You are placing too much load on the server.", 429},
{rpcSRC_ACT_MALFORMED, "srcActMalformed", "Source account is malformed.", 400},
{rpcSRC_ACT_MISSING, "srcActMissing", "Source account not provided.", 400},
{rpcSRC_ACT_NOT_FOUND, "srcActNotFound", "Source account not found.", 404},
{rpcDELEGATE_ACT_NOT_FOUND, "delegateActNotFound", "Delegate account not found.", 404},
{rpcSRC_CUR_MALFORMED, "srcCurMalformed", "Source currency is malformed.", 400},
{rpcSRC_ISR_MALFORMED, "srcIsrMalformed", "Source issuer is malformed.", 400},
{rpcSTREAM_MALFORMED, "malformedStream", "Stream malformed.", 400},
{rpcTOO_BUSY, "tooBusy", "The server is too busy to help you now.", 503},
{rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found.", 404},
{rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown method.", 405},
{rpcORACLE_MALFORMED, "oracleMalformed", "Oracle request is malformed.", 400},
{rpcBAD_CREDENTIALS, "badCredentials", "Credentials do not exist, are not accepted, or have expired.", 400},
{rpcTX_SIGNED, "transactionSigned", "Transaction should not be signed.", 400},
{rpcDOMAIN_MALFORMED, "domainMalformed", "Domain is malformed.", 400},
{rpcENTRY_NOT_FOUND, "entryNotFound", "Entry not found.", 400},
{rpcUNEXPECTED_LEDGER_TYPE, "unexpectedLedgerType", "Unexpected ledger type.", 400},
static constexpr ErrorInfo kUnorderedErrorInfos[]{
{RpcActMalformed, "actMalformed", "Account malformed."},
{RpcActNotFound, "actNotFound", "Account not found."},
{RpcAlreadyMultisig, "alreadyMultisig", "Already multisigned."},
{RpcAlreadySingleSig, "alreadySingleSig", "Already single-signed."},
{RpcAmendmentBlocked, "amendmentBlocked", "Amendment blocked, need upgrade.", 503},
{RpcExpiredValidatorList, "unlBlocked", "Validator list expired.", 503},
{RpcAtxDeprecated, "deprecated", "Use the new API or specify a ledger range.", 400},
{RpcBadKeyType, "badKeyType", "Bad key type.", 400},
{RpcBadFeature, "badFeature", "Feature unknown or invalid.", 500},
{RpcBadIssuer, "badIssuer", "Issuer account malformed.", 400},
{RpcBadMarket, "badMarket", "No such market.", 404},
{RpcBadSecret, "badSecret", "Secret does not match account.", 403},
{RpcBadSeed, "badSeed", "Disallowed seed.", 403},
{RpcBadSyntax, "badSyntax", "Syntax error.", 400},
{RpcChannelMalformed, "channelMalformed", "Payment channel is malformed.", 400},
{RpcChannelAmtMalformed, "channelAmtMalformed", "Payment channel amount is malformed.", 400},
{RpcCommandMissing, "commandMissing", "Missing command entry.", 400},
{RpcDbDeserialization, "dbDeserialization", "Database deserialization error.", 502},
{RpcDstActMalformed, "dstActMalformed", "Destination account is malformed.", 400},
{RpcDstActMissing, "dstActMissing", "Destination account not provided.", 400},
{RpcDstActNotFound, "dstActNotFound", "Destination account not found.", 404},
{RpcDstAmtMalformed, "dstAmtMalformed", "Destination amount/currency/issuer is malformed.", 400},
{RpcDstAmtMissing, "dstAmtMissing", "Destination amount/currency/issuer is missing.", 400},
{RpcDstIsrMalformed, "dstIsrMalformed", "Destination issuer is malformed.", 400},
{RpcExcessiveLgrRange, "excessiveLgrRange", "Ledger range exceeds 1000.", 400},
{RpcForbidden, "forbidden", "Bad credentials.", 403},
{RpcHighFee, "highFee", "Current transaction fee exceeds your limit.", 402},
{RpcInternal, "internal", "Internal error.", 500},
{RpcInvalidLgrRange, "invalidLgrRange", "Ledger range is invalid.", 400},
{RpcInvalidParams, "invalidParams", "Invalid parameters.", 400},
{RpcInvalidHotwallet, "invalidHotWallet", "Invalid hotwallet.", 400},
{RpcIssueMalformed, "issueMalformed", "Issue is malformed.", 400},
{RpcJsonRpc, "json_rpc", "JSON-RPC transport error.", 500},
{RpcLgrIdxsInvalid, "lgrIdxsInvalid", "Ledger indexes invalid.", 400},
{RpcLgrIdxMalformed, "lgrIdxMalformed", "Ledger index malformed.", 400},
{RpcLgrNotFound, "lgrNotFound", "Ledger not found.", 404},
{RpcLgrNotValidated, "lgrNotValidated", "Ledger not validated.", 202},
{RpcMasterDisabled, "masterDisabled", "Master key is disabled.", 403},
{RpcNotEnabled, "notEnabled", "Not enabled in configuration.", 501},
{RpcNotImpl, "notImpl", "Not implemented.", 501},
{RpcNotReady, "notReady", "Not ready to handle this request.", 503},
{RpcNotSupported, "notSupported", "Operation not supported.", 501},
{RpcNoClosed, "noClosed", "Closed ledger is unavailable.", 503},
{RpcNoCurrent, "noCurrent", "Current ledger is unavailable.", 503},
{RpcNotSynced, "notSynced", "Not synced to the network.", 503},
{RpcNoEvents, "noEvents", "Current transport does not support events.", 405},
{RpcNoNetwork, "noNetwork", "Not synced to the network.", 503},
{RpcWrongNetwork, "wrongNetwork", "Wrong network.", 503},
{RpcNoPermission, "noPermission", "You don't have permission for this command.", 401},
{RpcNoPfRequest, "noPathRequest", "No pathfinding request in progress.", 404},
{RpcObjectNotFound, "objectNotFound", "The requested object was not found.", 404},
{RpcPublicMalformed, "publicMalformed", "Public key is malformed.", 400},
{RpcSendmaxMalformed, "sendMaxMalformed", "SendMax amount malformed.", 400},
{RpcSigningMalformed, "signingMalformed", "Signing of transaction is malformed.", 400},
{RpcSlowDown, "slowDown", "You are placing too much load on the server.", 429},
{RpcSrcActMalformed, "srcActMalformed", "Source account is malformed.", 400},
{RpcSrcActMissing, "srcActMissing", "Source account not provided.", 400},
{RpcSrcActNotFound, "srcActNotFound", "Source account not found.", 404},
{RpcDelegateActNotFound, "delegateActNotFound", "Delegate account not found.", 404},
{RpcSrcCurMalformed, "srcCurMalformed", "Source currency is malformed.", 400},
{RpcSrcIsrMalformed, "srcIsrMalformed", "Source issuer is malformed.", 400},
{RpcStreamMalformed, "malformedStream", "Stream malformed.", 400},
{RpcTooBusy, "tooBusy", "The server is too busy to help you now.", 503},
{RpcTxnNotFound, "txnNotFound", "Transaction not found.", 404},
{RpcUnknownCommand, "unknownCmd", "Unknown method.", 405},
{RpcOracleMalformed, "oracleMalformed", "Oracle request is malformed.", 400},
{RpcBadCredentials, "badCredentials", "Credentials do not exist, are not accepted, or have expired.", 400},
{RpcTxSigned, "transactionSigned", "Transaction should not be signed.", 400},
{RpcDomainMalformed, "domainMalformed", "Domain is malformed.", 400},
{RpcEntryNotFound, "entryNotFound", "Entry not found.", 400},
{RpcUnexpectedLedgerType, "unexpectedLedgerType", "Unexpected ledger type.", 400},
};
// clang-format on
@@ -115,14 +115,14 @@ sortErrorInfos(ErrorInfo const (&unordered)[N]) -> std::array<ErrorInfo, M>
for (ErrorInfo const& info : unordered)
{
if (info.code <= rpcSUCCESS || info.code > rpcLAST)
if (info.code <= RpcSuccess || info.code > RpcLast)
throw(std::out_of_range("Invalid error_code_i"));
// The first valid code follows rpcSUCCESS immediately.
static_assert(rpcSUCCESS == 0, "Unexpected error_code_i layout.");
static_assert(RpcSuccess == 0, "Unexpected error_code_i layout.");
int const index{info.code - 1};
if (ret[index].code != rpcUNKNOWN)
if (ret[index].code != RpcUnknown)
throw(std::invalid_argument("Duplicate error_code_i in list"));
ret[index] = info;
@@ -134,18 +134,18 @@ sortErrorInfos(ErrorInfo const (&unordered)[N]) -> std::array<ErrorInfo, M>
// It's okay for there to be missing entries; they will contain the code
// rpcUNKNOWN. But other than that all entries should match their index.
int codeCount{0};
int expect{rpcBAD_SYNTAX - 1};
int expect{RpcBadSyntax - 1};
for (ErrorInfo const& info : ret)
{
++expect;
if (info.code == rpcUNKNOWN)
if (info.code == RpcUnknown)
continue;
if (info.code != expect)
throw(std::invalid_argument("Empty error_code_i in list"));
++codeCount;
}
if (expect != rpcLAST)
if (expect != RpcLast)
throw(std::invalid_argument("Insufficient list entries"));
if (codeCount != N)
throw(std::invalid_argument("Bad handling of unorderedErrorInfos"));
@@ -153,74 +153,74 @@ sortErrorInfos(ErrorInfo const (&unordered)[N]) -> std::array<ErrorInfo, M>
return ret;
}
constexpr auto sortedErrorInfos{sortErrorInfos<rpcLAST>(unorderedErrorInfos)};
constexpr auto kSortedErrorInfos{sortErrorInfos<RpcLast>(kUnorderedErrorInfos)};
constexpr ErrorInfo unknownError;
constexpr ErrorInfo kUnknownError;
} // namespace detail
//------------------------------------------------------------------------------
void
inject_error(error_code_i code, Json::Value& json)
injectError(ErrorCodeI code, json::Value& json)
{
ErrorInfo const& info(get_error_info(code));
ErrorInfo const& info(getErrorInfo(code));
json[jss::error] = info.token;
json[jss::error_code] = info.code;
json[jss::error_message] = info.message;
}
void
inject_error(error_code_i code, std::string const& message, Json::Value& json)
injectError(ErrorCodeI code, std::string const& message, json::Value& json)
{
ErrorInfo const& info(get_error_info(code));
ErrorInfo const& info(getErrorInfo(code));
json[jss::error] = info.token;
json[jss::error_code] = info.code;
json[jss::error_message] = message;
}
ErrorInfo const&
get_error_info(error_code_i code)
getErrorInfo(ErrorCodeI code)
{
if (code <= rpcSUCCESS || code > rpcLAST)
return detail::unknownError;
return detail::sortedErrorInfos[code - 1];
if (code <= RpcSuccess || code > RpcLast)
return detail::kUnknownError;
return detail::kSortedErrorInfos[code - 1];
}
Json::Value
make_error(error_code_i code)
json::Value
makeError(ErrorCodeI code)
{
Json::Value json;
inject_error(code, json);
json::Value json;
injectError(code, json);
return json;
}
Json::Value
make_error(error_code_i code, std::string const& message)
json::Value
makeError(ErrorCodeI code, std::string const& message)
{
Json::Value json;
inject_error(code, message, json);
json::Value json;
injectError(code, message, json);
return json;
}
bool
contains_error(Json::Value const& json)
containsError(json::Value const& json)
{
return json.isObject() && json.isMember(jss::error);
}
int
error_code_http_status(error_code_i code)
errorCodeHttpStatus(ErrorCodeI code)
{
return get_error_info(code).http_status;
return getErrorInfo(code).httpStatus;
}
} // namespace RPC
std::string
rpcErrorString(Json::Value const& jv)
rpcErrorString(json::Value const& jv)
{
XRPL_ASSERT(RPC::contains_error(jv), "xrpl::RPC::rpcErrorString : input contains an error");
XRPL_ASSERT(RPC::containsError(jv), "xrpl::RPC::rpcErrorString : input contains an error");
return jv[jss::error].asString() + jv[jss::error_message].asString();
}

View File

@@ -23,6 +23,7 @@
namespace xrpl {
inline std::size_t
// NOLINTNEXTLINE(readability-identifier-naming)
hash_value(xrpl::uint256 const& feature)
{
std::size_t seed = 0;
@@ -34,7 +35,7 @@ hash_value(xrpl::uint256 const& feature)
namespace {
enum class Supported : bool { no = false, yes };
enum class Supported : bool { No = false, Yes };
// *NOTE*
//
@@ -71,45 +72,45 @@ class FeatureCollections
uint256 feature;
Feature() = delete;
explicit Feature(std::string name_, uint256 const& feature_)
: name(std::move(name_)), feature(feature_)
explicit Feature(std::string name, uint256 const& feature)
: name(std::move(name)), feature(feature)
{
}
// These structs are used by the `features` multi_index_container to
// provide access to the features collection by size_t index, string
// name, and uint256 feature identifier
struct byIndex
struct ByIndex
{
};
struct byName
struct ByName
{
};
struct byFeature
struct ByFeature
{
};
};
// Intermediate types to help with readability
template <class tag, typename Type, Type Feature::* PtrToMember>
template <class Tag, typename Type, Type Feature::* PtrToMember>
using feature_hashed_unique = boost::multi_index::hashed_unique<
boost::multi_index::tag<tag>,
boost::multi_index::tag<Tag>,
boost::multi_index::member<Feature, Type, PtrToMember>>;
// Intermediate types to help with readability
using feature_indexing = boost::multi_index::indexed_by<
boost::multi_index::random_access<boost::multi_index::tag<Feature::byIndex>>,
feature_hashed_unique<Feature::byFeature, uint256, &Feature::feature>,
feature_hashed_unique<Feature::byName, std::string, &Feature::name>>;
boost::multi_index::random_access<boost::multi_index::tag<Feature::ByIndex>>,
feature_hashed_unique<Feature::ByFeature, uint256, &Feature::feature>,
feature_hashed_unique<Feature::ByName, std::string, &Feature::name>>;
// This multi_index_container provides access to the features collection by
// name, index, and uint256 feature identifier
boost::multi_index::multi_index_container<Feature, feature_indexing> features;
std::map<std::string, AmendmentSupport> all;
std::map<std::string, VoteBehavior> supported;
std::size_t upVotes = 0;
std::size_t downVotes = 0;
mutable std::atomic<bool> readOnly = false;
boost::multi_index::multi_index_container<Feature, feature_indexing> features_;
std::map<std::string, AmendmentSupport> all_;
std::map<std::string, VoteBehavior> supported_;
std::size_t upVotes_ = 0;
std::size_t downVotes_ = 0;
mutable std::atomic<bool> readOnly_ = false;
// These helper functions provide access to the features collection by name,
// index, and uint256 feature identifier, so the details of
@@ -117,31 +118,31 @@ class FeatureCollections
Feature const&
getByIndex(size_t i) const
{
if (i >= features.size())
LogicError("Invalid FeatureBitset index");
auto const& sequence = features.get<Feature::byIndex>();
if (i >= features_.size())
logicError("Invalid FeatureBitset index");
auto const& sequence = features_.get<Feature::ByIndex>();
return sequence[i];
}
size_t
getIndex(Feature const& feature) const
{
auto const& sequence = features.get<Feature::byIndex>();
auto const it_to = sequence.iterator_to(feature);
return it_to - sequence.begin();
auto const& sequence = features_.get<Feature::ByIndex>();
auto const itTo = sequence.iterator_to(feature);
return itTo - sequence.begin();
}
Feature const*
getByFeature(uint256 const& feature) const
{
auto const& feature_index = features.get<Feature::byFeature>();
auto const feature_it = feature_index.find(feature);
return feature_it == feature_index.end() ? nullptr : &*feature_it;
auto const& featureIndex = features_.get<Feature::ByFeature>();
auto const featureIt = featureIndex.find(feature);
return featureIt == featureIndex.end() ? nullptr : &*featureIt;
}
Feature const*
getByName(std::string const& name) const
{
auto const& name_index = features.get<Feature::byName>();
auto const name_it = name_index.find(name);
return name_it == name_index.end() ? nullptr : &*name_it;
auto const& nameIndex = features_.get<Feature::ByName>();
auto const nameIt = nameIndex.find(name);
return nameIt == nameIndex.end() ? nullptr : &*nameIt;
}
public:
@@ -170,7 +171,7 @@ public:
std::map<std::string, AmendmentSupport> const&
allAmendments() const
{
return all;
return all_;
}
/** Amendments that this server supports.
@@ -179,21 +180,21 @@ public:
std::map<std::string, VoteBehavior> const&
supportedAmendments() const
{
return supported;
return supported_;
}
/** Amendments that this server WON'T vote for by default. */
std::size_t
numDownVotedAmendments() const
{
return downVotes;
return downVotes_;
}
/** Amendments that this server WILL vote for by default. */
std::size_t
numUpVotedAmendments() const
{
return upVotes;
return upVotes_;
}
};
@@ -201,14 +202,14 @@ public:
FeatureCollections::FeatureCollections()
{
features.reserve(xrpl::detail::numFeatures);
features_.reserve(xrpl::detail::kNumFeatures);
}
std::optional<uint256>
FeatureCollections::getRegisteredFeature(std::string const& name) const
{
XRPL_ASSERT(
readOnly.load(), "xrpl::FeatureCollections::getRegisteredFeature : startup completed");
readOnly_.load(), "xrpl::FeatureCollections::getRegisteredFeature : startup completed");
Feature const* feature = getByName(name);
if (feature != nullptr)
return feature->feature;
@@ -219,61 +220,62 @@ void
check(bool condition, char const* logicErrorMessage)
{
if (!condition)
LogicError(logicErrorMessage);
logicError(logicErrorMessage);
}
uint256
FeatureCollections::registerFeature(std::string const& name, Supported support, VoteBehavior vote)
{
check(!readOnly, "Attempting to register a feature after startup.");
check(!readOnly_, "Attempting to register a feature after startup.");
check(
support == Supported::yes || vote == VoteBehavior::DefaultNo,
support == Supported::Yes || vote == VoteBehavior::DefaultNo,
"Invalid feature parameters. Must be supported to be up-voted.");
Feature const* i = getByName(name);
if (i == nullptr)
{
check(features.size() < detail::numFeatures, "More features defined than allocated.");
check(features_.size() < detail::kNumFeatures, "More features defined than allocated.");
auto const f = sha512Half(Slice(name.data(), name.size()));
features.emplace_back(name, f);
features_.emplace_back(name, f);
auto const getAmendmentSupport = [=]() {
if (vote == VoteBehavior::Obsolete)
return AmendmentSupport::Retired;
return support == Supported::yes ? AmendmentSupport::Supported
return support == Supported::Yes ? AmendmentSupport::Supported
: AmendmentSupport::Unsupported;
};
all.emplace(name, getAmendmentSupport());
all_.emplace(name, getAmendmentSupport());
if (support == Supported::yes)
if (support == Supported::Yes)
{
supported.emplace(name, vote);
supported_.emplace(name, vote);
if (vote == VoteBehavior::DefaultYes)
{
++upVotes;
++upVotes_;
}
else
{
++downVotes;
++downVotes_;
}
}
check(upVotes + downVotes == supported.size(), "Feature counting logic broke");
check(supported.size() <= features.size(), "More supported features than defined features");
check(features.size() == all.size(), "The 'all' features list is populated incorrectly");
check(upVotes_ + downVotes_ == supported_.size(), "Feature counting logic broke");
check(
supported_.size() <= features_.size(), "More supported features than defined features");
check(features_.size() == all_.size(), "The 'all' features list is populated incorrectly");
return f;
}
// Each feature should only be registered once
LogicError("Duplicate feature registration");
logicError("Duplicate feature registration");
}
/** Tell FeatureCollections when registration is complete. */
bool
FeatureCollections::registrationIsDone()
{
readOnly = true;
readOnly_ = true;
return true;
}
@@ -281,11 +283,11 @@ size_t
FeatureCollections::featureToBitsetIndex(uint256 const& f) const
{
XRPL_ASSERT(
readOnly.load(), "xrpl::FeatureCollections::featureToBitsetIndex : startup completed");
readOnly_.load(), "xrpl::FeatureCollections::featureToBitsetIndex : startup completed");
Feature const* feature = getByFeature(f);
if (feature == nullptr)
LogicError("Invalid Feature ID");
logicError("Invalid Feature ID");
return getIndex(*feature);
}
@@ -294,7 +296,7 @@ uint256 const&
FeatureCollections::bitsetIndexToFeature(size_t i) const
{
XRPL_ASSERT(
readOnly.load(), "xrpl::FeatureCollections::bitsetIndexToFeature : startup completed");
readOnly_.load(), "xrpl::FeatureCollections::bitsetIndexToFeature : startup completed");
Feature const& feature = getByIndex(i);
return feature.feature;
}
@@ -302,12 +304,12 @@ FeatureCollections::bitsetIndexToFeature(size_t i) const
std::string
FeatureCollections::featureToName(uint256 const& f) const
{
XRPL_ASSERT(readOnly.load(), "xrpl::FeatureCollections::featureToName : startup completed");
XRPL_ASSERT(readOnly_.load(), "xrpl::FeatureCollections::featureToName : startup completed");
Feature const* feature = getByFeature(f);
return (feature != nullptr) ? feature->name : to_string(f);
}
FeatureCollections featureCollections;
FeatureCollections gFeatureCollections;
} // namespace
@@ -315,7 +317,7 @@ FeatureCollections featureCollections;
std::map<std::string, AmendmentSupport> const&
allAmendments()
{
return featureCollections.allAmendments();
return gFeatureCollections.allAmendments();
}
/** Amendments that this server supports.
@@ -324,21 +326,21 @@ allAmendments()
std::map<std::string, VoteBehavior> const&
detail::supportedAmendments()
{
return featureCollections.supportedAmendments();
return gFeatureCollections.supportedAmendments();
}
/** Amendments that this server won't vote for by default. */
std::size_t
detail::numDownVotedAmendments()
{
return featureCollections.numDownVotedAmendments();
return gFeatureCollections.numDownVotedAmendments();
}
/** Amendments that this server will vote for by default. */
std::size_t
detail::numUpVotedAmendments()
{
return featureCollections.numUpVotedAmendments();
return gFeatureCollections.numUpVotedAmendments();
}
//------------------------------------------------------------------------------
@@ -346,13 +348,13 @@ detail::numUpVotedAmendments()
std::optional<uint256>
getRegisteredFeature(std::string const& name)
{
return featureCollections.getRegisteredFeature(name);
return gFeatureCollections.getRegisteredFeature(name);
}
uint256
registerFeature(std::string const& name, Supported support, VoteBehavior vote)
{
return featureCollections.registerFeature(name, support, vote);
return gFeatureCollections.registerFeature(name, support, vote);
}
// Retired features are in the ledger and have no code controlled by the
@@ -360,32 +362,32 @@ registerFeature(std::string const& name, Supported support, VoteBehavior vote)
uint256
retireFeature(std::string const& name)
{
return registerFeature(name, Supported::yes, VoteBehavior::Obsolete);
return registerFeature(name, Supported::Yes, VoteBehavior::Obsolete);
}
/** Tell FeatureCollections when registration is complete. */
bool
registrationIsDone()
{
return featureCollections.registrationIsDone();
return gFeatureCollections.registrationIsDone();
}
size_t
featureToBitsetIndex(uint256 const& f)
{
return featureCollections.featureToBitsetIndex(f);
return gFeatureCollections.featureToBitsetIndex(f);
}
uint256
bitsetIndexToFeature(size_t i)
{
return featureCollections.bitsetIndexToFeature(i);
return gFeatureCollections.bitsetIndexToFeature(i);
}
std::string
featureToName(uint256 const& f)
{
return featureCollections.featureToName(f);
return gFeatureCollections.featureToName(f);
}
// All known amendments must be registered either here or below with the
@@ -443,8 +445,7 @@ enforceValidFeatureName(auto fn) -> char const*
// All of the features should now be registered, since variables in a cpp file
// are initialized from top to bottom.
//
// Use initialization of one final static variable to set
// featureCollections::readOnly.
[[maybe_unused]] static bool const readOnlySet = featureCollections.registrationIsDone();
// Use initialization of one final static variable to set featureCollections::readOnly_.
[[maybe_unused]] static bool const kReadOnlySet = gFeatureCollections.registrationIsDone();
} // namespace xrpl

View File

@@ -23,8 +23,8 @@ namespace {
LocalValue<bool>&
getStaticSTNumberSwitchover()
{
static LocalValue<bool> r{true};
return r;
static LocalValue<bool> kR{true};
return kR;
}
} // namespace
@@ -43,11 +43,11 @@ setSTNumberSwitchover(bool v)
/* The range for the mantissa when normalized */
// log(2^63,10) ~ 18.96
//
static std::int64_t constexpr minMantissa = STAmount::cMinValue;
static std::int64_t constexpr maxMantissa = STAmount::cMaxValue;
static constexpr std::int64_t kMinMantissa = STAmount::kMinValue;
static constexpr std::int64_t kMaxMantissa = STAmount::kMaxValue;
/* The range for the exponent when normalized */
static int constexpr minExponent = STAmount::cMinOffset;
static int constexpr maxExponent = STAmount::cMaxOffset;
static constexpr int kMinExponent = STAmount::kMinOffset;
static constexpr int kMaxExponent = STAmount::kMaxOffset;
IOUAmount
IOUAmount::fromNumber(Number const& number)
@@ -56,14 +56,14 @@ IOUAmount::fromNumber(Number const& number)
// to normalize, which calls fromNumber
IOUAmount result{};
std::tie(result.mantissa_, result.exponent_) =
number.normalizeToRange(minMantissa, maxMantissa);
number.normalizeToRange<kMinMantissa, kMaxMantissa>();
return result;
}
IOUAmount
IOUAmount::minPositiveAmount()
{
return IOUAmount(minMantissa, minExponent);
return IOUAmount(kMinMantissa, kMinExponent);
}
void
@@ -71,7 +71,7 @@ IOUAmount::normalize()
{
if (mantissa_ == 0)
{
*this = beast::zero;
*this = beast::kZero;
return;
}
@@ -79,10 +79,10 @@ IOUAmount::normalize()
{
Number const v{mantissa_, exponent_};
*this = fromNumber(v);
if (exponent_ > maxExponent)
if (exponent_ > kMaxExponent)
Throw<std::overflow_error>("value overflow");
if (exponent_ < minExponent)
*this = beast::zero;
if (exponent_ < kMinExponent)
*this = beast::kZero;
return;
}
@@ -91,28 +91,28 @@ IOUAmount::normalize()
if (negative)
mantissa_ = -mantissa_;
while ((mantissa_ < minMantissa) && (exponent_ > minExponent))
while ((mantissa_ < kMinMantissa) && (exponent_ > kMinExponent))
{
mantissa_ *= 10;
--exponent_;
}
while (mantissa_ > maxMantissa)
while (mantissa_ > kMaxMantissa)
{
if (exponent_ >= maxExponent)
if (exponent_ >= kMaxExponent)
Throw<std::overflow_error>("IOUAmount::normalize");
mantissa_ /= 10;
++exponent_;
}
if ((exponent_ < minExponent) || (mantissa_ < minMantissa))
if ((exponent_ < kMinExponent) || (mantissa_ < kMinMantissa))
{
*this = beast::zero;
*this = beast::kZero;
return;
}
if (exponent_ > maxExponent)
if (exponent_ > kMaxExponent)
Throw<std::overflow_error>("value overflow");
if (negative)
@@ -121,19 +121,19 @@ IOUAmount::normalize()
IOUAmount::IOUAmount(Number const& other) : IOUAmount(fromNumber(other))
{
if (exponent_ > maxExponent)
if (exponent_ > kMaxExponent)
Throw<std::overflow_error>("value overflow");
if (exponent_ < minExponent)
*this = beast::zero;
if (exponent_ < kMinExponent)
*this = beast::kZero;
}
IOUAmount&
IOUAmount::operator+=(IOUAmount const& other)
{
if (other == beast::zero)
if (other == beast::kZero)
return *this;
if (*this == beast::zero)
if (*this == beast::kZero)
{
*this = other;
return *this;
@@ -165,7 +165,7 @@ IOUAmount::operator+=(IOUAmount const& other)
if (mantissa_ >= -10 && mantissa_ <= 10)
{
*this = beast::zero;
*this = beast::kZero;
return *this;
}
@@ -190,7 +190,7 @@ mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU
// A vector with the value 10^index for indexes from 0 to 29
// The largest intermediate value we expect is 2^96, which
// is less than 10^29
static auto const powerTable = [] {
static auto const kPowerTable = [] {
std::vector<uint128_t> result;
result.reserve(30); // 2^96 is largest intermediate result size
uint128_t cur(1);
@@ -204,11 +204,11 @@ mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU
// Return floor(log10(v))
// Note: Returns -1 for v == 0
static auto log10Floor = [](uint128_t const& v) {
static auto kLoG10Floor = [](uint128_t const& v) {
// Find the index of the first element >= the requested element, the
// index is the log of the element in the log table.
auto const l = std::ranges::lower_bound(powerTable, v);
int index = std::distance(powerTable.begin(), l);
auto const l = std::ranges::lower_bound(kPowerTable, v);
int index = std::distance(kPowerTable.begin(), l);
// If we're not equal, subtract to get the floor
if (*l != v)
--index;
@@ -216,14 +216,14 @@ mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU
};
// Return ceil(log10(v))
static auto log10Ceil = [](uint128_t const& v) {
static auto kLoG10Ceil = [](uint128_t const& v) {
// Find the index of the first element >= the requested element, the
// index is the log of the element in the log table.
auto const l = std::ranges::lower_bound(powerTable, v);
return int(std::distance(powerTable.begin(), l));
auto const l = std::ranges::lower_bound(kPowerTable, v);
return int(std::distance(kPowerTable.begin(), l));
};
static auto const fl64 = log10Floor(std::numeric_limits<std::int64_t>::max());
static auto const kFl64 = kLoG10Floor(std::numeric_limits<std::int64_t>::max());
bool const neg = amt.mantissa() < 0;
uint128_t const den128(den);
@@ -244,12 +244,12 @@ mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU
// and (rem/den128) is as large as possible. Scale by multiplying low
// and rem by 10 and subtracting one from the exponent. We could do this
// with a loop, but it's more efficient to use logarithms.
auto const roomToGrow = fl64 - log10Ceil(low);
auto const roomToGrow = kFl64 - kLoG10Ceil(low);
if (roomToGrow > 0)
{
exponent -= roomToGrow;
low *= powerTable[roomToGrow];
rem *= powerTable[roomToGrow];
low *= kPowerTable[roomToGrow];
rem *= kPowerTable[roomToGrow];
}
auto const addRem = rem / den128;
low += addRem;
@@ -261,14 +261,14 @@ mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU
// and adding one to the exponent until the low will fit in the 64-bit
// mantissa. Use logarithms to avoid looping.
bool hasRem = bool(rem);
auto const mustShrink = log10Ceil(low) - fl64;
auto const mustShrink = kLoG10Ceil(low) - kFl64;
if (mustShrink > 0)
{
uint128_t const sav(low);
exponent += mustShrink;
low /= powerTable[mustShrink];
low /= kPowerTable[mustShrink];
if (!hasRem)
hasRem = bool(sav - low * powerTable[mustShrink]);
hasRem = bool(sav - low * kPowerTable[mustShrink]);
}
std::int64_t mantissa = low.convert_to<std::int64_t>();
@@ -297,7 +297,7 @@ mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU
{
if (!result)
{
return IOUAmount(-minMantissa, minExponent);
return IOUAmount(-kMinMantissa, kMinExponent);
}
// This subtraction cannot underflow because `result` is not zero
return IOUAmount(result.mantissa() - 1, result.exponent());

View File

@@ -50,53 +50,52 @@ namespace xrpl {
and marked as [[deprecated]] to prevent accidental reuse.
*/
enum class LedgerNameSpace : std::uint16_t {
ACCOUNT = 'a',
DIR_NODE = 'd',
TRUST_LINE = 'r',
OFFER = 'o',
OWNER_DIR = 'O',
BOOK_DIR = 'B',
SKIP_LIST = 's',
ESCROW = 'u',
AMENDMENTS = 'f',
FEE_SETTINGS = 'e',
TICKET = 'T',
SIGNER_LIST = 'S',
XRP_PAYMENT_CHANNEL = 'x',
CHECK = 'C',
DEPOSIT_PREAUTH = 'p',
DEPOSIT_PREAUTH_CREDENTIALS = 'P',
NEGATIVE_UNL = 'N',
NFTOKEN_OFFER = 'q',
NFTOKEN_BUY_OFFERS = 'h',
NFTOKEN_SELL_OFFERS = 'i',
AMM = 'A',
BRIDGE = 'H',
XCHAIN_CLAIM_ID = 'Q',
XCHAIN_CREATE_ACCOUNT_CLAIM_ID = 'K',
DID = 'I',
ORACLE = 'R',
MPTOKEN_ISSUANCE = '~',
MPTOKEN = 't',
CREDENTIAL = 'D',
PERMISSIONED_DOMAIN = 'm',
DELEGATE = 'E',
VAULT = 'V',
LOAN_BROKER = 'l', // lower-case L
LOAN = 'L',
Account = 'a',
DirNode = 'd',
TrustLine = 'r',
Offer = 'o',
OwnerDir = 'O',
BookDir = 'B',
SkipList = 's',
Escrow = 'u',
Amendments = 'f',
FeeSettings = 'e',
Ticket = 'T',
SignerList = 'S',
XRPPaymentChannel = 'x',
Check = 'C',
DepositPreauth = 'p',
DepositPreauthCredentials = 'P',
NegativeUnl = 'N',
NftokenOffer = 'q',
NftokenBuyOffers = 'h',
NftokenSellOffers = 'i',
Amm = 'A',
Bridge = 'H',
XchainClaimId = 'Q',
XchainCreateAccountClaimId = 'K',
Did = 'I',
Oracle = 'R',
MPTokenIssuance = '~',
MPToken = 't',
Credential = 'D',
PermissionedDomain = 'm',
Delegate = 'E',
Vault = 'V',
LoanBroker = 'l', // lower-case L
Loan = 'L',
// No longer used or supported. Left here to reserve the space
// to avoid accidental reuse.
CONTRACT [[deprecated]] = 'c',
GENERATOR [[deprecated]] = 'g',
NICKNAME [[deprecated]] = 'n',
// No longer used or supported. Left here to reserve the space to avoid accidental reuse.
Contract [[deprecated]] = 'c',
Generator [[deprecated]] = 'g',
Nickname [[deprecated]] = 'n',
};
template <class... Args>
static uint256
indexHash(LedgerNameSpace space, Args const&... args)
{
return sha512Half(safe_cast<std::uint16_t>(space), args...);
return sha512Half(safeCast<std::uint16_t>(space), args...);
}
uint256
@@ -115,21 +114,21 @@ getBookBase(Book const& book)
if constexpr (std::is_same_v<TIn, Issue> && std::is_same_v<TOut, Issue>)
{
return getIndexHash(
LedgerNameSpace::BOOK_DIR, in.currency, out.currency, in.account, out.account);
LedgerNameSpace::BookDir, in.currency, out.currency, in.account, out.account);
}
else if constexpr (std::is_same_v<TIn, Issue> && std::is_same_v<TOut, MPTIssue>)
{
return getIndexHash(
LedgerNameSpace::BOOK_DIR, in.currency, out.getMptID(), in.account);
LedgerNameSpace::BookDir, in.currency, out.getMptID(), in.account);
}
else if constexpr (std::is_same_v<TIn, MPTIssue> && std::is_same_v<TOut, Issue>)
{
return getIndexHash(
LedgerNameSpace::BOOK_DIR, in.getMptID(), out.currency, out.account);
LedgerNameSpace::BookDir, in.getMptID(), out.currency, out.account);
}
else
{
return getIndexHash(LedgerNameSpace::BOOK_DIR, in.getMptID(), out.getMptID());
return getIndexHash(LedgerNameSpace::BookDir, in.getMptID(), out.getMptID());
}
},
book.in.value(),
@@ -144,9 +143,9 @@ getBookBase(Book const& book)
uint256
getQualityNext(uint256 const& uBase)
{
static constexpr uint256 nextQuality(
static constexpr uint256 kNextQuality(
"0000000000000000000000000000000000000000000000010000000000000000");
return uBase + nextQuality;
return uBase + kNextQuality;
}
std::uint64_t
@@ -159,7 +158,7 @@ getQuality(uint256 const& uBase)
uint256
getTicketIndex(AccountID const& account, std::uint32_t ticketSeq)
{
return indexHash(LedgerNameSpace::TICKET, account, ticketSeq);
return indexHash(LedgerNameSpace::Ticket, account, ticketSeq);
}
uint256
@@ -186,7 +185,7 @@ namespace keylet {
Keylet
account(AccountID const& id) noexcept
{
return Keylet{ltACCOUNT_ROOT, indexHash(LedgerNameSpace::ACCOUNT, id)};
return Keylet{ltACCOUNT_ROOT, indexHash(LedgerNameSpace::Account, id)};
}
Keylet
@@ -198,8 +197,8 @@ child(uint256 const& key) noexcept
Keylet const&
skip() noexcept
{
static Keylet const ret{ltLEDGER_HASHES, indexHash(LedgerNameSpace::SKIP_LIST)};
return ret;
static Keylet const kRet{ltLEDGER_HASHES, indexHash(LedgerNameSpace::SkipList)};
return kRet;
}
Keylet
@@ -208,32 +207,32 @@ skip(LedgerIndex ledger) noexcept
return {
ltLEDGER_HASHES,
indexHash(
LedgerNameSpace::SKIP_LIST, std::uint32_t(static_cast<std::uint32_t>(ledger) >> 16))};
LedgerNameSpace::SkipList, std::uint32_t(static_cast<std::uint32_t>(ledger) >> 16))};
}
Keylet const&
amendments() noexcept
{
static Keylet const ret{ltAMENDMENTS, indexHash(LedgerNameSpace::AMENDMENTS)};
return ret;
static Keylet const kRet{ltAMENDMENTS, indexHash(LedgerNameSpace::Amendments)};
return kRet;
}
Keylet const&
fees() noexcept
{
static Keylet const ret{ltFEE_SETTINGS, indexHash(LedgerNameSpace::FEE_SETTINGS)};
return ret;
static Keylet const kRet{ltFEE_SETTINGS, indexHash(LedgerNameSpace::FeeSettings)};
return kRet;
}
Keylet const&
negativeUNL() noexcept
{
static Keylet const ret{ltNEGATIVE_UNL, indexHash(LedgerNameSpace::NEGATIVE_UNL)};
return ret;
static Keylet const kRet{ltNEGATIVE_UNL, indexHash(LedgerNameSpace::NegativeUnl)};
return kRet;
}
Keylet
book_t::operator()(Book const& b) const
BookT::operator()(Book const& b) const
{
return {ltDIR_NODE, getBookBase(b)};
}
@@ -258,13 +257,13 @@ line(AccountID const& id0, AccountID const& id1, Currency const& currency) noexc
return {
ltRIPPLE_STATE,
indexHash(LedgerNameSpace::TRUST_LINE, accounts.first, accounts.second, currency)};
indexHash(LedgerNameSpace::TrustLine, accounts.first, accounts.second, currency)};
}
Keylet
offer(AccountID const& id, std::uint32_t seq) noexcept
{
return {ltOFFER, indexHash(LedgerNameSpace::OFFER, id, seq)};
return {ltOFFER, indexHash(LedgerNameSpace::Offer, id, seq)};
}
Keylet
@@ -286,20 +285,20 @@ quality(Keylet const& k, std::uint64_t q) noexcept
}
Keylet
next_t::operator()(Keylet const& k) const
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)};
}
Keylet
ticket_t::operator()(AccountID const& id, std::uint32_t ticketSeq) const
TicketT::operator()(AccountID const& id, std::uint32_t ticketSeq) const
{
return {ltTICKET, getTicketIndex(id, ticketSeq)};
}
Keylet
ticket_t::operator()(AccountID const& id, SeqProxy ticketSeq) const
TicketT::operator()(AccountID const& id, SeqProxy ticketSeq) const
{
return {ltTICKET, getTicketIndex(id, ticketSeq)};
}
@@ -310,7 +309,7 @@ ticket_t::operator()(AccountID const& id, SeqProxy ticketSeq) const
static Keylet
signers(AccountID const& account, std::uint32_t page) noexcept
{
return {ltSIGNER_LIST, indexHash(LedgerNameSpace::SIGNER_LIST, account, page)};
return {ltSIGNER_LIST, indexHash(LedgerNameSpace::SignerList, account, page)};
}
Keylet
@@ -322,13 +321,13 @@ signers(AccountID const& account) noexcept
Keylet
check(AccountID const& id, std::uint32_t seq) noexcept
{
return {ltCHECK, indexHash(LedgerNameSpace::CHECK, id, seq)};
return {ltCHECK, indexHash(LedgerNameSpace::Check, id, seq)};
}
Keylet
depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept
{
return {ltDEPOSIT_PREAUTH, indexHash(LedgerNameSpace::DEPOSIT_PREAUTH, owner, preauthorized)};
return {ltDEPOSIT_PREAUTH, indexHash(LedgerNameSpace::DepositPreauth, owner, preauthorized)};
}
// Credentials should be sorted here, use credentials::makeSorted
@@ -343,7 +342,7 @@ depositPreauth(
hashes.emplace_back(sha512Half(o.first, o.second));
return {
ltDEPOSIT_PREAUTH, indexHash(LedgerNameSpace::DEPOSIT_PREAUTH_CREDENTIALS, owner, hashes)};
ltDEPOSIT_PREAUTH, indexHash(LedgerNameSpace::DepositPreauthCredentials, owner, hashes)};
}
//------------------------------------------------------------------------------
@@ -357,7 +356,7 @@ unchecked(uint256 const& key) noexcept
Keylet
ownerDir(AccountID const& id) noexcept
{
return {ltDIR_NODE, indexHash(LedgerNameSpace::OWNER_DIR, id)};
return {ltDIR_NODE, indexHash(LedgerNameSpace::OwnerDir, id)};
}
Keylet
@@ -366,33 +365,33 @@ page(uint256 const& key, std::uint64_t index) noexcept
if (index == 0)
return {ltDIR_NODE, key};
return {ltDIR_NODE, indexHash(LedgerNameSpace::DIR_NODE, key, index)};
return {ltDIR_NODE, indexHash(LedgerNameSpace::DirNode, key, index)};
}
Keylet
escrow(AccountID const& src, std::uint32_t seq) noexcept
{
return {ltESCROW, indexHash(LedgerNameSpace::ESCROW, src, seq)};
return {ltESCROW, indexHash(LedgerNameSpace::Escrow, src, seq)};
}
Keylet
payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept
{
return {ltPAYCHAN, indexHash(LedgerNameSpace::XRP_PAYMENT_CHANNEL, src, dst, seq)};
return {ltPAYCHAN, indexHash(LedgerNameSpace::XRPPaymentChannel, src, dst, seq)};
}
Keylet
nftpage_min(AccountID const& owner)
nftpageMin(AccountID const& owner)
{
std::array<std::uint8_t, 32> buf{};
std::memcpy(buf.data(), owner.data(), owner.size());
return {ltNFTOKEN_PAGE, uint256{buf}};
return {ltNFTOKEN_PAGE, uint256::fromRaw(buf)};
}
Keylet
nftpage_max(AccountID const& owner)
nftpageMax(AccountID const& owner)
{
uint256 id = nft::pageMask;
uint256 id = nft::kPageMask;
std::memcpy(id.data(), owner.data(), owner.size());
return {ltNFTOKEN_PAGE, id};
}
@@ -401,25 +400,25 @@ Keylet
nftpage(Keylet const& k, uint256 const& token)
{
XRPL_ASSERT(k.type == ltNFTOKEN_PAGE, "xrpl::keylet::nftpage : valid input type");
return {ltNFTOKEN_PAGE, (k.key & ~nft::pageMask) + (token & nft::pageMask)};
return {ltNFTOKEN_PAGE, (k.key & ~nft::kPageMask) + (token & nft::kPageMask)};
}
Keylet
nftoffer(AccountID const& owner, std::uint32_t seq)
{
return {ltNFTOKEN_OFFER, indexHash(LedgerNameSpace::NFTOKEN_OFFER, owner, seq)};
return {ltNFTOKEN_OFFER, indexHash(LedgerNameSpace::NftokenOffer, owner, seq)};
}
Keylet
nft_buys(uint256 const& id) noexcept
nftBuys(uint256 const& id) noexcept
{
return {ltDIR_NODE, indexHash(LedgerNameSpace::NFTOKEN_BUY_OFFERS, id)};
return {ltDIR_NODE, indexHash(LedgerNameSpace::NftokenBuyOffers, id)};
}
Keylet
nft_sells(uint256 const& id) noexcept
nftSells(uint256 const& id) noexcept
{
return {ltDIR_NODE, indexHash(LedgerNameSpace::NFTOKEN_SELL_OFFERS, id)};
return {ltDIR_NODE, indexHash(LedgerNameSpace::NftokenSellOffers, id)};
}
Keylet
@@ -431,7 +430,7 @@ amm(Asset const& asset1, Asset const& asset2) noexcept
if constexpr (std::is_same_v<TIss1, Issue> && std::is_same_v<TIss2, Issue>)
{
return amm(indexHash(
LedgerNameSpace::AMM,
LedgerNameSpace::Amm,
issue1.account,
issue1.currency,
issue2.account,
@@ -440,16 +439,16 @@ amm(Asset const& asset1, Asset const& asset2) noexcept
else if constexpr (std::is_same_v<TIss1, Issue> && std::is_same_v<TIss2, MPTIssue>)
{
return amm(indexHash(
LedgerNameSpace::AMM, issue1.account, issue1.currency, issue2.getMptID()));
LedgerNameSpace::Amm, issue1.account, issue1.currency, issue2.getMptID()));
}
else if constexpr (std::is_same_v<TIss1, MPTIssue> && std::is_same_v<TIss2, Issue>)
{
return amm(indexHash(
LedgerNameSpace::AMM, issue1.getMptID(), issue2.account, issue2.currency));
LedgerNameSpace::Amm, issue1.getMptID(), issue2.account, issue2.currency));
}
else if constexpr (std::is_same_v<TIss1, MPTIssue> && std::is_same_v<TIss2, MPTIssue>)
{
return amm(indexHash(LedgerNameSpace::AMM, issue1.getMptID(), issue2.getMptID()));
return amm(indexHash(LedgerNameSpace::Amm, issue1.getMptID(), issue2.getMptID()));
}
},
minA.value(),
@@ -465,7 +464,7 @@ amm(uint256 const& id) noexcept
Keylet
delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept
{
return {ltDELEGATE, indexHash(LedgerNameSpace::DELEGATE, account, authorizedAccount)};
return {ltDELEGATE, indexHash(LedgerNameSpace::Delegate, account, authorizedAccount)};
}
Keylet
@@ -475,7 +474,7 @@ bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType)
// there can only be one bridge per lockingChainCurrency. On the issuing
// chain there can only be one bridge per issuingChainCurrency.
auto const& issue = bridge.issue(chainType);
return {ltBRIDGE, indexHash(LedgerNameSpace::BRIDGE, bridge.door(chainType), issue.currency)};
return {ltBRIDGE, indexHash(LedgerNameSpace::Bridge, bridge.door(chainType), issue.currency)};
}
Keylet
@@ -484,7 +483,7 @@ xChainClaimID(STXChainBridge const& bridge, std::uint64_t seq)
return {
ltXCHAIN_OWNED_CLAIM_ID,
indexHash(
LedgerNameSpace::XCHAIN_CLAIM_ID,
LedgerNameSpace::XchainClaimId,
bridge.lockingChainDoor(),
bridge.lockingChainIssue(),
bridge.issuingChainDoor(),
@@ -498,7 +497,7 @@ xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t seq)
return {
ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID,
indexHash(
LedgerNameSpace::XCHAIN_CREATE_ACCOUNT_CLAIM_ID,
LedgerNameSpace::XchainCreateAccountClaimId,
bridge.lockingChainDoor(),
bridge.lockingChainIssue(),
bridge.issuingChainDoor(),
@@ -509,13 +508,13 @@ xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t seq)
Keylet
did(AccountID const& account) noexcept
{
return {ltDID, indexHash(LedgerNameSpace::DID, account)};
return {ltDID, indexHash(LedgerNameSpace::Did, account)};
}
Keylet
oracle(AccountID const& account, std::uint32_t const& documentID) noexcept
{
return {ltORACLE, indexHash(LedgerNameSpace::ORACLE, account, documentID)};
return {ltORACLE, indexHash(LedgerNameSpace::Oracle, account, documentID)};
}
Keylet
@@ -527,7 +526,7 @@ mptIssuance(std::uint32_t seq, AccountID const& issuer) noexcept
Keylet
mptIssuance(MPTID const& issuanceID) noexcept
{
return {ltMPTOKEN_ISSUANCE, indexHash(LedgerNameSpace::MPTOKEN_ISSUANCE, issuanceID)};
return {ltMPTOKEN_ISSUANCE, indexHash(LedgerNameSpace::MPTokenIssuance, issuanceID)};
}
Keylet
@@ -539,37 +538,37 @@ mptoken(MPTID const& issuanceID, AccountID const& holder) noexcept
Keylet
mptoken(uint256 const& issuanceKey, AccountID const& holder) noexcept
{
return {ltMPTOKEN, indexHash(LedgerNameSpace::MPTOKEN, issuanceKey, holder)};
return {ltMPTOKEN, indexHash(LedgerNameSpace::MPToken, issuanceKey, holder)};
}
Keylet
credential(AccountID const& subject, AccountID const& issuer, Slice const& credType) noexcept
{
return {ltCREDENTIAL, indexHash(LedgerNameSpace::CREDENTIAL, subject, issuer, credType)};
return {ltCREDENTIAL, indexHash(LedgerNameSpace::Credential, subject, issuer, credType)};
}
Keylet
vault(AccountID const& owner, std::uint32_t seq) noexcept
{
return vault(indexHash(LedgerNameSpace::VAULT, owner, seq));
return vault(indexHash(LedgerNameSpace::Vault, owner, seq));
}
Keylet
loanbroker(AccountID const& owner, std::uint32_t seq) noexcept
{
return loanbroker(indexHash(LedgerNameSpace::LOAN_BROKER, owner, seq));
return loanbroker(indexHash(LedgerNameSpace::LoanBroker, owner, seq));
}
Keylet
loan(uint256 const& loanBrokerID, std::uint32_t loanSeq) noexcept
{
return loan(indexHash(LedgerNameSpace::LOAN, loanBrokerID, loanSeq));
return loan(indexHash(LedgerNameSpace::Loan, loanBrokerID, loanSeq));
}
Keylet
permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept
{
return {ltPERMISSIONED_DOMAIN, indexHash(LedgerNameSpace::PERMISSIONED_DOMAIN, account, seq)};
return {ltPERMISSIONED_DOMAIN, indexHash(LedgerNameSpace::PermissionedDomain, account, seq)};
}
Keylet

View File

@@ -13,160 +13,160 @@ InnerObjectFormats::InnerObjectFormats()
add(sfSignerEntry.jsonName,
sfSignerEntry.getCode(),
{
{sfAccount, soeREQUIRED},
{sfSignerWeight, soeREQUIRED},
{sfWalletLocator, soeOPTIONAL},
{sfAccount, SoeRequired},
{sfSignerWeight, SoeRequired},
{sfWalletLocator, SoeOptional},
});
add(sfSigner.jsonName,
sfSigner.getCode(),
{
{sfAccount, soeREQUIRED},
{sfSigningPubKey, soeREQUIRED},
{sfTxnSignature, soeREQUIRED},
{sfAccount, SoeRequired},
{sfSigningPubKey, SoeRequired},
{sfTxnSignature, SoeRequired},
});
add(sfMajority.jsonName,
sfMajority.getCode(),
{
{sfAmendment, soeREQUIRED},
{sfCloseTime, soeREQUIRED},
{sfAmendment, SoeRequired},
{sfCloseTime, SoeRequired},
});
add(sfDisabledValidator.jsonName,
sfDisabledValidator.getCode(),
{
{sfPublicKey, soeREQUIRED},
{sfFirstLedgerSequence, soeREQUIRED},
{sfPublicKey, SoeRequired},
{sfFirstLedgerSequence, SoeRequired},
});
add(sfNFToken.jsonName,
sfNFToken.getCode(),
{
{sfNFTokenID, soeREQUIRED},
{sfURI, soeOPTIONAL},
{sfNFTokenID, SoeRequired},
{sfURI, SoeOptional},
});
add(sfVoteEntry.jsonName,
sfVoteEntry.getCode(),
{
{sfAccount, soeREQUIRED},
{sfTradingFee, soeDEFAULT},
{sfVoteWeight, soeREQUIRED},
{sfAccount, SoeRequired},
{sfTradingFee, SoeDefault},
{sfVoteWeight, SoeRequired},
});
add(sfAuctionSlot.jsonName,
sfAuctionSlot.getCode(),
{{sfAccount, soeREQUIRED},
{sfExpiration, soeREQUIRED},
{sfDiscountedFee, soeDEFAULT},
{sfPrice, soeREQUIRED},
{sfAuthAccounts, soeOPTIONAL}});
{{sfAccount, SoeRequired},
{sfExpiration, SoeRequired},
{sfDiscountedFee, SoeDefault},
{sfPrice, SoeRequired},
{sfAuthAccounts, SoeOptional}});
add(sfXChainClaimAttestationCollectionElement.jsonName,
sfXChainClaimAttestationCollectionElement.getCode(),
{
{sfAttestationSignerAccount, soeREQUIRED},
{sfPublicKey, soeREQUIRED},
{sfSignature, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfAccount, soeREQUIRED},
{sfAttestationRewardAccount, soeREQUIRED},
{sfWasLockingChainSend, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
{sfDestination, soeOPTIONAL},
{sfAttestationSignerAccount, SoeRequired},
{sfPublicKey, SoeRequired},
{sfSignature, SoeRequired},
{sfAmount, SoeRequired},
{sfAccount, SoeRequired},
{sfAttestationRewardAccount, SoeRequired},
{sfWasLockingChainSend, SoeRequired},
{sfXChainClaimID, SoeRequired},
{sfDestination, SoeOptional},
});
add(sfXChainCreateAccountAttestationCollectionElement.jsonName,
sfXChainCreateAccountAttestationCollectionElement.getCode(),
{
{sfAttestationSignerAccount, soeREQUIRED},
{sfPublicKey, soeREQUIRED},
{sfSignature, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfAccount, soeREQUIRED},
{sfAttestationRewardAccount, soeREQUIRED},
{sfWasLockingChainSend, soeREQUIRED},
{sfXChainAccountCreateCount, soeREQUIRED},
{sfDestination, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
{sfAttestationSignerAccount, SoeRequired},
{sfPublicKey, SoeRequired},
{sfSignature, SoeRequired},
{sfAmount, SoeRequired},
{sfAccount, SoeRequired},
{sfAttestationRewardAccount, SoeRequired},
{sfWasLockingChainSend, SoeRequired},
{sfXChainAccountCreateCount, SoeRequired},
{sfDestination, SoeRequired},
{sfSignatureReward, SoeRequired},
});
add(sfXChainClaimProofSig.jsonName,
sfXChainClaimProofSig.getCode(),
{
{sfAttestationSignerAccount, soeREQUIRED},
{sfPublicKey, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfAttestationRewardAccount, soeREQUIRED},
{sfWasLockingChainSend, soeREQUIRED},
{sfDestination, soeOPTIONAL},
{sfAttestationSignerAccount, SoeRequired},
{sfPublicKey, SoeRequired},
{sfAmount, SoeRequired},
{sfAttestationRewardAccount, SoeRequired},
{sfWasLockingChainSend, SoeRequired},
{sfDestination, SoeOptional},
});
add(sfXChainCreateAccountProofSig.jsonName,
sfXChainCreateAccountProofSig.getCode(),
{
{sfAttestationSignerAccount, soeREQUIRED},
{sfPublicKey, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
{sfAttestationRewardAccount, soeREQUIRED},
{sfWasLockingChainSend, soeREQUIRED},
{sfDestination, soeREQUIRED},
{sfAttestationSignerAccount, SoeRequired},
{sfPublicKey, SoeRequired},
{sfAmount, SoeRequired},
{sfSignatureReward, SoeRequired},
{sfAttestationRewardAccount, SoeRequired},
{sfWasLockingChainSend, SoeRequired},
{sfDestination, SoeRequired},
});
add(sfAuthAccount.jsonName,
sfAuthAccount.getCode(),
{
{sfAccount, soeREQUIRED},
{sfAccount, SoeRequired},
});
add(sfPriceData.jsonName,
sfPriceData.getCode(),
{
{sfBaseAsset, soeREQUIRED},
{sfQuoteAsset, soeREQUIRED},
{sfAssetPrice, soeOPTIONAL},
{sfScale, soeDEFAULT},
{sfBaseAsset, SoeRequired},
{sfQuoteAsset, SoeRequired},
{sfAssetPrice, SoeOptional},
{sfScale, SoeDefault},
});
add(sfCredential.jsonName,
sfCredential.getCode(),
{
{sfIssuer, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
{sfIssuer, SoeRequired},
{sfCredentialType, SoeRequired},
});
add(sfPermission.jsonName.c_str(), sfPermission.getCode(), {{sfPermissionValue, soeREQUIRED}});
add(sfPermission.jsonName.cStr(), sfPermission.getCode(), {{sfPermissionValue, SoeRequired}});
add(sfBatchSigner.jsonName.c_str(),
add(sfBatchSigner.jsonName.cStr(),
sfBatchSigner.getCode(),
{{sfAccount, soeREQUIRED},
{sfSigningPubKey, soeOPTIONAL},
{sfTxnSignature, soeOPTIONAL},
{sfSigners, soeOPTIONAL}});
{{sfAccount, SoeRequired},
{sfSigningPubKey, SoeOptional},
{sfTxnSignature, SoeOptional},
{sfSigners, SoeOptional}});
add(sfBook.jsonName,
sfBook.getCode(),
{
{sfBookDirectory, soeREQUIRED},
{sfBookNode, soeREQUIRED},
{sfBookDirectory, SoeRequired},
{sfBookNode, SoeRequired},
});
add(sfCounterpartySignature.jsonName,
sfCounterpartySignature.getCode(),
{
{sfSigningPubKey, soeOPTIONAL},
{sfTxnSignature, soeOPTIONAL},
{sfSigners, soeOPTIONAL},
{sfSigningPubKey, SoeOptional},
{sfTxnSignature, SoeOptional},
{sfSigners, SoeOptional},
});
}
InnerObjectFormats const&
InnerObjectFormats::getInstance()
{
static InnerObjectFormats const instance;
return instance;
static InnerObjectFormats const kInstance;
return kInstance;
}
SOTemplate const*

View File

@@ -43,7 +43,7 @@ Issue::getText() const
}
void
Issue::setJson(Json::Value& jv) const
Issue::setJson(json::Value& jv) const
{
jv[jss::currency] = to_string(currency);
if (!isXRP(currency))
@@ -77,16 +77,16 @@ to_string(Issue const& ac)
return to_string(ac.account) + "/" + to_string(ac.currency);
}
Json::Value
to_json(Issue const& is)
json::Value
toJson(Issue const& is)
{
Json::Value jv;
json::Value jv;
is.setJson(jv);
return jv;
}
Issue
issueFromJson(Json::Value const& v)
issueFromJson(json::Value const& v)
{
if (!v.isObject())
{
@@ -99,38 +99,38 @@ issueFromJson(Json::Value const& v)
Throw<std::runtime_error>("issueFromJson, Issue should not have mpt_issuance_id");
}
Json::Value const curStr = v[jss::currency];
Json::Value const issStr = v[jss::issuer];
json::Value const curStr = v[jss::currency];
json::Value const issStr = v[jss::issuer];
if (!curStr.isString())
{
Throw<Json::error>("issueFromJson currency must be a string Json value");
Throw<json::Error>("issueFromJson currency must be a string Json value");
}
auto const currency = to_currency(curStr.asString());
auto const currency = toCurrency(curStr.asString());
if (currency == badCurrency() || currency == noCurrency())
{
Throw<Json::error>("issueFromJson currency must be a valid currency");
Throw<json::Error>("issueFromJson currency must be a valid currency");
}
if (isXRP(currency))
{
if (!issStr.isNull())
{
Throw<Json::error>("Issue, XRP should not have issuer");
Throw<json::Error>("Issue, XRP should not have issuer");
}
return xrpIssue();
}
if (!issStr.isString())
{
Throw<Json::error>("issueFromJson issuer must be a string Json value");
Throw<json::Error>("issueFromJson issuer must be a string Json value");
}
auto const issuer = parseBase58<AccountID>(issStr.asString());
if (!issuer)
if (!issuer || *issuer == noAccount() || *issuer == xrpAccount())
{
Throw<Json::error>("issueFromJson issuer must be a valid account");
Throw<json::Error>("issueFromJson issuer must be a valid account");
}
return Issue{currency, *issuer};

View File

@@ -11,12 +11,12 @@ namespace xrpl {
std::vector<SOElement> const&
LedgerFormats::getCommonFields()
{
static auto const commonFields = std::vector<SOElement>{
{sfLedgerIndex, soeOPTIONAL},
{sfLedgerEntryType, soeREQUIRED},
{sfFlags, soeREQUIRED},
static auto const kCommonFields = std::vector<SOElement>{
{sfLedgerIndex, SoeOptional},
{sfLedgerEntryType, SoeRequired},
{sfFlags, SoeRequired},
};
return commonFields;
return kCommonFields;
}
LedgerFormats::LedgerFormats()
@@ -41,8 +41,8 @@ LedgerFormats::LedgerFormats()
LedgerFormats const&
LedgerFormats::getInstance()
{
static LedgerFormats const instance;
return instance;
static LedgerFormats const kInstance;
return kInstance;
}
} // namespace xrpl

View File

@@ -61,7 +61,7 @@ calculateLedgerHash(LedgerHeader const& info)
{
// VFALCO This has to match addRaw in View.h.
return sha512Half(
HashPrefix::ledgerMaster,
HashPrefix::LedgerMaster,
std::uint32_t(info.seq),
std::uint64_t(info.drops.drops()),
info.parentHash,

View File

@@ -44,15 +44,15 @@ MPTIssue::getText() const
}
void
MPTIssue::setJson(Json::Value& jv) const
MPTIssue::setJson(json::Value& jv) const
{
jv[jss::mpt_issuance_id] = to_string(mptID_);
}
Json::Value
to_json(MPTIssue const& mptIssue)
json::Value
toJson(MPTIssue const& mptIssue)
{
Json::Value jv;
json::Value jv;
mptIssue.setJson(jv);
return jv;
}
@@ -64,7 +64,7 @@ to_string(MPTIssue const& mptIssue)
}
MPTIssue
mptIssueFromJson(Json::Value const& v)
mptIssueFromJson(json::Value const& v)
{
if (!v.isObject())
{
@@ -78,17 +78,17 @@ mptIssueFromJson(Json::Value const& v)
Throw<std::runtime_error>("mptIssueFromJson, MPTIssue should not have currency or issuer");
}
Json::Value const& idStr = v[jss::mpt_issuance_id];
json::Value const& idStr = v[jss::mpt_issuance_id];
if (!idStr.isString())
{
Throw<Json::error>("mptIssueFromJson MPTID must be a string Json value");
Throw<json::Error>("mptIssueFromJson MPTID must be a string Json value");
}
MPTID id;
if (!id.parseHex(idStr.asString()))
{
Throw<Json::error>("mptIssueFromJson MPTID is invalid");
Throw<json::Error>("mptIssueFromJson MPTID is invalid");
}
return MPTIssue{id};

View File

@@ -13,7 +13,7 @@ namespace xrpl::RPC {
void
insertNFTSyntheticInJson(
Json::Value& response,
json::Value& response,
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta)
{

View File

@@ -134,7 +134,7 @@ getNFTokenIDFromDeletedOffer(TxMeta const& transactionMeta)
void
insertNFTokenID(
Json::Value& response,
json::Value& response,
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta)
{
@@ -159,7 +159,7 @@ insertNFTokenID(
{
std::vector<uint256> const result = getNFTokenIDFromDeletedOffer(transactionMeta);
response[jss::nftoken_ids] = Json::Value(Json::arrayValue);
response[jss::nftoken_ids] = json::Value(json::ValueType::Array);
for (auto const& nftID : result)
response[jss::nftoken_ids].append(to_string(nftID));
}

View File

@@ -52,7 +52,7 @@ getOfferIDFromCreatedOffer(TxMeta const& transactionMeta)
void
insertNFTokenOfferID(
Json::Value& response,
json::Value& response,
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta)
{

View File

@@ -92,8 +92,8 @@ Permission::Permission()
Permission const&
Permission::getInstance()
{
static Permission const instance;
return instance;
static Permission const kInstance;
return kInstance;
}
std::optional<std::string>
@@ -182,7 +182,7 @@ Permission::isDelegable(std::uint32_t const& permissionValue, Rules const& rules
if (txFeaturesIt->second != uint256{} && !rules.enabled(txFeaturesIt->second))
return false;
if (it->second == Delegation::notDelegable)
if (it->second == Delegation::NotDelegable)
return false;
return true;

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