feat: logging

This commit is contained in:
Denis Angell
2026-05-10 18:08:31 +02:00
parent 8490206228
commit 84ce5482e6
498 changed files with 6214 additions and 2 deletions

499
bin/add_trace_logging.py Normal file
View File

@@ -0,0 +1,499 @@
#!/usr/bin/env python3
"""
Instrument every function in the rippled codebase with TRACE_FUNC().
Adds an RAII trace scope to every function body that logs:
- ENTER on function entry (with file:line)
- EXIT on function exit (with file:line and duration in microseconds)
Usage:
python3 bin/add_trace_logging.py [--dry-run] [--verbose] [--dir path]
"""
import argparse
import os
import re
import sys
from pathlib import Path
TRACE_INCLUDE = '#include <xrpl/basics/TraceLog.h>'
TRACE_CALL = ' TRACE_FUNC();'
# Control-flow keywords that produce a '{' on its own line
# (due to AfterControlStatement: true in .clang-format)
CONTROL_KW_RE = re.compile(
r'^\s*('
r'if\s*\(|'
r'else\s*if\s*\(|'
r'else\s*$|'
r'for\s*\(|'
r'while\s*\(|'
r'do\s*$|'
r'switch\s*\(|'
r'try\s*$|'
r'catch\s*\('
r')'
)
# Structural keywords (class/struct/enum/union) — brace on own line
STRUCT_KW_RE = re.compile(
r'^\s*(class|struct|enum|union)\b'
)
# Namespace — AfterNamespace: false so '{' is on same line,
# but handle edge cases where someone puts it on next line
NAMESPACE_RE = re.compile(r'^\s*namespace\b')
# Lambda capture: line contains ] possibly followed by () and qualifiers
LAMBDA_RE = re.compile(r'\]\s*(\([^)]*\))?\s*(mutable\s*)?(noexcept\s*)?'
r'(->[\s\S]*)?\s*$')
# Function ending: line ends with ) and optional qualifiers
FUNC_END_RE = re.compile(
r'\)\s*'
r'(const\s*)?'
r'(volatile\s*)?'
r'(noexcept(\([^)]*\))?\s*)?'
r'(override\s*)?'
r'(final\s*)?'
r'(requires\s*\([^)]*\)\s*)?'
r'(->[\s\w:<>,*&]+\s*)?'
r'\s*$'
)
# Constructor initializer list line: starts with : or , for member init
INIT_LIST_RE = re.compile(r'^\s*[,:]\s+\w')
# Macro-like patterns to skip
MACRO_RE = re.compile(r'^\s*\\?\s*$')
def find_source_files(root, dirs, extensions=('.cpp',), exclude_dirs=None):
"""Find all source files under given directories."""
if exclude_dirs is None:
exclude_dirs = {'tests', 'test'}
files = []
for d in dirs:
search_dir = root / d
if not search_dir.exists():
continue
for ext in extensions:
for f in sorted(search_dir.rglob(f'*{ext}')):
# Skip test directories
parts = f.relative_to(root).parts
if any(p in exclude_dirs for p in parts):
continue
files.append(f)
return files
def find_template_headers(root):
"""Find .h files with template implementations that need instrumentation."""
headers = []
# These directories have header-only template implementations
template_dirs = [
'src/xrpld/consensus',
'src/xrpld/overlay',
'src/xrpld/overlay/detail',
'src/xrpld/peerfinder',
'src/xrpld/peerfinder/detail',
'src/xrpld/app/consensus',
'src/xrpld/app/ledger',
'src/xrpld/app/ledger/detail',
'src/xrpld/app/misc',
'src/xrpld/app/misc/detail',
'src/xrpld/app/main',
'src/xrpld/rpc',
'src/xrpld/rpc/detail',
'src/xrpld/core',
'src/xrpld/core/detail',
]
for d in template_dirs:
search_dir = root / d
if not search_dir.exists():
continue
for f in sorted(search_dir.glob('*.h')):
headers.append(f)
# Also include key libxrpl headers with implementations
libxrpl_dirs = [
'include/xrpl/shamap',
'include/xrpl/basics',
'include/xrpl/protocol',
]
for d in libxrpl_dirs:
search_dir = root / d
if not search_dir.exists():
continue
for f in sorted(search_dir.glob('*.h')):
# Skip TraceLog.h itself
if f.name == 'TraceLog.h':
continue
headers.append(f)
return headers
def add_include(lines):
"""Add the TraceLog.h include if not already present. Returns modified lines."""
# Check if already included
for line in lines:
if 'TraceLog.h' in line:
return lines, False
# Find insertion point: after last #include <xrpl/...> or <xrpld/...>
last_xrpl_idx = -1
last_xrpld_idx = -1
last_include_idx = -1
for i, line in enumerate(lines):
stripped = line.strip()
if stripped.startswith('#include'):
last_include_idx = i
if '<xrpl/' in stripped:
last_xrpl_idx = i
elif '<xrpld/' in stripped:
last_xrpld_idx = i
if last_include_idx == -1:
return lines, False # No includes at all — skip
# Prefer inserting after xrpl/ includes (same group), else after xrpld/
if last_xrpl_idx >= 0:
insert_at = last_xrpl_idx + 1
elif last_xrpld_idx >= 0:
# Insert after the xrpld block, with a blank line before xrpl includes
insert_at = last_xrpld_idx + 1
else:
insert_at = last_include_idx + 1
lines.insert(insert_at, TRACE_INCLUDE + '\n')
return lines, True
def get_prev_nonblank(lines, idx):
"""Get the index of the previous non-blank line before idx."""
i = idx - 1
while i >= 0:
if lines[i].strip():
return i
i -= 1
return -1
def find_matching_open_paren_line(lines, start_idx):
"""
Starting from start_idx, walk backwards through lines to find the line
containing the '(' that matches the last ')' on start_idx's line.
Returns the line index, or -1 if not found.
Uses character-level paren tracking for accuracy.
"""
depth = 0
for scan in range(start_idx, max(start_idx - 30, -1), -1):
line = lines[scan].rstrip()
for ch in reversed(line):
if ch == ')':
depth += 1
elif ch == '(':
depth -= 1
if depth == 0:
return scan
return -1
def is_lambda(lines, brace_idx):
"""Check if the '{' at brace_idx opens a lambda body."""
# Walk back up to 5 non-blank lines looking for ] (lambda capture close)
prev = brace_idx - 1
checked = 0
while prev >= 0 and checked < 6:
line = lines[prev].rstrip()
if not line.strip():
prev -= 1
continue
# Lambda pattern: line contains ']' possibly followed by () qualifiers
if ']' in line:
# Skip C++ attributes like [[nodiscard]], [[maybe_unused]], etc.
# Attributes use [[ ]] (double brackets)
stripped = line.strip()
if re.match(r'^\[\[', stripped):
# This is a C++ attribute, not a lambda
checked += 1
prev -= 1
continue
# Also skip ]] patterns mid-line (attributes in return types)
if ']]' in line and '[[' in line:
checked += 1
prev -= 1
continue
# Check for actual lambda pattern: ] followed by ( or { or mutable
# Lambda captures end with ] then optional (params) or {body}
if re.search(r'\]\s*(\([^)]*\))?\s*(mutable\s*)?(noexcept\s*)?'
r'(->[\s\S]*)?\s*$', line):
return True
# Stop walking back at scope boundaries
if line.strip().startswith('{') or line.strip().startswith('}'):
break
if line.strip().startswith('#'):
break
checked += 1
prev -= 1
return False
def is_function_body(lines, brace_idx):
"""
Determine if the '{' at brace_idx opens a function body.
Returns True if this looks like a function definition, False otherwise.
"""
prev_idx = get_prev_nonblank(lines, brace_idx)
if prev_idx < 0:
return False
prev_line = lines[prev_idx].rstrip()
# Skip if preceded by a single-line control keyword
if CONTROL_KW_RE.match(prev_line):
return False
# Skip namespace
if NAMESPACE_RE.match(prev_line):
return False
# Skip class/struct/enum/union
if STRUCT_KW_RE.match(prev_line):
return False
# Skip lambdas
if is_lambda(lines, brace_idx):
return False
# Case 1: Previous line ends with ) + optional qualifiers
if FUNC_END_RE.search(prev_line):
# Walk back to find the line with the matching '('
open_paren_line = find_matching_open_paren_line(lines, prev_idx)
if open_paren_line >= 0:
# Check if that line (or preceding lines) is a control keyword
line = lines[open_paren_line].rstrip()
if CONTROL_KW_RE.match(line):
return False
# Also check the line before (for multi-line: "else\n if(...)")
prev_kw = get_prev_nonblank(lines, open_paren_line)
if prev_kw >= 0:
kw_line = lines[prev_kw].rstrip()
if re.match(r'^\s*else\s*$', kw_line):
return False
return True
# Case 2: Constructor initializer list — line starts with , or :
if INIT_LIST_RE.match(prev_line):
# Walk back through initializer list to find constructor signature
scan = prev_idx - 1
while scan >= 0:
line = lines[scan].rstrip()
if FUNC_END_RE.search(line):
return True
if not INIT_LIST_RE.match(line) and ')' not in line:
break
scan -= 1
# Even if we can't find the signature, an init list implies constructor
return True
# Case 3: Previous line ends with something unusual — check a few
# lines back for a ')' that might be part of a function signature
# (e.g., trailing requires clause or -> return type on separate line)
for lookback in range(1, 4):
check_idx = prev_idx - lookback
if check_idx < 0:
break
check_line = lines[check_idx].rstrip()
if check_line.strip() == '' or check_line.strip().startswith('#'):
break
if FUNC_END_RE.search(check_line):
open_paren_line = find_matching_open_paren_line(
lines, check_idx)
if open_paren_line >= 0:
if CONTROL_KW_RE.match(lines[open_paren_line].rstrip()):
return False
return True
return False
def is_empty_body(lines, brace_idx):
"""Check if the function body is empty (next non-blank line is '}')."""
i = brace_idx + 1
while i < len(lines):
stripped = lines[i].strip()
if stripped:
return stripped == '}'
i += 1
return True
def already_has_trace(lines, brace_idx):
"""Check if TRACE_FUNC is already the first statement."""
i = brace_idx + 1
while i < len(lines):
stripped = lines[i].strip()
if stripped:
return 'TRACE_FUNC()' in stripped
i += 1
return False
def get_function_context(lines, brace_idx):
"""Try to extract a meaningful function name from the context."""
prev_idx = get_prev_nonblank(lines, brace_idx)
if prev_idx < 0:
return "unknown"
# Walk back to find the function name line
scan = prev_idx
while scan >= 0:
line = lines[scan].strip()
# Look for ClassName::methodName or just functionName
match = re.search(r'(\w+(?:::\w+)?)\s*\(', line)
if match:
return match.group(1)
if line.startswith('#') or line == '':
break
scan -= 1
return lines[prev_idx].strip()[:60]
def instrument_file(filepath, dry_run=False, verbose=False):
"""
Add TRACE_FUNC() to every function body in the given file.
Returns (functions_found, include_added) tuple.
"""
with open(filepath, 'r') as f:
lines = f.readlines()
original_lines = list(lines)
functions_found = 0
insertions = [] # (line_index, context_string)
# Pass 1: Find all function body openings
# Track brace depth to skip nested blocks inside functions
brace_depth = 0
in_function = False
i = 0
while i < len(lines):
line = lines[i]
stripped = line.strip()
if in_function:
# Count braces to track nesting within the current function
brace_depth += stripped.count('{') - stripped.count('}')
if brace_depth <= 0:
in_function = False
brace_depth = 0
elif stripped == '{':
if is_function_body(lines, i):
if not is_empty_body(lines, i) and not already_has_trace(lines, i):
ctx = get_function_context(lines, i)
insertions.append((i, ctx))
functions_found += 1
in_function = True
brace_depth = 1
i += 1
if functions_found == 0 and not any('TraceLog.h' in l for l in lines):
return 0, False # Nothing to do
# Pass 2: Add include
include_added = False
if functions_found > 0:
lines, include_added = add_include(lines)
# Adjust insertion indices if include was added
if include_added:
# Find where the include was inserted
for idx in range(len(lines)):
if TRACE_INCLUDE in lines[idx]:
include_line = idx
break
insertions = [
(i + 1 if i >= include_line else i, ctx)
for i, ctx in insertions
]
# Pass 3: Insert TRACE_FUNC() calls (reverse order to preserve indices)
for insert_idx, ctx in reversed(insertions):
lines.insert(insert_idx + 1, TRACE_CALL + '\n')
if verbose and functions_found > 0:
rel_path = filepath.name
print(f" {rel_path}: {functions_found} functions")
for _, ctx in insertions:
print(f" -> {ctx}")
if not dry_run and lines != original_lines:
with open(filepath, 'w') as f:
f.writelines(lines)
return functions_found, include_added
def main():
parser = argparse.ArgumentParser(
description='Add TRACE_FUNC() to every function in the rippled codebase')
parser.add_argument('--dry-run', action='store_true',
help='Print what would change without modifying files')
parser.add_argument('--verbose', '-v', action='store_true',
help='Show each function found')
parser.add_argument('--dir', type=str, default=None,
help='Only process files under this subdirectory')
parser.add_argument('--headers', action='store_true',
help='Also process .h files with template implementations')
parser.add_argument('--root', type=str, default='.',
help='Project root directory')
args = parser.parse_args()
root = Path(args.root).resolve()
# Find source files
if args.dir:
dirs = [args.dir]
else:
dirs = ['src/xrpld', 'src/libxrpl']
files = find_source_files(root, dirs)
if args.headers:
files.extend(find_template_headers(root))
if not files:
print(f"No source files found under {root}")
sys.exit(1)
total_functions = 0
total_includes = 0
total_files_modified = 0
mode = "DRY RUN" if args.dry_run else "INSTRUMENTING"
print(f"[{mode}] Processing {len(files)} files under {root}")
print()
for filepath in files:
funcs, inc = instrument_file(
filepath, dry_run=args.dry_run, verbose=args.verbose)
if funcs > 0:
total_functions += funcs
total_files_modified += 1
if inc:
total_includes += 1
print()
print(f"{'Would instrument' if args.dry_run else 'Instrumented'}: "
f"{total_functions} functions across {total_files_modified} files")
print(f"{'Would add' if args.dry_run else 'Added'}: "
f"{total_includes} new #include directives")
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,37 @@
#pragma once
#include <cstdint>
namespace xrpl {
namespace tracing {
void init(
char const* outputPath,
double samplingRate = 1.0,
std::uint64_t maxFileSizeMB = 500,
int maxFiles = 10);
void shutdown();
} // namespace tracing
class TraceScope
{
std::uint64_t spanId_;
std::uint64_t traceId_;
std::uint64_t parentId_;
char const* func_;
char const* file_;
int line_;
std::int64_t startUs_;
bool active_;
public:
TraceScope(char const* func, char const* file, int line) noexcept;
~TraceScope() noexcept;
TraceScope(TraceScope const&) = delete;
TraceScope& operator=(TraceScope const&) = delete;
};
} // namespace xrpl
#define TRACE_FUNC() \
xrpl::TraceScope xrpl_trace_scope_(__func__, __FILE__, __LINE__)

View File

