mirror of
https://github.com/XRPLF/rippled.git
synced 2026-03-20 11:42:29 +00:00
Compare commits
25 Commits
bthomee/no
...
ximinez/le
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8afba1d8cd | ||
|
|
72ebea20f6 | ||
|
|
e15972d239 | ||
|
|
cd740beed3 | ||
|
|
e80b95b1fc | ||
|
|
2d616f194c | ||
|
|
976932566e | ||
|
|
48dcac476d | ||
|
|
5e0f1d2ddf | ||
|
|
74f2003db6 | ||
|
|
7a72b54ba7 | ||
|
|
87776e3114 | ||
|
|
3523f8828c | ||
|
|
058080f6cd | ||
|
|
a646956271 | ||
|
|
7c59b7e064 | ||
|
|
a1f7e1fd78 | ||
|
|
ca06325ed9 | ||
|
|
ca8ef9bf0c | ||
|
|
74875e9ab8 | ||
|
|
f71c7f1959 | ||
|
|
049e12bfd6 | ||
|
|
6fbd1360d6 | ||
|
|
d0810d3cbe | ||
|
|
9568ea0f02 |
71
.clang-tidy
71
.clang-tidy
@@ -8,7 +8,6 @@ Checks: "-*,
|
||||
bugprone-chained-comparison,
|
||||
bugprone-compare-pointer-to-member-virtual-function,
|
||||
bugprone-copy-constructor-init,
|
||||
bugprone-crtp-constructor-accessibility,
|
||||
bugprone-dangling-handle,
|
||||
bugprone-dynamic-static-initializers,
|
||||
bugprone-empty-catch,
|
||||
@@ -60,29 +59,19 @@ Checks: "-*,
|
||||
bugprone-suspicious-string-compare,
|
||||
bugprone-suspicious-stringview-data-usage,
|
||||
bugprone-swapped-arguments,
|
||||
bugprone-switch-missing-default-case,
|
||||
bugprone-terminating-continue,
|
||||
bugprone-throw-keyword-missing,
|
||||
bugprone-too-small-loop-variable,
|
||||
# bugprone-unchecked-optional-access, # see https://github.com/XRPLF/rippled/pull/6502
|
||||
bugprone-undefined-memory-manipulation,
|
||||
bugprone-undelegated-constructor,
|
||||
bugprone-unhandled-exception-at-new,
|
||||
bugprone-unhandled-self-assignment,
|
||||
bugprone-unique-ptr-array-mismatch,
|
||||
bugprone-unsafe-functions,
|
||||
bugprone-use-after-move,
|
||||
bugprone-unused-raii,
|
||||
bugprone-unused-return-value,
|
||||
bugprone-unused-local-non-trivial-variable,
|
||||
bugprone-virtual-near-miss,
|
||||
cppcoreguidelines-init-variables,
|
||||
cppcoreguidelines-misleading-capture-default-by-value,
|
||||
cppcoreguidelines-no-suspend-with-lock,
|
||||
cppcoreguidelines-pro-type-member-init,
|
||||
cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
cppcoreguidelines-rvalue-reference-param-not-moved,
|
||||
cppcoreguidelines-use-default-member-init,
|
||||
cppcoreguidelines-virtual-class-destructor,
|
||||
hicpp-ignored-remove-result,
|
||||
misc-definitions-in-headers,
|
||||
@@ -92,48 +81,62 @@ Checks: "-*,
|
||||
misc-throw-by-value-catch-by-reference,
|
||||
misc-unused-alias-decls,
|
||||
misc-unused-using-decls,
|
||||
readability-duplicate-include,
|
||||
readability-enum-initial-value,
|
||||
readability-misleading-indentation,
|
||||
readability-non-const-parameter,
|
||||
readability-redundant-declaration,
|
||||
readability-reference-to-constructed-temporary,
|
||||
modernize-deprecated-headers,
|
||||
modernize-make-shared,
|
||||
modernize-make-unique,
|
||||
performance-implicit-conversion-in-loop,
|
||||
performance-move-constructor-init,
|
||||
performance-trivially-destructible,
|
||||
readability-avoid-nested-conditional-operator,
|
||||
readability-avoid-return-with-void-value,
|
||||
readability-braces-around-statements,
|
||||
readability-const-return-type,
|
||||
readability-container-contains,
|
||||
readability-container-size-empty,
|
||||
readability-duplicate-include,
|
||||
readability-else-after-return,
|
||||
readability-enum-initial-value,
|
||||
readability-make-member-function-const,
|
||||
readability-misleading-indentation,
|
||||
readability-non-const-parameter,
|
||||
readability-redundant-casting,
|
||||
readability-redundant-declaration,
|
||||
readability-redundant-inline-specifier,
|
||||
readability-redundant-member-init,
|
||||
readability-redundant-string-init,
|
||||
readability-reference-to-constructed-temporary,
|
||||
readability-static-definition-in-anonymous-namespace,
|
||||
readability-use-std-min-max
|
||||
performance-trivially-destructible
|
||||
"
|
||||
# ---
|
||||
# checks that have some issues that need to be resolved:
|
||||
#
|
||||
# bugprone-crtp-constructor-accessibility,
|
||||
# bugprone-move-forwarding-reference,
|
||||
# bugprone-switch-missing-default-case,
|
||||
# bugprone-unused-raii,
|
||||
# bugprone-unused-return-value,
|
||||
# bugprone-use-after-move,
|
||||
#
|
||||
# cppcoreguidelines-misleading-capture-default-by-value,
|
||||
# cppcoreguidelines-init-variables,
|
||||
# cppcoreguidelines-pro-type-member-init,
|
||||
# cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
# cppcoreguidelines-use-default-member-init,
|
||||
# cppcoreguidelines-rvalue-reference-param-not-moved,
|
||||
#
|
||||
# llvm-namespace-comment,
|
||||
# misc-const-correctness,
|
||||
# misc-include-cleaner,
|
||||
# misc-redundant-expression,
|
||||
#
|
||||
# readability-avoid-nested-conditional-operator,
|
||||
# readability-avoid-return-with-void-value,
|
||||
# readability-braces-around-statements,
|
||||
# readability-container-contains,
|
||||
# readability-container-size-empty,
|
||||
# readability-convert-member-functions-to-static,
|
||||
# readability-const-return-type,
|
||||
# readability-else-after-return,
|
||||
# readability-implicit-bool-conversion,
|
||||
# readability-inconsistent-declaration-parameter-name,
|
||||
# readability-identifier-naming,
|
||||
# readability-make-member-function-const,
|
||||
# readability-math-missing-parentheses,
|
||||
# readability-redundant-inline-specifier,
|
||||
# readability-redundant-member-init,
|
||||
# readability-redundant-casting,
|
||||
# readability-redundant-string-init,
|
||||
# readability-simplify-boolean-expr,
|
||||
# readability-static-definition-in-anonymous-namespace,
|
||||
# readability-suspicious-call-argument,
|
||||
# readability-use-std-min-max,
|
||||
# readability-static-accessed-through-instance,
|
||||
#
|
||||
# modernize-concat-nested-namespaces,
|
||||
@@ -157,7 +160,7 @@ Checks: "-*,
|
||||
# ---
|
||||
#
|
||||
CheckOptions:
|
||||
readability-braces-around-statements.ShortStatementLines: 2
|
||||
# readability-braces-around-statements.ShortStatementLines: 2
|
||||
# readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
|
||||
# readability-identifier-naming.ClassCase: CamelCase
|
||||
# readability-identifier-naming.StructCase: CamelCase
|
||||
@@ -192,7 +195,7 @@ CheckOptions:
|
||||
# readability-identifier-naming.PublicMemberSuffix: ""
|
||||
# readability-identifier-naming.FunctionIgnoredRegexp: ".*tag_invoke.*"
|
||||
bugprone-unsafe-functions.ReportMoreUnsafeFunctions: true
|
||||
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
|
||||
# bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
|
||||
# misc-include-cleaner.IgnoreHeaders: '.*/(detail|impl)/.*;.*(expected|unexpected).*;.*ranges_lower_bound\.h;time.h;stdlib.h;__chrono/.*;fmt/chrono.h;boost/uuid/uuid_hash.hpp'
|
||||
#
|
||||
# HeaderFilterRegex: '^.*/(src|tests)/.*\.(h|hpp)$'
|
||||
|
||||
@@ -42,7 +42,6 @@ libxrpl.tx > xrpl.server
|
||||
libxrpl.tx > xrpl.tx
|
||||
test.app > test.jtx
|
||||
test.app > test.rpc
|
||||
test.app > test.shamap
|
||||
test.app > test.toplevel
|
||||
test.app > test.unit_test
|
||||
test.app > xrpl.basics
|
||||
@@ -58,7 +57,6 @@ test.app > xrpl.protocol
|
||||
test.app > xrpl.rdb
|
||||
test.app > xrpl.resource
|
||||
test.app > xrpl.server
|
||||
test.app > xrpl.shamap
|
||||
test.app > xrpl.tx
|
||||
test.basics > test.jtx
|
||||
test.basics > test.unit_test
|
||||
@@ -136,7 +134,6 @@ test.peerfinder > xrpld.core
|
||||
test.peerfinder > xrpld.peerfinder
|
||||
test.peerfinder > xrpl.protocol
|
||||
test.protocol > test.toplevel
|
||||
test.protocol > test.unit_test
|
||||
test.protocol > xrpl.basics
|
||||
test.protocol > xrpl.json
|
||||
test.protocol > xrpl.protocol
|
||||
@@ -174,7 +171,6 @@ test.shamap > xrpl.shamap
|
||||
test.toplevel > test.csf
|
||||
test.toplevel > xrpl.json
|
||||
test.unit_test > xrpl.basics
|
||||
test.unit_test > xrpl.protocol
|
||||
tests.libxrpl > xrpl.basics
|
||||
tests.libxrpl > xrpl.json
|
||||
tests.libxrpl > xrpl.net
|
||||
|
||||
5
.github/workflows/check-pr-title.yml
vendored
5
.github/workflows/check-pr-title.yml
vendored
@@ -1,13 +1,10 @@
|
||||
name: Check PR title
|
||||
|
||||
on:
|
||||
merge_group:
|
||||
types:
|
||||
- checks_requested
|
||||
pull_request:
|
||||
types: [opened, edited, reopened, synchronize]
|
||||
branches: [develop]
|
||||
|
||||
jobs:
|
||||
check_title:
|
||||
uses: XRPLF/actions/.github/workflows/check-pr-title.yml@c6311685db43aa07971c4a6764320fecbc2acdcd
|
||||
uses: XRPLF/actions/.github/workflows/check-pr-title.yml@943eb8277e8f4b010fde0c826ce4154c36c39509
|
||||
|
||||
3
.github/workflows/pre-commit.yml
vendored
3
.github/workflows/pre-commit.yml
vendored
@@ -1,9 +1,6 @@
|
||||
name: Run pre-commit hooks
|
||||
|
||||
on:
|
||||
merge_group:
|
||||
types:
|
||||
- checks_requested
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
|
||||
16
.github/workflows/reusable-build-test-config.yml
vendored
16
.github/workflows/reusable-build-test-config.yml
vendored
@@ -76,7 +76,7 @@ jobs:
|
||||
name: ${{ inputs.config_name }}
|
||||
runs-on: ${{ fromJSON(inputs.runs_on) }}
|
||||
container: ${{ inputs.image != '' && inputs.image || null }}
|
||||
timeout-minutes: ${{ inputs.sanitizers != '' && 360 || 60 }}
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
# Use a namespace to keep the objects separate for each configuration.
|
||||
CCACHE_NAMESPACE: ${{ inputs.config_name }}
|
||||
@@ -204,17 +204,11 @@ jobs:
|
||||
|
||||
- name: Set sanitizer options
|
||||
if: ${{ !inputs.build_only && env.SANITIZERS_ENABLED == 'true' }}
|
||||
env:
|
||||
CONFIG_NAME: ${{ inputs.config_name }}
|
||||
run: |
|
||||
ASAN_OPTS="include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-asan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/asan.supp"
|
||||
if [[ "${CONFIG_NAME}" == *gcc* ]]; then
|
||||
ASAN_OPTS="${ASAN_OPTS}:alloc_dealloc_mismatch=0"
|
||||
fi
|
||||
echo "ASAN_OPTIONS=${ASAN_OPTS}" >> ${GITHUB_ENV}
|
||||
echo "TSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-tsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >> ${GITHUB_ENV}
|
||||
echo "UBSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-ubsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >> ${GITHUB_ENV}
|
||||
echo "LSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-lsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >> ${GITHUB_ENV}
|
||||
echo "ASAN_OPTIONS=print_stacktrace=1:detect_container_overflow=0:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/asan.supp" >> ${GITHUB_ENV}
|
||||
echo "TSAN_OPTIONS=second_deadlock_stack=1:halt_on_error=0:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >> ${GITHUB_ENV}
|
||||
echo "UBSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >> ${GITHUB_ENV}
|
||||
echo "LSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >> ${GITHUB_ENV}
|
||||
|
||||
- name: Run the separate tests
|
||||
if: ${{ !inputs.build_only }}
|
||||
|
||||
@@ -35,10 +35,6 @@ This section contains changes targeting a future version.
|
||||
- `LEDGER_ENTRY_FLAGS`: Maps ledger entry type names to their flags and flag values.
|
||||
- `ACCOUNT_SET_FLAGS`: Maps AccountSet flag names (asf flags) to their numeric values.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- Peer Crawler: The `port` field in `overlay.active[]` now consistently returns an integer instead of a string for outbound peers. [#6318](https://github.com/XRPLF/rippled/pull/6318)
|
||||
|
||||
## XRP Ledger server version 3.1.0
|
||||
|
||||
[Version 3.1.0](https://github.com/XRPLF/rippled/releases/tag/3.1.0) was released on Jan 27, 2026.
|
||||
|
||||
@@ -118,7 +118,7 @@ if(MSVC)
|
||||
NOMINMAX
|
||||
# TODO: Resolve these warnings, don't just silence them
|
||||
_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>,$<NOT:$<BOOL:${is_ci}>>>:_CRTDBG_MAP_ALLOC>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:_CRTDBG_MAP_ALLOC>
|
||||
)
|
||||
target_link_libraries(common INTERFACE -errorreport:none -machine:X64)
|
||||
else()
|
||||
|
||||
@@ -23,7 +23,7 @@ target_compile_definitions(
|
||||
BOOST_FILESYSTEM_NO_DEPRECATED
|
||||
>
|
||||
$<$<NOT:$<BOOL:${boost_show_deprecated}>>:
|
||||
BOOST_COROUTINES2_NO_DEPRECATION_WARNING
|
||||
BOOST_COROUTINES_NO_DEPRECATION_WARNING
|
||||
BOOST_BEAST_ALLOW_DEPRECATED
|
||||
BOOST_FILESYSTEM_DEPRECATED
|
||||
>
|
||||
|
||||
@@ -7,7 +7,7 @@ find_package(
|
||||
COMPONENTS
|
||||
chrono
|
||||
container
|
||||
context
|
||||
coroutine
|
||||
date_time
|
||||
filesystem
|
||||
json
|
||||
@@ -26,7 +26,7 @@ target_link_libraries(
|
||||
Boost::headers
|
||||
Boost::chrono
|
||||
Boost::container
|
||||
Boost::context
|
||||
Boost::coroutine
|
||||
Boost::date_time
|
||||
Boost::filesystem
|
||||
Boost::json
|
||||
@@ -38,26 +38,23 @@ target_link_libraries(
|
||||
if(Boost_COMPILER)
|
||||
target_link_libraries(xrpl_boost INTERFACE Boost::disable_autolinking)
|
||||
endif()
|
||||
|
||||
# GCC 14+ has a false positive -Wuninitialized warning in Boost.Coroutine2's
|
||||
# state.hpp when compiled with -O3. This is due to GCC's intentional behavior
|
||||
# change (Bug #98871, #119388) where warnings from inlined system header code
|
||||
# are no longer suppressed by -isystem. The warning occurs in operator|= in
|
||||
# boost/coroutine2/detail/state.hpp when inlined from push_control_block::destroy().
|
||||
# See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119388
|
||||
if(is_gcc AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 14)
|
||||
target_compile_options(xrpl_boost INTERFACE -Wno-uninitialized)
|
||||
endif()
|
||||
|
||||
# Boost.Context's ucontext backend has ASAN fiber-switching annotations
|
||||
# (start/finish_switch_fiber) that are compiled in when BOOST_USE_ASAN is defined.
|
||||
# This tells ASAN about coroutine stack switches, preventing false positive
|
||||
# stack-use-after-scope errors. BOOST_USE_UCONTEXT ensures the ucontext backend
|
||||
# is selected (fcontext does not support ASAN annotations).
|
||||
# These defines must match what Boost was compiled with (see conan/profiles/sanitizers).
|
||||
if(enable_asan)
|
||||
target_compile_definitions(
|
||||
xrpl_boost
|
||||
INTERFACE BOOST_USE_ASAN BOOST_USE_UCONTEXT
|
||||
if(SANITIZERS_ENABLED AND is_clang)
|
||||
# TODO: gcc does not support -fsanitize-blacklist...can we do something else for gcc ?
|
||||
if(NOT Boost_INCLUDE_DIRS AND TARGET Boost::headers)
|
||||
get_target_property(
|
||||
Boost_INCLUDE_DIRS
|
||||
Boost::headers
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
)
|
||||
endif()
|
||||
message(STATUS "Adding [${Boost_INCLUDE_DIRS}] to sanitizer blacklist")
|
||||
file(
|
||||
WRITE ${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt
|
||||
"src:${Boost_INCLUDE_DIRS}/*"
|
||||
)
|
||||
target_compile_options(
|
||||
opts
|
||||
INTERFACE # ignore boost headers for sanitizing
|
||||
-fsanitize-blacklist=${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -7,21 +7,16 @@ include(default)
|
||||
{% if compiler == "gcc" %}
|
||||
{% if "address" in sanitizers or "thread" in sanitizers or "undefinedbehavior" in sanitizers %}
|
||||
{% set sanitizer_list = [] %}
|
||||
{% set defines = [] %}
|
||||
{% set model_code = "" %}
|
||||
{% set extra_cxxflags = ["-fno-omit-frame-pointer", "-O1", "-Wno-stringop-overflow"] %}
|
||||
|
||||
{% if "address" in sanitizers %}
|
||||
{% set _ = sanitizer_list.append("address") %}
|
||||
{% set model_code = "-mcmodel=large" %}
|
||||
{% set _ = defines.append("BOOST_USE_ASAN")%}
|
||||
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
|
||||
{% elif "thread" in sanitizers %}
|
||||
{% set _ = sanitizer_list.append("thread") %}
|
||||
{% set model_code = "-mcmodel=medium" %}
|
||||
{% set _ = extra_cxxflags.append("-Wno-tsan") %}
|
||||
{% set _ = defines.append("BOOST_USE_TSAN")%}
|
||||
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
|
||||
{% endif %}
|
||||
|
||||
{% if "undefinedbehavior" in sanitizers %}
|
||||
@@ -34,22 +29,16 @@ include(default)
|
||||
tools.build:cxxflags+=['{{sanitizer_flags}} {{" ".join(extra_cxxflags)}}']
|
||||
tools.build:sharedlinkflags+=['{{sanitizer_flags}}']
|
||||
tools.build:exelinkflags+=['{{sanitizer_flags}}']
|
||||
tools.build:defines+={{defines}}
|
||||
{% endif %}
|
||||
{% elif compiler == "apple-clang" or compiler == "clang" %}
|
||||
{% if "address" in sanitizers or "thread" in sanitizers or "undefinedbehavior" in sanitizers %}
|
||||
{% set sanitizer_list = [] %}
|
||||
{% set defines = [] %}
|
||||
{% set extra_cxxflags = ["-fno-omit-frame-pointer", "-O1"] %}
|
||||
|
||||
{% if "address" in sanitizers %}
|
||||
{% set _ = sanitizer_list.append("address") %}
|
||||
{% set _ = defines.append("BOOST_USE_ASAN")%}
|
||||
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
|
||||
{% elif "thread" in sanitizers %}
|
||||
{% set _ = sanitizer_list.append("thread") %}
|
||||
{% set _ = defines.append("BOOST_USE_TSAN")%}
|
||||
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
|
||||
{% endif %}
|
||||
|
||||
{% if "undefinedbehavior" in sanitizers %}
|
||||
@@ -63,24 +52,8 @@ include(default)
|
||||
tools.build:cxxflags+=['{{sanitizer_flags}} {{" ".join(extra_cxxflags)}}']
|
||||
tools.build:sharedlinkflags+=['{{sanitizer_flags}}']
|
||||
tools.build:exelinkflags+=['{{sanitizer_flags}}']
|
||||
tools.build:defines+={{defines}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags", "tools.build:defines"]
|
||||
|
||||
[options]
|
||||
{% if sanitizers %}
|
||||
{% if "address" in sanitizers %}
|
||||
# Build Boost.Context with ucontext backend (not fcontext) so that
|
||||
# ASAN fiber-switching annotations (__sanitizer_start/finish_switch_fiber)
|
||||
# are compiled into the library. fcontext (assembly) has no ASAN support.
|
||||
# define=BOOST_USE_ASAN=1 is critical: it must be defined when building
|
||||
# Boost.Context itself so the ucontext backend compiles in the ASAN annotations.
|
||||
boost/*:extra_b2_flags=context-impl=ucontext address-sanitizer=on define=BOOST_USE_ASAN=1
|
||||
boost/*:without_context=False
|
||||
# Boost stacktrace fails to build with some sanitizers
|
||||
boost/*:without_stacktrace=True
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags"]
|
||||
|
||||
12
conanfile.py
12
conanfile.py
@@ -1,5 +1,4 @@
|
||||
import re
|
||||
import os
|
||||
|
||||
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
|
||||
|
||||
@@ -58,9 +57,6 @@ class Xrpl(ConanFile):
|
||||
"tests": False,
|
||||
"unity": False,
|
||||
"xrpld": False,
|
||||
"boost/*:without_context": False,
|
||||
"boost/*:without_coroutine": True,
|
||||
"boost/*:without_coroutine2": False,
|
||||
"date/*:header_only": True,
|
||||
"ed25519/*:shared": False,
|
||||
"grpc/*:shared": False,
|
||||
@@ -130,12 +126,6 @@ class Xrpl(ConanFile):
|
||||
if self.settings.compiler in ["clang", "gcc"]:
|
||||
self.options["boost"].without_cobalt = True
|
||||
|
||||
# Check if environment variable exists
|
||||
if "SANITIZERS" in os.environ:
|
||||
sanitizers = os.environ["SANITIZERS"]
|
||||
if "address" in sanitizers.lower():
|
||||
self.default_options["fPIC"] = False
|
||||
|
||||
def requirements(self):
|
||||
# Conan 2 requires transitive headers to be specified
|
||||
transitive_headers_opt = (
|
||||
@@ -206,7 +196,7 @@ class Xrpl(ConanFile):
|
||||
"boost::headers",
|
||||
"boost::chrono",
|
||||
"boost::container",
|
||||
"boost::context",
|
||||
"boost::coroutine",
|
||||
"boost::date_time",
|
||||
"boost::filesystem",
|
||||
"boost::json",
|
||||
|
||||
@@ -99,7 +99,6 @@ words:
|
||||
- endmacro
|
||||
- exceptioned
|
||||
- Falco
|
||||
- fcontext
|
||||
- finalizers
|
||||
- firewalled
|
||||
- fmtdur
|
||||
@@ -112,7 +111,6 @@ words:
|
||||
- gpgcheck
|
||||
- gpgkey
|
||||
- hotwallet
|
||||
- hwaddress
|
||||
- hwrap
|
||||
- ifndef
|
||||
- inequation
|
||||
|
||||
8
docs/build/sanitizers.md
vendored
8
docs/build/sanitizers.md
vendored
@@ -89,8 +89,8 @@ cmake --build . --parallel 4
|
||||
**IMPORTANT**: ASAN with Boost produces many false positives. Use these options:
|
||||
|
||||
```bash
|
||||
export ASAN_OPTIONS="include=sanitizers/suppressions/runtime-asan-options.txt:suppressions=sanitizers/suppressions/asan.supp"
|
||||
export LSAN_OPTIONS="include=sanitizers/suppressions/runtime-lsan-options.txt:suppressions=sanitizers/suppressions/lsan.supp"
|
||||
export ASAN_OPTIONS="print_stacktrace=1:detect_container_overflow=0:suppressions=path/to/asan.supp:halt_on_error=0:log_path=asan.log"
|
||||
export LSAN_OPTIONS="suppressions=path/to/lsan.supp:halt_on_error=0:log_path=lsan.log"
|
||||
|
||||
# Run tests
|
||||
./xrpld --unittest --unittest-jobs=5
|
||||
@@ -108,7 +108,7 @@ export LSAN_OPTIONS="include=sanitizers/suppressions/runtime-lsan-options.txt:su
|
||||
### ThreadSanitizer (TSan)
|
||||
|
||||
```bash
|
||||
export TSAN_OPTIONS="include=sanitizers/suppressions/runtime-tsan-options.txt:suppressions=sanitizers/suppressions/tsan.supp"
|
||||
export TSAN_OPTIONS="suppressions=path/to/tsan.supp halt_on_error=0 log_path=tsan.log"
|
||||
|
||||
# Run tests
|
||||
./xrpld --unittest --unittest-jobs=5
|
||||
@@ -129,7 +129,7 @@ More details [here](https://github.com/google/sanitizers/wiki/AddressSanitizerLe
|
||||
### UndefinedBehaviorSanitizer (UBSan)
|
||||
|
||||
```bash
|
||||
export UBSAN_OPTIONS="include=sanitizers/suppressions/runtime-ubsan-options.txt:suppressions=sanitizers/suppressions/ubsan.supp"
|
||||
export UBSAN_OPTIONS="suppressions=path/to/ubsan.supp:print_stacktrace=1:halt_on_error=0:log_path=ubsan.log"
|
||||
|
||||
# Run tests
|
||||
./xrpld --unittest --unittest-jobs=5
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
@@ -232,11 +231,4 @@ makeSlice(std::basic_string<char, Traits, Alloc> const& s)
|
||||
return Slice(s.data(), s.size());
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
Slice
|
||||
makeSlice(std::basic_string_view<char, Traits> const& s)
|
||||
{
|
||||
return Slice(s.data(), s.size());
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/sanitizers.h>
|
||||
#include <xrpl/beast/type_name.h>
|
||||
|
||||
#include <exception>
|
||||
@@ -24,28 +23,16 @@ LogThrow(std::string const& title);
|
||||
When called from within a catch block, it will pass
|
||||
control to the next matching exception handler, if any.
|
||||
Otherwise, std::terminate will be called.
|
||||
|
||||
ASAN can't handle sudden jumps in control flow very well. This
|
||||
function is marked as XRPL_NO_SANITIZE_ADDRESS to prevent it from
|
||||
triggering false positives, since it throws.
|
||||
*/
|
||||
[[noreturn]] XRPL_NO_SANITIZE_ADDRESS inline void
|
||||
[[noreturn]] inline void
|
||||
Rethrow()
|
||||
{
|
||||
LogThrow("Re-throwing exception");
|
||||
throw;
|
||||
}
|
||||
|
||||
/*
|
||||
Logs and throws an exception of type E.
|
||||
|
||||
ASAN can't handle sudden jumps in control flow very well. This
|
||||
function is marked as XRPL_NO_SANITIZE_ADDRESS to prevent it from
|
||||
triggering false positives, since it throws.
|
||||
*/
|
||||
|
||||
template <class E, class... Args>
|
||||
[[noreturn]] XRPL_NO_SANITIZE_ADDRESS inline void
|
||||
[[noreturn]] inline void
|
||||
Throw(Args&&... args)
|
||||
{
|
||||
static_assert(
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -72,31 +70,4 @@ unsafe_cast(Src s) noexcept
|
||||
return unsafe_cast<Dest>(static_cast<std::underlying_type_t<Src>>(s));
|
||||
}
|
||||
|
||||
template <class Dest, class Src>
|
||||
requires std::is_pointer_v<Dest>
|
||||
inline Dest
|
||||
safe_downcast(Src* s) noexcept
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
return static_cast<Dest>(s); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
|
||||
#else
|
||||
auto* result = dynamic_cast<Dest>(s);
|
||||
XRPL_ASSERT(result != nullptr, "xrpl::safe_downcast : pointer downcast is valid");
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Dest, class Src>
|
||||
requires std::is_lvalue_reference_v<Dest>
|
||||
inline Dest
|
||||
safe_downcast(Src& s) noexcept
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
XRPL_ASSERT(
|
||||
dynamic_cast<std::add_pointer_t<std::remove_reference_t<Dest>>>(&s) != nullptr,
|
||||
"xrpl::safe_downcast : reference downcast is valid");
|
||||
#endif
|
||||
return static_cast<Dest>(s); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Helper to disable ASan/HwASan for specific functions
|
||||
/*
|
||||
ASAN flags some false positives with sudden jumps in control flow, like
|
||||
exceptions, or when encountering coroutine stack switches. This macro can be used to disable ASAN
|
||||
intrumentation for specific functions.
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define XRPL_NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address", "hwaddress")))
|
||||
#else
|
||||
#define XRPL_NO_SANITIZE_ADDRESS
|
||||
#endif
|
||||
@@ -43,8 +43,8 @@ private:
|
||||
template <typename>
|
||||
friend class ListIterator;
|
||||
|
||||
ListNode* m_next = nullptr;
|
||||
ListNode* m_prev = nullptr;
|
||||
ListNode* m_next;
|
||||
ListNode* m_prev;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -567,7 +567,7 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
size_type m_size = 0u;
|
||||
size_type m_size;
|
||||
Node m_head;
|
||||
Node m_tail;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/ByteUtilities.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <class F>
|
||||
@@ -9,18 +11,16 @@ JobQueue::Coro::Coro(Coro_create_t, JobQueue& jq, JobType type, std::string cons
|
||||
, name_(name)
|
||||
, running_(false)
|
||||
, coro_(
|
||||
// Stack size of 1MB wasn't sufficient for deep calls. ASAN tests flagged the issue. Hence
|
||||
// increasing the size to 1.5MB.
|
||||
boost::context::protected_fixedsize_stack(1536 * 1024),
|
||||
[this, fn = std::forward<F>(f)](
|
||||
boost::coroutines2::asymmetric_coroutine<void>::push_type& do_yield) {
|
||||
boost::coroutines::asymmetric_coroutine<void>::push_type& do_yield) {
|
||||
yield_ = &do_yield;
|
||||
yield();
|
||||
fn(shared_from_this());
|
||||
#ifndef NDEBUG
|
||||
finished_ = true;
|
||||
#endif
|
||||
})
|
||||
},
|
||||
boost::coroutines::attributes(megabytes(1)))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
#include <xrpl/core/detail/Workers.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <boost/context/protected_fixedsize_stack.hpp>
|
||||
#include <boost/coroutine2/all.hpp>
|
||||
#include <boost/coroutine/all.hpp>
|
||||
|
||||
#include <set>
|
||||
|
||||
@@ -49,8 +48,8 @@ public:
|
||||
std::mutex mutex_;
|
||||
std::mutex mutex_run_;
|
||||
std::condition_variable cv_;
|
||||
boost::coroutines2::coroutine<void>::pull_type coro_;
|
||||
boost::coroutines2::coroutine<void>::push_type* yield_;
|
||||
boost::coroutines::asymmetric_coroutine<void>::pull_type coro_;
|
||||
boost::coroutines::asymmetric_coroutine<void>::push_type* yield_;
|
||||
#ifndef NDEBUG
|
||||
bool finished_ = false;
|
||||
#endif
|
||||
|
||||
@@ -421,7 +421,7 @@ private:
|
||||
ObjectValues* map_{nullptr};
|
||||
} value_;
|
||||
ValueType type_ : 8;
|
||||
int allocated_ : 1 {}; // Notes: if declared as bool, bitfield is useless.
|
||||
int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
|
||||
};
|
||||
|
||||
inline Value
|
||||
|
||||
@@ -108,7 +108,7 @@ private:
|
||||
std::string indentString_;
|
||||
int rightMargin_;
|
||||
int indentSize_;
|
||||
bool addChildValues_{};
|
||||
bool addChildValues_;
|
||||
};
|
||||
|
||||
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
|
||||
@@ -175,7 +175,7 @@ private:
|
||||
std::string indentString_;
|
||||
int rightMargin_;
|
||||
std::string indentation_;
|
||||
bool addChildValues_{};
|
||||
bool addChildValues_;
|
||||
};
|
||||
|
||||
std::string
|
||||
|
||||
@@ -49,7 +49,7 @@ validDomain(ReadView const& view, uint256 domainID, AccountID const& subject);
|
||||
// This function is only called when we about to return tecNO_PERMISSION
|
||||
// because all the checks for the DepositPreauth authorization failed.
|
||||
TER
|
||||
authorizedDepositPreauth(ReadView const& view, STVector256 const& ctx, AccountID const& dst);
|
||||
authorizedDepositPreauth(ApplyView const& view, STVector256 const& ctx, AccountID const& dst);
|
||||
|
||||
// Sort credentials array, return empty set if there are duplicates
|
||||
std::set<std::pair<AccountID, Slice>>
|
||||
@@ -74,7 +74,7 @@ verifyDepositPreauth(
|
||||
ApplyView& view,
|
||||
AccountID const& src,
|
||||
AccountID const& dst,
|
||||
std::shared_ptr<SLE const> const& sleDst,
|
||||
std::shared_ptr<SLE> const& sleDst,
|
||||
beast::Journal j);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -29,18 +29,6 @@ public:
|
||||
bool sslVerify,
|
||||
beast::Journal j);
|
||||
|
||||
/** Destroys the global SSL context created by initializeSSLContext().
|
||||
*
|
||||
* This releases the underlying boost::asio::ssl::context and any
|
||||
* associated OpenSSL resources. Must not be called while any
|
||||
* HTTPClient requests are in flight.
|
||||
*
|
||||
* @note Currently only called from tests during teardown. In production,
|
||||
* the SSL context lives for the lifetime of the process.
|
||||
*/
|
||||
static void
|
||||
cleanupSSLContext();
|
||||
|
||||
static void
|
||||
get(bool bSSL,
|
||||
boost::asio::io_context& io_context,
|
||||
|
||||
@@ -244,15 +244,7 @@ message TMGetObjectByHash {
|
||||
|
||||
message TMLedgerNode {
|
||||
required bytes nodedata = 1;
|
||||
|
||||
// Used when protocol version <2.3. Not set for ledger base data.
|
||||
optional bytes nodeid = 2;
|
||||
|
||||
// Used when protocol version >=2.3. Neither value is set for ledger base data.
|
||||
oneof reference {
|
||||
bytes id = 3; // Set for inner nodes.
|
||||
uint32 depth = 4; // Set for leaf nodes.
|
||||
}
|
||||
optional bytes nodeid = 2; // missing for ledger base data
|
||||
}
|
||||
|
||||
enum TMLedgerInfoType {
|
||||
|
||||
@@ -64,49 +64,6 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Feature names must not exceed this length (in characters, excluding the null terminator).
|
||||
static constexpr std::size_t maxFeatureNameSize = 63;
|
||||
// Reserve this exact feature-name length (in characters/bytes, excluding the null terminator)
|
||||
// so that a 32-byte uint256 (for example, in WASM or other interop contexts) can be used
|
||||
// as a compact, fixed-size feature selector without conflicting with human-readable names.
|
||||
static constexpr std::size_t reservedFeatureNameSize = 32;
|
||||
|
||||
// Both validFeatureNameSize and validFeatureName are consteval functions that can be used in
|
||||
// static_asserts to validate feature names at compile time. They are only used inside
|
||||
// enforceValidFeatureName in Feature.cpp, but are exposed here for testing. The expected
|
||||
// parameter `auto fn` is a constexpr lambda which returns a const char*, making it available
|
||||
// for compile-time evaluation. Read more in https://accu.org/journals/overload/30/172/wu/
|
||||
consteval auto
|
||||
validFeatureNameSize(auto fn) -> bool
|
||||
{
|
||||
constexpr char const* n = fn();
|
||||
// Note, std::strlen is not constexpr, we need to implement our own here.
|
||||
constexpr std::size_t N = [](auto n) {
|
||||
std::size_t ret = 0;
|
||||
for (auto ptr = n; *ptr != '\0'; ret++, ++ptr)
|
||||
;
|
||||
return ret;
|
||||
}(n);
|
||||
return N != reservedFeatureNameSize && //
|
||||
N <= maxFeatureNameSize;
|
||||
}
|
||||
|
||||
consteval auto
|
||||
validFeatureName(auto fn) -> bool
|
||||
{
|
||||
constexpr char const* n = fn();
|
||||
// Prevent the use of visually confusable characters and enforce that feature names
|
||||
// are always valid ASCII. This is needed because C++ allows Unicode identifiers.
|
||||
// Characters below 0x20 are nonprintable control characters, and characters with the 0x80 bit
|
||||
// set are non-ASCII (e.g. UTF-8 encoding of Unicode), so both are disallowed.
|
||||
for (auto ptr = n; *ptr != '\0'; ++ptr)
|
||||
{
|
||||
if (*ptr & 0x80 || *ptr < 0x20)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
enum class VoteBehavior : int { Obsolete = -1, DefaultNo = 0, DefaultYes };
|
||||
enum class AmendmentSupport : int { Retired = -1, Supported = 0, Unsupported };
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
std::optional<TxType>
|
||||
getGranularTxType(GranularPermissionType const& gpType) const;
|
||||
|
||||
std::optional<std::reference_wrapper<uint256 const>>
|
||||
std::optional<std::reference_wrapper<uint256 const>> const
|
||||
getTxFeature(TxType txType) const;
|
||||
|
||||
bool
|
||||
|
||||
@@ -209,7 +209,7 @@ std::size_t constexpr maxDIDDocumentLength = 256;
|
||||
std::size_t constexpr maxDIDURILength = 256;
|
||||
|
||||
/** The maximum length of an Attestation inside a DID */
|
||||
std::size_t constexpr maxDIDDataLength = 256;
|
||||
std::size_t constexpr maxDIDAttestationLength = 256;
|
||||
|
||||
/** The maximum length of a domain */
|
||||
std::size_t constexpr maxDomainLength = 256;
|
||||
|
||||
@@ -44,7 +44,7 @@ protected:
|
||||
// All the constructed public keys are valid, non-empty and contain 33
|
||||
// bytes of data.
|
||||
static constexpr std::size_t size_ = 33;
|
||||
std::uint8_t buf_[size_]{}; // should be large enough
|
||||
std::uint8_t buf_[size_]; // should be large enough
|
||||
|
||||
public:
|
||||
using const_iterator = std::uint8_t const*;
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
STAccount();
|
||||
|
||||
STAccount(SField const& n);
|
||||
STAccount(SField const& n, Buffer const& v);
|
||||
STAccount(SField const& n, Buffer&& v);
|
||||
STAccount(SerialIter& sit, SField const& name);
|
||||
STAccount(SField const& n, AccountID const& v);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class STObject : public STBase, public CountedObject<STObject>
|
||||
using list_type = std::vector<detail::STVar>;
|
||||
|
||||
list_type v_;
|
||||
SOTemplate const* mType{};
|
||||
SOTemplate const* mType;
|
||||
|
||||
public:
|
||||
using iterator = boost::transform_iterator<Transform, STObject::list_type::const_iterator>;
|
||||
@@ -401,7 +401,7 @@ public:
|
||||
getStyle(SField const& field) const;
|
||||
|
||||
bool
|
||||
hasMatchingEntry(STBase const&) const;
|
||||
hasMatchingEntry(STBase const&);
|
||||
|
||||
bool
|
||||
operator==(STObject const& o) const;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
enum class TxnSql : char {
|
||||
enum TxnSql : char {
|
||||
txnSqlNew = 'N',
|
||||
txnSqlConflict = 'C',
|
||||
txnSqlHeld = 'H',
|
||||
@@ -83,9 +83,6 @@ public:
|
||||
std::uint32_t
|
||||
getSeqValue() const;
|
||||
|
||||
AccountID
|
||||
getFeePayer() const;
|
||||
|
||||
boost::container::flat_set<AccountID>
|
||||
getMentionedAccounts() const;
|
||||
|
||||
@@ -125,7 +122,7 @@ public:
|
||||
getMetaSQL(
|
||||
Serializer rawTxn,
|
||||
std::uint32_t inLedger,
|
||||
TxnSql status,
|
||||
char status,
|
||||
std::string const& escapedMetaData) const;
|
||||
|
||||
std::vector<uint256> const&
|
||||
|
||||
@@ -16,11 +16,8 @@ namespace xrpl {
|
||||
/** A secret key. */
|
||||
class SecretKey
|
||||
{
|
||||
public:
|
||||
static constexpr std::size_t size_ = 32;
|
||||
|
||||
private:
|
||||
std::uint8_t buf_[size_]{};
|
||||
std::uint8_t buf_[32];
|
||||
|
||||
public:
|
||||
using const_iterator = std::uint8_t const*;
|
||||
@@ -30,14 +27,9 @@ public:
|
||||
SecretKey&
|
||||
operator=(SecretKey const&) = default;
|
||||
|
||||
bool
|
||||
operator==(SecretKey const&) = delete;
|
||||
bool
|
||||
operator!=(SecretKey const&) = delete;
|
||||
|
||||
~SecretKey();
|
||||
|
||||
SecretKey(std::array<std::uint8_t, size_> const& data);
|
||||
SecretKey(std::array<std::uint8_t, 32> const& data);
|
||||
SecretKey(Slice const& slice);
|
||||
|
||||
std::uint8_t const*
|
||||
@@ -86,10 +78,16 @@ public:
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(SecretKey const& lhs, SecretKey const& rhs) = delete;
|
||||
operator==(SecretKey const& lhs, SecretKey const& rhs)
|
||||
{
|
||||
return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), rhs.size()) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(SecretKey const& lhs, SecretKey const& rhs) = delete;
|
||||
operator!=(SecretKey const& lhs, SecretKey const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace xrpl {
|
||||
class Seed
|
||||
{
|
||||
private:
|
||||
std::array<uint8_t, 16> buf_{};
|
||||
std::array<uint8_t, 16> buf_;
|
||||
|
||||
public:
|
||||
using const_iterator = std::array<uint8_t, 16>::const_iterator;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace xrpl {
|
||||
static inline std::string const&
|
||||
systemName()
|
||||
{
|
||||
static std::string const name = "xrpld";
|
||||
static std::string const name = "ripple";
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ private:
|
||||
// The largest "small object" we can accommodate
|
||||
static std::size_t constexpr max_size = 72;
|
||||
|
||||
std::aligned_storage<max_size>::type d_ = {};
|
||||
std::aligned_storage<max_size>::type d_;
|
||||
STBase* p_ = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
operator result_type() noexcept;
|
||||
|
||||
private:
|
||||
char ctx_[96]{};
|
||||
char ctx_[96];
|
||||
};
|
||||
|
||||
/** SHA-512 digest
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
operator result_type() noexcept;
|
||||
|
||||
private:
|
||||
char ctx_[216]{};
|
||||
char ctx_[216];
|
||||
};
|
||||
|
||||
/** SHA-256 digest
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
operator result_type() noexcept;
|
||||
|
||||
private:
|
||||
char ctx_[112]{};
|
||||
char ctx_[112];
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -112,7 +112,6 @@ JSS(accounts); // in: LedgerEntry, Subscribe,
|
||||
// handlers/Ledger, Unsubscribe
|
||||
JSS(accounts_proposed); // in: Subscribe, Unsubscribe
|
||||
JSS(action);
|
||||
JSS(active); // out: OverlayImpl
|
||||
JSS(acquiring); // out: LedgerRequest
|
||||
JSS(address); // out: PeerImp
|
||||
JSS(affected); // out: AcceptedLedgerTx
|
||||
@@ -301,7 +300,6 @@ JSS(id); // websocket.
|
||||
JSS(ident); // in: AccountCurrencies, AccountInfo,
|
||||
// OwnerInfo
|
||||
JSS(ignore_default); // in: AccountLines
|
||||
JSS(in); // out: OverlayImpl
|
||||
JSS(inLedger); // out: tx/Transaction
|
||||
JSS(inbound); // out: PeerImp
|
||||
JSS(index); // in: LedgerEntry
|
||||
@@ -466,7 +464,6 @@ JSS(open_ledger_level); // out: TxQ
|
||||
JSS(optionality); // out: server_definitions
|
||||
JSS(oracles); // in: get_aggregate_price
|
||||
JSS(oracle_document_id); // in: get_aggregate_price
|
||||
JSS(out); // out: OverlayImpl
|
||||
JSS(owner); // in: LedgerEntry, out: NetworkOPs
|
||||
JSS(owner_funds); // in/out: Ledger, NetworkOPs, AcceptedLedgerTx
|
||||
JSS(page_index);
|
||||
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
send(Json::Value const& jvObj, bool broadcast) = 0;
|
||||
|
||||
std::uint64_t
|
||||
getSeq() const;
|
||||
getSeq();
|
||||
|
||||
void
|
||||
onSendEmpty();
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <set>
|
||||
#include <stack>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -254,7 +253,7 @@ public:
|
||||
bool
|
||||
getNodeFat(
|
||||
SHAMapNodeID const& wanted,
|
||||
std::vector<std::tuple<SHAMapNodeID, Blob, bool>>& data,
|
||||
std::vector<std::pair<SHAMapNodeID, Blob>>& data,
|
||||
bool fatLeaves,
|
||||
std::uint32_t depth) const;
|
||||
|
||||
@@ -281,45 +280,10 @@ public:
|
||||
void
|
||||
serializeRoot(Serializer& s) const;
|
||||
|
||||
/** Add a root node to the SHAMap during synchronization.
|
||||
*
|
||||
* This function is used when receiving the root node of a SHAMap from a peer during ledger
|
||||
* synchronization. The node must already have been deserialized.
|
||||
*
|
||||
* @param hash The expected hash of the root node.
|
||||
* @param rootNode A deserialized root node to add.
|
||||
* @param filter Optional sync filter to track received nodes.
|
||||
* @return Status indicating whether the node was useful, duplicate, or invalid.
|
||||
*
|
||||
* @note This function expects the rootNode to be a valid, deserialized SHAMapTreeNode. The
|
||||
* caller is responsible for deserialization and basic validation before calling this
|
||||
* function.
|
||||
*/
|
||||
SHAMapAddNode
|
||||
addRootNode(
|
||||
SHAMapHash const& hash,
|
||||
intr_ptr::SharedPtr<SHAMapTreeNode> rootNode,
|
||||
SHAMapSyncFilter const* filter);
|
||||
|
||||
/** Add a known node at a specific position in the SHAMap during synchronization.
|
||||
*
|
||||
* This function is used when receiving nodes from peers during ledger synchronization. The node
|
||||
* is inserted at the position specified by nodeID. The node must already have been
|
||||
* deserialized.
|
||||
*
|
||||
* @param nodeID The position in the tree where this node belongs.
|
||||
* @param treeNode A deserialized tree node to add.
|
||||
* @param filter Optional sync filter to track received nodes.
|
||||
* @return Status indicating whether the node was useful, duplicate, or invalid.
|
||||
*
|
||||
* @note This function expects that the caller has already validated that the nodeID is
|
||||
* consistent with the node's content.
|
||||
*/
|
||||
addRootNode(SHAMapHash const& hash, Slice const& rootNode, SHAMapSyncFilter* filter);
|
||||
SHAMapAddNode
|
||||
addKnownNode(
|
||||
SHAMapNodeID const& nodeID,
|
||||
intr_ptr::SharedPtr<SHAMapTreeNode> treeNode,
|
||||
SHAMapSyncFilter const* filter);
|
||||
addKnownNode(SHAMapNodeID const& nodeID, Slice const& rawNode, SHAMapSyncFilter* filter);
|
||||
|
||||
// status functions
|
||||
void
|
||||
@@ -380,11 +344,11 @@ private:
|
||||
intr_ptr::SharedPtr<SHAMapTreeNode>
|
||||
fetchNodeNT(SHAMapHash const& hash) const;
|
||||
intr_ptr::SharedPtr<SHAMapTreeNode>
|
||||
fetchNodeNT(SHAMapHash const& hash, SHAMapSyncFilter const* filter) const;
|
||||
fetchNodeNT(SHAMapHash const& hash, SHAMapSyncFilter* filter) const;
|
||||
intr_ptr::SharedPtr<SHAMapTreeNode>
|
||||
fetchNode(SHAMapHash const& hash) const;
|
||||
intr_ptr::SharedPtr<SHAMapTreeNode>
|
||||
checkFilter(SHAMapHash const& hash, SHAMapSyncFilter const* filter) const;
|
||||
checkFilter(SHAMapHash const& hash, SHAMapSyncFilter* filter) const;
|
||||
|
||||
/** Update hashes up to the root */
|
||||
void
|
||||
@@ -456,7 +420,7 @@ private:
|
||||
descendAsync(
|
||||
SHAMapInnerNode* parent,
|
||||
int branch,
|
||||
SHAMapSyncFilter const* filter,
|
||||
SHAMapSyncFilter* filter,
|
||||
bool& pending,
|
||||
descendCallback&&) const;
|
||||
|
||||
@@ -465,7 +429,7 @@ private:
|
||||
SHAMapInnerNode* parent,
|
||||
SHAMapNodeID const& parentID,
|
||||
int branch,
|
||||
SHAMapSyncFilter const* filter) const;
|
||||
SHAMapSyncFilter* filter) const;
|
||||
|
||||
// Non-storing
|
||||
// Does not hook the returned node to its parent
|
||||
|
||||
@@ -114,7 +114,8 @@ protected:
|
||||
beast::Journal const j_;
|
||||
|
||||
AccountID const account_;
|
||||
XRPAmount preFeeBalance_{}; // Balance before fees.
|
||||
XRPAmount mPriorBalance; // Balance before fees.
|
||||
XRPAmount mSourceBalance; // Balance after fees.
|
||||
|
||||
virtual ~Transactor() = default;
|
||||
Transactor(Transactor const&) = delete;
|
||||
|
||||
@@ -213,7 +213,7 @@ public:
|
||||
, flags(ctx_.flags)
|
||||
, j(ctx_.j)
|
||||
, ter(ter_)
|
||||
, likelyToClaimFee(isTesSuccess(ter) || isTecClaimHardFail(ter, flags))
|
||||
, likelyToClaimFee(ter == tesSUCCESS || isTecClaimHardFail(ter, flags))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -27,33 +27,6 @@ namespace xrpl {
|
||||
* communicate the interface required of any invariant checker. Any invariant
|
||||
* check implementation should implement the public methods documented here.
|
||||
*
|
||||
* ## Rules for implementing `finalize`
|
||||
*
|
||||
* ### Invariants must run regardless of transaction result
|
||||
*
|
||||
* An invariant's `finalize` method MUST perform meaningful checks even when
|
||||
* the transaction has failed (i.e., `!isTesSuccess(tec)`). The following
|
||||
* pattern is almost certainly wrong and must never be used:
|
||||
*
|
||||
* @code
|
||||
* // WRONG: skipping all checks on failure defeats the purpose of invariants
|
||||
* if (!isTesSuccess(tec))
|
||||
* return true;
|
||||
* @endcode
|
||||
*
|
||||
* The entire purpose of invariants is to detect and prevent the impossible.
|
||||
* A bug or exploit could cause a failed transaction to mutate ledger state in
|
||||
* unexpected ways. Invariants are the last line of defense against such
|
||||
* scenarios.
|
||||
*
|
||||
* In general: an invariant that expects a domain-specific state change to
|
||||
* occur (e.g., a new object being created) should only expect that change
|
||||
* when the transaction succeeded. A failed VaultCreate must not have created
|
||||
* a Vault. A failed LoanSet must not have created a Loan.
|
||||
*
|
||||
* Also be aware that failed transactions, regardless of type, carry no
|
||||
* Privileges. Any privilege-gated checks must therefore also be applied to
|
||||
* failed transactions.
|
||||
*/
|
||||
class InvariantChecker_PROTOTYPE
|
||||
{
|
||||
@@ -75,11 +48,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief called after all ledger entries have been visited to determine
|
||||
* the final status of the check.
|
||||
*
|
||||
* This method MUST perform meaningful checks even when `tec` indicates a
|
||||
* failed transaction. See the class-level documentation for the rules
|
||||
* governing how failed transactions must be handled.
|
||||
* the final status of the check
|
||||
*
|
||||
* @param tx the transaction being applied
|
||||
* @param tec the current TER result of the transaction
|
||||
@@ -132,7 +101,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -152,7 +121,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -198,7 +167,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -215,7 +184,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -233,7 +202,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -252,7 +221,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -271,7 +240,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -287,7 +256,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -307,7 +276,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -328,7 +297,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&) const;
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -22,7 +22,7 @@ private:
|
||||
uint256 m_dir;
|
||||
uint256 m_index;
|
||||
std::shared_ptr<SLE> m_entry;
|
||||
Quality m_quality{};
|
||||
Quality m_quality;
|
||||
|
||||
public:
|
||||
/** Create the iterator. */
|
||||
|
||||
@@ -370,7 +370,7 @@ changeSpotPriceQuality(
|
||||
if (!amounts)
|
||||
{
|
||||
JLOG(j.trace()) << "changeSpotPrice calc failed: " << to_string(pool.in) << " "
|
||||
<< to_string(pool.out) << " " << quality << " " << tfee;
|
||||
<< to_string(pool.out) << " " << quality << " " << tfee << std::endl;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -639,9 +639,9 @@ getRoundedAsset(Rules const& rules, STAmount const& balance, A const& frac, IsDe
|
||||
STAmount
|
||||
getRoundedAsset(
|
||||
Rules const& rules,
|
||||
std::function<Number()> const& noRoundCb,
|
||||
std::function<Number()>&& noRoundCb,
|
||||
STAmount const& balance,
|
||||
std::function<Number()> const& productCb,
|
||||
std::function<Number()>&& productCb,
|
||||
IsDeposit isDeposit);
|
||||
|
||||
/** Round AMM deposit/withdrawal LPToken amount. Deposit/withdrawal formulas
|
||||
@@ -672,9 +672,9 @@ getRoundedLPTokens(
|
||||
STAmount
|
||||
getRoundedLPTokens(
|
||||
Rules const& rules,
|
||||
std::function<Number()> const& noRoundCb,
|
||||
std::function<Number()>&& noRoundCb,
|
||||
STAmount const& lptAMMBalance,
|
||||
std::function<Number()> const& productCb,
|
||||
std::function<Number()>&& productCb,
|
||||
IsDeposit isDeposit);
|
||||
|
||||
/* Next two functions adjust asset in/out amount to factor in the adjusted
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/nft.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
@@ -55,7 +54,7 @@ removeToken(
|
||||
ApplyView& view,
|
||||
AccountID const& owner,
|
||||
uint256 const& nftokenID,
|
||||
std::shared_ptr<SLE> const& page);
|
||||
std::shared_ptr<SLE>&& page);
|
||||
|
||||
/** Deletes the given token offer.
|
||||
|
||||
@@ -96,7 +95,7 @@ tokenOfferCreatePreflight(
|
||||
std::uint16_t nftFlags,
|
||||
Rules const& rules,
|
||||
std::optional<AccountID> const& owner = std::nullopt,
|
||||
std::uint32_t txFlags = tfSellNFToken);
|
||||
std::uint32_t txFlags = lsfSellNFToken);
|
||||
|
||||
/** Preclaim checks shared by NFTokenCreateOffer and NFTokenMint */
|
||||
TER
|
||||
@@ -110,7 +109,7 @@ tokenOfferCreatePreclaim(
|
||||
std::uint16_t xferFee,
|
||||
beast::Journal j,
|
||||
std::optional<AccountID> const& owner = std::nullopt,
|
||||
std::uint32_t txFlags = tfSellNFToken);
|
||||
std::uint32_t txFlags = lsfSellNFToken);
|
||||
|
||||
/** doApply implementation shared by NFTokenCreateOffer and NFTokenMint */
|
||||
TER
|
||||
@@ -124,7 +123,7 @@ tokenOfferCreateApply(
|
||||
uint256 const& nftokenID,
|
||||
XRPAmount const& priorBalance,
|
||||
beast::Journal j,
|
||||
std::uint32_t txFlags = tfSellNFToken);
|
||||
std::uint32_t txFlags = lsfSellNFToken);
|
||||
|
||||
TER
|
||||
checkTrustlineAuthorized(
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
# The idea is to empty this file gradually by fixing the underlying issues and removing suppressions.
|
||||
#
|
||||
# ASAN_OPTIONS="print_stacktrace=1:detect_container_overflow=0:suppressions=sanitizers/suppressions/asan.supp:halt_on_error=0"
|
||||
#
|
||||
# The detect_container_overflow=0 option disables false positives from:
|
||||
# - Boost intrusive containers (slist_iterator.hpp, hashtable.hpp, aged_unordered_container.h)
|
||||
# - Boost context/coroutine stack switching (Workers.cpp, thread.h)
|
||||
#
|
||||
# See: https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow
|
||||
|
||||
# Boost
|
||||
interceptor_name:boost/asio
|
||||
|
||||
# Leaks in Doctest tests: xrpl.test.*
|
||||
interceptor_name:src/libxrpl/net/HTTPClient.cpp
|
||||
interceptor_name:src/libxrpl/net/RegisterSSLCerts.cpp
|
||||
interceptor_name:src/tests/libxrpl/net/HTTPClient.cpp
|
||||
interceptor_name:xrpl/net/AutoSocket.h
|
||||
interceptor_name:xrpl/net/HTTPClient.h
|
||||
interceptor_name:xrpl/net/HTTPClientSSLContext.h
|
||||
interceptor_name:xrpl/net/RegisterSSLCerts.h
|
||||
|
||||
# Suppress false positive stack-buffer errors in thread stack allocation
|
||||
# Related to ASan's __asan_handle_no_return warnings (github.com/google/sanitizers/issues/189)
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# The idea is to empty this file gradually by fixing the underlying issues and removing suppresions.
|
||||
|
||||
# Suppress leaks detected by asan in rippled code.
|
||||
leak:src/libxrpl/net/HTTPClient.cpp
|
||||
leak:src/libxrpl/net/RegisterSSLCerts.cpp
|
||||
leak:src/tests/libxrpl/net/HTTPClient.cpp
|
||||
leak:xrpl/net/AutoSocket.h
|
||||
leak:xrpl/net/HTTPClient.h
|
||||
leak:xrpl/net/HTTPClientSSLContext.h
|
||||
leak:xrpl/net/RegisterSSLCerts.h
|
||||
leak:ripple::HTTPClient
|
||||
leak:ripple::HTTPClientImp
|
||||
|
||||
# Suppress leaks detected by asan in boost code.
|
||||
leak:boost::asio
|
||||
leak:boost/asio
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
detect_container_overflow=false
|
||||
detect_stack_use_after_return=false
|
||||
debug=true
|
||||
halt_on_error=false
|
||||
print_stats=true
|
||||
print_cmdline=true
|
||||
use_sigaltstack=0
|
||||
print_stacktrace=1
|
||||
@@ -1 +0,0 @@
|
||||
halt_on_error=false
|
||||
@@ -1,3 +0,0 @@
|
||||
halt_on_error=false
|
||||
verbosity=1
|
||||
second_deadlock_stack=1
|
||||
@@ -1 +0,0 @@
|
||||
halt_on_error=false
|
||||
@@ -27,11 +27,3 @@ src:core/JobQueue.cpp
|
||||
src:libxrpl/beast/utility/beast_Journal.cpp
|
||||
src:test/beast/beast_PropertyStream_test.cpp
|
||||
src:src/test/app/Invariants_test.cpp
|
||||
|
||||
# ASan false positive: stack-use-after-scope in ErrorCodes.h inline functions.
|
||||
# When Clang inlines the StaticString overloads (e.g. invalid_field_error(StaticString)),
|
||||
# ASan scope-poisons the temporary std::string before the inlined callee finishes reading
|
||||
# through the const ref. This corrupts the coroutine stack and crashes the Simulate test.
|
||||
# See asan.supp comments for full explanation and planned fix.
|
||||
[address]
|
||||
src:*ErrorCodes.h
|
||||
|
||||
@@ -182,17 +182,6 @@ signed-integer-overflow:src/test/beast/LexicalCast_test.cpp
|
||||
# External library suppressions
|
||||
unsigned-integer-overflow:nudb/detail/xxhash.hpp
|
||||
|
||||
# Loan_test.cpp intentional underflow in test arithmetic
|
||||
unsigned-integer-overflow:src/test/app/Loan_test.cpp
|
||||
undefined:src/test/app/Loan_test.cpp
|
||||
|
||||
# Source tree restructured paths (libxrpl/tx/transactors/)
|
||||
# These duplicate the xrpld/app/tx/detail entries above for the new layout
|
||||
unsigned-integer-overflow:src/libxrpl/tx/transactors/oracle/SetOracle.cpp
|
||||
undefined:src/libxrpl/tx/transactors/oracle/SetOracle.cpp
|
||||
unsigned-integer-overflow:src/libxrpl/tx/transactors/nft/NFTokenMint.cpp
|
||||
undefined:src/libxrpl/tx/transactors/nft/NFTokenMint.cpp
|
||||
|
||||
# Protobuf intentional overflows in hash functions
|
||||
# Protobuf uses intentional unsigned overflow for hash computation (stringpiece.h:393)
|
||||
unsigned-integer-overflow:google/protobuf/stubs/stringpiece.h
|
||||
|
||||
@@ -51,8 +51,8 @@ extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const&
|
||||
if (archive_write_disk_set_standard_lookup(aw.get()) < ARCHIVE_OK)
|
||||
Throw<std::runtime_error>(archive_error_string(aw.get()));
|
||||
|
||||
int result = 0;
|
||||
struct archive_entry* entry = nullptr;
|
||||
int result;
|
||||
struct archive_entry* entry;
|
||||
while (true)
|
||||
{
|
||||
result = archive_read_next_header(ar.get(), &entry);
|
||||
@@ -67,9 +67,9 @@ extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const&
|
||||
|
||||
if (archive_entry_size(entry) > 0)
|
||||
{
|
||||
void const* buf = nullptr;
|
||||
size_t sz = 0;
|
||||
la_int64_t offset = 0;
|
||||
void const* buf;
|
||||
size_t sz;
|
||||
la_int64_t offset;
|
||||
while (true)
|
||||
{
|
||||
result = archive_read_data_block(ar.get(), &buf, &sz, &offset);
|
||||
|
||||
@@ -55,7 +55,7 @@ Section::append(std::vector<std::string> const& lines)
|
||||
val = "";
|
||||
break;
|
||||
}
|
||||
if (val.at(comment - 1) == '\\')
|
||||
else if (val.at(comment - 1) == '\\')
|
||||
{
|
||||
// we have an escaped comment char. Erase the escape char
|
||||
// and keep looking
|
||||
@@ -83,13 +83,9 @@ Section::append(std::vector<std::string> const& lines)
|
||||
|
||||
boost::smatch match;
|
||||
if (boost::regex_match(line, match, re1))
|
||||
{
|
||||
set(match[1], match[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
values_.push_back(line);
|
||||
}
|
||||
|
||||
lines_.push_back(std::move(line));
|
||||
}
|
||||
|
||||
@@ -417,13 +417,9 @@ public:
|
||||
swap(holder_, sink);
|
||||
|
||||
if (holder_)
|
||||
{
|
||||
sink_ = *holder_;
|
||||
}
|
||||
else
|
||||
{
|
||||
sink_ = beast::Journal::getNullSink();
|
||||
}
|
||||
|
||||
return sink;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ parseStatmRSSkB(std::string const& statm)
|
||||
// /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);
|
||||
long size = 0, resident = 0;
|
||||
long size, resident;
|
||||
if (!(iss >> size >> resident))
|
||||
return -1;
|
||||
|
||||
|
||||
@@ -66,12 +66,14 @@ concept UnsignedMantissa = std::is_unsigned_v<T> || std::is_same_v<T, uint128_t>
|
||||
|
||||
class Number::Guard
|
||||
{
|
||||
std::uint64_t digits_{0}; // 16 decimal guard digits
|
||||
std::uint8_t xbit_ : 1 {0}; // has a non-zero digit been shifted off the end
|
||||
std::uint8_t sbit_ : 1 {0}; // the sign of the guard digits
|
||||
std::uint64_t digits_; // 16 decimal guard digits
|
||||
std::uint8_t xbit_ : 1; // has a non-zero digit been shifted off the end
|
||||
std::uint8_t sbit_ : 1; // the sign of the guard digits
|
||||
|
||||
public:
|
||||
explicit Guard() = default;
|
||||
explicit Guard() : digits_{0}, xbit_{0}, sbit_{0}
|
||||
{
|
||||
}
|
||||
|
||||
// set & test the sign bit
|
||||
void
|
||||
@@ -94,7 +96,7 @@ public:
|
||||
// This enables the client to round towards nearest, and on
|
||||
// tie, round towards even.
|
||||
int
|
||||
round() const noexcept;
|
||||
round() noexcept;
|
||||
|
||||
// Modify the result to the correctly rounded value
|
||||
template <UnsignedMantissa T>
|
||||
@@ -114,7 +116,7 @@ public:
|
||||
|
||||
// Modify the result to the correctly rounded value
|
||||
void
|
||||
doRound(rep& drops, std::string location) const;
|
||||
doRound(rep& drops, std::string location);
|
||||
|
||||
private:
|
||||
void
|
||||
@@ -171,7 +173,7 @@ Number::Guard::pop() noexcept
|
||||
// 0 if Guard is exactly half
|
||||
// 1 if Guard is greater than half
|
||||
int
|
||||
Number::Guard::round() const noexcept
|
||||
Number::Guard::round() noexcept
|
||||
{
|
||||
auto mode = Number::getround();
|
||||
|
||||
@@ -256,7 +258,7 @@ Number::Guard::doRoundUp(
|
||||
}
|
||||
bringIntoRange(negative, mantissa, exponent, minMantissa);
|
||||
if (exponent > maxExponent)
|
||||
Throw<std::overflow_error>(std::string(location));
|
||||
throw std::overflow_error(location);
|
||||
}
|
||||
|
||||
template <UnsignedMantissa T>
|
||||
@@ -282,7 +284,7 @@ Number::Guard::doRoundDown(
|
||||
|
||||
// Modify the result to the correctly rounded value
|
||||
void
|
||||
Number::Guard::doRound(rep& drops, std::string location) const
|
||||
Number::Guard::doRound(rep& drops, std::string location)
|
||||
{
|
||||
auto r = round();
|
||||
if (r == 1 || (r == 0 && (drops & 1) == 1))
|
||||
@@ -296,7 +298,7 @@ Number::Guard::doRound(rep& drops, std::string location) const
|
||||
// or "(maxRep + 1) / 10", neither of which will round up when
|
||||
// converting to rep, though the latter might overflow _before_
|
||||
// rounding.
|
||||
Throw<std::overflow_error>(std::string(location)); // LCOV_EXCL_LINE
|
||||
throw std::overflow_error(location); // LCOV_EXCL_LINE
|
||||
}
|
||||
++drops;
|
||||
}
|
||||
@@ -911,13 +913,9 @@ to_string(Number const& amount)
|
||||
|
||||
// Assemble the output:
|
||||
if (pre_from == pre_to)
|
||||
{
|
||||
ret.append(1, '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.append(pre_from, pre_to);
|
||||
}
|
||||
|
||||
if (post_to != post_from)
|
||||
{
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace xrpl {
|
||||
template <class Derived>
|
||||
class AsyncObject
|
||||
{
|
||||
protected:
|
||||
AsyncObject() : m_pending(0)
|
||||
{
|
||||
}
|
||||
@@ -92,8 +93,6 @@ public:
|
||||
private:
|
||||
// The number of handlers pending.
|
||||
std::atomic<int> m_pending;
|
||||
|
||||
friend Derived;
|
||||
};
|
||||
|
||||
class ResolverAsioImpl : public ResolverAsio, public AsyncObject<ResolverAsioImpl>
|
||||
@@ -109,7 +108,7 @@ public:
|
||||
|
||||
std::condition_variable m_cv;
|
||||
std::mutex m_mut;
|
||||
bool m_asyncHandlersCompleted{true};
|
||||
bool m_asyncHandlersCompleted;
|
||||
|
||||
std::atomic<bool> m_stop_called;
|
||||
std::atomic<bool> m_stopped;
|
||||
@@ -136,6 +135,7 @@ public:
|
||||
, m_io_context(io_context)
|
||||
, m_strand(boost::asio::make_strand(io_context))
|
||||
, m_resolver(io_context)
|
||||
, m_asyncHandlersCompleted(true)
|
||||
, m_stop_called(false)
|
||||
, m_stopped(true)
|
||||
{
|
||||
@@ -374,7 +374,7 @@ public:
|
||||
JLOG(m_journal.debug()) << "Queued new job with " << names.size() << " tasks. "
|
||||
<< m_work.size() << " jobs outstanding.";
|
||||
|
||||
if (!m_work.empty())
|
||||
if (m_work.size() > 0)
|
||||
{
|
||||
boost::asio::post(
|
||||
m_io_context,
|
||||
|
||||
@@ -103,7 +103,7 @@ trim_whitespace(std::string str)
|
||||
std::optional<std::uint64_t>
|
||||
to_uint64(std::string const& s)
|
||||
{
|
||||
std::uint64_t result = 0;
|
||||
std::uint64_t result;
|
||||
if (beast::lexicalCastChecked(result, s))
|
||||
return result;
|
||||
return std::nullopt;
|
||||
|
||||
@@ -77,13 +77,13 @@ get_inverse()
|
||||
}
|
||||
|
||||
/// Returns max chars needed to encode a base64 string
|
||||
std::size_t constexpr encoded_size(std::size_t n)
|
||||
inline std::size_t constexpr encoded_size(std::size_t n)
|
||||
{
|
||||
return 4 * ((n + 2) / 3);
|
||||
}
|
||||
|
||||
/// Returns max bytes needed to decode a base64 string
|
||||
std::size_t constexpr decoded_size(std::size_t n)
|
||||
inline std::size_t constexpr decoded_size(std::size_t n)
|
||||
{
|
||||
return ((n / 4) * 3) + 2;
|
||||
}
|
||||
@@ -116,7 +116,6 @@ encode(void* dest, void const* src, std::size_t len)
|
||||
in += 3;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-switch-missing-default-case)
|
||||
switch (len % 3)
|
||||
{
|
||||
case 2:
|
||||
|
||||
@@ -239,7 +239,6 @@ initAuthenticated(
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unused-return-value)
|
||||
context.use_certificate_file(cert_file, boost::asio::ssl::context::pem, ec);
|
||||
|
||||
if (ec)
|
||||
@@ -272,11 +271,9 @@ initAuthenticated(
|
||||
if (!cert_set)
|
||||
{
|
||||
if (SSL_CTX_use_certificate(ssl, x) != 1)
|
||||
{
|
||||
LogicError(
|
||||
"Problem retrieving SSL certificate from chain "
|
||||
"file.");
|
||||
}
|
||||
|
||||
cert_set = true;
|
||||
}
|
||||
@@ -301,7 +298,6 @@ initAuthenticated(
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unused-return-value)
|
||||
context.use_private_key_file(key_file, boost::asio::ssl::context::pem, ec);
|
||||
|
||||
if (ec)
|
||||
|
||||
@@ -16,7 +16,7 @@ class seconds_clock_thread
|
||||
{
|
||||
using Clock = basic_seconds_clock::Clock;
|
||||
|
||||
bool stop_{false};
|
||||
bool stop_;
|
||||
std::mutex mut_;
|
||||
std::condition_variable cv_;
|
||||
std::thread thread_;
|
||||
@@ -48,7 +48,8 @@ seconds_clock_thread::~seconds_clock_thread()
|
||||
thread_.join();
|
||||
}
|
||||
|
||||
seconds_clock_thread::seconds_clock_thread() : tp_{Clock::now().time_since_epoch().count()}
|
||||
seconds_clock_thread::seconds_clock_thread()
|
||||
: stop_{false}, tp_{Clock::now().time_since_epoch().count()}
|
||||
{
|
||||
thread_ = std::thread(&seconds_clock_thread::run, this);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ print_identifiers(SemanticVersion::identifier_list const& list)
|
||||
bool
|
||||
isNumeric(std::string const& s)
|
||||
{
|
||||
int n = 0;
|
||||
int n;
|
||||
|
||||
// Must be convertible to an integer
|
||||
if (!lexicalCastChecked(n, s))
|
||||
@@ -68,7 +68,7 @@ chopUInt(int& value, int limit, std::string& input)
|
||||
if (item.empty())
|
||||
return false;
|
||||
|
||||
int n = 0;
|
||||
int n;
|
||||
|
||||
// Must be convertible to an integer
|
||||
if (!lexicalCastChecked(n, item))
|
||||
@@ -234,43 +234,27 @@ int
|
||||
compare(SemanticVersion const& lhs, SemanticVersion const& rhs)
|
||||
{
|
||||
if (lhs.majorVersion > rhs.majorVersion)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (lhs.majorVersion < rhs.majorVersion)
|
||||
{
|
||||
else if (lhs.majorVersion < rhs.majorVersion)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lhs.minorVersion > rhs.minorVersion)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (lhs.minorVersion < rhs.minorVersion)
|
||||
{
|
||||
else if (lhs.minorVersion < rhs.minorVersion)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lhs.patchVersion > rhs.patchVersion)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (lhs.patchVersion < rhs.patchVersion)
|
||||
{
|
||||
else if (lhs.patchVersion < rhs.patchVersion)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lhs.isPreRelease() || rhs.isPreRelease())
|
||||
{
|
||||
// Pre-releases have a lower precedence
|
||||
if (lhs.isRelease() && rhs.isPreRelease())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (lhs.isPreRelease() && rhs.isRelease())
|
||||
{
|
||||
else if (lhs.isPreRelease() && rhs.isRelease())
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Compare pre-release identifiers
|
||||
for (int i = 0;
|
||||
@@ -279,26 +263,18 @@ compare(SemanticVersion const& lhs, SemanticVersion const& rhs)
|
||||
{
|
||||
// A larger list of identifiers has a higher precedence
|
||||
if (i >= rhs.preReleaseIdentifiers.size())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (i >= lhs.preReleaseIdentifiers.size())
|
||||
{
|
||||
else if (i >= lhs.preReleaseIdentifiers.size())
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string const& left(lhs.preReleaseIdentifiers[i]);
|
||||
std::string const& right(rhs.preReleaseIdentifiers[i]);
|
||||
|
||||
// Numeric identifiers have lower precedence
|
||||
if (!isNumeric(left) && isNumeric(right))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (isNumeric(left) && !isNumeric(right))
|
||||
{
|
||||
else if (isNumeric(left) && !isNumeric(right))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (isNumeric(left))
|
||||
{
|
||||
@@ -308,13 +284,9 @@ compare(SemanticVersion const& lhs, SemanticVersion const& rhs)
|
||||
int const iRight(lexicalCastThrow<int>(right));
|
||||
|
||||
if (iLeft > iRight)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (iLeft < iRight)
|
||||
{
|
||||
else if (iLeft < iRight)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -104,8 +104,8 @@ private:
|
||||
|
||||
std::shared_ptr<StatsDCollectorImp> m_impl;
|
||||
std::string m_name;
|
||||
CounterImpl::value_type m_value{0};
|
||||
bool m_dirty{false};
|
||||
CounterImpl::value_type m_value;
|
||||
bool m_dirty;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -162,9 +162,9 @@ private:
|
||||
|
||||
std::shared_ptr<StatsDCollectorImp> m_impl;
|
||||
std::string m_name;
|
||||
GaugeImpl::value_type m_last_value{0};
|
||||
GaugeImpl::value_type m_value{0};
|
||||
bool m_dirty{false};
|
||||
GaugeImpl::value_type m_last_value;
|
||||
GaugeImpl::value_type m_value;
|
||||
bool m_dirty;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -194,8 +194,8 @@ private:
|
||||
|
||||
std::shared_ptr<StatsDCollectorImp> m_impl;
|
||||
std::string m_name;
|
||||
MeterImpl::value_type m_value{0};
|
||||
bool m_dirty{false};
|
||||
MeterImpl::value_type m_value;
|
||||
bool m_dirty;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -470,7 +470,6 @@ public:
|
||||
|
||||
m_io_context.run();
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unused-return-value)
|
||||
m_socket.shutdown(boost::asio::ip::udp::socket::shutdown_send, ec);
|
||||
|
||||
m_socket.close();
|
||||
@@ -505,7 +504,7 @@ StatsDHookImpl::do_process()
|
||||
StatsDCounterImpl::StatsDCounterImpl(
|
||||
std::string const& name,
|
||||
std::shared_ptr<StatsDCollectorImp> const& impl)
|
||||
: m_impl(impl), m_name(name)
|
||||
: m_impl(impl), m_name(name), m_value(0), m_dirty(false)
|
||||
{
|
||||
m_impl->add(*this);
|
||||
}
|
||||
@@ -587,7 +586,7 @@ StatsDEventImpl::do_notify(EventImpl::value_type const& value)
|
||||
StatsDGaugeImpl::StatsDGaugeImpl(
|
||||
std::string const& name,
|
||||
std::shared_ptr<StatsDCollectorImp> const& impl)
|
||||
: m_impl(impl), m_name(name)
|
||||
: m_impl(impl), m_name(name), m_last_value(0), m_value(0), m_dirty(false)
|
||||
{
|
||||
m_impl->add(*this);
|
||||
}
|
||||
@@ -676,7 +675,7 @@ StatsDGaugeImpl::do_process()
|
||||
StatsDMeterImpl::StatsDMeterImpl(
|
||||
std::string const& name,
|
||||
std::shared_ptr<StatsDCollectorImp> const& impl)
|
||||
: m_impl(impl), m_name(name)
|
||||
: m_impl(impl), m_name(name), m_value(0), m_dirty(false)
|
||||
{
|
||||
m_impl->add(*this);
|
||||
}
|
||||
|
||||
@@ -95,14 +95,10 @@ operator>>(std::istream& is, Endpoint& endpoint)
|
||||
char i{0};
|
||||
char readTo{0};
|
||||
is.get(i);
|
||||
if (i == '[')
|
||||
{ // we are an IPv6 endpoint
|
||||
if (i == '[') // we are an IPv6 endpoint
|
||||
readTo = ']';
|
||||
}
|
||||
else
|
||||
{
|
||||
addrStr += i;
|
||||
}
|
||||
|
||||
while (is && is.rdbuf()->in_avail() > 0 && is.get(i))
|
||||
{
|
||||
@@ -163,16 +159,14 @@ operator>>(std::istream& is, Endpoint& endpoint)
|
||||
|
||||
if (is.rdbuf()->in_avail() > 0)
|
||||
{
|
||||
Port port = 0;
|
||||
Port port;
|
||||
is >> port;
|
||||
if (is.fail())
|
||||
return is;
|
||||
endpoint = Endpoint(addr, port);
|
||||
}
|
||||
else
|
||||
{
|
||||
endpoint = Endpoint(addr);
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
@@ -124,13 +124,9 @@ Journal::ScopedStream::~ScopedStream()
|
||||
if (!s.empty())
|
||||
{
|
||||
if (s == "\n")
|
||||
{
|
||||
m_sink.write(m_level, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sink.write(m_level, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace beast {
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
PropertyStream::Item::Item(Source* source) : ListNode(), m_source(source)
|
||||
PropertyStream::Item::Item(Source* source) : m_source(source)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -237,13 +237,9 @@ PropertyStream::Source::write(PropertyStream& stream, std::string const& path)
|
||||
return;
|
||||
|
||||
if (result.second)
|
||||
{
|
||||
result.first->write(stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.first->write_one(stream);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<PropertyStream::Source*, bool>
|
||||
@@ -305,13 +301,9 @@ PropertyStream::Source::peel_name(std::string* path)
|
||||
std::string s(first, pos);
|
||||
|
||||
if (pos != last)
|
||||
{
|
||||
*path = std::string(pos + 1, last);
|
||||
}
|
||||
else
|
||||
{
|
||||
*path = std::string();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -379,13 +371,9 @@ void
|
||||
PropertyStream::add(std::string const& key, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
add(key, "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
add(key, "false");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -476,13 +464,9 @@ void
|
||||
PropertyStream::add(bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
add("true");
|
||||
}
|
||||
else
|
||||
{
|
||||
add("false");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -331,7 +331,7 @@ JobQueue::finishJob(JobType type)
|
||||
void
|
||||
JobQueue::processTask(int instance)
|
||||
{
|
||||
JobType type = jtINVALID;
|
||||
JobType type;
|
||||
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
@@ -205,9 +205,11 @@ Workers::Worker::run()
|
||||
// We got paused
|
||||
break;
|
||||
}
|
||||
|
||||
// Undo our decrement
|
||||
++m_workers.m_pauseCount;
|
||||
else
|
||||
{
|
||||
// Undo our decrement
|
||||
++m_workers.m_pauseCount;
|
||||
}
|
||||
}
|
||||
|
||||
// We couldn't pause so we must have gotten
|
||||
|
||||
@@ -198,10 +198,10 @@ char const* RFC1751::s_dictionary[2048] = {
|
||||
unsigned long
|
||||
RFC1751::extract(char const* s, int start, int length)
|
||||
{
|
||||
unsigned char cl = 0;
|
||||
unsigned char cc = 0;
|
||||
unsigned char cr = 0;
|
||||
unsigned long x = 0;
|
||||
unsigned char cl;
|
||||
unsigned char cc;
|
||||
unsigned char cr;
|
||||
unsigned long x;
|
||||
|
||||
XRPL_ASSERT(length <= 11, "xrpl::RFC1751::extract : maximum length");
|
||||
XRPL_ASSERT(start >= 0, "xrpl::RFC1751::extract : minimum start");
|
||||
@@ -226,7 +226,7 @@ void
|
||||
RFC1751::btoe(std::string& strHuman, std::string const& strData)
|
||||
{
|
||||
char caBuffer[9]; /* add in room for the parity 2 bits*/
|
||||
int p = 0, i = 0;
|
||||
int p, i;
|
||||
|
||||
memcpy(caBuffer, strData.c_str(), 8);
|
||||
|
||||
@@ -245,11 +245,11 @@ RFC1751::btoe(std::string& strHuman, std::string const& strData)
|
||||
void
|
||||
RFC1751::insert(char* s, int x, int start, int length)
|
||||
{
|
||||
unsigned char cl = 0;
|
||||
unsigned char cc = 0;
|
||||
unsigned char cr = 0;
|
||||
unsigned long y = 0;
|
||||
int shift = 0;
|
||||
unsigned char cl;
|
||||
unsigned char cc;
|
||||
unsigned char cr;
|
||||
unsigned long y;
|
||||
int shift;
|
||||
|
||||
XRPL_ASSERT(length <= 11, "xrpl::RFC1751::insert : maximum length");
|
||||
XRPL_ASSERT(start >= 0, "xrpl::RFC1751::insert : minimum start");
|
||||
@@ -285,21 +285,13 @@ RFC1751::standard(std::string& strWord)
|
||||
for (auto& letter : strWord)
|
||||
{
|
||||
if (islower(static_cast<unsigned char>(letter)))
|
||||
{
|
||||
letter = toupper(static_cast<unsigned char>(letter));
|
||||
}
|
||||
else if (letter == '1')
|
||||
{
|
||||
letter = 'L';
|
||||
}
|
||||
else if (letter == '0')
|
||||
{
|
||||
letter = 'O';
|
||||
}
|
||||
else if (letter == '5')
|
||||
{
|
||||
letter = 'S';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +336,7 @@ RFC1751::etob(std::string& strData, std::vector<std::string> vsHuman)
|
||||
if (6 != vsHuman.size())
|
||||
return -1;
|
||||
|
||||
int i = 0, p = 0;
|
||||
int i, p = 0;
|
||||
char b[9] = {0};
|
||||
|
||||
for (auto& strWord : vsHuman)
|
||||
|
||||
@@ -30,7 +30,7 @@ csprng_engine::~csprng_engine()
|
||||
void
|
||||
csprng_engine::mix_entropy(void* buffer, std::size_t count)
|
||||
{
|
||||
std::array<std::random_device::result_type, 128> entropy{};
|
||||
std::array<std::random_device::result_type, 128> entropy;
|
||||
|
||||
{
|
||||
// On every platform we support, std::random_device
|
||||
@@ -71,7 +71,7 @@ csprng_engine::operator()(void* ptr, std::size_t count)
|
||||
csprng_engine::result_type
|
||||
csprng_engine::operator()()
|
||||
{
|
||||
result_type ret = 0;
|
||||
result_type ret;
|
||||
(*this)(&ret, sizeof(result_type));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ std::map<char, char const*> jsonSpecialCharacterEscape = {
|
||||
{'\r', "\\r"},
|
||||
{'\t', "\\t"}};
|
||||
|
||||
size_t const jsonEscapeLength = 2;
|
||||
static size_t const jsonEscapeLength = 2;
|
||||
|
||||
// All other JSON punctuation.
|
||||
char const closeBrace = '}';
|
||||
@@ -36,7 +36,7 @@ char const openBrace = '{';
|
||||
char const openBracket = '[';
|
||||
char const quote = '"';
|
||||
|
||||
auto const integralFloatsBecomeInts = false;
|
||||
static auto const integralFloatsBecomeInts = false;
|
||||
|
||||
size_t
|
||||
lengthWithoutTrailingZeros(std::string const& s)
|
||||
@@ -137,13 +137,9 @@ public:
|
||||
check(false, "Not an " + ((type == array ? "array: " : "object: ") + message));
|
||||
}
|
||||
if (stack_.top().isFirst)
|
||||
{
|
||||
stack_.top().isFirst = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
output_({&comma, 1});
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -200,7 +196,7 @@ private:
|
||||
explicit Collection() = default;
|
||||
|
||||
/** What type of collection are we in? */
|
||||
Writer::CollectionType type = Writer::CollectionType::array;
|
||||
Writer::CollectionType type;
|
||||
|
||||
/** Is this the first entry in a collection?
|
||||
* If false, we have to emit a , before we write the next entry. */
|
||||
|
||||
@@ -94,7 +94,7 @@ Reader::parse(char const* beginDoc, char const* endDoc, Value& root)
|
||||
|
||||
nodes_.push(&root);
|
||||
bool successful = readValue(0);
|
||||
Token token{};
|
||||
Token token;
|
||||
skipCommentTokens(token);
|
||||
|
||||
if (!root.isNull() && !root.isArray() && !root.isObject())
|
||||
@@ -114,7 +114,7 @@ Reader::parse(char const* beginDoc, char const* endDoc, Value& root)
|
||||
bool
|
||||
Reader::readValue(unsigned depth)
|
||||
{
|
||||
Token token{};
|
||||
Token token;
|
||||
skipCommentTokens(token);
|
||||
if (depth > nest_limit)
|
||||
return addError("Syntax error: maximum nesting depth exceeded", token);
|
||||
@@ -278,13 +278,9 @@ Reader::skipSpaces()
|
||||
Char c = *current_;
|
||||
|
||||
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
|
||||
{
|
||||
++current_;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,10 +293,8 @@ Reader::match(Location pattern, int patternLength)
|
||||
int index = patternLength;
|
||||
|
||||
while (index--)
|
||||
{
|
||||
if (current_[index] != pattern[index])
|
||||
return false;
|
||||
}
|
||||
|
||||
current_ += patternLength;
|
||||
return true;
|
||||
@@ -390,13 +384,9 @@ Reader::readString()
|
||||
c = getNextChar();
|
||||
|
||||
if (c == '\\')
|
||||
{
|
||||
getNextChar();
|
||||
}
|
||||
else if (c == '"')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return c == '"';
|
||||
@@ -405,7 +395,7 @@ Reader::readString()
|
||||
bool
|
||||
Reader::readObject(Token& tokenStart, unsigned depth)
|
||||
{
|
||||
Token tokenName{};
|
||||
Token tokenName;
|
||||
std::string name;
|
||||
currentValue() = Value(objectValue);
|
||||
|
||||
@@ -430,7 +420,7 @@ Reader::readObject(Token& tokenStart, unsigned depth)
|
||||
if (!decodeString(tokenName, name))
|
||||
return recoverFromError(tokenObjectEnd);
|
||||
|
||||
Token colon{};
|
||||
Token colon;
|
||||
|
||||
if (!readToken(colon) || colon.type_ != tokenMemberSeparator)
|
||||
{
|
||||
@@ -450,7 +440,7 @@ Reader::readObject(Token& tokenStart, unsigned depth)
|
||||
if (!ok) // error already set
|
||||
return recoverFromError(tokenObjectEnd);
|
||||
|
||||
Token comma{};
|
||||
Token comma;
|
||||
|
||||
if (!readToken(comma) ||
|
||||
(comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
|
||||
@@ -480,7 +470,7 @@ Reader::readArray(Token& tokenStart, unsigned depth)
|
||||
|
||||
if (*current_ == ']') // empty array
|
||||
{
|
||||
Token endArray{};
|
||||
Token endArray;
|
||||
readToken(endArray);
|
||||
return true;
|
||||
}
|
||||
@@ -497,7 +487,7 @@ Reader::readArray(Token& tokenStart, unsigned depth)
|
||||
if (!ok) // error already set
|
||||
return recoverFromError(tokenArrayEnd);
|
||||
|
||||
Token token{};
|
||||
Token token;
|
||||
// Accept Comment after last item in the array.
|
||||
ok = readToken(token);
|
||||
|
||||
@@ -588,13 +578,9 @@ Reader::decodeNumber(Token& token)
|
||||
|
||||
// If it's representable as a signed integer, construct it as one.
|
||||
if (value <= Value::maxInt)
|
||||
{
|
||||
currentValue() = static_cast<Value::Int>(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentValue() = static_cast<Value::UInt>(value);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -605,7 +591,7 @@ Reader::decodeDouble(Token& token)
|
||||
{
|
||||
double value = 0;
|
||||
int const bufferSize = 32;
|
||||
int count = 0;
|
||||
int count;
|
||||
int length = int(token.end_ - token.start_);
|
||||
// Sanity check to avoid buffer overflow exploits.
|
||||
if (length < 0)
|
||||
@@ -660,10 +646,8 @@ Reader::decodeString(Token& token, std::string& decoded)
|
||||
Char c = *current++;
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (c == '\\')
|
||||
else if (c == '\\')
|
||||
{
|
||||
if (current == end)
|
||||
return addError("Empty escape sequence in string", token, current);
|
||||
@@ -705,7 +689,7 @@ Reader::decodeString(Token& token, std::string& decoded)
|
||||
break;
|
||||
|
||||
case 'u': {
|
||||
unsigned int unicode = 0;
|
||||
unsigned int unicode;
|
||||
|
||||
if (!decodeUnicodeCodePoint(token, current, end, unicode))
|
||||
return false;
|
||||
@@ -737,23 +721,19 @@ Reader::decodeUnicodeCodePoint(Token& token, Location& current, Location end, un
|
||||
{
|
||||
// surrogate pairs
|
||||
if (end - current < 6)
|
||||
{
|
||||
return addError(
|
||||
"additional six characters expected to parse unicode surrogate "
|
||||
"pair.",
|
||||
token,
|
||||
current);
|
||||
}
|
||||
|
||||
unsigned int surrogatePair = 0;
|
||||
unsigned int surrogatePair;
|
||||
|
||||
if (*current != '\\' || *(current + 1) != 'u')
|
||||
{
|
||||
return addError(
|
||||
"expecting another \\u token to begin the second half of a unicode surrogate pair",
|
||||
token,
|
||||
current);
|
||||
}
|
||||
|
||||
current += 2; // skip two characters checked above
|
||||
|
||||
@@ -774,10 +754,8 @@ Reader::decodeUnicodeEscapeSequence(
|
||||
unsigned int& unicode)
|
||||
{
|
||||
if (end - current < 4)
|
||||
{
|
||||
return addError(
|
||||
"Bad unicode escape sequence in string: four digits expected.", token, current);
|
||||
}
|
||||
|
||||
unicode = 0;
|
||||
|
||||
@@ -787,25 +765,17 @@ Reader::decodeUnicodeEscapeSequence(
|
||||
unicode *= 16;
|
||||
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
unicode += c - '0';
|
||||
}
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
{
|
||||
unicode += c - 'a' + 10;
|
||||
}
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
{
|
||||
unicode += c - 'A' + 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
return addError(
|
||||
"Bad unicode escape sequence in string: hexadecimal digit "
|
||||
"expected.",
|
||||
token,
|
||||
current);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -826,7 +796,7 @@ bool
|
||||
Reader::recoverFromError(TokenType skipUntilToken)
|
||||
{
|
||||
int errorCount = int(errors_.size());
|
||||
Token skip{};
|
||||
Token skip;
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -897,7 +867,7 @@ Reader::getLocationLineAndColumn(Location location, int& line, int& column) cons
|
||||
std::string
|
||||
Reader::getLocationLineAndColumn(Location location) const
|
||||
{
|
||||
int line = 0, column = 0;
|
||||
int line, column;
|
||||
getLocationLineAndColumn(location, line, column);
|
||||
return "Line " + std::to_string(line) + ", Column " + std::to_string(column);
|
||||
}
|
||||
|
||||
@@ -98,11 +98,8 @@ Value::CZString::CZString(CZString const& other)
|
||||
other.index_ != noDuplication && other.cstr_ != 0
|
||||
? valueAllocator()->makeMemberName(other.cstr_)
|
||||
: other.cstr_)
|
||||
, index_([&]() -> int {
|
||||
if (!other.cstr_)
|
||||
return other.index_;
|
||||
return other.index_ == noDuplication ? noDuplication : duplicate;
|
||||
}())
|
||||
, index_(
|
||||
other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate) : other.index_)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -160,7 +157,7 @@ Value::CZString::isStaticString() const
|
||||
* memset( this, 0, sizeof(Value) )
|
||||
* This optimization is used in ValueInternalMap fast allocator.
|
||||
*/
|
||||
Value::Value(ValueType type) : type_(type)
|
||||
Value::Value(ValueType type) : type_(type), allocated_(0)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@@ -228,7 +225,7 @@ Value::Value(std::string const& value) : type_(stringValue), allocated_(true)
|
||||
valueAllocator()->duplicateStringValue(value.c_str(), (unsigned int)value.length());
|
||||
}
|
||||
|
||||
Value::Value(StaticString const& value) : type_(stringValue)
|
||||
Value::Value(StaticString const& value) : type_(stringValue), allocated_(false)
|
||||
{
|
||||
value_.string_ = const_cast<char*>(value.c_str());
|
||||
}
|
||||
@@ -257,9 +254,7 @@ Value::Value(Value const& other) : type_(other.type_)
|
||||
allocated_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
value_.string_ = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -356,9 +351,7 @@ integerCmp(Int i, UInt ui)
|
||||
return -1;
|
||||
|
||||
// Now we can safely compare.
|
||||
if (i < ui)
|
||||
return -1;
|
||||
return (i == ui) ? 0 : 1;
|
||||
return (i < ui) ? -1 : (i == ui) ? 0 : 1;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -367,13 +360,9 @@ operator<(Value const& x, Value const& y)
|
||||
if (auto signum = x.type_ - y.type_)
|
||||
{
|
||||
if (x.type_ == intValue && y.type_ == uintValue)
|
||||
{
|
||||
signum = integerCmp(x.value_.int_, y.value_.uint_);
|
||||
}
|
||||
else if (x.type_ == uintValue && y.type_ == intValue)
|
||||
{
|
||||
signum = -integerCmp(y.value_.int_, x.value_.uint_);
|
||||
}
|
||||
return signum < 0;
|
||||
}
|
||||
|
||||
@@ -707,7 +696,7 @@ Value::asBool() const
|
||||
|
||||
case arrayValue:
|
||||
case objectValue:
|
||||
return !value_.map_->empty();
|
||||
return value_.map_->size() != 0;
|
||||
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
@@ -754,10 +743,10 @@ Value::isConvertibleTo(ValueType other) const
|
||||
(other == nullValue && (!value_.string_ || value_.string_[0] == 0));
|
||||
|
||||
case arrayValue:
|
||||
return other == arrayValue || (other == nullValue && value_.map_->empty());
|
||||
return other == arrayValue || (other == nullValue && value_.map_->size() == 0);
|
||||
|
||||
case objectValue:
|
||||
return other == objectValue || (other == nullValue && value_.map_->empty());
|
||||
return other == objectValue || (other == nullValue && value_.map_->size() == 0);
|
||||
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Json {
|
||||
// //////////////////////////////////////////////////////////////////
|
||||
// //////////////////////////////////////////////////////////////////
|
||||
|
||||
ValueIteratorBase::ValueIteratorBase() : isNull_(true)
|
||||
ValueIteratorBase::ValueIteratorBase() : current_(), isNull_(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -304,9 +304,7 @@ StyledWriter::writeValue(Value const& value)
|
||||
Value::Members members(value.getMemberNames());
|
||||
|
||||
if (members.empty())
|
||||
{
|
||||
pushValue("{}");
|
||||
}
|
||||
else
|
||||
{
|
||||
writeWithIndent("{");
|
||||
@@ -341,9 +339,7 @@ StyledWriter::writeArrayValue(Value const& value)
|
||||
unsigned size = value.size();
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
pushValue("[]");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isArrayMultiLine = isMultilineArray(value);
|
||||
@@ -360,9 +356,7 @@ StyledWriter::writeArrayValue(Value const& value)
|
||||
Value const& childValue = value[index];
|
||||
|
||||
if (hasChildValue)
|
||||
{
|
||||
writeWithIndent(childValues_[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeIndent();
|
||||
@@ -435,13 +429,9 @@ void
|
||||
StyledWriter::pushValue(std::string const& value)
|
||||
{
|
||||
if (addChildValues_)
|
||||
{
|
||||
childValues_.push_back(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
document_ += value;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -539,9 +529,7 @@ StyledStreamWriter::writeValue(Value const& value)
|
||||
Value::Members members(value.getMemberNames());
|
||||
|
||||
if (members.empty())
|
||||
{
|
||||
pushValue("{}");
|
||||
}
|
||||
else
|
||||
{
|
||||
writeWithIndent("{");
|
||||
@@ -576,9 +564,7 @@ StyledStreamWriter::writeArrayValue(Value const& value)
|
||||
unsigned size = value.size();
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
pushValue("[]");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isArrayMultiLine = isMultilineArray(value);
|
||||
@@ -595,9 +581,7 @@ StyledStreamWriter::writeArrayValue(Value const& value)
|
||||
Value const& childValue = value[index];
|
||||
|
||||
if (hasChildValue)
|
||||
{
|
||||
writeWithIndent(childValues_[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeIndent();
|
||||
@@ -670,13 +654,9 @@ void
|
||||
StyledStreamWriter::pushValue(std::string const& value)
|
||||
{
|
||||
if (addChildValues_)
|
||||
{
|
||||
childValues_.push_back(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
*document_ << value;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -107,7 +107,7 @@ ApplyStateTable::apply(
|
||||
Mods newMod;
|
||||
for (auto& item : items_)
|
||||
{
|
||||
SField const* type = nullptr;
|
||||
SField const* type;
|
||||
switch (item.second.first)
|
||||
{
|
||||
default:
|
||||
@@ -169,11 +169,9 @@ ApplyStateTable::apply(
|
||||
"xrpl::detail::ApplyStateTable::apply : valid nodes for "
|
||||
"modification");
|
||||
|
||||
if (curNode->isThreadedType(to.rules()))
|
||||
{ // thread transaction to node
|
||||
// item modified
|
||||
if (curNode->isThreadedType(to.rules())) // thread transaction to node
|
||||
// item modified
|
||||
threadItem(meta, curNode);
|
||||
}
|
||||
|
||||
STObject prevs(sfPreviousFields);
|
||||
for (auto const& obj : *origNode)
|
||||
@@ -515,7 +513,7 @@ void
|
||||
ApplyStateTable::threadItem(TxMeta& meta, std::shared_ptr<SLE> const& sle)
|
||||
{
|
||||
key_type prevTxID;
|
||||
LedgerIndex prevLgrID = 0;
|
||||
LedgerIndex prevLgrID;
|
||||
|
||||
if (!sle->thread(meta.getTxID(), meta.getLgrSeq(), prevTxID, prevLgrID))
|
||||
return;
|
||||
|
||||
@@ -38,9 +38,7 @@ BookListeners::publish(MultiApiJson const& jvObj, hash_set<std::uint64_t>& haveP
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
it = mListeners.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,17 +40,11 @@ CachedViewImpl::read(Keylet const& k) const
|
||||
// If the sle is null, then a failure must have occurred in base_.read()
|
||||
XRPL_ASSERT(sle || baseRead, "xrpl::CachedView::read : null SLE result from base");
|
||||
if (cacheHit && baseRead)
|
||||
{
|
||||
hitsexpired.increment();
|
||||
}
|
||||
else if (cacheHit)
|
||||
{
|
||||
hits.increment();
|
||||
}
|
||||
else
|
||||
{
|
||||
misses.increment();
|
||||
}
|
||||
|
||||
if (!cacheHit)
|
||||
{
|
||||
|
||||
@@ -186,12 +186,10 @@ validDomain(ReadView const& view, uint256 domainID, AccountID const& subject)
|
||||
foundExpired = true;
|
||||
continue;
|
||||
}
|
||||
if (sleCredential->getFlags() & lsfAccepted)
|
||||
{
|
||||
else if (sleCredential->getFlags() & lsfAccepted)
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
continue;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +197,7 @@ validDomain(ReadView const& view, uint256 domainID, AccountID const& subject)
|
||||
}
|
||||
|
||||
TER
|
||||
authorizedDepositPreauth(ReadView const& view, STVector256 const& credIDs, AccountID const& dst)
|
||||
authorizedDepositPreauth(ApplyView const& view, STVector256 const& credIDs, AccountID const& dst)
|
||||
{
|
||||
std::set<std::pair<AccountID, Slice>> sorted;
|
||||
std::vector<std::shared_ptr<SLE const>> lifeExtender;
|
||||
@@ -320,7 +318,7 @@ verifyDepositPreauth(
|
||||
ApplyView& view,
|
||||
AccountID const& src,
|
||||
AccountID const& dst,
|
||||
std::shared_ptr<SLE const> const& sleDst,
|
||||
std::shared_ptr<SLE> const& sleDst,
|
||||
beast::Journal j)
|
||||
{
|
||||
// If depositPreauth is enabled, then an account that requires
|
||||
@@ -339,11 +337,9 @@ verifyDepositPreauth(
|
||||
if (src != dst)
|
||||
{
|
||||
if (!view.exists(keylet::depositPreauth(dst, src)))
|
||||
{
|
||||
return !credentialsPresent ? tecNO_PERMISSION
|
||||
: credentials::authorizedDepositPreauth(
|
||||
view, tx.getFieldV256(sfCredentialIDs), dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ OpenView::txsEnd() const -> std::unique_ptr<txs_type::iter_base>
|
||||
bool
|
||||
OpenView::txExists(key_type const& key) const
|
||||
{
|
||||
return txs_.contains(key);
|
||||
return txs_.find(key) != txs_.end();
|
||||
}
|
||||
|
||||
auto
|
||||
@@ -198,13 +198,9 @@ OpenView::txRead(key_type const& key) const -> tx_type
|
||||
auto stx = std::make_shared<STTx const>(SerialIter{item.txn->slice()});
|
||||
decltype(tx_type::second) sto;
|
||||
if (item.meta)
|
||||
{
|
||||
sto = std::make_shared<STObject const>(SerialIter{item.meta->slice()}, sfMetadata);
|
||||
}
|
||||
else
|
||||
{
|
||||
sto = nullptr;
|
||||
}
|
||||
return {std::move(stx), std::move(sto)};
|
||||
}
|
||||
|
||||
|
||||
@@ -11,11 +11,9 @@ auto
|
||||
DeferredCredits::makeKey(AccountID const& a1, AccountID const& a2, Currency const& c) -> Key
|
||||
{
|
||||
if (a1 < a2)
|
||||
{
|
||||
return std::make_tuple(a1, a2, c);
|
||||
}
|
||||
|
||||
return std::make_tuple(a2, a1, c);
|
||||
else
|
||||
return std::make_tuple(a2, a1, c);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -55,13 +53,9 @@ DeferredCredits::credit(
|
||||
// only record the balance the first time, do not record it here
|
||||
auto& v = i->second;
|
||||
if (sender < receiver)
|
||||
{
|
||||
v.highAcctCredits += amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
v.lowAcctCredits += amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,9 +101,11 @@ DeferredCredits::adjustments(
|
||||
result.emplace(v.highAcctCredits, v.lowAcctCredits, v.lowAcctOrigBalance);
|
||||
return result;
|
||||
}
|
||||
|
||||
result.emplace(v.lowAcctCredits, v.highAcctCredits, -v.lowAcctOrigBalance);
|
||||
return result;
|
||||
else
|
||||
{
|
||||
result.emplace(v.lowAcctCredits, v.highAcctCredits, -v.lowAcctOrigBalance);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -183,13 +179,11 @@ PaymentSandbox::balanceHook(
|
||||
adjustedAmt.setIssuer(amount.getIssuer());
|
||||
|
||||
if (isXRP(issuer) && adjustedAmt < beast::zero)
|
||||
{
|
||||
// A calculated negative XRP balance is not an error case. Consider a
|
||||
// payment snippet that credits a large XRP amount and then debits the
|
||||
// same amount. The credit can't be used but we subtract the debit and
|
||||
// calculate a negative value. It's not an error case.
|
||||
adjustedAmt.clear();
|
||||
}
|
||||
|
||||
return adjustedAmt;
|
||||
}
|
||||
|
||||
@@ -94,13 +94,9 @@ public:
|
||||
dereference() const override
|
||||
{
|
||||
if (!sle1_)
|
||||
{
|
||||
return sle0_;
|
||||
}
|
||||
if (!sle0_)
|
||||
{
|
||||
else if (!sle0_)
|
||||
return sle1_;
|
||||
}
|
||||
if (sle1_->key() <= sle0_->key())
|
||||
return sle1_;
|
||||
return sle0_;
|
||||
@@ -112,13 +108,9 @@ private:
|
||||
{
|
||||
++iter0_;
|
||||
if (iter0_ == end0_)
|
||||
{
|
||||
sle0_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
sle0_ = *iter0_;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -126,13 +118,9 @@ private:
|
||||
{
|
||||
++iter1_;
|
||||
if (iter1_ == end1_)
|
||||
{
|
||||
sle1_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
sle1_ = iter1_->second.sle;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -51,13 +51,9 @@ internalDirNext(
|
||||
}
|
||||
|
||||
if constexpr (std::is_const_v<N>)
|
||||
{
|
||||
page = view.read(keylet::page(root, next));
|
||||
}
|
||||
else
|
||||
{
|
||||
page = view.peek(keylet::page(root, next));
|
||||
}
|
||||
|
||||
XRPL_ASSERT(page, "xrpl::detail::internalDirNext : non-null root");
|
||||
|
||||
@@ -87,13 +83,9 @@ internalDirFirst(
|
||||
uint256& entry)
|
||||
{
|
||||
if constexpr (std::is_const_v<N>)
|
||||
{
|
||||
page = view.read(keylet::page(root));
|
||||
}
|
||||
else
|
||||
{
|
||||
page = view.peek(keylet::page(root));
|
||||
}
|
||||
|
||||
if (!page)
|
||||
return false;
|
||||
@@ -188,13 +180,9 @@ isGlobalFrozen(ReadView const& view, Asset const& asset)
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
{
|
||||
return isGlobalFrozen(view, issue.getIssuer());
|
||||
}
|
||||
else
|
||||
{
|
||||
return isGlobalFrozen(view, issue);
|
||||
}
|
||||
},
|
||||
asset.value());
|
||||
}
|
||||
@@ -393,7 +381,7 @@ getLineIfUsable(
|
||||
{
|
||||
return nullptr; // LCOV_EXCL_LINE
|
||||
}
|
||||
if (sleIssuer->isFieldPresent(sfAMMID))
|
||||
else if (sleIssuer->isFieldPresent(sfAMMID))
|
||||
{
|
||||
auto const sleAmm = view.read(keylet::amm((*sleIssuer)[sfAMMID]));
|
||||
|
||||
@@ -469,11 +457,9 @@ accountHolds(
|
||||
|
||||
bool const returnSpendable = (includeFullBalance == shFULL_BALANCE);
|
||||
if (returnSpendable && account == issuer)
|
||||
{
|
||||
// If the account is the issuer, then their limit is effectively
|
||||
// infinite
|
||||
return STAmount{Issue{currency, issuer}, STAmount::cMaxValue, STAmount::cMaxOffset};
|
||||
}
|
||||
|
||||
// IOU: Return balance on trust line modulo freeze
|
||||
SLE::const_pointer const sle =
|
||||
@@ -528,13 +514,9 @@ accountHolds(
|
||||
auto const sleMpt = view.read(keylet::mptoken(mptIssue.getMptID(), account));
|
||||
|
||||
if (!sleMpt)
|
||||
{
|
||||
amount.clear(mptIssue);
|
||||
}
|
||||
else if (zeroIfFrozen == fhZERO_IF_FROZEN && isFrozen(view, account, mptIssue))
|
||||
{
|
||||
amount.clear(mptIssue);
|
||||
}
|
||||
else
|
||||
{
|
||||
amount = STAmount{mptIssue, sleMpt->getFieldU64(sfMPTAmount)};
|
||||
@@ -769,10 +751,8 @@ forEachItemAfter(
|
||||
if (!ownerDir)
|
||||
return true;
|
||||
for (auto const& key : ownerDir->getFieldV256(sfIndexes))
|
||||
{
|
||||
if (f(view.read(keylet::child(key))) && limit-- <= 1)
|
||||
return true;
|
||||
}
|
||||
auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext);
|
||||
if (uNodeNext == 0)
|
||||
return true;
|
||||
@@ -811,13 +791,9 @@ transferRate(ReadView const& view, STAmount const& amount)
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
{
|
||||
return transferRate(view, issue.getIssuer());
|
||||
}
|
||||
else
|
||||
{
|
||||
return transferRate(view, issue.getMptID());
|
||||
}
|
||||
},
|
||||
amount.asset().value());
|
||||
}
|
||||
@@ -1192,13 +1168,9 @@ canAddHolding(ReadView const& view, Issue const& issue)
|
||||
|
||||
auto const issuer = view.read(keylet::account(issue.getIssuer()));
|
||||
if (!issuer)
|
||||
{
|
||||
return terNO_ACCOUNT;
|
||||
}
|
||||
if (!issuer->isFlag(lsfDefaultRipple))
|
||||
{
|
||||
else if (!issuer->isFlag(lsfDefaultRipple))
|
||||
return terNO_RIPPLE;
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
@@ -1349,7 +1321,7 @@ doWithdraw(
|
||||
}
|
||||
else
|
||||
{
|
||||
auto dstSle = view.read(keylet::account(dstAcct));
|
||||
auto dstSle = view.peek(keylet::account(dstAcct));
|
||||
if (auto err = verifyDepositPreauth(tx, view, senderAcct, dstAcct, dstSle, j))
|
||||
return err;
|
||||
}
|
||||
@@ -1554,15 +1526,11 @@ authorizeMPToken(
|
||||
// Issuer wants to unauthorize the holder, unset lsfMPTAuthorized on
|
||||
// their MPToken
|
||||
if (flags & tfMPTUnauthorize)
|
||||
{
|
||||
flagsOut &= ~lsfMPTAuthorized;
|
||||
}
|
||||
// Issuer wants to authorize a holder, set lsfMPTAuthorized on their
|
||||
// MPToken
|
||||
else
|
||||
{
|
||||
flagsOut |= lsfMPTAuthorized;
|
||||
}
|
||||
|
||||
if (flagsIn != flagsOut)
|
||||
sleMpt->setFieldU32(sfFlags, flagsOut);
|
||||
@@ -2027,7 +1995,7 @@ rippleSendIOU(
|
||||
{
|
||||
// Direct send: redeeming IOUs and/or sending own IOUs.
|
||||
auto const ter = rippleCreditIOU(view, uSenderID, uReceiverID, saAmount, false, j);
|
||||
if (!isTesSuccess(ter))
|
||||
if (ter != tesSUCCESS)
|
||||
return ter;
|
||||
saActual = saAmount;
|
||||
return tesSUCCESS;
|
||||
@@ -2351,13 +2319,15 @@ accountSendMultiIOU(
|
||||
{
|
||||
return TER{tecFAILED_PROCESSING};
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const sndBal = sender->getFieldAmount(sfBalance);
|
||||
view.creditHook(senderID, xrpAccount(), takeFromSender, sndBal);
|
||||
|
||||
auto const sndBal = sender->getFieldAmount(sfBalance);
|
||||
view.creditHook(senderID, xrpAccount(), takeFromSender, sndBal);
|
||||
|
||||
// Decrement XRP balance.
|
||||
sender->setFieldAmount(sfBalance, sndBal - takeFromSender);
|
||||
view.update(sender);
|
||||
// Decrement XRP balance.
|
||||
sender->setFieldAmount(sfBalance, sndBal - takeFromSender);
|
||||
view.update(sender);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto stream = j.trace())
|
||||
@@ -2405,9 +2375,7 @@ rippleCreditMPT(
|
||||
view.update(sle);
|
||||
}
|
||||
else
|
||||
{
|
||||
return tecNO_AUTH;
|
||||
}
|
||||
}
|
||||
|
||||
if (uReceiverID == issuer)
|
||||
@@ -2420,9 +2388,7 @@ rippleCreditMPT(
|
||||
view.update(sleIssuance);
|
||||
}
|
||||
else
|
||||
{
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2433,9 +2399,7 @@ rippleCreditMPT(
|
||||
view.update(sle);
|
||||
}
|
||||
else
|
||||
{
|
||||
return tecNO_AUTH;
|
||||
}
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -2475,7 +2439,7 @@ rippleSendMPT(
|
||||
|
||||
// Direct send: redeeming MPTs and/or sending own MPTs.
|
||||
auto const ter = rippleCreditMPT(view, uSenderID, uReceiverID, saAmount, j);
|
||||
if (!isTesSuccess(ter))
|
||||
if (ter != tesSUCCESS)
|
||||
return ter;
|
||||
saActual = saAmount;
|
||||
return tesSUCCESS;
|
||||
@@ -2491,7 +2455,7 @@ rippleSendMPT(
|
||||
<< " cost=" << saActual.getFullText();
|
||||
|
||||
if (auto const terResult = rippleCreditMPT(view, issuer, uReceiverID, saAmount, j);
|
||||
!isTesSuccess(terResult))
|
||||
terResult != tesSUCCESS)
|
||||
return terResult;
|
||||
|
||||
return rippleCreditMPT(view, uSenderID, issuer, saActual, j);
|
||||
@@ -2635,13 +2599,9 @@ accountSend(
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
{
|
||||
return accountSendIOU(view, uSenderID, uReceiverID, saAmount, j, waiveFee);
|
||||
}
|
||||
else
|
||||
{
|
||||
return accountSendMPT(view, uSenderID, uReceiverID, saAmount, j, waiveFee);
|
||||
}
|
||||
},
|
||||
saAmount.asset().value());
|
||||
}
|
||||
@@ -2660,13 +2620,9 @@ accountSendMulti(
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
{
|
||||
return accountSendMultiIOU(view, senderID, issue, receivers, j, waiveFee);
|
||||
}
|
||||
else
|
||||
{
|
||||
return accountSendMultiMPT(view, senderID, issue, receivers, j, waiveFee);
|
||||
}
|
||||
},
|
||||
asset.value());
|
||||
}
|
||||
@@ -2769,14 +2725,12 @@ issueIOU(
|
||||
// time of deletion.
|
||||
state->setFieldAmount(sfBalance, final_balance);
|
||||
if (must_delete)
|
||||
{
|
||||
return trustDelete(
|
||||
view,
|
||||
state,
|
||||
bSenderHigh ? account : issue.account,
|
||||
bSenderHigh ? issue.account : account,
|
||||
j);
|
||||
}
|
||||
|
||||
view.update(state);
|
||||
|
||||
@@ -2944,11 +2898,9 @@ requireAuth(ReadView const& view, Issue const& issue, AccountID const& account,
|
||||
issuerAccount && (*issuerAccount)[sfFlags] & lsfRequireAuth)
|
||||
{
|
||||
if (trustLine)
|
||||
{
|
||||
return ((*trustLine)[sfFlags] & ((account > issue.account) ? lsfLowAuth : lsfHighAuth))
|
||||
? tesSUCCESS
|
||||
: TER{tecNO_AUTH};
|
||||
}
|
||||
return TER{tecNO_LINE};
|
||||
}
|
||||
|
||||
@@ -2996,13 +2948,9 @@ requireAuth(
|
||||
if (auto const err = std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
{
|
||||
return requireAuth(view, issue, account, authType);
|
||||
}
|
||||
else
|
||||
{
|
||||
return requireAuth(view, issue, account, authType, depth + 1);
|
||||
}
|
||||
},
|
||||
asset.value());
|
||||
!isTesSuccess(err))
|
||||
@@ -3026,15 +2974,11 @@ requireAuth(
|
||||
sleIssuance->getFieldU32(sfFlags) & lsfMPTRequireAuth,
|
||||
"xrpl::requireAuth : issuance requires authorization");
|
||||
// ter = tefINTERNAL | tecOBJECT_NOT_FOUND | tecNO_AUTH | tecEXPIRED
|
||||
auto const ter = credentials::validDomain(view, *maybeDomainID, account);
|
||||
if (isTesSuccess(ter))
|
||||
{
|
||||
if (auto const ter = credentials::validDomain(view, *maybeDomainID, account);
|
||||
isTesSuccess(ter))
|
||||
return ter; // Note: sleToken might be null
|
||||
}
|
||||
if (!sleToken)
|
||||
{
|
||||
else if (!sleToken)
|
||||
return ter;
|
||||
}
|
||||
// We ignore error from validDomain if we found sleToken, as it could
|
||||
// belong to someone who is explicitly authorized e.g. a vault owner.
|
||||
}
|
||||
@@ -3101,14 +3045,14 @@ enforceMPTokenAuthorization(
|
||||
// Either way, return tecNO_AUTH and there is nothing else to do
|
||||
return expired ? tecEXPIRED : tecNO_AUTH;
|
||||
}
|
||||
if (!authorizedByDomain && maybeDomainID.has_value())
|
||||
else if (!authorizedByDomain && maybeDomainID.has_value())
|
||||
{
|
||||
// Found an MPToken but the account is not authorized and we expect
|
||||
// it to have been authorized by the domain. This could be because the
|
||||
// credentials used to create the MPToken have expired or been deleted.
|
||||
return expired ? tecEXPIRED : tecNO_AUTH;
|
||||
}
|
||||
if (!authorizedByDomain)
|
||||
else if (!authorizedByDomain)
|
||||
{
|
||||
// We found an MPToken, but sfDomainID is not set, so this is a classic
|
||||
// MPToken which requires authorization by the token issuer.
|
||||
@@ -3120,7 +3064,7 @@ enforceMPTokenAuthorization(
|
||||
|
||||
return tecNO_AUTH;
|
||||
}
|
||||
if (authorizedByDomain && sleToken != nullptr)
|
||||
else if (authorizedByDomain && sleToken != nullptr)
|
||||
{
|
||||
// Found an MPToken, authorized by the domain. Ignore authorization flag
|
||||
// lsfMPTAuthorized because it is meaningless. Return tesSUCCESS
|
||||
@@ -3129,7 +3073,7 @@ enforceMPTokenAuthorization(
|
||||
"xrpl::enforceMPTokenAuthorization : found MPToken for domain");
|
||||
return tesSUCCESS;
|
||||
}
|
||||
if (authorizedByDomain)
|
||||
else if (authorizedByDomain)
|
||||
{
|
||||
// Could not find MPToken but there should be one because we are
|
||||
// authorized by domain. Proceed to create it, then return tesSUCCESS
|
||||
@@ -3246,7 +3190,7 @@ cleanupOnAccountDelete(
|
||||
// Deleter handles the details of specific account-owned object
|
||||
// deletion
|
||||
auto const [ter, skipEntry] = deleter(nodeType, dirEntry, sleItem);
|
||||
if (!isTesSuccess(ter))
|
||||
if (ter != tesSUCCESS)
|
||||
return ter;
|
||||
|
||||
// dirFirst() and dirNext() are like iterators with exposed
|
||||
@@ -3315,7 +3259,7 @@ deleteAMMTrustLine(
|
||||
if (ammAccountID && (low != *ammAccountID && high != *ammAccountID))
|
||||
return terNO_AMM;
|
||||
|
||||
if (auto const ter = trustDelete(view, sleState, low, high, j); !isTesSuccess(ter))
|
||||
if (auto const ter = trustDelete(view, sleState, low, high, j); ter != tesSUCCESS)
|
||||
{
|
||||
JLOG(j.error()) << "deleteAMMTrustLine: failed to delete the trustline.";
|
||||
return ter;
|
||||
@@ -3370,11 +3314,9 @@ assetsToSharesDeposit(
|
||||
Number const assetTotal = vault->at(sfAssetsTotal);
|
||||
STAmount shares{vault->at(sfShareMPTID)};
|
||||
if (assetTotal == 0)
|
||||
{
|
||||
return STAmount{
|
||||
shares.asset(),
|
||||
Number(assets.mantissa(), assets.exponent() + vault->at(sfScale)).truncate()};
|
||||
}
|
||||
|
||||
Number const shareTotal = issuance->at(sfOutstandingAmount);
|
||||
shares = ((shareTotal * assets) / assetTotal).truncate();
|
||||
@@ -3397,10 +3339,8 @@ sharesToAssetsDeposit(
|
||||
Number const assetTotal = vault->at(sfAssetsTotal);
|
||||
STAmount assets{vault->at(sfAsset)};
|
||||
if (assetTotal == 0)
|
||||
{
|
||||
return STAmount{
|
||||
assets.asset(), shares.mantissa(), shares.exponent() - vault->at(sfScale), false};
|
||||
}
|
||||
|
||||
Number const shareTotal = issuance->at(sfOutstandingAmount);
|
||||
assets = (assetTotal * shares) / shareTotal;
|
||||
@@ -3515,13 +3455,9 @@ rippleLockEscrowMPT(
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
if (sle->isFieldPresent(sfLockedAmount))
|
||||
{
|
||||
(*sle)[sfLockedAmount] += pay;
|
||||
}
|
||||
else
|
||||
{
|
||||
sle->setFieldU64(sfLockedAmount, pay);
|
||||
}
|
||||
|
||||
view.update(sle);
|
||||
}
|
||||
@@ -3542,13 +3478,9 @@ rippleLockEscrowMPT(
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
if (sleIssuance->isFieldPresent(sfLockedAmount))
|
||||
{
|
||||
(*sleIssuance)[sfLockedAmount] += pay;
|
||||
}
|
||||
else
|
||||
{
|
||||
sleIssuance->setFieldU64(sfLockedAmount, pay);
|
||||
}
|
||||
|
||||
view.update(sleIssuance);
|
||||
}
|
||||
@@ -3565,10 +3497,8 @@ rippleUnlockEscrowMPT(
|
||||
beast::Journal j)
|
||||
{
|
||||
if (!view.rules().enabled(fixTokenEscrowV1))
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
netAmount == grossAmount, "xrpl::rippleUnlockEscrowMPT : netAmount == grossAmount");
|
||||
}
|
||||
|
||||
auto const& issuer = netAmount.getIssuer();
|
||||
auto const& mptIssue = netAmount.get<MPTIssue>();
|
||||
@@ -3603,13 +3533,9 @@ rippleUnlockEscrowMPT(
|
||||
|
||||
auto const newLocked = locked - redeem;
|
||||
if (newLocked == 0)
|
||||
{
|
||||
sleIssuance->makeFieldAbsent(sfLockedAmount);
|
||||
}
|
||||
else
|
||||
{
|
||||
sleIssuance->setFieldU64(sfLockedAmount, newLocked);
|
||||
}
|
||||
view.update(sleIssuance);
|
||||
}
|
||||
|
||||
@@ -3662,44 +3588,42 @@ rippleUnlockEscrowMPT(
|
||||
"cannot unlock MPTs.";
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
// Decrease the MPT Holder EscrowedAmount
|
||||
auto const mptokenID = keylet::mptoken(mptID.key, sender);
|
||||
auto sle = view.peek(mptokenID);
|
||||
if (!sle)
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: MPToken not found for " << sender;
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
if (!sle->isFieldPresent(sfLockedAmount))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: no locked amount in MPToken for "
|
||||
<< to_string(sender);
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
auto const locked = sle->getFieldU64(sfLockedAmount);
|
||||
auto const delta = grossAmount.mpt().value();
|
||||
|
||||
// Underflow check for subtraction
|
||||
if (!canSubtract(STAmount(mptIssue, locked), STAmount(mptIssue, delta)))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient locked amount for "
|
||||
<< to_string(sender) << ": " << locked << " < " << delta;
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
auto const newLocked = locked - delta;
|
||||
if (newLocked == 0)
|
||||
{
|
||||
sle->makeFieldAbsent(sfLockedAmount);
|
||||
}
|
||||
else
|
||||
{
|
||||
sle->setFieldU64(sfLockedAmount, newLocked);
|
||||
// Decrease the MPT Holder EscrowedAmount
|
||||
auto const mptokenID = keylet::mptoken(mptID.key, sender);
|
||||
auto sle = view.peek(mptokenID);
|
||||
if (!sle)
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: MPToken not found for " << sender;
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
if (!sle->isFieldPresent(sfLockedAmount))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: no locked amount in MPToken for "
|
||||
<< to_string(sender);
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
auto const locked = sle->getFieldU64(sfLockedAmount);
|
||||
auto const delta = grossAmount.mpt().value();
|
||||
|
||||
// Underflow check for subtraction
|
||||
if (!canSubtract(STAmount(mptIssue, locked), STAmount(mptIssue, delta)))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient locked amount for "
|
||||
<< to_string(sender) << ": " << locked << " < " << delta;
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
auto const newLocked = locked - delta;
|
||||
if (newLocked == 0)
|
||||
sle->makeFieldAbsent(sfLockedAmount);
|
||||
else
|
||||
sle->setFieldU64(sfLockedAmount, newLocked);
|
||||
view.update(sle);
|
||||
}
|
||||
view.update(sle);
|
||||
|
||||
// Note: The gross amount is the amount that was locked, the net
|
||||
// amount is the amount that is being unlocked. The difference is the fee
|
||||
|
||||
@@ -26,12 +26,6 @@ HTTPClient::initializeSSLContext(
|
||||
httpClientSSLContext.emplace(sslVerifyDir, sslVerifyFile, sslVerify, j);
|
||||
}
|
||||
|
||||
void
|
||||
HTTPClient::cleanupSSLContext()
|
||||
{
|
||||
httpClientSSLContext.reset();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Fetch a web page via http or https.
|
||||
@@ -478,7 +472,7 @@ public:
|
||||
private:
|
||||
using pointer = std::shared_ptr<HTTPClient>;
|
||||
|
||||
bool mSSL{};
|
||||
bool mSSL;
|
||||
AutoSocket mSocket;
|
||||
boost::asio::ip::tcp::resolver mResolver;
|
||||
|
||||
@@ -496,7 +490,7 @@ private:
|
||||
std::string mBody;
|
||||
unsigned short const mPort;
|
||||
std::size_t const maxResponseSize_;
|
||||
int mStatus{};
|
||||
int mStatus;
|
||||
std::function<void(boost::asio::streambuf& sb, std::string const& strHost)> mBuild;
|
||||
std::function<
|
||||
bool(boost::system::error_code const& ecResult, int iStatus, std::string const& strData)>
|
||||
@@ -508,7 +502,7 @@ private:
|
||||
boost::system::error_code mShutdown;
|
||||
|
||||
std::deque<std::string> mDeqSites;
|
||||
std::chrono::seconds mTimeout{};
|
||||
std::chrono::seconds mTimeout;
|
||||
beast::Journal j_;
|
||||
};
|
||||
|
||||
|
||||
@@ -79,7 +79,6 @@ registerSSLCerts(boost::asio::ssl::context& ctx, boost::system::error_code& ec,
|
||||
SSL_CTX_set_cert_store(ctx.native_handle(), store.release());
|
||||
|
||||
#else
|
||||
// NOLINTNEXTLINE(bugprone-unused-return-value)
|
||||
ctx.set_default_verify_paths(ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ BatchWriter::writeBatch()
|
||||
}
|
||||
}
|
||||
|
||||
BatchWriteReport report{};
|
||||
BatchWriteReport report;
|
||||
report.writeCount = set.size();
|
||||
auto const before = std::chrono::steady_clock::now();
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ DatabaseNodeImp::fetchNodeObject(
|
||||
bool duplicate)
|
||||
{
|
||||
std::shared_ptr<NodeObject> nodeObject = nullptr;
|
||||
Status status = ok;
|
||||
Status status;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -101,7 +101,7 @@ DatabaseRotatingImp::fetchNodeObject(
|
||||
bool duplicate)
|
||||
{
|
||||
auto fetch = [&](std::shared_ptr<Backend> const& backend) {
|
||||
Status status = ok;
|
||||
Status status;
|
||||
std::shared_ptr<NodeObject> nodeObject;
|
||||
try
|
||||
{
|
||||
|
||||
@@ -142,13 +142,9 @@ public:
|
||||
std::shared_ptr<NodeObject> nObj;
|
||||
Status status = fetch(h, &nObj);
|
||||
if (status != ok)
|
||||
{
|
||||
results.push_back({});
|
||||
}
|
||||
else
|
||||
{
|
||||
results.push_back(nObj);
|
||||
}
|
||||
}
|
||||
|
||||
return {results, ok};
|
||||
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
Status
|
||||
fetch(uint256 const& hash, std::shared_ptr<NodeObject>* pno) override
|
||||
{
|
||||
Status status = ok;
|
||||
Status status;
|
||||
pno->reset();
|
||||
nudb::error_code ec;
|
||||
db_.fetch(
|
||||
@@ -216,13 +216,9 @@ public:
|
||||
std::shared_ptr<NodeObject> nObj;
|
||||
Status status = fetch(h, &nObj);
|
||||
if (status != ok)
|
||||
{
|
||||
results.push_back({});
|
||||
}
|
||||
else
|
||||
{
|
||||
results.push_back(nObj);
|
||||
}
|
||||
}
|
||||
|
||||
return {results, ok};
|
||||
@@ -243,7 +239,7 @@ public:
|
||||
void
|
||||
store(std::shared_ptr<NodeObject> const& no) override
|
||||
{
|
||||
BatchWriteReport report{};
|
||||
BatchWriteReport report;
|
||||
report.writeCount = 1;
|
||||
auto const start = std::chrono::steady_clock::now();
|
||||
do_insert(no);
|
||||
@@ -255,7 +251,7 @@ public:
|
||||
void
|
||||
storeBatch(Batch const& batch) override
|
||||
{
|
||||
BatchWriteReport report{};
|
||||
BatchWriteReport report;
|
||||
report.writeCount = batch.size();
|
||||
auto const start = std::chrono::steady_clock::now();
|
||||
for (auto const& e : batch)
|
||||
|
||||
@@ -166,10 +166,8 @@ public:
|
||||
auto const s = rocksdb::GetBlockBasedTableOptionsFromString(
|
||||
config_options, table_options, get(keyValues, "bbt_options"), &table_options);
|
||||
if (!s.ok())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
std::string("Unable to set RocksDB bbt_options: ") + s.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
m_options.table_factory.reset(NewBlockBasedTableFactory(table_options));
|
||||
@@ -179,10 +177,8 @@ public:
|
||||
auto const s =
|
||||
rocksdb::GetOptionsFromString(m_options, get(keyValues, "options"), &m_options);
|
||||
if (!s.ok())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
std::string("Unable to set RocksDB options: ") + s.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
std::string s1, s2;
|
||||
@@ -214,10 +210,8 @@ public:
|
||||
m_options.create_if_missing = createIfMissing;
|
||||
rocksdb::Status status = rocksdb::DB::Open(m_options, m_name, &db);
|
||||
if (!status.ok() || !db)
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
std::string("Unable to open/create RocksDB: ") + status.ToString());
|
||||
}
|
||||
m_db.reset(db);
|
||||
}
|
||||
|
||||
@@ -310,13 +304,9 @@ public:
|
||||
std::shared_ptr<NodeObject> nObj;
|
||||
Status status = fetch(h, &nObj);
|
||||
if (status != ok)
|
||||
{
|
||||
results.push_back({});
|
||||
}
|
||||
else
|
||||
{
|
||||
results.push_back(nObj);
|
||||
}
|
||||
}
|
||||
|
||||
return {results, ok};
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <xrpl/beast/core/SemanticVersion.h>
|
||||
#include <xrpl/git/Git.h>
|
||||
#include <xrpl/protocol/BuildInfo.h>
|
||||
#include <xrpl/protocol/SystemParameters.h>
|
||||
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
|
||||
@@ -81,7 +80,7 @@ getVersionString()
|
||||
std::string const&
|
||||
getFullVersionString()
|
||||
{
|
||||
static std::string const value = systemName() + "-" + getVersionString();
|
||||
static std::string const value = "rippled-" + getVersionString();
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -250,22 +250,18 @@ FeatureCollections::registerFeature(std::string const& name, Supported support,
|
||||
supported.emplace(name, vote);
|
||||
|
||||
if (vote == VoteBehavior::DefaultYes)
|
||||
{
|
||||
++upVotes;
|
||||
}
|
||||
else
|
||||
{
|
||||
++downVotes;
|
||||
}
|
||||
}
|
||||
check(upVotes + downVotes == supported.size(), "Feature counting logic broke");
|
||||
check(supported.size() <= features.size(), "More supported features than defined features");
|
||||
check(features.size() == all.size(), "The 'all' features list is populated incorrectly");
|
||||
return f;
|
||||
}
|
||||
|
||||
// Each feature should only be registered once
|
||||
LogicError("Duplicate feature registration");
|
||||
else
|
||||
// Each feature should only be registered once
|
||||
LogicError("Duplicate feature registration");
|
||||
}
|
||||
|
||||
/** Tell FeatureCollections when registration is complete. */
|
||||
@@ -306,7 +302,7 @@ FeatureCollections::featureToName(uint256 const& f) const
|
||||
return feature ? feature->name : to_string(f);
|
||||
}
|
||||
|
||||
FeatureCollections featureCollections;
|
||||
static FeatureCollections featureCollections;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -399,20 +395,10 @@ featureToName(uint256 const& f)
|
||||
#pragma push_macro("XRPL_RETIRE_FIX")
|
||||
#undef XRPL_RETIRE_FIX
|
||||
|
||||
consteval auto
|
||||
enforceValidFeatureName(auto fn) -> char const*
|
||||
{
|
||||
static_assert(validFeatureName(fn), "Invalid feature name");
|
||||
static_assert(validFeatureNameSize(fn), "Invalid feature name size");
|
||||
return fn();
|
||||
}
|
||||
|
||||
#define XRPL_FEATURE(name, supported, vote) \
|
||||
uint256 const feature##name = \
|
||||
registerFeature(enforceValidFeatureName([] { return #name; }), supported, vote);
|
||||
uint256 const feature##name = registerFeature(#name, supported, vote);
|
||||
#define XRPL_FIX(name, supported, vote) \
|
||||
uint256 const fix##name = \
|
||||
registerFeature(enforceValidFeatureName([] { return "fix" #name; }), supported, vote);
|
||||
uint256 const fix##name = registerFeature("fix" #name, supported, vote);
|
||||
|
||||
// clang-format off
|
||||
#define XRPL_RETIRE_FEATURE(name) \
|
||||
|
||||
@@ -137,7 +137,7 @@ getQuality(uint256 const& uBase)
|
||||
uint256
|
||||
getTicketIndex(AccountID const& account, std::uint32_t ticketSeq)
|
||||
{
|
||||
return indexHash(LedgerNameSpace::TICKET, account, ticketSeq);
|
||||
return indexHash(LedgerNameSpace::TICKET, account, std::uint32_t(ticketSeq));
|
||||
}
|
||||
|
||||
uint256
|
||||
|
||||
@@ -25,17 +25,11 @@ Issue::getText() const
|
||||
ret += "/";
|
||||
|
||||
if (isXRP(account))
|
||||
{
|
||||
ret += "0";
|
||||
}
|
||||
else if (account == noAccount())
|
||||
{
|
||||
ret += "1";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += to_string(account);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user