mirror of
https://github.com/XRPLF/rippled.git
synced 2026-03-31 00:52:29 +00:00
Compare commits
27 Commits
release-3.
...
bthomee/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
554d842692 | ||
|
|
00a8d806d5 | ||
|
|
5c8dfe5456 | ||
|
|
ab8c168e3b | ||
|
|
3a477e4d01 | ||
|
|
96bfc32fe2 | ||
|
|
de671863e2 | ||
|
|
e0cabb9f8c | ||
|
|
27e0e8f93a | ||
|
|
4011f74914 | ||
|
|
9f311be539 | ||
|
|
8599212d07 | ||
|
|
64f3cd1ca0 | ||
|
|
3d9c545f59 | ||
|
|
b0e5859aea | ||
|
|
9b944ee8c2 | ||
|
|
1490a1401e | ||
|
|
5df14e58d7 | ||
|
|
750f762c01 | ||
|
|
5ef8813891 | ||
|
|
0ef3ca9674 | ||
|
|
d57a9b1ad3 | ||
|
|
509677abfd | ||
|
|
addc1e8e25 | ||
|
|
faf69da4b0 | ||
|
|
76e3b4fb0f | ||
|
|
e8bdbf975a |
106
.clang-tidy
106
.clang-tidy
@@ -1,4 +1,6 @@
|
||||
---
|
||||
# This entire group of checks was applied to all cpp files but not all header files.
|
||||
# ---
|
||||
Checks: "-*,
|
||||
bugprone-argument-comment,
|
||||
bugprone-assert-side-effect,
|
||||
@@ -8,26 +10,26 @@ Checks: "-*,
|
||||
bugprone-chained-comparison,
|
||||
bugprone-compare-pointer-to-member-virtual-function,
|
||||
bugprone-copy-constructor-init,
|
||||
bugprone-crtp-constructor-accessibility,
|
||||
# bugprone-crtp-constructor-accessibility, # has issues
|
||||
bugprone-dangling-handle,
|
||||
bugprone-dynamic-static-initializers,
|
||||
bugprone-empty-catch,
|
||||
# bugprone-empty-catch, # has issues
|
||||
bugprone-fold-init-type,
|
||||
bugprone-forward-declaration-namespace,
|
||||
bugprone-inaccurate-erase,
|
||||
bugprone-inc-dec-in-conditions,
|
||||
bugprone-incorrect-enable-if,
|
||||
bugprone-incorrect-roundings,
|
||||
bugprone-infinite-loop,
|
||||
bugprone-integer-division,
|
||||
# bugprone-forward-declaration-namespace, # has issues
|
||||
# bugprone-inaccurate-erase,
|
||||
# bugprone-inc-dec-in-conditions,
|
||||
# bugprone-incorrect-enable-if,
|
||||
# bugprone-incorrect-roundings,
|
||||
# bugprone-infinite-loop,
|
||||
# bugprone-integer-division,
|
||||
bugprone-lambda-function-name,
|
||||
bugprone-macro-parentheses,
|
||||
# bugprone-macro-parentheses, # has issues
|
||||
bugprone-macro-repeated-side-effects,
|
||||
bugprone-misplaced-operator-in-strlen-in-alloc,
|
||||
bugprone-misplaced-pointer-arithmetic-in-alloc,
|
||||
bugprone-misplaced-widening-cast,
|
||||
bugprone-move-forwarding-reference,
|
||||
bugprone-multi-level-implicit-pointer-conversion,
|
||||
# bugprone-multi-level-implicit-pointer-conversion, # has issues
|
||||
bugprone-multiple-new-in-one-expression,
|
||||
bugprone-multiple-statement-macro,
|
||||
bugprone-no-escape,
|
||||
@@ -37,13 +39,13 @@ Checks: "-*,
|
||||
bugprone-pointer-arithmetic-on-polymorphic-object,
|
||||
bugprone-posix-return,
|
||||
bugprone-redundant-branch-condition,
|
||||
bugprone-reserved-identifier,
|
||||
bugprone-return-const-ref-from-parameter,
|
||||
# bugprone-reserved-identifier, # has issues
|
||||
# bugprone-return-const-ref-from-parameter, # has issues
|
||||
bugprone-shared-ptr-array-mismatch,
|
||||
bugprone-signal-handler,
|
||||
bugprone-signed-char-misuse,
|
||||
bugprone-sizeof-container,
|
||||
bugprone-sizeof-expression,
|
||||
# bugprone-sizeof-expression, # has issues
|
||||
bugprone-spuriously-wake-up-functions,
|
||||
bugprone-standalone-empty,
|
||||
bugprone-string-constructor,
|
||||
@@ -60,7 +62,7 @@ Checks: "-*,
|
||||
bugprone-suspicious-string-compare,
|
||||
bugprone-suspicious-stringview-data-usage,
|
||||
bugprone-swapped-arguments,
|
||||
bugprone-switch-missing-default-case,
|
||||
# bugprone-switch-missing-default-case, # has issues
|
||||
bugprone-terminating-continue,
|
||||
bugprone-throw-keyword-missing,
|
||||
bugprone-too-small-loop-variable,
|
||||
@@ -71,61 +73,66 @@ Checks: "-*,
|
||||
bugprone-unhandled-self-assignment,
|
||||
bugprone-unique-ptr-array-mismatch,
|
||||
bugprone-unsafe-functions,
|
||||
bugprone-use-after-move,
|
||||
# bugprone-use-after-move, # has issues
|
||||
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-init-variables, # has issues
|
||||
# cppcoreguidelines-misleading-capture-default-by-value, # has issues
|
||||
cppcoreguidelines-no-suspend-with-lock,
|
||||
cppcoreguidelines-pro-type-member-init,
|
||||
# cppcoreguidelines-pro-type-member-init, # has issues
|
||||
cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
cppcoreguidelines-rvalue-reference-param-not-moved,
|
||||
cppcoreguidelines-use-default-member-init,
|
||||
cppcoreguidelines-virtual-class-destructor,
|
||||
# cppcoreguidelines-rvalue-reference-param-not-moved, # has issues
|
||||
# cppcoreguidelines-use-default-member-init, # has issues
|
||||
# cppcoreguidelines-virtual-class-destructor, # has issues
|
||||
hicpp-ignored-remove-result,
|
||||
misc-definitions-in-headers,
|
||||
# misc-definitions-in-headers, # has issues
|
||||
misc-header-include-cycle,
|
||||
misc-misplaced-const,
|
||||
misc-static-assert,
|
||||
misc-throw-by-value-catch-by-reference,
|
||||
# misc-throw-by-value-catch-by-reference, # has issues
|
||||
misc-unused-alias-decls,
|
||||
misc-unused-using-decls,
|
||||
modernize-deprecated-headers,
|
||||
modernize-make-shared,
|
||||
modernize-make-unique,
|
||||
performance-faster-string-find,
|
||||
performance-for-range-copy,
|
||||
performance-implicit-conversion-in-loop,
|
||||
performance-inefficient-vector-operation,
|
||||
performance-move-const-arg,
|
||||
performance-move-constructor-init,
|
||||
performance-no-automatic-move,
|
||||
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-convert-member-functions-to-static,
|
||||
# readability-avoid-nested-conditional-operator, # has issues
|
||||
# readability-avoid-return-with-void-value, # has issues
|
||||
# readability-braces-around-statements, # has issues
|
||||
# readability-const-return-type, # has issues
|
||||
# readability-container-contains, # has issues
|
||||
# readability-container-size-empty, # has issues
|
||||
# readability-convert-member-functions-to-static, # has issues
|
||||
readability-duplicate-include,
|
||||
readability-else-after-return,
|
||||
readability-enum-initial-value,
|
||||
readability-implicit-bool-conversion,
|
||||
readability-make-member-function-const,
|
||||
readability-math-missing-parentheses,
|
||||
# readability-else-after-return, # has issues
|
||||
# readability-enum-initial-value, # has issues
|
||||
# readability-implicit-bool-conversion, # has issues
|
||||
# readability-make-member-function-const, # has issues
|
||||
# readability-math-missing-parentheses, # has issues
|
||||
readability-misleading-indentation,
|
||||
readability-non-const-parameter,
|
||||
readability-redundant-casting,
|
||||
readability-redundant-declaration,
|
||||
readability-redundant-inline-specifier,
|
||||
readability-redundant-member-init,
|
||||
# readability-redundant-casting, # has issues
|
||||
# readability-redundant-declaration, # has issues
|
||||
# readability-redundant-inline-specifier, # has issues
|
||||
# readability-redundant-member-init, # has issues
|
||||
readability-redundant-string-init,
|
||||
readability-reference-to-constructed-temporary,
|
||||
readability-simplify-boolean-expr,
|
||||
readability-static-definition-in-anonymous-namespace,
|
||||
readability-suspicious-call-argument,
|
||||
# readability-simplify-boolean-expr, # has issues
|
||||
# readability-static-definition-in-anonymous-namespace, # has issues
|
||||
# readability-suspicious-call-argument, # has issues
|
||||
readability-use-std-min-max
|
||||
"
|
||||
# ---
|
||||
# checks that have some issues that need to be resolved:
|
||||
# other checks that have issues that need to be resolved:
|
||||
#
|
||||
# llvm-namespace-comment,
|
||||
# misc-const-correctness,
|
||||
@@ -134,7 +141,7 @@ Checks: "-*,
|
||||
#
|
||||
# readability-inconsistent-declaration-parameter-name, # in this codebase this check will break a lot of arg names
|
||||
# readability-static-accessed-through-instance, # this check is probably unnecessary. it makes the code less readable
|
||||
# readability-identifier-naming,
|
||||
# readability-identifier-naming, # https://github.com/XRPLF/rippled/pull/6571
|
||||
#
|
||||
# modernize-concat-nested-namespaces,
|
||||
# modernize-pass-by-value,
|
||||
@@ -148,12 +155,6 @@ Checks: "-*,
|
||||
# modernize-use-starts-ends-with,
|
||||
# modernize-use-std-numbers,
|
||||
# modernize-use-using,
|
||||
#
|
||||
# performance-faster-string-find,
|
||||
# performance-for-range-copy,
|
||||
# performance-inefficient-vector-operation,
|
||||
# performance-move-const-arg,
|
||||
# performance-no-automatic-move,
|
||||
# ---
|
||||
#
|
||||
CheckOptions:
|
||||
@@ -195,5 +196,6 @@ CheckOptions:
|
||||
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)$'
|
||||
HeaderFilterRegex: '^.*/(test|xrpl|xrpld)/.*\.(h|hpp)$'
|
||||
ExcludeHeaderFilterRegex: '^.*/protocol_autogen/.*\.(h|hpp)$'
|
||||
WarningsAsErrors: "*"
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest a new feature for the rippled project
|
||||
title: "[Title with short description] (Version: [rippled version])"
|
||||
about: Suggest a new feature for the xrpld project
|
||||
title: "[Title with short description] (Version: [xrpld version])"
|
||||
labels: Feature Request
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
12
.github/scripts/levelization/README.md
vendored
12
.github/scripts/levelization/README.md
vendored
@@ -1,14 +1,14 @@
|
||||
# Levelization
|
||||
|
||||
Levelization is the term used to describe efforts to prevent rippled from
|
||||
Levelization is the term used to describe efforts to prevent xrpld from
|
||||
having or creating cyclic dependencies.
|
||||
|
||||
rippled code is organized into directories under `src/xrpld`, `src/libxrpl` (and
|
||||
xrpld code is organized into directories under `src/xrpld`, `src/libxrpl` (and
|
||||
`src/test`) representing modules. The modules are intended to be
|
||||
organized into "tiers" or "levels" such that a module from one level can
|
||||
only include code from lower levels. Additionally, a module
|
||||
in one level should never include code in an `impl` or `detail` folder of any level
|
||||
other than it's own.
|
||||
other than its own.
|
||||
|
||||
The codebase is split into two main areas:
|
||||
|
||||
@@ -22,7 +22,7 @@ levelization violations they find (by moving files or individual
|
||||
classes). At the very least, don't make things worse.
|
||||
|
||||
The table below summarizes the _desired_ division of modules, based on the current
|
||||
state of the rippled code. The levels are numbered from
|
||||
state of the xrpld code. The levels are numbered from
|
||||
the bottom up with the lower level, lower numbered, more independent
|
||||
modules listed first, and the higher level, higher numbered modules with
|
||||
more dependencies listed later.
|
||||
@@ -72,10 +72,10 @@ that `test` code should _never_ be included in `xrpl` or `xrpld` code.)
|
||||
|
||||
The [levelization](generate.py) script takes no parameters,
|
||||
reads no environment variables, and can be run from any directory,
|
||||
as long as it is in the expected location in the rippled repo.
|
||||
as long as it is in the expected location in the xrpld repo.
|
||||
It can be run at any time from within a checked out repo, and will
|
||||
do an analysis of all the `#include`s in
|
||||
the rippled source. The only caveat is that it runs much slower
|
||||
the xrpld source. The only caveat is that it runs much slower
|
||||
under Windows than in Linux. It hasn't yet been tested under MacOS.
|
||||
It generates many files of [results](results):
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ libxrpl.protocol > xrpl.json
|
||||
libxrpl.protocol > xrpl.protocol
|
||||
libxrpl.protocol_autogen > xrpl.protocol_autogen
|
||||
libxrpl.rdb > xrpl.basics
|
||||
libxrpl.rdb > xrpl.core
|
||||
libxrpl.rdb > xrpl.rdb
|
||||
libxrpl.resource > xrpl.basics
|
||||
libxrpl.resource > xrpl.json
|
||||
@@ -184,7 +185,6 @@ xrpl.conditions > xrpl.basics
|
||||
xrpl.conditions > xrpl.protocol
|
||||
xrpl.core > xrpl.basics
|
||||
xrpl.core > xrpl.json
|
||||
xrpl.core > xrpl.ledger
|
||||
xrpl.core > xrpl.protocol
|
||||
xrpl.json > xrpl.basics
|
||||
xrpl.ledger > xrpl.basics
|
||||
|
||||
3
.github/scripts/rename/README.md
vendored
3
.github/scripts/rename/README.md
vendored
@@ -34,6 +34,8 @@ run from the repository root.
|
||||
6. `.github/scripts/rename/config.sh`: This script will rename the config from
|
||||
`rippled.cfg` to `xrpld.cfg`, and updating the code accordingly. The old
|
||||
filename will still be accepted.
|
||||
7. `.github/scripts/rename/docs.sh`: This script will rename any lingering
|
||||
references of `ripple(d)` to `xrpl(d)` in code, comments, and documentation.
|
||||
|
||||
You can run all these scripts from the repository root as follows:
|
||||
|
||||
@@ -44,4 +46,5 @@ You can run all these scripts from the repository root as follows:
|
||||
./.github/scripts/rename/binary.sh .
|
||||
./.github/scripts/rename/namespace.sh .
|
||||
./.github/scripts/rename/config.sh .
|
||||
./.github/scripts/rename/docs.sh .
|
||||
```
|
||||
|
||||
3
.github/scripts/rename/binary.sh
vendored
3
.github/scripts/rename/binary.sh
vendored
@@ -29,7 +29,7 @@ if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd ${DIRECTORY}
|
||||
pushd "${DIRECTORY}"
|
||||
|
||||
# Remove the binary name override added by the cmake.sh script.
|
||||
${SED_COMMAND} -z -i -E 's@\s+# For the time being.+"rippled"\)@@' cmake/XrplCore.cmake
|
||||
@@ -49,6 +49,7 @@ ${SED_COMMAND} -i -E 's@ripple/xrpld@XRPLF/rippled@g' BUILD.md
|
||||
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' BUILD.md
|
||||
${SED_COMMAND} -i -E 's@xrpld \(`xrpld`\)@xrpld@g' BUILD.md
|
||||
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' CONTRIBUTING.md
|
||||
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' docs/build/install.md
|
||||
|
||||
popd
|
||||
echo "Processing complete."
|
||||
|
||||
2
.github/scripts/rename/cmake.sh
vendored
2
.github/scripts/rename/cmake.sh
vendored
@@ -38,7 +38,7 @@ if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd ${DIRECTORY}
|
||||
pushd "${DIRECTORY}"
|
||||
|
||||
# Rename the files.
|
||||
find cmake -type f -name 'Rippled*.cmake' -exec bash -c 'mv "${1}" "${1/Rippled/Xrpl}"' - {} \;
|
||||
|
||||
5
.github/scripts/rename/config.sh
vendored
5
.github/scripts/rename/config.sh
vendored
@@ -28,7 +28,7 @@ if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd ${DIRECTORY}
|
||||
pushd "${DIRECTORY}"
|
||||
|
||||
# Add the xrpld.cfg to the .gitignore.
|
||||
if ! grep -q 'xrpld.cfg' .gitignore; then
|
||||
@@ -52,16 +52,15 @@ for DIRECTORY in "${DIRECTORIES[@]}"; do
|
||||
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.cmake" -o -name "*.txt" -o -name "*.cfg" -o -name "*.md" \) | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
${SED_COMMAND} -i -E 's/rippled(-example)?[ .]cfg/xrpld\1.cfg/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/rippleConfig/xrpldConfig/g' "${FILE}"
|
||||
done
|
||||
done
|
||||
${SED_COMMAND} -i 's/rippled/xrpld/g' cfg/xrpld-example.cfg
|
||||
${SED_COMMAND} -i 's/rippled/xrpld/g' src/test/core/Config_test.cpp
|
||||
${SED_COMMAND} -i 's/ripplevalidators/xrplvalidators/g' src/test/core/Config_test.cpp # cspell: disable-line
|
||||
${SED_COMMAND} -i 's/rippleConfig/xrpldConfig/g' src/test/core/Config_test.cpp
|
||||
${SED_COMMAND} -i 's@ripple/@xrpld/@g' src/test/core/Config_test.cpp
|
||||
${SED_COMMAND} -i 's/Rippled/File/g' src/test/core/Config_test.cpp
|
||||
|
||||
|
||||
# Restore the old config file name in the code that maintains support for now.
|
||||
${SED_COMMAND} -i 's/configLegacyName = "xrpld.cfg"/configLegacyName = "rippled.cfg"/g' src/xrpld/core/detail/Config.cpp
|
||||
|
||||
|
||||
2
.github/scripts/rename/copyright.sh
vendored
2
.github/scripts/rename/copyright.sh
vendored
@@ -31,7 +31,7 @@ if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd ${DIRECTORY}
|
||||
pushd "${DIRECTORY}"
|
||||
|
||||
# Prevent sed and echo from removing newlines and tabs in string literals by
|
||||
# temporarily replacing them with placeholders. This only affects one file.
|
||||
|
||||
96
.github/scripts/rename/docs.sh
vendored
Executable file
96
.github/scripts/rename/docs.sh
vendored
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit the script as soon as an error occurs.
|
||||
set -e
|
||||
|
||||
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
|
||||
SED_COMMAND=sed
|
||||
if [[ "${OSTYPE}" == 'darwin'* ]]; then
|
||||
if ! command -v gsed &> /dev/null; then
|
||||
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
|
||||
exit 1
|
||||
fi
|
||||
SED_COMMAND=gsed
|
||||
fi
|
||||
|
||||
# This script renames all remaining references to `ripple` and `rippled` to
|
||||
# `xrpl` and `xrpld`, respectively, in code, comments, and documentation.
|
||||
# Usage: .github/scripts/rename/docs.sh <repository directory>
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <repository directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRECTORY=$1
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd "${DIRECTORY}"
|
||||
|
||||
find . -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.txt" -o -name "*.cfg" -o -name "*.md" -o -name "*.proto" \) -not -path "./.github/scripts/*" | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
${SED_COMMAND} -i 's/rippleLockEscrowMPT/lockEscrowMPT/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/rippleUnlockEscrowMPT/unlockEscrowMPT/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/rippleCredit/directSendNoFee/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/rippleSend/directSendNoLimit/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's@([^/+-])rippled@\1xrpld@g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's@([^/+-])Rippled@\1Xrpld@g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/^rippled/xrpld/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/^Rippled/Xrpld/g' "${FILE}"
|
||||
# cspell: disable
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (a|A)ddress/XRPL address/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (a|A)ccount/XRPL account/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (a|A)lgorithm/XRPL algorithm/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (c|C)lient/XRPL client/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (c|C)luster/XRPL cluster/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (c|C)onsensus/XRPL consensus/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (d|D)efault/XRPL default/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (e|E)poch/XRPL epoch/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (f|F)eature/XRPL feature/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (n|N)etwork/XRPL network/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (p|P)ayment/XRPL payment/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (p|P)rotocol/XRPL protocol/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (r|R)epository/XRPL repository/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple RPC/XRPL RPC/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (s|S)erialization/XRPL serialization/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (s|S)erver/XRPL server/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (s|S)pecific/XRPL specific/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple Source/XRPL Source/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (t|T)imestamp/XRPL timestamp/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple uses the consensus/XRPL uses the consensus/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(r|R)ipple (v|V)alidator/XRPL validator/g' "${FILE}"
|
||||
# cspell: enable
|
||||
${SED_COMMAND} -i 's/RippleLib/XrplLib/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/ripple-lib/XrplLib/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's@opt/ripple/@opt/xrpld/@g' "${FILE}"
|
||||
${SED_COMMAND} -i 's@src/ripple/@src/xrpld/@g' "${FILE}"
|
||||
${SED_COMMAND} -i 's@ripple/app/@xrpld/app/@g' "${FILE}"
|
||||
${SED_COMMAND} -i 's@github.com/ripple/rippled@github.com/XRPLF/rippled@g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/\ba xrpl/an xrpl/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/\ba XRPL/an XRPL/g' "${FILE}"
|
||||
done
|
||||
${SED_COMMAND} -i 's/ripple_libs/xrpl_libs/' BUILD.md
|
||||
${SED_COMMAND} -i 's/Ripple integrators/XRPL developers/' README.md
|
||||
${SED_COMMAND} -i 's/sanitizer-configuration-for-rippled/sanitizer-configuration-for-xrpld/' docs/build/sanitizers.md
|
||||
${SED_COMMAND} -i 's/rippled/xrpld/g' .github/scripts/levelization/README.md
|
||||
${SED_COMMAND} -i 's/rippled/xrpld/g' .github/scripts/strategy-matrix/generate.py
|
||||
${SED_COMMAND} -i 's@/rippled@/xrpld@g' docs/build/install.md
|
||||
${SED_COMMAND} -i 's@github.com/XRPLF/xrpld@github.com/XRPLF/rippled@g' docs/build/install.md
|
||||
${SED_COMMAND} -i 's/rippled/xrpld/g' docs/Doxyfile
|
||||
${SED_COMMAND} -i 's/ripple_basics/basics/' include/xrpl/basics/CountedObject.h
|
||||
${SED_COMMAND} -i 's/<ripple/<xrpl/' include/xrpl/protocol/AccountID.h
|
||||
${SED_COMMAND} -i 's/Ripple:/the XRPL:/g' include/xrpl/protocol/SecretKey.h
|
||||
${SED_COMMAND} -i 's/Ripple:/the XRPL:/g' include/xrpl/protocol/Seed.h
|
||||
${SED_COMMAND} -i 's/ripple/xrpl/g' src/test/README.md
|
||||
${SED_COMMAND} -i 's/www.ripple.com/www.xrpl.org/g' src/test/protocol/Seed_test.cpp
|
||||
|
||||
# Restore specific changes.
|
||||
${SED_COMMAND} -i 's@b5efcc/src/xrpld@b5efcc/src/ripple@' include/xrpl/protocol/README.md
|
||||
${SED_COMMAND} -i 's/dbPrefix_ = "xrpldb"/dbPrefix_ = "rippledb"/' src/xrpld/app/misc/SHAMapStoreImp.h # cspell: disable-line
|
||||
${SED_COMMAND} -i 's/configLegacyName = "xrpld.cfg"/configLegacyName = "rippled.cfg"/' src/xrpld/core/detail/Config.cpp
|
||||
|
||||
popd
|
||||
echo "Renaming complete."
|
||||
5
.github/scripts/rename/namespace.sh
vendored
5
.github/scripts/rename/namespace.sh
vendored
@@ -31,16 +31,17 @@ if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd ${DIRECTORY}
|
||||
pushd "${DIRECTORY}"
|
||||
|
||||
DIRECTORIES=("include" "src" "tests")
|
||||
for DIRECTORY in "${DIRECTORIES[@]}"; do
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
|
||||
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" \) | while read -r FILE; do
|
||||
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.macro" \) | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
${SED_COMMAND} -i 's/namespace ripple/namespace xrpl/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/ripple::/xrpl::/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/"ripple:/"xrpl::/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(BEAST_DEFINE_TESTSUITE.+)ripple(.+)/\1xrpl\2/g' "${FILE}"
|
||||
done
|
||||
done
|
||||
|
||||
2
.github/scripts/strategy-matrix/generate.py
vendored
2
.github/scripts/strategy-matrix/generate.py
vendored
@@ -235,7 +235,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
# so that they are easier to identify in the GitHub Actions UI, as long
|
||||
# names get truncated.
|
||||
# Add Address and Thread (both coupled with UB) sanitizers for specific bookworm distros.
|
||||
# GCC-Asan rippled-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
|
||||
# GCC-Asan xrpld-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
|
||||
if (
|
||||
os["distro_version"] == "bookworm"
|
||||
and f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
|
||||
|
||||
7
.github/workflows/publish-docs.yml
vendored
7
.github/workflows/publish-docs.yml
vendored
@@ -6,7 +6,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- "develop"
|
||||
- "release*"
|
||||
paths:
|
||||
- ".github/workflows/publish-docs.yml"
|
||||
- "*.md"
|
||||
@@ -82,13 +81,13 @@ jobs:
|
||||
cmake --build . --target docs --parallel ${BUILD_NPROC}
|
||||
|
||||
- name: Create documentation artifact
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
if: ${{ github.event.repository.visibility == 'public' && github.event_name == 'push' }}
|
||||
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
|
||||
with:
|
||||
path: ${{ env.BUILD_DIR }}/docs/html
|
||||
|
||||
deploy:
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
if: ${{ github.event.repository.visibility == 'public' && github.event_name == 'push' }}
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
@@ -100,4 +99,4 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deploy
|
||||
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
|
||||
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
|
||||
|
||||
@@ -199,7 +199,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Upload the binary (Linux)
|
||||
if: ${{ github.repository == 'XRPLF/rippled' && runner.os == 'Linux' }}
|
||||
if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }}
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: xrpld-${{ inputs.config_name }}
|
||||
@@ -298,7 +298,7 @@ jobs:
|
||||
|
||||
- name: Upload coverage report
|
||||
if: ${{ github.repository == 'XRPLF/rippled' && !inputs.build_only && env.COVERAGE_ENABLED == 'true' }}
|
||||
uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3
|
||||
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
|
||||
with:
|
||||
disable_search: true
|
||||
disable_telem: true
|
||||
|
||||
2
.github/workflows/reusable-check-rename.yml
vendored
2
.github/workflows/reusable-check-rename.yml
vendored
@@ -33,6 +33,8 @@ jobs:
|
||||
run: .github/scripts/rename/config.sh .
|
||||
- name: Check include guards
|
||||
run: .github/scripts/rename/include.sh .
|
||||
- name: Check documentation
|
||||
run: .github/scripts/rename/docs.sh .
|
||||
- name: Check for differences
|
||||
env:
|
||||
MESSAGE: |
|
||||
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
run-clang-tidy -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" ${TARGETS} 2>&1 | tee clang-tidy-output.txt
|
||||
|
||||
- name: Upload clang-tidy output
|
||||
if: steps.run_clang_tidy.outcome != 'success'
|
||||
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: clang-tidy-results
|
||||
|
||||
@@ -4,23 +4,23 @@ This changelog is intended to list all updates to the [public API methods](https
|
||||
|
||||
For info about how [API versioning](https://xrpl.org/request-formatting.html#api-versioning) works, including examples, please view the [XLS-22d spec](https://github.com/XRPLF/XRPL-Standards/discussions/54). For details about the implementation of API versioning, view the [implementation PR](https://github.com/XRPLF/rippled/pull/3155). API versioning ensures existing integrations and users continue to receive existing behavior, while those that request a higher API version will experience new behavior.
|
||||
|
||||
The API version controls the API behavior you see. This includes what properties you see in responses, what parameters you're permitted to send in requests, and so on. You specify the API version in each of your requests. When a breaking change is introduced to the `rippled` API, a new version is released. To avoid breaking your code, you should set (or increase) your version when you're ready to upgrade.
|
||||
The API version controls the API behavior you see. This includes what properties you see in responses, what parameters you're permitted to send in requests, and so on. You specify the API version in each of your requests. When a breaking change is introduced to the `xrpld` API, a new version is released. To avoid breaking your code, you should set (or increase) your version when you're ready to upgrade.
|
||||
|
||||
The [commandline](https://xrpl.org/docs/references/http-websocket-apis/api-conventions/request-formatting/#commandline-format) always uses the latest API version. The command line is intended for ad-hoc usage by humans, not programs or automated scripts. The command line is not meant for use in production code.
|
||||
|
||||
For a log of breaking changes, see the **API Version [number]** headings. In general, breaking changes are associated with a particular API Version number. For non-breaking changes, scroll to the **XRP Ledger version [x.y.z]** headings. Non-breaking changes are associated with a particular XRP Ledger (`rippled`) release.
|
||||
For a log of breaking changes, see the **API Version [number]** headings. In general, breaking changes are associated with a particular API Version number. For non-breaking changes, scroll to the **XRP Ledger version [x.y.z]** headings. Non-breaking changes are associated with a particular XRP Ledger (`xrpld`) release.
|
||||
|
||||
## API Version 3 (Beta)
|
||||
|
||||
API version 3 is currently a beta API. It requires enabling `[beta_rpc_api]` in the rippled configuration to use. See [API-VERSION-3.md](API-VERSION-3.md) for the full list of changes in API version 3.
|
||||
API version 3 is currently a beta API. It requires enabling `[beta_rpc_api]` in the xrpld configuration to use. See [API-VERSION-3.md](API-VERSION-3.md) for the full list of changes in API version 3.
|
||||
|
||||
## API Version 2
|
||||
|
||||
API version 2 is available in `rippled` version 2.0.0 and later. See [API-VERSION-2.md](API-VERSION-2.md) for the full list of changes in API version 2.
|
||||
API version 2 is available in `xrpld` version 2.0.0 and later. See [API-VERSION-2.md](API-VERSION-2.md) for the full list of changes in API version 2.
|
||||
|
||||
## API Version 1
|
||||
|
||||
This version is supported by all `rippled` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
|
||||
This version is supported by all `xrpld` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
|
||||
|
||||
## Unreleased
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# API Version 2
|
||||
|
||||
API version 2 is available in `rippled` version 2.0.0 and later. To use this API, clients specify `"api_version" : 2` in each request.
|
||||
API version 2 is available in `xrpld` version 2.0.0 and later. To use this API, clients specify `"api_version" : 2` in each request.
|
||||
|
||||
For info about how [API versioning](https://xrpl.org/request-formatting.html#api-versioning) works, including examples, please view the [XLS-22d spec](https://github.com/XRPLF/XRPL-Standards/discussions/54). For details about the implementation of API versioning, view the [implementation PR](https://github.com/XRPLF/rippled/pull/3155). API versioning ensures existing integrations and users continue to receive existing behavior, while those that request a higher API version will experience new behavior.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# API Version 3
|
||||
|
||||
API version 3 is currently a **beta API**. It requires enabling `[beta_rpc_api]` in the rippled configuration to use. To use this API, clients specify `"api_version" : 3` in each request.
|
||||
API version 3 is currently a **beta API**. It requires enabling `[beta_rpc_api]` in the xrpld configuration to use. To use this API, clients specify `"api_version" : 3` in each request.
|
||||
|
||||
For info about how [API versioning](https://xrpl.org/request-formatting.html#api-versioning) works, including examples, please view the [XLS-22d spec](https://github.com/XRPLF/XRPL-Standards/discussions/54). For details about the implementation of API versioning, view the [implementation PR](https://github.com/XRPLF/rippled/pull/3155). API versioning ensures existing integrations and users continue to receive existing behavior, while those that request a higher API version will experience new behavior.
|
||||
|
||||
|
||||
4
BUILD.md
4
BUILD.md
@@ -603,8 +603,8 @@ If you want to experiment with a new package, follow these steps:
|
||||
`default_options` property (with syntax `'$package:$option': $value`).
|
||||
3. Modify [`CMakeLists.txt`](./CMakeLists.txt):
|
||||
- Add a call to `find_package($package REQUIRED)`.
|
||||
- Link a library from the package to the target `ripple_libs`
|
||||
(search for the existing call to `target_link_libraries(ripple_libs INTERFACE ...)`).
|
||||
- Link a library from the package to the target `xrpl_libs`
|
||||
(search for the existing call to `target_link_libraries(xrpl_libs INTERFACE ...)`).
|
||||
4. Start coding! Don't forget to include whatever headers you need from the package.
|
||||
|
||||
[1]: https://github.com/conan-io/conan-center-index/issues/13168
|
||||
|
||||
@@ -533,7 +533,7 @@ All releases, including release candidates and betas, are handled
|
||||
differently from typical PRs. Most importantly, never use
|
||||
the Github UI to merge a release.
|
||||
|
||||
Rippled uses a linear workflow model that can be summarized as:
|
||||
Xrpld uses a linear workflow model that can be summarized as:
|
||||
|
||||
1. In between releases, developers work against the `develop` branch.
|
||||
2. Periodically, a maintainer will build and tag a beta version from
|
||||
|
||||
22
README.md
22
README.md
@@ -8,11 +8,11 @@ The [XRP Ledger](https://xrpl.org/) is a decentralized cryptographic ledger powe
|
||||
|
||||
[XRP](https://xrpl.org/xrp.html) is a public, counterparty-free crypto-asset native to the XRP Ledger, and is designed as a gas token for network services and to bridge different currencies. XRP is traded on the open-market and is available for anyone to access. The XRP Ledger was created in 2012 with a finite supply of 100 billion units of XRP.
|
||||
|
||||
## rippled
|
||||
## xrpld
|
||||
|
||||
The server software that powers the XRP Ledger is called `rippled` and is available in this repository under the permissive [ISC open-source license](LICENSE.md). The `rippled` server software is written primarily in C++ and runs on a variety of platforms. The `rippled` server software can run in several modes depending on its [configuration](https://xrpl.org/rippled-server-modes.html).
|
||||
The server software that powers the XRP Ledger is called `xrpld` and is available in this repository under the permissive [ISC open-source license](LICENSE.md). The `xrpld` server software is written primarily in C++ and runs on a variety of platforms. The `xrpld` server software can run in several modes depending on its [configuration](https://xrpl.org/rippled-server-modes.html).
|
||||
|
||||
If you are interested in running an **API Server** (including a **Full History Server**), take a look at [Clio](https://github.com/XRPLF/clio). (rippled Reporting Mode has been replaced by Clio.)
|
||||
If you are interested in running an **API Server** (including a **Full History Server**), take a look at [Clio](https://github.com/XRPLF/clio). (xrpld Reporting Mode has been replaced by Clio.)
|
||||
|
||||
### Build from Source
|
||||
|
||||
@@ -41,19 +41,19 @@ If you are interested in running an **API Server** (including a **Full History S
|
||||
|
||||
Here are some good places to start learning the source code:
|
||||
|
||||
- Read the markdown files in the source tree: `src/ripple/**/*.md`.
|
||||
- Read the markdown files in the source tree: `src/xrpld/**/*.md`.
|
||||
- Read [the levelization document](.github/scripts/levelization) to get an idea of the internal dependency graph.
|
||||
- In the big picture, the `main` function constructs an `ApplicationImp` object, which implements the `Application` virtual interface. Almost every component in the application takes an `Application&` parameter in its constructor, typically named `app` and stored as a member variable `app_`. This allows most components to depend on any other component.
|
||||
|
||||
### Repository Contents
|
||||
|
||||
| Folder | Contents |
|
||||
| :--------- | :----------------------------------------------- |
|
||||
| `./bin` | Scripts and data files for Ripple integrators. |
|
||||
| `./Builds` | Platform-specific guides for building `rippled`. |
|
||||
| `./docs` | Source documentation files and doxygen config. |
|
||||
| `./cfg` | Example configuration files. |
|
||||
| `./src` | Source code. |
|
||||
| Folder | Contents |
|
||||
| :--------- | :--------------------------------------------- |
|
||||
| `./bin` | Scripts and data files for XRPL developers. |
|
||||
| `./Builds` | Platform-specific guides for building `xrpld`. |
|
||||
| `./docs` | Source documentation files and doxygen config. |
|
||||
| `./cfg` | Example configuration files. |
|
||||
| `./src` | Source code. |
|
||||
|
||||
Some of the directories under `src` are external repositories included using
|
||||
git-subtree. See those directories' README files for more details.
|
||||
|
||||
@@ -6,7 +6,7 @@ For more details on operating an XRP Ledger server securely, please visit https:
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Software constantly evolves. In order to focus resources, we only generally only accept vulnerability reports that affect recent and current versions of the software. We always accept reports for issues present in the **master**, **release** or **develop** branches, and with proposed, [open pull requests](https://github.com/ripple/rippled/pulls).
|
||||
Software constantly evolves. In order to focus resources, we only generally only accept vulnerability reports that affect recent and current versions of the software. We always accept reports for issues present in the **master**, **release** or **develop** branches, and with proposed, [open pull requests](https://github.com/XRPLF/rippled/pulls).
|
||||
|
||||
## Identifying and Reporting Vulnerabilities
|
||||
|
||||
@@ -59,11 +59,11 @@ While we commit to responding with 24 hours of your initial report with our tria
|
||||
|
||||
## Bug Bounty Program
|
||||
|
||||
[Ripple](https://ripple.com) is generously sponsoring a bug bounty program for vulnerabilities in [`rippled`](https://github.com/XRPLF/rippled) (and other related projects, like [`xrpl.js`](https://github.com/XRPLF/xrpl.js), [`xrpl-py`](https://github.com/XRPLF/xrpl-py), [`xrpl4j`](https://github.com/XRPLF/xrpl4j)).
|
||||
[Ripple](https://ripple.com) is generously sponsoring a bug bounty program for vulnerabilities in [`xrpld`](https://github.com/XRPLF/rippled) (and other related projects, like [`xrpl.js`](https://github.com/XRPLF/xrpl.js), [`xrpl-py`](https://github.com/XRPLF/xrpl-py), [`xrpl4j`](https://github.com/XRPLF/xrpl4j)).
|
||||
|
||||
This program allows us to recognize and reward individuals or groups that identify and report bugs. In summary, in order to qualify for a bounty, the bug must be:
|
||||
|
||||
1. **In scope**. Only bugs in software under the scope of the program qualify. Currently, that means `rippled`, `xrpl.js`, `xrpl-py`, `xrpl4j`.
|
||||
1. **In scope**. Only bugs in software under the scope of the program qualify. Currently, that means `xrpld`, `xrpl.js`, `xrpl-py`, `xrpl4j`.
|
||||
2. **Relevant**. A security issue, posing a danger to user funds, privacy, or the operation of the XRP Ledger.
|
||||
3. **Original and previously unknown**. Bugs that are already known and discussed in public do not qualify. Previously reported bugs, even if publicly unknown, are not eligible.
|
||||
4. **Specific**. We welcome general security advice or recommendations, but we cannot pay bounties for that.
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
# https://vl.ripple.com
|
||||
# https://unl.xrplf.org
|
||||
# http://127.0.0.1:8000
|
||||
# file:///etc/opt/ripple/vl.txt
|
||||
# file:///etc/opt/xrpld/vl.txt
|
||||
#
|
||||
# [validator_list_keys]
|
||||
#
|
||||
@@ -43,11 +43,11 @@
|
||||
# ED307A760EE34F2D0CAA103377B1969117C38B8AA0AA1E2A24DAC1F32FC97087ED
|
||||
#
|
||||
|
||||
# The default validator list publishers that the rippled instance
|
||||
# The default validator list publishers that the xrpld instance
|
||||
# trusts.
|
||||
#
|
||||
# WARNING: Changing these values can cause your rippled instance to see a
|
||||
# validated ledger that contradicts other rippled instances'
|
||||
# WARNING: Changing these values can cause your xrpld instance to see a
|
||||
# validated ledger that contradicts other xrpld instances'
|
||||
# validated ledgers (aka a ledger fork) if your validator list(s)
|
||||
# do not sufficiently overlap with the list(s) used by others.
|
||||
# See: https://arxiv.org/pdf/1802.07242.pdf
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# 2. Peer Protocol
|
||||
#
|
||||
# 3. Ripple Protocol
|
||||
# 3. XRPL protocol
|
||||
#
|
||||
# 4. HTTPS Client
|
||||
#
|
||||
@@ -383,7 +383,7 @@
|
||||
#
|
||||
# These settings control security and access attributes of the Peer to Peer
|
||||
# server section of the xrpld process. Peer Protocol implements the
|
||||
# Ripple Payment protocol. It is over peer connections that transactions
|
||||
# XRPL payment protocol. It is over peer connections that transactions
|
||||
# and validations are passed from to machine to machine, to determine the
|
||||
# contents of validated ledgers.
|
||||
#
|
||||
@@ -406,7 +406,7 @@
|
||||
#
|
||||
# [ips]
|
||||
#
|
||||
# List of hostnames or ips where the Ripple protocol is served. A default
|
||||
# List of hostnames or ips where the XRPL protocol is served. A default
|
||||
# starter list is included in the code and used if no other hostnames are
|
||||
# available.
|
||||
#
|
||||
@@ -435,7 +435,7 @@
|
||||
# List of IP addresses or hostnames to which xrpld should always attempt to
|
||||
# maintain peer connections with. This is useful for manually forming private
|
||||
# networks, for example to configure a validation server that connects to the
|
||||
# Ripple network through a public-facing server, or for building a set
|
||||
# XRPL network through a public-facing server, or for building a set
|
||||
# of cluster peers.
|
||||
#
|
||||
# One address or domain names per line is allowed. A port must be specified
|
||||
@@ -748,8 +748,8 @@
|
||||
# the folder in which the xrpld.cfg file is located.
|
||||
#
|
||||
# Examples:
|
||||
# /home/ripple/validators.txt
|
||||
# C:/home/ripple/validators.txt
|
||||
# /home/username/validators.txt
|
||||
# C:/home/username/validators.txt
|
||||
#
|
||||
# Example content:
|
||||
# [validators]
|
||||
@@ -840,7 +840,7 @@
|
||||
#
|
||||
# 0: Disable the ledger replay feature [default]
|
||||
# 1: Enable the ledger replay feature. With this feature enabled, when
|
||||
# acquiring a ledger from the network, a xrpld node only downloads
|
||||
# acquiring a ledger from the network, an xrpld node only downloads
|
||||
# the ledger header and the transactions instead of the whole ledger.
|
||||
# And the ledger is built by applying the transactions to the parent
|
||||
# ledger.
|
||||
@@ -853,7 +853,7 @@
|
||||
#
|
||||
# The xrpld server instance uses HTTPS GET requests in a variety of
|
||||
# circumstances, including but not limited to contacting trusted domains to
|
||||
# fetch information such as mapping an email address to a Ripple Payment
|
||||
# fetch information such as mapping an email address to an XRPL payment
|
||||
# Network address.
|
||||
#
|
||||
# [ssl_verify]
|
||||
@@ -1227,7 +1227,7 @@
|
||||
#
|
||||
#----------
|
||||
#
|
||||
# The vote settings configure settings for the entire Ripple network.
|
||||
# The vote settings configure settings for the entire XRPL network.
|
||||
# While a single instance of xrpld cannot unilaterally enforce network-wide
|
||||
# settings, these choices become part of the instance's vote during the
|
||||
# consensus process for each voting ledger.
|
||||
|
||||
@@ -558,7 +558,7 @@ network delay. A test case specifies:
|
||||
1. a UNL with different number of validators for different test cases,
|
||||
1. a network with zero or more non-validator nodes,
|
||||
1. a sequence of validator reliability change events (by killing/restarting
|
||||
nodes, or by running modified rippled that does not send all validation
|
||||
nodes, or by running modified xrpld that does not send all validation
|
||||
messages),
|
||||
1. the correct outcomes.
|
||||
|
||||
@@ -566,7 +566,7 @@ For all the test cases, the correct outcomes are verified by examining logs. We
|
||||
will grep the log to see if the correct negative UNLs are generated, and whether
|
||||
or not the network is making progress when it should be. The ripdtop tool will
|
||||
be helpful for monitoring validators' states and ledger progress. Some of the
|
||||
timing parameters of rippled will be changed to have faster ledger time. Most if
|
||||
timing parameters of xrpld will be changed to have faster ledger time. Most if
|
||||
not all test cases do not need client transactions.
|
||||
|
||||
For example, the test cases for the prototype:
|
||||
@@ -583,7 +583,7 @@ For example, the test cases for the prototype:
|
||||
|
||||
We considered testing with the current unit test framework, specifically the
|
||||
[Consensus Simulation
|
||||
Framework](https://github.com/ripple/rippled/blob/develop/src/test/csf/README.md)
|
||||
Framework](https://github.com/XRPLF/rippled/blob/develop/src/test/csf/README.md)
|
||||
(CSF). However, the CSF currently can only test the generic consensus algorithm
|
||||
as in the paper: [Analysis of the XRP Ledger Consensus
|
||||
Protocol](https://arxiv.org/abs/1802.07242).
|
||||
|
||||
@@ -4,7 +4,7 @@ skinparam sequenceArrowThickness 2
|
||||
skinparam roundcorner 20
|
||||
skinparam maxmessagesize 160
|
||||
|
||||
actor "Rippled Start" as RS
|
||||
actor "Xrpld Start" as RS
|
||||
participant "Timer" as T
|
||||
participant "NetworkOPs" as NOP
|
||||
participant "ValidatorList" as VL #lightgreen
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# `rippled` Docker Image
|
||||
# `xrpld` Docker Image
|
||||
|
||||
- Some info relating to Docker containers can be found here: [../Builds/containers](../Builds/containers)
|
||||
- Images for building and testing rippled can be found here: [thejohnfreeman/rippled-docker](https://github.com/thejohnfreeman/rippled-docker/)
|
||||
- These images do not have rippled. They have all the tools necessary to build rippled.
|
||||
- Images for building and testing xrpld can be found here: [thejohnfreeman/rippled-docker](https://github.com/thejohnfreeman/rippled-docker/)
|
||||
- These images do not have xrpld. They have all the tools necessary to build xrpld.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "rippled"
|
||||
PROJECT_NAME = "xrpld"
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_BRIEF =
|
||||
PROJECT_LOGO =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## Heap profiling of rippled with jemalloc
|
||||
## Heap profiling of xrpld with jemalloc
|
||||
|
||||
The jemalloc library provides a good API for doing heap analysis,
|
||||
including a mechanism to dump a description of the heap from within the
|
||||
@@ -7,26 +7,26 @@ activity in general, as well as how to acquire the software, are available on
|
||||
the jemalloc site:
|
||||
[https://github.com/jemalloc/jemalloc/wiki/Use-Case:-Heap-Profiling](https://github.com/jemalloc/jemalloc/wiki/Use-Case:-Heap-Profiling)
|
||||
|
||||
jemalloc is acquired separately from rippled, and is not affiliated
|
||||
jemalloc is acquired separately from xrpld, and is not affiliated
|
||||
with Ripple Labs. If you compile and install jemalloc from the
|
||||
source release with default options, it will install the library and header
|
||||
under `/usr/local/lib` and `/usr/local/include`, respectively. Heap
|
||||
profiling has been tested with rippled on a Linux platform. It should
|
||||
work on platforms on which both rippled and jemalloc are available.
|
||||
profiling has been tested with xrpld on a Linux platform. It should
|
||||
work on platforms on which both xrpld and jemalloc are available.
|
||||
|
||||
To link rippled with jemalloc, the argument
|
||||
To link xrpld with jemalloc, the argument
|
||||
`profile-jemalloc=<jemalloc_dir>` is provided after the optional target.
|
||||
The `<jemalloc_dir>` argument should be the same as that of the
|
||||
`--prefix` parameter passed to the jemalloc configure script when building.
|
||||
|
||||
## Examples:
|
||||
|
||||
Build rippled with jemalloc library under /usr/local/lib and
|
||||
Build xrpld with jemalloc library under /usr/local/lib and
|
||||
header under /usr/local/include:
|
||||
|
||||
$ scons profile-jemalloc=/usr/local
|
||||
|
||||
Build rippled using clang with the jemalloc library under /opt/local/lib
|
||||
Build xrpld using clang with the jemalloc library under /opt/local/lib
|
||||
and header under /opt/local/include:
|
||||
|
||||
$ scons clang profile-jemalloc=/opt/local
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
# Building documentation
|
||||
|
||||
## Dependencies
|
||||
|
||||
Install these dependencies:
|
||||
|
||||
- [Doxygen](http://www.doxygen.nl): All major platforms have [official binary
|
||||
distributions](http://www.doxygen.nl/download.html#srcbin), or you can
|
||||
build from [source](http://www.doxygen.nl/download.html#srcbin).
|
||||
- MacOS: We recommend installing via Homebrew: `brew install doxygen`.
|
||||
The executable will be installed in `/usr/local/bin` which is already
|
||||
in the default `PATH`.
|
||||
|
||||
If you use the official binary distribution, then you'll need to make
|
||||
Doxygen available to your command line. You can do this by adding
|
||||
a symbolic link from `/usr/local/bin` to the `doxygen` executable. For
|
||||
example,
|
||||
|
||||
```
|
||||
$ ln -s /Applications/Doxygen.app/Contents/Resources/doxygen /usr/local/bin/doxygen
|
||||
```
|
||||
|
||||
- [PlantUML](http://plantuml.com):
|
||||
1. Install a functioning Java runtime, if you don't already have one.
|
||||
2. Download [`plantuml.jar`](http://sourceforge.net/projects/plantuml/files/plantuml.jar/download).
|
||||
|
||||
- [Graphviz](https://www.graphviz.org):
|
||||
- Linux: Install from your package manager.
|
||||
- Windows: Use an [official installer](https://graphviz.gitlab.io/_pages/Download/Download_windows.html).
|
||||
- MacOS: Install via Homebrew: `brew install graphviz`.
|
||||
|
||||
## Docker
|
||||
|
||||
Instead of installing the above dependencies locally, you can use the official
|
||||
build environment Docker image, which has all of them installed already.
|
||||
|
||||
1. Install [Docker](https://docs.docker.com/engine/installation/)
|
||||
2. Pull the image:
|
||||
|
||||
```
|
||||
sudo docker pull rippleci/rippled-ci-builder:2944b78d22db
|
||||
```
|
||||
|
||||
3. Run the image from the project folder:
|
||||
|
||||
```
|
||||
sudo docker run -v $PWD:/opt/rippled --rm rippleci/rippled-ci-builder:2944b78d22db
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
There is a `docs` target in the CMake configuration.
|
||||
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -Donly_docs=ON ..
|
||||
cmake --build . --target docs --parallel
|
||||
```
|
||||
|
||||
The output will be in `build/docs/html`.
|
||||
8
docs/build/depend.md
vendored
8
docs/build/depend.md
vendored
@@ -20,7 +20,7 @@ CMakeToolchain
|
||||
|
||||
```
|
||||
# If you want to depend on a version of libxrpl that is not in ConanCenter,
|
||||
# then you can export the recipe from the rippled project.
|
||||
# then you can export the recipe from the xrpld project.
|
||||
conan export <path>
|
||||
```
|
||||
|
||||
@@ -49,9 +49,9 @@ cmake --build . --parallel
|
||||
|
||||
## CMake subdirectory
|
||||
|
||||
The second method adds the [rippled][] project as a CMake
|
||||
The second method adds the [xrpld][] project as a CMake
|
||||
[subdirectory][add_subdirectory].
|
||||
This method works well when you keep the rippled project as a Git
|
||||
This method works well when you keep the xrpld project as a Git
|
||||
[submodule][].
|
||||
It's good for when you want to make changes to libxrpl as part of your own
|
||||
project.
|
||||
@@ -90,6 +90,6 @@ cmake --build . --parallel
|
||||
|
||||
[add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html
|
||||
[submodule]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
|
||||
[rippled]: https://github.com/ripple/rippled
|
||||
[xrpld]: https://github.com/XRPLF/rippled
|
||||
[Conan]: https://docs.conan.io/
|
||||
[CMake]: https://cmake.org/cmake/help/latest/
|
||||
|
||||
2
docs/build/environment.md
vendored
2
docs/build/environment.md
vendored
@@ -55,7 +55,7 @@ clang --version
|
||||
### Install Xcode Specific Version (Optional)
|
||||
|
||||
If you develop other applications using XCode you might be consistently updating to the newest version of Apple Clang.
|
||||
This will likely cause issues building rippled. You may want to install a specific version of Xcode:
|
||||
This will likely cause issues building xrpld. You may want to install a specific version of Xcode:
|
||||
|
||||
1. **Download Xcode**
|
||||
- Visit [Apple Developer Downloads](https://developer.apple.com/download/more/)
|
||||
|
||||
58
docs/build/install.md
vendored
58
docs/build/install.md
vendored
@@ -1,4 +1,4 @@
|
||||
This document contains instructions for installing rippled.
|
||||
This document contains instructions for installing xrpld.
|
||||
The APT package manager is common on Debian-based Linux distributions like
|
||||
Ubuntu,
|
||||
while the YUM package manager is common on Red Hat-based Linux distributions
|
||||
@@ -8,7 +8,7 @@ and the only supported option for installing custom builds.
|
||||
|
||||
## From source
|
||||
|
||||
From a source build, you can install rippled and libxrpl using CMake's
|
||||
From a source build, you can install xrpld and libxrpl using CMake's
|
||||
`--install` mode:
|
||||
|
||||
```
|
||||
@@ -16,7 +16,7 @@ cmake --install . --prefix /opt/local
|
||||
```
|
||||
|
||||
The default [prefix][1] is typically `/usr/local` on Linux and macOS and
|
||||
`C:/Program Files/rippled` on Windows.
|
||||
`C:/Program Files/xrpld` on Windows.
|
||||
|
||||
[1]: https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html
|
||||
|
||||
@@ -50,9 +50,9 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and
|
||||
|
||||
In particular, make sure that the fingerprint matches. (In the above example, the fingerprint is on the third line, starting with `C001`.)
|
||||
|
||||
5. Add the appropriate Ripple repository for your operating system version:
|
||||
5. Add the appropriate XRPL repository for your operating system version:
|
||||
|
||||
echo "deb [signed-by=/usr/local/share/keyrings/ripple-key.gpg] https://repos.ripple.com/repos/rippled-deb focal stable" | \
|
||||
echo "deb [signed-by=/usr/local/share/keyrings/ripple-key.gpg] https://repos.ripple.com/repos/xrpld-deb focal stable" | \
|
||||
sudo tee -a /etc/apt/sources.list.d/ripple.list
|
||||
|
||||
The above example is appropriate for **Ubuntu 20.04 Focal Fossa**. For other operating systems, replace the word `focal` with one of the following:
|
||||
@@ -61,33 +61,33 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and
|
||||
- `bullseye` for **Debian 11 Bullseye**
|
||||
- `buster` for **Debian 10 Buster**
|
||||
|
||||
If you want access to development or pre-release versions of `rippled`, use one of the following instead of `stable`:
|
||||
- `unstable` - Pre-release builds ([`release` branch](https://github.com/ripple/rippled/tree/release))
|
||||
- `nightly` - Experimental/development builds ([`develop` branch](https://github.com/ripple/rippled/tree/develop))
|
||||
If you want access to development or pre-release versions of `xrpld`, use one of the following instead of `stable`:
|
||||
- `unstable` - Pre-release builds ([`release` branch](https://github.com/XRPLF/rippled/tree/release))
|
||||
- `nightly` - Experimental/development builds ([`develop` branch](https://github.com/XRPLF/rippled/tree/develop))
|
||||
|
||||
**Warning:** Unstable and nightly builds may be broken at any time. Do not use these builds for production servers.
|
||||
|
||||
6. Fetch the Ripple repository.
|
||||
6. Fetch the XRPL repository.
|
||||
|
||||
sudo apt -y update
|
||||
|
||||
7. Install the `rippled` software package:
|
||||
7. Install the `xrpld` software package:
|
||||
|
||||
sudo apt -y install rippled
|
||||
sudo apt -y install xrpld
|
||||
|
||||
8. Check the status of the `rippled` service:
|
||||
8. Check the status of the `xrpld` service:
|
||||
|
||||
systemctl status rippled.service
|
||||
systemctl status xrpld.service
|
||||
|
||||
The `rippled` service should start automatically. If not, you can start it manually:
|
||||
The `xrpld` service should start automatically. If not, you can start it manually:
|
||||
|
||||
sudo systemctl start rippled.service
|
||||
sudo systemctl start xrpld.service
|
||||
|
||||
9. Optional: allow `rippled` to bind to privileged ports.
|
||||
9. Optional: allow `xrpld` to bind to privileged ports.
|
||||
|
||||
This allows you to serve incoming API requests on port 80 or 443. (If you want to do so, you must also update the config file's port settings.)
|
||||
|
||||
sudo setcap 'cap_net_bind_service=+ep' /opt/ripple/bin/rippled
|
||||
sudo setcap 'cap_net_bind_service=+ep' /opt/xrpld/bin/xrpld
|
||||
|
||||
## With the YUM package manager
|
||||
|
||||
@@ -106,8 +106,8 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
repo_gpgcheck=1
|
||||
baseurl=https://repos.ripple.com/repos/rippled-rpm/stable/
|
||||
gpgkey=https://repos.ripple.com/repos/rippled-rpm/stable/repodata/repomd.xml.key
|
||||
baseurl=https://repos.ripple.com/repos/xrpld-rpm/stable/
|
||||
gpgkey=https://repos.ripple.com/repos/xrpld-rpm/stable/repodata/repomd.xml.key
|
||||
REPOFILE
|
||||
|
||||
_Unstable_
|
||||
@@ -118,8 +118,8 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
repo_gpgcheck=1
|
||||
baseurl=https://repos.ripple.com/repos/rippled-rpm/unstable/
|
||||
gpgkey=https://repos.ripple.com/repos/rippled-rpm/unstable/repodata/repomd.xml.key
|
||||
baseurl=https://repos.ripple.com/repos/xrpld-rpm/unstable/
|
||||
gpgkey=https://repos.ripple.com/repos/xrpld-rpm/unstable/repodata/repomd.xml.key
|
||||
REPOFILE
|
||||
|
||||
_Nightly_
|
||||
@@ -130,22 +130,22 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
repo_gpgcheck=1
|
||||
baseurl=https://repos.ripple.com/repos/rippled-rpm/nightly/
|
||||
gpgkey=https://repos.ripple.com/repos/rippled-rpm/nightly/repodata/repomd.xml.key
|
||||
baseurl=https://repos.ripple.com/repos/xrpld-rpm/nightly/
|
||||
gpgkey=https://repos.ripple.com/repos/xrpld-rpm/nightly/repodata/repomd.xml.key
|
||||
REPOFILE
|
||||
|
||||
2. Fetch the latest repo updates:
|
||||
|
||||
sudo yum -y update
|
||||
|
||||
3. Install the new `rippled` package:
|
||||
3. Install the new `xrpld` package:
|
||||
|
||||
sudo yum install -y rippled
|
||||
sudo yum install -y xrpld
|
||||
|
||||
4. Configure the `rippled` service to start on boot:
|
||||
4. Configure the `xrpld` service to start on boot:
|
||||
|
||||
sudo systemctl enable rippled.service
|
||||
sudo systemctl enable xrpld.service
|
||||
|
||||
5. Start the `rippled` service:
|
||||
5. Start the `xrpld` service:
|
||||
|
||||
sudo systemctl start rippled.service
|
||||
sudo systemctl start xrpld.service
|
||||
|
||||
6
docs/build/sanitizers.md
vendored
6
docs/build/sanitizers.md
vendored
@@ -1,9 +1,9 @@
|
||||
# Sanitizer Configuration for Rippled
|
||||
# Sanitizer Configuration for Xrpld
|
||||
|
||||
This document explains how to properly configure and run sanitizers (AddressSanitizer, undefinedbehaviorSanitizer, ThreadSanitizer) with the xrpld project.
|
||||
Corresponding suppression files are located in the `sanitizers/suppressions` directory.
|
||||
|
||||
- [Sanitizer Configuration for Rippled](#sanitizer-configuration-for-rippled)
|
||||
- [Sanitizer Configuration for Xrpld](#sanitizer-configuration-for-xrpld)
|
||||
- [Building with Sanitizers](#building-with-sanitizers)
|
||||
- [Summary](#summary)
|
||||
- [Build steps:](#build-steps)
|
||||
@@ -100,7 +100,7 @@ export LSAN_OPTIONS="include=sanitizers/suppressions/runtime-lsan-options.txt:su
|
||||
|
||||
- Boost intrusive containers (used in `aged_unordered_container`) trigger false positives
|
||||
- Boost context switching (used in `Workers.cpp`) confuses ASAN's stack tracking
|
||||
- Since we usually don't build Boost (because we don't want to instrument Boost and detect issues in Boost code) with ASAN but use Boost containers in ASAN instrumented rippled code, it generates false positives.
|
||||
- Since we usually don't build Boost (because we don't want to instrument Boost and detect issues in Boost code) with ASAN but use Boost containers in ASAN instrumented xrpld code, it generates false positives.
|
||||
- Building dependencies with ASAN instrumentation reduces false positives. But we don't want to instrument dependencies like Boost with ASAN because it is slow (to compile as well as run tests) and not necessary.
|
||||
- See: https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow
|
||||
- More such flags are detailed [here](https://github.com/google/sanitizers/wiki/AddressSanitizerFlags)
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
Consensus is the task of reaching agreement within a distributed system in the
|
||||
presence of faulty or even malicious participants. This document outlines the
|
||||
[XRP Ledger Consensus Algorithm](https://arxiv.org/abs/1802.07242)
|
||||
as implemented in [rippled](https://github.com/ripple/rippled), but
|
||||
as implemented in [xrpld](https://github.com/XRPLF/rippled), but
|
||||
focuses on its utility as a generic consensus algorithm independent of the
|
||||
detailed mechanics of the Ripple Consensus Ledger. Most notably, the algorithm
|
||||
detailed mechanics of the XRPL consensus Ledger. Most notably, the algorithm
|
||||
does not require fully synchronous communication between all nodes in the
|
||||
network, or even a fixed network topology, but instead achieves consensus via
|
||||
collectively trusted subnetworks.
|
||||
@@ -15,7 +15,7 @@ collectively trusted subnetworks.
|
||||
## Distributed Agreement
|
||||
|
||||
A challenge for distributed systems is reaching agreement on changes in shared
|
||||
state. For the Ripple network, the shared state is the current ledger--account
|
||||
state. For the XRPL network, the shared state is the current ledger--account
|
||||
information, account balances, order books and other financial data. We will
|
||||
refer to shared distributed state as a /ledger/ throughout the remainder of this
|
||||
document.
|
||||
@@ -23,7 +23,7 @@ document.
|
||||

|
||||
|
||||
As shown above, new ledgers are made by applying a set of transactions to the
|
||||
prior ledger. For the Ripple network, transactions include payments,
|
||||
prior ledger. For the XRPL network, transactions include payments,
|
||||
modification of account settings, updates to offers and more.
|
||||
|
||||
In a centralized system, generating the next ledger is trivial since there is a
|
||||
@@ -33,10 +33,10 @@ the set of transactions to include, the order to apply those transactions, and
|
||||
even the resulting ledger after applying the transactions. This is even more
|
||||
difficult when some participants are faulty or malicious.
|
||||
|
||||
The Ripple network is a decentralized and **trust-full** network. Anyone is free
|
||||
The XRPL network is a decentralized and **trust-full** network. Anyone is free
|
||||
to join and participants are free to choose a subset of peers that are
|
||||
collectively trusted to not collude in an attempt to defraud the participant.
|
||||
Leveraging this network of trust, the Ripple algorithm has two main components.
|
||||
Leveraging this network of trust, the XRPL algorithm has two main components.
|
||||
|
||||
- _Consensus_ in which network participants agree on the transactions to apply
|
||||
to a prior ledger, based on the positions of their chosen peers.
|
||||
@@ -54,9 +54,9 @@ and was abandoned.
|
||||
|
||||
The remainder of this section describes the Consensus and Validation algorithms
|
||||
in more detail and is meant as a companion guide to understanding the generic
|
||||
implementation in `rippled`. The document **does not** discuss correctness,
|
||||
implementation in `xrpld`. The document **does not** discuss correctness,
|
||||
fault-tolerance or liveness properties of the algorithms or the full details of
|
||||
how they integrate within `rippled` to support the Ripple Consensus Ledger.
|
||||
how they integrate within `xrpld` to support the XRPL consensus Ledger.
|
||||
|
||||
## Consensus Overview
|
||||
|
||||
|
||||
2
external/README.md
vendored
2
external/README.md
vendored
@@ -1,6 +1,6 @@
|
||||
# External Conan recipes
|
||||
|
||||
The subdirectories in this directory contain external libraries used by rippled.
|
||||
The subdirectories in this directory contain external libraries used by xrpld.
|
||||
|
||||
| Folder | Upstream | Description |
|
||||
| :--------------- | :------------------------------------------------------------- | :------------------------------------------------------------------------------------------- |
|
||||
|
||||
4
external/antithesis-sdk/CMakeLists.txt
vendored
4
external/antithesis-sdk/CMakeLists.txt
vendored
@@ -1,11 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
# Note, version set explicitly by rippled project
|
||||
# Note, version set explicitly by xrpld project
|
||||
project(antithesis-sdk-cpp VERSION 0.4.4 LANGUAGES CXX)
|
||||
|
||||
add_library(antithesis-sdk-cpp INTERFACE antithesis_sdk.h)
|
||||
|
||||
# Note, both sections below created by rippled project
|
||||
# Note, both sections below created by xrpld project
|
||||
target_include_directories(antithesis-sdk-cpp INTERFACE
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
Derived classes have their instances counted automatically. This is used
|
||||
for reporting purposes.
|
||||
|
||||
@ingroup ripple_basics
|
||||
@ingroup basics
|
||||
*/
|
||||
template <class Object>
|
||||
class CountedObject
|
||||
|
||||
@@ -59,7 +59,7 @@ concept CAdoptTag = std::is_same_v<T, SharedIntrusiveAdoptIncrementStrongTag> ||
|
||||
still retaining the reference counts. For example, for SHAMapInnerNodes the
|
||||
children may be reset in that function. Note that std::shared_pointer WILL
|
||||
run the destructor when the strong count reaches zero, but may not free the
|
||||
memory used by the object until the weak count reaches zero. In rippled, we
|
||||
memory used by the object until the weak count reaches zero. In xrpld, we
|
||||
typically allocate shared pointers with the `make_shared` function. When
|
||||
that is used, the memory is not reclaimed until the weak count reaches zero.
|
||||
*/
|
||||
|
||||
@@ -33,7 +33,7 @@ enum class ReleaseWeakRefAction { noop, destroy };
|
||||
/** Implement the strong count, weak count, and bit flags for an intrusive
|
||||
pointer.
|
||||
|
||||
A class can satisfy the requirements of a xrpl::IntrusivePointer by
|
||||
A class can satisfy the requirements of an xrpl::IntrusivePointer by
|
||||
inheriting from this class.
|
||||
*/
|
||||
struct IntrusiveRefCounts
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
Utility functions and classes.
|
||||
|
||||
ripple/basic should contain no dependencies on other modules.
|
||||
libxrpl/basics should contain no dependencies on other modules.
|
||||
|
||||
# Choosing a rippled container.
|
||||
# Choosing an xrpld container.
|
||||
|
||||
- `std::vector`
|
||||
- For ordered containers with most insertions or erases at the end.
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
explicit UptimeClock() = default;
|
||||
|
||||
static time_point
|
||||
now(); // seconds since rippled program start
|
||||
now(); // seconds since xrpld program start
|
||||
|
||||
private:
|
||||
static std::atomic<rep> now_;
|
||||
|
||||
@@ -16,12 +16,12 @@ namespace xrpl {
|
||||
static_assert(
|
||||
std::is_integral<beast::xor_shift_engine::result_type>::value &&
|
||||
std::is_unsigned<beast::xor_shift_engine::result_type>::value,
|
||||
"The Ripple default PRNG engine must return an unsigned integral type.");
|
||||
"The XRPL default PRNG engine must return an unsigned integral type.");
|
||||
|
||||
static_assert(
|
||||
std::numeric_limits<beast::xor_shift_engine::result_type>::max() >=
|
||||
std::numeric_limits<std::uint64_t>::max(),
|
||||
"The Ripple default PRNG engine return must be at least 64 bits wide.");
|
||||
"The XRPL default PRNG engine return must be at least 64 bits wide.");
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -70,14 +70,24 @@ JobQueue::Coro::resume()
|
||||
running_ = true;
|
||||
}
|
||||
{
|
||||
std::lock_guard lock(jq_.m_mutex);
|
||||
std::lock_guard lk(jq_.m_mutex);
|
||||
--jq_.nSuspend_;
|
||||
}
|
||||
auto saved = detail::getLocalValues().release();
|
||||
detail::getLocalValues().reset(&lvs_);
|
||||
std::lock_guard lock(mutex_);
|
||||
XRPL_ASSERT(static_cast<bool>(coro_), "xrpl::JobQueue::Coro::resume : is runnable");
|
||||
coro_();
|
||||
// A late resume() can arrive after the coroutine has already completed.
|
||||
// This is an expected (if rare) outcome of the race condition documented
|
||||
// in JobQueue.h:354-377 where post() schedules a resume job before the
|
||||
// coroutine yields — the mutex serializes access, but by the time this
|
||||
// resume() acquires the lock the coroutine may have already run to
|
||||
// completion. Calling operator() on a completed boost::coroutine2 is
|
||||
// undefined behavior, so we must check and skip invoking the coroutine
|
||||
// body if it has already completed.
|
||||
if (coro_)
|
||||
{
|
||||
coro_();
|
||||
}
|
||||
detail::getLocalValues().release();
|
||||
detail::getLocalValues().reset(saved);
|
||||
std::lock_guard lk(mutex_run_);
|
||||
|
||||
@@ -99,8 +99,8 @@ public:
|
||||
Effects:
|
||||
The coroutine continues execution from where it last left off
|
||||
using this same thread.
|
||||
Undefined behavior if called after the coroutine has completed
|
||||
with a return (as opposed to a yield()).
|
||||
If the coroutine has already completed, returns immediately
|
||||
(handles the documented post-before-yield race condition).
|
||||
Undefined behavior if resume() or post() called consecutively
|
||||
without a corresponding yield.
|
||||
*/
|
||||
@@ -357,8 +357,10 @@ private:
|
||||
If the post() job were to be executed before yield(), undefined behavior
|
||||
would occur. The lock ensures that coro_ is not called again until we exit
|
||||
the coroutine. At which point a scheduled resume() job waiting on the lock
|
||||
would gain entry, harmlessly call coro_ and immediately return as we have
|
||||
already completed the coroutine.
|
||||
would gain entry. resume() checks if the coroutine has already completed
|
||||
(coro_ converts to false) and, if so, skips invoking operator() since
|
||||
calling operator() on a completed boost::coroutine2 pull_type is undefined
|
||||
behavior.
|
||||
|
||||
The race condition occurs as follows:
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <xrpl/basics/Blob.h>
|
||||
#include <xrpl/basics/SHAMapHash.h>
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
#include <xrpl/ledger/CachedSLEs.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
@@ -23,6 +22,20 @@ class PerfLog;
|
||||
// This is temporary until we migrate all code to use ServiceRegistry.
|
||||
class Application;
|
||||
|
||||
template <
|
||||
class Key,
|
||||
class T,
|
||||
bool IsKeyCache,
|
||||
class SharedWeakUnionPointer,
|
||||
class SharedPointerType,
|
||||
class Hash,
|
||||
class KeyEqual,
|
||||
class Mutex>
|
||||
class TaggedCache;
|
||||
class STLedgerEntry;
|
||||
using SLE = STLedgerEntry;
|
||||
using CachedSLEs = TaggedCache<uint256, SLE const>;
|
||||
|
||||
// Forward declarations
|
||||
class AcceptedLedger;
|
||||
class AmendmentTable;
|
||||
@@ -89,7 +102,7 @@ public:
|
||||
getNodeFamily() = 0;
|
||||
|
||||
virtual TimeKeeper&
|
||||
timeKeeper() = 0;
|
||||
getTimeKeeper() = 0;
|
||||
|
||||
virtual JobQueue&
|
||||
getJobQueue() = 0;
|
||||
@@ -98,7 +111,7 @@ public:
|
||||
getTempNodeCache() = 0;
|
||||
|
||||
virtual CachedSLEs&
|
||||
cachedSLEs() = 0;
|
||||
getCachedSLEs() = 0;
|
||||
|
||||
virtual NetworkIDService&
|
||||
getNetworkIDService() = 0;
|
||||
@@ -120,26 +133,26 @@ public:
|
||||
getValidations() = 0;
|
||||
|
||||
virtual ValidatorList&
|
||||
validators() = 0;
|
||||
getValidators() = 0;
|
||||
|
||||
virtual ValidatorSite&
|
||||
validatorSites() = 0;
|
||||
getValidatorSites() = 0;
|
||||
|
||||
virtual ManifestCache&
|
||||
validatorManifests() = 0;
|
||||
getValidatorManifests() = 0;
|
||||
|
||||
virtual ManifestCache&
|
||||
publisherManifests() = 0;
|
||||
getPublisherManifests() = 0;
|
||||
|
||||
// Network services
|
||||
virtual Overlay&
|
||||
overlay() = 0;
|
||||
getOverlay() = 0;
|
||||
|
||||
virtual Cluster&
|
||||
cluster() = 0;
|
||||
getCluster() = 0;
|
||||
|
||||
virtual PeerReservationTable&
|
||||
peerReservations() = 0;
|
||||
getPeerReservations() = 0;
|
||||
|
||||
virtual Resource::Manager&
|
||||
getResourceManager() = 0;
|
||||
@@ -174,13 +187,13 @@ public:
|
||||
getLedgerReplayer() = 0;
|
||||
|
||||
virtual PendingSaves&
|
||||
pendingSaves() = 0;
|
||||
getPendingSaves() = 0;
|
||||
|
||||
virtual OpenLedger&
|
||||
openLedger() = 0;
|
||||
getOpenLedger() = 0;
|
||||
|
||||
virtual OpenLedger const&
|
||||
openLedger() const = 0;
|
||||
getOpenLedger() const = 0;
|
||||
|
||||
// Transaction and operation services
|
||||
virtual NetworkOPs&
|
||||
@@ -210,16 +223,16 @@ public:
|
||||
isStopping() const = 0;
|
||||
|
||||
virtual beast::Journal
|
||||
journal(std::string const& name) = 0;
|
||||
getJournal(std::string const& name) = 0;
|
||||
|
||||
virtual boost::asio::io_context&
|
||||
getIOContext() = 0;
|
||||
|
||||
virtual Logs&
|
||||
logs() = 0;
|
||||
getLogs() = 0;
|
||||
|
||||
virtual std::optional<uint256> const&
|
||||
trapTxID() const = 0;
|
||||
getTrapTxID() const = 0;
|
||||
|
||||
/** Retrieve the "wallet database" */
|
||||
virtual DatabaseCon&
|
||||
@@ -228,7 +241,7 @@ public:
|
||||
// Temporary: Get the underlying Application for functions that haven't
|
||||
// been migrated yet. This should be removed once all code is migrated.
|
||||
virtual Application&
|
||||
app() = 0;
|
||||
getApp() = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
enum class StartUpType { FRESH, NORMAL, LOAD, LOAD_FILE, REPLAY, NETWORK };
|
||||
enum class StartUpType { Fresh, Normal, Load, LoadFile, Replay, Network };
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, StartUpType const& type)
|
||||
|
||||
@@ -34,7 +34,7 @@ auto constexpr decreaseLedgerTimeResolutionEvery = 1;
|
||||
|
||||
/** Calculates the close time resolution for the specified ledger.
|
||||
|
||||
The Ripple protocol uses binning to represent time intervals using only one
|
||||
The XRPL protocol uses binning to represent time intervals using only one
|
||||
timestamp. This allows servers to derive a common time for the next ledger,
|
||||
without the need for perfectly synchronized clocks.
|
||||
The time resolution (i.e. the size of the intervals) is adjusted dynamically
|
||||
@@ -62,7 +62,7 @@ getNextLedgerTimeResolution(
|
||||
bool previousAgree,
|
||||
Seq ledgerSeq)
|
||||
{
|
||||
XRPL_ASSERT(ledgerSeq != Seq{0}, "ripple:getNextLedgerTimeResolution : valid ledger sequence");
|
||||
XRPL_ASSERT(ledgerSeq != Seq{0}, "xrpl::getNextLedgerTimeResolution : valid ledger sequence");
|
||||
|
||||
using namespace std::chrono;
|
||||
// Find the current resolution:
|
||||
@@ -72,7 +72,7 @@ getNextLedgerTimeResolution(
|
||||
previousResolution);
|
||||
XRPL_ASSERT(
|
||||
iter != std::end(ledgerPossibleTimeResolutions),
|
||||
"ripple:getNextLedgerTimeResolution : found time resolution");
|
||||
"xrpl::getNextLedgerTimeResolution : found time resolution");
|
||||
|
||||
// This should never happen, but just as a precaution
|
||||
if (iter == std::end(ledgerPossibleTimeResolutions))
|
||||
|
||||
@@ -76,16 +76,33 @@ public:
|
||||
@return true if a book from this issue to XRP exists
|
||||
*/
|
||||
virtual bool
|
||||
isBookToXRP(Issue const& issue, std::optional<Domain> domain = std::nullopt) = 0;
|
||||
isBookToXRP(Issue const& issue, std::optional<Domain> const& domain = std::nullopt) = 0;
|
||||
|
||||
/**
|
||||
* Process a transaction for order book tracking.
|
||||
* @param ledger The ledger the transaction was applied to
|
||||
* @param alTx The transaction to process
|
||||
* @param jvObj The JSON object of the transaction
|
||||
*/
|
||||
virtual void
|
||||
processTxn(
|
||||
std::shared_ptr<ReadView const> const& ledger,
|
||||
AcceptedLedgerTx const& alTx,
|
||||
MultiApiJson const& jvObj) = 0;
|
||||
|
||||
/**
|
||||
* Get the book listeners for a book.
|
||||
* @param book The book to get the listeners for
|
||||
* @return The book listeners for the book
|
||||
*/
|
||||
virtual BookListeners::pointer
|
||||
getBookListeners(Book const&) = 0;
|
||||
|
||||
/**
|
||||
* Create a new book listeners for a book.
|
||||
* @param book The book to create the listeners for
|
||||
* @return The new book listeners for the book
|
||||
*/
|
||||
virtual BookListeners::pointer
|
||||
makeBookListeners(Book const&) = 0;
|
||||
};
|
||||
|
||||
@@ -30,10 +30,10 @@ enum class SkipEntry : bool { No = false, Yes };
|
||||
/** Determines whether the given expiration time has passed.
|
||||
|
||||
In the XRP Ledger, expiration times are defined as the number of whole
|
||||
seconds after the "Ripple Epoch" which, for historical reasons, is set
|
||||
seconds after the "XRPL epoch" which, for historical reasons, is set
|
||||
to January 1, 2000 (00:00 UTC).
|
||||
|
||||
This is like the way the Unix epoch works, except the Ripple Epoch is
|
||||
This is like the way the Unix epoch works, except the XRPL epoch is
|
||||
precisely 946,684,800 seconds after the Unix Epoch.
|
||||
|
||||
See https://xrpl.org/basic-data-types.html#specifying-time
|
||||
|
||||
@@ -142,14 +142,14 @@ removeEmptyHolding(
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TER
|
||||
rippleLockEscrowMPT(
|
||||
lockEscrowMPT(
|
||||
ApplyView& view,
|
||||
AccountID const& uGrantorID,
|
||||
STAmount const& saAmount,
|
||||
beast::Journal j);
|
||||
|
||||
TER
|
||||
rippleUnlockEscrowMPT(
|
||||
unlockEscrowMPT(
|
||||
ApplyView& view,
|
||||
AccountID const& uGrantorID,
|
||||
AccountID const& uGranteeID,
|
||||
|
||||
@@ -235,11 +235,11 @@ canTransfer(ReadView const& view, Asset const& asset, AccountID const& from, Acc
|
||||
// --> bCheckIssuer : normally require issuer to be involved.
|
||||
// [[nodiscard]] // nodiscard commented out so DirectStep.cpp compiles.
|
||||
|
||||
/** Calls static rippleCreditIOU if saAmount represents Issue.
|
||||
* Calls static rippleCreditMPT if saAmount represents MPTIssue.
|
||||
/** Calls static directSendNoFeeIOU if saAmount represents Issue.
|
||||
* Calls static directSendNoFeeMPT if saAmount represents MPTIssue.
|
||||
*/
|
||||
TER
|
||||
rippleCredit(
|
||||
directSendNoFee(
|
||||
ApplyView& view,
|
||||
AccountID const& uSenderID,
|
||||
AccountID const& uReceiverID,
|
||||
|
||||
@@ -51,7 +51,7 @@ A blob containing the payload. Stored in the following format.
|
||||
---
|
||||
|
||||
The `NodeStore` provides an interface that stores, in a persistent database, a
|
||||
collection of NodeObjects that rippled uses as its primary representation of
|
||||
collection of NodeObjects that xrpld uses as its primary representation of
|
||||
ledger entries. All ledger entries are stored as NodeObjects and as such, need
|
||||
to be persisted between launches. If a NodeObject is accessed and is not in
|
||||
memory, it will be retrieved from the database.
|
||||
@@ -110,7 +110,7 @@ The `NodeStore.Timing` test is used to execute a set of read/write workloads to
|
||||
compare current available nodestore backends. It can be executed with:
|
||||
|
||||
```
|
||||
$rippled --unittest=NodeStoreTiming
|
||||
$xrpld --unittest=NodeStoreTiming
|
||||
```
|
||||
|
||||
It is also possible to use alternate DB config params by passing config strings
|
||||
@@ -143,10 +143,10 @@ Through various executions and profiling some conclusions are presented below.
|
||||
just after ledger close, then that would provide similar, but more predictable
|
||||
guarantees. It would also remove an unneeded thread and unnecessary memory
|
||||
usage. An alternative point of view is that because there will always be many
|
||||
other rippled instances running there is no need for such guarantees. The nodes
|
||||
other xrpld instances running there is no need for such guarantees. The nodes
|
||||
will always be available from another peer.
|
||||
|
||||
- Lookup in a block was previously using binary search. With rippled's use case
|
||||
- Lookup in a block was previously using binary search. With xrpld's use case
|
||||
it is highly unlikely that two adjacent key/values will ever be requested one
|
||||
after the other. Therefore hash indexing of blocks makes much more sense.
|
||||
Rocksdb has a number of options for hash indexing both memtables and blocks and
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Protocol buffer definitions for gRPC
|
||||
|
||||
This folder contains the protocol buffer definitions used by the rippled gRPC API.
|
||||
This folder contains the protocol buffer definitions used by the xrpld gRPC API.
|
||||
The gRPC API attempts to mimic the JSON/Websocket API as much as possible.
|
||||
As of April 2020, the gRPC API supports a subset of the full rippled API:
|
||||
As of April 2020, the gRPC API supports a subset of the full xrpld API:
|
||||
tx, account_tx, account_info, fee and submit.
|
||||
|
||||
### Making Changes
|
||||
@@ -63,7 +63,7 @@ templated `CallData` class in GRPCServerImpl::setupListeners(). The template
|
||||
parameters should be the request type and the response type.
|
||||
|
||||
Finally, define the handler itself in the appropriate file under the
|
||||
src/ripple/rpc/handlers folder. If the method already has a JSON/Websocket
|
||||
src/xrpld/rpc/handlers folder. If the method already has a JSON/Websocket
|
||||
equivalent, write the gRPC handler in the same file, and abstract common logic
|
||||
into helper functions (see Tx.cpp or AccountTx.cpp for an example).
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ enum MessageType {
|
||||
|
||||
/* Provides the current ephemeral key for a validator. */
|
||||
message TMManifest {
|
||||
// A Manifest object in the Ripple serialization format.
|
||||
// A Manifest object in the XRPL serialization format.
|
||||
required bytes stobject = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <xrpl/protocol/tokens.h>
|
||||
// VFALCO Uncomment when the header issues are resolved
|
||||
// #include <ripple/protocol/PublicKey.h>
|
||||
// #include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
@@ -33,7 +33,7 @@ getFullVersionString();
|
||||
X: 16 bits identifying the particular implementation
|
||||
Y: 48 bits of data specific to the implementation
|
||||
|
||||
The rippled-specific format (implementation ID is: 0x18 0x3B) is:
|
||||
The xrpld-specific format (implementation ID is: 0x18 0x3B) is:
|
||||
|
||||
00011000-00111011-MMMMMMMM-mmmmmmmm-pppppppp-TTNNNNNN-00000000-00000000
|
||||
|
||||
@@ -55,23 +55,23 @@ encodeSoftwareVersion(std::string_view versionStr);
|
||||
std::uint64_t
|
||||
getEncodedVersion();
|
||||
|
||||
/** Check if the encoded software version is a rippled software version.
|
||||
/** Check if the encoded software version is an xrpld software version.
|
||||
|
||||
@param version another node's encoded software version
|
||||
@return true if the version is a rippled software version, false otherwise
|
||||
@return true if the version is an xrpld software version, false otherwise
|
||||
*/
|
||||
bool
|
||||
isRippledVersion(std::uint64_t version);
|
||||
isXrpldVersion(std::uint64_t version);
|
||||
|
||||
/** Check if the version is newer than the local node's rippled software
|
||||
/** Check if the version is newer than the local node's xrpld software
|
||||
version.
|
||||
|
||||
@param version another node's encoded software version
|
||||
@return true if the version is newer than the local node's rippled software
|
||||
@return true if the version is newer than the local node's xrpld software
|
||||
version, false otherwise.
|
||||
|
||||
@note This function only understands version numbers that are generated by
|
||||
rippled. Please see the encodeSoftwareVersion() function for detail.
|
||||
xrpld. Please see the encodeSoftwareVersion() function for detail.
|
||||
*/
|
||||
bool
|
||||
isNewerVersion(std::uint64_t version);
|
||||
|
||||
@@ -153,7 +153,7 @@ enum warning_code_i {
|
||||
warnRPC_AMENDMENT_BLOCKED = 1002,
|
||||
warnRPC_EXPIRED_VALIDATOR_LIST = 1003,
|
||||
// unused = 1004
|
||||
warnRPC_FIELDS_DEPRECATED = 2004, // rippled needs to maintain
|
||||
warnRPC_FIELDS_DEPRECATED = 2004, // xrpld needs to maintain
|
||||
// compatibility with Clio on this code.
|
||||
};
|
||||
|
||||
|
||||
@@ -37,10 +37,10 @@
|
||||
* 5) If a supported feature (`Supported::yes`) was _ever_ in a released
|
||||
* version, it can never be changed back to `Supported::no`, because
|
||||
* it _may_ still become enabled at any time. This would cause newer
|
||||
* versions of `rippled` to become amendment blocked.
|
||||
* versions of `xrpld` to become amendment blocked.
|
||||
* Instead, to prevent newer versions from voting on the feature, use
|
||||
* `VoteBehavior::Obsolete`. Obsolete features can not be voted for
|
||||
* by any versions of `rippled` built with that setting, but will still
|
||||
* by any versions of `xrpld` built with that setting, but will still
|
||||
* work correctly if they get enabled. If a feature remains obsolete
|
||||
* for long enough that _all_ clients that could vote for it are
|
||||
* amendment blocked, the feature can be removed from the code
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace xrpl {
|
||||
Public keys are used in the public-key cryptography
|
||||
system used to verify signatures attached to messages.
|
||||
|
||||
The format of the public key is Ripple specific,
|
||||
The format of the public key is XRPL specific,
|
||||
information needed to determine the cryptosystem
|
||||
parameters used is stored inside the key.
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ operator!=(TAmounts<In, Out> const& lhs, TAmounts<In, Out> const& rhs) noexcept
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Ripple specific constant used for parsing qualities and other things
|
||||
// XRPL specific constant used for parsing qualities and other things
|
||||
#define QUALITY_ONE 1'000'000'000
|
||||
|
||||
/** Represents the logical ratio of output currency to input currency.
|
||||
|
||||
@@ -22,7 +22,7 @@ optional fields easier to read:
|
||||
- The operation `x[~sfFoo]` means "return the value of 'Foo'
|
||||
if it exists, or nothing if it doesn't." This usage of the
|
||||
tilde/bitwise NOT operator is not standard outside of the
|
||||
`rippled` codebase.
|
||||
`xrpld` codebase.
|
||||
- As a consequence of this, `x[~sfFoo] = y[~sfFoo]`
|
||||
assigns the value of Foo from y to x, including omitting
|
||||
Foo from x if it doesn't exist in y.
|
||||
@@ -33,7 +33,7 @@ or may not hold a value. For things not guaranteed to exist,
|
||||
you use `x[~sfFoo]` because you want such a container. It
|
||||
avoids having to look something up twice, once just to see if
|
||||
it exists and a second time to get/set its value.
|
||||
([Real example](https://github.com/ripple/rippled/blob/35f4698aed5dce02f771b34cfbb690495cb5efcc/src/ripple/app/tx/impl/PayChan.cpp#L229-L236))
|
||||
([Real example](https://github.com/XRPLF/rippled/blob/35f4698aed5dce02f771b34cfbb690495cb5efcc/src/ripple/app/tx/impl/PayChan.cpp#L229-L236))
|
||||
|
||||
The source of this "type magic" is in
|
||||
[SField.h](./SField.h#L296-L302).
|
||||
|
||||
@@ -13,7 +13,7 @@ class STAccount final : public STBase, public CountedObject<STAccount>
|
||||
private:
|
||||
// The original implementation of STAccount kept the value in an STBlob.
|
||||
// But an STAccount is always 160 bits, so we can store it with less
|
||||
// overhead in a xrpl::uint160. However, so the serialized format of the
|
||||
// overhead in an xrpl::uint160. However, so the serialized format of the
|
||||
// STAccount stays unchanged, we serialize and deserialize like an STBlob.
|
||||
AccountID value_;
|
||||
bool default_;
|
||||
|
||||
@@ -69,9 +69,6 @@ public:
|
||||
std::vector<uint256>::iterator
|
||||
insert(std::vector<uint256>::const_iterator pos, uint256 const& value);
|
||||
|
||||
std::vector<uint256>::iterator
|
||||
insert(std::vector<uint256>::const_iterator pos, uint256&& value);
|
||||
|
||||
void
|
||||
push_back(uint256 const& v);
|
||||
|
||||
@@ -184,12 +181,6 @@ STVector256::insert(std::vector<uint256>::const_iterator pos, uint256 const& val
|
||||
return mValue.insert(pos, value);
|
||||
}
|
||||
|
||||
inline std::vector<uint256>::iterator
|
||||
STVector256::insert(std::vector<uint256>::const_iterator pos, uint256&& value)
|
||||
{
|
||||
return mValue.insert(pos, std::move(value));
|
||||
}
|
||||
|
||||
inline void
|
||||
STVector256::push_back(uint256 const& v)
|
||||
{
|
||||
|
||||
@@ -118,7 +118,7 @@ derivePublicKey(KeyType type, SecretKey const& sk);
|
||||
|
||||
/** Generate a key pair deterministically.
|
||||
|
||||
This algorithm is specific to Ripple:
|
||||
This algorithm is specific to the XRPL:
|
||||
|
||||
For secp256k1 key pairs, the seed is converted
|
||||
to a Generator and used to compute the key pair
|
||||
|
||||
@@ -80,7 +80,7 @@ randomSeed();
|
||||
|
||||
/** Generate a seed deterministically.
|
||||
|
||||
The algorithm is specific to Ripple:
|
||||
The algorithm is specific to the XRPL:
|
||||
|
||||
The seed is calculated as the first 128 bits
|
||||
of the SHA512-Half of the string text excluding
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
enum class TxSearched { all, some, unknown };
|
||||
enum class TxSearched { All, Some, Unknown };
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace unit {
|
||||
struct dropTag;
|
||||
/** "fee levels" are used by the transaction queue to compare the relative
|
||||
cost of transactions that require different levels of effort to process.
|
||||
See also: src/ripple/app/misc/FeeEscalation.md#fee-level */
|
||||
See also: src/xrpld/app/misc/FeeEscalation.md#fee-level */
|
||||
struct feelevelTag;
|
||||
/** unitless values are plain scalars wrapped in a ValueUnit. They are
|
||||
used for calculations in this header. */
|
||||
|
||||
@@ -578,7 +578,7 @@ LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
|
||||
// The unrounded true total value of the loan.
|
||||
//
|
||||
// - TrueTotalPrincipalOutstanding can be computed using the algorithm
|
||||
// in the ripple::detail::loanPrincipalFromPeriodicPayment function.
|
||||
// in the xrpl::detail::loanPrincipalFromPeriodicPayment function.
|
||||
//
|
||||
// - TrueTotalInterestOutstanding = TrueTotalLoanValue -
|
||||
// TrueTotalPrincipalOutstanding
|
||||
|
||||
@@ -100,7 +100,7 @@ using sha512_hasher = openssl_sha512_hasher;
|
||||
/** Returns the RIPEMD-160 digest of the SHA256 hash of the message.
|
||||
|
||||
This operation is used to compute the 160-bit identifier
|
||||
representing a Ripple account, from a message. Typically the
|
||||
representing an XRPL account, from a message. Typically the
|
||||
message is the public key of the account - which is not
|
||||
stored in the account root.
|
||||
|
||||
|
||||
@@ -534,7 +534,7 @@ JSS(response); // websocket
|
||||
JSS(result); // RPC
|
||||
JSS(ripple_lines); // out: NetworkOPs
|
||||
JSS(ripple_state); // in: LedgerEntr
|
||||
JSS(ripplerpc); // ripple RPC version
|
||||
JSS(ripplerpc); // XRPL RPC version
|
||||
JSS(role); // out: Ping.cpp
|
||||
JSS(rpc);
|
||||
JSS(rt_accounts); // in: Subscribe, Unsubscribe
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/core/PerfLog.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/core/StartUpType.h>
|
||||
#include <xrpl/rdb/DBInit.h>
|
||||
#include <xrpl/rdb/SociDB.h>
|
||||
@@ -69,7 +70,7 @@ public:
|
||||
{
|
||||
explicit Setup() = default;
|
||||
|
||||
StartUpType startUp = StartUpType::NORMAL;
|
||||
StartUpType startUp = StartUpType::Normal;
|
||||
bool standAlone = false;
|
||||
boost::filesystem::path dataDir;
|
||||
// Indicates whether or not to return the `globalPragma`
|
||||
@@ -94,7 +95,7 @@ public:
|
||||
struct CheckpointerSetup
|
||||
{
|
||||
JobQueue* jobQueue;
|
||||
Logs* logs;
|
||||
std::reference_wrapper<ServiceRegistry> registry;
|
||||
};
|
||||
|
||||
template <std::size_t N, std::size_t M>
|
||||
@@ -106,9 +107,8 @@ public:
|
||||
beast::Journal journal)
|
||||
// Use temporary files or regular DB files?
|
||||
: DatabaseCon(
|
||||
setup.standAlone && setup.startUp != StartUpType::LOAD &&
|
||||
setup.startUp != StartUpType::LOAD_FILE &&
|
||||
setup.startUp != StartUpType::REPLAY
|
||||
setup.standAlone && setup.startUp != StartUpType::Load &&
|
||||
setup.startUp != StartUpType::LoadFile && setup.startUp != StartUpType::Replay
|
||||
? ""
|
||||
: (setup.dataDir / dbName),
|
||||
setup.commonPragma(),
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
beast::Journal journal)
|
||||
: DatabaseCon(setup, dbName, pragma, initSQL, journal)
|
||||
{
|
||||
setupCheckpointing(checkpointerSetup.jobQueue, *checkpointerSetup.logs);
|
||||
setupCheckpointing(checkpointerSetup.jobQueue, checkpointerSetup.registry.get());
|
||||
}
|
||||
|
||||
template <std::size_t N, std::size_t M>
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
beast::Journal journal)
|
||||
: DatabaseCon(dataDir, dbName, pragma, initSQL, journal)
|
||||
{
|
||||
setupCheckpointing(checkpointerSetup.jobQueue, *checkpointerSetup.logs);
|
||||
setupCheckpointing(checkpointerSetup.jobQueue, checkpointerSetup.registry.get());
|
||||
}
|
||||
|
||||
~DatabaseCon();
|
||||
@@ -177,7 +177,7 @@ public:
|
||||
|
||||
private:
|
||||
void
|
||||
setupCheckpointing(JobQueue*, Logs&);
|
||||
setupCheckpointing(JobQueue*, ServiceRegistry&);
|
||||
|
||||
template <std::size_t N, std::size_t M>
|
||||
DatabaseCon(
|
||||
|
||||
@@ -49,8 +49,9 @@ public:
|
||||
struct AccountTxOptions
|
||||
{
|
||||
AccountID const& account;
|
||||
std::uint32_t minLedger;
|
||||
std::uint32_t maxLedger;
|
||||
/// Ledger sequence range to search. A value of 0 for min or max
|
||||
/// means unbounded in that direction (no constraint applied).
|
||||
LedgerRange ledgerRange;
|
||||
std::uint32_t offset;
|
||||
std::uint32_t limit;
|
||||
bool bUnlimited;
|
||||
@@ -59,8 +60,7 @@ public:
|
||||
struct AccountTxPageOptions
|
||||
{
|
||||
AccountID const& account;
|
||||
std::uint32_t minLedger;
|
||||
std::uint32_t maxLedger;
|
||||
LedgerRange ledgerRange;
|
||||
std::optional<AccountTxMarker> marker;
|
||||
std::uint32_t limit;
|
||||
bool bAdmin;
|
||||
@@ -247,7 +247,7 @@ public:
|
||||
* @return Struct CountMinMax which contains the minimum sequence,
|
||||
* maximum sequence and number of ledgers.
|
||||
*/
|
||||
virtual struct CountMinMax
|
||||
virtual CountMinMax
|
||||
getLedgerCountMinMax() = 0;
|
||||
|
||||
/**
|
||||
@@ -405,10 +405,10 @@ public:
|
||||
* @param id Hash of the transaction.
|
||||
* @param range Range of ledgers to check, if present.
|
||||
* @param ec Default error code value.
|
||||
* @return Transaction and its metadata if found, otherwise TxSearched::all
|
||||
* @return Transaction and its metadata if found, otherwise TxSearched::All
|
||||
* if a range is provided and all ledgers from the range are present
|
||||
* in the database, TxSearched::some if a range is provided and not
|
||||
* all ledgers are present, TxSearched::unknown if the range is not
|
||||
* in the database, TxSearched::Some if a range is provided and not
|
||||
* all ledgers are present, TxSearched::Unknown if the range is not
|
||||
* provided or a deserializing error occurred. In the last case the
|
||||
* error code is returned via the ec parameter, in other cases the
|
||||
* default error code is not changed.
|
||||
@@ -455,9 +455,10 @@ public:
|
||||
closeTransactionDB() = 0;
|
||||
};
|
||||
|
||||
template <class T, class C>
|
||||
template <typename T, typename C>
|
||||
T
|
||||
rangeCheckedCast(C c)
|
||||
requires(std::is_arithmetic_v<T> && std::is_arithmetic_v<C> && std::convertible_to<C, T>)
|
||||
{
|
||||
if ((c > std::numeric_limits<T>::max()) || (!std::numeric_limits<T>::is_signed && c < 0) ||
|
||||
(std::numeric_limits<T>::is_signed && std::numeric_limits<C>::is_signed &&
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
#endif
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/core/JobQueue.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
|
||||
#define SOCI_USE_BOOST
|
||||
#include <soci/soci.h>
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
and so must outlive them both.
|
||||
*/
|
||||
std::shared_ptr<Checkpointer>
|
||||
makeCheckpointer(std::uintptr_t id, std::weak_ptr<soci::session>, JobQueue&, Logs&);
|
||||
makeCheckpointer(std::uintptr_t id, std::weak_ptr<soci::session>, JobQueue&, ServiceRegistry&);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ performed, or simply disconnecting the endpoint.
|
||||
|
||||
Currently, consumption endpoints include websocket connections used to
|
||||
service clients, and peer connections used to create the peer to peer
|
||||
overlay network implementing the Ripple protocol.
|
||||
overlay network implementing the XRPL protocol.
|
||||
|
||||
The current "balance" of a Consumer represents resource consumption
|
||||
debt or credit. Debt is accrued when bad loads are imposed. Credit is
|
||||
@@ -72,6 +72,6 @@ drop connections to those IP addresses that occur commonly in the gossip.
|
||||
|
||||
## Access
|
||||
|
||||
In rippled, the Application holds a unique instance of Resource::Manager,
|
||||
In xrpld, the Application holds a unique instance of Resource::Manager,
|
||||
which may be retrieved by calling the method
|
||||
`Application::getResourceManager()`.
|
||||
|
||||
@@ -15,9 +15,9 @@ namespace xrpl {
|
||||
Validator key manifests
|
||||
-----------------------
|
||||
|
||||
Suppose the secret keys installed on a Ripple validator are compromised. Not
|
||||
Suppose the secret keys installed on an XRPL validator are compromised. Not
|
||||
only do you have to generate and install new key pairs on each validator,
|
||||
EVERY rippled needs to have its config updated with the new public keys, and
|
||||
EVERY xrpld needs to have its config updated with the new public keys, and
|
||||
is vulnerable to forged validation signatures until this is done. The
|
||||
solution is a new layer of indirection: A master secret key under
|
||||
restrictive access control is used to sign a "manifest": essentially, a
|
||||
@@ -39,11 +39,11 @@ namespace xrpl {
|
||||
seen for that validator, if any. On startup, the [validator_token] config
|
||||
entry (which contains the manifest for this validator) is decoded and
|
||||
added to the manifest cache. Other manifests are added as "gossip"
|
||||
received from rippled peers.
|
||||
received from xrpld peers.
|
||||
|
||||
When an ephemeral key is compromised, a new signing key pair is created,
|
||||
along with a new manifest vouching for it (with a higher sequence number),
|
||||
signed by the master key. When a rippled peer receives the new manifest,
|
||||
signed by the master key. When an xrpld peer receives the new manifest,
|
||||
it verifies it with the master key and (assuming it's valid) discards the
|
||||
old ephemeral key and stores the new one. If the master key itself gets
|
||||
compromised, a manifest with sequence number 0xFFFFFFFF will supersede a
|
||||
|
||||
@@ -63,8 +63,8 @@ enum class OperatingMode {
|
||||
needed.
|
||||
|
||||
A backend application or local client can trust a local instance of
|
||||
rippled / NetworkOPs. However, client software connecting to non-local
|
||||
instances of rippled will need to be hardened to protect against hostile
|
||||
xrpld / NetworkOPs. However, client software connecting to non-local
|
||||
instances of xrpld will need to be hardened to protect against hostile
|
||||
or unreliable servers.
|
||||
*/
|
||||
class NetworkOPs : public InfoSub::Source
|
||||
|
||||
@@ -112,7 +112,7 @@ When a `SHAMap` decides that it is safe to share a node of its own, it sets the
|
||||
node's sequence number to 0 (a `SHAMap` never has a sequence number of 0). This
|
||||
is done for every node in the trie when `SHAMap::walkSubTree` is executed.
|
||||
|
||||
Note that other objects in rippled also have sequence numbers (e.g. ledgers).
|
||||
Note that other objects in xrpld also have sequence numbers (e.g. ledgers).
|
||||
The `SHAMap` and node sequence numbers should not be confused with these other
|
||||
sequence numbers (no relation).
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
XRPL_ASSERT((flags & tapBATCH) == 0, "Batch apply flag should not be set");
|
||||
}
|
||||
|
||||
ServiceRegistry& registry;
|
||||
std::reference_wrapper<ServiceRegistry> registry;
|
||||
STTx const& tx;
|
||||
TER const preclaimResult;
|
||||
XRPAmount const baseFee;
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace xrpl {
|
||||
struct PreflightContext
|
||||
{
|
||||
public:
|
||||
ServiceRegistry& registry;
|
||||
std::reference_wrapper<ServiceRegistry> registry;
|
||||
STTx const& tx;
|
||||
Rules const rules;
|
||||
ApplyFlags flags;
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
struct PreclaimContext
|
||||
{
|
||||
public:
|
||||
ServiceRegistry& registry;
|
||||
std::reference_wrapper<ServiceRegistry> registry;
|
||||
ReadView const& view;
|
||||
TER preflightResult;
|
||||
ApplyFlags flags;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/tx/invariants/AMMInvariant.h>
|
||||
#include <xrpl/tx/invariants/FreezeInvariant.h>
|
||||
#include <xrpl/tx/invariants/LoanBrokerInvariant.h>
|
||||
#include <xrpl/tx/invariants/LoanInvariant.h>
|
||||
#include <xrpl/tx/invariants/MPTInvariant.h>
|
||||
#include <xrpl/tx/invariants/NFTInvariant.h>
|
||||
|
||||
55
include/xrpl/tx/invariants/LoanBrokerInvariant.h
Normal file
55
include/xrpl/tx/invariants/LoanBrokerInvariant.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* @brief Invariants: Loan brokers are internally consistent
|
||||
*
|
||||
* 1. If `LoanBroker.OwnerCount = 0` the `DirectoryNode` will have at most one
|
||||
* node (the root), which will only hold entries for `RippleState` or
|
||||
* `MPToken` objects.
|
||||
*
|
||||
*/
|
||||
class ValidLoanBroker
|
||||
{
|
||||
// Not all of these elements will necessarily be populated. Remaining items
|
||||
// will be looked up as needed.
|
||||
struct BrokerInfo
|
||||
{
|
||||
SLE::const_pointer brokerBefore = nullptr;
|
||||
// After is used for most of the checks, except
|
||||
// those that check changed values.
|
||||
SLE::const_pointer brokerAfter = nullptr;
|
||||
};
|
||||
// Collect all the LoanBrokers found directly or indirectly through
|
||||
// pseudo-accounts. Key is the brokerID / index. It will be used to find the
|
||||
// LoanBroker object if brokerBefore and brokerAfter are nullptr
|
||||
std::map<uint256, BrokerInfo> brokers_;
|
||||
// Collect all the modified trust lines. Their high and low accounts will be
|
||||
// loaded to look for LoanBroker pseudo-accounts.
|
||||
std::vector<SLE::const_pointer> lines_;
|
||||
// Collect all the modified MPTokens. Their accounts will be loaded to look
|
||||
// for LoanBroker pseudo-accounts.
|
||||
std::vector<SLE::const_pointer> mpts_;
|
||||
|
||||
static bool
|
||||
goodZeroDirectory(ReadView const& view, SLE::const_ref dir, beast::Journal const& j);
|
||||
|
||||
public:
|
||||
void
|
||||
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&);
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,57 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* @brief Invariants: Loan brokers are internally consistent
|
||||
*
|
||||
* 1. If `LoanBroker.OwnerCount = 0` the `DirectoryNode` will have at most one
|
||||
* node (the root), which will only hold entries for `RippleState` or
|
||||
* `MPToken` objects.
|
||||
*
|
||||
*/
|
||||
class ValidLoanBroker
|
||||
{
|
||||
// Not all of these elements will necessarily be populated. Remaining items
|
||||
// will be looked up as needed.
|
||||
struct BrokerInfo
|
||||
{
|
||||
SLE::const_pointer brokerBefore = nullptr;
|
||||
// After is used for most of the checks, except
|
||||
// those that check changed values.
|
||||
SLE::const_pointer brokerAfter = nullptr;
|
||||
};
|
||||
// Collect all the LoanBrokers found directly or indirectly through
|
||||
// pseudo-accounts. Key is the brokerID / index. It will be used to find the
|
||||
// LoanBroker object if brokerBefore and brokerAfter are nullptr
|
||||
std::map<uint256, BrokerInfo> brokers_;
|
||||
// Collect all the modified trust lines. Their high and low accounts will be
|
||||
// loaded to look for LoanBroker pseudo-accounts.
|
||||
std::vector<SLE::const_pointer> lines_;
|
||||
// Collect all the modified MPTokens. Their accounts will be loaded to look
|
||||
// for LoanBroker pseudo-accounts.
|
||||
std::vector<SLE::const_pointer> mpts_;
|
||||
|
||||
static bool
|
||||
goodZeroDirectory(ReadView const& view, SLE::const_ref dir, beast::Journal const& j);
|
||||
|
||||
public:
|
||||
void
|
||||
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&);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Invariants: Loans are internally consistent
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
STPathSet const& spsPaths,
|
||||
|
||||
std::optional<uint256> const& domainID,
|
||||
Logs& l,
|
||||
ServiceRegistry& registry,
|
||||
Input const* const pInputs = nullptr);
|
||||
|
||||
// The view we are currently working on
|
||||
|
||||
@@ -771,7 +771,7 @@ flow(
|
||||
{
|
||||
// Rounding in the payment engine is causing this assert to
|
||||
// sometimes fire with "dust" amounts. This is causing issues when
|
||||
// running debug builds of rippled. While this issue still needs to
|
||||
// running debug builds of xrpld. While this issue still needs to
|
||||
// be resolved, the assert is causing more harm than good at this
|
||||
// point.
|
||||
// UNREACHABLE("xrpl::flow : rounding error");
|
||||
|
||||
@@ -203,7 +203,7 @@ getAMMOfferStartWithTakerGets(
|
||||
|
||||
// Try to reduce the offer size to improve the quality.
|
||||
// The quality might still not match the targetQuality for a tiny offer.
|
||||
if (auto const amounts = getAmounts(*nTakerGets); Quality{amounts} < targetQuality)
|
||||
if (auto amounts = getAmounts(*nTakerGets); Quality{amounts} < targetQuality)
|
||||
return getAmounts(detail::reduceOffer(amounts.out));
|
||||
else
|
||||
return amounts;
|
||||
@@ -270,7 +270,7 @@ getAMMOfferStartWithTakerPays(
|
||||
|
||||
// Try to reduce the offer size to improve the quality.
|
||||
// The quality might still not match the targetQuality for a tiny offer.
|
||||
if (auto const amounts = getAmounts(*nTakerPays); Quality{amounts} < targetQuality)
|
||||
if (auto amounts = getAmounts(*nTakerPays); Quality{amounts} < targetQuality)
|
||||
return getAmounts(detail::reduceOffer(amounts.in));
|
||||
else
|
||||
return amounts;
|
||||
@@ -335,8 +335,7 @@ changeSpotPriceQuality(
|
||||
}
|
||||
auto const takerPays = toAmount<TIn>(getIssue(pool.in), nTakerPays, Number::upward);
|
||||
// should not fail
|
||||
if (auto const amounts =
|
||||
TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
|
||||
if (auto amounts = TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
|
||||
Quality{amounts} < quality &&
|
||||
!withinRelativeDistance(Quality{amounts}, quality, Number(1, -7)))
|
||||
{
|
||||
@@ -362,7 +361,7 @@ changeSpotPriceQuality(
|
||||
|
||||
// Generate the offer starting with XRP side. Return seated offer amounts
|
||||
// if the offer can be generated, otherwise nullopt.
|
||||
auto const amounts = [&]() {
|
||||
auto amounts = [&]() {
|
||||
if (isXRP(getIssue(pool.out)))
|
||||
return getAMMOfferStartWithTakerGets(pool, quality, tfee);
|
||||
return getAMMOfferStartWithTakerPays(pool, quality, tfee);
|
||||
|
||||
@@ -7,7 +7,7 @@ race:boost/context/
|
||||
race:boost/asio/executor.hpp
|
||||
race:boost::asio
|
||||
|
||||
# Suppress tsan related issues in rippled code.
|
||||
# Suppress tsan related issues in xrpld code.
|
||||
race:src/libxrpl/basics/make_SSLContext.cpp
|
||||
race:src/libxrpl/basics/Number.cpp
|
||||
race:src/libxrpl/json/json_value.cpp
|
||||
@@ -46,7 +46,7 @@ race:xrpl/server/detail/ServerImpl.h
|
||||
race:xrpl/nodestore/detail/DatabaseNodeImp.h
|
||||
race:src/libxrpl/beast/utility/beast_Journal.cpp
|
||||
race:src/test/beast/LexicalCast_test.cpp
|
||||
race:ripple::ServerHandler
|
||||
race:ServerHandler
|
||||
|
||||
# More suppressions in external library code.
|
||||
race:crtstuff.c
|
||||
@@ -65,7 +65,7 @@ deadlock:src/xrpld/app/misc/detail/ValidatorSite.cpp
|
||||
signal:src/libxrpl/beast/utility/beast_Journal.cpp
|
||||
signal:src/xrpld/core/detail/Workers.cpp
|
||||
signal:src/xrpld/core/JobQueue.cpp
|
||||
signal:ripple::Workers::Worker
|
||||
signal:Workers::Worker
|
||||
|
||||
# Aggressive suppressing of deadlock tsan errors
|
||||
deadlock:pthread_create
|
||||
|
||||
@@ -74,7 +74,7 @@ vptr:boost
|
||||
# Google protobuf
|
||||
undefined:protobuf
|
||||
|
||||
# Suppress UBSan errors in rippled code by source file path
|
||||
# Suppress UBSan errors in xrpld code by source file path
|
||||
undefined:src/libxrpl/basics/base64.cpp
|
||||
undefined:src/libxrpl/basics/Number.cpp
|
||||
undefined:src/libxrpl/beast/utility/beast_Journal.cpp
|
||||
@@ -165,7 +165,7 @@ unsigned-integer-overflow:xrpl/nodestore/detail/varint.h
|
||||
unsigned-integer-overflow:xrpl/peerfinder/detail/Counts.h
|
||||
unsigned-integer-overflow:xrpl/protocol/nft.h
|
||||
|
||||
# Rippled intentional overflows and operations
|
||||
# Xrpld intentional overflows and operations
|
||||
# STAmount uses intentional negation of INT64_MIN and overflow in arithmetic
|
||||
signed-integer-overflow:src/libxrpl/protocol/STAmount.cpp
|
||||
unsigned-integer-overflow:src/libxrpl/protocol/STAmount.cpp
|
||||
|
||||
@@ -45,7 +45,7 @@ getFileContents(
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string const result{
|
||||
std::string result{
|
||||
std::istreambuf_iterator<char>{fileStream}, std::istreambuf_iterator<char>{}};
|
||||
|
||||
if (fileStream.bad())
|
||||
|
||||
@@ -9,14 +9,14 @@ namespace xrpl {
|
||||
std::atomic<UptimeClock::rep> UptimeClock::now_{0}; // seconds since start
|
||||
std::atomic<bool> UptimeClock::stop_{false}; // stop update thread
|
||||
|
||||
// On rippled shutdown, cancel and wait for the update thread
|
||||
// On xrpld shutdown, cancel and wait for the update thread
|
||||
UptimeClock::update_thread::~update_thread()
|
||||
{
|
||||
if (joinable())
|
||||
{
|
||||
stop_ = true;
|
||||
// This join() may take up to a 1s, but happens only
|
||||
// once at rippled shutdown.
|
||||
// once at xrpld shutdown.
|
||||
join();
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ UptimeClock::start_clock()
|
||||
}};
|
||||
}
|
||||
|
||||
// This actually measures time since first use, instead of since rippled start.
|
||||
// This actually measures time since first use, instead of since xrpld start.
|
||||
// However the difference between these two epochs is a small fraction of a
|
||||
// second and unimportant.
|
||||
|
||||
@@ -50,7 +50,7 @@ UptimeClock::now()
|
||||
// start the update thread on first use
|
||||
static auto const init = start_clock();
|
||||
|
||||
// Return the number of seconds since rippled start
|
||||
// Return the number of seconds since xrpld start
|
||||
return time_point{duration{now_}};
|
||||
}
|
||||
|
||||
|
||||
@@ -80,8 +80,7 @@ public:
|
||||
|
||||
txs_iter_impl(txs_iter_impl const&) = default;
|
||||
|
||||
txs_iter_impl(bool metadata, SHAMap::const_iterator iter)
|
||||
: metadata_(metadata), iter_(std::move(iter))
|
||||
txs_iter_impl(bool metadata, SHAMap::const_iterator iter) : metadata_(metadata), iter_(iter)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -694,7 +693,7 @@ Ledger::updateNegativeUNL()
|
||||
if (sle->isFieldPresent(sfDisabledValidators))
|
||||
{
|
||||
auto const& oldNUnl = sle->getFieldArray(sfDisabledValidators);
|
||||
for (auto v : oldNUnl)
|
||||
for (auto const& v : oldNUnl)
|
||||
{
|
||||
if (hasToReEnable && v.isFieldPresent(sfPublicKey) &&
|
||||
v.getFieldVL(sfPublicKey) == sle->getFieldVL(sfValidatorToReEnable))
|
||||
|
||||
@@ -485,25 +485,20 @@ canTransfer(
|
||||
}
|
||||
|
||||
TER
|
||||
rippleLockEscrowMPT(
|
||||
ApplyView& view,
|
||||
AccountID const& sender,
|
||||
STAmount const& amount,
|
||||
beast::Journal j)
|
||||
lockEscrowMPT(ApplyView& view, AccountID const& sender, STAmount const& amount, beast::Journal j)
|
||||
{
|
||||
auto const mptIssue = amount.get<MPTIssue>();
|
||||
auto const mptID = keylet::mptIssuance(mptIssue.getMptID());
|
||||
auto sleIssuance = view.peek(mptID);
|
||||
if (!sleIssuance)
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleLockEscrowMPT: MPT issuance not found for "
|
||||
<< mptIssue.getMptID();
|
||||
JLOG(j.error()) << "lockEscrowMPT: MPT issuance not found for " << mptIssue.getMptID();
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
if (amount.getIssuer() == sender)
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleLockEscrowMPT: sender is the issuer, cannot lock MPTs.";
|
||||
JLOG(j.error()) << "lockEscrowMPT: sender is the issuer, cannot lock MPTs.";
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
@@ -514,7 +509,7 @@ rippleLockEscrowMPT(
|
||||
auto sle = view.peek(mptokenID);
|
||||
if (!sle)
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleLockEscrowMPT: MPToken not found for " << sender;
|
||||
JLOG(j.error()) << "lockEscrowMPT: MPToken not found for " << sender;
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
@@ -524,8 +519,8 @@ rippleLockEscrowMPT(
|
||||
// Underflow check for subtraction
|
||||
if (!canSubtract(STAmount(mptIssue, amt), STAmount(mptIssue, pay)))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleLockEscrowMPT: insufficient MPTAmount for "
|
||||
<< to_string(sender) << ": " << amt << " < " << pay;
|
||||
JLOG(j.error()) << "lockEscrowMPT: insufficient MPTAmount for " << to_string(sender)
|
||||
<< ": " << amt << " < " << pay;
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
@@ -536,8 +531,8 @@ rippleLockEscrowMPT(
|
||||
|
||||
if (!canAdd(STAmount(mptIssue, locked), STAmount(mptIssue, pay)))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleLockEscrowMPT: overflow on locked amount for "
|
||||
<< to_string(sender) << ": " << locked << " + " << pay;
|
||||
JLOG(j.error()) << "lockEscrowMPT: overflow on locked amount for " << to_string(sender)
|
||||
<< ": " << locked << " + " << pay;
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
@@ -562,7 +557,7 @@ rippleLockEscrowMPT(
|
||||
// Overflow check for addition
|
||||
if (!canAdd(STAmount(mptIssue, issuanceEscrowed), STAmount(mptIssue, pay)))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleLockEscrowMPT: overflow on issuance "
|
||||
JLOG(j.error()) << "lockEscrowMPT: overflow on issuance "
|
||||
"locked amount for "
|
||||
<< mptIssue.getMptID() << ": " << issuanceEscrowed << " + " << pay;
|
||||
return tecINTERNAL;
|
||||
@@ -583,7 +578,7 @@ rippleLockEscrowMPT(
|
||||
}
|
||||
|
||||
TER
|
||||
rippleUnlockEscrowMPT(
|
||||
unlockEscrowMPT(
|
||||
ApplyView& view,
|
||||
AccountID const& sender,
|
||||
AccountID const& receiver,
|
||||
@@ -593,8 +588,7 @@ rippleUnlockEscrowMPT(
|
||||
{
|
||||
if (!view.rules().enabled(fixTokenEscrowV1))
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
netAmount == grossAmount, "xrpl::rippleUnlockEscrowMPT : netAmount == grossAmount");
|
||||
XRPL_ASSERT(netAmount == grossAmount, "xrpl::unlockEscrowMPT : netAmount == grossAmount");
|
||||
}
|
||||
|
||||
auto const& issuer = netAmount.getIssuer();
|
||||
@@ -603,8 +597,7 @@ rippleUnlockEscrowMPT(
|
||||
auto sleIssuance = view.peek(mptID);
|
||||
if (!sleIssuance)
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: MPT issuance not found for "
|
||||
<< mptIssue.getMptID();
|
||||
JLOG(j.error()) << "unlockEscrowMPT: MPT issuance not found for " << mptIssue.getMptID();
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
@@ -612,7 +605,7 @@ rippleUnlockEscrowMPT(
|
||||
{
|
||||
if (!sleIssuance->isFieldPresent(sfLockedAmount))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: no locked amount in issuance for "
|
||||
JLOG(j.error()) << "unlockEscrowMPT: no locked amount in issuance for "
|
||||
<< mptIssue.getMptID();
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
@@ -623,7 +616,7 @@ rippleUnlockEscrowMPT(
|
||||
// Underflow check for subtraction
|
||||
if (!canSubtract(STAmount(mptIssue, locked), STAmount(mptIssue, redeem)))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient locked amount for "
|
||||
JLOG(j.error()) << "unlockEscrowMPT: insufficient locked amount for "
|
||||
<< mptIssue.getMptID() << ": " << locked << " < " << redeem;
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
@@ -647,7 +640,7 @@ rippleUnlockEscrowMPT(
|
||||
auto sle = view.peek(mptokenID);
|
||||
if (!sle)
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: MPToken not found for " << receiver;
|
||||
JLOG(j.error()) << "unlockEscrowMPT: MPToken not found for " << receiver;
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
@@ -657,8 +650,8 @@ rippleUnlockEscrowMPT(
|
||||
// Overflow check for addition
|
||||
if (!canAdd(STAmount(mptIssue, current), STAmount(mptIssue, delta)))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: overflow on MPTAmount for "
|
||||
<< to_string(receiver) << ": " << current << " + " << delta;
|
||||
JLOG(j.error()) << "unlockEscrowMPT: overflow on MPTAmount for " << to_string(receiver)
|
||||
<< ": " << current << " + " << delta;
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
@@ -674,7 +667,7 @@ rippleUnlockEscrowMPT(
|
||||
// Underflow check for subtraction
|
||||
if (!canSubtract(STAmount(mptIssue, outstanding), STAmount(mptIssue, redeem)))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient outstanding amount for "
|
||||
JLOG(j.error()) << "unlockEscrowMPT: insufficient outstanding amount for "
|
||||
<< mptIssue.getMptID() << ": " << outstanding << " < " << redeem;
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
@@ -685,7 +678,7 @@ rippleUnlockEscrowMPT(
|
||||
|
||||
if (issuer == sender)
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: sender is the issuer, "
|
||||
JLOG(j.error()) << "unlockEscrowMPT: sender is the issuer, "
|
||||
"cannot unlock MPTs.";
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
@@ -694,14 +687,13 @@ rippleUnlockEscrowMPT(
|
||||
auto sle = view.peek(mptokenID);
|
||||
if (!sle)
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: MPToken not found for " << sender;
|
||||
JLOG(j.error()) << "unlockEscrowMPT: 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);
|
||||
JLOG(j.error()) << "unlockEscrowMPT: no locked amount in MPToken for " << to_string(sender);
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
@@ -711,8 +703,8 @@ rippleUnlockEscrowMPT(
|
||||
// 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;
|
||||
JLOG(j.error()) << "unlockEscrowMPT: insufficient locked amount for " << to_string(sender)
|
||||
<< ": " << locked << " < " << delta;
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
@@ -738,7 +730,7 @@ rippleUnlockEscrowMPT(
|
||||
// Underflow check for subtraction
|
||||
if (!canSubtract(STAmount(mptIssue, outstanding), STAmount(mptIssue, diff)))
|
||||
{ // LCOV_EXCL_START
|
||||
JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient outstanding amount for "
|
||||
JLOG(j.error()) << "unlockEscrowMPT: insufficient outstanding amount for "
|
||||
<< mptIssue.getMptID() << ": " << outstanding << " < " << diff;
|
||||
return tecINTERNAL;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
@@ -161,7 +161,7 @@ getLineIfUsable(
|
||||
FreezeHandling zeroIfFrozen,
|
||||
beast::Journal j)
|
||||
{
|
||||
auto const sle = view.read(keylet::line(account, issuer, currency));
|
||||
auto sle = view.read(keylet::line(account, issuer, currency));
|
||||
|
||||
if (!sle)
|
||||
{
|
||||
@@ -513,7 +513,7 @@ canTransfer(ReadView const& view, Asset const& asset, AccountID const& from, Acc
|
||||
// - Create trust line if needed.
|
||||
// --> bCheckIssuer : normally require issuer to be involved.
|
||||
static TER
|
||||
rippleCreditIOU(
|
||||
directSendNoFeeIOU(
|
||||
ApplyView& view,
|
||||
AccountID const& uSenderID,
|
||||
AccountID const& uReceiverID,
|
||||
@@ -527,20 +527,21 @@ rippleCreditIOU(
|
||||
// Make sure issuer is involved.
|
||||
XRPL_ASSERT(
|
||||
!bCheckIssuer || uSenderID == issuer || uReceiverID == issuer,
|
||||
"xrpl::rippleCreditIOU : matching issuer or don't care");
|
||||
"xrpl::directSendNoFeeIOU : matching issuer or don't care");
|
||||
(void)issuer;
|
||||
|
||||
// Disallow sending to self.
|
||||
XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::rippleCreditIOU : sender is not receiver");
|
||||
XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::directSendNoFeeIOU : sender is not receiver");
|
||||
|
||||
bool const bSenderHigh = uSenderID > uReceiverID;
|
||||
auto const index = keylet::line(uSenderID, uReceiverID, currency);
|
||||
|
||||
XRPL_ASSERT(
|
||||
!isXRP(uSenderID) && uSenderID != noAccount(), "xrpl::rippleCreditIOU : sender is not XRP");
|
||||
!isXRP(uSenderID) && uSenderID != noAccount(),
|
||||
"xrpl::directSendNoFeeIOU : sender is not XRP");
|
||||
XRPL_ASSERT(
|
||||
!isXRP(uReceiverID) && uReceiverID != noAccount(),
|
||||
"xrpl::rippleCreditIOU : receiver is not XRP");
|
||||
"xrpl::directSendNoFeeIOU : receiver is not XRP");
|
||||
|
||||
// If the line exists, modify it accordingly.
|
||||
if (auto const sleRippleState = view.peek(index))
|
||||
@@ -556,7 +557,7 @@ rippleCreditIOU(
|
||||
|
||||
saBalance -= saAmount;
|
||||
|
||||
JLOG(j.trace()) << "rippleCreditIOU: " << to_string(uSenderID) << " -> "
|
||||
JLOG(j.trace()) << "directSendNoFeeIOU: " << to_string(uSenderID) << " -> "
|
||||
<< to_string(uReceiverID) << " : before=" << saBefore.getFullText()
|
||||
<< " amount=" << saAmount.getFullText()
|
||||
<< " after=" << saBalance.getFullText();
|
||||
@@ -623,7 +624,7 @@ rippleCreditIOU(
|
||||
|
||||
saBalance.setIssuer(noAccount());
|
||||
|
||||
JLOG(j.debug()) << "rippleCreditIOU: "
|
||||
JLOG(j.debug()) << "directSendNoFeeIOU: "
|
||||
"create line: "
|
||||
<< to_string(uSenderID) << " -> " << to_string(uReceiverID) << " : "
|
||||
<< saAmount.getFullText();
|
||||
@@ -656,7 +657,7 @@ rippleCreditIOU(
|
||||
// --> saAmount: Amount/currency/issuer to deliver to receiver.
|
||||
// <-- saActual: Amount actually cost. Sender pays fees.
|
||||
static TER
|
||||
rippleSendIOU(
|
||||
directSendNoLimitIOU(
|
||||
ApplyView& view,
|
||||
AccountID const& uSenderID,
|
||||
AccountID const& uReceiverID,
|
||||
@@ -669,13 +670,13 @@ rippleSendIOU(
|
||||
|
||||
XRPL_ASSERT(
|
||||
!isXRP(uSenderID) && !isXRP(uReceiverID),
|
||||
"xrpl::rippleSendIOU : neither sender nor receiver is XRP");
|
||||
XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::rippleSendIOU : sender is not receiver");
|
||||
"xrpl::directSendNoLimitIOU : neither sender nor receiver is XRP");
|
||||
XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::directSendNoLimitIOU : sender is not receiver");
|
||||
|
||||
if (uSenderID == issuer || uReceiverID == issuer || issuer == noAccount())
|
||||
{
|
||||
// Direct send: redeeming IOUs and/or sending own IOUs.
|
||||
auto const ter = rippleCreditIOU(view, uSenderID, uReceiverID, saAmount, false, j);
|
||||
auto const ter = directSendNoFeeIOU(view, uSenderID, uReceiverID, saAmount, false, j);
|
||||
if (!isTesSuccess(ter))
|
||||
return ter;
|
||||
saActual = saAmount;
|
||||
@@ -689,14 +690,14 @@ rippleSendIOU(
|
||||
saActual = (waiveFee == WaiveTransferFee::Yes) ? saAmount
|
||||
: multiply(saAmount, transferRate(view, issuer));
|
||||
|
||||
JLOG(j.debug()) << "rippleSendIOU> " << to_string(uSenderID) << " - > "
|
||||
JLOG(j.debug()) << "directSendNoLimitIOU> " << to_string(uSenderID) << " - > "
|
||||
<< to_string(uReceiverID) << " : deliver=" << saAmount.getFullText()
|
||||
<< " cost=" << saActual.getFullText();
|
||||
|
||||
TER terResult = rippleCreditIOU(view, issuer, uReceiverID, saAmount, true, j);
|
||||
TER terResult = directSendNoFeeIOU(view, issuer, uReceiverID, saAmount, true, j);
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
terResult = rippleCreditIOU(view, uSenderID, issuer, saActual, true, j);
|
||||
terResult = directSendNoFeeIOU(view, uSenderID, issuer, saActual, true, j);
|
||||
|
||||
return terResult;
|
||||
}
|
||||
@@ -705,7 +706,7 @@ rippleSendIOU(
|
||||
// --> receivers: Amount/currency/issuer to deliver to receivers.
|
||||
// <-- saActual: Amount actually cost to sender. Sender pays fees.
|
||||
static TER
|
||||
rippleSendMultiIOU(
|
||||
directSendNoLimitMultiIOU(
|
||||
ApplyView& view,
|
||||
AccountID const& senderID,
|
||||
Issue const& issue,
|
||||
@@ -716,7 +717,7 @@ rippleSendMultiIOU(
|
||||
{
|
||||
auto const& issuer = issue.getIssuer();
|
||||
|
||||
XRPL_ASSERT(!isXRP(senderID), "xrpl::rippleSendMultiIOU : sender is not XRP");
|
||||
XRPL_ASSERT(!isXRP(senderID), "xrpl::directSendNoLimitMultiIOU : sender is not XRP");
|
||||
|
||||
// These may diverge
|
||||
STAmount takeFromSender{issue};
|
||||
@@ -734,15 +735,15 @@ rippleSendMultiIOU(
|
||||
if (!amount || (senderID == receiverID))
|
||||
continue;
|
||||
|
||||
XRPL_ASSERT(!isXRP(receiverID), "xrpl::rippleSendMultiIOU : receiver is not XRP");
|
||||
XRPL_ASSERT(!isXRP(receiverID), "xrpl::directSendNoLimitMultiIOU : receiver is not XRP");
|
||||
|
||||
if (senderID == issuer || receiverID == issuer || issuer == noAccount())
|
||||
{
|
||||
// Direct send: redeeming IOUs and/or sending own IOUs.
|
||||
if (auto const ter = rippleCreditIOU(view, senderID, receiverID, amount, false, j))
|
||||
if (auto const ter = directSendNoFeeIOU(view, senderID, receiverID, amount, false, j))
|
||||
return ter;
|
||||
actual += amount;
|
||||
// Do not add amount to takeFromSender, because rippleCreditIOU took
|
||||
// Do not add amount to takeFromSender, because directSendNoFeeIOU took
|
||||
// it.
|
||||
|
||||
continue;
|
||||
@@ -758,17 +759,18 @@ rippleSendMultiIOU(
|
||||
actual += actualSend;
|
||||
takeFromSender += actualSend;
|
||||
|
||||
JLOG(j.debug()) << "rippleSendMultiIOU> " << to_string(senderID) << " - > "
|
||||
JLOG(j.debug()) << "directSendNoLimitMultiIOU> " << to_string(senderID) << " - > "
|
||||
<< to_string(receiverID) << " : deliver=" << amount.getFullText()
|
||||
<< " cost=" << actual.getFullText();
|
||||
|
||||
if (TER const terResult = rippleCreditIOU(view, issuer, receiverID, amount, true, j))
|
||||
if (TER const terResult = directSendNoFeeIOU(view, issuer, receiverID, amount, true, j))
|
||||
return terResult;
|
||||
}
|
||||
|
||||
if (senderID != issuer && takeFromSender)
|
||||
{
|
||||
if (TER const terResult = rippleCreditIOU(view, senderID, issuer, takeFromSender, true, j))
|
||||
if (TER const terResult =
|
||||
directSendNoFeeIOU(view, senderID, issuer, takeFromSender, true, j))
|
||||
return terResult;
|
||||
}
|
||||
|
||||
@@ -813,7 +815,7 @@ accountSendIOU(
|
||||
JLOG(j.trace()) << "accountSendIOU: " << to_string(uSenderID) << " -> "
|
||||
<< to_string(uReceiverID) << " : " << saAmount.getFullText();
|
||||
|
||||
return rippleSendIOU(view, uSenderID, uReceiverID, saAmount, saActual, j, waiveFee);
|
||||
return directSendNoLimitIOU(view, uSenderID, uReceiverID, saAmount, saActual, j, waiveFee);
|
||||
}
|
||||
|
||||
/* XRP send which does not check reserve and can do pure adjustment.
|
||||
@@ -912,7 +914,7 @@ accountSendMultiIOU(
|
||||
JLOG(j.trace()) << "accountSendMultiIOU: " << to_string(senderID) << " sending "
|
||||
<< receivers.size() << " IOUs";
|
||||
|
||||
return rippleSendMultiIOU(view, senderID, issue, receivers, actual, j, waiveFee);
|
||||
return directSendNoLimitMultiIOU(view, senderID, issue, receivers, actual, j, waiveFee);
|
||||
}
|
||||
|
||||
/* XRP send which does not check reserve and can do pure adjustment.
|
||||
@@ -1022,7 +1024,7 @@ accountSendMultiIOU(
|
||||
}
|
||||
|
||||
static TER
|
||||
rippleCreditMPT(
|
||||
directSendNoFeeMPT(
|
||||
ApplyView& view,
|
||||
AccountID const& uSenderID,
|
||||
AccountID const& uReceiverID,
|
||||
@@ -1090,7 +1092,7 @@ rippleCreditMPT(
|
||||
}
|
||||
|
||||
static TER
|
||||
rippleSendMPT(
|
||||
directSendNoLimitMPT(
|
||||
ApplyView& view,
|
||||
AccountID const& uSenderID,
|
||||
AccountID const& uReceiverID,
|
||||
@@ -1099,9 +1101,9 @@ rippleSendMPT(
|
||||
beast::Journal j,
|
||||
WaiveTransferFee waiveFee)
|
||||
{
|
||||
XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::rippleSendMPT : sender is not receiver");
|
||||
XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::directSendNoLimitMPT : sender is not receiver");
|
||||
|
||||
// Safe to get MPT since rippleSendMPT is only called by accountSendMPT
|
||||
// Safe to get MPT since directSendNoLimitMPT is only called by accountSendMPT
|
||||
auto const& issuer = saAmount.getIssuer();
|
||||
|
||||
auto const sle = view.read(keylet::mptIssuance(saAmount.get<MPTIssue>().getMptID()));
|
||||
@@ -1122,7 +1124,7 @@ rippleSendMPT(
|
||||
}
|
||||
|
||||
// Direct send: redeeming MPTs and/or sending own MPTs.
|
||||
auto const ter = rippleCreditMPT(view, uSenderID, uReceiverID, saAmount, j);
|
||||
auto const ter = directSendNoFeeMPT(view, uSenderID, uReceiverID, saAmount, j);
|
||||
if (!isTesSuccess(ter))
|
||||
return ter;
|
||||
saActual = saAmount;
|
||||
@@ -1134,19 +1136,19 @@ rippleSendMPT(
|
||||
? saAmount
|
||||
: multiply(saAmount, transferRate(view, saAmount.get<MPTIssue>().getMptID()));
|
||||
|
||||
JLOG(j.debug()) << "rippleSendMPT> " << to_string(uSenderID) << " - > "
|
||||
JLOG(j.debug()) << "directSendNoLimitMPT> " << to_string(uSenderID) << " - > "
|
||||
<< to_string(uReceiverID) << " : deliver=" << saAmount.getFullText()
|
||||
<< " cost=" << saActual.getFullText();
|
||||
|
||||
if (auto const terResult = rippleCreditMPT(view, issuer, uReceiverID, saAmount, j);
|
||||
if (auto const terResult = directSendNoFeeMPT(view, issuer, uReceiverID, saAmount, j);
|
||||
!isTesSuccess(terResult))
|
||||
return terResult;
|
||||
|
||||
return rippleCreditMPT(view, uSenderID, issuer, saActual, j);
|
||||
return directSendNoFeeMPT(view, uSenderID, issuer, saActual, j);
|
||||
}
|
||||
|
||||
static TER
|
||||
rippleSendMultiMPT(
|
||||
directSendNoLimitMultiMPT(
|
||||
ApplyView& view,
|
||||
AccountID const& senderID,
|
||||
MPTIssue const& mptIssue,
|
||||
@@ -1155,7 +1157,7 @@ rippleSendMultiMPT(
|
||||
beast::Journal j,
|
||||
WaiveTransferFee waiveFee)
|
||||
{
|
||||
// Safe to get MPT since rippleSendMultiMPT is only called by
|
||||
// Safe to get MPT since directSendNoLimitMultiMPT is only called by
|
||||
// accountSendMultiMPT
|
||||
auto const& issuer = mptIssue.getIssuer();
|
||||
|
||||
@@ -1191,7 +1193,7 @@ rippleSendMultiMPT(
|
||||
{
|
||||
XRPL_ASSERT_PARTS(
|
||||
takeFromSender == beast::zero,
|
||||
"xrpl::rippleSendMultiMPT",
|
||||
"xrpl::directSendNoLimitMultiMPT",
|
||||
"sender == issuer, takeFromSender == zero");
|
||||
auto const sendAmount = amount.mpt().value();
|
||||
auto const maximumAmount = sle->at(~sfMaximumAmount).value_or(maxMPTokenAmount);
|
||||
@@ -1201,10 +1203,10 @@ rippleSendMultiMPT(
|
||||
}
|
||||
|
||||
// Direct send: redeeming MPTs and/or sending own MPTs.
|
||||
if (auto const ter = rippleCreditMPT(view, senderID, receiverID, amount, j))
|
||||
if (auto const ter = directSendNoFeeMPT(view, senderID, receiverID, amount, j))
|
||||
return ter;
|
||||
actual += amount;
|
||||
// Do not add amount to takeFromSender, because rippleCreditMPT took
|
||||
// Do not add amount to takeFromSender, because directSendNoFeeMPT took
|
||||
// it
|
||||
|
||||
continue;
|
||||
@@ -1217,16 +1219,16 @@ rippleSendMultiMPT(
|
||||
actual += actualSend;
|
||||
takeFromSender += actualSend;
|
||||
|
||||
JLOG(j.debug()) << "rippleSendMultiMPT> " << to_string(senderID) << " - > "
|
||||
JLOG(j.debug()) << "directSendNoLimitMultiMPT> " << to_string(senderID) << " - > "
|
||||
<< to_string(receiverID) << " : deliver=" << amount.getFullText()
|
||||
<< " cost=" << actualSend.getFullText();
|
||||
|
||||
if (auto const terResult = rippleCreditMPT(view, issuer, receiverID, amount, j))
|
||||
if (auto const terResult = directSendNoFeeMPT(view, issuer, receiverID, amount, j))
|
||||
return terResult;
|
||||
}
|
||||
if (senderID != issuer && takeFromSender)
|
||||
{
|
||||
if (TER const terResult = rippleCreditMPT(view, senderID, issuer, takeFromSender, j))
|
||||
if (TER const terResult = directSendNoFeeMPT(view, senderID, issuer, takeFromSender, j))
|
||||
return terResult;
|
||||
}
|
||||
|
||||
@@ -1254,7 +1256,7 @@ accountSendMPT(
|
||||
|
||||
STAmount saActual{saAmount.asset()};
|
||||
|
||||
return rippleSendMPT(view, uSenderID, uReceiverID, saAmount, saActual, j, waiveFee);
|
||||
return directSendNoLimitMPT(view, uSenderID, uReceiverID, saAmount, saActual, j, waiveFee);
|
||||
}
|
||||
|
||||
static TER
|
||||
@@ -1268,7 +1270,7 @@ accountSendMultiMPT(
|
||||
{
|
||||
STAmount actual;
|
||||
|
||||
return rippleSendMultiMPT(view, senderID, mptIssue, receivers, actual, j, waiveFee);
|
||||
return directSendNoLimitMultiMPT(view, senderID, mptIssue, receivers, actual, j, waiveFee);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -1278,7 +1280,7 @@ accountSendMultiMPT(
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TER
|
||||
rippleCredit(
|
||||
directSendNoFee(
|
||||
ApplyView& view,
|
||||
AccountID const& uSenderID,
|
||||
AccountID const& uReceiverID,
|
||||
@@ -1290,12 +1292,12 @@ rippleCredit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
{
|
||||
return rippleCreditIOU(view, uSenderID, uReceiverID, saAmount, bCheckIssuer, j);
|
||||
return directSendNoFeeIOU(view, uSenderID, uReceiverID, saAmount, bCheckIssuer, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
XRPL_ASSERT(!bCheckIssuer, "xrpl::rippleCredit : not checking issuer");
|
||||
return rippleCreditMPT(view, uSenderID, uReceiverID, saAmount, j);
|
||||
XRPL_ASSERT(!bCheckIssuer, "xrpl::directSendNoFee : not checking issuer");
|
||||
return directSendNoFeeMPT(view, uSenderID, uReceiverID, saAmount, j);
|
||||
}
|
||||
},
|
||||
saAmount.asset().value());
|
||||
|
||||
@@ -113,7 +113,7 @@ encodeSoftwareVersion(std::string_view versionStr)
|
||||
{
|
||||
std::uint8_t x = 0;
|
||||
|
||||
for (auto id : v.preReleaseIdentifiers)
|
||||
for (auto const& id : v.preReleaseIdentifiers)
|
||||
{
|
||||
auto parsePreRelease = [](std::string_view identifier,
|
||||
std::string_view prefix,
|
||||
@@ -160,7 +160,7 @@ getEncodedVersion()
|
||||
}
|
||||
|
||||
bool
|
||||
isRippledVersion(std::uint64_t version)
|
||||
isXrpldVersion(std::uint64_t version)
|
||||
{
|
||||
return (version & implementationVersionIdentifierMask) == implementationVersionIdentifier;
|
||||
}
|
||||
@@ -168,7 +168,7 @@ isRippledVersion(std::uint64_t version)
|
||||
bool
|
||||
isNewerVersion(std::uint64_t version)
|
||||
{
|
||||
if (isRippledVersion(version))
|
||||
if (isXrpldVersion(version))
|
||||
return version > getEncodedVersion();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ getNFTokenIDFromPage(TxMeta const& transactionMeta)
|
||||
// field changing, but no NFTs within that page changing. In this
|
||||
// case, there will be no previous NFTs and we need to skip.
|
||||
// However, there will always be NFTs listed in the final fields,
|
||||
// as rippled outputs all fields in final fields even if they were
|
||||
// as xrpld outputs all fields in final fields even if they were
|
||||
// not changed.
|
||||
STObject const& previousFields =
|
||||
node.peekAtField(sfPreviousFields).downcast<STObject>();
|
||||
|
||||
@@ -153,7 +153,7 @@ STPath::getJson(JsonOptions) const
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
|
||||
for (auto it : mPath)
|
||||
for (auto const& it : mPath)
|
||||
{
|
||||
Json::Value elem(Json::objectValue);
|
||||
auto const iType = it.getNodeType();
|
||||
@@ -179,7 +179,7 @@ Json::Value
|
||||
STPathSet::getJson(JsonOptions options) const
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
for (auto it : value)
|
||||
for (auto const& it : value)
|
||||
ret.append(it.getJson(options));
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpl/rdb/SociDB.h>
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
auto it = checkpointers_.find(id);
|
||||
if (it != checkpointers_.end())
|
||||
return it->second;
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -40,11 +40,14 @@ public:
|
||||
}
|
||||
|
||||
std::shared_ptr<Checkpointer>
|
||||
create(std::shared_ptr<soci::session> const& session, JobQueue& jobQueue, Logs& logs)
|
||||
create(
|
||||
std::shared_ptr<soci::session> const& session,
|
||||
JobQueue& jobQueue,
|
||||
ServiceRegistry& registry)
|
||||
{
|
||||
std::lock_guard lock{mutex_};
|
||||
auto const id = nextId_++;
|
||||
auto const r = makeCheckpointer(id, session, jobQueue, logs);
|
||||
auto const r = makeCheckpointer(id, session, jobQueue, registry);
|
||||
checkpointers_[id] = r;
|
||||
return r;
|
||||
}
|
||||
@@ -82,11 +85,11 @@ DatabaseCon::~DatabaseCon()
|
||||
std::unique_ptr<std::vector<std::string> const> DatabaseCon::Setup::globalPragma;
|
||||
|
||||
void
|
||||
DatabaseCon::setupCheckpointing(JobQueue* q, Logs& l)
|
||||
DatabaseCon::setupCheckpointing(JobQueue* q, ServiceRegistry& registry)
|
||||
{
|
||||
if (q == nullptr)
|
||||
Throw<std::logic_error>("No JobQueue");
|
||||
checkpointer_ = checkpointers.create(session_, *q, l);
|
||||
checkpointer_ = checkpointers.create(session_, *q, registry);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -187,8 +187,11 @@ public:
|
||||
std::uintptr_t id,
|
||||
std::weak_ptr<soci::session> session,
|
||||
JobQueue& q,
|
||||
Logs& logs)
|
||||
: id_(id), session_(std::move(session)), jobQueue_(q), j_(logs.journal("WALCheckpointer"))
|
||||
ServiceRegistry& registry)
|
||||
: id_(id)
|
||||
, session_(std::move(session))
|
||||
, jobQueue_(q)
|
||||
, j_(registry.getJournal("WALCheckpointer"))
|
||||
{
|
||||
if (auto [conn, keepAlive] = getConnection(); conn)
|
||||
{
|
||||
@@ -307,9 +310,9 @@ makeCheckpointer(
|
||||
std::uintptr_t id,
|
||||
std::weak_ptr<soci::session> session,
|
||||
JobQueue& queue,
|
||||
Logs& logs)
|
||||
ServiceRegistry& registry)
|
||||
{
|
||||
return std::make_shared<WALCheckpointer>(id, std::move(session), queue, logs);
|
||||
return std::make_shared<WALCheckpointer>(id, std::move(session), queue, registry);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -12,7 +12,7 @@ doVacuumDB(DatabaseCon::Setup const& setup, beast::Journal j)
|
||||
boost::filesystem::path dbPath = setup.dataDir / TxDBName;
|
||||
|
||||
uintmax_t const dbSize = file_size(dbPath);
|
||||
XRPL_ASSERT(dbSize != static_cast<uintmax_t>(-1), "ripple:doVacuumDB : file_size succeeded");
|
||||
XRPL_ASSERT(dbSize != static_cast<uintmax_t>(-1), "xrpl::doVacuumDB : file_size succeeded");
|
||||
|
||||
if (auto available = space(dbPath.parent_path()).available; available < dbSize)
|
||||
{
|
||||
@@ -36,7 +36,7 @@ doVacuumDB(DatabaseCon::Setup const& setup, beast::Journal j)
|
||||
std::cout << "VACUUM beginning. page_size: " << pageSize << std::endl;
|
||||
|
||||
session << "VACUUM;";
|
||||
XRPL_ASSERT(setup.globalPragma, "ripple:doVacuumDB : non-null global pragma");
|
||||
XRPL_ASSERT(setup.globalPragma, "xrpl::doVacuumDB : non-null global pragma");
|
||||
for (auto const& p : *setup.globalPragma)
|
||||
session << p;
|
||||
session << "PRAGMA page_size;", soci::into(pageSize);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user