@@ -3,12 +3,14 @@
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/TaggedCache.ipp>
#include <xrpl/beast/hash/uhash.h>
#include <xrpl/nodestore/Backend.h>
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/protocol/SystemParameters.h>
#include <condition_variable>
#include <unordered_set>
namespace xrpl::NodeStore {
@@ -222,6 +224,12 @@ protected:
void
importInternal(Backend& dstBackend, Database& srcDB);
void
negCacheErase(uint256 const& hash);
void
negCacheClear();
void
updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
{
@@ -251,6 +259,10 @@ private:
std::atomic<int> readThreads_ = 0;
std::atomic<int> runningThreads_ = 0;
mutable std::mutex negCacheMutex_;
std::unordered_set<uint256, beast::Uhash<>> negCache_;
static constexpr std::size_t kNegCacheMax = 100'000;
virtual std::shared_ptr<NodeObject>
fetchNodeObject(
uint256 const& hash,

View File

@@ -2,6 +2,7 @@
#include <xrpl/nodestore/DatabaseRotating.h>
#include <atomic>
#include <mutex>
namespace xrpl::NodeStore {
@@ -59,6 +60,7 @@ private:
std::shared_ptr<Backend> writableBackend_;
std::shared_ptr<Backend> archiveBackend_;
mutable std::mutex mutex_;
std::atomic<bool> archiveHasData_{true};
std::shared_ptr<NodeObject>
fetchNodeObject(uint256 const& hash, std::uint32_t, FetchReport& fetchReport, bool duplicate)

View File

@@ -1,6 +1,7 @@
#include <xrpl/basics/Archive.h>
#include <xrpl/basics/contract.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
@@ -17,6 +18,7 @@ namespace xrpl {
void
extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const& dst)
{
TRACE_FUNC();
if (!is_regular_file(src))
Throw<std::runtime_error>("Invalid source file");

View File

@@ -1,6 +1,7 @@
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/StringUtilities.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/regex/v5/regbase.hpp>
#include <boost/regex/v5/regex.hpp>
@@ -21,12 +22,14 @@ Section::Section(std::string name) : name_(std::move(name))
void
Section::set(std::string const& key, std::string const& value)
{
TRACE_FUNC();
lookup_.insert_or_assign(key, value);
}
void
Section::append(std::vector<std::string> const& lines)
{
TRACE_FUNC();
// <key> '=' <value>
static boost::regex const kRE1(
"^" // start of line
@@ -98,12 +101,14 @@ Section::append(std::vector<std::string> const& lines)
bool
Section::exists(std::string const& name) const
{
TRACE_FUNC();
return lookup_.contains(name);
}
std::ostream&
operator<<(std::ostream& os, Section const& section)
{
TRACE_FUNC();
for (auto const& [k, v] : section.lookup_)
os << k << "=" << v << "\n";
return os;
@@ -114,18 +119,21 @@ operator<<(std::ostream& os, Section const& section)
bool
BasicConfig::exists(std::string const& name) const
{
TRACE_FUNC();
return map_.contains(name);
}
Section&
BasicConfig::section(std::string const& name)
{
TRACE_FUNC();
return map_.emplace(name, name).first->second;
}
Section const&
BasicConfig::section(std::string const& name) const
{
TRACE_FUNC();
static Section const kNONE("");
auto const iter = map_.find(name);
if (iter == map_.end())
@@ -136,6 +144,7 @@ BasicConfig::section(std::string const& name) const
void
BasicConfig::overwrite(std::string const& section, std::string const& key, std::string const& value)
{
TRACE_FUNC();
auto const result =
map_.emplace(std::piecewise_construct, std::make_tuple(section), std::make_tuple(section));
result.first->second.set(key, value);
@@ -144,6 +153,7 @@ BasicConfig::overwrite(std::string const& section, std::string const& key, std::
void
BasicConfig::deprecatedClearSection(std::string const& section)
{
TRACE_FUNC();
auto i = map_.find(section);
if (i != map_.end())
i->second = Section(section);
@@ -152,18 +162,21 @@ BasicConfig::deprecatedClearSection(std::string const& section)
void
BasicConfig::legacy(std::string const& section, std::string value)
{
TRACE_FUNC();
map_.emplace(section, section).first->second.legacy(std::move(value));
}
std::string
BasicConfig::legacy(std::string const& sectionName) const
{
TRACE_FUNC();
return section(sectionName).legacy();
}
void
BasicConfig::build(IniFileSections const& ifs)
{
TRACE_FUNC();
for (auto const& entry : ifs)
{
auto const result = map_.emplace(
@@ -175,6 +188,7 @@ BasicConfig::build(IniFileSections const& ifs)
std::ostream&
operator<<(std::ostream& ss, BasicConfig const& c)
{
TRACE_FUNC();
for (auto const& [k, v] : c.map_)
ss << "[" << k << "]\n" << v;
return ss;

View File

@@ -1,4 +1,5 @@
#include <xrpl/basics/CountedObject.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
@@ -7,6 +8,7 @@ namespace xrpl {
CountedObjects&
CountedObjects::getInstance() noexcept
{
TRACE_FUNC();
static CountedObjects kINSTANCE;
return kINSTANCE;
@@ -19,6 +21,7 @@ CountedObjects::CountedObjects() noexcept : count_(0), head_(nullptr)
CountedObjects::List
CountedObjects::getCounts(int minimumThreshold) const
{
TRACE_FUNC();
List counts;
// When other operations are concurrent, the count

View File

@@ -1,4 +1,5 @@
#include <xrpl/basics/FileUtilities.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
@@ -22,6 +23,7 @@ getFileContents(
boost::filesystem::path const& sourcePath,
std::optional<std::size_t> maxSize)
{
TRACE_FUNC();
using namespace boost::filesystem;
using namespace boost::system::errc;
@@ -62,6 +64,7 @@ writeFileContents(
boost::filesystem::path const& destPath,
std::string const& contents)
{
TRACE_FUNC();
using namespace boost::filesystem;
using namespace boost::system::errc;

View File

@@ -3,6 +3,7 @@
#include <xrpl/basics/chrono.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/path.hpp>
@@ -28,6 +29,7 @@ Logs::Sink::Sink(std::string partition, beast::severities::Severity thresh, Logs
void
Logs::Sink::write(beast::severities::Severity level, std::string const& text)
{
TRACE_FUNC();
if (level < threshold())
return;
@@ -37,6 +39,7 @@ Logs::Sink::write(beast::severities::Severity level, std::string const& text)
void
Logs::Sink::writeAlways(beast::severities::Severity level, std::string const& text)
{
TRACE_FUNC();
logs_.write(level, partition_, text, console());
}
@@ -49,12 +52,14 @@ Logs::File::File() : stream_(nullptr)
bool
Logs::File::isOpen() const noexcept
{
TRACE_FUNC();
return stream_ != nullptr;
}
bool
Logs::File::open(boost::filesystem::path const& path)
{
TRACE_FUNC();
close();
bool wasOpened = false;
@@ -77,6 +82,7 @@ Logs::File::open(boost::filesystem::path const& path)
bool
Logs::File::closeAndReopen()
{
TRACE_FUNC();
close();
return open(path_);
@@ -85,12 +91,14 @@ Logs::File::closeAndReopen()
void
Logs::File::close()
{
TRACE_FUNC();
stream_ = nullptr;
}
void
Logs::File::write(char const* text)
{
TRACE_FUNC();
if (stream_ != nullptr)
(*stream_) << text;
}
@@ -98,6 +106,7 @@ Logs::File::write(char const* text)
void
Logs::File::writeln(char const* text)
{
TRACE_FUNC();
if (stream_ != nullptr)
{
(*stream_) << text;
@@ -114,12 +123,14 @@ Logs::Logs(beast::severities::Severity thresh) : thresh_(thresh) // default sev
bool
Logs::open(boost::filesystem::path const& pathToLogFile)
{
TRACE_FUNC();
return file_.open(pathToLogFile);
}
beast::Journal::Sink&
Logs::get(std::string const& name)
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
auto const result = sinks_.emplace(name, makeSink(name, thresh_));
return *result.first->second;
@@ -134,18 +145,21 @@ Logs::operator[](std::string const& name)
beast::Journal
Logs::journal(std::string const& name)
{
TRACE_FUNC();
return beast::Journal(get(name));
}
beast::severities::Severity
Logs::threshold() const
{
TRACE_FUNC();
return thresh_;
}
void
Logs::threshold(beast::severities::Severity thresh)
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
thresh_ = thresh;
for (auto& sink : sinks_)
@@ -155,6 +169,7 @@ Logs::threshold(beast::severities::Severity thresh)
std::vector<std::pair<std::string, std::string>>
Logs::partitionSeverities() const
{
TRACE_FUNC();
std::vector<std::pair<std::string, std::string>> list;
std::scoped_lock const lock(mutex_);
list.reserve(sinks_.size());
@@ -170,6 +185,7 @@ Logs::write(
std::string const& text,
bool console)
{
TRACE_FUNC();
std::string s;
format(s, text, level, partition);
std::scoped_lock const lock(mutex_);
@@ -184,6 +200,7 @@ Logs::write(
std::string
Logs::rotate()
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
bool const wasOpened = file_.closeAndReopen();
if (wasOpened)
@@ -194,12 +211,14 @@ Logs::rotate()
std::unique_ptr<beast::Journal::Sink>
Logs::makeSink(std::string const& name, beast::severities::Severity threshold)
{
TRACE_FUNC();
return std::make_unique<Sink>(name, threshold, *this);
}
LogSeverity
Logs::fromSeverity(beast::severities::Severity level)
{
TRACE_FUNC();
using namespace beast::severities;
switch (level)
{
@@ -229,6 +248,7 @@ Logs::fromSeverity(beast::severities::Severity level)
beast::severities::Severity
Logs::toSeverity(LogSeverity level)
{
TRACE_FUNC();
using namespace beast::severities;
switch (level)
{
@@ -257,6 +277,7 @@ Logs::toSeverity(LogSeverity level)
std::string
Logs::toString(LogSeverity s)
{
TRACE_FUNC();
switch (s)
{
case LSTrace:
@@ -282,6 +303,7 @@ Logs::toString(LogSeverity s)
LogSeverity
Logs::fromString(std::string const& s)
{
TRACE_FUNC();
if (boost::iequals(s, "trace"))
return LSTrace;
@@ -310,6 +332,7 @@ Logs::format(
beast::severities::Severity severity,
std::string const& partition)
{
TRACE_FUNC();
output.reserve(message.size() + partition.size() + 100);
output = xrpl::to_string(std::chrono::system_clock::now());
@@ -412,6 +435,7 @@ public:
std::unique_ptr<beast::Journal::Sink>
set(std::unique_ptr<beast::Journal::Sink> sink)
{
TRACE_FUNC();
std::scoped_lock const _(mtx_);
using std::swap;
@@ -432,6 +456,7 @@ public:
beast::Journal::Sink&
get()
{
TRACE_FUNC();
std::scoped_lock const _(mtx_);
return sink_.get();
}
@@ -440,6 +465,7 @@ public:
static DebugSink&
debugSink()
{
TRACE_FUNC();
static DebugSink kINST;
return kINST;
}
@@ -447,12 +473,14 @@ debugSink()
std::unique_ptr<beast::Journal::Sink>
setDebugLogSink(std::unique_ptr<beast::Journal::Sink> sink)
{
TRACE_FUNC();
return debugSink().set(std::move(sink));
}
beast::Journal
debugLog()
{
TRACE_FUNC();
return beast::Journal(debugSink().get());
}

View File

@@ -2,6 +2,7 @@
#include <xrpl/basics/Log.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/predef.h>
@@ -31,6 +32,7 @@ namespace {
bool
getRusageThread(struct rusage& ru)
{
TRACE_FUNC();
return ::getrusage(RUSAGE_THREAD, &ru) == 0; // LCOV_EXCL_LINE
}
@@ -48,12 +50,14 @@ namespace detail {
inline int
mallocTrimWithPad(std::size_t padBytes)
{
TRACE_FUNC();
return ::malloc_trim(padBytes);
}
long
parseStatmRSSkB(std::string const& statm)
{
TRACE_FUNC();
// /proc/self/statm format: size resident shared text lib data dt
// We want the second field (resident) which is in pages
std::istringstream iss(statm);
@@ -76,6 +80,7 @@ parseStatmRSSkB(std::string const& statm)
MallocTrimReport
mallocTrim(std::string_view tag, beast::Journal journal)
{
TRACE_FUNC();
// LCOV_EXCL_START
MallocTrimReport report;

View File

@@ -2,6 +2,7 @@
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cstddef>
@@ -33,24 +34,28 @@ thread_local std::reference_wrapper<MantissaRange const> Number::kRANGE = kLARGE
Number::RoundingMode
Number::getround()
{
TRACE_FUNC();
return mode;
}
Number::RoundingMode
Number::setround(RoundingMode inMode)
{
TRACE_FUNC();
return std::exchange(Number::mode, inMode);
}
MantissaRange::MantissaScale
Number::getMantissaScale()
{
TRACE_FUNC();
return kRANGE.get().scale;
}
void
Number::setMantissaScale(MantissaRange::MantissaScale scale)
{
TRACE_FUNC();
if (scale != MantissaRange::MantissaScale::Small &&
scale != MantissaRange::MantissaScale::Large)
logicError("Unknown mantissa scale");
@@ -130,24 +135,28 @@ private:
inline void
Number::Guard::setPositive() noexcept
{
TRACE_FUNC();
sbit_ = 0;
}
inline void
Number::Guard::setNegative() noexcept
{
TRACE_FUNC();
sbit_ = 1;
}
inline bool
Number::Guard::isNegative() const noexcept
{
TRACE_FUNC();
return sbit_ == 1;
}
inline void
Number::Guard::doPush(unsigned d) noexcept
{
TRACE_FUNC();
xbit_ = xbit_ || ((digits_ & 0x0000'0000'0000'000F) != 0);
digits_ >>= 4;
digits_ |= (d & 0x0000'0000'0000'000FULL) << 60;
@@ -157,12 +166,14 @@ template <class T>
inline void
Number::Guard::push(T d) noexcept
{
TRACE_FUNC();
doPush(static_cast<unsigned>(d));
}
inline unsigned
Number::Guard::pop() noexcept
{
TRACE_FUNC();
unsigned const d = (digits_ & 0xF000'0000'0000'0000) >> 60;
digits_ <<= 4;
return d;
@@ -175,6 +186,7 @@ Number::Guard::pop() noexcept
int
Number::Guard::round() const noexcept
{
TRACE_FUNC();
auto mode = Number::getround();
if (mode == RoundingMode::TowardsZero)
@@ -217,6 +229,7 @@ Number::Guard::bringIntoRange(
int& exponent,
internalrep const& minMantissa)
{
TRACE_FUNC();
// Bring mantissa back into the minMantissa / maxMantissa range AFTER
// rounding
if (mantissa < minMantissa)
@@ -244,6 +257,7 @@ Number::Guard::doRoundUp(
internalrep const& maxMantissa,
std::string location)
{
TRACE_FUNC();
auto r = round();
if (r == 1 || (r == 0 && (mantissa & 1) == 1))
{
@@ -269,6 +283,7 @@ Number::Guard::doRoundDown(
int& exponent,
internalrep const& minMantissa)
{
TRACE_FUNC();
auto r = round();
if (r == 1 || (r == 0 && (mantissa & 1) == 1))
{
@@ -286,6 +301,7 @@ Number::Guard::doRoundDown(
void
Number::Guard::doRound(rep& drops, std::string location) const
{
TRACE_FUNC();
auto r = round();
if (r == 1 || (r == 0 && (drops & 1) == 1))
{
@@ -315,6 +331,7 @@ Number::Guard::doRound(rep& drops, std::string location) const
Number::internalrep
Number::externalToInternal(rep mantissa)
{
TRACE_FUNC();
// If the mantissa is already positive, just return it
if (mantissa >= 0)
return mantissa;
@@ -350,6 +367,7 @@ constexpr Number kONE_LRG = Number::oneLarge();
Number
Number::one()
{
TRACE_FUNC();
if (&kRANGE.get() == &kSMALL_RANGE)
return kONE_SML;
XRPL_ASSERT(&kRANGE.get() == &kLARGE_RANGE, "Number::one() : valid range");
@@ -367,6 +385,7 @@ doNormalize(
MantissaRange::rep const& minMantissa,
MantissaRange::rep const& maxMantissa)
{
TRACE_FUNC();
auto constexpr kMIN_EXPONENT = Number::kMIN_EXPONENT;
auto constexpr kMAX_EXPONENT = Number::kMAX_EXPONENT;
auto constexpr kMAX_REP = Number::kMAX_REP;
@@ -450,6 +469,7 @@ Number::normalize<uint128_t>(
internalrep const& minMantissa,
internalrep const& maxMantissa)
{
TRACE_FUNC();
doNormalize(negative, mantissa, exponent, minMantissa, maxMantissa);
}
@@ -462,6 +482,7 @@ Number::normalize<unsigned long long>(
internalrep const& minMantissa,
internalrep const& maxMantissa)
{
TRACE_FUNC();
doNormalize(negative, mantissa, exponent, minMantissa, maxMantissa);
}
@@ -474,12 +495,14 @@ Number::normalize<unsigned long>(
internalrep const& minMantissa,
internalrep const& maxMantissa)
{
TRACE_FUNC();
doNormalize(negative, mantissa, exponent, minMantissa, maxMantissa);
}
void
Number::normalize()
{
TRACE_FUNC();
auto const& range = kRANGE.get();
normalize(negative_, mantissa_, exponent_, range.min, range.max);
}
@@ -490,6 +513,7 @@ Number::normalize()
Number
Number::shiftExponent(int exponentDelta) const
{
TRACE_FUNC();
XRPL_ASSERT_PARTS(isnormal(), "xrpl::Number::shiftExponent", "normalized");
auto const newExponent = exponent_ + exponentDelta;
if (newExponent >= kMAX_EXPONENT)
@@ -506,6 +530,7 @@ Number::shiftExponent(int exponentDelta) const
Number&
Number::operator+=(Number const& y)
{
TRACE_FUNC();
constexpr Number kZERO = Number{};
if (y == kZERO)
return *this;
@@ -611,6 +636,7 @@ Number::operator+=(Number const& y)
static inline unsigned
divu10(uint128_t& u)
{
TRACE_FUNC();
// q = u * 0.75
auto q = (u >> 1) + (u >> 2);
// iterate towards q = u * 0.8
@@ -633,6 +659,7 @@ divu10(uint128_t& u)
Number&
Number::operator*=(Number const& y)
{
TRACE_FUNC();
constexpr Number kZERO = Number{};
if (*this == kZERO)
return *this;
@@ -696,6 +723,7 @@ Number::operator*=(Number const& y)
Number&
Number::operator/=(Number const& y)
{
TRACE_FUNC();
constexpr Number kZERO = Number{};
if (y == kZERO)
throw std::overflow_error("Number: divide by 0");
@@ -791,6 +819,7 @@ Number::operator/=(Number const& y)
Number::
operator rep() const
{
TRACE_FUNC();
rep drops = mantissa();
int offset = exponent();
Guard g;
@@ -820,6 +849,7 @@ operator rep() const
Number
Number::truncate() const noexcept
{
TRACE_FUNC();
if (exponent_ >= 0 || mantissa_ == 0)
return *this;
@@ -838,6 +868,7 @@ Number::truncate() const noexcept
std::string
to_string(Number const& amount)
{
TRACE_FUNC();
// keep full internal accuracy, but make more human friendly if possible
constexpr Number kZERO = Number{};
if (amount == kZERO)
@@ -936,6 +967,7 @@ to_string(Number const& amount)
Number
power(Number const& f, unsigned n)
{
TRACE_FUNC();
if (n == 0)
return Number::one();
if (n == 1)
@@ -959,6 +991,7 @@ power(Number const& f, unsigned n)
Number
root(Number f, unsigned d)
{
TRACE_FUNC();
constexpr Number kZERO = Number{};
auto const one = Number::one();
@@ -1031,6 +1064,7 @@ root(Number f, unsigned d)
Number
root2(Number f)
{
TRACE_FUNC();
constexpr Number kZERO = Number{};
auto const one = Number::one();
@@ -1078,6 +1112,7 @@ root2(Number f)
Number
power(Number const& f, unsigned n, unsigned d)
{
TRACE_FUNC();
constexpr Number kZERO = Number{};
auto const one = Number::one();

View File

@@ -6,6 +6,7 @@
#include <xrpl/beast/net/IPEndpoint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/dispatch.hpp>
@@ -47,6 +48,7 @@ class AsyncObject
public:
~AsyncObject()
{
TRACE_FUNC();
// Destroying the object with I/O pending? Not a clean exit!
XRPL_ASSERT(pending_.load() == 0, "xrpl::AsyncObject::~AsyncObject : nothing pending");
}
@@ -60,16 +62,19 @@ public:
public:
explicit CompletionCounter(Derived* owner) : owner_(owner)
{
TRACE_FUNC();
++owner_->pending_;
}
CompletionCounter(CompletionCounter const& other) : owner_(other.owner_)
{
TRACE_FUNC();
++owner_->pending_;
}
~CompletionCounter()
{
TRACE_FUNC();
if (--owner_->pending_ == 0)
owner_->asyncHandlersComplete();
}
@@ -84,12 +89,14 @@ public:
void
addReference()
{
TRACE_FUNC();
++pending_;
}
void
removeReference()
{
TRACE_FUNC();
if (--pending_ == 0)
(static_cast<Derived*>(this))->asyncHandlersComplete();
}
@@ -128,6 +135,7 @@ public:
template <class StringSequence>
Work(StringSequence const& inNames, HandlerType handler) : handler(std::move(handler))
{
TRACE_FUNC();
names.reserve(inNames.size());
std::reverse_copy(inNames.begin(), inNames.end(), std::back_inserter(names));
@@ -148,6 +156,7 @@ public:
~ResolverAsioImpl() override
{
TRACE_FUNC();
XRPL_ASSERT(work.empty(), "xrpl::ResolverAsioImpl::~ResolverAsioImpl : no pending work");
XRPL_ASSERT(stopped, "xrpl::ResolverAsioImpl::~ResolverAsioImpl : stopped");
}
@@ -157,6 +166,7 @@ public:
void
asyncHandlersComplete()
{
TRACE_FUNC();
std::unique_lock<std::mutex> const lk{mut};
asyncHandlersCompleted = true;
cv.notify_all();
@@ -171,6 +181,7 @@ public:
void
start() override
{
TRACE_FUNC();
XRPL_ASSERT(stopped == true, "xrpl::ResolverAsioImpl::start : stopped");
XRPL_ASSERT(stop_called == false, "xrpl::ResolverAsioImpl::start : not stopping");
@@ -187,6 +198,7 @@ public:
void
stopAsync() override
{
TRACE_FUNC();
if (!stop_called.exchange(true))
{
boost::asio::dispatch(
@@ -201,6 +213,7 @@ public:
void
stop() override
{
TRACE_FUNC();
stopAsync();
JLOG(journal.debug()) << "Waiting to stop";
@@ -213,6 +226,7 @@ public:
void
resolve(std::vector<std::string> const& names, HandlerType const& handler) override
{
TRACE_FUNC();
XRPL_ASSERT(stop_called == false, "xrpl::ResolverAsioImpl::resolve : not stopping");
XRPL_ASSERT(!names.empty(), "xrpl::ResolverAsioImpl::resolve : names non-empty");
@@ -231,6 +245,7 @@ public:
void
doStop(CompletionCounter)
{
TRACE_FUNC();
XRPL_ASSERT(stop_called == true, "xrpl::ResolverAsioImpl::do_stop : stopping");
if (!stopped.exchange(true))
@@ -250,6 +265,7 @@ public:
boost::asio::ip::tcp::resolver::results_type results,
CompletionCounter)
{
TRACE_FUNC();
if (ec == boost::asio::error::operation_aborted)
return;
@@ -278,6 +294,7 @@ public:
static HostAndPort
parseName(std::string const& str)
{
TRACE_FUNC();
// first attempt to parse as an endpoint (IP addr + port).
// If that doesn't succeed, fall back to generic name + port parsing
@@ -324,6 +341,7 @@ public:
void
doWork(CompletionCounter)
{
TRACE_FUNC();
if (stop_called)
return;
@@ -369,6 +387,7 @@ public:
void
doResolve(std::vector<std::string> const& names, HandlerType const& handler, CompletionCounter)
{
TRACE_FUNC();
XRPL_ASSERT(!names.empty(), "xrpl::ResolverAsioImpl::do_resolve : names non-empty");
if (!stop_called)
@@ -395,6 +414,7 @@ public:
std::unique_ptr<ResolverAsio>
ResolverAsio::make(boost::asio::io_context& ioContext, beast::Journal journal)
{
TRACE_FUNC();
return std::make_unique<ResolverAsioImpl>(ioContext, journal);
}

View File

@@ -3,6 +3,7 @@
#include <xrpl/basics/Blob.h>
#include <xrpl/beast/core/LexicalCast.h>
#include <xrpl/beast/net/IPEndpoint.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/algorithm/hex.hpp>
#include <boost/algorithm/string/case_conv.hpp>
@@ -22,6 +23,7 @@ namespace xrpl {
std::string
sqlBlobLiteral(Blob const& blob)
{
TRACE_FUNC();
std::string j;
j.reserve((blob.size() * 2) + 3);
@@ -36,6 +38,7 @@ sqlBlobLiteral(Blob const& blob)
bool
parseUrl(ParsedUrl& pUrl, std::string const& strUrl)
{
TRACE_FUNC();
// scheme://username:password@hostname:port/rest
static boost::regex const kRE_URL(
"(?i)\\`\\s*"
@@ -96,6 +99,7 @@ parseUrl(ParsedUrl& pUrl, std::string const& strUrl)
std::string
trimWhitespace(std::string str)
{
TRACE_FUNC();
boost::trim(str);
return str;
}
@@ -103,6 +107,7 @@ trimWhitespace(std::string str)
std::optional<std::uint64_t>
toUint64(std::string const& s)
{
TRACE_FUNC();
std::uint64_t result = 0;
if (beast::lexicalCastChecked(result, s))
return result;
@@ -112,6 +117,7 @@ toUint64(std::string const& s)
bool
isProperlyFormedTomlDomain(std::string_view domain)
{
TRACE_FUNC();
// The domain must be between 4 and 128 characters long
if (domain.size() < 4 || domain.size() > 128)
return false;

View File

@@ -0,0 +1,304 @@
#include <xrpl/basics/TraceLog.h>
#include <atomic>
#include <chrono>
#include <cstdio>
#include <cstring>
#include <mutex>
#include <random>
#include <string>
#include <thread>
namespace xrpl {
namespace {
std::atomic<bool> s_enabled{false};
std::atomic<double> s_samplingRate{1.0};
std::atomic<std::uint64_t> s_nextSpanId{1};
std::mutex s_fileMutex;
std::FILE* s_file{nullptr};
std::string s_basePath;
std::uint64_t s_maxFileSize{500ULL * 1024 * 1024};
int s_maxFiles{10};
std::uint64_t s_currentFileSize{0};
constexpr int kMaxStackDepth = 512;
constexpr std::size_t kFlushThreshold = 65536;
struct ThreadContext
{
std::uint64_t traceId{0};
std::uint64_t spanStack[kMaxStackDepth];
int stackDepth{0};
bool sampled{true};
std::string buffer;
};
thread_local ThreadContext t_ctx;
std::uint64_t
generateTraceId()
{
thread_local std::mt19937_64 rng(
std::chrono::steady_clock::now().time_since_epoch().count() ^
std::hash<std::thread::id>{}(std::this_thread::get_id()));
return rng();
}
void
rotateFiles()
{
if (s_file)
{
std::fclose(s_file);
s_file = nullptr;
}
// traces.jsonl.9 -> delete, traces.jsonl.8 -> .9, ... .0 -> .1
for (int i = s_maxFiles - 1; i >= 0; --i)
{
std::string src =
(i == 0) ? s_basePath : (s_basePath + "." + std::to_string(i));
std::string dst = s_basePath + "." + std::to_string(i + 1);
if (i == s_maxFiles - 1)
std::remove(src.c_str());
else
std::rename(src.c_str(), dst.c_str());
}
s_file = std::fopen(s_basePath.c_str(), "w");
s_currentFileSize = 0;
}
void
flushBuffer()
{
if (t_ctx.buffer.empty())
return;
std::lock_guard<std::mutex> lock(s_fileMutex);
if (s_file)
{
auto written =
std::fwrite(t_ctx.buffer.data(), 1, t_ctx.buffer.size(), s_file);
std::fflush(s_file);
s_currentFileSize += written;
if (s_currentFileSize >= s_maxFileSize)
rotateFiles();
}
t_ctx.buffer.clear();
}
char const*
extractFilename(char const* path)
{
char const* last = path;
for (char const* p = path; *p; ++p)
{
if (*p == '/' || *p == '\\')
last = p + 1;
}
return last;
}
void
appendJsonString(std::string& buf, char const* s)
{
buf += '"';
for (; *s; ++s)
{
switch (*s)
{
case '"':
buf += "\\\"";
break;
case '\\':
buf += "\\\\";
break;
case '\n':
buf += "\\n";
break;
case '\r':
buf += "\\r";
break;
case '\t':
buf += "\\t";
break;
default:
buf += *s;
}
}
buf += '"';
}
void
appendHex(std::string& buf, std::uint64_t val)
{
static constexpr char kHEX[] = "0123456789abcdef";
char hex[17];
for (int i = 15; i >= 0; --i)
{
hex[i] = kHEX[val & 0xf];
val >>= 4;
}
hex[16] = '\0';
buf.append(hex, 16);
}
void
writeSpan(
std::uint64_t traceId,
std::uint64_t spanId,
std::uint64_t parentId,
char const* name,
char const* file,
int line,
std::int64_t startUs,
std::int64_t durUs)
{
auto& buf = t_ctx.buffer;
buf += "{\"name\":";
appendJsonString(buf, name);
buf += ",\"trace\":\"";
appendHex(buf, traceId);
buf += "\",\"span\":\"";
appendHex(buf, spanId);
buf += "\",\"parent\":\"";
appendHex(buf, parentId);
buf += "\",\"file\":";
appendJsonString(buf, extractFilename(file));
buf += ",\"line\":";
buf += std::to_string(line);
buf += ",\"start_us\":";
buf += std::to_string(startUs);
buf += ",\"dur_us\":";
buf += std::to_string(durUs);
buf += "}\n";
if (buf.size() > kFlushThreshold || t_ctx.stackDepth == 0)
flushBuffer();
}
} // namespace
namespace tracing {
void
init(char const* outputPath, double samplingRate, std::uint64_t maxFileSizeMB, int maxFiles)
{
std::lock_guard<std::mutex> lock(s_fileMutex);
if (s_file)
std::fclose(s_file);
s_basePath = outputPath;
s_maxFileSize = maxFileSizeMB * 1024ULL * 1024ULL;
s_maxFiles = maxFiles;
s_file = std::fopen(outputPath, "a");
if (s_file)
{
std::fseek(s_file, 0, SEEK_END);
s_currentFileSize = static_cast<std::uint64_t>(std::ftell(s_file));
}
s_samplingRate.store(samplingRate, std::memory_order_relaxed);
s_enabled.store(s_file != nullptr, std::memory_order_release);
}
void
shutdown()
{
s_enabled.store(false, std::memory_order_release);
std::lock_guard<std::mutex> lock(s_fileMutex);
if (s_file)
{
std::fclose(s_file);
s_file = nullptr;
}
}
} // namespace tracing
TraceScope::TraceScope(
char const* func,
char const* file,
int line) noexcept
: spanId_(0)
, traceId_(0)
, parentId_(0)
, func_(func)
, file_(file)
, line_(line)
, startUs_(0)
, active_(false)
{
if (!s_enabled.load(std::memory_order_relaxed))
return;
spanId_ = s_nextSpanId.fetch_add(1, std::memory_order_relaxed);
if (t_ctx.stackDepth == 0)
{
traceId_ = generateTraceId();
parentId_ = 0;
double rate = s_samplingRate.load(std::memory_order_relaxed);
if (rate < 1.0)
{
thread_local std::mt19937 samplerRng(std::random_device{}());
std::uniform_real_distribution<double> dist(0.0, 1.0);
t_ctx.sampled = dist(samplerRng) < rate;
}
else
{
t_ctx.sampled = true;
}
}
else
{
traceId_ = t_ctx.traceId;
parentId_ = t_ctx.spanStack[t_ctx.stackDepth - 1];
}
t_ctx.traceId = traceId_;
if (t_ctx.stackDepth < kMaxStackDepth)
t_ctx.spanStack[t_ctx.stackDepth] = spanId_;
++t_ctx.stackDepth;
if (!t_ctx.sampled)
return;
startUs_ = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count();
active_ = true;
}
TraceScope::~TraceScope() noexcept
{
if (spanId_ == 0)
return;
if (active_)
{
auto const endUs =
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count();
writeSpan(
traceId_,
spanId_,
parentId_,
func_,
file_,
line_,
startUs_,
endUs - startUs_);
}
--t_ctx.stackDepth;
if (t_ctx.stackDepth == 0)
t_ctx.traceId = 0;
}
} // namespace xrpl

View File

@@ -1,5 +1,6 @@
#include <xrpl/basics/UptimeClock.h>
#include <xrpl/basics/TraceLog.h>
#include <atomic>
#include <chrono>
@@ -13,6 +14,7 @@ std::atomic<bool> UptimeClock::kSTOP{false}; // stop update thread
// On xrpld shutdown, cancel and wait for the update thread
UptimeClock::UpdateThread::~UpdateThread()
{
TRACE_FUNC();
if (joinable())
{
kSTOP = true;
@@ -26,6 +28,7 @@ UptimeClock::UpdateThread::~UpdateThread()
UptimeClock::UpdateThread
UptimeClock::startClock()
{
TRACE_FUNC();
return UpdateThread{[] {
using namespace std;
using namespace std::chrono;
@@ -48,6 +51,7 @@ UptimeClock::startClock()
UptimeClock::time_point
UptimeClock::now()
{
TRACE_FUNC();
// start the update thread on first use
static auto const kINIT = startClock();

View File

@@ -33,6 +33,7 @@
*/
#include <xrpl/basics/base64.h>
#include <xrpl/basics/TraceLog.h>
#include <cstddef>
#include <cstdint>
@@ -47,6 +48,7 @@ namespace base64 {
inline char const*
getAlphabet()
{
TRACE_FUNC();
static char constexpr kTAB[] = {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"};
return &kTAB[0];
@@ -55,6 +57,7 @@ getAlphabet()
inline signed char const*
getInverse()
{
TRACE_FUNC();
static signed char constexpr 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
@@ -103,6 +106,7 @@ std::size_t constexpr decodedSize(std::size_t n)
std::size_t
encode(void* dest, void const* src, std::size_t len)
{
TRACE_FUNC();
char* out = static_cast<char*>(dest); // NOLINT(misc-const-correctness)
char const* in = static_cast<char const*>(src);
auto const tab = base64::getAlphabet();
@@ -154,6 +158,7 @@ encode(void* dest, void const* src, std::size_t len)
std::pair<std::size_t, std::size_t>
decode(void* dest, char const* src, std::size_t len)
{
TRACE_FUNC();
char* out = static_cast<char*>(dest); // NOLINT(misc-const-correctness)
auto in = reinterpret_cast<unsigned char const*>(src);
unsigned char c3[3]{}, c4[4]{};
@@ -199,6 +204,7 @@ decode(void* dest, char const* src, std::size_t len)
std::string
base64Encode(std::uint8_t const* data, std::size_t len)
{
TRACE_FUNC();
std::string dest;
dest.resize(base64::encodedSize(len));
dest.resize(base64::encode(&dest[0], data, len));
@@ -208,6 +214,7 @@ base64Encode(std::uint8_t const* data, std::size_t len)
std::string
base64Decode(std::string_view data)
{
TRACE_FUNC();
std::string dest;
dest.resize(base64::decodedSize(data.size()));
auto const result = base64::decode(&dest[0], data.data(), data.size());

View File

@@ -2,6 +2,7 @@
#include <xrpl/basics/Log.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdlib>
#include <iostream>
@@ -12,12 +13,14 @@ namespace xrpl {
void
logThrow(std::string const& title)
{
TRACE_FUNC();
JLOG(debugLog().warn()) << title;
}
[[noreturn]] void
logicError(std::string const& s) noexcept
{
TRACE_FUNC();
// LCOV_EXCL_START
JLOG(debugLog().fatal()) << s;
std::cerr << "Logic error: " << s << std::endl;

View File

@@ -1,6 +1,7 @@
#include <xrpl/basics/make_SSLContext.h>
#include <xrpl/basics/contract.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/asio/ssl/context.hpp>
#include <boost/asio/ssl/verify_mode.hpp>
@@ -89,6 +90,7 @@ std::string const kDEFAULT_CIPHER_LIST = "TLSv1.2:!CBC:!DSS:!PSK:!eNULL:!aNULL";
static void
initAnonymous(boost::asio::ssl::context& context)
{
TRACE_FUNC();
using namespace openssl;
static auto kDEFAULT_RSA = []() {
@@ -229,6 +231,7 @@ initAuthenticated(
std::string const& certFile,
std::string const& chainFile)
{
TRACE_FUNC();
auto fmtError = [](boost::system::error_code ec) -> std::string {
return " [" + std::to_string(ec.value()) + ": " + ec.message() + "]";
};
@@ -321,6 +324,7 @@ initAuthenticated(
std::shared_ptr<boost::asio::ssl::context>
getContext(std::string cipherList)
{
TRACE_FUNC();
auto c = std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23);
c->set_options(
@@ -352,6 +356,7 @@ getContext(std::string cipherList)
std::shared_ptr<boost::asio::ssl::context>
makeSslContext(std::string const& cipherList)
{
TRACE_FUNC();
auto context = openssl::detail::getContext(cipherList);
openssl::detail::initAnonymous(*context);
// VFALCO NOTE, It seems the WebSocket context never has
@@ -367,6 +372,7 @@ makeSslContextAuthed(
std::string const& chainFile,
std::string const& cipherList)
{
TRACE_FUNC();
auto context = openssl::detail::getContext(cipherList);
openssl::detail::initAuthenticated(*context, keyFile, certFile, chainFile);
return context;

View File

@@ -1,4 +1,5 @@
#include <xrpl/basics/mulDiv.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/multiprecision/cpp_int.hpp> // IWYU pragma: keep
@@ -10,6 +11,7 @@ namespace xrpl {
std::optional<std::uint64_t>
mulDiv(std::uint64_t value, std::uint64_t mul, std::uint64_t div)
{
TRACE_FUNC();
boost::multiprecision::uint128_t result;
result = multiply(result, value, mul);

View File

@@ -5,6 +5,7 @@
#include <xrpl/conditions/detail/PreimageSha256.h>
#include <xrpl/conditions/detail/error.h>
#include <xrpl/conditions/detail/utils.h>
#include <xrpl/basics/TraceLog.h>
#include <cstddef>
#include <cstdint>
@@ -57,6 +58,7 @@ constexpr std::size_t kFINGERPRINT_SIZE = 32;
std::unique_ptr<Condition>
loadSimpleSha256(Type type, Slice s, std::error_code& ec)
{
TRACE_FUNC();
using namespace der;
auto p = parsePreamble(s, ec);
@@ -137,6 +139,7 @@ loadSimpleSha256(Type type, Slice s, std::error_code& ec)
std::unique_ptr<Condition>
Condition::deserialize(Slice s, std::error_code& ec)
{
TRACE_FUNC();
// Per the RFC, in a condition we choose a type based
// on the tag of the item we contain:
//

View File

@@ -6,6 +6,7 @@
#include <xrpl/conditions/detail/PreimageSha256.h>
#include <xrpl/conditions/detail/error.h>
#include <xrpl/conditions/detail/utils.h>
#include <xrpl/basics/TraceLog.h>
#include <memory>
#include <system_error>
@@ -15,6 +16,7 @@ namespace xrpl::cryptoconditions {
bool
match(Fulfillment const& f, Condition const& c)
{
TRACE_FUNC();
// Fast check: the fulfillment's type must match the
// conditions's type:
if (f.type() != c.type)
@@ -28,18 +30,21 @@ match(Fulfillment const& f, Condition const& c)
bool
validate(Fulfillment const& f, Condition const& c, Slice m)
{
TRACE_FUNC();
return match(f, c) && f.validate(m);
}
bool
validate(Fulfillment const& f, Condition const& c)
{
TRACE_FUNC();
return validate(f, c, {});
}
std::unique_ptr<Fulfillment>
Fulfillment::deserialize(Slice s, std::error_code& ec)
{
TRACE_FUNC();
// Per the RFC, in a fulfillment we choose a type based
// on the tag of the item we contain:
//

View File

@@ -1,6 +1,7 @@
#include <xrpl/conditions/detail/error.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/basics/TraceLog.h>
#include <string>
#include <system_error>
@@ -17,12 +18,14 @@ public:
[[nodiscard]] char const*
name() const noexcept override
{
TRACE_FUNC();
return "cryptoconditions";
}
[[nodiscard]] std::string
message(int ev) const override
{
TRACE_FUNC();
switch (safeCast<Error>(ev))
{
case Error::UnsupportedType:
@@ -82,18 +85,21 @@ public:
[[nodiscard]] std::error_condition
default_error_condition(int ev) const noexcept override
{
TRACE_FUNC();
return std::error_condition{ev, *this};
}
[[nodiscard]] bool
equivalent(int ev, std::error_condition const& condition) const noexcept override
{
TRACE_FUNC();
return &condition.category() == this && condition.value() == ev;
}
[[nodiscard]] bool
equivalent(std::error_code const& error, int ev) const noexcept override
{
TRACE_FUNC();
return &error.category() == this && error.value() == ev;
}
};
@@ -101,6 +107,7 @@ public:
inline std::error_category const&
getCryptoconditionsErrorCategory()
{
TRACE_FUNC();
static CryptoconditionsErrorCategory const kCAT{};
return kCAT;
}
@@ -110,6 +117,7 @@ getCryptoconditionsErrorCategory()
std::error_code
make_error_code(Error ev)
{
TRACE_FUNC();
return std::error_code{
safeCast<std::underlying_type_t<Error>>(ev), detail::getCryptoconditionsErrorCategory()};
}

View File

@@ -4,6 +4,7 @@
#include <xrpl/basics/chrono.h>
#include <xrpl/beast/container/detail/aged_unordered_container.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/basics/TraceLog.h>
#include <chrono>
#include <functional>
@@ -17,6 +18,7 @@ namespace xrpl {
auto
HashRouter::emplace(uint256 const& key) -> std::pair<Entry&, bool>
{
TRACE_FUNC();
auto iter = suppressionMap_.find(key);
if (iter != suppressionMap_.end())
@@ -34,6 +36,7 @@ HashRouter::emplace(uint256 const& key) -> std::pair<Entry&, bool>
void
HashRouter::addSuppression(uint256 const& key)
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
emplace(key);
@@ -42,12 +45,14 @@ HashRouter::addSuppression(uint256 const& key)
bool
HashRouter::addSuppressionPeer(uint256 const& key, PeerShortID peer)
{
TRACE_FUNC();
return addSuppressionPeerWithStatus(key, peer).first;
}
std::pair<bool, std::optional<Stopwatch::time_point>>
HashRouter::addSuppressionPeerWithStatus(uint256 const& key, PeerShortID peer)
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
auto result = emplace(key);
@@ -58,6 +63,7 @@ HashRouter::addSuppressionPeerWithStatus(uint256 const& key, PeerShortID peer)
bool
HashRouter::addSuppressionPeer(uint256 const& key, PeerShortID peer, HashRouterFlags& flags)
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
auto [s, created] = emplace(key);
@@ -73,6 +79,7 @@ HashRouter::shouldProcess(
HashRouterFlags& flags,
std::chrono::seconds txInterval)
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
auto result = emplace(key);
@@ -85,6 +92,7 @@ HashRouter::shouldProcess(
HashRouterFlags
HashRouter::getFlags(uint256 const& key)
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
return emplace(key).first.getFlags();
@@ -93,6 +101,7 @@ HashRouter::getFlags(uint256 const& key)
bool
HashRouter::setFlags(uint256 const& key, HashRouterFlags flags)
{
TRACE_FUNC();
XRPL_ASSERT(static_cast<bool>(flags), "xrpl::HashRouter::setFlags : valid input");
std::scoped_lock const lock(mutex_);
@@ -109,6 +118,7 @@ HashRouter::setFlags(uint256 const& key, HashRouterFlags flags)
auto
HashRouter::shouldRelay(uint256 const& key) -> std::optional<std::set<PeerShortID>>
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
auto& s = emplace(key).first;

View File

@@ -3,6 +3,7 @@
#include <xrpl/beast/core/CurrentThreadName.h>
#include <xrpl/core/LoadEvent.h>
#include <xrpl/core/LoadMonitor.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdint>
#include <functional>
@@ -27,24 +28,28 @@ Job::Job(
std::function<void()> const& job)
: type_(type), jobIndex_(index), job_(job), name_(name), queue_time_(clock_type::now())
{
TRACE_FUNC();
loadEvent_ = std::make_shared<LoadEvent>(std::ref(lm), name, false);
}
JobType
Job::getType() const
{
TRACE_FUNC();
return type_;
}
Job::clock_type::time_point const&
Job::queueTime() const
{
TRACE_FUNC();
return queue_time_;
}
void
Job::doJob()
{
TRACE_FUNC();
beast::setCurrentThreadName("j:" + name_);
loadEvent_->start();
loadEvent_->setName(name_);
@@ -59,6 +64,7 @@ Job::doJob()
bool
Job::operator>(Job const& j) const
{
TRACE_FUNC();
if (type_ < j.type_)
return true;
@@ -71,6 +77,7 @@ Job::operator>(Job const& j) const
bool
Job::operator>=(Job const& j) const
{
TRACE_FUNC();
if (type_ < j.type_)
return true;
@@ -83,6 +90,7 @@ Job::operator>=(Job const& j) const
bool
Job::operator<(Job const& j) const
{
TRACE_FUNC();
if (type_ < j.type_)
return false;
@@ -95,6 +103,7 @@ Job::operator<(Job const& j) const
bool
Job::operator<=(Job const& j) const
{
TRACE_FUNC();
if (type_ < j.type_)
return false;

View File

@@ -9,6 +9,7 @@
#include <xrpl/core/LoadEvent.h>
#include <xrpl/core/PerfLog.h>
#include <xrpl/json/json_value.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <chrono>
@@ -33,6 +34,7 @@ JobQueue::JobQueue(
, perfLog_(perfLog)
, collector_(collector)
{
TRACE_FUNC();
JLOG(journal_.info()) << "Using " << threadCount << " threads";
hook_ = collector_->makeHook(std::bind(&JobQueue::collect, this));
@@ -58,6 +60,7 @@ JobQueue::JobQueue(
JobQueue::~JobQueue()
{
TRACE_FUNC();
// Must unhook before destroying
hook_ = beast::insight::Hook();
}
@@ -65,6 +68,7 @@ JobQueue::~JobQueue()
void
JobQueue::collect()
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
job_count_ = jobSet_.size();
}
@@ -72,6 +76,7 @@ JobQueue::collect()
bool
JobQueue::addRefCountedJob(JobType type, std::string const& name, JobFunction const& func)
{
TRACE_FUNC();
XRPL_ASSERT(type != JtInvalid, "xrpl::JobQueue::addRefCountedJob : valid input job type");
auto iter(jobData_.find(type));
@@ -119,6 +124,7 @@ JobQueue::addRefCountedJob(JobType type, std::string const& name, JobFunction co
int
JobQueue::getJobCount(JobType t) const
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
JobDataMap::const_iterator const c = jobData_.find(t);
@@ -129,6 +135,7 @@ JobQueue::getJobCount(JobType t) const
int
JobQueue::getJobCountTotal(JobType t) const
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
JobDataMap::const_iterator const c = jobData_.find(t);
@@ -139,6 +146,7 @@ JobQueue::getJobCountTotal(JobType t) const
int
JobQueue::getJobCountGE(JobType t) const
{
TRACE_FUNC();
// return the number of jobs at this priority level or greater
int ret = 0;
@@ -156,6 +164,7 @@ JobQueue::getJobCountGE(JobType t) const
std::unique_ptr<LoadEvent>
JobQueue::makeLoadEvent(JobType t, std::string const& name)
{
TRACE_FUNC();
JobDataMap::iterator const iter(jobData_.find(t));
XRPL_ASSERT(iter != jobData_.end(), "xrpl::JobQueue::makeLoadEvent : valid job type input");
@@ -168,6 +177,7 @@ JobQueue::makeLoadEvent(JobType t, std::string const& name)
void
JobQueue::addLoadEvents(JobType t, int count, std::chrono::milliseconds elapsed)
{
TRACE_FUNC();
if (isStopped())
logicError("JobQueue::addLoadEvents() called after JobQueue stopped");
@@ -179,12 +189,14 @@ JobQueue::addLoadEvents(JobType t, int count, std::chrono::milliseconds elapsed)
bool
JobQueue::isOverloaded()
{
TRACE_FUNC();
return std::ranges::any_of(jobData_, [](auto& entry) { return entry.second.load().isOver(); });
}
json::Value
JobQueue::getJson(int c)
{
TRACE_FUNC();
using namespace std::chrono_literals;
json::Value ret(json::ObjectValue);
@@ -242,6 +254,7 @@ JobQueue::getJson(int c)
void
JobQueue::rendezvous()
{
TRACE_FUNC();
std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [this] { return processCount_ == 0 && jobSet_.empty(); });
}
@@ -249,6 +262,7 @@ JobQueue::rendezvous()
JobTypeData&
JobQueue::getJobTypeData(JobType type)
{
TRACE_FUNC();
JobDataMap::iterator const c(jobData_.find(type));
XRPL_ASSERT(c != jobData_.end(), "xrpl::JobQueue::getJobTypeData : valid job type input");
@@ -263,6 +277,7 @@ JobQueue::getJobTypeData(JobType type)
void
JobQueue::stop()
{
TRACE_FUNC();
stopping_ = true;
using namespace std::chrono_literals;
jobCounter_.join("JobQueue", 1s, journal_);
@@ -284,12 +299,14 @@ JobQueue::stop()
bool
JobQueue::isStopped() const
{
TRACE_FUNC();
return stopped_;
}
void
JobQueue::getNextJob(Job& job)
{
TRACE_FUNC();
XRPL_ASSERT(!jobSet_.empty(), "xrpl::JobQueue::getNextJob : non-empty jobs");
std::set<Job>::const_iterator iter;
@@ -320,6 +337,7 @@ JobQueue::getNextJob(Job& job)
void
JobQueue::finishJob(JobType type)
{
TRACE_FUNC();
XRPL_ASSERT(type != JtInvalid, "xrpl::JobQueue::finishJob : valid input job type");
JobTypeData& data = getJobTypeData(type);
@@ -341,6 +359,7 @@ JobQueue::finishJob(JobType type)
void
JobQueue::processTask(int instance)
{
TRACE_FUNC();
JobType type = JtInvalid;
{
@@ -392,6 +411,7 @@ JobQueue::processTask(int instance)
int
JobQueue::getJobLimit(JobType type)
{
TRACE_FUNC();
JobTypeInfo const& j(JobTypes::instance().get(type));
XRPL_ASSERT(j.type() != JtInvalid, "xrpl::JobQueue::getJobLimit : valid job type");

View File

@@ -2,6 +2,7 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/core/LoadMonitor.h>
#include <xrpl/basics/TraceLog.h>
#include <chrono>
#include <string>
@@ -21,6 +22,7 @@ LoadEvent::LoadEvent(LoadMonitor& monitor, std::string name, bool shouldStart)
LoadEvent::~LoadEvent()
{
TRACE_FUNC();
if (running_)
stop();
}
@@ -28,30 +30,35 @@ LoadEvent::~LoadEvent()
std::string const&
LoadEvent::name() const
{
TRACE_FUNC();
return name_;
}
std::chrono::steady_clock::duration
LoadEvent::waitTime() const
{
TRACE_FUNC();
return timeWaiting_;
}
std::chrono::steady_clock::duration
LoadEvent::runTime() const
{
TRACE_FUNC();
return timeRunning_;
}
void
LoadEvent::setName(std::string const& name)
{
TRACE_FUNC();
name_ = name;
}
void
LoadEvent::start()
{
TRACE_FUNC();
auto const now = std::chrono::steady_clock::now();
// If we had already called start, this call will
@@ -65,6 +72,7 @@ LoadEvent::start()
void
LoadEvent::stop()
{
TRACE_FUNC();
XRPL_ASSERT(running_, "xrpl::LoadEvent::stop : is running");
auto const now = std::chrono::steady_clock::now();

View File

@@ -4,6 +4,7 @@
#include <xrpl/basics/UptimeClock.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/core/LoadEvent.h>
#include <xrpl/basics/TraceLog.h>
#include <chrono>
#include <mutex>
@@ -46,6 +47,7 @@ LoadMonitor::LoadMonitor(beast::Journal j)
void
LoadMonitor::update()
{
TRACE_FUNC();
using namespace std::chrono_literals;
auto now = UptimeClock::now();
if (now == lastUpdate_) // current
@@ -84,6 +86,7 @@ LoadMonitor::update()
void
LoadMonitor::addLoadSample(LoadEvent const& s)
{
TRACE_FUNC();
using namespace std::chrono;
auto const total = s.runTime() + s.waitTime();
@@ -108,6 +111,7 @@ LoadMonitor::addLoadSample(LoadEvent const& s)
void
LoadMonitor::addSamples(int count, std::chrono::milliseconds latency)
{
TRACE_FUNC();
std::scoped_lock const sl(mutex_);
update();
@@ -125,6 +129,7 @@ LoadMonitor::addSamples(int count, std::chrono::milliseconds latency)
void
LoadMonitor::setTargetLatency(std::chrono::milliseconds avg, std::chrono::milliseconds pk)
{
TRACE_FUNC();
targetLatencyAvg_ = avg;
targetLatencyPk_ = pk;
}
@@ -132,6 +137,7 @@ LoadMonitor::setTargetLatency(std::chrono::milliseconds avg, std::chrono::millis
bool
LoadMonitor::isOverTarget(std::chrono::milliseconds avg, std::chrono::milliseconds peak)
{
TRACE_FUNC();
using namespace std::chrono_literals;
return (targetLatencyPk_ > 0ms && (peak > targetLatencyPk_)) ||
(targetLatencyAvg_ > 0ms && (avg > targetLatencyAvg_));
@@ -140,6 +146,7 @@ LoadMonitor::isOverTarget(std::chrono::milliseconds avg, std::chrono::millisecon
bool
LoadMonitor::isOver()
{
TRACE_FUNC();
std::scoped_lock const sl(mutex_);
update();
@@ -154,6 +161,7 @@ LoadMonitor::isOver()
LoadMonitor::Stats
LoadMonitor::getStats()
{
TRACE_FUNC();
using namespace std::chrono_literals;
Stats stats;

View File

@@ -3,6 +3,7 @@
#include <xrpl/beast/core/CurrentThreadName.h>
#include <xrpl/beast/core/LockFreeStack.h>
#include <xrpl/core/PerfLog.h>
#include <xrpl/basics/TraceLog.h>
#include <mutex>
#include <string>
@@ -23,11 +24,13 @@ Workers::Workers(
, pauseCount_(0)
, runningTaskCount_(0)
{
TRACE_FUNC();
setNumberOfThreads(numberOfThreads);
}
Workers::~Workers()
{
TRACE_FUNC();
stop();
deleteWorkers(everyone_);
@@ -36,6 +39,7 @@ Workers::~Workers()
int
Workers::getNumberOfThreads() const noexcept
{
TRACE_FUNC();
return numberOfThreads_;
}
@@ -46,6 +50,7 @@ Workers::getNumberOfThreads() const noexcept
void
Workers::setNumberOfThreads(int numberOfThreads)
{
TRACE_FUNC();
static int kINSTANCE{0};
if (numberOfThreads_ == numberOfThreads)
return;
@@ -97,6 +102,7 @@ Workers::setNumberOfThreads(int numberOfThreads)
void
Workers::stop()
{
TRACE_FUNC();
setNumberOfThreads(0);
// Wait until all workers have paused AND no tasks are actively running.
@@ -111,18 +117,21 @@ Workers::stop()
void
Workers::addTask()
{
TRACE_FUNC();
semaphore_.notify();
}
int
Workers::numberOfCurrentlyRunningTasks() const noexcept
{
TRACE_FUNC();
return runningTaskCount_.load();
}
void
Workers::deleteWorkers(beast::LockFreeStack<Worker>& stack)
{
TRACE_FUNC();
for (;;)
{
Worker const* const worker = stack.popFront();
@@ -145,11 +154,13 @@ Workers::Worker::Worker(Workers& workers, std::string threadName, int const inst
: workers_{workers}, threadName_{std::move(threadName)}, instance_{instance}
{
TRACE_FUNC();
thread_ = std::thread{&Workers::Worker::run, this};
}
Workers::Worker::~Worker()
{
TRACE_FUNC();
{
std::scoped_lock const lock{mutex_};
++wakeCount_;
@@ -163,6 +174,7 @@ Workers::Worker::~Worker()
void
Workers::Worker::notify()
{
TRACE_FUNC();
std::scoped_lock const lock{mutex_};
++wakeCount_;
wakeup_.notify_one();
@@ -171,6 +183,7 @@ Workers::Worker::notify()
void
Workers::Worker::run()
{
TRACE_FUNC();
bool shouldExit = true;
do
{

View File

@@ -1,6 +1,7 @@
#include <xrpl/crypto/RFC1751.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/constants.hpp>
@@ -199,6 +200,7 @@ char const* RFC1751::dictionary[2048] = {
unsigned long
RFC1751::extract(char const* s, int start, int length)
{
TRACE_FUNC();
unsigned char cl = 0;
unsigned char cc = 0;
unsigned char cr = 0;
@@ -226,6 +228,7 @@ RFC1751::extract(char const* s, int start, int length)
void
RFC1751::btoe(std::string& strHuman, std::string const& strData)
{
TRACE_FUNC();
char caBuffer[9]; /* add in room for the parity 2 bits*/
int p = 0, i = 0;
@@ -246,6 +249,7 @@ RFC1751::btoe(std::string& strHuman, std::string const& strData)
void
RFC1751::insert(char* s, int x, int start, int length)
{
TRACE_FUNC();
unsigned char cl = 0;
unsigned char cc = 0;
unsigned char cr = 0;
@@ -283,6 +287,7 @@ RFC1751::insert(char* s, int x, int start, int length)
void
RFC1751::standard(std::string& strWord)
{
TRACE_FUNC();
for (auto& letter : strWord)
{
if (islower(static_cast<unsigned char>(letter)) != 0)
@@ -308,6 +313,7 @@ RFC1751::standard(std::string& strWord)
int
RFC1751::wsrch(std::string const& strWord, int iMin, int iMax)
{
TRACE_FUNC();
int iResult = -1;
while (iResult < 0 && iMin != iMax)
@@ -342,6 +348,7 @@ RFC1751::wsrch(std::string const& strWord, int iMin, int iMax)
int
RFC1751::etob(std::string& strData, std::vector<std::string> vsHuman)
{
TRACE_FUNC();
if (6 != vsHuman.size())
return -1;
@@ -389,6 +396,7 @@ RFC1751::etob(std::string& strData, std::vector<std::string> vsHuman)
int
RFC1751::getKeyFromEnglish(std::string& strKey, std::string const& strHuman)
{
TRACE_FUNC();
std::vector<std::string> vWords;
std::string strFirst, strSecond;
int rc = 0;
@@ -419,6 +427,7 @@ RFC1751::getKeyFromEnglish(std::string& strKey, std::string const& strHuman)
void
RFC1751::getEnglishFromKey(std::string& strHuman, std::string const& strKey)
{
TRACE_FUNC();
std::string strFirst, strSecond;
btoe(strFirst, strKey.substr(0, 8));
@@ -430,6 +439,7 @@ RFC1751::getEnglishFromKey(std::string& strHuman, std::string const& strKey)
std::string
RFC1751::getWordFromBlob(void const* blob, size_t bytes)
{
TRACE_FUNC();
// This is a simple implementation of the Jenkins one-at-a-time hash
// algorithm:
// http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time

View File

@@ -1,6 +1,7 @@
#include <xrpl/crypto/csprng.h>
#include <xrpl/basics/contract.h>
#include <xrpl/basics/TraceLog.h>
#include <openssl/opensslv.h>
#include <openssl/rand.h>
@@ -15,6 +16,7 @@ namespace xrpl {
CsprngEngine::CsprngEngine()
{
TRACE_FUNC();
// This is not strictly necessary
if (RAND_poll() != 1)
Throw<std::runtime_error>("CSPRNG: Initial polling failed");
@@ -22,6 +24,7 @@ CsprngEngine::CsprngEngine()
CsprngEngine::~CsprngEngine()
{
TRACE_FUNC();
// This cleanup function is not needed in newer versions of OpenSSL
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
RAND_cleanup();
@@ -31,6 +34,7 @@ CsprngEngine::~CsprngEngine()
void
CsprngEngine::mixEntropy(void* buffer, std::size_t count)
{
TRACE_FUNC();
std::array<std::random_device::result_type, 128> entropy{};
{
@@ -56,6 +60,7 @@ CsprngEngine::mixEntropy(void* buffer, std::size_t count)
void
CsprngEngine::operator()(void* ptr, std::size_t count)
{
TRACE_FUNC();
// 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
@@ -72,6 +77,7 @@ CsprngEngine::operator()(void* ptr, std::size_t count)
CsprngEngine::result_type
CsprngEngine::operator()()
{
TRACE_FUNC();
result_type ret = 0;
(*this)(&ret, sizeof(result_type));
return ret;
@@ -80,6 +86,7 @@ CsprngEngine::operator()()
CsprngEngine&
cryptoPrng()
{
TRACE_FUNC();
static CsprngEngine kENGINE;
return kENGINE;
}

View File

@@ -1,4 +1,5 @@
#include <xrpl/crypto/secure_erase.h>
#include <xrpl/basics/TraceLog.h>
#include <openssl/crypto.h>
@@ -9,6 +10,7 @@ namespace xrpl {
void
secureErase(void* dest, std::size_t bytes)
{
TRACE_FUNC();
OPENSSL_cleanse(dest, bytes);
}

View File

@@ -1,6 +1,7 @@
#include <xrpl/json/JsonPropertyStream.h>
#include <xrpl/json/json_value.h>
#include <xrpl/basics/TraceLog.h>
#include <string>
@@ -8,6 +9,7 @@ namespace xrpl {
JsonPropertyStream::JsonPropertyStream() : topValue(json::ObjectValue)
{
TRACE_FUNC();
stack.reserve(64);
stack.push_back(&topValue);
}
@@ -15,12 +17,14 @@ JsonPropertyStream::JsonPropertyStream() : topValue(json::ObjectValue)
json::Value const&
JsonPropertyStream::top() const
{
TRACE_FUNC();
return topValue;
}
void
JsonPropertyStream::mapBegin()
{
TRACE_FUNC();
// top is array
json::Value& top(*stack.back());
json::Value& map(top.append(json::ObjectValue));
@@ -30,6 +34,7 @@ JsonPropertyStream::mapBegin()
void
JsonPropertyStream::mapBegin(std::string const& key)
{
TRACE_FUNC();
// top is a map
json::Value& top(*stack.back());
json::Value& map(top[key] = json::ObjectValue);
@@ -39,60 +44,70 @@ JsonPropertyStream::mapBegin(std::string const& key)
void
JsonPropertyStream::mapEnd()
{
TRACE_FUNC();
stack.pop_back();
}
void
JsonPropertyStream::add(std::string const& key, short v)
{
TRACE_FUNC();
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, unsigned short v)
{
TRACE_FUNC();
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, int v)
{
TRACE_FUNC();
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, unsigned int v)
{
TRACE_FUNC();
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, long v)
{
TRACE_FUNC();
(*stack.back())[key] = int(v);
}
void
JsonPropertyStream::add(std::string const& key, float v)
{
TRACE_FUNC();
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, double v)
{
TRACE_FUNC();
(*stack.back())[key] = v;
}
void
JsonPropertyStream::add(std::string const& key, std::string const& v)
{
TRACE_FUNC();
(*stack.back())[key] = v;
}
void
JsonPropertyStream::arrayBegin()
{
TRACE_FUNC();
// top is array
json::Value& top(*stack.back());
json::Value& vec(top.append(json::ArrayValue));
@@ -102,6 +117,7 @@ JsonPropertyStream::arrayBegin()
void
JsonPropertyStream::arrayBegin(std::string const& key)
{
TRACE_FUNC();
// top is a map
json::Value& top(*stack.back());
json::Value& vec(top[key] = json::ArrayValue);
@@ -111,54 +127,63 @@ JsonPropertyStream::arrayBegin(std::string const& key)
void
JsonPropertyStream::arrayEnd()
{
TRACE_FUNC();
stack.pop_back();
}
void
JsonPropertyStream::add(short v)
{
TRACE_FUNC();
stack.back()->append(v);
}
void
JsonPropertyStream::add(unsigned short v)
{
TRACE_FUNC();
stack.back()->append(v);
}
void
JsonPropertyStream::add(int v)
{
TRACE_FUNC();
stack.back()->append(v);
}
void
JsonPropertyStream::add(unsigned int v)
{
TRACE_FUNC();
stack.back()->append(v);
}
void
JsonPropertyStream::add(long v)
{
TRACE_FUNC();
stack.back()->append(int(v));
}
void
JsonPropertyStream::add(float v)
{
TRACE_FUNC();
stack.back()->append(v);
}
void
JsonPropertyStream::add(double v)
{
TRACE_FUNC();
stack.back()->append(v);
}
void
JsonPropertyStream::add(std::string const& v)
{
TRACE_FUNC();
stack.back()->append(v);
}

View File

@@ -2,6 +2,7 @@
#include <xrpl/json/Writer.h>
#include <xrpl/json/json_value.h>
#include <xrpl/basics/TraceLog.h>
#include <string>
@@ -12,6 +13,7 @@ namespace {
void
outputJson(json::Value const& value, Writer& writer)
{
TRACE_FUNC();
switch (value.type())
{
case json::NullValue: {
@@ -74,6 +76,7 @@ outputJson(json::Value const& value, Writer& writer)
void
outputJson(json::Value const& value, Output const& out)
{
TRACE_FUNC();
Writer writer(out);
outputJson(value, writer);
}
@@ -81,6 +84,7 @@ outputJson(json::Value const& value, Output const& out)
std::string
jsonAsString(json::Value const& value)
{
TRACE_FUNC();
std::string s;
Writer writer(stringOutput(s));
outputJson(value, writer);

View File

@@ -2,6 +2,7 @@
#include <xrpl/basics/ToString.h>
#include <xrpl/json/Output.h>
#include <xrpl/basics/TraceLog.h>
#include <cstddef>
#include <map>
@@ -42,6 +43,7 @@ auto const kINTEGRAL_FLOATS_BECOME_INTS = false;
size_t
lengthWithoutTrailingZeros(std::string const& s)
{
TRACE_FUNC();
auto dotPos = s.find('.');
if (dotPos == std::string::npos)
return s.size();
@@ -75,12 +77,14 @@ public:
[[nodiscard]] bool
empty() const
{
TRACE_FUNC();
return stack_.empty();
}
void
start(CollectionType ct)
{
TRACE_FUNC();
char const ch = (ct == CollectionType::Array) ? kOPEN_BRACKET : kOPEN_BRACE;
output({&ch, 1});
stack_.emplace(Collection{.type = ct});
@@ -89,6 +93,7 @@ public:
void
output(boost::beast::string_view const& bytes)
{
TRACE_FUNC();
markStarted();
output_(bytes);
}
@@ -96,6 +101,7 @@ public:
void
stringOutput(boost::beast::string_view const& bytes)
{
TRACE_FUNC();
markStarted();
std::size_t position = 0, writtenUntil = 0;
@@ -122,6 +128,7 @@ public:
void
markStarted()
{
TRACE_FUNC();
check(!isFinished(), "isFinished() in output.");
isStarted_ = true;
}
@@ -129,6 +136,7 @@ public:
void
nextCollectionEntry(CollectionType type, std::string const& message)
{
TRACE_FUNC();
check(!empty(), "empty () in " + message);
auto t = stack_.top().type;
@@ -151,6 +159,7 @@ public:
void
writeObjectTag(std::string const& tag)
{
TRACE_FUNC();
#ifndef NDEBUG
// Make sure we haven't already seen this tag.
auto& tags = stack_.top().tags;
@@ -165,12 +174,14 @@ public:
[[nodiscard]] bool
isFinished() const
{
TRACE_FUNC();
return isStarted_ && empty();
}
void
finish()
{
TRACE_FUNC();
check(!empty(), "Empty stack in finish()");
auto isArray = stack_.top().type == CollectionType::Array;
@@ -182,6 +193,7 @@ public:
void
finishAll()
{
TRACE_FUNC();
if (isStarted_)
{
while (!isFinished())
@@ -192,6 +204,7 @@ public:
[[nodiscard]] Output const&
getOutput() const
{
TRACE_FUNC();
return output_;
}
@@ -226,18 +239,21 @@ Writer::Writer(Output const& output) : impl_(std::make_unique<Impl>(output))
Writer::~Writer()
{
TRACE_FUNC();
if (impl_)
impl_->finishAll();
}
Writer::Writer(Writer&& w) noexcept
{
TRACE_FUNC();
impl_ = std::move(w.impl_);
}
Writer&
Writer::operator=(Writer&& w) noexcept
{
TRACE_FUNC();
impl_ = std::move(w.impl_);
return *this;
}
@@ -245,18 +261,21 @@ Writer::operator=(Writer&& w) noexcept
void
Writer::output(char const* s)
{
TRACE_FUNC();
impl_->stringOutput(s);
}
void
Writer::output(std::string const& s)
{
TRACE_FUNC();
impl_->stringOutput(s);
}
void
Writer::output(json::Value const& value)
{
TRACE_FUNC();
impl_->markStarted();
outputJson(value, impl_->getOutput());
}
@@ -264,6 +283,7 @@ Writer::output(json::Value const& value)
void
Writer::output(float f)
{
TRACE_FUNC();
auto s = xrpl::to_string(f);
impl_->output({s.data(), lengthWithoutTrailingZeros(s)});
}
@@ -271,6 +291,7 @@ Writer::output(float f)
void
Writer::output(double f)
{
TRACE_FUNC();
auto s = xrpl::to_string(f);
impl_->output({s.data(), lengthWithoutTrailingZeros(s)});
}
@@ -278,24 +299,28 @@ Writer::output(double f)
void
Writer::output(std::nullptr_t)
{
TRACE_FUNC();
impl_->output("null");
}
void
Writer::output(bool b)
{
TRACE_FUNC();
impl_->output(b ? "true" : "false");
}
void
Writer::implOutput(std::string const& s)
{
TRACE_FUNC();
impl_->output(s);
}
void
Writer::finishAll()
{
TRACE_FUNC();
if (impl_)
impl_->finishAll();
}
@@ -303,12 +328,14 @@ Writer::finishAll()
void
Writer::rawAppend()
{
TRACE_FUNC();
impl_->nextCollectionEntry(CollectionType::Array, "append");
}
void
Writer::rawSet(std::string const& tag)
{
TRACE_FUNC();
check(!tag.empty(), "Tag can't be empty");
impl_->nextCollectionEntry(CollectionType::Object, "set");
@@ -318,12 +345,14 @@ Writer::rawSet(std::string const& tag)
void
Writer::startRoot(CollectionType type)
{
TRACE_FUNC();
impl_->start(type);
}
void
Writer::startAppend(CollectionType type)
{
TRACE_FUNC();
impl_->nextCollectionEntry(CollectionType::Array, "startAppend");
impl_->start(type);
}
@@ -331,6 +360,7 @@ Writer::startAppend(CollectionType type)
void
Writer::startSet(CollectionType type, std::string const& key)
{
TRACE_FUNC();
impl_->nextCollectionEntry(CollectionType::Object, "startSet");
impl_->writeObjectTag(key);
impl_->start(type);
@@ -339,6 +369,7 @@ Writer::startSet(CollectionType type, std::string const& key)
void
Writer::finish()
{
TRACE_FUNC();
if (impl_)
impl_->finish();
}

View File

@@ -2,6 +2,7 @@
#include <xrpl/basics/contract.h>
#include <xrpl/json/json_value.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cctype>
@@ -19,6 +20,7 @@ namespace json {
static std::string
codePointToUTF8(unsigned int cp)
{
TRACE_FUNC();
std::string result;
// based on description from http://en.wikipedia.org/wiki/UTF-8
@@ -59,6 +61,7 @@ codePointToUTF8(unsigned int cp)
bool
Reader::parse(std::string const& document, Value& root)
{
TRACE_FUNC();
document_ = document;
char const* begin = document_.c_str();
char const* end = begin + document_.length();
@@ -68,6 +71,7 @@ Reader::parse(std::string const& document, Value& root)
bool
Reader::parse(std::istream& sin, Value& root)
{
TRACE_FUNC();
// std::istream_iterator<char> begin(sin);
// std::istream_iterator<char> end;
// Those would allow streamed input from a file, if parse() were a
@@ -83,6 +87,7 @@ Reader::parse(std::istream& sin, Value& root)
bool
Reader::parse(char const* beginDoc, char const* endDoc, Value& root)
{
TRACE_FUNC();
begin_ = beginDoc;
end_ = endDoc;
current_ = begin_;
@@ -115,6 +120,7 @@ Reader::parse(char const* beginDoc, char const* endDoc, Value& root)
bool
Reader::readValue(unsigned depth)
{
TRACE_FUNC();
Token token{};
skipCommentTokens(token);
if (depth > kNEST_LIMIT)
@@ -165,6 +171,7 @@ Reader::readValue(unsigned depth)
void
Reader::skipCommentTokens(Token& token)
{
TRACE_FUNC();
do
{
readToken(token);
@@ -174,6 +181,7 @@ Reader::skipCommentTokens(Token& token)
bool
Reader::expectToken(TokenType type, Token& token, char const* message)
{
TRACE_FUNC();
readToken(token);
if (token.type != type)
@@ -185,6 +193,7 @@ Reader::expectToken(TokenType type, Token& token, char const* message)
bool
Reader::readToken(Token& token)
{
TRACE_FUNC();
skipSpaces();
token.start = current_;
Char const c = getNextChar();
@@ -274,6 +283,7 @@ Reader::readToken(Token& token)
void
Reader::skipSpaces()
{
TRACE_FUNC();
while (current_ != end_)
{
Char const c = *current_;
@@ -292,6 +302,7 @@ Reader::skipSpaces()
bool
Reader::match(Location pattern, int patternLength)
{
TRACE_FUNC();
if (end_ - current_ < patternLength)
return false;
@@ -310,6 +321,7 @@ Reader::match(Location pattern, int patternLength)
bool
Reader::readComment()
{
TRACE_FUNC();
Char const c = getNextChar();
if (c == '*')
@@ -324,6 +336,7 @@ Reader::readComment()
bool
Reader::readCStyleComment()
{
TRACE_FUNC();
while (current_ != end_)
{
Char const c = getNextChar();
@@ -338,6 +351,7 @@ Reader::readCStyleComment()
bool
Reader::readCppStyleComment()
{
TRACE_FUNC();
while (current_ != end_)
{
Char const c = getNextChar();
@@ -352,6 +366,7 @@ Reader::readCppStyleComment()
Reader::TokenType
Reader::readNumber()
{
TRACE_FUNC();
static char const kEXTENDED_TOKENS[] = {'.', 'e', 'E', '+', '-'};
TokenType type = TokenInteger;
@@ -383,6 +398,7 @@ Reader::readNumber()
bool
Reader::readString()
{
TRACE_FUNC();
Char c = 0;
while (current_ != end_)
@@ -405,6 +421,7 @@ Reader::readString()
bool
Reader::readObject(Token& tokenStart, unsigned depth)
{
TRACE_FUNC();
Token tokenName{};
std::string name;
currentValue() = Value(ObjectValue);
@@ -475,6 +492,7 @@ Reader::readObject(Token& tokenStart, unsigned depth)
bool
Reader::readArray(Token& tokenStart, unsigned depth)
{
TRACE_FUNC();
currentValue() = Value(ArrayValue);
skipSpaces();
@@ -525,6 +543,7 @@ Reader::readArray(Token& tokenStart, unsigned depth)
bool
Reader::decodeNumber(Token& token)
{
TRACE_FUNC();
Location current = token.start;
bool const isNegative = *current == '-';
@@ -604,6 +623,7 @@ Reader::decodeNumber(Token& token)
bool
Reader::decodeDouble(Token& token)
{
TRACE_FUNC();
double value = 0;
int const bufferSize = 32;
int count = 0;
@@ -640,6 +660,7 @@ Reader::decodeDouble(Token& token)
bool
Reader::decodeString(Token& token)
{
TRACE_FUNC();
std::string decoded;
if (!decodeString(token, decoded))
@@ -652,6 +673,7 @@ Reader::decodeString(Token& token)
bool
Reader::decodeString(Token& token, std::string& decoded)
{
TRACE_FUNC();
decoded.reserve(token.end - token.start - 2);
Location current = token.start + 1; // skip '"'
Location end = token.end - 1; // do not include '"'
@@ -731,6 +753,7 @@ Reader::decodeString(Token& token, std::string& decoded)
bool
Reader::decodeUnicodeCodePoint(Token& token, Location& current, Location end, unsigned int& unicode)
{
TRACE_FUNC();
if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
return false;
@@ -774,6 +797,7 @@ Reader::decodeUnicodeEscapeSequence(
Location end,
unsigned int& unicode)
{
TRACE_FUNC();
if (end - current < 4)
{
return addError(
@@ -815,6 +839,7 @@ Reader::decodeUnicodeEscapeSequence(
bool
Reader::addError(std::string const& message, Token& token, Location extra)
{
TRACE_FUNC();
ErrorInfo info;
info.token = token;
info.message = message;
@@ -826,6 +851,7 @@ Reader::addError(std::string const& message, Token& token, Location extra)
bool
Reader::recoverFromError(TokenType skipUntilToken)
{
TRACE_FUNC();
int const errorCount = int(errors_.size());
Token skip{};
@@ -845,6 +871,7 @@ Reader::recoverFromError(TokenType skipUntilToken)
bool
Reader::addErrorAndRecover(std::string const& message, Token& token, TokenType skipUntilToken)
{
TRACE_FUNC();
addError(message, token);
return recoverFromError(skipUntilToken);
}
@@ -852,12 +879,14 @@ Reader::addErrorAndRecover(std::string const& message, Token& token, TokenType s
Value&
Reader::currentValue()
{
TRACE_FUNC();
return *(nodes_.top());
}
Reader::Char
Reader::getNextChar()
{
TRACE_FUNC();
if (current_ == end_)
return 0;
@@ -867,6 +896,7 @@ Reader::getNextChar()
void
Reader::getLocationLineAndColumn(Location location, int& line, int& column) const
{
TRACE_FUNC();
Location current = begin_;
Location lastLineStart = current;
line = 0;
@@ -898,6 +928,7 @@ Reader::getLocationLineAndColumn(Location location, int& line, int& column) cons
std::string
Reader::getLocationLineAndColumn(Location location) const
{
TRACE_FUNC();
int line = 0, column = 0;
getLocationLineAndColumn(location, line, column);
return "Line " + std::to_string(line) + ", Column " + std::to_string(column);
@@ -906,6 +937,7 @@ Reader::getLocationLineAndColumn(Location location) const
std::string
Reader::getFormattedErrorMessages() const
{
TRACE_FUNC();
std::string formattedMessage;
for (Errors::const_iterator itError = errors_.begin(); itError != errors_.end(); ++itError)
@@ -924,6 +956,7 @@ Reader::getFormattedErrorMessages() const
std::istream&
operator>>(std::istream& sin, Value& root)
{
TRACE_FUNC();
json::Reader reader;
bool const ok = reader.parse(sin, root);

View File

@@ -6,6 +6,7 @@
#include <xrpl/json/detail/json_assert.h>
#include <xrpl/json/json_forwards.h>
#include <xrpl/json/json_writer.h>
#include <xrpl/basics/TraceLog.h>
#include <cmath>
#include <cstdint>
@@ -27,18 +28,21 @@ public:
char*
makeMemberName(char const* memberName) override
{
TRACE_FUNC();
return duplicateStringValue(memberName);
}
void
releaseMemberName(char* memberName) override
{
TRACE_FUNC();
releaseStringValue(memberName);
}
char*
duplicateStringValue(char const* value, unsigned int length = Unknown) override
{
TRACE_FUNC();
//@todo investigate this old optimization
// if ( !value || value[0] == 0 )
// return 0;
@@ -56,6 +60,7 @@ public:
void
releaseStringValue(char* value) override
{
TRACE_FUNC();
if (value != nullptr)
free(value);
}
@@ -64,6 +69,7 @@ public:
static ValueAllocator*&
valueAllocator()
{
TRACE_FUNC();
static ValueAllocator* kVALUE_ALLOCATOR = new DefaultValueAllocator; // NOLINT TODO
return kVALUE_ALLOCATOR;
}
@@ -72,6 +78,7 @@ static struct DummyValueAllocatorInitializer
{
DummyValueAllocatorInitializer()
{
TRACE_FUNC();
valueAllocator(); // ensure valueAllocator() statics are initialized
// before main().
}
@@ -112,6 +119,7 @@ Value::CZString::CZString(CZString const& other)
Value::CZString::~CZString()
{
TRACE_FUNC();
if ((cstr_ != nullptr) && index_ == Duplicate)
valueAllocator()->releaseMemberName(const_cast<char*>(cstr_));
}
@@ -119,6 +127,7 @@ Value::CZString::~CZString()
bool
Value::CZString::operator<(CZString const& other) const
{
TRACE_FUNC();
if ((cstr_ != nullptr) && (other.cstr_ != nullptr))
return strcmp(cstr_, other.cstr_) < 0;
@@ -128,6 +137,7 @@ Value::CZString::operator<(CZString const& other) const
bool
Value::CZString::operator==(CZString const& other) const
{
TRACE_FUNC();
if ((cstr_ != nullptr) && (other.cstr_ != nullptr))
return strcmp(cstr_, other.cstr_) == 0;
@@ -137,18 +147,21 @@ Value::CZString::operator==(CZString const& other) const
int
Value::CZString::index() const
{
TRACE_FUNC();
return index_;
}
char const*
Value::CZString::cStr() const
{
TRACE_FUNC();
return cstr_;
}
bool
Value::CZString::isStaticString() const
{
TRACE_FUNC();
return index_ == NoDuplication;
}
@@ -166,6 +179,7 @@ Value::CZString::isStaticString() const
*/
Value::Value(ValueType type) : type_(type)
{
TRACE_FUNC();
switch (type)
{
case NullValue:
@@ -202,48 +216,57 @@ Value::Value(ValueType type) : type_(type)
Value::Value(Int value) : type_(IntValue)
{
TRACE_FUNC();
value_.intVal = value;
}
Value::Value(UInt value) : type_(UintValue)
{
TRACE_FUNC();
value_.uintVal = value;
}
Value::Value(double value) : type_(RealValue)
{
TRACE_FUNC();
value_.realVal = value;
}
Value::Value(char const* value) : type_(StringValue), allocated_(true)
{
TRACE_FUNC();
value_.stringVal = valueAllocator()->duplicateStringValue(value);
}
Value::Value(xrpl::Number const& value) : type_(StringValue), allocated_(true)
{
TRACE_FUNC();
auto const tmp = to_string(value);
value_.stringVal = valueAllocator()->duplicateStringValue(tmp.c_str(), tmp.length());
}
Value::Value(std::string const& value) : type_(StringValue), allocated_(true)
{
TRACE_FUNC();
value_.stringVal =
valueAllocator()->duplicateStringValue(value.c_str(), (unsigned int)value.length());
}
Value::Value(StaticString const& value) : type_(StringValue)
{
TRACE_FUNC();
value_.stringVal = const_cast<char*>(value.cStr());
}
Value::Value(bool value) : type_(BooleanValue)
{
TRACE_FUNC();
value_.boolVal = value;
}
Value::Value(Value const& other) : type_(other.type_)
{
TRACE_FUNC();
switch (type_)
{
case NullValue:
@@ -281,6 +304,7 @@ Value::Value(Value const& other) : type_(other.type_)
Value::~Value()
{
TRACE_FUNC();
switch (type_)
{
case NullValue:
@@ -312,6 +336,7 @@ Value::~Value()
Value&
Value::operator=(Value const& other)
{
TRACE_FUNC();
Value tmp(other);
swap(tmp);
return *this;
@@ -320,6 +345,7 @@ Value::operator=(Value const& other)
Value::Value(Value&& other) noexcept
: value_(other.value_), type_(other.type_), allocated_(other.allocated_)
{
TRACE_FUNC();
other.type_ = NullValue;
other.allocated_ = 0;
}
@@ -327,6 +353,7 @@ Value::Value(Value&& other) noexcept
Value&
Value::operator=(Value&& other)
{
TRACE_FUNC();
Value tmp(std::move(other));
swap(tmp);
return *this;
@@ -335,6 +362,7 @@ Value::operator=(Value&& other)
void
Value::swap(Value& other) noexcept
{
TRACE_FUNC();
std::swap(value_, other.value_);
ValueType const temp = type_;
@@ -349,12 +377,14 @@ Value::swap(Value& other) noexcept
ValueType
Value::type() const
{
TRACE_FUNC();
return type_;
}
static int
integerCmp(Int i, UInt ui)
{
TRACE_FUNC();
// All negative numbers are less than all unsigned numbers.
if (i < 0)
return -1;
@@ -368,6 +398,7 @@ integerCmp(Int i, UInt ui)
bool
operator<(Value const& x, Value const& y)
{
TRACE_FUNC();
if (auto signum = x.type_ - y.type_)
{
if (x.type_ == IntValue && y.type_ == UintValue)
@@ -423,6 +454,7 @@ operator<(Value const& x, Value const& y)
bool
operator==(Value const& x, Value const& y)
{
TRACE_FUNC();
if (x.type_ != y.type_)
{
if (x.type_ == IntValue && y.type_ == UintValue)
@@ -471,6 +503,7 @@ operator==(Value const& x, Value const& y)
char const*
Value::asCString() const
{
TRACE_FUNC();
XRPL_ASSERT(type_ == StringValue, "json::Value::asCString : valid type");
return value_.stringVal;
}
@@ -478,6 +511,7 @@ Value::asCString() const
std::string
Value::asString() const
{
TRACE_FUNC();
switch (type_)
{
case NullValue:
@@ -514,6 +548,7 @@ Value::asString() const
Value::Int
Value::asInt() const
{
TRACE_FUNC();
switch (type_)
{
case NullValue:
@@ -557,6 +592,7 @@ Value::asInt() const
UInt
Value::asAbsUInt() const
{
TRACE_FUNC();
switch (type_)
{
case NullValue:
@@ -616,6 +652,7 @@ Value::asAbsUInt() const
Value::UInt
Value::asUInt() const
{
TRACE_FUNC();
switch (type_)
{
case NullValue:
@@ -659,6 +696,7 @@ Value::asUInt() const
double
Value::asDouble() const
{
TRACE_FUNC();
switch (type_)
{
case NullValue:
@@ -693,6 +731,7 @@ Value::asDouble() const
bool
Value::asBool() const
{
TRACE_FUNC();
switch (type_)
{
case NullValue:
@@ -727,6 +766,7 @@ Value::asBool() const
bool
Value::isConvertibleTo(ValueType other) const
{
TRACE_FUNC();
switch (type_)
{
case NullValue:
@@ -778,6 +818,7 @@ Value::isConvertibleTo(ValueType other) const
Value::UInt
Value::size() const
{
TRACE_FUNC();
switch (type_)
{
case NullValue:
@@ -813,6 +854,7 @@ Value::size() const
Value::
operator bool() const
{
TRACE_FUNC();
if (isNull())
return false;
@@ -828,6 +870,7 @@ operator bool() const
void
Value::clear()
{
TRACE_FUNC();
XRPL_ASSERT(
type_ == NullValue || type_ == ArrayValue || type_ == ObjectValue,
"json::Value::clear : valid type");
@@ -867,6 +910,7 @@ Value::operator[](UInt index)
Value const&
Value::operator[](UInt index) const
{
TRACE_FUNC();
XRPL_ASSERT(
type_ == NullValue || type_ == ArrayValue,
"json::Value::operator[](UInt) const : valid type");
@@ -892,6 +936,7 @@ Value::operator[](char const* key)
Value&
Value::resolveReference(char const* key, bool isStatic)
{
TRACE_FUNC();
XRPL_ASSERT(
type_ == NullValue || type_ == ObjectValue, "json::Value::resolveReference : valid type");
@@ -913,6 +958,7 @@ Value::resolveReference(char const* key, bool isStatic)
Value
Value::get(UInt index, Value const& defaultValue) const
{
TRACE_FUNC();
Value const* value = &((*this)[index]);
return value == &kNULL ? defaultValue : *value;
}
@@ -920,12 +966,14 @@ Value::get(UInt index, Value const& defaultValue) const
bool
Value::isValidIndex(UInt index) const
{
TRACE_FUNC();
return index < size();
}
Value const&
Value::operator[](char const* key) const
{
TRACE_FUNC();
XRPL_ASSERT(
type_ == NullValue || type_ == ObjectValue,
"json::Value::operator[](const char*) const : valid type");
@@ -951,6 +999,7 @@ Value::operator[](std::string const& key)
Value const&
Value::operator[](std::string const& key) const
{
TRACE_FUNC();
return (*this)[key.c_str()];
}
@@ -963,24 +1012,28 @@ Value::operator[](StaticString const& key)
Value const&
Value::operator[](StaticString const& key) const
{
TRACE_FUNC();
return (*this)[key.cStr()];
}
Value&
Value::append(Value const& value)
{
TRACE_FUNC();
return (*this)[size()] = value;
}
Value&
Value::append(Value&& value)
{
TRACE_FUNC();
return (*this)[size()] = std::move(value);
}
Value
Value::get(char const* key, Value const& defaultValue) const
{
TRACE_FUNC();
Value const* value = &((*this)[key]);
return value == &kNULL ? defaultValue : *value;
}
@@ -988,12 +1041,14 @@ Value::get(char const* key, Value const& defaultValue) const
Value
Value::get(std::string const& key, Value const& defaultValue) const
{
TRACE_FUNC();
return get(key.c_str(), defaultValue);
}
Value
Value::removeMember(char const* key)
{
TRACE_FUNC();
XRPL_ASSERT(
type_ == NullValue || type_ == ObjectValue, "json::Value::removeMember : valid type");
@@ -1014,12 +1069,14 @@ Value::removeMember(char const* key)
Value
Value::removeMember(std::string const& key)
{
TRACE_FUNC();
return removeMember(key.c_str());
}
bool
Value::isMember(char const* key) const
{
TRACE_FUNC();
if (type_ != ObjectValue)
return false;
@@ -1030,18 +1087,21 @@ Value::isMember(char const* key) const
bool
Value::isMember(std::string const& key) const
{
TRACE_FUNC();
return isMember(key.c_str());
}
bool
Value::isMember(StaticString const& key) const
{
TRACE_FUNC();
return isMember(key.cStr());
}
Value::Members
Value::getMemberNames() const
{
TRACE_FUNC();
XRPL_ASSERT(
type_ == NullValue || type_ == ObjectValue, "json::Value::getMemberNames : valid type");
@@ -1062,78 +1122,91 @@ Value::getMemberNames() const
bool
Value::isNull() const
{
TRACE_FUNC();
return type_ == NullValue;
}
bool
Value::isBool() const
{
TRACE_FUNC();
return type_ == BooleanValue;
}
bool
Value::isInt() const
{
TRACE_FUNC();
return type_ == IntValue;
}
bool
Value::isUInt() const
{
TRACE_FUNC();
return type_ == UintValue;
}
bool
Value::isIntegral() const
{
TRACE_FUNC();
return type_ == IntValue || type_ == UintValue || type_ == BooleanValue;
}
bool
Value::isDouble() const
{
TRACE_FUNC();
return type_ == RealValue;
}
bool
Value::isNumeric() const
{
TRACE_FUNC();
return isIntegral() || isDouble();
}
bool
Value::isString() const
{
TRACE_FUNC();
return type_ == StringValue;
}
bool
Value::isArray() const
{
TRACE_FUNC();
return type_ == ArrayValue;
}
bool
Value::isArrayOrNull() const
{
TRACE_FUNC();
return type_ == NullValue || type_ == ArrayValue;
}
bool
Value::isObject() const
{
TRACE_FUNC();
return type_ == ObjectValue;
}
bool
Value::isObjectOrNull() const
{
TRACE_FUNC();
return type_ == NullValue || type_ == ObjectValue;
}
std::string
Value::toStyledString() const
{
TRACE_FUNC();
StyledWriter writer;
return writer.write(*this);
}
@@ -1141,6 +1214,7 @@ Value::toStyledString() const
Value::const_iterator
Value::begin() const
{
TRACE_FUNC();
switch (type_)
{
case ArrayValue:
@@ -1159,6 +1233,7 @@ Value::begin() const
Value::const_iterator
Value::end() const
{
TRACE_FUNC();
switch (type_)
{
case ArrayValue:
@@ -1177,6 +1252,7 @@ Value::end() const
Value::iterator
Value::begin()
{
TRACE_FUNC();
switch (type_)
{
case ArrayValue:
@@ -1194,6 +1270,7 @@ Value::begin()
Value::iterator
Value::end()
{
TRACE_FUNC();
switch (type_)
{
case ArrayValue:

View File

@@ -2,6 +2,7 @@
#include <xrpl/json/json_forwards.h>
#include <xrpl/json/json_value.h>
#include <xrpl/basics/TraceLog.h>
namespace json {
@@ -25,24 +26,28 @@ ValueIteratorBase::ValueIteratorBase(Value::ObjectValues::iterator const& curren
Value&
ValueIteratorBase::deref() const
{
TRACE_FUNC();
return current_->second;
}
void
ValueIteratorBase::increment()
{
TRACE_FUNC();
++current_;
}
void
ValueIteratorBase::decrement()
{
TRACE_FUNC();
--current_;
}
ValueIteratorBase::difference_type
ValueIteratorBase::computeDistance(SelfType const& other) const
{
TRACE_FUNC();
// Iterator for null value are initialized using the default
// constructor, which initialize current_ to the default
// std::map::iterator. As begin() and end() are two instance
@@ -70,6 +75,7 @@ ValueIteratorBase::computeDistance(SelfType const& other) const
bool
ValueIteratorBase::isEqual(SelfType const& other) const
{
TRACE_FUNC();
if (isNull_)
{
return other.isNull_;
@@ -81,12 +87,14 @@ ValueIteratorBase::isEqual(SelfType const& other) const
void
ValueIteratorBase::copy(SelfType const& other)
{
TRACE_FUNC();
current_ = other.current_;
}
Value
ValueIteratorBase::key() const
{
TRACE_FUNC();
Value::CZString const czString = (*current_).first;
if (czString.cStr() != nullptr)
@@ -103,6 +111,7 @@ ValueIteratorBase::key() const
UInt
ValueIteratorBase::index() const
{
TRACE_FUNC();
Value::CZString const czString = (*current_).first;
if (czString.cStr() == nullptr)
@@ -114,6 +123,7 @@ ValueIteratorBase::index() const
char const*
ValueIteratorBase::memberName() const
{
TRACE_FUNC();
char const* name = (*current_).first.cStr();
return (name != nullptr) ? name : "";
}
@@ -134,6 +144,7 @@ ValueConstIterator::ValueConstIterator(Value::ObjectValues::iterator const& curr
ValueConstIterator&
ValueConstIterator::operator=(ValueIteratorBase const& other)
{
TRACE_FUNC();
copy(other);
return *this;
}
@@ -160,6 +171,7 @@ ValueIterator::ValueIterator(ValueIterator const& other) = default;
ValueIterator&
ValueIterator::operator=(SelfType const& other)
{
TRACE_FUNC();
copy(other);
return *this;
}

View File

@@ -3,6 +3,7 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_forwards.h>
#include <xrpl/json/json_value.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdio>
#include <cstring>
@@ -18,12 +19,14 @@ namespace json {
static bool
isControlCharacter(char ch)
{
TRACE_FUNC();
return ch > 0 && ch <= 0x1F;
}
static bool
containsControlCharacter(char const* str)
{
TRACE_FUNC();
while (*str != 0)
{
if (isControlCharacter(*(str++)))
@@ -35,6 +38,7 @@ containsControlCharacter(char const* str)
static void
uintToString(unsigned int value, char*& current)
{
TRACE_FUNC();
*--current = 0;
do
@@ -47,6 +51,7 @@ uintToString(unsigned int value, char*& current)
std::string
valueToString(Int value)
{
TRACE_FUNC();
char buffer[32];
char* current = buffer + sizeof(buffer); // NOLINT(misc-const-correctness)
bool const isNegative = value < 0;
@@ -66,6 +71,7 @@ valueToString(Int value)
std::string
valueToString(UInt value)
{
TRACE_FUNC();
char buffer[32];
char* current = buffer + sizeof(buffer); // NOLINT(misc-const-correctness)
uintToString(value, current);
@@ -76,6 +82,7 @@ valueToString(UInt value)
std::string
valueToString(double value)
{
TRACE_FUNC();
// Allocate a buffer that is more than large enough to store the 16 digits
// of precision requested below.
char buffer[32];
@@ -94,12 +101,14 @@ valueToString(double value)
std::string
valueToString(bool value)
{
TRACE_FUNC();
return value ? "true" : "false";
}
std::string
valueToQuotedString(char const* value)
{
TRACE_FUNC();
// Not sure how to handle unicode...
if (strpbrk(value, "\"\\\b\f\n\r\t") == nullptr && !containsControlCharacter(value))
return std::string("\"") + value + "\"";
@@ -178,6 +187,7 @@ valueToQuotedString(char const* value)
std::string
FastWriter::write(Value const& root)
{
TRACE_FUNC();
document_ = "";
writeValue(root);
return std::move(document_);
@@ -186,6 +196,7 @@ FastWriter::write(Value const& root)
void
FastWriter::writeValue(Value const& value)
{
TRACE_FUNC();
switch (value.type())
{
case NullValue:
@@ -258,6 +269,7 @@ StyledWriter::StyledWriter() = default;
std::string
StyledWriter::write(Value const& root)
{
TRACE_FUNC();
document_ = "";
addChildValues_ = false;
indentString_ = "";
@@ -269,6 +281,7 @@ StyledWriter::write(Value const& root)
void
StyledWriter::writeValue(Value const& value)
{
TRACE_FUNC();
switch (value.type())
{
case NullValue:
@@ -337,6 +350,7 @@ StyledWriter::writeValue(Value const& value)
void
StyledWriter::writeArrayValue(Value const& value)
{
TRACE_FUNC();
unsigned const size = value.size();
if (size == 0)
@@ -400,6 +414,7 @@ StyledWriter::writeArrayValue(Value const& value)
bool
StyledWriter::isMultilineArray(Value const& value)
{
TRACE_FUNC();
int const size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
childValues_.clear();
@@ -433,6 +448,7 @@ StyledWriter::isMultilineArray(Value const& value)
void
StyledWriter::pushValue(std::string const& value)
{
TRACE_FUNC();
if (addChildValues_)
{
childValues_.push_back(value);
@@ -446,6 +462,7 @@ StyledWriter::pushValue(std::string const& value)
void
StyledWriter::writeIndent()
{
TRACE_FUNC();
if (!document_.empty())
{
char const last = document_[document_.length() - 1];
@@ -463,6 +480,7 @@ StyledWriter::writeIndent()
void
StyledWriter::writeWithIndent(std::string const& value)
{
TRACE_FUNC();
writeIndent();
document_ += value;
}
@@ -470,12 +488,14 @@ StyledWriter::writeWithIndent(std::string const& value)
void
StyledWriter::indent()
{
TRACE_FUNC();
indentString_ += std::string(indentSize_, ' ');
}
void
StyledWriter::unindent()
{
TRACE_FUNC();
XRPL_ASSERT(
int(indentString_.size()) >= indentSize_,
"json::StyledWriter::unindent : maximum indent size");
@@ -493,6 +513,7 @@ StyledStreamWriter::StyledStreamWriter(std::string indentation)
void
StyledStreamWriter::write(std::ostream& out, Value const& root)
{
TRACE_FUNC();
document_ = &out;
addChildValues_ = false;
indentString_ = "";
@@ -504,6 +525,7 @@ StyledStreamWriter::write(std::ostream& out, Value const& root)
void
StyledStreamWriter::writeValue(Value const& value)
{
TRACE_FUNC();
switch (value.type())
{
case NullValue:
@@ -572,6 +594,7 @@ StyledStreamWriter::writeValue(Value const& value)
void
StyledStreamWriter::writeArrayValue(Value const& value)
{
TRACE_FUNC();
unsigned const size = value.size();
if (size == 0)
@@ -635,6 +658,7 @@ StyledStreamWriter::writeArrayValue(Value const& value)
bool
StyledStreamWriter::isMultilineArray(Value const& value)
{
TRACE_FUNC();
int const size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
childValues_.clear();
@@ -668,6 +692,7 @@ StyledStreamWriter::isMultilineArray(Value const& value)
void
StyledStreamWriter::pushValue(std::string const& value)
{
TRACE_FUNC();
if (addChildValues_)
{
childValues_.push_back(value);
@@ -681,6 +706,7 @@ StyledStreamWriter::pushValue(std::string const& value)
void
StyledStreamWriter::writeIndent()
{
TRACE_FUNC();
/*
Some comments in this method would have been nice. ;-)
@@ -699,6 +725,7 @@ StyledStreamWriter::writeIndent()
void
StyledStreamWriter::writeWithIndent(std::string const& value)
{
TRACE_FUNC();
writeIndent();
*document_ << value;
}
@@ -706,12 +733,14 @@ StyledStreamWriter::writeWithIndent(std::string const& value)
void
StyledStreamWriter::indent()
{
TRACE_FUNC();
indentString_ += indentation_;
}
void
StyledStreamWriter::unindent()
{
TRACE_FUNC();
XRPL_ASSERT(
indentString_.size() >= indentation_.size(),
"json::StyledStreamWriter::unindent : maximum indent size");
@@ -721,6 +750,7 @@ StyledStreamWriter::unindent()
std::ostream&
operator<<(std::ostream& sout, Value const& root)
{
TRACE_FUNC();
json::StyledStreamWriter writer;
writer.write(sout, root);
return sout;

View File

@@ -1,6 +1,7 @@
#include <xrpl/json/to_string.h>
#include <xrpl/json/json_writer.h>
#include <xrpl/basics/TraceLog.h>
#include <string>
@@ -9,12 +10,14 @@ namespace json {
std::string
to_string(Value const& value)
{
TRACE_FUNC();
return FastWriter().write(value);
}
std::string
pretty(Value const& value)
{
TRACE_FUNC();
return StyledWriter().write(value);
}

View File

@@ -14,6 +14,7 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFormats.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/basics/TraceLog.h>
#include <memory>
#include <string>
@@ -29,6 +30,7 @@ AcceptedLedgerTx::AcceptedLedgerTx(
, meta_(txn->getTransactionID(), ledger->seq(), *met)
, affected_(meta_.getAffectedAccounts())
{
TRACE_FUNC();
XRPL_ASSERT(!ledger->open(), "xrpl::AcceptedLedgerTx::AcceptedLedgerTx : valid ledger state");
Serializer s;
@@ -73,6 +75,7 @@ AcceptedLedgerTx::AcceptedLedgerTx(
std::string
AcceptedLedgerTx::getEscMeta() const
{
TRACE_FUNC();
XRPL_ASSERT(!rawMeta_.empty(), "xrpl::AcceptedLedgerTx::getEscMeta : metadata is set");
return sqlBlobLiteral(rawMeta_);
}

View File

@@ -22,6 +22,7 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxMeta.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/basics/TraceLog.h>
#include <cstddef>
#include <cstdint>
@@ -37,6 +38,7 @@ namespace xrpl::detail {
void
ApplyStateTable::apply(RawView& to) const
{
TRACE_FUNC();
to.rawDestroyXRP(dropsDestroyed_);
for (auto const& item : items_)
{
@@ -61,6 +63,7 @@ ApplyStateTable::apply(RawView& to) const
std::size_t
ApplyStateTable::size() const
{
TRACE_FUNC();
std::size_t ret = 0;
for (auto& item : items_)
{
@@ -86,6 +89,7 @@ ApplyStateTable::visit(
std::shared_ptr<SLE const> const& before,
std::shared_ptr<SLE const> const& after)> const& func) const
{
TRACE_FUNC();
for (auto& item : items_)
{
switch (item.second.first)
@@ -118,6 +122,7 @@ ApplyStateTable::apply(
bool isDryRun,
beast::Journal j)
{
TRACE_FUNC();
// Build metadata and insert
auto const sTx = std::make_shared<Serializer>();
tx.add(*sTx);
@@ -287,6 +292,7 @@ ApplyStateTable::apply(
bool
ApplyStateTable::exists(ReadView const& base, Keylet const& k) const
{
TRACE_FUNC();
auto const iter = items_.find(k.key);
if (iter == items_.end())
return base.exists(k);
@@ -310,6 +316,7 @@ ApplyStateTable::succ(
key_type const& key,
std::optional<key_type> const& last) const -> std::optional<key_type>
{
TRACE_FUNC();
std::optional<key_type> next = key;
items_t::const_iterator iter;
// Find base successor that is
@@ -342,6 +349,7 @@ ApplyStateTable::succ(
std::shared_ptr<SLE const>
ApplyStateTable::read(ReadView const& base, Keylet const& k) const
{
TRACE_FUNC();
auto const iter = items_.find(k.key);
if (iter == items_.end())
return base.read(k);
@@ -364,6 +372,7 @@ ApplyStateTable::read(ReadView const& base, Keylet const& k) const
std::shared_ptr<SLE>
ApplyStateTable::peek(ReadView const& base, Keylet const& k)
{
TRACE_FUNC();
auto iter = items_.lower_bound(k.key);
if (iter == items_.end() || iter->first != k.key)
{
@@ -398,6 +407,7 @@ ApplyStateTable::peek(ReadView const& base, Keylet const& k)
void
ApplyStateTable::erase(ReadView const& base, std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
auto const iter = items_.find(sle->key());
if (iter == items_.end())
Throw<std::logic_error>("ApplyStateTable::erase: missing key");
@@ -422,6 +432,7 @@ ApplyStateTable::erase(ReadView const& base, std::shared_ptr<SLE> const& sle)
void
ApplyStateTable::rawErase(ReadView const& base, std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
using namespace std;
auto const result = items_.emplace(
piecewise_construct, forward_as_tuple(sle->key()), forward_as_tuple(Action::Erase, sle));
@@ -447,6 +458,7 @@ ApplyStateTable::rawErase(ReadView const& base, std::shared_ptr<SLE> const& sle)
void
ApplyStateTable::insert(ReadView const& base, std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
auto const iter = items_.lower_bound(sle->key());
if (iter == items_.end() || iter->first != sle->key())
{
@@ -477,6 +489,7 @@ ApplyStateTable::insert(ReadView const& base, std::shared_ptr<SLE> const& sle)
void
ApplyStateTable::replace(ReadView const& base, std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
auto const iter = items_.lower_bound(sle->key());
if (iter == items_.end() || iter->first != sle->key())
{
@@ -506,6 +519,7 @@ ApplyStateTable::replace(ReadView const& base, std::shared_ptr<SLE> const& sle)
void
ApplyStateTable::update(ReadView const& base, std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
auto const iter = items_.find(sle->key());
if (iter == items_.end())
Throw<std::logic_error>("ApplyStateTable::update: missing key");
@@ -529,6 +543,7 @@ ApplyStateTable::update(ReadView const& base, std::shared_ptr<SLE> const& sle)
void
ApplyStateTable::destroyXRP(XRPAmount const& fee)
{
TRACE_FUNC();
dropsDestroyed_ += fee;
}
@@ -538,6 +553,7 @@ ApplyStateTable::destroyXRP(XRPAmount const& fee)
void
ApplyStateTable::threadItem(TxMeta& meta, std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
key_type prevTxID;
LedgerIndex prevLgrID = 0;
@@ -571,6 +587,7 @@ ApplyStateTable::threadItem(TxMeta& meta, std::shared_ptr<SLE> const& sle)
std::shared_ptr<SLE>
ApplyStateTable::getForMod(ReadView const& base, key_type const& key, Mods& mods, beast::Journal j)
{
TRACE_FUNC();
{
auto miter = mods.find(key);
if (miter != mods.end())
@@ -621,6 +638,7 @@ ApplyStateTable::threadTx(
Mods& mods,
beast::Journal j)
{
TRACE_FUNC();
auto const sle = getForMod(base, keylet::account(to).key, mods, j);
if (!sle)
{
@@ -644,6 +662,7 @@ ApplyStateTable::threadOwners(
Mods& mods,
beast::Journal j)
{
TRACE_FUNC();
LedgerEntryType const ledgerType{sle->getType()};
switch (ledgerType)
{

View File

@@ -11,6 +11,7 @@
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STVector256.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cstdint>
@@ -33,6 +34,7 @@ createRoot(
uint256 const& key,
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
{
TRACE_FUNC();
auto newRoot = std::make_shared<SLE>(directory);
newRoot->setFieldH256(sfRootIndex, directory.key);
describe(newRoot);
@@ -48,6 +50,7 @@ createRoot(
auto
findPreviousPage(ApplyView& view, Keylet const& directory, SLE::ref start)
{
TRACE_FUNC();
std::uint64_t const page = start->getFieldU64(sfIndexPrevious);
auto node = start;
@@ -75,6 +78,7 @@ insertKey(
STVector256& indexes,
uint256 const& key)
{
TRACE_FUNC();
if (preserveOrder)
{
if (std::ranges::find(indexes, key) != indexes.end())
@@ -112,6 +116,7 @@ insertPage(
Keylet const& directory,
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
{
TRACE_FUNC();
// We rely on modulo arithmetic of unsigned integers (guaranteed in
// [basic.fundamental] paragraph 2) to detect page representation overflow.
// For signed integers this would be UB, hence static_assert here.
@@ -168,6 +173,7 @@ ApplyView::dirAdd(
uint256 const& key,
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
{
TRACE_FUNC();
auto root = peek(directory);
if (!root)
@@ -190,6 +196,7 @@ ApplyView::dirAdd(
bool
ApplyView::emptyDirDelete(Keylet const& directory)
{
TRACE_FUNC();
auto node = peek(directory);
if (!node)
@@ -255,6 +262,7 @@ ApplyView::emptyDirDelete(Keylet const& directory)
bool
ApplyView::dirRemove(Keylet const& directory, std::uint64_t page, uint256 const& key, bool keepRoot)
{
TRACE_FUNC();
auto node = peek(keylet::page(directory, page));
if (!node)
@@ -395,6 +403,7 @@ ApplyView::dirRemove(Keylet const& directory, std::uint64_t page, uint256 const&
bool
ApplyView::dirDelete(Keylet const& directory, std::function<void(uint256 const&)> const& callback)
{
TRACE_FUNC();
std::optional<std::uint64_t> pi;
do

View File

@@ -9,6 +9,7 @@
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/basics/TraceLog.h>
#include <memory>
#include <optional>
@@ -24,30 +25,35 @@ ApplyViewBase::ApplyViewBase(ReadView const* base, ApplyFlags flags) : flags_(fl
bool
ApplyViewBase::open() const
{
TRACE_FUNC();
return base_->open();
}
LedgerHeader const&
ApplyViewBase::header() const
{
TRACE_FUNC();
return base_->header();
}
Fees const&
ApplyViewBase::fees() const
{
TRACE_FUNC();
return base_->fees();
}
Rules const&
ApplyViewBase::rules() const
{
TRACE_FUNC();
return base_->rules();
}
bool
ApplyViewBase::exists(Keylet const& k) const
{
TRACE_FUNC();
return items_.exists(*base_, k);
}
@@ -55,54 +61,63 @@ auto
ApplyViewBase::succ(key_type const& key, std::optional<key_type> const& last) const
-> std::optional<key_type>
{
TRACE_FUNC();
return items_.succ(*base_, key, last);
}
std::shared_ptr<SLE const>
ApplyViewBase::read(Keylet const& k) const
{
TRACE_FUNC();
return items_.read(*base_, k);
}
auto
ApplyViewBase::slesBegin() const -> std::unique_ptr<SlesType::iter_base>
{
TRACE_FUNC();
return base_->slesBegin();
}
auto
ApplyViewBase::slesEnd() const -> std::unique_ptr<SlesType::iter_base>
{
TRACE_FUNC();
return base_->slesEnd();
}
auto
ApplyViewBase::slesUpperBound(uint256 const& key) const -> std::unique_ptr<SlesType::iter_base>
{
TRACE_FUNC();
return base_->slesUpperBound(key);
}
auto
ApplyViewBase::txsBegin() const -> std::unique_ptr<TxsType::iter_base>
{
TRACE_FUNC();
return base_->txsBegin();
}
auto
ApplyViewBase::txsEnd() const -> std::unique_ptr<TxsType::iter_base>
{
TRACE_FUNC();
return base_->txsEnd();
}
bool
ApplyViewBase::txExists(key_type const& key) const
{
TRACE_FUNC();
return base_->txExists(key);
}
auto
ApplyViewBase::txRead(key_type const& key) const -> tx_type
{
TRACE_FUNC();
return base_->txRead(key);
}
@@ -111,30 +126,35 @@ ApplyViewBase::txRead(key_type const& key) const -> tx_type
ApplyFlags
ApplyViewBase::flags() const
{
TRACE_FUNC();
return flags_;
}
std::shared_ptr<SLE>
ApplyViewBase::peek(Keylet const& k)
{
TRACE_FUNC();
return items_.peek(*base_, k);
}
void
ApplyViewBase::erase(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
items_.erase(*base_, sle);
}
void
ApplyViewBase::insert(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
items_.insert(*base_, sle);
}
void
ApplyViewBase::update(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
items_.update(*base_, sle);
}
@@ -143,24 +163,28 @@ ApplyViewBase::update(std::shared_ptr<SLE> const& sle)
void
ApplyViewBase::rawErase(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
items_.rawErase(*base_, sle);
}
void
ApplyViewBase::rawInsert(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
items_.insert(*base_, sle);
}
void
ApplyViewBase::rawReplace(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
items_.replace(*base_, sle);
}
void
ApplyViewBase::rawDestroyXRP(XRPAmount const& fee)
{
TRACE_FUNC();
items_.destroyXRP(fee);
}

View File

@@ -10,6 +10,7 @@
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxMeta.h>
#include <xrpl/basics/TraceLog.h>
#include <cstddef>
#include <functional>
@@ -31,12 +32,14 @@ ApplyViewImpl::apply(
bool isDryRun,
beast::Journal j)
{
TRACE_FUNC();
return items_.apply(to, tx, ter, deliver_, parentBatchId, isDryRun, j);
}
std::size_t
ApplyViewImpl::size()
{
TRACE_FUNC();
return items_.size();
}
@@ -49,6 +52,7 @@ ApplyViewImpl::visit(
std::shared_ptr<SLE const> const& before,
std::shared_ptr<SLE const> const& after)> const& func)
{
TRACE_FUNC();
items_.visit(to, func);
}

View File

@@ -6,6 +6,7 @@
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
#include <xrpl/protocol/Book.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/basics/TraceLog.h>
#include <optional>
@@ -17,6 +18,7 @@ BookDirs::BookDirs(ReadView const& view, Book const& book)
, next_quality_(getQualityNext(root_))
, key_(view_->succ(root_, next_quality_).value_or(beast::kZERO))
{
TRACE_FUNC();
XRPL_ASSERT(root_ != beast::kZERO, "xrpl::BookDirs::BookDirs : nonzero root");
if (key_ != beast::kZERO)
{
@@ -32,6 +34,7 @@ BookDirs::BookDirs(ReadView const& view, Book const& book)
auto
BookDirs::begin() const -> BookDirs::const_iterator
{
TRACE_FUNC();
auto it = BookDirs::const_iterator(*view_, root_, key_);
if (key_ != beast::kZERO)
{
@@ -46,12 +49,14 @@ BookDirs::begin() const -> BookDirs::const_iterator
auto
BookDirs::end() const -> BookDirs::const_iterator
{
TRACE_FUNC();
return BookDirs::const_iterator(*view_, root_, key_);
}
bool
BookDirs::const_iterator::operator==(BookDirs::const_iterator const& other) const
{
TRACE_FUNC();
if (view_ == nullptr || other.view_ == nullptr)
return false;
@@ -65,6 +70,7 @@ BookDirs::const_iterator::operator==(BookDirs::const_iterator const& other) cons
BookDirs::const_iterator::reference
BookDirs::const_iterator::operator*() const
{
TRACE_FUNC();
XRPL_ASSERT(
index_ != beast::kZERO, "xrpl::BookDirs::const_iterator::operator* : nonzero index");
if (!cache_)
@@ -75,6 +81,7 @@ BookDirs::const_iterator::operator*() const
BookDirs::const_iterator&
BookDirs::const_iterator::operator++()
{
TRACE_FUNC();
using beast::kZERO;
XRPL_ASSERT(index_ != kZERO, "xrpl::BookDirs::const_iterator::operator++ : nonzero index");
@@ -104,6 +111,7 @@ BookDirs::const_iterator::operator++()
BookDirs::const_iterator
BookDirs::const_iterator::operator++(int)
{
TRACE_FUNC();
XRPL_ASSERT(
index_ != beast::kZERO, "xrpl::BookDirs::const_iterator::operator++(int) : nonzero index");
const_iterator tmp(*this);

View File

@@ -4,6 +4,7 @@
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/MultiApiJson.h>
#include <xrpl/server/InfoSub.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdint>
#include <mutex>
@@ -13,6 +14,7 @@ namespace xrpl {
void
BookListeners::addSubscriber(InfoSub::ref sub)
{
TRACE_FUNC();
std::scoped_lock const sl(lock_);
listeners_[sub->getSeq()] = sub;
}
@@ -20,6 +22,7 @@ BookListeners::addSubscriber(InfoSub::ref sub)
void
BookListeners::removeSubscriber(std::uint64_t seq)
{
TRACE_FUNC();
std::scoped_lock const sl(lock_);
listeners_.erase(seq);
}
@@ -27,6 +30,7 @@ BookListeners::removeSubscriber(std::uint64_t seq)
void
BookListeners::publish(MultiApiJson const& jvObj, hash_set<std::uint64_t>& havePublished)
{
TRACE_FUNC();
std::scoped_lock const sl(lock_);
auto it = listeners_.cbegin();

View File

@@ -6,6 +6,7 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/basics/TraceLog.h>
#include <memory>
#include <mutex>
@@ -16,12 +17,14 @@ namespace xrpl::detail {
bool
CachedViewImpl::exists(Keylet const& k) const
{
TRACE_FUNC();
return read(k) != nullptr;
}
std::shared_ptr<SLE const>
CachedViewImpl::read(Keylet const& k) const
{
TRACE_FUNC();
static CountedObjects::Counter kHITS{"CachedView::hit"};
static CountedObjects::Counter kHITSEXPIRED{"CachedView::hitExpired"};
static CountedObjects::Counter kMISSES{"CachedView::miss"};

View File

@@ -5,6 +5,7 @@
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/basics/TraceLog.h>
#include <cstring>
#include <memory>
@@ -15,6 +16,7 @@ namespace xrpl {
bool
operator<(CanonicalTXSet::Key const& lhs, CanonicalTXSet::Key const& rhs)
{
TRACE_FUNC();
if (lhs.account_ < rhs.account_)
return true;
@@ -33,6 +35,7 @@ operator<(CanonicalTXSet::Key const& lhs, CanonicalTXSet::Key const& rhs)
uint256
CanonicalTXSet::accountKey(AccountID const& account)
{
TRACE_FUNC();
uint256 ret = beast::kZERO;
memcpy(ret.begin(), account.begin(), account.size());
ret ^= salt_;
@@ -42,6 +45,7 @@ CanonicalTXSet::accountKey(AccountID const& account)
void
CanonicalTXSet::insert(std::shared_ptr<STTx const> const& txn)
{
TRACE_FUNC();
map_.insert(
std::make_pair(
Key(accountKey(txn->getAccountID(sfAccount)),
@@ -53,6 +57,7 @@ CanonicalTXSet::insert(std::shared_ptr<STTx const> const& txn)
std::shared_ptr<STTx const>
CanonicalTXSet::popAcctTransaction(std::shared_ptr<STTx const> const& tx)
{
TRACE_FUNC();
// Determining the next viable transaction for an account with Tickets:
//
// 1. Prioritize transactions with Sequences over transactions with

View File

@@ -6,6 +6,7 @@
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/basics/TraceLog.h>
#include <cstddef>
#include <iterator>
@@ -18,6 +19,7 @@ using const_iterator = Dir::ConstIterator;
Dir::Dir(ReadView const& view, Keylet const& key)
: view_(&view), root_(key), sle_(view_->read(root_))
{
TRACE_FUNC();
if (sle_ != nullptr)
indexes_ = &sle_->getFieldV256(sfIndexes);
}
@@ -25,6 +27,7 @@ Dir::Dir(ReadView const& view, Keylet const& key)
auto
Dir::begin() const -> ConstIterator
{
TRACE_FUNC();
auto it = ConstIterator(*view_, root_, root_);
if (sle_ != nullptr)
{
@@ -43,12 +46,14 @@ Dir::begin() const -> ConstIterator
auto
Dir::end() const -> ConstIterator
{
TRACE_FUNC();
return ConstIterator(*view_, root_, root_);
}
bool
const_iterator::operator==(ConstIterator const& other) const
{
TRACE_FUNC();
if (view_ == nullptr || other.view_ == nullptr)
return false;
@@ -61,6 +66,7 @@ const_iterator::operator==(ConstIterator const& other) const
const_iterator::reference
const_iterator::operator*() const
{
TRACE_FUNC();
XRPL_ASSERT(index_ != beast::kZERO, "xrpl::const_iterator::operator* : nonzero index");
if (!cache_)
cache_ = view_->read(keylet::child(index_));
@@ -70,6 +76,7 @@ const_iterator::operator*() const
const_iterator&
const_iterator::operator++()
{
TRACE_FUNC();
XRPL_ASSERT(index_ != beast::kZERO, "xrpl::const_iterator::operator++ : nonzero index");
if (++it_ != std::end(*indexes_))
{
@@ -84,6 +91,7 @@ const_iterator::operator++()
const_iterator
const_iterator::operator++(int)
{
TRACE_FUNC();
XRPL_ASSERT(index_ != beast::kZERO, "xrpl::const_iterator::operator++(int) : nonzero index");
ConstIterator tmp(*this);
++(*this);
@@ -93,6 +101,7 @@ const_iterator::operator++(int)
const_iterator&
const_iterator::nextPage()
{
TRACE_FUNC();
auto const next = sle_->getFieldU64(sfIndexNext);
if (next == 0)
{
@@ -122,6 +131,7 @@ const_iterator::nextPage()
std::size_t
const_iterator::pageSize()
{
TRACE_FUNC();
return indexes_->size();
}

View File

@@ -35,6 +35,7 @@
#include <xrpl/shamap/SHAMapItem.h>
#include <xrpl/shamap/SHAMapMissingNode.h>
#include <xrpl/shamap/SHAMapTreeNode.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cstdint>
@@ -69,12 +70,14 @@ public:
[[nodiscard]] std::unique_ptr<base_type>
copy() const override
{
TRACE_FUNC();
return std::make_unique<SlesIterImpl>(*this);
}
[[nodiscard]] bool
equal(base_type const& impl) const override
{
TRACE_FUNC();
if (auto const p = dynamic_cast<SlesIterImpl const*>(&impl))
return iter_ == p->iter_;
return false;
@@ -83,12 +86,14 @@ public:
void
increment() override
{
TRACE_FUNC();
++iter_;
}
[[nodiscard]] SlesType::value_type
dereference() const override
{
TRACE_FUNC();
SerialIter sit(iter_->slice());
return std::make_shared<SLE const>(sit, iter_->key());
}
@@ -116,12 +121,14 @@ public:
[[nodiscard]] std::unique_ptr<base_type>
copy() const override
{
TRACE_FUNC();
return std::make_unique<TxsIterImpl>(*this);
}
[[nodiscard]] bool
equal(base_type const& impl) const override
{
TRACE_FUNC();
if (auto const p = dynamic_cast<TxsIterImpl const*>(&impl))
return iter_ == p->iter_;
return false;
@@ -130,12 +137,14 @@ public:
void
increment() override
{
TRACE_FUNC();
++iter_;
}
[[nodiscard]] TxsType::value_type
dereference() const override
{
TRACE_FUNC();
auto const& item = *iter_;
if (metadata_)
return Ledger::deserializeTxPlusMeta(item);
@@ -158,6 +167,7 @@ Ledger::Ledger(
, rules_(std::move(rules))
, j_(beast::Journal(beast::Journal::getNullSink()))
{
TRACE_FUNC();
header_.seq = 1;
header_.drops = kINITIAL_XRP;
header_.closeTimeResolution = kLEDGER_GENESIS_TIME_RESOLUTION;
@@ -221,6 +231,7 @@ Ledger::Ledger(
, header_(info)
, j_(j)
{
TRACE_FUNC();
loaded = true;
if (header_.txHash.isNonZero() && !txMap_.fetchRoot(SHAMapHash{header_.txHash}, nullptr))
@@ -259,6 +270,7 @@ Ledger::Ledger(Ledger const& prevLedger, NetClock::time_point closeTime)
, rules_(prevLedger.rules_)
, j_(beast::Journal(beast::Journal::getNullSink()))
{
TRACE_FUNC();
header_.seq = prevLedger.header_.seq + 1;
header_.parentCloseTime = prevLedger.header_.closeTime;
header_.hash = prevLedger.header().hash + uint256(1);
@@ -286,6 +298,7 @@ Ledger::Ledger(LedgerHeader const& info, Rules rules, Family& family)
, header_(info)
, j_(beast::Journal(beast::Journal::getNullSink()))
{
TRACE_FUNC();
header_.hash = calculateLedgerHash(header_);
}
@@ -302,6 +315,7 @@ Ledger::Ledger(
, rules_(std::move(rules))
, j_(beast::Journal(beast::Journal::getNullSink()))
{
TRACE_FUNC();
header_.seq = ledgerSeq;
header_.closeTime = closeTime;
header_.closeTimeResolution = kLEDGER_DEFAULT_TIME_RESOLUTION;
@@ -311,6 +325,7 @@ Ledger::Ledger(
void
Ledger::setImmutable(bool rehash)
{
TRACE_FUNC();
// Force update, since this is the only
// place the hash transitions to valid
if (!immutable_ && rehash)
@@ -334,6 +349,7 @@ Ledger::setAccepted(
NetClock::duration closeResolution,
bool correctCloseTime)
{
TRACE_FUNC();
// Used when we witnessed the consensus.
XRPL_ASSERT(!open(), "xrpl::Ledger::setAccepted : valid ledger state");
@@ -346,6 +362,7 @@ Ledger::setAccepted(
bool
Ledger::addSLE(SLE const& sle)
{
TRACE_FUNC();
auto const s = sle.getSerializer();
return stateMap_.addItem(SHAMapNodeType::TnAccountState, makeShamapitem(sle.key(), s.slice()));
}
@@ -355,6 +372,7 @@ Ledger::addSLE(SLE const& sle)
std::shared_ptr<STTx const>
Ledger::deserializeTx(SHAMapItem const& item)
{
TRACE_FUNC();
SerialIter sit(item.slice());
return std::make_shared<STTx const>(sit);
}
@@ -362,6 +380,7 @@ Ledger::deserializeTx(SHAMapItem const& item)
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>
Ledger::deserializeTxPlusMeta(SHAMapItem const& item)
{
TRACE_FUNC();
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>> result;
SerialIter sit(item.slice());
{
@@ -380,6 +399,7 @@ Ledger::deserializeTxPlusMeta(SHAMapItem const& item)
bool
Ledger::exists(Keylet const& k) const
{
TRACE_FUNC();
// VFALCO NOTE Perhaps check the type for debug builds?
return stateMap_.hasItem(k.key);
}
@@ -387,12 +407,14 @@ Ledger::exists(Keylet const& k) const
bool
Ledger::exists(uint256 const& key) const
{
TRACE_FUNC();
return stateMap_.hasItem(key);
}
std::optional<uint256>
Ledger::succ(uint256 const& key, std::optional<uint256> const& last) const
{
TRACE_FUNC();
auto item = stateMap_.upperBound(key);
if (item == stateMap_.end())
return std::nullopt;
@@ -404,6 +426,7 @@ Ledger::succ(uint256 const& key, std::optional<uint256> const& last) const
std::shared_ptr<SLE const>
Ledger::read(Keylet const& k) const
{
TRACE_FUNC();
if (k.key == beast::kZERO)
{
// LCOV_EXCL_START
@@ -425,42 +448,49 @@ Ledger::read(Keylet const& k) const
auto
Ledger::slesBegin() const -> std::unique_ptr<SlesType::iter_base>
{
TRACE_FUNC();
return std::make_unique<SlesIterImpl>(stateMap_.begin());
}
auto
Ledger::slesEnd() const -> std::unique_ptr<SlesType::iter_base>
{
TRACE_FUNC();
return std::make_unique<SlesIterImpl>(stateMap_.end());
}
auto
Ledger::slesUpperBound(uint256 const& key) const -> std::unique_ptr<SlesType::iter_base>
{
TRACE_FUNC();
return std::make_unique<SlesIterImpl>(stateMap_.upperBound(key));
}
auto
Ledger::txsBegin() const -> std::unique_ptr<TxsType::iter_base>
{
TRACE_FUNC();
return std::make_unique<TxsIterImpl>(!open(), txMap_.begin());
}
auto
Ledger::txsEnd() const -> std::unique_ptr<TxsType::iter_base>
{
TRACE_FUNC();
return std::make_unique<TxsIterImpl>(!open(), txMap_.end());
}
bool
Ledger::txExists(uint256 const& key) const
{
TRACE_FUNC();
return txMap_.hasItem(key);
}
auto
Ledger::txRead(key_type const& key) const -> tx_type
{
TRACE_FUNC();
auto const& item = txMap_.peekItem(key);
if (!item)
return {};
@@ -475,6 +505,7 @@ Ledger::txRead(key_type const& key) const -> tx_type
auto
Ledger::digest(key_type const& key) const -> std::optional<digest_type>
{
TRACE_FUNC();
SHAMapHash digest;
// VFALCO Unfortunately this loads the item
// from the NodeStore needlessly.
@@ -488,6 +519,7 @@ Ledger::digest(key_type const& key) const -> std::optional<digest_type>
void
Ledger::rawErase(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
if (!stateMap_.delItem(sle->key()))
logicError("Ledger::rawErase: key not found");
}
@@ -495,6 +527,7 @@ Ledger::rawErase(std::shared_ptr<SLE> const& sle)
void
Ledger::rawErase(uint256 const& key)
{
TRACE_FUNC();
if (!stateMap_.delItem(key))
logicError("Ledger::rawErase: key not found");
}
@@ -502,6 +535,7 @@ Ledger::rawErase(uint256 const& key)
void
Ledger::rawInsert(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
Serializer ss;
sle->add(ss);
if (!stateMap_.addGiveItem(
@@ -514,6 +548,7 @@ Ledger::rawInsert(std::shared_ptr<SLE> const& sle)
void
Ledger::rawReplace(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
Serializer ss;
sle->add(ss);
if (!stateMap_.updateGiveItem(
@@ -529,6 +564,7 @@ Ledger::rawTxInsert(
std::shared_ptr<Serializer const> const& txn,
std::shared_ptr<Serializer const> const& metaData)
{
TRACE_FUNC();
XRPL_ASSERT(metaData, "xrpl::Ledger::rawTxInsert : non-null metadata input");
// low-level - just add to table
@@ -542,6 +578,7 @@ Ledger::rawTxInsert(
bool
Ledger::setup()
{
TRACE_FUNC();
bool ret = true;
try
@@ -626,6 +663,7 @@ Ledger::setup()
std::shared_ptr<SLE>
Ledger::peek(Keylet const& k) const
{
TRACE_FUNC();
auto const& value = stateMap_.peekItem(k.key);
if (!value)
return nullptr;
@@ -638,6 +676,7 @@ Ledger::peek(Keylet const& k) const
hash_set<PublicKey>
Ledger::negativeUNL() const
{
TRACE_FUNC();
hash_set<PublicKey> negUnl;
if (auto sle = read(keylet::negativeUNL()); sle && sle->isFieldPresent(sfDisabledValidators))
{
@@ -663,6 +702,7 @@ Ledger::negativeUNL() const
std::optional<PublicKey>
Ledger::validatorToDisable() const
{
TRACE_FUNC();
if (auto sle = read(keylet::negativeUNL()); sle && sle->isFieldPresent(sfValidatorToDisable))
{
auto d = sle->getFieldVL(sfValidatorToDisable);
@@ -677,6 +717,7 @@ Ledger::validatorToDisable() const
std::optional<PublicKey>
Ledger::validatorToReEnable() const
{
TRACE_FUNC();
if (auto sle = read(keylet::negativeUNL()); sle && sle->isFieldPresent(sfValidatorToReEnable))
{
auto d = sle->getFieldVL(sfValidatorToReEnable);
@@ -691,6 +732,7 @@ Ledger::validatorToReEnable() const
void
Ledger::updateNegativeUNL()
{
TRACE_FUNC();
auto sle = peek(keylet::negativeUNL());
if (!sle)
return;
@@ -740,6 +782,7 @@ Ledger::updateNegativeUNL()
bool
Ledger::walkLedger(beast::Journal j, bool parallel) const
{
TRACE_FUNC();
std::vector<SHAMapMissingNode> missingNodes1;
std::vector<SHAMapMissingNode> missingNodes2;
@@ -791,6 +834,7 @@ Ledger::walkLedger(beast::Journal j, bool parallel) const
bool
Ledger::isSensible() const
{
TRACE_FUNC();
if (header_.hash.isZero())
return false;
if (header_.accountHash.isZero())
@@ -807,6 +851,7 @@ Ledger::isSensible() const
void
Ledger::updateSkipList()
{
TRACE_FUNC();
if (header_.seq == 0) // genesis ledger has no previous ledger
return;
@@ -880,17 +925,20 @@ Ledger::updateSkipList()
bool
Ledger::isFlagLedger() const
{
TRACE_FUNC();
return ::xrpl::isFlagLedger(header_.seq);
}
bool
Ledger::isVotingLedger() const
{
TRACE_FUNC();
return ::xrpl::isVotingLedger(header_.seq + 1);
}
void
Ledger::unshare() const
{
TRACE_FUNC();
stateMap_.unshare();
txMap_.unshare();
}
@@ -898,6 +946,7 @@ Ledger::unshare() const
void
Ledger::invariants() const
{
TRACE_FUNC();
stateMap_.invariants();
txMap_.invariants();
}

View File

@@ -12,6 +12,7 @@
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/container/pmr/monotonic_buffer_resource.hpp>
@@ -39,12 +40,14 @@ public:
[[nodiscard]] std::unique_ptr<base_type>
copy() const override
{
TRACE_FUNC();
return std::make_unique<TxsIterImpl>(metadata_, iter_);
}
[[nodiscard]] bool
equal(base_type const& impl) const override
{
TRACE_FUNC();
if (auto const p = dynamic_cast<TxsIterImpl const*>(&impl))
return iter_ == p->iter_;
return false;
@@ -53,14 +56,17 @@ public:
void
increment() override
{
TRACE_FUNC();
++iter_;
}
[[nodiscard]] value_type
dereference() const override
{
TRACE_FUNC();
value_type result;
{
TRACE_FUNC();
SerialIter sit(iter_->second.txn->slice());
result.first = std::make_shared<STTx const>(sit);
}
@@ -97,6 +103,7 @@ OpenView::OpenView(OpenLedgerT, ReadView const* base, Rules rules, std::shared_p
, base_(base)
, hold_(std::move(hold))
{
TRACE_FUNC();
header_.validated = false;
header_.accepted = false;
header_.seq = base_->header().seq + 1;
@@ -119,12 +126,14 @@ OpenView::OpenView(ReadView const* base, std::shared_ptr<void const> hold)
std::size_t
OpenView::txCount() const
{
TRACE_FUNC();
return baseTxCount_ + txs_.size();
}
void
OpenView::apply(TxsRawView& to) const
{
TRACE_FUNC();
items_.apply(to);
for (auto const& item : txs_)
to.rawTxInsert(item.first, item.second.txn, item.second.meta);
@@ -135,24 +144,28 @@ OpenView::apply(TxsRawView& to) const
LedgerHeader const&
OpenView::header() const
{
TRACE_FUNC();
return header_;
}
Fees const&
OpenView::fees() const
{
TRACE_FUNC();
return base_->fees();
}
Rules const&
OpenView::rules() const
{
TRACE_FUNC();
return rules_;
}
bool
OpenView::exists(Keylet const& k) const
{
TRACE_FUNC();
return items_.exists(*base_, k);
}
@@ -160,54 +173,63 @@ auto
OpenView::succ(key_type const& key, std::optional<key_type> const& last) const
-> std::optional<key_type>
{
TRACE_FUNC();
return items_.succ(*base_, key, last);
}
std::shared_ptr<SLE const>
OpenView::read(Keylet const& k) const
{
TRACE_FUNC();
return items_.read(*base_, k);
}
auto
OpenView::slesBegin() const -> std::unique_ptr<SlesType::iter_base>
{
TRACE_FUNC();
return items_.slesBegin(*base_);
}
auto
OpenView::slesEnd() const -> std::unique_ptr<SlesType::iter_base>
{
TRACE_FUNC();
return items_.slesEnd(*base_);
}
auto
OpenView::slesUpperBound(uint256 const& key) const -> std::unique_ptr<SlesType::iter_base>
{
TRACE_FUNC();
return items_.slesUpperBound(*base_, key);
}
auto
OpenView::txsBegin() const -> std::unique_ptr<TxsType::iter_base>
{
TRACE_FUNC();
return std::make_unique<TxsIterImpl>(!open(), txs_.cbegin());
}
auto
OpenView::txsEnd() const -> std::unique_ptr<TxsType::iter_base>
{
TRACE_FUNC();
return std::make_unique<TxsIterImpl>(!open(), txs_.cend());
}
bool
OpenView::txExists(key_type const& key) const
{
TRACE_FUNC();
return txs_.contains(key);
}
auto
OpenView::txRead(key_type const& key) const -> tx_type
{
TRACE_FUNC();
auto const iter = txs_.find(key);
if (iter == txs_.end())
return base_->txRead(key);
@@ -230,24 +252,28 @@ OpenView::txRead(key_type const& key) const -> tx_type
void
OpenView::rawErase(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
items_.erase(sle);
}
void
OpenView::rawInsert(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
items_.insert(sle);
}
void
OpenView::rawReplace(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
items_.replace(sle);
}
void
OpenView::rawDestroyXRP(XRPAmount const& fee)
{
TRACE_FUNC();
items_.destroyXRP(fee);
// VFALCO Deduct from header_.totalDrops ?
// What about child views?
@@ -261,6 +287,7 @@ OpenView::rawTxInsert(
std::shared_ptr<Serializer const> const& txn,
std::shared_ptr<Serializer const> const& metaData)
{
TRACE_FUNC();
auto const result = txs_.emplace(
std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(txn, metaData));
if (!result.second)

View File

@@ -10,6 +10,7 @@
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cstdint>
@@ -25,6 +26,7 @@ namespace detail {
auto
DeferredCredits::makeKeyIOU(AccountID const& a1, AccountID const& a2, Currency const& c) -> KeyIOU
{
TRACE_FUNC();
if (a1 < a2)
{
return std::make_tuple(a1, a2, c);
@@ -40,6 +42,7 @@ DeferredCredits::creditIOU(
STAmount const& amount,
STAmount const& preCreditSenderBalance)
{
TRACE_FUNC();
XRPL_ASSERT(
sender != receiver, "xrpl::detail::DeferredCredits::creditIOU : sender is not receiver");
XRPL_ASSERT(!amount.negative(), "xrpl::detail::DeferredCredits::creditIOU : positive amount");
@@ -90,6 +93,7 @@ DeferredCredits::creditMPT(
std::uint64_t preCreditBalanceHolder,
std::int64_t preCreditBalanceIssuer)
{
TRACE_FUNC();
XRPL_ASSERT(
amount.holds<MPTIssue>(),
"xrpl::detail::DeferredCredits::creditMPT : amount is for MPTIssue");
@@ -153,6 +157,7 @@ DeferredCredits::issuerSelfDebitMPT(
std::uint64_t amount,
std::int64_t origBalance)
{
TRACE_FUNC();
auto const& mptID = issue.getMptID();
auto i = creditsMPT_.find(mptID);
@@ -172,6 +177,7 @@ DeferredCredits::issuerSelfDebitMPT(
void
DeferredCredits::ownerCount(AccountID const& id, std::uint32_t cur, std::uint32_t next)
{
TRACE_FUNC();
auto const v = std::max(cur, next);
auto r = ownerCounts_.emplace(id, v);
if (!r.second)
@@ -184,6 +190,7 @@ DeferredCredits::ownerCount(AccountID const& id, std::uint32_t cur, std::uint32_
std::optional<std::uint32_t>
DeferredCredits::ownerCount(AccountID const& id) const
{
TRACE_FUNC();
auto i = ownerCounts_.find(id);
if (i != ownerCounts_.end())
return i->second;
@@ -197,6 +204,7 @@ DeferredCredits::adjustmentsIOU(
AccountID const& other,
Currency const& currency) const -> std::optional<AdjustmentIOU>
{
TRACE_FUNC();
std::optional<AdjustmentIOU> result;
KeyIOU const k = makeKeyIOU(main, other, currency);
@@ -219,6 +227,7 @@ DeferredCredits::adjustmentsIOU(
auto
DeferredCredits::adjustmentsMPT(xrpl::MPTID const& mptID) const -> std::optional<AdjustmentMPT>
{
TRACE_FUNC();
auto i = creditsMPT_.find(mptID);
if (i == creditsMPT_.end())
return std::nullopt;
@@ -228,6 +237,7 @@ DeferredCredits::adjustmentsMPT(xrpl::MPTID const& mptID) const -> std::optional
void
DeferredCredits::apply(DeferredCredits& to)
{
TRACE_FUNC();
for (auto const& i : creditsIOU_)
{
auto r = to.creditsIOU_.emplace(i);
@@ -285,6 +295,7 @@ PaymentSandbox::balanceHookIOU(
AccountID const& issuer,
STAmount const& amount) const
{
TRACE_FUNC();
XRPL_ASSERT(amount.holds<Issue>(), "balanceHookIOU: amount is for Issue");
/*
@@ -337,6 +348,7 @@ STAmount
PaymentSandbox::balanceHookMPT(AccountID const& account, MPTIssue const& issue, std::int64_t amount)
const
{
TRACE_FUNC();
auto const& issuer = issue.getIssuer();
bool const accountIsHolder = account != issuer;
@@ -374,6 +386,7 @@ PaymentSandbox::balanceHookMPT(AccountID const& account, MPTIssue const& issue,
STAmount
PaymentSandbox::balanceHookSelfIssueMPT(xrpl::MPTIssue const& issue, std::int64_t amount) const
{
TRACE_FUNC();
std::int64_t selfDebited = 0;
std::int64_t lastBal = amount;
for (auto curSB = this; curSB != nullptr; curSB = curSB->ps_)
@@ -394,6 +407,7 @@ PaymentSandbox::balanceHookSelfIssueMPT(xrpl::MPTIssue const& issue, std::int64_
std::uint32_t
PaymentSandbox::ownerCountHook(AccountID const& account, std::uint32_t count) const
{
TRACE_FUNC();
std::uint32_t result = count;
for (auto curSB = this; curSB != nullptr; curSB = curSB->ps_)
{
@@ -410,6 +424,7 @@ PaymentSandbox::creditHookIOU(
STAmount const& amount,
STAmount const& preCreditBalance)
{
TRACE_FUNC();
XRPL_ASSERT(amount.holds<Issue>(), "creditHookIOU: amount is for Issue");
tab_.creditIOU(from, to, amount, preCreditBalance);
@@ -423,6 +438,7 @@ PaymentSandbox::creditHookMPT(
std::uint64_t preCreditBalanceHolder,
std::int64_t preCreditBalanceIssuer)
{
TRACE_FUNC();
XRPL_ASSERT(amount.holds<MPTIssue>(), "creditHookMPT: amount is for MPTIssue");
tab_.creditMPT(from, to, amount, preCreditBalanceHolder, preCreditBalanceIssuer);
@@ -434,6 +450,7 @@ PaymentSandbox::issuerSelfDebitHookMPT(
std::uint64_t amount,
std::int64_t origBalance)
{
TRACE_FUNC();
XRPL_ASSERT(amount > 0, "PaymentSandbox::issuerSelfDebitHookMPT: amount must be > 0");
tab_.issuerSelfDebitMPT(issue, amount, origBalance);
@@ -445,12 +462,14 @@ PaymentSandbox::adjustOwnerCountHook(
std::uint32_t cur,
std::uint32_t next)
{
TRACE_FUNC();
tab_.ownerCount(account, cur, next);
}
void
PaymentSandbox::apply(RawView& to)
{
TRACE_FUNC();
XRPL_ASSERT(!ps_, "xrpl::PaymentSandbox::apply : non-null sandbox");
items_.apply(to);
}
@@ -458,6 +477,7 @@ PaymentSandbox::apply(RawView& to)
void
PaymentSandbox::apply(PaymentSandbox& to)
{
TRACE_FUNC();
XRPL_ASSERT(ps_ == &to, "xrpl::PaymentSandbox::apply : matching sandbox");
items_.apply(to);
tab_.apply(to.tab_);
@@ -466,6 +486,7 @@ PaymentSandbox::apply(PaymentSandbox& to)
XRPAmount
PaymentSandbox::xrpDestroyed() const
{
TRACE_FUNC();
return items_.dropsDestroyed();
}

View File

@@ -8,6 +8,7 @@
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/basics/TraceLog.h>
#include <memory>
#include <optional>
@@ -37,6 +38,7 @@ public:
ReadView::SlesType::Iterator end0)
: iter0_(std::move(iter0)), end0_(std::move(end0)), iter1_(iter1), end1_(end1)
{
TRACE_FUNC();
if (iter0_ != end0_)
sle0_ = *iter0_;
if (iter1_ != end1)
@@ -49,12 +51,14 @@ public:
std::unique_ptr<base_type>
copy() const override
{
TRACE_FUNC();
return std::make_unique<SlesIterImpl>(*this);
}
bool
equal(base_type const& impl) const override
{
TRACE_FUNC();
if (auto const p = dynamic_cast<SlesIterImpl const*>(&impl))
{
XRPL_ASSERT(
@@ -70,6 +74,7 @@ public:
void
increment() override
{
TRACE_FUNC();
XRPL_ASSERT(
sle1_ || sle0_,
"xrpl::detail::RawStateTable::increment : either SLE is "
@@ -106,6 +111,7 @@ public:
value_type
dereference() const override
{
TRACE_FUNC();
if (!sle1_)
{
return sle0_;
@@ -123,6 +129,7 @@ private:
void
inc0()
{
TRACE_FUNC();
++iter0_;
if (iter0_ == end0_)
{
@@ -137,6 +144,7 @@ private:
void
inc1()
{
TRACE_FUNC();
++iter1_;
if (iter1_ == end1_)
{
@@ -151,6 +159,7 @@ private:
void
skip()
{
TRACE_FUNC();
while (iter1_ != end1_ && iter1_->second.action == Action::Erase &&
sle0_->key() == sle1_->key())
{
@@ -169,6 +178,7 @@ private:
void
RawStateTable::apply(RawView& to) const
{
TRACE_FUNC();
to.rawDestroyXRP(dropsDestroyed_);
for (auto const& elem : items_)
{
@@ -191,6 +201,7 @@ RawStateTable::apply(RawView& to) const
bool
RawStateTable::exists(ReadView const& base, Keylet const& k) const
{
TRACE_FUNC();
XRPL_ASSERT(k.key.isNonZero(), "xrpl::detail::RawStateTable::exists : nonzero key");
auto const iter = items_.find(k.key);
if (iter == items_.end())
@@ -211,6 +222,7 @@ auto
RawStateTable::succ(ReadView const& base, key_type const& key, std::optional<key_type> const& last)
const -> std::optional<key_type>
{
TRACE_FUNC();
std::optional<key_type> next = key;
items_t::const_iterator iter;
// Find base successor that is
@@ -243,6 +255,7 @@ RawStateTable::succ(ReadView const& base, key_type const& key, std::optional<key
void
RawStateTable::erase(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
// The base invariant is checked during apply
auto const result = items_.emplace(
std::piecewise_construct,
@@ -269,6 +282,7 @@ RawStateTable::erase(std::shared_ptr<SLE> const& sle)
void
RawStateTable::insert(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
auto const result = items_.emplace(
std::piecewise_construct,
std::forward_as_tuple(sle->key()),
@@ -294,6 +308,7 @@ RawStateTable::insert(std::shared_ptr<SLE> const& sle)
void
RawStateTable::replace(std::shared_ptr<SLE> const& sle)
{
TRACE_FUNC();
auto const result = items_.emplace(
std::piecewise_construct,
std::forward_as_tuple(sle->key()),
@@ -316,6 +331,7 @@ RawStateTable::replace(std::shared_ptr<SLE> const& sle)
std::shared_ptr<SLE const>
RawStateTable::read(ReadView const& base, Keylet const& k) const
{
TRACE_FUNC();
auto const iter = items_.find(k.key);
if (iter == items_.end())
return base.read(k);
@@ -332,12 +348,14 @@ RawStateTable::read(ReadView const& base, Keylet const& k) const
void
RawStateTable::destroyXRP(XRPAmount const& fee)
{
TRACE_FUNC();
dropsDestroyed_ += fee;
}
std::unique_ptr<ReadView::SlesType::iter_base>
RawStateTable::slesBegin(ReadView const& base) const
{
TRACE_FUNC();
return std::make_unique<SlesIterImpl>(
items_.begin(), items_.end(), base.sles.begin(), base.sles.end());
}
@@ -345,6 +363,7 @@ RawStateTable::slesBegin(ReadView const& base) const
std::unique_ptr<ReadView::SlesType::iter_base>
RawStateTable::slesEnd(ReadView const& base) const
{
TRACE_FUNC();
return std::make_unique<SlesIterImpl>(
items_.end(), items_.end(), base.sles.end(), base.sles.end());
}
@@ -352,6 +371,7 @@ RawStateTable::slesEnd(ReadView const& base) const
std::unique_ptr<ReadView::SlesType::iter_base>
RawStateTable::slesUpperBound(ReadView const& base, uint256 const& key) const
{
TRACE_FUNC();
return std::make_unique<SlesIterImpl>(
items_.upper_bound(key), items_.end(), base.sles.upperBound(key), base.sles.end());
}

View File

@@ -7,6 +7,7 @@
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/basics/TraceLog.h>
#include <optional>
#include <unordered_set>
@@ -20,18 +21,21 @@ ReadView::SlesType::SlesType(ReadView const& view) : ReadViewFwdRange(view)
auto
ReadView::SlesType::begin() const -> Iterator
{
TRACE_FUNC();
return Iterator(view_, view_->slesBegin());
}
auto
ReadView::SlesType::end() const -> Iterator
{
TRACE_FUNC();
return Iterator(view_, view_->slesEnd());
}
auto
ReadView::SlesType::upperBound(key_type const& key) const -> Iterator
{
TRACE_FUNC();
return Iterator(view_, view_->slesUpperBound(key));
}
@@ -42,24 +46,28 @@ ReadView::TxsType::TxsType(ReadView const& view) : ReadViewFwdRange(view)
bool
ReadView::TxsType::empty() const
{
TRACE_FUNC();
return begin() == end();
}
auto
ReadView::TxsType::begin() const -> Iterator
{
TRACE_FUNC();
return Iterator(view_, view_->txsBegin());
}
auto
ReadView::TxsType::end() const -> Iterator
{
TRACE_FUNC();
return Iterator(view_, view_->txsEnd());
}
Rules
makeRulesGivenLedger(DigestAwareReadView const& ledger, Rules const& current)
{
TRACE_FUNC();
return makeRulesGivenLedger(ledger, current.presets());
}
@@ -68,6 +76,7 @@ makeRulesGivenLedger(
DigestAwareReadView const& ledger,
std::unordered_set<uint256, beast::Uhash<>> const& presets)
{
TRACE_FUNC();
Keylet const k = keylet::amendments();
std::optional const digest = ledger.digest(k.key);
if (digest)

View File

@@ -29,6 +29,7 @@
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdint>
#include <memory>
@@ -46,6 +47,7 @@ namespace xrpl {
bool
hasExpired(ReadView const& view, std::optional<std::uint32_t> const& exp)
{
TRACE_FUNC();
using d = NetClock::duration;
using tp = NetClock::time_point;
@@ -59,6 +61,7 @@ isVaultPseudoAccountFrozen(
MPTIssue const& mptShare,
int depth)
{
TRACE_FUNC();
if (!view.rules().enabled(featureSingleAssetVault))
return false;
@@ -100,6 +103,7 @@ isLPTokenFrozen(
Asset const& asset,
Asset const& asset2)
{
TRACE_FUNC();
return isFrozen(view, account, asset) || isFrozen(view, account, asset2);
}
@@ -110,6 +114,7 @@ areCompatible(
beast::Journal::Stream& s,
char const* reason)
{
TRACE_FUNC();
bool ret = true;
if (validLedger.header().seq < testLedger.header().seq)
@@ -169,6 +174,7 @@ areCompatible(
beast::Journal::Stream& s,
char const* reason)
{
TRACE_FUNC();
bool ret = true;
if (testLedger.header().seq > validIndex)
@@ -204,6 +210,7 @@ areCompatible(
std::set<uint256>
getEnabledAmendments(ReadView const& view)
{
TRACE_FUNC();
std::set<uint256> amendments;
if (auto const sle = view.read(keylet::amendments()))
@@ -221,6 +228,7 @@ getEnabledAmendments(ReadView const& view)
majorityAmendments_t
getMajorityAmendments(ReadView const& view)
{
TRACE_FUNC();
majorityAmendments_t ret;
if (auto const sle = view.read(keylet::amendments()))
@@ -243,6 +251,7 @@ getMajorityAmendments(ReadView const& view)
std::optional<uint256>
hashOfSeq(ReadView const& ledger, LedgerIndex seq, beast::Journal journal)
{
TRACE_FUNC();
// Easy cases...
if (seq > ledger.seq())
{
@@ -311,6 +320,7 @@ dirLink(
std::shared_ptr<SLE>& object,
SF_UINT64 const& node)
{
TRACE_FUNC();
auto const page =
view.dirInsert(keylet::ownerDir(owner), object->key(), describeOwnerDir(owner));
if (!page)
@@ -342,6 +352,7 @@ withdrawToDestExceedsLimit(
AccountID const& to,
STAmount const& amount)
{
TRACE_FUNC();
auto const& issuer = amount.getIssuer();
if (from == to || to == issuer || isXRP(issuer))
return tesSUCCESS;
@@ -370,6 +381,7 @@ canWithdraw(
STAmount const& amount,
bool hasDestinationTag)
{
TRACE_FUNC();
if (auto const ret = checkDestinationAndTag(toSle, hasDestinationTag))
return ret;
@@ -393,6 +405,7 @@ canWithdraw(
STAmount const& amount,
bool hasDestinationTag)
{
TRACE_FUNC();
auto const toSle = view.read(keylet::account(to));
return canWithdraw(view, from, to, toSle, amount, hasDestinationTag);
@@ -401,6 +414,7 @@ canWithdraw(
[[nodiscard]] TER
canWithdraw(ReadView const& view, STTx const& tx)
{
TRACE_FUNC();
auto const from = tx[sfAccount];
auto const to = tx[~sfDestination].value_or(from);
@@ -418,6 +432,7 @@ doWithdraw(
STAmount const& amount,
beast::Journal j)
{
TRACE_FUNC();
// Create trust line or MPToken for the receiving account
if (dstAcct == senderAcct)
{
@@ -460,6 +475,7 @@ cleanupOnAccountDelete(
beast::Journal j,
std::optional<uint16_t> maxNodesToDelete)
{
TRACE_FUNC();
// Delete all the entries in the account directory.
std::shared_ptr<SLE> sleDirNode{};
unsigned int uDirEntry{0};
@@ -531,6 +547,7 @@ cleanupOnAccountDelete(
bool
after(NetClock::time_point now, std::uint32_t mark)
{
TRACE_FUNC();
return now.time_since_epoch().count() > mark;
}

View File

@@ -30,6 +30,7 @@
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <chrono>
@@ -45,6 +46,7 @@ namespace xrpl {
STAmount
ammLPTokens(STAmount const& asset1, STAmount const& asset2, Asset const& lptIssue)
{
TRACE_FUNC();
// AMM invariant: sqrt(asset1 * asset2) >= LPTokensBalance
auto const rounding =
isFeatureEnabled(fixAMMv1_3) ? Number::RoundingMode::Downward : Number::getround();
@@ -66,6 +68,7 @@ lpTokensOut(
STAmount const& lptAMMBalance,
std::uint16_t tfee)
{
TRACE_FUNC();
auto const f1 = feeMult(tfee);
auto const f2 = feeMultHalf(tfee) / f1;
Number const r = asset1Deposit / asset1Balance;
@@ -99,6 +102,7 @@ ammAssetIn(
STAmount const& lpTokens,
std::uint16_t tfee)
{
TRACE_FUNC();
auto const f1 = feeMult(tfee);
auto const f2 = feeMultHalf(tfee) / f1;
auto const t1 = lpTokens / lptAMMBalance;
@@ -128,6 +132,7 @@ lpTokensIn(
STAmount const& lptAMMBalance,
std::uint16_t tfee)
{
TRACE_FUNC();
Number const fr = asset1Withdraw / asset1Balance;
auto const f1 = getFee(tfee);
auto const c = fr * f1 + 2 - f1;
@@ -159,6 +164,7 @@ ammAssetOut(
STAmount const& lpTokens,
std::uint16_t tfee)
{
TRACE_FUNC();
auto const f = getFee(tfee);
Number const t1 = lpTokens / lptAMMBalance;
if (!isFeatureEnabled(fixAMMv1_3))
@@ -175,12 +181,14 @@ ammAssetOut(
Number
square(Number const& n)
{
TRACE_FUNC();
return n * n;
}
STAmount
adjustLPTokens(STAmount const& lptAMMBalance, STAmount const& lpTokens, IsDeposit isDeposit)
{
TRACE_FUNC();
// Force rounding downward to ensure adjusted tokens are less or equal
// to requested tokens.
SaveNumberRoundMode const rm(Number::setround(Number::RoundingMode::Downward));
@@ -199,6 +207,7 @@ adjustAmountsByLPTokens(
std::uint16_t tfee,
IsDeposit isDeposit)
{
TRACE_FUNC();
// AMMv1_3 amendment adjusts tokens and amounts in deposit/withdraw
if (isFeatureEnabled(fixAMMv1_3))
return std::make_tuple(amount, amount2, lpTokens);
@@ -269,6 +278,7 @@ adjustAmountsByLPTokens(
Number
solveQuadraticEq(Number const& a, Number const& b, Number const& c)
{
TRACE_FUNC();
return (-b + root2(b * b - 4 * a * c)) / (2 * a);
}
@@ -276,6 +286,7 @@ solveQuadraticEq(Number const& a, Number const& b, Number const& c)
std::optional<Number>
solveQuadraticEqSmallest(Number const& a, Number const& b, Number const& c)
{
TRACE_FUNC();
auto const d = b * b - 4 * a * c;
if (d < 0)
return std::nullopt;
@@ -292,6 +303,7 @@ solveQuadraticEqSmallest(Number const& a, Number const& b, Number const& c)
STAmount
multiply(STAmount const& amount, Number const& frac, Number::RoundingMode rm)
{
TRACE_FUNC();
NumberRoundModeGuard const g(rm);
auto const t = amount * frac;
return toSTAmount(amount.asset(), t, rm);
@@ -305,6 +317,7 @@ getRoundedAsset(
std::function<Number()> const& productCb,
IsDeposit isDeposit)
{
TRACE_FUNC();
if (!rules.enabled(fixAMMv1_3))
return toSTAmount(balance.asset(), noRoundCb());
@@ -322,6 +335,7 @@ getRoundedLPTokens(
Number const& frac,
IsDeposit isDeposit)
{
TRACE_FUNC();
if (!rules.enabled(fixAMMv1_3))
return toSTAmount(balance.asset(), balance * frac);
@@ -338,6 +352,7 @@ getRoundedLPTokens(
std::function<Number()> const& productCb,
IsDeposit isDeposit)
{
TRACE_FUNC();
if (!rules.enabled(fixAMMv1_3))
return toSTAmount(lptAMMBalance.asset(), noRoundCb());
@@ -362,6 +377,7 @@ adjustAssetInByTokens(
STAmount const& tokens,
std::uint16_t tfee)
{
TRACE_FUNC();
if (!rules.enabled(fixAMMv1_3))
return {tokens, amount};
auto assetAdj = ammAssetIn(balance, lptAMMBalance, tokens, tfee);
@@ -388,6 +404,7 @@ adjustAssetOutByTokens(
STAmount const& tokens,
std::uint16_t tfee)
{
TRACE_FUNC();
if (!rules.enabled(fixAMMv1_3))
return {tokens, amount};
auto assetAdj = ammAssetOut(balance, lptAMMBalance, tokens, tfee);
@@ -412,6 +429,7 @@ adjustFracByTokens(
STAmount const& tokens,
Number const& frac)
{
TRACE_FUNC();
if (!rules.enabled(fixAMMv1_3))
return frac;
return tokens / lptAMMBalance;
@@ -427,6 +445,7 @@ ammPoolHolds(
AuthHandling authHandling,
beast::Journal const j)
{
TRACE_FUNC();
auto const assetInBalance =
accountHolds(view, ammAccountID, asset1, freezeHandling, authHandling, j);
auto const assetOutBalance =
@@ -444,6 +463,7 @@ ammHolds(
AuthHandling authHandling,
beast::Journal const j)
{
TRACE_FUNC();
auto const assets = [&]() -> std::optional<std::pair<Asset, Asset>> {
auto const asset1 = ammSle[sfAsset];
auto const asset2 = ammSle[sfAsset2];
@@ -511,6 +531,7 @@ ammLPHolds(
AccountID const& lpAccount,
beast::Journal const j)
{
TRACE_FUNC();
// This function looks similar to `accountHolds`. However, it only checks if
// a LPToken holder has enough balance. On the other hand, `accountHolds`
// checks if the underlying assets of LPToken are frozen with the
@@ -559,12 +580,14 @@ ammLPHolds(
AccountID const& lpAccount,
beast::Journal const j)
{
TRACE_FUNC();
return ammLPHolds(view, ammSle[sfAsset], ammSle[sfAsset2], ammSle[sfAccount], lpAccount, j);
}
std::uint16_t
getTradingFee(ReadView const& view, SLE const& ammSle, AccountID const& account)
{
TRACE_FUNC();
using namespace std::chrono;
XRPL_ASSERT(
!view.rules().enabled(fixInnerObjTemplate) || ammSle.isFieldPresent(sfAuctionSlot),
@@ -595,6 +618,7 @@ getTradingFee(ReadView const& view, SLE const& ammSle, AccountID const& account)
STAmount
ammAccountHolds(ReadView const& view, AccountID const& ammAccountID, Asset const& asset)
{
TRACE_FUNC();
// Get the actual AMM balance without factoring in the balance hook
return asset.visit(
[&](MPTIssue const& issue) {
@@ -631,6 +655,7 @@ deleteAMMTrustLines(
std::uint16_t maxTrustlinesToDelete,
beast::Journal j)
{
TRACE_FUNC();
return cleanupOnAccountDelete(
sb,
keylet::ownerDir(ammAccountID),
@@ -667,6 +692,7 @@ deleteAMMTrustLines(
static TER
deleteAMMMPTokens(Sandbox& sb, AccountID const& ammAccountID, beast::Journal j)
{
TRACE_FUNC();
return cleanupOnAccountDelete(
sb,
keylet::ownerDir(ammAccountID),
@@ -712,6 +738,7 @@ deleteAMMMPTokens(Sandbox& sb, AccountID const& ammAccountID, beast::Journal j)
TER
deleteAMMAccount(Sandbox& sb, Asset const& asset, Asset const& asset2, beast::Journal j)
{
TRACE_FUNC();
auto ammSle = sb.peek(keylet::amm(asset, asset2));
if (!ammSle)
{
@@ -773,6 +800,7 @@ initializeFeeAuctionVote(
Asset const& lptAsset,
std::uint16_t tfee)
{
TRACE_FUNC();
auto const& rules = view.rules();
// AMM creator gets the voting slot.
STArray voteSlots;
@@ -822,6 +850,7 @@ initializeFeeAuctionVote(
Expected<bool, TER>
isOnlyLiquidityProvider(ReadView const& view, Issue const& ammIssue, AccountID const& lpAccount)
{
TRACE_FUNC();
// Liquidity Provider (LP) must have one LPToken trustline
std::uint8_t nLPTokenTrustLines = 0;
// AMM account has at most two IOU (pool tokens, not LPToken) trustlines.
@@ -926,6 +955,7 @@ verifyAndAdjustLPTokenBalance(
std::shared_ptr<SLE>& ammSle,
AccountID const& account)
{
TRACE_FUNC();
auto const res = isOnlyLiquidityProvider(sb, lpTokens.get<Issue>(), account);
if (!res.has_value())
{

View File

@@ -19,6 +19,7 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cstdint>
@@ -34,6 +35,7 @@ namespace xrpl {
bool
isGlobalFrozen(ReadView const& view, AccountID const& issuer)
{
TRACE_FUNC();
if (isXRP(issuer))
return false;
if (auto const sle = view.read(keylet::account(issuer)))
@@ -54,6 +56,7 @@ confineOwnerCount(
std::optional<AccountID> const& id = std::nullopt,
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
{
TRACE_FUNC();
std::uint32_t adjusted{current + adjustment};
if (adjustment > 0)
{
@@ -86,6 +89,7 @@ confineOwnerCount(
XRPAmount
xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j)
{
TRACE_FUNC();
auto const sle = view.read(keylet::account(id));
if (sle == nullptr)
return beast::kZERO;
@@ -116,6 +120,7 @@ xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj,
Rate
transferRate(ReadView const& view, AccountID const& issuer)
{
TRACE_FUNC();
auto const sle = view.read(keylet::account(issuer));
if (sle && sle->isFieldPresent(sfTransferRate))
@@ -131,6 +136,7 @@ adjustOwnerCount(
std::int32_t amount,
beast::Journal j)
{
TRACE_FUNC();
if (!sle)
return;
XRPL_ASSERT(amount, "xrpl::adjustOwnerCount : nonzero amount input");
@@ -145,6 +151,7 @@ adjustOwnerCount(
AccountID
pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey)
{
TRACE_FUNC();
// This number must not be changed without an amendment
constexpr std::uint16_t kMAX_ACCOUNT_ATTEMPTS = 256;
for (std::uint16_t i = 0; i < kMAX_ACCOUNT_ATTEMPTS; ++i)
@@ -168,6 +175,7 @@ pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey)
[[nodiscard]] std::vector<SField const*> const&
getPseudoAccountFields()
{
TRACE_FUNC();
static std::vector<SField const*> const kPSEUDO_FIELDS = []() {
auto const ar = LedgerFormats::getInstance().findByType(ltACCOUNT_ROOT);
if (!ar)
@@ -196,6 +204,7 @@ isPseudoAccount(
std::shared_ptr<SLE const> sleAcct,
std::set<SField const*> const& pseudoFieldFilter)
{
TRACE_FUNC();
auto const& fields = getPseudoAccountFields();
// Intentionally use defensive coding here because it's cheap and makes the
@@ -211,6 +220,7 @@ isPseudoAccount(
Expected<std::shared_ptr<SLE>, TER>
createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const& ownerField)
{
TRACE_FUNC();
[[maybe_unused]]
auto const& fields = getPseudoAccountFields();
XRPL_ASSERT(
@@ -253,6 +263,7 @@ createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const
[[nodiscard]] TER
checkDestinationAndTag(SLE::const_ref toSle, bool hasDestinationTag)
{
TRACE_FUNC();
if (toSle == nullptr)
return tecNO_DST;

View File

@@ -20,6 +20,7 @@
#include <xrpl/protocol/STVector256.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdint>
#include <limits>
@@ -35,6 +36,7 @@ namespace credentials {
bool
checkExpired(std::shared_ptr<SLE const> const& sleCredential, NetClock::time_point const& closed)
{
TRACE_FUNC();
std::uint32_t const exp =
(*sleCredential)[~sfExpiration].value_or(std::numeric_limits<std::uint32_t>::max());
std::uint32_t const now = closed.time_since_epoch().count();
@@ -44,6 +46,7 @@ checkExpired(std::shared_ptr<SLE const> const& sleCredential, NetClock::time_poi
bool
removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j)
{
TRACE_FUNC();
auto const closeTime = view.header().parentCloseTime;
bool foundExpired = false;
@@ -68,6 +71,7 @@ removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j)
TER
deleteSLE(ApplyView& view, std::shared_ptr<SLE> const& sleCredential, beast::Journal j)
{
TRACE_FUNC();
if (!sleCredential)
return tecNO_ENTRY;
@@ -122,6 +126,7 @@ deleteSLE(ApplyView& view, std::shared_ptr<SLE> const& sleCredential, beast::Jou
NotTEC
checkFields(STTx const& tx, beast::Journal j)
{
TRACE_FUNC();
if (!tx.isFieldPresent(sfCredentialIDs))
return tesSUCCESS;
@@ -150,6 +155,7 @@ checkFields(STTx const& tx, beast::Journal j)
TER
valid(STTx const& tx, ReadView const& view, AccountID const& src, beast::Journal j)
{
TRACE_FUNC();
if (!tx.isFieldPresent(sfCredentialIDs))
return tesSUCCESS;
@@ -184,6 +190,7 @@ valid(STTx const& tx, ReadView const& view, AccountID const& src, beast::Journal
TER
validDomain(ReadView const& view, uint256 domainID, AccountID const& subject)
{
TRACE_FUNC();
// Note, permissioned domain objects can be deleted at any time
auto const slePD = view.read(keylet::permissionedDomain(domainID));
if (!slePD)
@@ -225,6 +232,7 @@ validDomain(ReadView const& view, uint256 domainID, AccountID const& subject)
TER
authorizedDepositPreauth(ReadView const& view, STVector256 const& credIDs, AccountID const& dst)
{
TRACE_FUNC();
std::set<std::pair<AccountID, Slice>> sorted;
std::vector<std::shared_ptr<SLE const>> lifeExtender;
lifeExtender.reserve(credIDs.size());
@@ -249,6 +257,7 @@ authorizedDepositPreauth(ReadView const& view, STVector256 const& credIDs, Accou
std::set<std::pair<AccountID, Slice>>
makeSorted(STArray const& credentials)
{
TRACE_FUNC();
std::set<std::pair<AccountID, Slice>> out;
for (auto const& cred : credentials)
{
@@ -262,6 +271,7 @@ makeSorted(STArray const& credentials)
NotTEC
checkArray(STArray const& credentials, unsigned maxSize, beast::Journal j)
{
TRACE_FUNC();
if (credentials.empty() || (credentials.size() > maxSize))
{
JLOG(j.trace()) << "Malformed transaction: "
@@ -308,6 +318,7 @@ checkArray(STArray const& credentials, unsigned maxSize, beast::Journal j)
TER
verifyValidDomain(ApplyView& view, AccountID const& account, uint256 domainID, beast::Journal j)
{
TRACE_FUNC();
auto const slePD = view.read(keylet::permissionedDomain(domainID));
if (!slePD)
return tecOBJECT_NOT_FOUND;
@@ -347,6 +358,7 @@ verifyDepositPreauth(
std::shared_ptr<SLE const> const& sleDst,
beast::Journal j)
{
TRACE_FUNC();
// If depositPreauth is enabled, then an account that requires
// authorization has at least two ways to get a payment in:
// 1. If src == dst, or

View File

@@ -10,6 +10,7 @@
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdint>
#include <functional>
@@ -25,6 +26,7 @@ dirFirst(
unsigned int& index,
uint256& entry)
{
TRACE_FUNC();
return detail::internalDirFirst(view, root, page, index, entry);
}
@@ -36,6 +38,7 @@ dirNext(
unsigned int& index,
uint256& entry)
{
TRACE_FUNC();
return detail::internalDirNext(view, root, page, index, entry);
}
@@ -47,6 +50,7 @@ cdirFirst(
unsigned int& index,
uint256& entry)
{
TRACE_FUNC();
return detail::internalDirFirst(view, root, page, index, entry);
}
@@ -58,6 +62,7 @@ cdirNext(
unsigned int& index,
uint256& entry)
{
TRACE_FUNC();
return detail::internalDirNext(view, root, page, index, entry);
}
@@ -67,6 +72,7 @@ forEachItem(
Keylet const& root,
std::function<void(std::shared_ptr<SLE const> const&)> const& f)
{
TRACE_FUNC();
XRPL_ASSERT(root.type == ltDIR_NODE, "xrpl::forEachItem : valid root type");
if (root.type != ltDIR_NODE)
@@ -97,6 +103,7 @@ forEachItemAfter(
unsigned int limit,
std::function<bool(std::shared_ptr<SLE const> const&)> const& f)
{
TRACE_FUNC();
XRPL_ASSERT(root.type == ltDIR_NODE, "xrpl::forEachItemAfter : valid root type");
if (root.type != ltDIR_NODE)
@@ -170,6 +177,7 @@ forEachItemAfter(
bool
dirIsEmpty(ReadView const& view, Keylet const& k)
{
TRACE_FUNC();
auto const sleNode = view.read(k);
if (!sleNode)
return true;
@@ -184,6 +192,7 @@ dirIsEmpty(ReadView const& view, Keylet const& k)
std::function<void(SLE::ref)>
describeOwnerDir(AccountID const& account)
{
TRACE_FUNC();
return [account](std::shared_ptr<SLE> const& sle) { (*sle)[sfOwner] = account; };
}

View File

@@ -20,6 +20,7 @@
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/Units.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cstddef>
@@ -31,6 +32,7 @@ namespace xrpl {
bool
checkLendingProtocolDependencies(Rules const& rules, STTx const& tx)
{
TRACE_FUNC();
if (!rules.enabled(featureSingleAssetVault))
return false;
@@ -46,6 +48,7 @@ checkLendingProtocolDependencies(Rules const& rules, STTx const& tx)
LoanPaymentParts&
LoanPaymentParts::operator+=(LoanPaymentParts const& other)
{
TRACE_FUNC();
XRPL_ASSERT(
other.principalPaid >= beast::kZERO,
@@ -70,6 +73,7 @@ LoanPaymentParts::operator+=(LoanPaymentParts const& other)
bool
LoanPaymentParts::operator==(LoanPaymentParts const& other) const
{
TRACE_FUNC();
return principalPaid == other.principalPaid && interestPaid == other.interestPaid &&
valueChange == other.valueChange && feePaid == other.feePaid;
}
@@ -82,6 +86,7 @@ LoanPaymentParts::operator==(LoanPaymentParts const& other) const
Number
loanPeriodicRate(TenthBips32 interestRate, std::uint32_t paymentInterval)
{
TRACE_FUNC();
// Need floating point math, since we're dividing by a large number
return tenthBipsOfValue(Number(paymentInterval), interestRate) / kSECONDS_IN_YEAR;
}
@@ -93,6 +98,7 @@ loanPeriodicRate(TenthBips32 interestRate, std::uint32_t paymentInterval)
bool
isRounded(Asset const& asset, Number const& value, std::int32_t scale)
{
TRACE_FUNC();
return roundToAsset(asset, value, scale, Number::RoundingMode::Downward) ==
roundToAsset(asset, value, scale, Number::RoundingMode::Upward);
}
@@ -102,6 +108,7 @@ namespace detail {
void
LoanStateDeltas::nonNegative()
{
TRACE_FUNC();
if (principal < beast::kZERO)
principal = kNUM_ZERO;
if (interest < beast::kZERO)
@@ -117,6 +124,7 @@ LoanStateDeltas::nonNegative()
Number
computeRaisedRate(Number const& periodicRate, std::uint32_t paymentsRemaining)
{
TRACE_FUNC();
return power(1 + periodicRate, paymentsRemaining);
}
@@ -128,6 +136,7 @@ computeRaisedRate(Number const& periodicRate, std::uint32_t paymentsRemaining)
Number
computePaymentFactor(Number const& periodicRate, std::uint32_t paymentsRemaining)
{
TRACE_FUNC();
if (paymentsRemaining == 0)
return kNUM_ZERO;
@@ -151,6 +160,7 @@ loanPeriodicPayment(
Number const& periodicRate,
std::uint32_t paymentsRemaining)
{
TRACE_FUNC();
if (principalOutstanding == 0 || paymentsRemaining == 0)
return 0;
@@ -172,6 +182,7 @@ loanPrincipalFromPeriodicPayment(
Number const& periodicRate,
std::uint32_t paymentsRemaining)
{
TRACE_FUNC();
if (paymentsRemaining == 0)
return kNUM_ZERO;
@@ -193,6 +204,7 @@ computeInterestAndFeeParts(
TenthBips16 managementFeeRate,
std::int32_t loanScale)
{
TRACE_FUNC();
auto const fee = computeManagementFee(asset, interest, managementFeeRate, loanScale);
return std::make_pair(interest - fee, fee);
@@ -210,6 +222,7 @@ loanLatePaymentInterest(
NetClock::time_point parentCloseTime,
std::uint32_t nextPaymentDueDate)
{
TRACE_FUNC();
if (principalOutstanding == beast::kZERO)
return kNUM_ZERO;
@@ -245,6 +258,7 @@ loanAccruedInterest(
std::uint32_t prevPaymentDate,
std::uint32_t paymentInterval)
{
TRACE_FUNC();
if (periodicRate == beast::kZERO)
return kNUM_ZERO;
@@ -289,6 +303,7 @@ doPayment(
UInt32OptionalProxy& nextDueDateProxy,
std::uint32_t paymentInterval)
{
TRACE_FUNC();
XRPL_ASSERT_PARTS(nextDueDateProxy, "xrpl::detail::doPayment", "Next due date proxy set");
if (payment.specialCase == PaymentSpecialCase::Final)
@@ -412,6 +427,7 @@ tryOverpayment(
TenthBips16 const managementFeeRate,
beast::Journal j)
{
TRACE_FUNC();
// Calculate what the loan state SHOULD be theoretically (at full precision)
auto const theoreticalState = computeTheoreticalLoanState(
periodicPayment, periodicRate, paymentRemaining, managementFeeRate);
@@ -594,6 +610,7 @@ doOverpayment(
TenthBips16 const managementFeeRate,
beast::Journal j)
{
TRACE_FUNC();
auto const loanState = constructLoanState(
totalValueOutstandingProxy, principalOutstandingProxy, managementFeeOutstandingProxy);
auto const periodicPayment = periodicPaymentProxy;
@@ -712,6 +729,7 @@ computeLatePayment(
TenthBips16 managementFeeRate,
beast::Journal j)
{
TRACE_FUNC();
// Check if the due date has passed. If not, reject the payment as
// being too soon
if (!hasExpired(view, nextDueDate))
@@ -812,6 +830,7 @@ computeFullPayment(
TenthBips16 managementFeeRate,
beast::Journal j)
{
TRACE_FUNC();
// Full payment must be made before the final scheduled payment.
if (paymentRemaining <= 1)
{
@@ -906,6 +925,7 @@ computeFullPayment(
Number
PaymentComponents::trackedInterestPart() const
{
TRACE_FUNC();
return trackedValueDelta - (trackedPrincipalDelta + trackedManagementFeeDelta);
}
@@ -939,6 +959,7 @@ computePaymentComponents(
std::uint32_t paymentRemaining,
TenthBips16 managementFeeRate)
{
TRACE_FUNC();
XRPL_ASSERT_PARTS(
isRounded(asset, totalValueOutstanding, scale) &&
isRounded(asset, principalOutstanding, scale) &&
@@ -1149,6 +1170,7 @@ computeOverpaymentComponents(
TenthBips32 const overpaymentFeeRate,
TenthBips16 const managementFeeRate)
{
TRACE_FUNC();
XRPL_ASSERT(
overpayment > 0 && isRounded(asset, overpayment, loanScale),
"xrpl::detail::computeOverpaymentComponents : valid overpayment "
@@ -1200,6 +1222,7 @@ computeOverpaymentComponents(
detail::LoanStateDeltas
operator-(LoanState const& lhs, LoanState const& rhs)
{
TRACE_FUNC();
detail::LoanStateDeltas result{
.principal = lhs.principalOutstanding - rhs.principalOutstanding,
.interest = lhs.interestDue - rhs.interestDue,
@@ -1212,6 +1235,7 @@ operator-(LoanState const& lhs, LoanState const& rhs)
LoanState
operator-(LoanState const& lhs, detail::LoanStateDeltas const& rhs)
{
TRACE_FUNC();
LoanState result{
.valueOutstanding = lhs.valueOutstanding - rhs.total(),
.principalOutstanding = lhs.principalOutstanding - rhs.principal,
@@ -1225,6 +1249,7 @@ operator-(LoanState const& lhs, detail::LoanStateDeltas const& rhs)
LoanState
operator+(LoanState const& lhs, detail::LoanStateDeltas const& rhs)
{
TRACE_FUNC();
LoanState result{
.valueOutstanding = lhs.valueOutstanding + rhs.total(),
.principalOutstanding = lhs.principalOutstanding + rhs.principal,
@@ -1244,6 +1269,7 @@ checkLoanGuards(
LoanProperties const& properties,
beast::Journal j)
{
TRACE_FUNC();
auto const totalInterestOutstanding =
properties.loanState.valueOutstanding - principalRequested;
// Guard 1: if there is no computed total interest over the life of the
@@ -1329,6 +1355,7 @@ computeFullPaymentInterest(
std::uint32_t startDate,
TenthBips32 closeInterestRate)
{
TRACE_FUNC();
auto const accruedInterest = detail::loanAccruedInterest(
theoreticalPrincipalOutstanding,
periodicRate,
@@ -1384,6 +1411,7 @@ computeTheoreticalLoanState(
std::uint32_t const paymentRemaining,
TenthBips32 const managementFeeRate)
{
TRACE_FUNC();
if (paymentRemaining == 0)
{
return LoanState{
@@ -1443,6 +1471,7 @@ constructLoanState(
Number const& principalOutstanding,
Number const& managementFeeOutstanding)
{
TRACE_FUNC();
// This implementation is pretty trivial, but ensures the calculations
// are consistent everywhere, and reduces copy/paste errors.
return LoanState{
@@ -1455,6 +1484,7 @@ constructLoanState(
LoanState
constructRoundedLoanState(SLE::const_ref loan)
{
TRACE_FUNC();
return constructLoanState(
loan->at(sfTotalValueOutstanding),
loan->at(sfPrincipalOutstanding),
@@ -1474,6 +1504,7 @@ computeManagementFee(
TenthBips32 managementFeeRate,
std::int32_t scale)
{
TRACE_FUNC();
return roundToAsset(
asset, tenthBipsOfValue(value, managementFeeRate), scale, Number::RoundingMode::Downward);
}
@@ -1496,6 +1527,7 @@ computeLoanProperties(
TenthBips32 managementFeeRate,
std::int32_t minimumScale)
{
TRACE_FUNC();
auto const periodicRate = loanPeriodicRate(interestRate, paymentInterval);
XRPL_ASSERT(interestRate == 0 || periodicRate > 0, "xrpl::computeLoanProperties : valid rate");
return computeLoanProperties(
@@ -1524,6 +1556,7 @@ computeLoanProperties(
TenthBips32 managementFeeRate,
std::int32_t minimumScale)
{
TRACE_FUNC();
auto const periodicPayment =
detail::loanPeriodicPayment(principalOutstanding, periodicRate, paymentsRemaining);
@@ -1608,6 +1641,7 @@ loanMakePayment(
LoanPaymentType const paymentType,
beast::Journal j)
{
TRACE_FUNC();
using namespace Lending;
auto principalOutstandingProxy = loan->at(sfPrincipalOutstanding);

View File

@@ -28,6 +28,7 @@
#include <xrpl/protocol/TxFormats.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdint>
#include <initializer_list>
@@ -41,6 +42,7 @@ namespace xrpl {
bool
isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue)
{
TRACE_FUNC();
if (auto const sle = view.read(keylet::mptIssuance(mptIssue.getMptID())))
return sle->isFlag(lsfMPTLocked);
return false;
@@ -49,6 +51,7 @@ isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue)
bool
isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue)
{
TRACE_FUNC();
if (auto const sle = view.read(keylet::mptoken(mptIssue.getMptID(), account)))
return sle->isFlag(lsfMPTLocked);
return false;
@@ -57,6 +60,7 @@ isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue cons
bool
isFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue, int depth)
{
TRACE_FUNC();
return isGlobalFrozen(view, mptIssue) || isIndividualFrozen(view, account, mptIssue) ||
isVaultPseudoAccountFrozen(view, account, mptIssue, depth);
}
@@ -68,6 +72,7 @@ isAnyFrozen(
MPTIssue const& mptIssue,
int depth)
{
TRACE_FUNC();
if (isGlobalFrozen(view, mptIssue))
return true;
@@ -89,6 +94,7 @@ isAnyFrozen(
Rate
transferRate(ReadView const& view, MPTID const& issuanceID)
{
TRACE_FUNC();
// fee is 0-50,000 (0-50%), rate is 1,000,000,000-2,000,000,000
// For example, if transfer fee is 50% then 10,000 * 50,000 = 500,000
// which represents 50% of 1,000,000,000
@@ -106,6 +112,7 @@ transferRate(ReadView const& view, MPTID const& issuanceID)
[[nodiscard]] TER
canAddHolding(ReadView const& view, MPTIssue const& mptIssue)
{
TRACE_FUNC();
auto mptID = mptIssue.getMptID();
auto issuance = view.read(keylet::mptIssuance(mptID));
if (!issuance)
@@ -128,6 +135,7 @@ addEmptyHolding(
MPTIssue const& mptIssue,
beast::Journal journal)
{
TRACE_FUNC();
auto const& mptID = mptIssue.getMptID();
auto const mpt = view.peek(keylet::mptIssuance(mptID));
if (!mpt)
@@ -152,6 +160,7 @@ authorizeMPToken(
std::uint32_t flags,
std::optional<AccountID> holderID)
{
TRACE_FUNC();
auto const sleAcct = view.peek(keylet::account(account));
if (!sleAcct)
return tecINTERNAL; // LCOV_EXCL_LINE
@@ -271,6 +280,7 @@ removeEmptyHolding(
MPTIssue const& mptIssue,
beast::Journal journal)
{
TRACE_FUNC();
// If the account is the issuer, then no token should exist. MPTs do not
// have the legacy ability to create such a situation, but check anyway. If
// a token does exist, it will get deleted. If not, return success.
@@ -305,6 +315,7 @@ requireAuth(
AuthType authType,
int depth)
{
TRACE_FUNC();
auto const mptID = keylet::mptIssuance(mptIssue.getMptID());
auto const sleIssuance = view.read(mptID);
if (!sleIssuance)
@@ -397,6 +408,7 @@ enforceMPTokenAuthorization(
XRPAmount const& priorBalance, // for MPToken authorization
beast::Journal j)
{
TRACE_FUNC();
auto const sleIssuance = view.read(keylet::mptIssuance(mptIssuanceID));
if (!sleIssuance)
return tefINTERNAL; // LCOV_EXCL_LINE
@@ -496,6 +508,7 @@ canTransfer(
AccountID const& from,
AccountID const& to)
{
TRACE_FUNC();
auto const mptID = keylet::mptIssuance(mptIssue.getMptID());
auto const sleIssuance = view.read(mptID);
if (!sleIssuance)
@@ -512,6 +525,7 @@ canTransfer(
TER
canTrade(ReadView const& view, Asset const& asset)
{
TRACE_FUNC();
return asset.visit(
[&](Issue const&) -> TER { return tesSUCCESS; },
[&](MPTIssue const& mptIssue) -> TER {
@@ -527,6 +541,7 @@ canTrade(ReadView const& view, Asset const& asset)
TER
lockEscrowMPT(ApplyView& view, AccountID const& sender, STAmount const& amount, beast::Journal j)
{
TRACE_FUNC();
auto const mptIssue = amount.get<MPTIssue>();
auto const mptID = keylet::mptIssuance(mptIssue.getMptID());
auto sleIssuance = view.peek(mptID);
@@ -626,6 +641,7 @@ unlockEscrowMPT(
STAmount const& grossAmount,
beast::Journal j)
{
TRACE_FUNC();
if (!view.rules().enabled(fixTokenEscrowV1))
{
XRPL_ASSERT(netAmount == grossAmount, "xrpl::unlockEscrowMPT : netAmount == grossAmount");
@@ -788,6 +804,7 @@ createMPToken(
AccountID const& account,
std::uint32_t const flags)
{
TRACE_FUNC();
auto const mptokenKey = keylet::mptoken(mptIssuanceID, account);
auto const ownerNode =
@@ -814,6 +831,7 @@ checkCreateMPT(
xrpl::AccountID const& holder,
beast::Journal j)
{
TRACE_FUNC();
if (mptIssue.getIssuer() == holder)
return tesSUCCESS;
@@ -839,12 +857,14 @@ checkCreateMPT(
std::int64_t
maxMPTAmount(SLE const& sleIssuance)
{
TRACE_FUNC();
return sleIssuance[~sfMaximumAmount].value_or(kMAX_MP_TOKEN_AMOUNT);
}
std::int64_t
availableMPTAmount(SLE const& sleIssuance)
{
TRACE_FUNC();
auto const max = maxMPTAmount(sleIssuance);
auto const outstanding = sleIssuance[sfOutstandingAmount];
return max - outstanding;
@@ -853,6 +873,7 @@ availableMPTAmount(SLE const& sleIssuance)
std::int64_t
availableMPTAmount(ReadView const& view, MPTID const& mptID)
{
TRACE_FUNC();
auto const sle = view.read(keylet::mptIssuance(mptID));
if (!sle)
Throw<std::runtime_error>(transHuman(tecINTERNAL));
@@ -866,6 +887,7 @@ isMPTOverflow(
std::int64_t maximumAmount,
AllowMPTOverflow allowOverflow)
{
TRACE_FUNC();
std::uint64_t const limit = (allowOverflow == AllowMPTOverflow::Yes)
? std::numeric_limits<std::uint64_t>::max()
: maximumAmount;
@@ -875,6 +897,7 @@ isMPTOverflow(
STAmount
issuerFundsToSelfIssue(ReadView const& view, MPTIssue const& issue)
{
TRACE_FUNC();
STAmount amount{issue};
auto const sle = view.read(keylet::mptIssuance(issue));
@@ -887,6 +910,7 @@ issuerFundsToSelfIssue(ReadView const& view, MPTIssue const& issue)
void
issuerSelfDebitHookMPT(ApplyView& view, MPTIssue const& issue, std::uint64_t amount)
{
TRACE_FUNC();
auto const available = availableMPTAmount(view, issue);
view.issuerSelfDebitHookMPT(issue, amount, available);
}
@@ -894,6 +918,7 @@ issuerSelfDebitHookMPT(ApplyView& view, MPTIssue const& issue, std::uint64_t amo
static TER
checkMPTAllowed(ReadView const& view, TxType txType, Asset const& asset, AccountID const& accountID)
{
TRACE_FUNC();
if (!asset.holds<MPTIssue>())
return tesSUCCESS;
@@ -947,6 +972,7 @@ checkMPTTxAllowed(
Asset const& asset,
AccountID const& accountID)
{
TRACE_FUNC();
// use isDEXAllowed for payment/offer crossing
XRPL_ASSERT(txType != ttPAYMENT, "xrpl::checkMPTTxAllowed : not payment");
return checkMPTAllowed(view, txType, asset, accountID);

View File

@@ -28,6 +28,7 @@
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol/nft.h>
#include <xrpl/protocol/nftPageMask.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cstddef>
@@ -44,6 +45,7 @@ namespace xrpl::nft {
static std::shared_ptr<SLE const>
locatePage(ReadView const& view, AccountID const& owner, uint256 const& id)
{
TRACE_FUNC();
auto const first = keylet::nftpage(keylet::nftpageMin(owner), id);
auto const last = keylet::nftpageMax(owner);
@@ -57,6 +59,7 @@ locatePage(ReadView const& view, AccountID const& owner, uint256 const& id)
static std::shared_ptr<SLE>
locatePage(ApplyView& view, AccountID const& owner, uint256 const& id)
{
TRACE_FUNC();
auto const first = keylet::nftpage(keylet::nftpageMin(owner), id);
auto const last = keylet::nftpageMax(owner);
@@ -74,6 +77,7 @@ getPageForToken(
uint256 const& id,
std::function<void(ApplyView&, AccountID const&)> const& createCallback)
{
TRACE_FUNC();
auto const base = keylet::nftpageMin(owner);
auto const first = keylet::nftpage(base, id);
auto const last = keylet::nftpageMax(owner);
@@ -212,6 +216,7 @@ getPageForToken(
bool
compareTokens(uint256 const& a, uint256 const& b)
{
TRACE_FUNC();
// The sort of NFTokens needs to be fully deterministic, but the sort
// is weird because we sort on the low 96-bits first. But if the low
// 96-bits are identical we still need a fully deterministic sort.
@@ -230,6 +235,7 @@ changeTokenURI(
uint256 const& nftokenID,
std::optional<xrpl::Slice> const& uri)
{
TRACE_FUNC();
std::shared_ptr<SLE> const page = locatePage(view, owner, nftokenID);
// If the page couldn't be found, the given NFT isn't owned by this account
@@ -262,6 +268,7 @@ changeTokenURI(
TER
insertToken(ApplyView& view, AccountID owner, STObject&& nft)
{
TRACE_FUNC();
XRPL_ASSERT(nft.isFieldPresent(sfNFTokenID), "xrpl::nft::insertToken : has NFT token");
// First, we need to locate the page the NFT belongs to, creating it
@@ -298,6 +305,7 @@ insertToken(ApplyView& view, AccountID owner, STObject&& nft)
static bool
mergePages(ApplyView& view, std::shared_ptr<SLE> const& p1, std::shared_ptr<SLE> const& p2)
{
TRACE_FUNC();
if (p1->key() >= p2->key())
Throw<std::runtime_error>("mergePages: pages passed in out of order!");
@@ -355,6 +363,7 @@ mergePages(ApplyView& view, std::shared_ptr<SLE> const& p1, std::shared_ptr<SLE>
TER
removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID)
{
TRACE_FUNC();
std::shared_ptr<SLE> const page = locatePage(view, owner, nftokenID);
// If the page couldn't be found, the given NFT isn't owned by this account
@@ -372,6 +381,7 @@ removeToken(
uint256 const& nftokenID,
std::shared_ptr<SLE> const& curr)
{
TRACE_FUNC();
// We found a page, but the given NFT may not be in it.
auto arr = curr->getFieldArray(sfNFTokens);
@@ -535,6 +545,7 @@ removeToken(
std::optional<STObject>
findToken(ReadView const& view, AccountID const& owner, uint256 const& nftokenID)
{
TRACE_FUNC();
std::shared_ptr<SLE const> const page = locatePage(view, owner, nftokenID);
// If the page couldn't be found, the given NFT isn't owned by this account
@@ -554,6 +565,7 @@ findToken(ReadView const& view, AccountID const& owner, uint256 const& nftokenID
std::optional<TokenAndPage>
findTokenAndPage(ApplyView& view, AccountID const& owner, uint256 const& nftokenID)
{
TRACE_FUNC();
std::shared_ptr<SLE> page = locatePage(view, owner, nftokenID);
// If the page couldn't be found, the given NFT isn't owned by this account
@@ -575,6 +587,7 @@ findTokenAndPage(ApplyView& view, AccountID const& owner, uint256 const& nftoken
std::size_t
removeTokenOffersWithLimit(ApplyView& view, Keylet const& directory, std::size_t maxDeletableOffers)
{
TRACE_FUNC();
if (maxDeletableOffers == 0)
return 0;
@@ -625,6 +638,7 @@ removeTokenOffersWithLimit(ApplyView& view, Keylet const& directory, std::size_t
bool
deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer)
{
TRACE_FUNC();
if (offer->getType() != ltNFTOKEN_OFFER)
return false;
@@ -653,6 +667,7 @@ deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer)
bool
repairNFTokenDirectoryLinks(ApplyView& view, AccountID const& owner)
{
TRACE_FUNC();
bool didRepair = false;
auto const last = keylet::nftpageMax(owner);
@@ -780,6 +795,7 @@ tokenOfferCreatePreflight(
std::optional<AccountID> const& owner,
std::uint32_t txFlags)
{
TRACE_FUNC();
if (amount.negative())
{
// An offer for a negative amount makes no sense.
@@ -833,6 +849,7 @@ tokenOfferCreatePreclaim(
std::optional<AccountID> const& owner,
std::uint32_t txFlags)
{
TRACE_FUNC();
if (((nftFlags & nft::kFLAG_CREATE_TRUST_LINES) == 0) && !amount.native() && (xferFee != 0u))
{
if (!view.exists(keylet::account(nftIssuer)))
@@ -933,6 +950,7 @@ tokenOfferCreateApply(
beast::Journal j,
std::uint32_t txFlags)
{
TRACE_FUNC();
Keylet const acctKeylet = keylet::account(acctID);
if (auto const acct = view.read(acctKeylet);
priorBalance < view.fees().accountReserve((*acct)[sfOwnerCount] + 1))
@@ -999,6 +1017,7 @@ checkTrustlineAuthorized(
beast::Journal const j,
Issue const& issue)
{
TRACE_FUNC();
// Only valid for custom currencies
XRPL_ASSERT(!isXRP(issue.currency), "xrpl::nft::checkTrustlineAuthorized : valid to check.");
@@ -1051,6 +1070,7 @@ checkTrustlineDeepFrozen(
beast::Journal const j,
Issue const& issue)
{
TRACE_FUNC();
// Only valid for custom currencies
XRPL_ASSERT(!isXRP(issue.currency), "xrpl::nft::checkTrustlineDeepFrozen : valid to check.");

View File

@@ -11,6 +11,7 @@
#include <xrpl/protocol/STArray.h> // IWYU pragma: keep
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/basics/TraceLog.h>
#include <memory>
@@ -19,6 +20,7 @@ namespace xrpl {
TER
offerDelete(ApplyView& view, std::shared_ptr<SLE> const& sle, beast::Journal j)
{
TRACE_FUNC();
if (!sle)
return tesSUCCESS;
auto offerIndex = sle->key();

View File

@@ -11,6 +11,7 @@
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/basics/TraceLog.h>
#include <memory>
@@ -23,6 +24,7 @@ closeChannel(
uint256 const& key,
beast::Journal j)
{
TRACE_FUNC();
AccountID const src = (*slep)[sfAccount];
// Remove PayChan from owner directory
{

View File

@@ -11,6 +11,7 @@
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
@@ -19,6 +20,7 @@ namespace xrpl::permissioned_dex {
bool
accountInDomain(ReadView const& view, AccountID const& account, Domain const& domainID)
{
TRACE_FUNC();
auto const sleDomain = view.read(keylet::permissionedDomain(domainID));
if (!sleDomain)
return false;
@@ -48,6 +50,7 @@ offerInDomain(
Domain const& domainID,
beast::Journal j)
{
TRACE_FUNC();
auto const sleOffer = view.read(keylet::offer(offerID));
// The following are defensive checks that should never happen, since this

View File

@@ -24,6 +24,7 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cstdint>
@@ -45,6 +46,7 @@ creditLimit(
AccountID const& issuer,
Currency const& currency)
{
TRACE_FUNC();
STAmount result(Issue{currency, account});
auto sleRippleState = view.read(keylet::line(account, issuer, currency));
@@ -66,6 +68,7 @@ creditLimit(
IOUAmount
creditLimit2(ReadView const& v, AccountID const& acc, AccountID const& iss, Currency const& cur)
{
TRACE_FUNC();
return toAmount<IOUAmount>(creditLimit(v, acc, iss, cur));
}
@@ -76,6 +79,7 @@ creditBalance(
AccountID const& issuer,
Currency const& currency)
{
TRACE_FUNC();
STAmount result(Issue{currency, account});
auto sleRippleState = view.read(keylet::line(account, issuer, currency));
@@ -109,6 +113,7 @@ isIndividualFrozen(
Currency const& currency,
AccountID const& issuer)
{
TRACE_FUNC();
if (isXRP(currency))
return false;
if (issuer != account)
@@ -130,6 +135,7 @@ isFrozen(
Currency const& currency,
AccountID const& issuer)
{
TRACE_FUNC();
if (isXRP(currency))
return false;
auto sle = view.read(keylet::account(issuer));
@@ -152,6 +158,7 @@ isDeepFrozen(
Currency const& currency,
AccountID const& issuer)
{
TRACE_FUNC();
if (isXRP(currency))
{
return false;
@@ -197,6 +204,7 @@ trustCreate(
std::uint32_t uQualityOut,
beast::Journal j)
{
TRACE_FUNC();
JLOG(j.trace()) << "trustCreate: " << to_string(uSrcAccountID) << ", "
<< to_string(uDstAccountID) << ", " << saBalance.getFullText();
@@ -299,6 +307,7 @@ trustDelete(
AccountID const& uHighAccountID,
beast::Journal j)
{
TRACE_FUNC();
// Detect legacy dirs.
std::uint64_t const uLowNode = sleRippleState->getFieldU64(sfLowNode);
std::uint64_t const uHighNode = sleRippleState->getFieldU64(sfHighNode);
@@ -339,6 +348,7 @@ updateTrustLine(
STAmount const& after,
beast::Journal j)
{
TRACE_FUNC();
if (!state)
return false;
std::uint32_t const flags(state->getFieldU32(sfFlags));
@@ -387,6 +397,7 @@ issueIOU(
Issue const& issue,
beast::Journal j)
{
TRACE_FUNC();
XRPL_ASSERT(
!isXRP(account) && !isXRP(issue.account),
"xrpl::issueIOU : neither account nor issuer is XRP");
@@ -481,6 +492,7 @@ redeemIOU(
Issue const& issue,
beast::Journal j)
{
TRACE_FUNC();
XRPL_ASSERT(
!isXRP(account) && !isXRP(issue.account),
"xrpl::redeemIOU : neither account nor issuer is XRP");
@@ -553,6 +565,7 @@ redeemIOU(
TER
requireAuth(ReadView const& view, Issue const& issue, AccountID const& account, AuthType authType)
{
TRACE_FUNC();
if (isXRP(issue) || issue.account == account)
return tesSUCCESS;
@@ -582,6 +595,7 @@ requireAuth(ReadView const& view, Issue const& issue, AccountID const& account,
TER
canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, AccountID const& to)
{
TRACE_FUNC();
if (issue.native())
return tesSUCCESS;
@@ -625,6 +639,7 @@ addEmptyHolding(
Issue const& issue,
beast::Journal journal)
{
TRACE_FUNC();
// Every account can hold XRP. An issuer can issue directly.
if (issue.native() || accountID == issue.getIssuer())
return tesSUCCESS;
@@ -678,6 +693,7 @@ removeEmptyHolding(
Issue const& issue,
beast::Journal journal)
{
TRACE_FUNC();
if (issue.native())
{
auto const sle = view.read(keylet::account(accountID));
@@ -741,6 +757,7 @@ deleteAMMTrustLine(
std::optional<AccountID> const& ammAccountID,
beast::Journal j)
{
TRACE_FUNC();
if (!sleState || sleState->getType() != ltRIPPLE_STATE)
return tecINTERNAL; // LCOV_EXCL_LINE
@@ -789,6 +806,7 @@ deleteAMMMPToken(
AccountID const& ammAccountID,
beast::Journal j)
{
TRACE_FUNC();
if (!view.dirRemove(
keylet::ownerDir(ammAccountID), (*sleMpt)[sfOwnerNode], sleMpt->key(), false))
return tefBAD_LEDGER; // LCOV_EXCL_LINE

View File

@@ -25,6 +25,7 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdint>
#include <initializer_list>
@@ -50,6 +51,7 @@ isLPTokenFrozen(
bool
isGlobalFrozen(ReadView const& view, Asset const& asset)
{
TRACE_FUNC();
return asset.visit(
[&](Issue const& issue) { return isGlobalFrozen(view, issue.getIssuer()); },
[&](MPTIssue const& issue) { return isGlobalFrozen(view, issue); });
@@ -58,6 +60,7 @@ isGlobalFrozen(ReadView const& view, Asset const& asset)
bool
isIndividualFrozen(ReadView const& view, AccountID const& account, Asset const& asset)
{
TRACE_FUNC();
return std::visit(
[&](auto const& issue) { return isIndividualFrozen(view, account, issue); }, asset.value());
}
@@ -65,6 +68,7 @@ isIndividualFrozen(ReadView const& view, AccountID const& account, Asset const&
bool
isFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth)
{
TRACE_FUNC();
return std::visit(
[&](auto const& issue) { return isFrozen(view, account, issue, depth); }, asset.value());
}
@@ -72,18 +76,21 @@ isFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int
TER
checkFrozen(ReadView const& view, AccountID const& account, Issue const& issue)
{
TRACE_FUNC();
return isFrozen(view, account, issue) ? (TER)tecFROZEN : (TER)tesSUCCESS;
}
TER
checkFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue)
{
TRACE_FUNC();
return isFrozen(view, account, mptIssue) ? (TER)tecLOCKED : (TER)tesSUCCESS;
}
TER
checkFrozen(ReadView const& view, AccountID const& account, Asset const& asset)
{
TRACE_FUNC();
return std::visit(
[&](auto const& issue) { return checkFrozen(view, account, issue); }, asset.value());
}
@@ -94,6 +101,7 @@ isAnyFrozen(
std::initializer_list<AccountID> const& accounts,
Issue const& issue)
{
TRACE_FUNC();
for (auto const& account : accounts)
{
if (isFrozen(view, account, issue.currency, issue.account))
@@ -109,6 +117,7 @@ isAnyFrozen(
Asset const& asset,
int depth)
{
TRACE_FUNC();
return asset.visit(
[&](Issue const& issue) { return isAnyFrozen(view, accounts, issue); },
[&](MPTIssue const& issue) { return isAnyFrozen(view, accounts, issue, depth); });
@@ -117,6 +126,7 @@ isAnyFrozen(
bool
isDeepFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue, int depth)
{
TRACE_FUNC();
// Unlike IOUs, frozen / locked MPTs are not allowed to send or receive
// funds, so checking "deep frozen" is the same as checking "frozen".
return isFrozen(view, account, mptIssue, depth);
@@ -125,6 +135,7 @@ isDeepFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mpt
bool
isDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth)
{
TRACE_FUNC();
return std::visit(
[&](auto const& issue) { return isDeepFrozen(view, account, issue, depth); },
asset.value());
@@ -133,12 +144,14 @@ isDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset,
TER
checkDeepFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue)
{
TRACE_FUNC();
return isDeepFrozen(view, account, mptIssue) ? (TER)tecLOCKED : (TER)tesSUCCESS;
}
TER
checkDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset)
{
TRACE_FUNC();
return std::visit(
[&](auto const& issue) { return checkDeepFrozen(view, account, issue); }, asset.value());
}
@@ -158,6 +171,7 @@ getLineIfUsable(
FreezeHandling zeroIfFrozen,
beast::Journal j)
{
TRACE_FUNC();
auto sle = view.read(keylet::line(account, issuer, currency));
if (!sle)
@@ -208,6 +222,7 @@ getTrustLineBalance(
bool includeOppositeLimit,
beast::Journal j)
{
TRACE_FUNC();
STAmount amount;
if (sle)
{
@@ -246,6 +261,7 @@ accountHolds(
beast::Journal j,
SpendableHandling includeFullBalance)
{
TRACE_FUNC();
STAmount const amount;
if (isXRP(currency))
{
@@ -276,6 +292,7 @@ accountHolds(
beast::Journal j,
SpendableHandling includeFullBalance)
{
TRACE_FUNC();
return accountHolds(
view, account, issue.currency, issue.account, zeroIfFrozen, j, includeFullBalance);
}
@@ -290,6 +307,7 @@ accountHolds(
beast::Journal j,
SpendableHandling includeFullBalance)
{
TRACE_FUNC();
bool const returnSpendable = (includeFullBalance == SpendableHandling::FullBalance);
STAmount amount{mptIssue};
auto const& issuer = mptIssue.getIssuer();
@@ -361,6 +379,7 @@ accountHolds(
beast::Journal j,
SpendableHandling includeFullBalance)
{
TRACE_FUNC();
return asset.visit(
[&](Issue const& issue) {
return accountHolds(view, account, issue, zeroIfFrozen, j, includeFullBalance);
@@ -379,6 +398,7 @@ accountFunds(
FreezeHandling freezeHandling,
beast::Journal j)
{
TRACE_FUNC();
XRPL_ASSERT(saDefault.holds<Issue>(), "xrpl::accountFunds: saDefault holds Issue");
if (!saDefault.native() && saDefault.getIssuer() == id)
@@ -397,6 +417,7 @@ accountFunds(
AuthHandling authHandling,
beast::Journal j)
{
TRACE_FUNC();
return saDefault.asset().visit(
[&](Issue const&) { return accountFunds(view, id, saDefault, freezeHandling, j); },
[&](MPTIssue const&) {
@@ -414,6 +435,7 @@ accountFunds(
Rate
transferRate(ReadView const& view, STAmount const& amount)
{
TRACE_FUNC();
return amount.asset().visit(
[&](Issue const& issue) { return transferRate(view, issue.getIssuer()); },
[&](MPTIssue const& issue) { return transferRate(view, issue.getMptID()); });
@@ -428,6 +450,7 @@ transferRate(ReadView const& view, STAmount const& amount)
[[nodiscard]] TER
canAddHolding(ReadView const& view, Issue const& issue)
{
TRACE_FUNC();
if (issue.native())
{
return tesSUCCESS; // No special checks for XRP
@@ -449,6 +472,7 @@ canAddHolding(ReadView const& view, Issue const& issue)
[[nodiscard]] TER
canAddHolding(ReadView const& view, Asset const& asset)
{
TRACE_FUNC();
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) -> TER { return canAddHolding(view, issue); },
asset.value());
@@ -462,6 +486,7 @@ addEmptyHolding(
Asset const& asset,
beast::Journal journal)
{
TRACE_FUNC();
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) -> TER {
return addEmptyHolding(view, accountID, priorBalance, issue, journal);
@@ -476,6 +501,7 @@ removeEmptyHolding(
Asset const& asset,
beast::Journal journal)
{
TRACE_FUNC();
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) -> TER {
return removeEmptyHolding(view, accountID, issue, journal);
@@ -492,6 +518,7 @@ removeEmptyHolding(
TER
requireAuth(ReadView const& view, Asset const& asset, AccountID const& account, AuthType authType)
{
TRACE_FUNC();
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) {
return requireAuth(view, issue, account, authType);
@@ -502,6 +529,7 @@ requireAuth(ReadView const& view, Asset const& asset, AccountID const& account,
TER
canTransfer(ReadView const& view, Asset const& asset, AccountID const& from, AccountID const& to)
{
TRACE_FUNC();
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) -> TER {
return canTransfer(view, issue, from, to);
@@ -528,6 +556,7 @@ directSendNoFeeIOU(
bool bCheckIssuer,
beast::Journal j)
{
TRACE_FUNC();
AccountID const& issuer = saAmount.getIssuer();
Currency const& currency = saAmount.get<Issue>().currency;
@@ -673,6 +702,7 @@ directSendNoLimitIOU(
beast::Journal j,
WaiveTransferFee waiveFee)
{
TRACE_FUNC();
auto const& issuer = saAmount.getIssuer();
XRPL_ASSERT(
@@ -722,6 +752,7 @@ directSendNoLimitMultiIOU(
beast::Journal j,
WaiveTransferFee waiveFee)
{
TRACE_FUNC();
auto const& issuer = issue.getIssuer();
XRPL_ASSERT(!isXRP(senderID), "xrpl::directSendNoLimitMultiIOU : sender is not XRP");
@@ -793,6 +824,7 @@ accountSendIOU(
beast::Journal j,
WaiveTransferFee waiveFee)
{
TRACE_FUNC();
if (view.rules().enabled(fixAMMv1_1))
{
if (saAmount < beast::kZERO || saAmount.holds<MPTIssue>())
@@ -910,6 +942,7 @@ accountSendMultiIOU(
beast::Journal j,
WaiveTransferFee waiveFee)
{
TRACE_FUNC();
XRPL_ASSERT_PARTS(
receivers.size() > 1, "xrpl::accountSendMultiIOU", "multiple recipients provided");
@@ -1036,6 +1069,7 @@ directSendNoFeeMPT(
STAmount const& saAmount,
beast::Journal j)
{
TRACE_FUNC();
// Do not check MPT authorization here - it must have been checked earlier
auto const mptID = keylet::mptIssuance(saAmount.get<MPTIssue>().getMptID());
auto const& issuer = saAmount.getIssuer();
@@ -1117,6 +1151,7 @@ directSendNoLimitMPT(
WaiveTransferFee waiveFee,
AllowMPTOverflow allowOverflow)
{
TRACE_FUNC();
XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::directSendNoLimitMPT : sender is not receiver");
// Safe to get MPT since directSendNoLimitMPT is only called by accountSendMPT
@@ -1177,6 +1212,7 @@ directSendNoLimitMultiMPT(
beast::Journal j,
WaiveTransferFee waiveFee)
{
TRACE_FUNC();
auto const& issuer = mptIssue.getIssuer();
auto const sle = view.read(keylet::mptIssuance(mptIssue.getMptID()));
@@ -1297,6 +1333,7 @@ accountSendMPT(
WaiveTransferFee waiveFee,
AllowMPTOverflow allowOverflow)
{
TRACE_FUNC();
XRPL_ASSERT(
saAmount >= beast::kZERO && saAmount.holds<MPTIssue>(),
"xrpl::accountSendMPT : minimum amount and MPT");
@@ -1322,6 +1359,7 @@ accountSendMultiMPT(
beast::Journal j,
WaiveTransferFee waiveFee)
{
TRACE_FUNC();
STAmount actual;
return directSendNoLimitMultiMPT(view, senderID, mptIssue, receivers, actual, j, waiveFee);
@@ -1342,6 +1380,7 @@ directSendNoFee(
bool bCheckIssuer,
beast::Journal j)
{
TRACE_FUNC();
return saAmount.asset().visit(
[&](Issue const&) {
return directSendNoFeeIOU(view, uSenderID, uReceiverID, saAmount, bCheckIssuer, j);
@@ -1362,6 +1401,7 @@ accountSend(
WaiveTransferFee waiveFee,
AllowMPTOverflow allowOverflow)
{
TRACE_FUNC();
return saAmount.asset().visit(
[&](Issue const&) {
return accountSendIOU(view, uSenderID, uReceiverID, saAmount, j, waiveFee);
@@ -1381,6 +1421,7 @@ accountSendMulti(
beast::Journal j,
WaiveTransferFee waiveFee)
{
TRACE_FUNC();
XRPL_ASSERT_PARTS(
receivers.size() > 1, "xrpl::accountSendMulti", "multiple recipients provided");
return asset.visit(
@@ -1400,6 +1441,7 @@ transferXRP(
STAmount const& amount,
beast::Journal j)
{
TRACE_FUNC();
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");

View File

@@ -6,6 +6,7 @@
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STNumber.h> // IWYU pragma: keep
#include <xrpl/basics/TraceLog.h>
#include <memory>
#include <optional>
@@ -18,6 +19,7 @@ assetsToSharesDeposit(
std::shared_ptr<SLE const> const& issuance,
STAmount const& assets)
{
TRACE_FUNC();
XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesDeposit : non-negative assets");
XRPL_ASSERT(
assets.asset() == vault->at(sfAsset),
@@ -45,6 +47,7 @@ sharesToAssetsDeposit(
std::shared_ptr<SLE const> const& issuance,
STAmount const& shares)
{
TRACE_FUNC();
XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares");
XRPL_ASSERT(
shares.asset() == vault->at(sfShareMPTID),
@@ -72,6 +75,7 @@ assetsToSharesWithdraw(
STAmount const& assets,
TruncateShares truncate)
{
TRACE_FUNC();
XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesWithdraw : non-negative assets");
XRPL_ASSERT(
assets.asset() == vault->at(sfAsset),
@@ -98,6 +102,7 @@ sharesToAssetsWithdraw(
std::shared_ptr<SLE const> const& issuance,
STAmount const& shares)
{
TRACE_FUNC();
XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsWithdraw : non-negative shares");
XRPL_ASSERT(
shares.asset() == vault->at(sfShareMPTID),

View File

@@ -5,6 +5,7 @@
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/net/AutoSocket.h>
#include <xrpl/net/HTTPClientSSLContext.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/asio/basic_waitable_timer.hpp>
#include <boost/asio/completion_condition.hpp>
@@ -42,12 +43,14 @@ HTTPClient::initializeSSLContext(
bool sslVerify,
beast::Journal j)
{
TRACE_FUNC();
gHttpClientSslContext.emplace(sslVerifyDir, sslVerifyFile, sslVerify, j);
}
void
HTTPClient::cleanupSSLContext()
{
TRACE_FUNC();
gHttpClientSslContext.reset();
}
@@ -83,6 +86,7 @@ public:
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
makeGet(std::string const& strPath, boost::asio::streambuf& sb, std::string const& strHost)
{
TRACE_FUNC();
std::ostream osRequest(&sb);
osRequest << "GET " << strPath
@@ -107,6 +111,7 @@ public:
int iStatus,
std::string const& strData)> complete)
{
TRACE_FUNC();
ssl_ = bSSL;
deqSites_ = deqSites;
build_ = build;
@@ -128,6 +133,7 @@ public:
int iStatus,
std::string const& strData)> complete)
{
TRACE_FUNC();
complete_ = complete;
timeout_ = timeout;
@@ -149,6 +155,7 @@ public:
void
httpsNext()
{
TRACE_FUNC();
JLOG(j_.trace()) << "Fetch: " << deqSites_[0];
auto query = std::make_shared<Query>(
@@ -193,6 +200,7 @@ public:
void
handleDeadline(boost::system::error_code const& ecResult)
{
TRACE_FUNC();
if (ecResult == boost::asio::error::operation_aborted)
{
// Timer canceled because deadline no longer needed.
@@ -229,6 +237,7 @@ public:
void
handleShutdown(boost::system::error_code const& ecResult)
{
TRACE_FUNC();
if (ecResult)
{
JLOG(j_.trace()) << "Shutdown error: " << deqSites_[0] << ": " << ecResult.message();
@@ -240,6 +249,7 @@ public:
boost::system::error_code const& ecResult,
boost::asio::ip::tcp::resolver::results_type result)
{
TRACE_FUNC();
if (!shutdown_)
{
shutdown_ = ecResult
@@ -270,6 +280,7 @@ public:
void
handleConnect(boost::system::error_code const& ecResult)
{
TRACE_FUNC();
if (!shutdown_)
shutdown_ = ecResult;
@@ -313,6 +324,7 @@ public:
void
handleRequest(boost::system::error_code const& ecResult)
{
TRACE_FUNC();
if (!shutdown_)
shutdown_ = ecResult;
@@ -341,6 +353,7 @@ public:
void
handleWrite(boost::system::error_code const& ecResult, std::size_t bytesTransferred)
{
TRACE_FUNC();
if (!shutdown_)
shutdown_ = ecResult;
@@ -368,6 +381,7 @@ public:
void
handleHeader(boost::system::error_code const& ecResult, std::size_t bytesTransferred)
{
TRACE_FUNC();
std::string strHeader{
{std::istreambuf_iterator<char>(&header_)}, std::istreambuf_iterator<char>()};
JLOG(j_.trace()) << "Header: \"" << strHeader << "\"";
@@ -435,6 +449,7 @@ public:
void
handleData(boost::system::error_code const& ecResult, std::size_t bytesTransferred)
{
TRACE_FUNC();
if (!shutdown_)
shutdown_ = ecResult;
@@ -467,6 +482,7 @@ public:
int iStatus = 0,
std::string const& strData = "")
{
TRACE_FUNC();
boost::system::error_code ecCancel;
try
{
@@ -554,6 +570,7 @@ HTTPClient::get(
complete,
beast::Journal& j)
{
TRACE_FUNC();
auto client = std::make_shared<HTTPClientImp>(ioContext, port, responseMax, j);
client->get(bSSL, deqSites, strPath, timeout, complete);
}
@@ -572,6 +589,7 @@ HTTPClient::get(
complete,
beast::Journal& j)
{
TRACE_FUNC();
std::deque<std::string> const deqSites(1, strSite);
auto client = std::make_shared<HTTPClientImp>(ioContext, port, responseMax, j);
@@ -592,6 +610,7 @@ HTTPClient::request(
complete,
beast::Journal& j)
{
TRACE_FUNC();
std::deque<std::string> const deqSites(1, strSite);
auto client = std::make_shared<HTTPClientImp>(ioContext, port, responseMax, j);

View File

@@ -1,6 +1,7 @@
#include <xrpl/net/RegisterSSLCerts.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/asio/ssl/context.hpp>
#include <boost/system/detail/error_code.hpp>
@@ -23,6 +24,7 @@ namespace xrpl {
void
registerSSLCerts(boost::asio::ssl::context& ctx, boost::system::error_code& ec, beast::Journal j)
{
TRACE_FUNC();
#if BOOST_OS_WINDOWS
auto certStoreDelete = [](void* h) {
if (h != nullptr)

View File

@@ -4,6 +4,7 @@
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Types.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <chrono>
@@ -16,17 +17,20 @@ namespace xrpl::NodeStore {
BatchWriter::BatchWriter(Callback& callback, Scheduler& scheduler)
: callback_(callback), scheduler_(scheduler)
{
TRACE_FUNC();
writeSet_.reserve(BatchWritePreallocationSize);
}
BatchWriter::~BatchWriter()
{
TRACE_FUNC();
waitForWriting();
}
void
BatchWriter::store(std::shared_ptr<NodeObject> const& object)
{
TRACE_FUNC();
std::unique_lock<decltype(writeMutex_)> sl(writeMutex_);
// If the batch has reached its limit, we wait
@@ -47,6 +51,7 @@ BatchWriter::store(std::shared_ptr<NodeObject> const& object)
int
BatchWriter::getWriteLoad()
{
TRACE_FUNC();
std::scoped_lock const sl(writeMutex_);
return std::max(writeLoad_, static_cast<int>(writeSet_.size()));
@@ -55,12 +60,14 @@ BatchWriter::getWriteLoad()
void
BatchWriter::performScheduledTask()
{
TRACE_FUNC();
writeBatch();
}
void
BatchWriter::writeBatch()
{
TRACE_FUNC();
for (;;)
{
std::vector<std::shared_ptr<NodeObject>> set;
@@ -101,6 +108,7 @@ BatchWriter::writeBatch()
void
BatchWriter::waitForWriting()
{
TRACE_FUNC();
std::unique_lock<decltype(writeMutex_)> sl(writeMutex_);
while (writePending_)

View File

@@ -15,6 +15,7 @@
#include <xrpl/nodestore/Types.h>
#include <xrpl/protocol/SystemParameters.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <atomic>
@@ -42,6 +43,7 @@ Database::Database(
, requestBundle_(get<int>(config, "rq_bundle", 4))
, readThreads_(std::max(1, readThreads))
{
TRACE_FUNC();
XRPL_ASSERT(readThreads, "xrpl::NodeStore::Database::Database : nonzero threads input");
if (earliestLedgerSeq_ < 1)
@@ -124,6 +126,7 @@ Database::Database(
Database::~Database()
{
TRACE_FUNC();
// NOTE!
// Any derived class should call the stop() method in its
// destructor. Otherwise, occasionally, the derived class may
@@ -136,12 +139,14 @@ Database::~Database()
bool
Database::isStopping() const
{
TRACE_FUNC();
return readStopping_.load(std::memory_order_relaxed);
}
void
Database::stop()
{
TRACE_FUNC();
{
std::scoped_lock const lock(readLock_);
@@ -179,6 +184,7 @@ Database::asyncFetch(
std::uint32_t ledgerSeq,
std::function<void(std::shared_ptr<NodeObject> const&)>&& cb)
{
TRACE_FUNC();
std::scoped_lock const lock(readLock_);
if (!isStopping())
@@ -191,6 +197,7 @@ Database::asyncFetch(
void
Database::importInternal(Backend& dstBackend, Database& srcDB)
{
TRACE_FUNC();
Batch batch;
batch.reserve(BatchWritePreallocationSize);
auto storeBatch = [&, fname = __func__]() {
@@ -233,6 +240,17 @@ Database::fetchNodeObject(
FetchType fetchType,
bool duplicate)
{
TRACE_FUNC();
{
std::scoped_lock const lock(negCacheMutex_);
if (negCache_.count(hash))
{
++fetchTotalCount_;
return nullptr;
}
}
FetchReport fetchReport(fetchType);
using namespace std::chrono;
@@ -246,6 +264,12 @@ Database::fetchNodeObject(
++fetchHitCount_;
fetchSz_ += nodeObject->getData().size();
}
else
{
std::scoped_lock const lock(negCacheMutex_);
if (negCache_.size() < kNegCacheMax)
negCache_.insert(hash);
}
++fetchTotalCount_;
fetchReport.elapsed = duration_cast<milliseconds>(dur);
@@ -253,9 +277,24 @@ Database::fetchNodeObject(
return nodeObject;
}
void
Database::negCacheErase(uint256 const& hash)
{
std::scoped_lock const lock(negCacheMutex_);
negCache_.erase(hash);
}
void
Database::negCacheClear()
{
std::scoped_lock const lock(negCacheMutex_);
negCache_.clear();
}
void
Database::getCountsJson(json::Value& obj)
{
TRACE_FUNC();
XRPL_ASSERT(obj.isObject(), "xrpl::NodeStore::Database::getCountsJson : valid input type");
{

View File

@@ -10,6 +10,7 @@
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Types.h>
#include <xrpl/basics/TraceLog.h>
#include <chrono>
#include <cstddef>
@@ -25,10 +26,12 @@ namespace xrpl::NodeStore {
void
DatabaseNodeImp::store(NodeObjectType type, Blob&& data, uint256 const& hash, std::uint32_t)
{
TRACE_FUNC();
storeStats(1, data.size());
auto obj = NodeObject::createObject(type, std::move(data), hash);
backend_->store(obj);
negCacheErase(hash);
}
void
@@ -37,6 +40,7 @@ DatabaseNodeImp::asyncFetch(
std::uint32_t ledgerSeq,
std::function<void(std::shared_ptr<NodeObject> const&)>&& callback)
{
TRACE_FUNC();
Database::asyncFetch(hash, ledgerSeq, std::move(callback));
}
@@ -47,6 +51,7 @@ DatabaseNodeImp::fetchNodeObject(
FetchReport& fetchReport,
bool duplicate)
{
TRACE_FUNC();
std::shared_ptr<NodeObject> nodeObject = nullptr;
Status status = Status::Ok;
@@ -84,6 +89,7 @@ DatabaseNodeImp::fetchNodeObject(
std::vector<std::shared_ptr<NodeObject>>
DatabaseNodeImp::fetchBatch(std::vector<uint256> const& hashes)
{
TRACE_FUNC();
using namespace std::chrono;
auto const before = steady_clock::now();

View File

@@ -12,6 +12,7 @@
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Types.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdint>
#include <exception>
@@ -33,7 +34,9 @@ DatabaseRotatingImp::DatabaseRotatingImp(
: DatabaseRotating(scheduler, readThreads, config, j)
, writableBackend_(std::move(writableBackend))
, archiveBackend_(std::move(archiveBackend))
, archiveHasData_(!get<bool>(config, "fresh_sync", false))
{
TRACE_FUNC();
if (writableBackend_)
fdRequired_ += writableBackend_->fdRequired();
if (archiveBackend_)
@@ -45,6 +48,7 @@ DatabaseRotatingImp::rotate(
std::unique_ptr<NodeStore::Backend>&& newBackend,
std::function<void(std::string const& writableName, std::string const& archiveName)> const& f)
{
TRACE_FUNC();
// Pass these two names to the callback function
std::string const newWritableBackendName = newBackend->getName();
std::string newArchiveBackendName;
@@ -64,12 +68,15 @@ DatabaseRotatingImp::rotate(
writableBackend_ = std::move(newBackend);
}
archiveHasData_.store(true, std::memory_order_relaxed);
negCacheClear();
f(newWritableBackendName, newArchiveBackendName);
}
std::string
DatabaseRotatingImp::getName() const
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
return writableBackend_->getName();
}
@@ -77,6 +84,7 @@ DatabaseRotatingImp::getName() const
std::int32_t
DatabaseRotatingImp::getWriteLoad() const
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
return writableBackend_->getWriteLoad();
}
@@ -84,6 +92,7 @@ DatabaseRotatingImp::getWriteLoad() const
void
DatabaseRotatingImp::importDatabase(Database& source)
{
TRACE_FUNC();
auto const backend = [&] {
std::scoped_lock const lock(mutex_);
return writableBackend_;
@@ -95,6 +104,7 @@ DatabaseRotatingImp::importDatabase(Database& source)
void
DatabaseRotatingImp::sync()
{
TRACE_FUNC();
std::scoped_lock const lock(mutex_);
writableBackend_->sync();
}
@@ -102,6 +112,7 @@ DatabaseRotatingImp::sync()
void
DatabaseRotatingImp::store(NodeObjectType type, Blob&& data, uint256 const& hash, std::uint32_t)
{
TRACE_FUNC();
auto nObj = NodeObject::createObject(type, std::move(data), hash);
auto const backend = [&] {
@@ -111,6 +122,7 @@ DatabaseRotatingImp::store(NodeObjectType type, Blob&& data, uint256 const& hash
backend->store(nObj);
storeStats(1, nObj->getData().size());
negCacheErase(hash);
}
std::shared_ptr<NodeObject>
@@ -120,6 +132,7 @@ DatabaseRotatingImp::fetchNodeObject(
FetchReport& fetchReport,
bool duplicate)
{
TRACE_FUNC();
auto fetch = [&](std::shared_ptr<Backend> const& backend) {
Status status = Status::Ok;
std::shared_ptr<NodeObject> nodeObject;
@@ -159,12 +172,14 @@ DatabaseRotatingImp::fetchNodeObject(
// Try to fetch from the writable backend
nodeObject = fetch(writable);
if (!nodeObject)
if (!nodeObject && archiveHasData_.load(std::memory_order_relaxed))
{
// Otherwise try to fetch from the archive backend
// Only try archive if it's known to have data
nodeObject = fetch(archive);
if (nodeObject)
{
archiveHasData_.store(true, std::memory_order_relaxed);
{
// Refresh the writable backend pointer
std::scoped_lock const lock(mutex_);
@@ -186,6 +201,7 @@ DatabaseRotatingImp::fetchNodeObject(
void
DatabaseRotatingImp::forEach(std::function<void(std::shared_ptr<NodeObject>)> f)
{
TRACE_FUNC();
auto [writable, archive] = [&] {
std::scoped_lock const lock(mutex_);
return std::make_pair(writableBackend_, archiveBackend_);

View File

@@ -5,6 +5,7 @@
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <memory>
@@ -14,6 +15,7 @@ namespace xrpl::NodeStore {
DecodedBlob::DecodedBlob(void const* key, void const* value, int valueBytes)
{
TRACE_FUNC();
/* Data format:
Bytes
@@ -59,6 +61,7 @@ DecodedBlob::DecodedBlob(void const* key, void const* value, int valueBytes)
std::shared_ptr<NodeObject>
DecodedBlob::createObject()
{
TRACE_FUNC();
XRPL_ASSERT(success_, "xrpl::NodeStore::DecodedBlob::createObject : valid object type");
std::shared_ptr<NodeObject> object;

View File

@@ -2,12 +2,14 @@
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Task.h>
#include <xrpl/basics/TraceLog.h>
namespace xrpl::NodeStore {
void
DummyScheduler::scheduleTask(Task& task)
{
TRACE_FUNC();
// Invoke the task synchronously.
task.performScheduledTask();
}

View File

@@ -10,6 +10,7 @@
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/detail/DatabaseNodeImp.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/algorithm/string/predicate.hpp>
@@ -26,6 +27,7 @@ namespace xrpl::NodeStore {
ManagerImp&
ManagerImp::instance()
{
TRACE_FUNC();
static ManagerImp k_;
return k_;
}
@@ -33,6 +35,7 @@ ManagerImp::instance()
void
ManagerImp::missingBackend()
{
TRACE_FUNC();
Throw<std::runtime_error>(
"Your xrpld.cfg is missing a [node_db] entry, "
"please see the xrpld-example.cfg file!");
@@ -53,6 +56,7 @@ registerMemoryFactory(Manager& manager);
ManagerImp::ManagerImp()
{
TRACE_FUNC();
registerNuDBFactory(*this);
registerRocksDBFactory(*this);
registerNullFactory(*this);
@@ -66,6 +70,7 @@ ManagerImp::makeBackend(
Scheduler& scheduler,
beast::Journal journal)
{
TRACE_FUNC();
std::string const type{get(parameters, "type")};
if (type.empty())
missingBackend();
@@ -88,6 +93,7 @@ ManagerImp::makeDatabase(
Section const& config,
beast::Journal journal)
{
TRACE_FUNC();
auto backend{makeBackend(config, burstSize, scheduler, journal)};
backend->open();
return std::make_unique<DatabaseNodeImp>(
@@ -97,6 +103,7 @@ ManagerImp::makeDatabase(
void
ManagerImp::insert(Factory& factory)
{
TRACE_FUNC();
std::scoped_lock const _(mutex_);
list_.push_back(&factory);
}
@@ -104,6 +111,7 @@ ManagerImp::insert(Factory& factory)
void
ManagerImp::erase(Factory& factory)
{
TRACE_FUNC();
std::scoped_lock const _(mutex_);
auto const iter =
std::ranges::find_if(list_, [&factory](Factory* other) { return other == &factory; });
@@ -114,6 +122,7 @@ ManagerImp::erase(Factory& factory)
Factory*
ManagerImp::find(std::string const& name)
{
TRACE_FUNC();
std::scoped_lock const _(mutex_);
auto const iter = std::ranges::find_if(
list_, [&name](Factory* other) { return boost::iequals(name, other->getName()); });
@@ -127,6 +136,7 @@ ManagerImp::find(std::string const& name)
Manager&
Manager::instance()
{
TRACE_FUNC();
return ManagerImp::instance();
}

View File

@@ -2,6 +2,7 @@
#include <xrpl/basics/Blob.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/TraceLog.h>
#include <memory>
#include <utility>
@@ -18,24 +19,28 @@ NodeObject::NodeObject(NodeObjectType type, Blob&& data, uint256 const& hash, Pr
std::shared_ptr<NodeObject>
NodeObject::createObject(NodeObjectType type, Blob&& data, uint256 const& hash)
{
TRACE_FUNC();
return std::make_shared<NodeObject>(type, std::move(data), hash, PrivateAccess());
}
NodeObjectType
NodeObject::getType() const
{
TRACE_FUNC();
return type_;
}
uint256 const&
NodeObject::getHash() const
{
TRACE_FUNC();
return hash_;
}
Blob const&
NodeObject::getData() const
{
TRACE_FUNC();
return data_;
}

View File

@@ -9,6 +9,7 @@
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Types.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/beast/core/string.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -59,6 +60,7 @@ public:
MemoryDB&
open(std::string const& path)
{
TRACE_FUNC();
std::scoped_lock const _(mutex_);
auto const result =
map_.emplace(std::piecewise_construct, std::make_tuple(path), std::make_tuple());
@@ -74,6 +76,7 @@ MemoryFactory* gMemoryFactory = nullptr;
void
registerMemoryFactory(Manager& manager)
{
TRACE_FUNC();
static MemoryFactory kINSTANCE{manager};
gMemoryFactory = &kINSTANCE;
}
@@ -93,6 +96,7 @@ public:
MemoryBackend(size_t keyBytes, Section const& keyValues, beast::Journal journal)
: name_(get(keyValues, "path")), journal_(journal)
{
TRACE_FUNC();
boost::ignore_unused(journal_); // Keep unused journal_ just in case.
if (name_.empty())
Throw<std::runtime_error>("Missing path in Memory backend");
@@ -100,30 +104,35 @@ public:
~MemoryBackend() override
{
TRACE_FUNC();
close();
}
std::string
getName() override
{
TRACE_FUNC();
return name_;
}
void
open(bool) override
{
TRACE_FUNC();
db_ = &gMemoryFactory->open(name_);
}
bool
isOpen() override
{
TRACE_FUNC();
return static_cast<bool>(db_);
}
void
close() override
{
TRACE_FUNC();
db_ = nullptr;
}
@@ -132,6 +141,7 @@ public:
Status
fetch(uint256 const& hash, std::shared_ptr<NodeObject>* pObject) override
{
TRACE_FUNC();
XRPL_ASSERT(db_, "xrpl::NodeStore::MemoryBackend::fetch : non-null database");
std::scoped_lock const _(db_->mutex);
@@ -149,6 +159,7 @@ public:
std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
fetchBatch(std::vector<uint256> const& hashes) override
{
TRACE_FUNC();
std::vector<std::shared_ptr<NodeObject>> results;
results.reserve(hashes.size());
for (auto const& h : hashes)
@@ -171,6 +182,7 @@ public:
void
store(std::shared_ptr<NodeObject> const& object) override
{
TRACE_FUNC();
XRPL_ASSERT(db_, "xrpl::NodeStore::MemoryBackend::store : non-null database");
std::scoped_lock const _(db_->mutex);
db_->table.emplace(object->getHash(), object);
@@ -179,6 +191,7 @@ public:
void
storeBatch(Batch const& batch) override
{
TRACE_FUNC();
for (auto const& e : batch)
store(e);
}
@@ -191,6 +204,7 @@ public:
void
forEach(std::function<void(std::shared_ptr<NodeObject>)> f) override
{
TRACE_FUNC();
XRPL_ASSERT(db_, "xrpl::NodeStore::MemoryBackend::forEach : non-null database");
for (auto const& e : db_->table)
f(e.second);
@@ -199,6 +213,7 @@ public:
int
getWriteLoad() override
{
TRACE_FUNC();
return 0;
}
@@ -210,6 +225,7 @@ public:
[[nodiscard]] int
fdRequired() const override
{
TRACE_FUNC();
return 0;
}
};
@@ -218,12 +234,14 @@ public:
MemoryFactory::MemoryFactory(Manager& manager) : manager_(manager)
{
TRACE_FUNC();
manager_.insert(*this);
}
std::string
MemoryFactory::getName() const
{
TRACE_FUNC();
return "Memory";
}
@@ -235,6 +253,7 @@ MemoryFactory::createInstance(
Scheduler& scheduler,
beast::Journal journal)
{
TRACE_FUNC();
return std::make_unique<MemoryBackend>(keyBytes, keyValues, journal);
}

View File

@@ -14,6 +14,7 @@
#include <xrpl/nodestore/detail/DecodedBlob.h>
#include <xrpl/nodestore/detail/EncodedBlob.h>
#include <xrpl/nodestore/detail/codec.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
@@ -78,6 +79,7 @@ public:
, deletePath(false)
, scheduler(scheduler)
{
TRACE_FUNC();
if (name.empty())
Throw<std::runtime_error>("nodestore: Missing path in NuDB backend");
}
@@ -98,12 +100,14 @@ public:
, deletePath(false)
, scheduler(scheduler)
{
TRACE_FUNC();
if (name.empty())
Throw<std::runtime_error>("nodestore: Missing path in NuDB backend");
}
~NuDBBackend() override
{
TRACE_FUNC();
try
{
// close can throw and we don't want the destructor to throw.
@@ -119,18 +123,21 @@ public:
std::string
getName() override
{
TRACE_FUNC();
return name;
}
[[nodiscard]] std::optional<std::size_t>
getBlockSize() const override
{
TRACE_FUNC();
return blockSize;
}
void
open(bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt) override
{
TRACE_FUNC();
using namespace boost::filesystem;
if (db.is_open())
{
@@ -169,18 +176,21 @@ public:
bool
isOpen() override
{
TRACE_FUNC();
return db.is_open();
}
void
open(bool createIfMissing) override
{
TRACE_FUNC();
open(createIfMissing, kAPPNUM, nudb::make_uid(), nudb::make_salt());
}
void
close() override
{
TRACE_FUNC();
if (db.is_open())
{
nudb::error_code ec;
@@ -207,6 +217,7 @@ public:
Status
fetch(uint256 const& hash, std::shared_ptr<NodeObject>* pno) override
{
TRACE_FUNC();
Status status = Status::Ok;
pno->reset();
nudb::error_code ec;
@@ -235,6 +246,7 @@ public:
std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
fetchBatch(std::vector<uint256> const& hashes) override
{
TRACE_FUNC();
std::vector<std::shared_ptr<NodeObject>> results;
results.reserve(hashes.size());
for (auto const& h : hashes)
@@ -257,6 +269,7 @@ public:
void
doInsert(std::shared_ptr<NodeObject> const& no)
{
TRACE_FUNC();
EncodedBlob const e(no);
nudb::error_code ec;
nudb::detail::buffer bf;
@@ -269,6 +282,7 @@ public:
void
store(std::shared_ptr<NodeObject> const& no) override
{
TRACE_FUNC();
BatchWriteReport report{};
report.writeCount = 1;
auto const start = std::chrono::steady_clock::now();
@@ -281,6 +295,7 @@ public:
void
storeBatch(Batch const& batch) override
{
TRACE_FUNC();
BatchWriteReport report{};
report.writeCount = batch.size();
auto const start = std::chrono::steady_clock::now();
@@ -299,6 +314,7 @@ public:
void
forEach(std::function<void(std::shared_ptr<NodeObject>)> f) override
{
TRACE_FUNC();
auto const dp = db.dat_path();
auto const kp = db.key_path();
auto const lp = db.log_path();
@@ -336,18 +352,21 @@ public:
int
getWriteLoad() override
{
TRACE_FUNC();
return 0;
}
void
setDeletePath() override
{
TRACE_FUNC();
deletePath = true;
}
void
verify() override
{
TRACE_FUNC();
auto const dp = db.dat_path();
auto const kp = db.key_path();
auto const lp = db.log_path();
@@ -367,6 +386,7 @@ public:
[[nodiscard]] int
fdRequired() const override
{
TRACE_FUNC();
return 3;
}
@@ -374,6 +394,7 @@ private:
static std::size_t
parseBlockSize(std::string const& name, Section const& keyValues, beast::Journal journal)
{
TRACE_FUNC();
using namespace boost::filesystem;
auto const folder = path(name);
auto const kp = (folder / "nudb.key").string();
@@ -423,12 +444,14 @@ private:
public:
explicit NuDBFactory(Manager& manager) : manager_(manager)
{
TRACE_FUNC();
manager_.insert(*this);
}
[[nodiscard]] std::string
getName() const override
{
TRACE_FUNC();
return "NuDB";
}
@@ -440,6 +463,7 @@ public:
Scheduler& scheduler,
beast::Journal journal) override
{
TRACE_FUNC();
return std::make_unique<NuDBBackend>(keyBytes, keyValues, burstSize, scheduler, journal);
}
@@ -452,6 +476,7 @@ public:
nudb::context& context,
beast::Journal journal) override
{
TRACE_FUNC();
return std::make_unique<NuDBBackend>(
keyBytes, keyValues, burstSize, scheduler, context, journal);
}
@@ -460,6 +485,7 @@ public:
void
registerNuDBFactory(Manager& manager)
{
TRACE_FUNC();
static NuDBFactory const kINSTANCE{manager};
}

View File

@@ -7,6 +7,7 @@
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Types.h>
#include <xrpl/basics/TraceLog.h>
#include <cstddef>
#include <functional>
@@ -27,6 +28,7 @@ public:
std::string
getName() override
{
TRACE_FUNC();
return std::string();
}
@@ -38,6 +40,7 @@ public:
bool
isOpen() override
{
TRACE_FUNC();
return false;
}
@@ -49,12 +52,14 @@ public:
Status
fetch(uint256 const&, std::shared_ptr<NodeObject>*) override
{
TRACE_FUNC();
return Status::NotFound;
}
std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
fetchBatch(std::vector<uint256> const& hashes) override
{
TRACE_FUNC();
return {};
}
@@ -81,6 +86,7 @@ public:
int
getWriteLoad() override
{
TRACE_FUNC();
return 0;
}
@@ -93,6 +99,7 @@ public:
[[nodiscard]] int
fdRequired() const override
{
TRACE_FUNC();
return 0;
}
@@ -109,18 +116,21 @@ private:
public:
explicit NullFactory(Manager& manager) : manager_(manager)
{
TRACE_FUNC();
manager_.insert(*this);
}
[[nodiscard]] std::string
getName() const override
{
TRACE_FUNC();
return "none";
}
std::unique_ptr<Backend>
createInstance(size_t, Section const&, std::size_t, Scheduler&, beast::Journal) override
{
TRACE_FUNC();
return std::make_unique<NullBackend>();
}
};
@@ -128,6 +138,7 @@ public:
void
registerNullFactory(Manager& manager)
{
TRACE_FUNC();
static NullFactory const kINSTANCE{manager};
}

View File

@@ -42,6 +42,7 @@
#include <xrpl/nodestore/detail/BatchWriter.h>
#include <xrpl/nodestore/detail/DecodedBlob.h>
#include <xrpl/nodestore/detail/EncodedBlob.h>
#include <xrpl/basics/TraceLog.h>
#include <atomic>
#include <memory>
@@ -68,6 +69,7 @@ public:
static void
threadEntry(void* ptr)
{
TRACE_FUNC();
ThreadParams const* const p(reinterpret_cast<ThreadParams*>(ptr));
auto const f = p->f;
@@ -84,6 +86,7 @@ public:
void
StartThread(void (*f)(void*), void* a) override
{
TRACE_FUNC();
ThreadParams* const p(new ThreadParams(f, a));
EnvWrapper::StartThread(&RocksDBEnv::threadEntry, p);
}
@@ -113,6 +116,7 @@ public:
RocksDBEnv* env)
: deletePath_(false), journal(journal), keyBytes(keyBytes), batch(*this, scheduler)
{
TRACE_FUNC();
if (!getIfExists(keyValues, "path", name))
Throw<std::runtime_error>("Missing path in RocksDBFactory backend");
@@ -223,12 +227,14 @@ public:
~RocksDBBackend() override
{
TRACE_FUNC();
close();
}
void
open(bool createIfMissing) override
{
TRACE_FUNC();
if (db)
{
// LCOV_EXCL_START
@@ -253,12 +259,14 @@ public:
bool
isOpen() override
{
TRACE_FUNC();
return static_cast<bool>(db);
}
void
close() override
{
TRACE_FUNC();
if (db)
{
db.reset();
@@ -273,6 +281,7 @@ public:
std::string
getName() override
{
TRACE_FUNC();
return name;
}
@@ -281,6 +290,7 @@ public:
Status
fetch(uint256 const& hash, std::shared_ptr<NodeObject>* pObject) override
{
TRACE_FUNC();
XRPL_ASSERT(db, "xrpl::NodeStore::RocksDBBackend::fetch : non-null database");
pObject->reset();
@@ -333,6 +343,7 @@ public:
std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
fetchBatch(std::vector<uint256> const& hashes) override
{
TRACE_FUNC();
std::vector<std::shared_ptr<NodeObject>> results;
results.reserve(hashes.size());
for (auto const& h : hashes)
@@ -355,12 +366,14 @@ public:
void
store(std::shared_ptr<NodeObject> const& object) override
{
TRACE_FUNC();
batch.store(object);
}
void
storeBatch(Batch const& batch) override
{
TRACE_FUNC();
XRPL_ASSERT(
db,
"xrpl::NodeStore::RocksDBBackend::storeBatch : non-null "
@@ -392,6 +405,7 @@ public:
void
forEach(std::function<void(std::shared_ptr<NodeObject>)> f) override
{
TRACE_FUNC();
XRPL_ASSERT(db, "xrpl::NodeStore::RocksDBBackend::forEach : non-null database");
rocksdb::ReadOptions const options;
@@ -425,12 +439,14 @@ public:
int
getWriteLoad() override
{
TRACE_FUNC();
return batch.getWriteLoad();
}
void
setDeletePath() override
{
TRACE_FUNC();
deletePath_ = true;
}
@@ -439,6 +455,7 @@ public:
void
writeBatch(Batch const& batch) override
{
TRACE_FUNC();
storeBatch(batch);
}
@@ -446,6 +463,7 @@ public:
[[nodiscard]] int
fdRequired() const override
{
TRACE_FUNC();
return fdMinRequired;
}
};
@@ -462,12 +480,14 @@ public:
RocksDBFactory(Manager& manager) : manager_(manager)
{
TRACE_FUNC();
manager_.insert(*this);
}
[[nodiscard]] std::string
getName() const override
{
TRACE_FUNC();
return "RocksDB";
}
@@ -479,6 +499,7 @@ public:
Scheduler& scheduler,
beast::Journal journal) override
{
TRACE_FUNC();
return std::make_unique<RocksDBBackend>(keyBytes, keyValues, scheduler, journal, &env);
}
};
@@ -486,6 +507,7 @@ public:
void
registerRocksDBFactory(Manager& manager)
{
TRACE_FUNC();
static RocksDBFactory const kINSTANCE{manager};
}

View File

@@ -16,6 +16,7 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cstdint>
@@ -28,6 +29,7 @@ namespace xrpl {
Currency
ammLPTCurrency(Asset const& asset1, Asset const& asset2)
{
TRACE_FUNC();
// AMM LPToken is 0x03 plus 19 bytes of the hash
std::int32_t constexpr kAMM_CURRENCY_CODE = 0x03;
auto const& [minA, maxA] = std::minmax(asset1, asset2);
@@ -52,12 +54,14 @@ ammLPTCurrency(Asset const& asset1, Asset const& asset2)
Issue
ammLPTIssue(Asset const& asset1, Asset const& asset2, AccountID const& ammAccountID)
{
TRACE_FUNC();
return Issue(ammLPTCurrency(asset1, asset2), ammAccountID);
}
NotTEC
invalidAMMAsset(Asset const& asset, std::optional<std::pair<Asset, Asset>> const& pair)
{
TRACE_FUNC();
auto const err = asset.visit(
[](MPTIssue const& issue) -> std::optional<NotTEC> {
if (issue.getIssuer() == beast::kZERO)
@@ -84,6 +88,7 @@ invalidAMMAssetPair(
Asset const& asset2,
std::optional<std::pair<Asset, Asset>> const& pair)
{
TRACE_FUNC();
if (asset1 == asset2)
return temBAD_AMM_TOKENS;
if (auto const res = invalidAMMAsset(asset1, pair))
@@ -99,6 +104,7 @@ invalidAMMAmount(
std::optional<std::pair<Asset, Asset>> const& pair,
bool validZero)
{
TRACE_FUNC();
if (auto const res = invalidAMMAsset(amount.asset(), pair))
return res;
if (amount < beast::kZERO || (!validZero && amount == beast::kZERO))
@@ -109,6 +115,7 @@ invalidAMMAmount(
std::optional<std::uint8_t>
ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot)
{
TRACE_FUNC();
// It should be impossible for expiration to be < TOTAL_TIME_SLOT_SECS,
// but check just to be safe
auto const expiration = auctionSlot[sfExpiration];
@@ -128,6 +135,7 @@ ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot)
bool
ammEnabled(Rules const& rules)
{
TRACE_FUNC();
return rules.enabled(featureAMM) && rules.enabled(fixUniversalNumber);
}

View File

@@ -7,6 +7,7 @@
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/protocol/tokens.h>
#include <xrpl/basics/TraceLog.h>
#include <atomic>
#include <cstdint>
@@ -43,6 +44,7 @@ private:
public:
AccountIdCache(std::size_t count) : cache_(count)
{
TRACE_FUNC();
// This is non-binding, but we try to avoid wasting memory that
// is caused by overallocation.
cache_.shrink_to_fit();
@@ -51,6 +53,7 @@ public:
std::string
toBase58(AccountID const& id)
{
TRACE_FUNC();
auto const index = hasher_(id) % cache_.size();
PackedSpinlock sl(locks_, index % 64);
@@ -85,6 +88,7 @@ static std::unique_ptr<detail::AccountIdCache> gAccountIdCache;
void
initAccountIdCache(std::size_t count)
{
TRACE_FUNC();
if (!gAccountIdCache && count != 0)
gAccountIdCache = std::make_unique<detail::AccountIdCache>(count);
}
@@ -92,6 +96,7 @@ initAccountIdCache(std::size_t count)
std::string
toBase58(AccountID const& v)
{
TRACE_FUNC();
if (gAccountIdCache)
return gAccountIdCache->toBase58(v);
@@ -102,6 +107,7 @@ template <>
std::optional<AccountID>
parseBase58(std::string const& s)
{
TRACE_FUNC();
auto const result = decodeBase58Token(s, TokenType::AccountID);
if (result.size() != AccountID::kBYTES)
return std::nullopt;
@@ -146,6 +152,7 @@ parseBase58(std::string const& s)
AccountID
calcAccountID(PublicKey const& pk)
{
TRACE_FUNC();
static_assert(AccountID::kBYTES == sizeof(RipeshaHasher::result_type));
RipeshaHasher rsh;
@@ -156,6 +163,7 @@ calcAccountID(PublicKey const& pk)
AccountID const&
xrpAccount()
{
TRACE_FUNC();
static AccountID const kACCOUNT(beast::kZERO);
return kACCOUNT;
}
@@ -163,6 +171,7 @@ xrpAccount()
AccountID const&
noAccount()
{
TRACE_FUNC();
static AccountID const kACCOUNT(1);
return kACCOUNT;
}
@@ -170,6 +179,7 @@ noAccount()
bool
toIssuer(AccountID& issuer, std::string const& s)
{
TRACE_FUNC();
if (issuer.parseHex(s))
return true;
auto const account = parseBase58<AccountID>(s);

View File

@@ -9,6 +9,7 @@
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/basics/TraceLog.h>
#include <ostream>
#include <stdexcept>
@@ -20,36 +21,42 @@ namespace xrpl {
AccountID const&
Asset::getIssuer() const
{
TRACE_FUNC();
return std::visit([&](auto&& issue) -> AccountID const& { return issue.getIssuer(); }, issue_);
}
std::string
Asset::getText() const
{
TRACE_FUNC();
return std::visit([&](auto&& issue) { return issue.getText(); }, issue_);
}
void
Asset::setJson(json::Value& jv) const
{
TRACE_FUNC();
std::visit([&](auto&& issue) { issue.setJson(jv); }, issue_);
}
STAmount
Asset::operator()(Number const& number) const
{
TRACE_FUNC();
return STAmount{*this, number};
}
std::string
to_string(Asset const& asset)
{
TRACE_FUNC();
return std::visit([&](auto const& issue) { return to_string(issue); }, asset.value());
}
bool
validJSONAsset(json::Value const& jv)
{
TRACE_FUNC();
if (jv.isMember(jss::mpt_issuance_id))
return !(jv.isMember(jss::currency) || jv.isMember(jss::issuer));
return jv.isMember(jss::currency);
@@ -58,6 +65,7 @@ validJSONAsset(json::Value const& jv)
Asset
assetFromJson(json::Value const& v)
{
TRACE_FUNC();
if (!v.isMember(jss::currency) && !v.isMember(jss::mpt_issuance_id))
Throw<std::runtime_error>("assetFromJson must contain currency or mpt_issuance_id");
@@ -69,6 +77,7 @@ assetFromJson(json::Value const& v)
std::ostream&
operator<<(std::ostream& os, Asset const& x)
{
TRACE_FUNC();
std::visit([&]<ValidIssueType TIss>(TIss const& issue) { os << issue; }, x.value());
return os;
}

View File

@@ -1,6 +1,7 @@
#include <xrpl/protocol/Book.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/basics/TraceLog.h>
#include <ostream>
#include <string>
@@ -10,18 +11,21 @@ namespace xrpl {
bool
isConsistent(Book const& book)
{
TRACE_FUNC();
return isConsistent(book.in) && isConsistent(book.out) && book.in != book.out;
}
std::string
to_string(Book const& book)
{
TRACE_FUNC();
return to_string(book.in) + "->" + to_string(book.out);
}
std::ostream&
operator<<(std::ostream& os, Book const& x)
{
TRACE_FUNC();
os << to_string(x);
return os;
}
@@ -29,6 +33,7 @@ operator<<(std::ostream& os, Book const& x)
Book
reversed(Book const& book)
{
TRACE_FUNC();
return Book(book.out, book.in, book.domain);
}

View File

@@ -5,6 +5,7 @@
#include <xrpl/beast/core/SemanticVersion.h>
#include <xrpl/git/Git.h> // IWYU pragma: keep
#include <xrpl/protocol/SystemParameters.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/preprocessor/stringize.hpp> // IWYU pragma: keep
@@ -34,6 +35,7 @@ char const* const versionString = "3.2.0-b0"
std::string
buildVersionString()
{
TRACE_FUNC();
std::string version = versionString;
#if defined(DEBUG) || defined(SANITIZERS)
@@ -67,6 +69,7 @@ buildVersionString()
std::string const&
getVersionString()
{
TRACE_FUNC();
static std::string const kVALUE = [] {
std::string const s = buildVersionString();
@@ -81,6 +84,7 @@ getVersionString()
std::string const&
getFullVersionString()
{
TRACE_FUNC();
static std::string const kVALUE = systemName() + "-" + getVersionString();
return kVALUE;
}
@@ -91,6 +95,7 @@ static constexpr std::uint64_t kIMPLEMENTATION_VERSION_IDENTIFIER_MASK = 0xFFFF'
std::uint64_t
encodeSoftwareVersion(std::string_view versionStr)
{
TRACE_FUNC();
std::uint64_t c = kIMPLEMENTATION_VERSION_IDENTIFIER;
beast::SemanticVersion v;
@@ -155,6 +160,7 @@ encodeSoftwareVersion(std::string_view versionStr)
std::uint64_t
getEncodedVersion()
{
TRACE_FUNC();
static std::uint64_t const kCOOKIE = {encodeSoftwareVersion(getVersionString())};
return kCOOKIE;
}
@@ -162,6 +168,7 @@ getEncodedVersion()
bool
isXrpldVersion(std::uint64_t version)
{
TRACE_FUNC();
return (version & kIMPLEMENTATION_VERSION_IDENTIFIER_MASK) ==
kIMPLEMENTATION_VERSION_IDENTIFIER;
}
@@ -169,6 +176,7 @@ isXrpldVersion(std::uint64_t version)
bool
isNewerVersion(std::uint64_t version)
{
TRACE_FUNC();
if (isXrpldVersion(version))
return version > getEncodedVersion();
return false;

View File

@@ -3,6 +3,7 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/basics/TraceLog.h>
#include <array>
#include <stdexcept>
@@ -164,6 +165,7 @@ constexpr ErrorInfo kUNKNOWN_ERROR;
void
injectError(ErrorCodeI code, json::Value& json)
{
TRACE_FUNC();
ErrorInfo const& info(getErrorInfo(code));
json[jss::error] = info.token;
json[jss::error_code] = info.code;
@@ -173,6 +175,7 @@ injectError(ErrorCodeI code, json::Value& json)
void
injectError(ErrorCodeI code, std::string const& message, json::Value& json)
{
TRACE_FUNC();
ErrorInfo const& info(getErrorInfo(code));
json[jss::error] = info.token;
json[jss::error_code] = info.code;
@@ -182,6 +185,7 @@ injectError(ErrorCodeI code, std::string const& message, json::Value& json)
ErrorInfo const&
getErrorInfo(ErrorCodeI code)
{
TRACE_FUNC();
if (code <= RpcSuccess || code > RpcLast)
return detail::kUNKNOWN_ERROR;
return detail::kSORTED_ERROR_INFOS[code - 1];
@@ -190,6 +194,7 @@ getErrorInfo(ErrorCodeI code)
json::Value
makeError(ErrorCodeI code)
{
TRACE_FUNC();
json::Value json;
injectError(code, json);
return json;
@@ -198,6 +203,7 @@ makeError(ErrorCodeI code)
json::Value
makeError(ErrorCodeI code, std::string const& message)
{
TRACE_FUNC();
json::Value json;
injectError(code, message, json);
return json;
@@ -206,12 +212,14 @@ makeError(ErrorCodeI code, std::string const& message)
bool
containsError(json::Value const& json)
{
TRACE_FUNC();
return json.isObject() && json.isMember(jss::error);
}
int
errorCodeHttpStatus(ErrorCodeI code)
{
TRACE_FUNC();
return getErrorInfo(code).http_status;
}
@@ -220,6 +228,7 @@ errorCodeHttpStatus(ErrorCodeI code)
std::string
rpcErrorString(json::Value const& jv)
{
TRACE_FUNC();
XRPL_ASSERT(RPC::containsError(jv), "xrpl::RPC::rpcErrorString : input contains an error");
return jv[jss::error].asString() + jv[jss::error_message].asString();
}

View File

@@ -5,6 +5,7 @@
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/container_hash/hash.hpp>
#include <boost/multi_index/hashed_index.hpp>
@@ -26,6 +27,7 @@ inline std::size_t
// NOLINTNEXTLINE(readability-identifier-naming)
hash_value(xrpl::uint256 const& feature)
{
TRACE_FUNC();
std::size_t seed = 0;
using namespace boost;
for (auto const& n : feature)
@@ -118,6 +120,7 @@ class FeatureCollections
Feature const&
getByIndex(size_t i) const
{
TRACE_FUNC();
if (i >= features_.size())
logicError("Invalid FeatureBitset index");
auto const& sequence = features_.get<Feature::ByIndex>();
@@ -126,6 +129,7 @@ class FeatureCollections
size_t
getIndex(Feature const& feature) const
{
TRACE_FUNC();
auto const& sequence = features_.get<Feature::ByIndex>();
auto const itTo = sequence.iterator_to(feature);
return itTo - sequence.begin();
@@ -133,6 +137,7 @@ class FeatureCollections
Feature const*
getByFeature(uint256 const& feature) const
{
TRACE_FUNC();
auto const& featureIndex = features_.get<Feature::ByFeature>();
auto const featureIt = featureIndex.find(feature);
return featureIt == featureIndex.end() ? nullptr : &*featureIt;
@@ -140,6 +145,7 @@ class FeatureCollections
Feature const*
getByName(std::string const& name) const
{
TRACE_FUNC();
auto const& nameIndex = features_.get<Feature::ByName>();
auto const nameIt = nameIndex.find(name);
return nameIt == nameIndex.end() ? nullptr : &*nameIt;
@@ -171,6 +177,7 @@ public:
std::map<std::string, AmendmentSupport> const&
allAmendments() const
{
TRACE_FUNC();
return all_;
}
@@ -180,6 +187,7 @@ public:
std::map<std::string, VoteBehavior> const&
supportedAmendments() const
{
TRACE_FUNC();
return supported_;
}
@@ -187,6 +195,7 @@ public:
std::size_t
numDownVotedAmendments() const
{
TRACE_FUNC();
return downVotes_;
}
@@ -194,6 +203,7 @@ public:
std::size_t
numUpVotedAmendments() const
{
TRACE_FUNC();
return upVotes_;
}
};
@@ -202,12 +212,14 @@ public:
FeatureCollections::FeatureCollections()
{
TRACE_FUNC();
features_.reserve(xrpl::detail::kNUM_FEATURES);
}
std::optional<uint256>
FeatureCollections::getRegisteredFeature(std::string const& name) const
{
TRACE_FUNC();
XRPL_ASSERT(
readOnly_.load(), "xrpl::FeatureCollections::getRegisteredFeature : startup completed");
Feature const* feature = getByName(name);
@@ -219,6 +231,7 @@ FeatureCollections::getRegisteredFeature(std::string const& name) const
void
check(bool condition, char const* logicErrorMessage)
{
TRACE_FUNC();
if (!condition)
logicError(logicErrorMessage);
}
@@ -226,6 +239,7 @@ check(bool condition, char const* logicErrorMessage)
uint256
FeatureCollections::registerFeature(std::string const& name, Supported support, VoteBehavior vote)
{
TRACE_FUNC();
check(!readOnly_, "Attempting to register a feature after startup.");
check(
support == Supported::Yes || vote == VoteBehavior::DefaultNo,
@@ -275,6 +289,7 @@ FeatureCollections::registerFeature(std::string const& name, Supported support,
bool
FeatureCollections::registrationIsDone()
{
TRACE_FUNC();
readOnly_ = true;
return true;
}
@@ -282,6 +297,7 @@ FeatureCollections::registrationIsDone()
size_t
FeatureCollections::featureToBitsetIndex(uint256 const& f) const
{
TRACE_FUNC();
XRPL_ASSERT(
readOnly_.load(), "xrpl::FeatureCollections::featureToBitsetIndex : startup completed");
@@ -295,6 +311,7 @@ FeatureCollections::featureToBitsetIndex(uint256 const& f) const
uint256 const&
FeatureCollections::bitsetIndexToFeature(size_t i) const
{
TRACE_FUNC();
XRPL_ASSERT(
readOnly_.load(), "xrpl::FeatureCollections::bitsetIndexToFeature : startup completed");
Feature const& feature = getByIndex(i);
@@ -304,6 +321,7 @@ FeatureCollections::bitsetIndexToFeature(size_t i) const
std::string
FeatureCollections::featureToName(uint256 const& f) const
{
TRACE_FUNC();
XRPL_ASSERT(readOnly_.load(), "xrpl::FeatureCollections::featureToName : startup completed");
Feature const* feature = getByFeature(f);
return (feature != nullptr) ? feature->name : to_string(f);
@@ -317,6 +335,7 @@ FeatureCollections gFeatureCollections;
std::map<std::string, AmendmentSupport> const&
allAmendments()
{
TRACE_FUNC();
return gFeatureCollections.allAmendments();
}
@@ -326,6 +345,7 @@ allAmendments()
std::map<std::string, VoteBehavior> const&
detail::supportedAmendments()
{
TRACE_FUNC();
return gFeatureCollections.supportedAmendments();
}
@@ -333,6 +353,7 @@ detail::supportedAmendments()
std::size_t
detail::numDownVotedAmendments()
{
TRACE_FUNC();
return gFeatureCollections.numDownVotedAmendments();
}
@@ -340,6 +361,7 @@ detail::numDownVotedAmendments()
std::size_t
detail::numUpVotedAmendments()
{
TRACE_FUNC();
return gFeatureCollections.numUpVotedAmendments();
}
@@ -348,12 +370,14 @@ detail::numUpVotedAmendments()
std::optional<uint256>
getRegisteredFeature(std::string const& name)
{
TRACE_FUNC();
return gFeatureCollections.getRegisteredFeature(name);
}
uint256
registerFeature(std::string const& name, Supported support, VoteBehavior vote)
{
TRACE_FUNC();
return gFeatureCollections.registerFeature(name, support, vote);
}
@@ -362,6 +386,7 @@ registerFeature(std::string const& name, Supported support, VoteBehavior vote)
uint256
retireFeature(std::string const& name)
{
TRACE_FUNC();
return registerFeature(name, Supported::Yes, VoteBehavior::Obsolete);
}
@@ -369,24 +394,28 @@ retireFeature(std::string const& name)
bool
registrationIsDone()
{
TRACE_FUNC();
return gFeatureCollections.registrationIsDone();
}
size_t
featureToBitsetIndex(uint256 const& f)
{
TRACE_FUNC();
return gFeatureCollections.featureToBitsetIndex(f);
}
uint256
bitsetIndexToFeature(size_t i)
{
TRACE_FUNC();
return gFeatureCollections.bitsetIndexToFeature(i);
}
std::string
featureToName(uint256 const& f)
{
TRACE_FUNC();
return gFeatureCollections.featureToName(f);
}

View File

@@ -5,6 +5,7 @@
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <cstdint>
@@ -23,6 +24,7 @@ namespace {
LocalValue<bool>&
getStaticSTNumberSwitchover()
{
TRACE_FUNC();
static LocalValue<bool> kR{true};
return kR;
}
@@ -31,12 +33,14 @@ getStaticSTNumberSwitchover()
bool
getSTNumberSwitchover()
{
TRACE_FUNC();
return *getStaticSTNumberSwitchover();
}
void
setSTNumberSwitchover(bool v)
{
TRACE_FUNC();
*getStaticSTNumberSwitchover() = v;
}
@@ -52,6 +56,7 @@ static int constexpr kMAX_EXPONENT = STAmount::kMAX_OFFSET;
IOUAmount
IOUAmount::fromNumber(Number const& number)
{
TRACE_FUNC();
// Need to create a default IOUAmount and assign directly so it doesn't try
// to normalize, which calls fromNumber
IOUAmount result{};
@@ -63,12 +68,14 @@ IOUAmount::fromNumber(Number const& number)
IOUAmount
IOUAmount::minPositiveAmount()
{
TRACE_FUNC();
return IOUAmount(kMIN_MANTISSA, kMIN_EXPONENT);
}
void
IOUAmount::normalize()
{
TRACE_FUNC();
if (mantissa_ == 0)
{
*this = beast::kZERO;
@@ -121,6 +128,7 @@ IOUAmount::normalize()
IOUAmount::IOUAmount(Number const& other) : IOUAmount(fromNumber(other))
{
TRACE_FUNC();
if (exponent_ > kMAX_EXPONENT)
Throw<std::overflow_error>("value overflow");
if (exponent_ < kMIN_EXPONENT)
@@ -130,6 +138,7 @@ IOUAmount::IOUAmount(Number const& other) : IOUAmount(fromNumber(other))
IOUAmount&
IOUAmount::operator+=(IOUAmount const& other)
{
TRACE_FUNC();
if (other == beast::kZERO)
return *this;
@@ -176,12 +185,14 @@ IOUAmount::operator+=(IOUAmount const& other)
std::string
to_string(IOUAmount const& amount)
{
TRACE_FUNC();
return to_string(Number{amount});
}
IOUAmount
mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundUp)
{
TRACE_FUNC();
using namespace boost::multiprecision;
if (den == 0u)

View File

@@ -18,6 +18,7 @@
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/protocol/nftPageMask.h>
#include <xrpl/basics/TraceLog.h>
#include <boost/endian/conversion.hpp>
@@ -95,12 +96,14 @@ template <class... Args>
static uint256
indexHash(LedgerNameSpace space, Args const&... args)
{
TRACE_FUNC();
return sha512Half(safeCast<std::uint16_t>(space), args...);
}
uint256
getBookBase(Book const& book)
{
TRACE_FUNC();
XRPL_ASSERT(isConsistent(book), "xrpl::getBookBase : input is consistent");
auto getIndexHash = [&book]<typename... Args>(Args... args) {
@@ -143,6 +146,7 @@ getBookBase(Book const& book)
uint256
getQualityNext(uint256 const& uBase)
{
TRACE_FUNC();
static constexpr uint256 kNEXT_QUALITY(
"0000000000000000000000000000000000000000000000010000000000000000");
return uBase + kNEXT_QUALITY;
@@ -151,6 +155,7 @@ getQualityNext(uint256 const& uBase)
std::uint64_t
getQuality(uint256 const& uBase)
{
TRACE_FUNC();
// VFALCO [base_uint] This assumes a certain storage format
return boost::endian::big_to_native(((std::uint64_t*)uBase.end())[-1]);
}
@@ -158,12 +163,14 @@ getQuality(uint256 const& uBase)
uint256
getTicketIndex(AccountID const& account, std::uint32_t ticketSeq)
{
TRACE_FUNC();
return indexHash(LedgerNameSpace::Ticket, account, ticketSeq);
}
uint256
getTicketIndex(AccountID const& account, SeqProxy ticketSeq)
{
TRACE_FUNC();
XRPL_ASSERT(ticketSeq.isTicket(), "xrpl::getTicketIndex : valid input");
return getTicketIndex(account, ticketSeq.value());
}
@@ -171,6 +178,7 @@ getTicketIndex(AccountID const& account, SeqProxy ticketSeq)
MPTID
makeMptID(std::uint32_t sequence, AccountID const& account)
{
TRACE_FUNC();
MPTID u;
sequence = boost::endian::native_to_big(sequence);
memcpy(u.data(), &sequence, sizeof(sequence));
@@ -185,18 +193,21 @@ namespace keylet {
Keylet
account(AccountID const& id) noexcept
{
TRACE_FUNC();
return Keylet{ltACCOUNT_ROOT, indexHash(LedgerNameSpace::Account, id)};
}
Keylet
child(uint256 const& key) noexcept
{
TRACE_FUNC();
return {ltCHILD, key};
}
Keylet const&
skip() noexcept
{
TRACE_FUNC();
static Keylet const kRET{ltLEDGER_HASHES, indexHash(LedgerNameSpace::SkipList)};
return kRET;
}
@@ -204,6 +215,7 @@ skip() noexcept
Keylet
skip(LedgerIndex ledger) noexcept
{
TRACE_FUNC();
return {
ltLEDGER_HASHES,
indexHash(
@@ -213,6 +225,7 @@ skip(LedgerIndex ledger) noexcept
Keylet const&
amendments() noexcept
{
TRACE_FUNC();
static Keylet const kRET{ltAMENDMENTS, indexHash(LedgerNameSpace::Amendments)};
return kRET;
}
@@ -220,6 +233,7 @@ amendments() noexcept
Keylet const&
fees() noexcept
{
TRACE_FUNC();
static Keylet const kRET{ltFEE_SETTINGS, indexHash(LedgerNameSpace::FeeSettings)};
return kRET;
}
@@ -227,6 +241,7 @@ fees() noexcept
Keylet const&
negativeUNL() noexcept
{
TRACE_FUNC();
static Keylet const kRET{ltNEGATIVE_UNL, indexHash(LedgerNameSpace::NegativeUnl)};
return kRET;
}
@@ -234,12 +249,14 @@ negativeUNL() noexcept
Keylet
BookT::operator()(Book const& b) const
{
TRACE_FUNC();
return {ltDIR_NODE, getBookBase(b)};
}
Keylet
line(AccountID const& id0, AccountID const& id1, Currency const& currency) noexcept
{
TRACE_FUNC();
// There is code in TrustSet that calls us with id0 == id1, to allow users
// to locate and delete such "weird" trustlines. If we remove that code, we
// could enable this assert:
@@ -263,12 +280,14 @@ line(AccountID const& id0, AccountID const& id1, Currency const& currency) noexc
Keylet
offer(AccountID const& id, std::uint32_t seq) noexcept
{
TRACE_FUNC();
return {ltOFFER, indexHash(LedgerNameSpace::Offer, id, seq)};
}
Keylet
quality(Keylet const& k, std::uint64_t q) noexcept
{
TRACE_FUNC();
XRPL_ASSERT(k.type == ltDIR_NODE, "xrpl::keylet::quality : valid input type");
// Indexes are stored in big endian format: they print as hex as stored.
@@ -287,6 +306,7 @@ quality(Keylet const& k, std::uint64_t q) noexcept
Keylet
NextT::operator()(Keylet const& k) const
{
TRACE_FUNC();
XRPL_ASSERT(k.type == ltDIR_NODE, "xrpl::keylet::next_t::operator() : valid input type");
return {ltDIR_NODE, getQualityNext(k.key)};
}
@@ -294,12 +314,14 @@ NextT::operator()(Keylet const& k) const
Keylet
TicketT::operator()(AccountID const& id, std::uint32_t ticketSeq) const
{
TRACE_FUNC();
return {ltTICKET, getTicketIndex(id, ticketSeq)};
}
Keylet
TicketT::operator()(AccountID const& id, SeqProxy ticketSeq) const
{
TRACE_FUNC();
return {ltTICKET, getTicketIndex(id, ticketSeq)};
}
@@ -309,24 +331,28 @@ TicketT::operator()(AccountID const& id, SeqProxy ticketSeq) const
static Keylet
signers(AccountID const& account, std::uint32_t page) noexcept
{
TRACE_FUNC();
return {ltSIGNER_LIST, indexHash(LedgerNameSpace::SignerList, account, page)};
}
Keylet
signers(AccountID const& account) noexcept
{
TRACE_FUNC();
return signers(account, 0);
}
Keylet
check(AccountID const& id, std::uint32_t seq) noexcept
{
TRACE_FUNC();
return {ltCHECK, indexHash(LedgerNameSpace::Check, id, seq)};
}
Keylet
depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept
{
TRACE_FUNC();
return {ltDEPOSIT_PREAUTH, indexHash(LedgerNameSpace::DepositPreauth, owner, preauthorized)};
}
@@ -336,6 +362,7 @@ depositPreauth(
AccountID const& owner,
std::set<std::pair<AccountID, Slice>> const& authCreds) noexcept
{
TRACE_FUNC();
std::vector<uint256> hashes;
hashes.reserve(authCreds.size());
for (auto const& o : authCreds)
@@ -350,18 +377,21 @@ depositPreauth(
Keylet
unchecked(uint256 const& key) noexcept
{
TRACE_FUNC();
return {ltANY, key};
}
Keylet
ownerDir(AccountID const& id) noexcept
{
TRACE_FUNC();
return {ltDIR_NODE, indexHash(LedgerNameSpace::OwnerDir, id)};
}
Keylet
page(uint256 const& key, std::uint64_t index) noexcept
{
TRACE_FUNC();
if (index == 0)
return {ltDIR_NODE, key};
@@ -371,18 +401,21 @@ page(uint256 const& key, std::uint64_t index) noexcept
Keylet
escrow(AccountID const& src, std::uint32_t seq) noexcept
{
TRACE_FUNC();
return {ltESCROW, indexHash(LedgerNameSpace::Escrow, src, seq)};
}
Keylet
payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept
{
TRACE_FUNC();
return {ltPAYCHAN, indexHash(LedgerNameSpace::XRPPaymentChannel, src, dst, seq)};
}
Keylet
nftpageMin(AccountID const& owner)
{
TRACE_FUNC();
std::array<std::uint8_t, 32> buf{};
std::memcpy(buf.data(), owner.data(), owner.size());
return {ltNFTOKEN_PAGE, uint256{buf}};
@@ -391,6 +424,7 @@ nftpageMin(AccountID const& owner)
Keylet
nftpageMax(AccountID const& owner)
{
TRACE_FUNC();
uint256 id = nft::kPAGE_MASK;
std::memcpy(id.data(), owner.data(), owner.size());
return {ltNFTOKEN_PAGE, id};
@@ -399,6 +433,7 @@ nftpageMax(AccountID const& owner)
Keylet
nftpage(Keylet const& k, uint256 const& token)
{
TRACE_FUNC();
XRPL_ASSERT(k.type == ltNFTOKEN_PAGE, "xrpl::keylet::nftpage : valid input type");
return {ltNFTOKEN_PAGE, (k.key & ~nft::kPAGE_MASK) + (token & nft::kPAGE_MASK)};
}
@@ -406,24 +441,28 @@ nftpage(Keylet const& k, uint256 const& token)
Keylet
nftoffer(AccountID const& owner, std::uint32_t seq)
{
TRACE_FUNC();
return {ltNFTOKEN_OFFER, indexHash(LedgerNameSpace::NftokenOffer, owner, seq)};
}
Keylet
nftBuys(uint256 const& id) noexcept
{
TRACE_FUNC();
return {ltDIR_NODE, indexHash(LedgerNameSpace::NftokenBuyOffers, id)};
}
Keylet
nftSells(uint256 const& id) noexcept
{
TRACE_FUNC();
return {ltDIR_NODE, indexHash(LedgerNameSpace::NftokenSellOffers, id)};
}
Keylet
amm(Asset const& asset1, Asset const& asset2) noexcept
{
TRACE_FUNC();
auto const& [minA, maxA] = std::minmax(asset1, asset2);
return std::visit(
[]<ValidIssueType TIss1, ValidIssueType TIss2>(TIss1 const& issue1, TIss2 const& issue2) {
@@ -458,18 +497,21 @@ amm(Asset const& asset1, Asset const& asset2) noexcept
Keylet
amm(uint256 const& id) noexcept
{
TRACE_FUNC();
return {ltAMM, id};
}
Keylet
delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept
{
TRACE_FUNC();
return {ltDELEGATE, indexHash(LedgerNameSpace::Delegate, account, authorizedAccount)};
}
Keylet
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType)
{
TRACE_FUNC();
// A door account can support multiple bridges. On the locking chain
// there can only be one bridge per lockingChainCurrency. On the issuing
// chain there can only be one bridge per issuingChainCurrency.
@@ -480,6 +522,7 @@ bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType)
Keylet
xChainClaimID(STXChainBridge const& bridge, std::uint64_t seq)
{
TRACE_FUNC();
return {
ltXCHAIN_OWNED_CLAIM_ID,
indexHash(
@@ -494,6 +537,7 @@ xChainClaimID(STXChainBridge const& bridge, std::uint64_t seq)
Keylet
xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t seq)
{
TRACE_FUNC();
return {
ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID,
indexHash(
@@ -508,72 +552,84 @@ xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t seq)
Keylet
did(AccountID const& account) noexcept
{
TRACE_FUNC();
return {ltDID, indexHash(LedgerNameSpace::Did, account)};
}
Keylet
oracle(AccountID const& account, std::uint32_t const& documentID) noexcept
{
TRACE_FUNC();
return {ltORACLE, indexHash(LedgerNameSpace::Oracle, account, documentID)};
}
Keylet
mptIssuance(std::uint32_t seq, AccountID const& issuer) noexcept
{
TRACE_FUNC();
return mptIssuance(makeMptID(seq, issuer));
}
Keylet
mptIssuance(MPTID const& issuanceID) noexcept
{
TRACE_FUNC();
return {ltMPTOKEN_ISSUANCE, indexHash(LedgerNameSpace::MPTokenIssuance, issuanceID)};
}
Keylet
mptoken(MPTID const& issuanceID, AccountID const& holder) noexcept
{
TRACE_FUNC();
return mptoken(mptIssuance(issuanceID).key, holder);
}
Keylet
mptoken(uint256 const& issuanceKey, AccountID const& holder) noexcept
{
TRACE_FUNC();
return {ltMPTOKEN, indexHash(LedgerNameSpace::MPToken, issuanceKey, holder)};
}
Keylet
credential(AccountID const& subject, AccountID const& issuer, Slice const& credType) noexcept
{
TRACE_FUNC();
return {ltCREDENTIAL, indexHash(LedgerNameSpace::Credential, subject, issuer, credType)};
}
Keylet
vault(AccountID const& owner, std::uint32_t seq) noexcept
{
TRACE_FUNC();
return vault(indexHash(LedgerNameSpace::Vault, owner, seq));
}
Keylet
loanbroker(AccountID const& owner, std::uint32_t seq) noexcept
{
TRACE_FUNC();
return loanbroker(indexHash(LedgerNameSpace::LoanBroker, owner, seq));
}
Keylet
loan(uint256 const& loanBrokerID, std::uint32_t loanSeq) noexcept
{
TRACE_FUNC();
return loan(indexHash(LedgerNameSpace::Loan, loanBrokerID, loanSeq));
}
Keylet
permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept
{
TRACE_FUNC();
return {ltPERMISSIONED_DOMAIN, indexHash(LedgerNameSpace::PermissionedDomain, account, seq)};
}
Keylet
permissionedDomain(uint256 const& domainID) noexcept
{
TRACE_FUNC();
return {ltPERMISSIONED_DOMAIN, domainID};
}

View File

@@ -2,11 +2,13 @@
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/SOTemplate.h>
#include <xrpl/basics/TraceLog.h>
namespace xrpl {
InnerObjectFormats::InnerObjectFormats()
{
TRACE_FUNC();
// inner objects with the default fields have to be
// constructed with STObject::makeInnerObject()
@@ -165,6 +167,7 @@ InnerObjectFormats::InnerObjectFormats()
InnerObjectFormats const&
InnerObjectFormats::getInstance()
{
TRACE_FUNC();
static InnerObjectFormats const kINSTANCE;
return kINSTANCE;
}
@@ -172,6 +175,7 @@ InnerObjectFormats::getInstance()
SOTemplate const*
InnerObjectFormats::findSOTemplateBySField(SField const& sField) const
{
TRACE_FUNC();
auto itemPtr = findByType(sField.getCode());
if (itemPtr != nullptr)
return &(itemPtr->getSOTemplate());

View File

@@ -6,6 +6,7 @@
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/basics/TraceLog.h>
#include <ostream>
#include <stdexcept>
@@ -16,6 +17,7 @@ namespace xrpl {
std::string
Issue::getText() const
{
TRACE_FUNC();
std::string ret;
ret.reserve(64);
@@ -45,6 +47,7 @@ Issue::getText() const
void
Issue::setJson(json::Value& jv) const
{
TRACE_FUNC();
jv[jss::currency] = to_string(currency);
if (!isXRP(currency))
jv[jss::issuer] = toBase58(account);
@@ -53,24 +56,28 @@ Issue::setJson(json::Value& jv) const
bool
Issue::native() const
{
TRACE_FUNC();
return *this == xrpIssue();
}
bool
Issue::integral() const
{
TRACE_FUNC();
return native();
}
bool
isConsistent(Issue const& ac)
{
TRACE_FUNC();
return isXRP(ac.currency) == isXRP(ac.account);
}
std::string
to_string(Issue const& ac)
{
TRACE_FUNC();
if (isXRP(ac.account))
return to_string(ac.currency);
@@ -80,6 +87,7 @@ to_string(Issue const& ac)
json::Value
toJson(Issue const& is)
{
TRACE_FUNC();
json::Value jv;
is.setJson(jv);
return jv;
@@ -88,6 +96,7 @@ toJson(Issue const& is)
Issue
issueFromJson(json::Value const& v)
{
TRACE_FUNC();
if (!v.isObject())
{
Throw<std::runtime_error>(
@@ -139,6 +148,7 @@ issueFromJson(json::Value const& v)
std::ostream&
operator<<(std::ostream& os, Issue const& x)
{
TRACE_FUNC();
os << to_string(x);
return os;
}

View File

@@ -3,12 +3,14 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/basics/TraceLog.h>
namespace xrpl {
bool
Keylet::check(STLedgerEntry const& sle) const
{
TRACE_FUNC();
XRPL_ASSERT(
sle.getType() != ltANY && sle.getType() != ltCHILD,
"xrpl::Keylet::check : valid input type");

View File

@@ -1,5 +1,6 @@
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/basics/TraceLog.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/SOTemplate.h>
#include <xrpl/protocol/jss.h> // IWYU pragma: keep
@@ -11,6 +12,7 @@ namespace xrpl {
std::vector<SOElement> const&
LedgerFormats::getCommonFields()
{
TRACE_FUNC();
static auto const kCOMMON_FIELDS = std::vector<SOElement>{
{sfLedgerIndex, SoeOptional},
{sfLedgerEntryType, SoeRequired},
@@ -21,6 +23,7 @@ LedgerFormats::getCommonFields()
LedgerFormats::LedgerFormats()
{
TRACE_FUNC();
#pragma push_macro("UNWRAP")
#undef UNWRAP
#pragma push_macro("LEDGER_ENTRY")
@@ -41,6 +44,7 @@ LedgerFormats::LedgerFormats()
LedgerFormats const&
LedgerFormats::getInstance()
{
TRACE_FUNC();
static LedgerFormats const kINSTANCE;
return kINSTANCE;
}

View File

@@ -5,6 +5,7 @@
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdint>
@@ -13,6 +14,7 @@ namespace xrpl {
void
addRaw(LedgerHeader const& info, Serializer& s, bool includeHash)
{
TRACE_FUNC();
s.add32(info.seq);
s.add64(info.drops.drops());
s.addBitString(info.parentHash);
@@ -30,6 +32,7 @@ addRaw(LedgerHeader const& info, Serializer& s, bool includeHash)
LedgerHeader
deserializeHeader(Slice data, bool hasHash)
{
TRACE_FUNC();
SerialIter sit(data.data(), data.size());
LedgerHeader header;
@@ -53,12 +56,14 @@ deserializeHeader(Slice data, bool hasHash)
LedgerHeader
deserializePrefixedHeader(Slice data, bool hasHash)
{
TRACE_FUNC();
return deserializeHeader(data + 4, hasHash);
}
uint256
calculateLedgerHash(LedgerHeader const& info)
{
TRACE_FUNC();
// VFALCO This has to match addRaw in View.h.
return sha512Half(
HashPrefix::LedgerMaster,

View File

@@ -1,10 +1,12 @@
#include <xrpl/protocol/MPTAmount.h>
#include <xrpl/basics/TraceLog.h>
namespace xrpl {
MPTAmount&
MPTAmount::operator+=(MPTAmount const& other)
{
TRACE_FUNC();
value_ += other.value();
return *this;
}
@@ -12,6 +14,7 @@ MPTAmount::operator+=(MPTAmount const& other)
MPTAmount&
MPTAmount::operator-=(MPTAmount const& other)
{
TRACE_FUNC();
value_ -= other.value();
return *this;
}
@@ -19,30 +22,35 @@ MPTAmount::operator-=(MPTAmount const& other)
MPTAmount
MPTAmount::operator-() const
{
TRACE_FUNC();
return MPTAmount{-value_};
}
bool
MPTAmount::operator==(MPTAmount const& other) const
{
TRACE_FUNC();
return value_ == other.value_;
}
bool
MPTAmount::operator==(value_type other) const
{
TRACE_FUNC();
return value_ == other;
}
bool
MPTAmount::operator<(MPTAmount const& other) const
{
TRACE_FUNC();
return value_ < other.value_;
}
MPTAmount
MPTAmount::minPositiveAmount()
{
TRACE_FUNC();
return MPTAmount{1};
}

View File

@@ -8,6 +8,7 @@
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/basics/TraceLog.h>
#include <cstdint>
#include <ostream>
@@ -28,6 +29,7 @@ MPTIssue::MPTIssue(std::uint32_t sequence, AccountID const& account)
AccountID const&
MPTIssue::getIssuer() const
{
TRACE_FUNC();
// MPTID is concatenation of sequence + account
static_assert(sizeof(MPTID) == (sizeof(std::uint32_t) + sizeof(AccountID)));
// copy from id skipping the sequence
@@ -40,18 +42,21 @@ MPTIssue::getIssuer() const
std::string
MPTIssue::getText() const
{
TRACE_FUNC();
return to_string(mptID_);
}
void
MPTIssue::setJson(json::Value& jv) const
{
TRACE_FUNC();
jv[jss::mpt_issuance_id] = to_string(mptID_);
}
json::Value
toJson(MPTIssue const& mptIssue)
{
TRACE_FUNC();
json::Value jv;
mptIssue.setJson(jv);
return jv;
@@ -60,12 +65,14 @@ toJson(MPTIssue const& mptIssue)
std::string
to_string(MPTIssue const& mptIssue)
{
TRACE_FUNC();
return to_string(mptIssue.getMptID());
}
MPTIssue
mptIssueFromJson(json::Value const& v)
{
TRACE_FUNC();
if (!v.isObject())
{
Throw<std::runtime_error>(
@@ -97,6 +104,7 @@ mptIssueFromJson(json::Value const& v)
std::ostream&
operator<<(std::ostream& os, MPTIssue const& x)
{
TRACE_FUNC();
os << to_string(x);
return os;
}

View File

@@ -6,6 +6,7 @@
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TxMeta.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/basics/TraceLog.h>
#include <memory>
@@ -17,6 +18,7 @@ insertNFTSyntheticInJson(
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta)
{
TRACE_FUNC();
insertNFTokenID(response[jss::meta], transaction, transactionMeta);
insertNFTokenOfferID(response[jss::meta], transaction, transactionMeta);
}

View File

@@ -11,6 +11,7 @@
#include <xrpl/protocol/TxFormats.h>
#include <xrpl/protocol/TxMeta.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/basics/TraceLog.h>
#include <algorithm>
#include <iterator>
@@ -23,6 +24,7 @@ namespace xrpl {
bool
canHaveNFTokenID(std::shared_ptr<STTx const> const& serializedTx, TxMeta const& transactionMeta)
{
TRACE_FUNC();
if (!serializedTx)
return false;
@@ -40,6 +42,7 @@ canHaveNFTokenID(std::shared_ptr<STTx const> const& serializedTx, TxMeta const&
std::optional<uint256>
getNFTokenIDFromPage(TxMeta const& transactionMeta)
{
TRACE_FUNC();
// The metadata does not make it obvious which NFT was added. To figure
// that out we gather up all of the previous NFT IDs and all of the final
// NFT IDs and compare them to find what changed.
@@ -112,6 +115,7 @@ getNFTokenIDFromPage(TxMeta const& transactionMeta)
std::vector<uint256>
getNFTokenIDFromDeletedOffer(TxMeta const& transactionMeta)
{
TRACE_FUNC();
std::vector<uint256> tokenIDResult;
for (STObject const& node : transactionMeta.getNodes())
{
@@ -138,6 +142,7 @@ insertNFTokenID(
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta)
{
TRACE_FUNC();
if (!canHaveNFTokenID(transaction, transactionMeta))
return;

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