mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-09 13:32:23 +00:00
Compare commits
24 Commits
ripple/se/
...
kennyzlei/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96dc3f17b8 | ||
|
|
9f7b9983f0 | ||
|
|
5ff0ad9ebd | ||
|
|
bd91668883 | ||
|
|
871d60f910 | ||
|
|
36503b5017 | ||
|
|
e47107bf3a | ||
|
|
bcb48fbad3 | ||
|
|
6cb9f336da | ||
|
|
e752479219 | ||
|
|
70752f8b82 | ||
|
|
ddcf08593b | ||
|
|
d0b54a0a5a | ||
|
|
c3cff1ed5c | ||
|
|
d892f0e73d | ||
|
|
200f93a287 | ||
|
|
90d2eb839a | ||
|
|
359a94b766 | ||
|
|
5e39c1d80c | ||
|
|
25abc8ffae | ||
|
|
a669dcec87 | ||
|
|
4f5a3241de | ||
|
|
c729a26dd3 | ||
|
|
69084a6ff5 |
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 xrpld project
|
||||
title: "[Title with short description] (Version: [xrpld version])"
|
||||
about: Suggest a new feature for the rippled project
|
||||
title: "[Title with short description] (Version: [rippled 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 xrpld from
|
||||
Levelization is the term used to describe efforts to prevent rippled from
|
||||
having or creating cyclic dependencies.
|
||||
|
||||
xrpld code is organized into directories under `src/xrpld`, `src/libxrpl` (and
|
||||
rippled 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 its own.
|
||||
other than it's 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 xrpld code. The levels are numbered from
|
||||
state of the rippled 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 xrpld repo.
|
||||
as long as it is in the expected location in the rippled 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 xrpld source. The only caveat is that it runs much slower
|
||||
the rippled 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):
|
||||
|
||||
|
||||
3
.github/scripts/rename/README.md
vendored
3
.github/scripts/rename/README.md
vendored
@@ -34,8 +34,6 @@ 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:
|
||||
|
||||
@@ -46,5 +44,4 @@ 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,7 +49,6 @@ ${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,15 +52,16 @@ 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
96
.github/scripts/rename/docs.sh
vendored
@@ -1,96 +0,0 @@
|
||||
#!/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,17 +31,16 @@ 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" -o -name "*.macro" \) | while read -r FILE; do
|
||||
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" \) | 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 xrpld-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
|
||||
# GCC-Asan rippled-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"
|
||||
|
||||
4
.github/workflows/publish-docs.yml
vendored
4
.github/workflows/publish-docs.yml
vendored
@@ -81,13 +81,13 @@ jobs:
|
||||
cmake --build . --target docs --parallel ${BUILD_NPROC}
|
||||
|
||||
- name: Create documentation artifact
|
||||
if: ${{ github.event.repository.visibility == 'public' && github.event_name == 'push' }}
|
||||
if: ${{ (github.repository_owner == 'XRPLF' || 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.repository == 'XRPLF/rippled' && github.event_name == 'push' }}
|
||||
if: ${{ (github.repository_owner == 'XRPLF' || github.event.repository.visibility == 'public') && github.event_name == 'push' }}
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
|
||||
@@ -199,7 +199,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Upload the binary (Linux)
|
||||
if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }}
|
||||
if: ${{ (github.repository_owner == 'XRPLF' || github.event.repository.visibility == 'public') && runner.os == 'Linux' }}
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: xrpld-${{ inputs.config_name }}
|
||||
|
||||
2
.github/workflows/reusable-check-rename.yml
vendored
2
.github/workflows/reusable-check-rename.yml
vendored
@@ -33,8 +33,6 @@ 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}" -quiet -allow-no-checks ${TARGETS} 2>&1 | tee clang-tidy-output.txt
|
||||
|
||||
- name: Upload clang-tidy output
|
||||
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
|
||||
if: ${{ (github.repository_owner == 'XRPLF' || 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 `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 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 [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 (`xrpld`) 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 (`rippled`) release.
|
||||
|
||||
## API Version 3 (Beta)
|
||||
|
||||
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 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 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 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 1
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Unreleased
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# API Version 2
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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 xrpld 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 rippled 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 `xrpl_libs`
|
||||
(search for the existing call to `target_link_libraries(xrpl_libs INTERFACE ...)`).
|
||||
- Link a library from the package to the target `ripple_libs`
|
||||
(search for the existing call to `target_link_libraries(ripple_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
|
||||
|
||||
@@ -88,12 +88,12 @@ find_package(ed25519 REQUIRED)
|
||||
find_package(gRPC REQUIRED)
|
||||
find_package(LibArchive REQUIRED)
|
||||
find_package(lz4 REQUIRED)
|
||||
find_package(mpt-crypto REQUIRED)
|
||||
find_package(nudb REQUIRED)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(secp256k1 REQUIRED)
|
||||
find_package(SOCI REQUIRED)
|
||||
find_package(SQLite3 REQUIRED)
|
||||
find_package(wasmi REQUIRED)
|
||||
find_package(xxHash REQUIRED)
|
||||
|
||||
target_link_libraries(
|
||||
@@ -101,6 +101,7 @@ target_link_libraries(
|
||||
INTERFACE
|
||||
ed25519::ed25519
|
||||
lz4::lz4
|
||||
mpt-crypto::mpt-crypto
|
||||
OpenSSL::Crypto
|
||||
OpenSSL::SSL
|
||||
secp256k1::secp256k1
|
||||
|
||||
@@ -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.
|
||||
|
||||
Xrpld uses a linear workflow model that can be summarized as:
|
||||
Rippled 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.
|
||||
|
||||
## xrpld
|
||||
## rippled
|
||||
|
||||
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).
|
||||
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).
|
||||
|
||||
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.)
|
||||
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.)
|
||||
|
||||
### 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/xrpld/**/*.md`.
|
||||
- Read the markdown files in the source tree: `src/ripple/**/*.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 XRPL developers. |
|
||||
| `./Builds` | Platform-specific guides for building `xrpld`. |
|
||||
| `./docs` | Source documentation files and doxygen config. |
|
||||
| `./cfg` | Example configuration files. |
|
||||
| `./src` | Source code. |
|
||||
| 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. |
|
||||
|
||||
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 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).
|
||||
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).
|
||||
|
||||
## 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 [`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)).
|
||||
[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)).
|
||||
|
||||
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 `xrpld`, `xrpl.js`, `xrpl-py`, `xrpl4j`.
|
||||
1. **In scope**. Only bugs in software under the scope of the program qualify. Currently, that means `rippled`, `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/xrpld/vl.txt
|
||||
# file:///etc/opt/ripple/vl.txt
|
||||
#
|
||||
# [validator_list_keys]
|
||||
#
|
||||
@@ -43,11 +43,11 @@
|
||||
# ED307A760EE34F2D0CAA103377B1969117C38B8AA0AA1E2A24DAC1F32FC97087ED
|
||||
#
|
||||
|
||||
# The default validator list publishers that the xrpld instance
|
||||
# The default validator list publishers that the rippled instance
|
||||
# trusts.
|
||||
#
|
||||
# WARNING: Changing these values can cause your xrpld instance to see a
|
||||
# validated ledger that contradicts other xrpld instances'
|
||||
# WARNING: Changing these values can cause your rippled instance to see a
|
||||
# validated ledger that contradicts other rippled 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. XRPL protocol
|
||||
# 3. Ripple 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
|
||||
# XRPL payment protocol. It is over peer connections that transactions
|
||||
# Ripple 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 XRPL protocol is served. A default
|
||||
# List of hostnames or ips where the Ripple 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
|
||||
# XRPL network through a public-facing server, or for building a set
|
||||
# Ripple 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/username/validators.txt
|
||||
# C:/home/username/validators.txt
|
||||
# /home/ripple/validators.txt
|
||||
# C:/home/ripple/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, an xrpld node only downloads
|
||||
# acquiring a ledger from the network, a 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 an XRPL payment
|
||||
# fetch information such as mapping an email address to a Ripple Payment
|
||||
# Network address.
|
||||
#
|
||||
# [ssl_verify]
|
||||
@@ -1227,7 +1227,7 @@
|
||||
#
|
||||
#----------
|
||||
#
|
||||
# The vote settings configure settings for the entire XRPL network.
|
||||
# The vote settings configure settings for the entire Ripple 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.
|
||||
@@ -1272,39 +1272,6 @@
|
||||
# Example:
|
||||
# owner_reserve = 2000000 # 2 XRP
|
||||
#
|
||||
# extension_compute_limit = <gas>
|
||||
#
|
||||
# The extension compute limit is the maximum amount of gas that can be
|
||||
# consumed by a single transaction. The gas limit is used to prevent
|
||||
# transactions from consuming too many resources.
|
||||
#
|
||||
# If this parameter is unspecified, xrpld will use an internal
|
||||
# default. Don't change this without understanding the consequences.
|
||||
#
|
||||
# Example:
|
||||
# extension_compute_limit = 1000000 # 1 million gas
|
||||
#
|
||||
# extension_size_limit = <bytes>
|
||||
#
|
||||
# The extension size limit is the maximum size of a WASM extension in
|
||||
# bytes. The size limit is used to prevent extensions from consuming
|
||||
# too many resources.
|
||||
#
|
||||
# If this parameter is unspecified, xrpld will use an internal
|
||||
# default. Don't change this without understanding the consequences.
|
||||
#
|
||||
# Example:
|
||||
# extension_size_limit = 100000 # 100 kb
|
||||
#
|
||||
# gas_price = <bytes>
|
||||
#
|
||||
# The gas price is the conversion between WASM gas and its price in drops.
|
||||
#
|
||||
# If this parameter is unspecified, xrpld will use an internal
|
||||
# default. Don't change this without understanding the consequences.
|
||||
#
|
||||
# Example:
|
||||
# gas_price = 1000000 # 1 drop per gas
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# 9. Misc Settings
|
||||
|
||||
@@ -67,7 +67,6 @@ target_link_libraries(
|
||||
Xrpl::opts
|
||||
Xrpl::syslibs
|
||||
secp256k1::secp256k1
|
||||
wasmi::wasmi
|
||||
xrpl.libpb
|
||||
xxHash::xxhash
|
||||
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
|
||||
|
||||
11
conan.lock
11
conan.lock
@@ -3,7 +3,6 @@
|
||||
"requires": [
|
||||
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809",
|
||||
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
|
||||
"wasmi/1.0.9#1fecdab9b90c96698eb35ea99ca4f5cb%1772227278.324",
|
||||
"sqlite3/3.51.0#66aa11eabd0e34954c5c1c061ad44abe%1774467355.988",
|
||||
"soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231",
|
||||
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",
|
||||
@@ -12,7 +11,8 @@
|
||||
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1774398111.888",
|
||||
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1774467363.12",
|
||||
"openssl/3.6.1#e6399de266349245a4542fc5f6c71552%1774458290.139",
|
||||
"nudb/2.0.9#11149c73f8f2baff9a0198fe25971fc7%1775040983.408",
|
||||
"nudb/2.0.9#11149c73f8f2baff9a0198fe25971fc7%1774883011.384",
|
||||
"mpt-crypto/0.2.0-rc1#ed3f241f69d8b9ebf80069d1923d93a8%1773853481.755",
|
||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914",
|
||||
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492",
|
||||
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1765842973.03",
|
||||
@@ -35,6 +35,7 @@
|
||||
"msys2/cci.latest#d22fe7b2808f5fd34d0a7923ace9c54f%1770657326.649",
|
||||
"m4/1.4.19#5d7a4994e5875d76faf7acf3ed056036%1774365463.87",
|
||||
"cmake/4.3.0#b939a42e98f593fb34d3a8c5cc860359%1774439249.183",
|
||||
"cmake/3.31.10#313d16a1aa16bbdb2ca0792467214b76%1765850153.479",
|
||||
"b2/5.4.2#ffd6084a119587e70f11cd45d1a386e2%1774439233.447",
|
||||
"automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56",
|
||||
"autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86",
|
||||
@@ -59,6 +60,12 @@
|
||||
],
|
||||
"lz4/[>=1.9.4 <2]": [
|
||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504"
|
||||
],
|
||||
"openssl/3.5.5": [
|
||||
"openssl/3.6.1"
|
||||
],
|
||||
"openssl/[>=3 <4]": [
|
||||
"openssl/3.6.1"
|
||||
]
|
||||
},
|
||||
"config_requires": []
|
||||
|
||||
@@ -31,11 +31,11 @@ class Xrpl(ConanFile):
|
||||
"ed25519/2015.03",
|
||||
"grpc/1.78.1",
|
||||
"libarchive/3.8.1",
|
||||
"mpt-crypto/0.2.0-rc1",
|
||||
"nudb/2.0.9",
|
||||
"openssl/3.6.1",
|
||||
"secp256k1/0.7.1",
|
||||
"soci/4.0.3",
|
||||
"wasmi/1.0.9",
|
||||
"zlib/1.3.1",
|
||||
]
|
||||
|
||||
@@ -215,13 +215,13 @@ class Xrpl(ConanFile):
|
||||
"grpc::grpc++",
|
||||
"libarchive::libarchive",
|
||||
"lz4::lz4",
|
||||
"mpt-crypto::mpt-crypto",
|
||||
"nudb::nudb",
|
||||
"openssl::crypto",
|
||||
"protobuf::libprotobuf",
|
||||
"soci::soci",
|
||||
"secp256k1::secp256k1",
|
||||
"sqlite3::sqlite",
|
||||
"wasmi::wasmi",
|
||||
"xxhash::xxhash",
|
||||
"zlib::zlib",
|
||||
]
|
||||
|
||||
@@ -7,8 +7,6 @@ ignorePaths:
|
||||
- cmake/**
|
||||
- LICENSE.md
|
||||
- .clang-tidy
|
||||
- src/test/app/wasm_fixtures/**/*.wat
|
||||
- src/test/app/wasm_fixtures/*.c
|
||||
language: en
|
||||
allowCompoundWords: true # TODO (#6334)
|
||||
ignoreRandomStrings: true
|
||||
@@ -46,10 +44,6 @@ suggestWords:
|
||||
words:
|
||||
- abempty
|
||||
- AMMID
|
||||
- AMMMPT
|
||||
- AMMMPToken
|
||||
- AMMMPTokens
|
||||
- AMMXRP
|
||||
- amt
|
||||
- amts
|
||||
- asnode
|
||||
@@ -61,12 +55,12 @@ words:
|
||||
- autobridging
|
||||
- bimap
|
||||
- bindir
|
||||
- blindings
|
||||
- bookdir
|
||||
- Bougalis
|
||||
- Britto
|
||||
- Btrfs
|
||||
- canonicality
|
||||
- cdylib
|
||||
- changespq
|
||||
- checkme
|
||||
- choco
|
||||
@@ -94,6 +88,7 @@ words:
|
||||
- daria
|
||||
- dcmake
|
||||
- dearmor
|
||||
- decryptor
|
||||
- deleteme
|
||||
- demultiplexer
|
||||
- deserializaton
|
||||
@@ -103,7 +98,7 @@ words:
|
||||
- distro
|
||||
- doxyfile
|
||||
- dxrpl
|
||||
- enabled
|
||||
- elgamal
|
||||
- endmacro
|
||||
- exceptioned
|
||||
- Falco
|
||||
@@ -113,6 +108,7 @@ words:
|
||||
- fmtdur
|
||||
- fsanitize
|
||||
- funclets
|
||||
- Gamal
|
||||
- gcov
|
||||
- gcovr
|
||||
- ghead
|
||||
@@ -156,8 +152,6 @@ words:
|
||||
- ltype
|
||||
- mcmodel
|
||||
- MEMORYSTATUSEX
|
||||
- MPTAMM
|
||||
- MPTDEX
|
||||
- Merkle
|
||||
- Metafuncton
|
||||
- misprediction
|
||||
@@ -167,7 +161,6 @@ words:
|
||||
- mptid
|
||||
- mptissuance
|
||||
- mptissuanceid
|
||||
- mptissue
|
||||
- mptoken
|
||||
- mptokenid
|
||||
- mptokenissuance
|
||||
@@ -202,6 +195,7 @@ words:
|
||||
- partitioner
|
||||
- paychan
|
||||
- paychans
|
||||
- Pedersen
|
||||
- permdex
|
||||
- perminute
|
||||
- permissioned
|
||||
@@ -238,6 +232,7 @@ words:
|
||||
- sahyadri
|
||||
- Satoshi
|
||||
- scons
|
||||
- Schnorr
|
||||
- secp
|
||||
- sendq
|
||||
- seqit
|
||||
@@ -257,7 +252,6 @@ words:
|
||||
- STATSDCOLLECTOR
|
||||
- stissue
|
||||
- stnum
|
||||
- stnumber
|
||||
- stobj
|
||||
- stobject
|
||||
- stpath
|
||||
@@ -266,6 +260,7 @@ words:
|
||||
- stvar
|
||||
- stvector
|
||||
- stxchainattestations
|
||||
- summands
|
||||
- superpeer
|
||||
- superpeers
|
||||
- takergets
|
||||
|
||||
@@ -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 xrpld that does not send all validation
|
||||
nodes, or by running modified rippled 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 xrpld will be changed to have faster ledger time. Most if
|
||||
timing parameters of rippled 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/XRPLF/rippled/blob/develop/src/test/csf/README.md)
|
||||
Framework](https://github.com/ripple/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 "Xrpld Start" as RS
|
||||
actor "Rippled Start" as RS
|
||||
participant "Timer" as T
|
||||
participant "NetworkOPs" as NOP
|
||||
participant "ValidatorList" as VL #lightgreen
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# `xrpld` Docker Image
|
||||
# `rippled` Docker Image
|
||||
|
||||
- Some info relating to Docker containers can be found here: [../Builds/containers](../Builds/containers)
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "xrpld"
|
||||
PROJECT_NAME = "rippled"
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_BRIEF =
|
||||
PROJECT_LOGO =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## Heap profiling of xrpld with jemalloc
|
||||
## Heap profiling of rippled 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 xrpld, and is not affiliated
|
||||
jemalloc is acquired separately from rippled, 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 xrpld on a Linux platform. It should
|
||||
work on platforms on which both xrpld and jemalloc are available.
|
||||
profiling has been tested with rippled on a Linux platform. It should
|
||||
work on platforms on which both rippled and jemalloc are available.
|
||||
|
||||
To link xrpld with jemalloc, the argument
|
||||
To link rippled 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 xrpld with jemalloc library under /usr/local/lib and
|
||||
Build rippled with jemalloc library under /usr/local/lib and
|
||||
header under /usr/local/include:
|
||||
|
||||
$ scons profile-jemalloc=/usr/local
|
||||
|
||||
Build xrpld using clang with the jemalloc library under /opt/local/lib
|
||||
Build rippled using clang with the jemalloc library under /opt/local/lib
|
||||
and header under /opt/local/include:
|
||||
|
||||
$ scons clang profile-jemalloc=/opt/local
|
||||
|
||||
61
docs/README.md
Normal file
61
docs/README.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# 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 xrpld project.
|
||||
# then you can export the recipe from the rippled project.
|
||||
conan export <path>
|
||||
```
|
||||
|
||||
@@ -49,9 +49,9 @@ cmake --build . --parallel
|
||||
|
||||
## CMake subdirectory
|
||||
|
||||
The second method adds the [xrpld][] project as a CMake
|
||||
The second method adds the [rippled][] project as a CMake
|
||||
[subdirectory][add_subdirectory].
|
||||
This method works well when you keep the xrpld project as a Git
|
||||
This method works well when you keep the rippled 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
|
||||
[xrpld]: https://github.com/XRPLF/rippled
|
||||
[rippled]: https://github.com/ripple/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 xrpld. You may want to install a specific version of Xcode:
|
||||
This will likely cause issues building rippled. 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 xrpld.
|
||||
This document contains instructions for installing rippled.
|
||||
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 xrpld and libxrpl using CMake's
|
||||
From a source build, you can install rippled 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/xrpld` on Windows.
|
||||
`C:/Program Files/rippled` 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 XRPL repository for your operating system version:
|
||||
5. Add the appropriate Ripple repository for your operating system version:
|
||||
|
||||
echo "deb [signed-by=/usr/local/share/keyrings/ripple-key.gpg] https://repos.ripple.com/repos/xrpld-deb focal stable" | \
|
||||
echo "deb [signed-by=/usr/local/share/keyrings/ripple-key.gpg] https://repos.ripple.com/repos/rippled-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 `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))
|
||||
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))
|
||||
|
||||
**Warning:** Unstable and nightly builds may be broken at any time. Do not use these builds for production servers.
|
||||
|
||||
6. Fetch the XRPL repository.
|
||||
6. Fetch the Ripple repository.
|
||||
|
||||
sudo apt -y update
|
||||
|
||||
7. Install the `xrpld` software package:
|
||||
7. Install the `rippled` software package:
|
||||
|
||||
sudo apt -y install xrpld
|
||||
sudo apt -y install rippled
|
||||
|
||||
8. Check the status of the `xrpld` service:
|
||||
8. Check the status of the `rippled` service:
|
||||
|
||||
systemctl status xrpld.service
|
||||
systemctl status rippled.service
|
||||
|
||||
The `xrpld` service should start automatically. If not, you can start it manually:
|
||||
The `rippled` service should start automatically. If not, you can start it manually:
|
||||
|
||||
sudo systemctl start xrpld.service
|
||||
sudo systemctl start rippled.service
|
||||
|
||||
9. Optional: allow `xrpld` to bind to privileged ports.
|
||||
9. Optional: allow `rippled` 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/xrpld/bin/xrpld
|
||||
sudo setcap 'cap_net_bind_service=+ep' /opt/ripple/bin/rippled
|
||||
|
||||
## 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/xrpld-rpm/stable/
|
||||
gpgkey=https://repos.ripple.com/repos/xrpld-rpm/stable/repodata/repomd.xml.key
|
||||
baseurl=https://repos.ripple.com/repos/rippled-rpm/stable/
|
||||
gpgkey=https://repos.ripple.com/repos/rippled-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/xrpld-rpm/unstable/
|
||||
gpgkey=https://repos.ripple.com/repos/xrpld-rpm/unstable/repodata/repomd.xml.key
|
||||
baseurl=https://repos.ripple.com/repos/rippled-rpm/unstable/
|
||||
gpgkey=https://repos.ripple.com/repos/rippled-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/xrpld-rpm/nightly/
|
||||
gpgkey=https://repos.ripple.com/repos/xrpld-rpm/nightly/repodata/repomd.xml.key
|
||||
baseurl=https://repos.ripple.com/repos/rippled-rpm/nightly/
|
||||
gpgkey=https://repos.ripple.com/repos/rippled-rpm/nightly/repodata/repomd.xml.key
|
||||
REPOFILE
|
||||
|
||||
2. Fetch the latest repo updates:
|
||||
|
||||
sudo yum -y update
|
||||
|
||||
3. Install the new `xrpld` package:
|
||||
3. Install the new `rippled` package:
|
||||
|
||||
sudo yum install -y xrpld
|
||||
sudo yum install -y rippled
|
||||
|
||||
4. Configure the `xrpld` service to start on boot:
|
||||
4. Configure the `rippled` service to start on boot:
|
||||
|
||||
sudo systemctl enable xrpld.service
|
||||
sudo systemctl enable rippled.service
|
||||
|
||||
5. Start the `xrpld` service:
|
||||
5. Start the `rippled` service:
|
||||
|
||||
sudo systemctl start xrpld.service
|
||||
sudo systemctl start rippled.service
|
||||
|
||||
6
docs/build/sanitizers.md
vendored
6
docs/build/sanitizers.md
vendored
@@ -1,9 +1,9 @@
|
||||
# Sanitizer Configuration for Xrpld
|
||||
# Sanitizer Configuration for Rippled
|
||||
|
||||
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 Xrpld](#sanitizer-configuration-for-xrpld)
|
||||
- [Sanitizer Configuration for Rippled](#sanitizer-configuration-for-rippled)
|
||||
- [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 xrpld 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 rippled 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 [xrpld](https://github.com/XRPLF/rippled), but
|
||||
as implemented in [rippled](https://github.com/ripple/rippled), but
|
||||
focuses on its utility as a generic consensus algorithm independent of the
|
||||
detailed mechanics of the XRPL consensus Ledger. Most notably, the algorithm
|
||||
detailed mechanics of the Ripple 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 XRPL network, the shared state is the current ledger--account
|
||||
state. For the Ripple 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 XRPL network, transactions include payments,
|
||||
prior ledger. For the Ripple 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 XRPL network is a decentralized and **trust-full** network. Anyone is free
|
||||
The Ripple 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 XRPL algorithm has two main components.
|
||||
Leveraging this network of trust, the Ripple 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 `xrpld`. The document **does not** discuss correctness,
|
||||
implementation in `rippled`. The document **does not** discuss correctness,
|
||||
fault-tolerance or liveness properties of the algorithms or the full details of
|
||||
how they integrate within `xrpld` to support the XRPL consensus Ledger.
|
||||
how they integrate within `rippled` to support the Ripple 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 xrpld.
|
||||
The subdirectories in this directory contain external libraries used by rippled.
|
||||
|
||||
| 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 xrpld project
|
||||
# Note, version set explicitly by rippled 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 xrpld project
|
||||
# Note, both sections below created by rippled 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 basics
|
||||
@ingroup ripple_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 xrpld, we
|
||||
memory used by the object until the weak count reaches zero. In rippled, 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 an xrpl::IntrusivePointer by
|
||||
A class can satisfy the requirements of a xrpl::IntrusivePointer by
|
||||
inheriting from this class.
|
||||
*/
|
||||
struct IntrusiveRefCounts
|
||||
|
||||
@@ -381,9 +381,6 @@ public:
|
||||
friend Number
|
||||
root2(Number f);
|
||||
|
||||
friend Number
|
||||
log10(Number const&, int);
|
||||
|
||||
// Thread local rounding control. Default is to_nearest
|
||||
enum rounding_mode { to_nearest, towards_zero, downward, upward };
|
||||
static rounding_mode
|
||||
@@ -732,10 +729,6 @@ abs(Number x) noexcept
|
||||
Number
|
||||
power(Number const& f, unsigned n);
|
||||
|
||||
// logarithm with base 10
|
||||
Number
|
||||
log10(Number const& value, int iterations = 50);
|
||||
|
||||
// Returns f^(1/d)
|
||||
// Uses Newton–Raphson iterations until the result stops changing
|
||||
// to find the root of the polynomial g(x) = x^d - f
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
Utility functions and classes.
|
||||
|
||||
The module xrpl/basics should contain no dependencies on other modules.
|
||||
ripple/basic should contain no dependencies on other modules.
|
||||
|
||||
# Choosing an xrpld container.
|
||||
# Choosing a rippled 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 xrpld program start
|
||||
now(); // seconds since rippled program start
|
||||
|
||||
private:
|
||||
static std::atomic<rep> now_;
|
||||
|
||||
@@ -17,13 +17,13 @@ static_assert(
|
||||
// NOLINTNEXTLINE(misc-redundant-expression)
|
||||
std::is_integral<beast::xor_shift_engine::result_type>::value &&
|
||||
std::is_unsigned<beast::xor_shift_engine::result_type>::value,
|
||||
"The XRPL default PRNG engine must return an unsigned integral type.");
|
||||
"The Ripple default PRNG engine must return an unsigned integral type.");
|
||||
|
||||
static_assert(
|
||||
// NOLINTNEXTLINE(misc-redundant-expression)
|
||||
std::numeric_limits<beast::xor_shift_engine::result_type>::max() >=
|
||||
std::numeric_limits<std::uint64_t>::max(),
|
||||
"The XRPL default PRNG engine return must be at least 64 bits wide.");
|
||||
"The Ripple default PRNG engine return must be at least 64 bits wide.");
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <xrpl/basics/Blob.h>
|
||||
#include <xrpl/basics/SHAMapHash.h>
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
#include <xrpl/protocol/Fees.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
@@ -239,9 +238,6 @@ public:
|
||||
virtual DatabaseCon&
|
||||
getWalletDB() = 0;
|
||||
|
||||
virtual Fees
|
||||
getFees() const = 0;
|
||||
|
||||
// Temporary: Get the underlying Application for functions that haven't
|
||||
// been migrated yet. This should be removed once all code is migrated.
|
||||
virtual Application&
|
||||
|
||||
@@ -213,60 +213,11 @@ public:
|
||||
// Called when a credit is made to an account
|
||||
// This is required to support PaymentSandbox
|
||||
virtual void
|
||||
creditHookIOU(
|
||||
creditHook(
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
STAmount const& amount,
|
||||
STAmount const& preCreditBalance)
|
||||
{
|
||||
XRPL_ASSERT(amount.holds<Issue>(), "creditHookIOU: amount is for Issue");
|
||||
}
|
||||
|
||||
virtual void
|
||||
creditHookMPT(
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
STAmount const& amount,
|
||||
std::uint64_t preCreditBalanceHolder,
|
||||
std::int64_t preCreditBalanceIssuer)
|
||||
{
|
||||
XRPL_ASSERT(amount.holds<MPTIssue>(), "creditHookMPT: amount is for MPTIssue");
|
||||
}
|
||||
|
||||
/** Facilitate tracking of MPT sold by an issuer owning MPT sell offer.
|
||||
* Unlike IOU, MPT doesn't have bi-directional relationship with an issuer,
|
||||
* where a trustline limits an amount that can be issued to a holder.
|
||||
* Consequently, the credit step (last MPTEndpointStep or
|
||||
* BookStep buying MPT) might temporarily overflow OutstandingAmount.
|
||||
* Limiting of a step's output amount in this case is delegated to
|
||||
* the next step (in rev order). The next step always redeems when a holder
|
||||
* account sells MPT (first MPTEndpointStep or BookStep selling MPT).
|
||||
* In this case the holder account is only limited by the step's output
|
||||
* and it's available funds since it's transferring the funds from one
|
||||
* account to another account and doesn't change OutstandingAmount.
|
||||
* This doesn't apply to an offer owned by an issuer.
|
||||
* In this case the issuer sells or self debits and is increasing
|
||||
* OutstandingAmount. Ability to issue is limited by the issuer
|
||||
* originally available funds less already self sold MPT amounts (MPT sell
|
||||
* offer).
|
||||
* Consider an example:
|
||||
* - GW creates MPT(USD) with 1,000USD MaximumAmount.
|
||||
* - GW pays 950USD to A1.
|
||||
* - A1 creates an offer 100XRP(buy)/100USD(sell).
|
||||
* - GW creates an offer 100XRP(buy)/100USD(sell).
|
||||
* - A2 pays 200USD to A3 with sendMax of 200XRP.
|
||||
* Since the payment engine executes payments in reverse,
|
||||
* OutstandingAmount overflows in MPTEndpointStep: 950 + 200 = 1,150USD.
|
||||
* BookStep first consumes A1 offer. This reduces OutstandingAmount
|
||||
* by 100USD: 1,150 - 100 = 1,050USD. GW offer can only be partially
|
||||
* consumed because the initial available amount is 50USD = 1,000 - 950.
|
||||
* BookStep limits it's output to 150USD. This in turn limits A3's send
|
||||
* amount to 150XRP: A1 buys 100XRP and sells 100USD to A3. This doesn't
|
||||
* change OutstandingAmount. GW buys 50XRP and sells 50USD to A3. This
|
||||
* changes OutstandingAmount to 1,000USD.
|
||||
*/
|
||||
virtual void
|
||||
issuerSelfDebitHookMPT(MPTIssue const& issue, std::uint64_t amount, std::int64_t origBalance)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -54,18 +54,6 @@ public:
|
||||
deliver_ = amount;
|
||||
}
|
||||
|
||||
void
|
||||
setGasUsed(std::optional<std::uint32_t> const gasUsed)
|
||||
{
|
||||
gasUsed_ = gasUsed;
|
||||
}
|
||||
|
||||
void
|
||||
setWasmReturnCode(std::int32_t const wasmReturnCode)
|
||||
{
|
||||
wasmReturnCode_ = wasmReturnCode;
|
||||
}
|
||||
|
||||
/** Get the number of modified entries
|
||||
*/
|
||||
std::size_t
|
||||
@@ -84,8 +72,6 @@ public:
|
||||
|
||||
private:
|
||||
std::optional<STAmount> deliver_;
|
||||
std::optional<std::uint32_t> gasUsed_;
|
||||
std::optional<std::int32_t> wasmReturnCode_;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -34,7 +34,7 @@ auto constexpr decreaseLedgerTimeResolutionEvery = 1;
|
||||
|
||||
/** Calculates the close time resolution for the specified ledger.
|
||||
|
||||
The XRPL protocol uses binning to represent time intervals using only one
|
||||
The Ripple 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}, "xrpl::getNextLedgerTimeResolution : valid ledger sequence");
|
||||
XRPL_ASSERT(ledgerSeq != Seq{0}, "ripple:getNextLedgerTimeResolution : valid ledger sequence");
|
||||
|
||||
using namespace std::chrono;
|
||||
// Find the current resolution:
|
||||
@@ -72,7 +72,7 @@ getNextLedgerTimeResolution(
|
||||
previousResolution);
|
||||
XRPL_ASSERT(
|
||||
iter != std::end(ledgerPossibleTimeResolutions),
|
||||
"xrpl::getNextLedgerTimeResolution : found time resolution");
|
||||
"ripple:getNextLedgerTimeResolution : found time resolution");
|
||||
|
||||
// This should never happen, but just as a precaution
|
||||
if (iter == std::end(ledgerPossibleTimeResolutions))
|
||||
|
||||
@@ -28,7 +28,7 @@ inline constexpr struct open_ledger_t
|
||||
/** Batch view construction tag.
|
||||
|
||||
Views constructed with this tag are part of a stack of views
|
||||
used during batch transaction applied.
|
||||
used during batch transaction application.
|
||||
*/
|
||||
inline constexpr struct batch_view_t
|
||||
{
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <xrpl/ledger/AcceptedLedgerTx.h>
|
||||
#include <xrpl/ledger/BookListeners.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Book.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/MultiApiJson.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
@@ -53,30 +53,30 @@ public:
|
||||
issue. This is useful for pathfinding to find all possible next hops
|
||||
from a given currency.
|
||||
|
||||
@param asset The asset to search for
|
||||
@param issue The issue to search for
|
||||
@param domain Optional domain restriction for the order book
|
||||
@return Vector of books that want this issue
|
||||
*/
|
||||
virtual std::vector<Book>
|
||||
getBooksByTakerPays(Asset const& asset, std::optional<Domain> const& domain = std::nullopt) = 0;
|
||||
getBooksByTakerPays(Issue const& issue, std::optional<Domain> const& domain = std::nullopt) = 0;
|
||||
|
||||
/** Get the count of order books that want a specific issue.
|
||||
|
||||
@param asset The asset to search for
|
||||
@param issue The issue to search for
|
||||
@param domain Optional domain restriction for the order book
|
||||
@return Number of books that want this issue
|
||||
*/
|
||||
virtual int
|
||||
getBookSize(Asset const& asset, std::optional<Domain> const& domain = std::nullopt) = 0;
|
||||
getBookSize(Issue const& issue, std::optional<Domain> const& domain = std::nullopt) = 0;
|
||||
|
||||
/** Check if an order book to XRP exists for the given issue.
|
||||
|
||||
@param asset The asset to check
|
||||
@param issue The issue to check
|
||||
@param domain Optional domain restriction for the order book
|
||||
@return true if a book from this issue to XRP exists
|
||||
*/
|
||||
virtual bool
|
||||
isBookToXRP(Asset const& asset, std::optional<Domain> const& domain = std::nullopt) = 0;
|
||||
isBookToXRP(Issue const& issue, std::optional<Domain> const& domain = std::nullopt) = 0;
|
||||
|
||||
/**
|
||||
* Process a transaction for order book tracking.
|
||||
|
||||
@@ -15,55 +15,10 @@ namespace detail {
|
||||
// into the PaymentSandbox class itself
|
||||
class DeferredCredits
|
||||
{
|
||||
private:
|
||||
using KeyIOU = std::tuple<AccountID, AccountID, Currency>;
|
||||
struct ValueIOU
|
||||
{
|
||||
explicit ValueIOU() = default;
|
||||
|
||||
STAmount lowAcctCredits;
|
||||
STAmount highAcctCredits;
|
||||
STAmount lowAcctOrigBalance;
|
||||
};
|
||||
|
||||
struct HolderValueMPT
|
||||
{
|
||||
HolderValueMPT() = default;
|
||||
// Debit to issuer
|
||||
std::uint64_t debit = 0;
|
||||
std::uint64_t origBalance = 0;
|
||||
};
|
||||
|
||||
struct IssuerValueMPT
|
||||
{
|
||||
IssuerValueMPT() = default;
|
||||
std::map<AccountID, HolderValueMPT> holders;
|
||||
// Credit to holder
|
||||
std::uint64_t credit = 0;
|
||||
// OutstandingAmount might overflow when MPTs are credited to a holder.
|
||||
// Consider A1 paying 100MPT to A2 and A1 already having maximum MPTs.
|
||||
// Since the payment engine executes a payment in revers, A2 is
|
||||
// credited first and OutstandingAmount is going to be equal
|
||||
// to MaximumAmount + 100MPT. In the next step A1 redeems 100MPT
|
||||
// to the issuer and OutstandingAmount balances out.
|
||||
std::int64_t origBalance = 0;
|
||||
// Self debit on offer selling MPT. Since the payment engine executes
|
||||
// a payment in reverse, a crediting/buying step may overflow
|
||||
// OutstandingAmount. A sell MPT offer owned by a holder can redeem any
|
||||
// amount up to the offer's amount and holder's available funds,
|
||||
// balancing out OutstandingAmount. But if the offer's owner is issuer
|
||||
// then it issues more MPT. In this case the available amount to issue
|
||||
// is the initial issuer's available amount less all offer sell amounts
|
||||
// by the issuer. This is self-debit, where the offer's owner,
|
||||
// issuer in this case, debits to self.
|
||||
std::uint64_t selfDebit = 0;
|
||||
};
|
||||
using AdjustmentMPT = IssuerValueMPT;
|
||||
|
||||
public:
|
||||
struct AdjustmentIOU
|
||||
struct Adjustment
|
||||
{
|
||||
AdjustmentIOU(STAmount const& d, STAmount const& c, STAmount const& b)
|
||||
Adjustment(STAmount const& d, STAmount const& c, STAmount const& b)
|
||||
: debits(d), credits(c), origBalance(b)
|
||||
{
|
||||
}
|
||||
@@ -74,30 +29,16 @@ public:
|
||||
|
||||
// Get the adjustments for the balance between main and other.
|
||||
// Returns the debits, credits and the original balance
|
||||
std::optional<AdjustmentIOU>
|
||||
adjustmentsIOU(AccountID const& main, AccountID const& other, Currency const& currency) const;
|
||||
|
||||
std::optional<AdjustmentMPT>
|
||||
adjustmentsMPT(MPTID const& mptID) const;
|
||||
std::optional<Adjustment>
|
||||
adjustments(AccountID const& main, AccountID const& other, Currency const& currency) const;
|
||||
|
||||
void
|
||||
creditIOU(
|
||||
credit(
|
||||
AccountID const& sender,
|
||||
AccountID const& receiver,
|
||||
STAmount const& amount,
|
||||
STAmount const& preCreditSenderBalance);
|
||||
|
||||
void
|
||||
creditMPT(
|
||||
AccountID const& sender,
|
||||
AccountID const& receiver,
|
||||
STAmount const& amount,
|
||||
std::uint64_t preCreditBalanceHolder,
|
||||
std::int64_t preCreditBalanceIssuer);
|
||||
|
||||
void
|
||||
issuerSelfDebitMPT(MPTIssue const& issue, std::uint64_t amount, std::int64_t origBalance);
|
||||
|
||||
void
|
||||
ownerCount(AccountID const& id, std::uint32_t cur, std::uint32_t next);
|
||||
|
||||
@@ -111,11 +52,21 @@ public:
|
||||
apply(DeferredCredits& to);
|
||||
|
||||
private:
|
||||
static KeyIOU
|
||||
makeKeyIOU(AccountID const& a1, AccountID const& a2, Currency const& currency);
|
||||
// lowAccount, highAccount
|
||||
using Key = std::tuple<AccountID, AccountID, Currency>;
|
||||
struct Value
|
||||
{
|
||||
explicit Value() = default;
|
||||
|
||||
std::map<KeyIOU, ValueIOU> creditsIOU_;
|
||||
std::map<MPTID, IssuerValueMPT> creditsMPT_;
|
||||
STAmount lowAcctCredits;
|
||||
STAmount highAcctCredits;
|
||||
STAmount lowAcctOrigBalance;
|
||||
};
|
||||
|
||||
static Key
|
||||
makeKey(AccountID const& a1, AccountID const& a2, Currency const& c);
|
||||
|
||||
std::map<Key, Value> credits_;
|
||||
std::map<AccountID, std::uint32_t> ownerCounts_;
|
||||
};
|
||||
|
||||
@@ -180,35 +131,16 @@ public:
|
||||
/** @} */
|
||||
|
||||
STAmount
|
||||
balanceHookIOU(AccountID const& account, AccountID const& issuer, STAmount const& amount)
|
||||
balanceHook(AccountID const& account, AccountID const& issuer, STAmount const& amount)
|
||||
const override;
|
||||
|
||||
STAmount
|
||||
balanceHookMPT(AccountID const& account, MPTIssue const& issue, std::int64_t amount)
|
||||
const override;
|
||||
|
||||
STAmount
|
||||
balanceHookSelfIssueMPT(MPTIssue const& issue, std::int64_t amount) const override;
|
||||
|
||||
void
|
||||
creditHookIOU(
|
||||
creditHook(
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
STAmount const& amount,
|
||||
STAmount const& preCreditBalance) override;
|
||||
|
||||
void
|
||||
creditHookMPT(
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
STAmount const& amount,
|
||||
std::uint64_t preCreditBalanceHolder,
|
||||
std::int64_t preCreditBalanceIssuer) override;
|
||||
|
||||
void
|
||||
issuerSelfDebitHookMPT(MPTIssue const& issue, std::uint64_t amount, std::int64_t origBalance)
|
||||
override;
|
||||
|
||||
void
|
||||
adjustOwnerCountHook(AccountID const& account, std::uint32_t cur, std::uint32_t next) override;
|
||||
|
||||
|
||||
@@ -148,35 +148,15 @@ public:
|
||||
|
||||
// Accounts in a payment are not allowed to use assets acquired during that
|
||||
// payment. The PaymentSandbox tracks the debits, credits, and owner count
|
||||
// changes that accounts make during a payment. `balanceHookIOU` adjusts
|
||||
// changes that accounts make during a payment. `balanceHook` adjusts
|
||||
// balances so newly acquired assets are not counted toward the balance.
|
||||
// This is required to support PaymentSandbox.
|
||||
virtual STAmount
|
||||
balanceHookIOU(AccountID const& account, AccountID const& issuer, STAmount const& amount) const
|
||||
balanceHook(AccountID const& account, AccountID const& issuer, STAmount const& amount) const
|
||||
{
|
||||
XRPL_ASSERT(amount.holds<Issue>(), "balanceHookIOU: amount is for Issue");
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// balanceHookMPT adjusts balances so newly acquired assets are not counted
|
||||
// toward the balance.
|
||||
virtual STAmount
|
||||
balanceHookMPT(AccountID const& account, MPTIssue const& issue, std::int64_t amount) const
|
||||
{
|
||||
return STAmount{issue, amount};
|
||||
}
|
||||
|
||||
// An offer owned by an issuer and selling MPT is limited by the issuer's
|
||||
// funds available to issue, which are originally available funds less
|
||||
// already self sold MPT amounts (MPT sell offer). This hook is used
|
||||
// by issuerFundsToSelfIssue() function.
|
||||
virtual STAmount
|
||||
balanceHookSelfIssueMPT(MPTIssue const& issue, std::int64_t amount) const
|
||||
{
|
||||
return STAmount{issue, amount};
|
||||
}
|
||||
|
||||
// Accounts in a payment are not allowed to use assets acquired during that
|
||||
// payment. The PaymentSandbox tracks the debits, credits, and owner count
|
||||
// changes that accounts make during a payment. `ownerCountHook` adjusts the
|
||||
|
||||
@@ -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 "XRPL epoch" which, for historical reasons, is set
|
||||
seconds after the "Ripple 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 XRPL epoch is
|
||||
This is like the way the Unix epoch works, except the Ripple Epoch is
|
||||
precisely 946,684,800 seconds after the Unix Epoch.
|
||||
|
||||
See https://xrpl.org/basic-data-types.html#specifying-time
|
||||
@@ -63,8 +63,8 @@ isVaultPseudoAccountFrozen(
|
||||
isLPTokenFrozen(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
Asset const& asset,
|
||||
Asset const& asset2);
|
||||
Issue const& asset,
|
||||
Issue const& asset2);
|
||||
|
||||
// Return the list of enabled amendments
|
||||
[[nodiscard]] std::set<uint256>
|
||||
|
||||
@@ -52,8 +52,6 @@ public:
|
||||
TER ter,
|
||||
std::optional<STAmount> const& deliver,
|
||||
std::optional<uint256 const> const& parentBatchId,
|
||||
std::optional<std::uint32_t> const& gasUsed,
|
||||
std::optional<std::int32_t> const& wasmReturnCode,
|
||||
bool isDryRun,
|
||||
beast::Journal j);
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ enum class IsDeposit : bool { No = false, Yes = true };
|
||||
* @return LP Tokens as IOU
|
||||
*/
|
||||
STAmount
|
||||
ammLPTokens(STAmount const& asset1, STAmount const& asset2, Asset const& lptIssue);
|
||||
ammLPTokens(STAmount const& asset1, STAmount const& asset2, Issue const& lptIssue);
|
||||
|
||||
/** Calculate LP Tokens given asset's deposit amount.
|
||||
* @param asset1Balance current AMM asset1 balance
|
||||
@@ -124,8 +124,7 @@ withinRelativeDistance(Quality const& calcQuality, Quality const& reqQuality, Nu
|
||||
template <typename Amt>
|
||||
requires(
|
||||
std::is_same_v<Amt, STAmount> || std::is_same_v<Amt, IOUAmount> ||
|
||||
std::is_same_v<Amt, XRPAmount> || std::is_same_v<Amt, MPTAmount> ||
|
||||
std::is_same_v<Amt, Number>)
|
||||
std::is_same_v<Amt, XRPAmount> || std::is_same_v<Amt, Number>)
|
||||
bool
|
||||
withinRelativeDistance(Amt const& calc, Amt const& req, Number const& dist)
|
||||
{
|
||||
@@ -196,7 +195,7 @@ getAMMOfferStartWithTakerGets(
|
||||
// Round downward to minimize the offer and to maximize the quality.
|
||||
// This has the most impact when takerGets is XRP.
|
||||
auto const takerGets =
|
||||
toAmount<TOut>(getAsset(pool.out), nTakerGetsProposed, Number::downward);
|
||||
toAmount<TOut>(getIssue(pool.out), nTakerGetsProposed, Number::downward);
|
||||
return TAmounts<TIn, TOut>{swapAssetOut(pool, takerGets, tfee), takerGets};
|
||||
};
|
||||
|
||||
@@ -263,7 +262,7 @@ getAMMOfferStartWithTakerPays(
|
||||
// Round downward to minimize the offer and to maximize the quality.
|
||||
// This has the most impact when takerPays is XRP.
|
||||
auto const takerPays =
|
||||
toAmount<TIn>(getAsset(pool.in), nTakerPaysProposed, Number::downward);
|
||||
toAmount<TIn>(getIssue(pool.in), nTakerPaysProposed, Number::downward);
|
||||
return TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
|
||||
};
|
||||
|
||||
@@ -332,7 +331,7 @@ changeSpotPriceQuality(
|
||||
<< " " << to_string(pool.out) << " " << quality << " " << tfee;
|
||||
return std::nullopt;
|
||||
}
|
||||
auto const takerPays = toAmount<TIn>(getAsset(pool.in), nTakerPays, Number::upward);
|
||||
auto const takerPays = toAmount<TIn>(getIssue(pool.in), nTakerPays, Number::upward);
|
||||
// should not fail
|
||||
if (auto amounts = TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
|
||||
Quality{amounts} < quality &&
|
||||
@@ -361,7 +360,7 @@ changeSpotPriceQuality(
|
||||
// Generate the offer starting with XRP side. Return seated offer amounts
|
||||
// if the offer can be generated, otherwise nullopt.
|
||||
auto amounts = [&]() {
|
||||
if (isXRP(getAsset(pool.out)))
|
||||
if (isXRP(getIssue(pool.out)))
|
||||
return getAMMOfferStartWithTakerGets(pool, quality, tfee);
|
||||
return getAMMOfferStartWithTakerPays(pool, quality, tfee);
|
||||
}();
|
||||
@@ -446,7 +445,7 @@ swapAssetIn(TAmounts<TIn, TOut> const& pool, TIn const& assetIn, std::uint16_t t
|
||||
auto const denom = pool.in + assetIn * (1 - fee);
|
||||
|
||||
if (denom.signum() <= 0)
|
||||
return toAmount<TOut>(getAsset(pool.out), 0);
|
||||
return toAmount<TOut>(getIssue(pool.out), 0);
|
||||
|
||||
Number::setround(Number::upward);
|
||||
auto const ratio = numerator / denom;
|
||||
@@ -455,14 +454,14 @@ swapAssetIn(TAmounts<TIn, TOut> const& pool, TIn const& assetIn, std::uint16_t t
|
||||
auto const swapOut = pool.out - ratio;
|
||||
|
||||
if (swapOut.signum() < 0)
|
||||
return toAmount<TOut>(getAsset(pool.out), 0);
|
||||
return toAmount<TOut>(getIssue(pool.out), 0);
|
||||
|
||||
return toAmount<TOut>(getAsset(pool.out), swapOut, Number::downward);
|
||||
return toAmount<TOut>(getIssue(pool.out), swapOut, Number::downward);
|
||||
}
|
||||
else
|
||||
{
|
||||
return toAmount<TOut>(
|
||||
getAsset(pool.out),
|
||||
getIssue(pool.out),
|
||||
pool.out - (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)),
|
||||
Number::downward);
|
||||
}
|
||||
@@ -509,7 +508,7 @@ swapAssetOut(TAmounts<TIn, TOut> const& pool, TOut const& assetOut, std::uint16_
|
||||
auto const denom = pool.out - assetOut;
|
||||
if (denom.signum() <= 0)
|
||||
{
|
||||
return toMaxAmount<TIn>(getAsset(pool.in));
|
||||
return toMaxAmount<TIn>(getIssue(pool.in));
|
||||
}
|
||||
|
||||
Number::setround(Number::upward);
|
||||
@@ -523,14 +522,14 @@ swapAssetOut(TAmounts<TIn, TOut> const& pool, TOut const& assetOut, std::uint16_
|
||||
Number::setround(Number::upward);
|
||||
auto const swapIn = numerator2 / feeMult;
|
||||
if (swapIn.signum() < 0)
|
||||
return toAmount<TIn>(getAsset(pool.in), 0);
|
||||
return toAmount<TIn>(getIssue(pool.in), 0);
|
||||
|
||||
return toAmount<TIn>(getAsset(pool.in), swapIn, Number::upward);
|
||||
return toAmount<TIn>(getIssue(pool.in), swapIn, Number::upward);
|
||||
}
|
||||
else
|
||||
{
|
||||
return toAmount<TIn>(
|
||||
getAsset(pool.in),
|
||||
getIssue(pool.in),
|
||||
((pool.in * pool.out) / (pool.out - assetOut) - pool.in) / feeMult(tfee),
|
||||
Number::upward);
|
||||
}
|
||||
@@ -617,9 +616,9 @@ getRoundedAsset(Rules const& rules, STAmount const& balance, A const& frac, IsDe
|
||||
if (!rules.enabled(fixAMMv1_3))
|
||||
{
|
||||
if constexpr (std::is_same_v<A, STAmount>)
|
||||
return multiply(balance, frac, balance.asset());
|
||||
return multiply(balance, frac, balance.issue());
|
||||
else
|
||||
return toSTAmount(balance.asset(), balance * frac);
|
||||
return toSTAmount(balance.issue(), balance * frac);
|
||||
}
|
||||
auto const rm = detail::getAssetRounding(isDeposit);
|
||||
return multiply(balance, frac, rm);
|
||||
|
||||
@@ -21,10 +21,9 @@ std::pair<STAmount, STAmount>
|
||||
ammPoolHolds(
|
||||
ReadView const& view,
|
||||
AccountID const& ammAccountID,
|
||||
Asset const& asset1,
|
||||
Asset const& asset2,
|
||||
Issue const& issue1,
|
||||
Issue const& issue2,
|
||||
FreezeHandling freezeHandling,
|
||||
AuthHandling authHandling,
|
||||
beast::Journal const j);
|
||||
|
||||
/** Get AMM pool and LP token balances. If both optIssue are
|
||||
@@ -35,10 +34,9 @@ Expected<std::tuple<STAmount, STAmount, STAmount>, TER>
|
||||
ammHolds(
|
||||
ReadView const& view,
|
||||
SLE const& ammSle,
|
||||
std::optional<Asset> const& optAsset1,
|
||||
std::optional<Asset> const& optAsset2,
|
||||
std::optional<Issue> const& optIssue1,
|
||||
std::optional<Issue> const& optIssue2,
|
||||
FreezeHandling freezeHandling,
|
||||
AuthHandling authHandling,
|
||||
beast::Journal const j);
|
||||
|
||||
/** Get the balance of LP tokens.
|
||||
@@ -46,8 +44,8 @@ ammHolds(
|
||||
STAmount
|
||||
ammLPHolds(
|
||||
ReadView const& view,
|
||||
Asset const& asset1,
|
||||
Asset const& asset2,
|
||||
Currency const& cur1,
|
||||
Currency const& cur2,
|
||||
AccountID const& ammAccount,
|
||||
AccountID const& lpAccount,
|
||||
beast::Journal const j);
|
||||
@@ -69,13 +67,13 @@ getTradingFee(ReadView const& view, SLE const& ammSle, AccountID const& account)
|
||||
/** Returns total amount held by AMM for the given token.
|
||||
*/
|
||||
STAmount
|
||||
ammAccountHolds(ReadView const& view, AccountID const& ammAccountID, Asset const& asset);
|
||||
ammAccountHolds(ReadView const& view, AccountID const& ammAccountID, Issue const& issue);
|
||||
|
||||
/** Delete trustlines to AMM. If all trustlines are deleted then
|
||||
* AMM object and account are deleted. Otherwise tecIMPCOMPLETE is returned.
|
||||
*/
|
||||
TER
|
||||
deleteAMMAccount(Sandbox& view, Asset const& asset, Asset const& asset2, beast::Journal j);
|
||||
deleteAMMAccount(Sandbox& view, Issue const& asset, Issue const& asset2, beast::Journal j);
|
||||
|
||||
/** Initialize Auction and Voting slots and set the trading/discounted fee.
|
||||
*/
|
||||
@@ -84,7 +82,7 @@ initializeFeeAuctionVote(
|
||||
ApplyView& view,
|
||||
std::shared_ptr<SLE>& ammSle,
|
||||
AccountID const& account,
|
||||
Asset const& lptAsset,
|
||||
Issue const& lptIssue,
|
||||
std::uint16_t tfee);
|
||||
|
||||
/** Return true if the Liquidity Provider is the only AMM provider, false
|
||||
|
||||
@@ -41,8 +41,7 @@ escrowUnlockApplyHelper<Issue>(
|
||||
bool createAsset,
|
||||
beast::Journal journal)
|
||||
{
|
||||
Issue const& issue = amount.get<Issue>();
|
||||
Keylet const trustLineKey = keylet::line(receiver, issue);
|
||||
Keylet const trustLineKey = keylet::line(receiver, amount.issue());
|
||||
bool const recvLow = issuer > receiver;
|
||||
bool const senderIssuer = issuer == sender;
|
||||
bool const receiverIssuer = issuer == receiver;
|
||||
@@ -65,9 +64,9 @@ escrowUnlockApplyHelper<Issue>(
|
||||
return tecNO_LINE_INSUF_RESERVE;
|
||||
}
|
||||
|
||||
Currency const currency = issue.currency;
|
||||
STAmount initialBalance(issue);
|
||||
initialBalance.get<Issue>().account = noAccount();
|
||||
Currency const currency = amount.getCurrency();
|
||||
STAmount initialBalance(amount.issue());
|
||||
initialBalance.setIssuer(noAccount());
|
||||
|
||||
if (TER const ter = trustCreate(
|
||||
view, // payment sandbox
|
||||
@@ -114,8 +113,7 @@ escrowUnlockApplyHelper<Issue>(
|
||||
if ((!senderIssuer && !receiverIssuer) && lockedRate != parityRate)
|
||||
{
|
||||
// compute transfer fee, if any
|
||||
auto const xferFee =
|
||||
amount.value() - divideRound(amount, lockedRate, amount.get<Issue>(), true);
|
||||
auto const xferFee = amount.value() - divideRound(amount, lockedRate, amount.issue(), true);
|
||||
// compute balance to transfer
|
||||
finalAmt = amount.value() - xferFee;
|
||||
}
|
||||
@@ -150,7 +148,7 @@ escrowUnlockApplyHelper<Issue>(
|
||||
// if destination is not the issuer then transfer funds
|
||||
if (!receiverIssuer)
|
||||
{
|
||||
auto const ter = directSendNoFee(view, issuer, receiver, finalAmt, true, journal);
|
||||
auto const ter = rippleCredit(view, issuer, receiver, finalAmt, true, journal);
|
||||
if (!isTesSuccess(ter))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
@@ -218,7 +216,7 @@ escrowUnlockApplyHelper<MPTIssue>(
|
||||
// compute balance to transfer
|
||||
finalAmt = amount.value() - xferFee;
|
||||
}
|
||||
return unlockEscrowMPT(
|
||||
return rippleUnlockEscrowMPT(
|
||||
view,
|
||||
sender,
|
||||
receiver,
|
||||
@@ -227,15 +225,4 @@ escrowUnlockApplyHelper<MPTIssue>(
|
||||
journal);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static uint32_t
|
||||
calculateAdditionalReserve(T const& finishFunction)
|
||||
{
|
||||
if (!finishFunction)
|
||||
return 1;
|
||||
// First 500 bytes included in the normal reserve
|
||||
// Each additional 500 bytes requires an additional reserve
|
||||
return 1 + (finishFunction->size() / 500);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -80,7 +80,6 @@ authorizeMPToken(
|
||||
* requireAuth check is recursive for MPT shares in a vault, descending to
|
||||
* assets in the vault, up to maxAssetCheckDepth recursion depth. This is
|
||||
* purely defensive, as we currently do not allow such vaults to be created.
|
||||
* WeakAuth intentionally allows missing MPTokens under MPToken V2.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
requireAuth(
|
||||
@@ -115,12 +114,6 @@ canTransfer(
|
||||
AccountID const& from,
|
||||
AccountID const& to);
|
||||
|
||||
/** Check if Asset can be traded on DEX. return tecNO_PERMISSION
|
||||
* if it doesn't and tesSUCCESS otherwise.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
canTrade(ReadView const& view, Asset const& asset);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Empty holding operations (MPT-specific)
|
||||
@@ -149,14 +142,14 @@ removeEmptyHolding(
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TER
|
||||
lockEscrowMPT(
|
||||
rippleLockEscrowMPT(
|
||||
ApplyView& view,
|
||||
AccountID const& uGrantorID,
|
||||
STAmount const& saAmount,
|
||||
beast::Journal j);
|
||||
|
||||
TER
|
||||
unlockEscrowMPT(
|
||||
rippleUnlockEscrowMPT(
|
||||
ApplyView& view,
|
||||
AccountID const& uGrantorID,
|
||||
AccountID const& uGranteeID,
|
||||
@@ -171,73 +164,4 @@ createMPToken(
|
||||
AccountID const& account,
|
||||
std::uint32_t const flags);
|
||||
|
||||
TER
|
||||
checkCreateMPT(
|
||||
xrpl::ApplyView& view,
|
||||
xrpl::MPTIssue const& mptIssue,
|
||||
xrpl::AccountID const& holder,
|
||||
beast::Journal j);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// MPT Overflow related
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// MaximumAmount doesn't exceed 2**63-1
|
||||
std::int64_t
|
||||
maxMPTAmount(SLE const& sleIssuance);
|
||||
|
||||
// OutstandingAmount may overflow and available amount might be negative.
|
||||
// But available amount is always <= |MaximumAmount - OutstandingAmount|.
|
||||
std::int64_t
|
||||
availableMPTAmount(SLE const& sleIssuance);
|
||||
|
||||
std::int64_t
|
||||
availableMPTAmount(ReadView const& view, MPTID const& mptID);
|
||||
|
||||
/** Checks for two types of OutstandingAmount overflow during a send operation.
|
||||
* 1. **Direct directSendNoFee (Overflow: No):** A true overflow check when
|
||||
* `OutstandingAmount > MaximumAmount`. This threshold is used for direct
|
||||
* directSendNoFee transactions that bypass the payment engine.
|
||||
* 2. **accountSend & Payment Engine (Overflow: Yes):** A temporary overflow
|
||||
* check when `OutstandingAmount > UINT64_MAX`. This higher threshold is used
|
||||
* for `accountSend` and payments processed via the payment engine.
|
||||
*/
|
||||
bool
|
||||
isMPTOverflow(
|
||||
std::int64_t sendAmount,
|
||||
std::uint64_t outstandingAmount,
|
||||
std::int64_t maximumAmount,
|
||||
AllowMPTOverflow allowOverflow);
|
||||
|
||||
/**
|
||||
* Determine funds available for an issuer to sell in an issuer owned offer.
|
||||
* Issuing step, which could be either MPTEndPointStep last step or BookStep's
|
||||
* TakerPays may overflow OutstandingAmount. Redeeming step, in BookStep's
|
||||
* TakerGets redeems the offer's owner funds, essentially balancing out
|
||||
* the overflow, unless the offer's owner is the issuer.
|
||||
*/
|
||||
[[nodiscard]] STAmount
|
||||
issuerFundsToSelfIssue(ReadView const& view, MPTIssue const& issue);
|
||||
|
||||
/** Facilitate tracking of MPT sold by an issuer owning MPT sell offer.
|
||||
* See ApplyView::issuerSelfDebitHookMPT().
|
||||
*/
|
||||
void
|
||||
issuerSelfDebitHookMPT(ApplyView& view, MPTIssue const& issue, std::uint64_t amount);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// MPT DEX
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* Return true if a transaction is allowed for the specified MPT/account. The
|
||||
* function checks MPTokenIssuance and MPToken objects flags to determine if the
|
||||
* transaction is allowed.
|
||||
*/
|
||||
TER
|
||||
checkMPTTxAllowed(ReadView const& v, TxType tx, Asset const& asset, AccountID const& accountID);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -252,14 +252,4 @@ deleteAMMTrustLine(
|
||||
std::optional<AccountID> const& ammAccountID,
|
||||
beast::Journal j);
|
||||
|
||||
/** Delete AMMs MPToken. The passed `sle` must be obtained from a prior
|
||||
* call to view.peek().
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
deleteAMMMPToken(
|
||||
ApplyView& view,
|
||||
std::shared_ptr<SLE> sleMPT,
|
||||
AccountID const& ammAccountID,
|
||||
beast::Journal j);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -31,9 +31,6 @@ enum SpendableHandling { shSIMPLE_BALANCE, shFULL_BALANCE };
|
||||
|
||||
enum class WaiveTransferFee : bool { No = false, Yes };
|
||||
|
||||
/** Controls whether accountSend is allowed to overflow OutstandingAmount **/
|
||||
enum class AllowMPTOverflow : bool { No = false, Yes };
|
||||
|
||||
/* Check if MPToken (for MPT) or trust line (for IOU) exists:
|
||||
* - StrongAuth - before checking if authorization is required
|
||||
* - WeakAuth
|
||||
@@ -179,16 +176,6 @@ accountFunds(
|
||||
FreezeHandling freezeHandling,
|
||||
beast::Journal j);
|
||||
|
||||
// Overload with AuthHandling to support IOU and MPT.
|
||||
[[nodiscard]] STAmount
|
||||
accountFunds(
|
||||
ReadView const& view,
|
||||
AccountID const& id,
|
||||
STAmount const& saDefault,
|
||||
FreezeHandling freezeHandling,
|
||||
AuthHandling authHandling,
|
||||
beast::Journal j);
|
||||
|
||||
/** Returns the transfer fee as Rate based on the type of token
|
||||
* @param view The ledger view
|
||||
* @param amount The amount to transfer
|
||||
@@ -248,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 directSendNoFeeIOU if saAmount represents Issue.
|
||||
* Calls static directSendNoFeeMPT if saAmount represents MPTIssue.
|
||||
/** Calls static rippleCreditIOU if saAmount represents Issue.
|
||||
* Calls static rippleCreditMPT if saAmount represents MPTIssue.
|
||||
*/
|
||||
TER
|
||||
directSendNoFee(
|
||||
rippleCredit(
|
||||
ApplyView& view,
|
||||
AccountID const& uSenderID,
|
||||
AccountID const& uReceiverID,
|
||||
@@ -270,8 +257,7 @@ accountSend(
|
||||
AccountID const& to,
|
||||
STAmount const& saAmount,
|
||||
beast::Journal j,
|
||||
WaiveTransferFee waiveFee = WaiveTransferFee::No,
|
||||
AllowMPTOverflow allowOverflow = AllowMPTOverflow::No);
|
||||
WaiveTransferFee waiveFee = WaiveTransferFee::No);
|
||||
|
||||
using MultiplePaymentDestinations = std::vector<std::pair<AccountID, Number>>;
|
||||
/** Like accountSend, except one account is sending multiple payments (with the
|
||||
|
||||
@@ -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 xrpld uses as its primary representation of
|
||||
collection of NodeObjects that rippled 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:
|
||||
|
||||
```
|
||||
$xrpld --unittest=NodeStoreTiming
|
||||
$rippled --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 xrpld instances running there is no need for such guarantees. The nodes
|
||||
other rippled 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 xrpld's use case
|
||||
- Lookup in a block was previously using binary search. With rippled'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 xrpld gRPC API.
|
||||
This folder contains the protocol buffer definitions used by the rippled 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 xrpld API:
|
||||
As of April 2020, the gRPC API supports a subset of the full rippled 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/xrpld/rpc/handlers folder. If the method already has a JSON/Websocket
|
||||
src/ripple/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 XRPL serialization format.
|
||||
// A Manifest object in the Ripple serialization format.
|
||||
required bytes stobject = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
@@ -31,12 +31,12 @@ class Rules;
|
||||
/** Calculate Liquidity Provider Token (LPT) Currency.
|
||||
*/
|
||||
Currency
|
||||
ammLPTCurrency(Asset const& asset1, Asset const& asset2);
|
||||
ammLPTCurrency(Currency const& cur1, Currency const& cur2);
|
||||
|
||||
/** Calculate LPT Issue from AMM asset pair.
|
||||
*/
|
||||
Issue
|
||||
ammLPTIssue(Asset const& asset1, Asset const& asset2, AccountID const& ammAccountID);
|
||||
ammLPTIssue(Currency const& cur1, Currency const& cur2, AccountID const& ammAccountID);
|
||||
|
||||
/** Validate the amount.
|
||||
* If validZero is false and amount is beast::zero then invalid amount.
|
||||
@@ -46,19 +46,19 @@ ammLPTIssue(Asset const& asset1, Asset const& asset2, AccountID const& ammAccoun
|
||||
NotTEC
|
||||
invalidAMMAmount(
|
||||
STAmount const& amount,
|
||||
std::optional<std::pair<Asset, Asset>> const& pair = std::nullopt,
|
||||
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt,
|
||||
bool validZero = false);
|
||||
|
||||
NotTEC
|
||||
invalidAMMAsset(
|
||||
Asset const& asset,
|
||||
std::optional<std::pair<Asset, Asset>> const& pair = std::nullopt);
|
||||
Issue const& issue,
|
||||
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt);
|
||||
|
||||
NotTEC
|
||||
invalidAMMAssetPair(
|
||||
Asset const& asset1,
|
||||
Asset const& asset2,
|
||||
std::optional<std::pair<Asset, Asset>> const& pair = std::nullopt);
|
||||
Issue const& issue1,
|
||||
Issue const& issue2,
|
||||
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt);
|
||||
|
||||
/** Get time slot of the auction slot.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <xrpl/protocol/tokens.h>
|
||||
// VFALCO Uncomment when the header issues are resolved
|
||||
// #include <xrpl/protocol/PublicKey.h>
|
||||
// #include <ripple/protocol/PublicKey.h>
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/IOUAmount.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
@@ -10,12 +9,11 @@
|
||||
namespace xrpl {
|
||||
|
||||
inline STAmount
|
||||
toSTAmount(IOUAmount const& iou, Asset const& asset)
|
||||
toSTAmount(IOUAmount const& iou, Issue const& iss)
|
||||
{
|
||||
XRPL_ASSERT(asset.holds<Issue>(), "xrpl::toSTAmount : is Issue");
|
||||
bool const isNeg = iou.signum() < 0;
|
||||
std::uint64_t const umant = isNeg ? -iou.mantissa() : iou.mantissa();
|
||||
return STAmount(asset, umant, iou.exponent(), isNeg, STAmount::unchecked());
|
||||
return STAmount(iss, umant, iou.exponent(), isNeg, STAmount::unchecked());
|
||||
}
|
||||
|
||||
inline STAmount
|
||||
@@ -33,25 +31,12 @@ toSTAmount(XRPAmount const& xrp)
|
||||
}
|
||||
|
||||
inline STAmount
|
||||
toSTAmount(XRPAmount const& xrp, Asset const& asset)
|
||||
toSTAmount(XRPAmount const& xrp, Issue const& iss)
|
||||
{
|
||||
XRPL_ASSERT(isXRP(asset), "xrpl::toSTAmount : is XRP");
|
||||
XRPL_ASSERT(isXRP(iss.account) && isXRP(iss.currency), "xrpl::toSTAmount : is XRP");
|
||||
return toSTAmount(xrp);
|
||||
}
|
||||
|
||||
inline STAmount
|
||||
toSTAmount(MPTAmount const& mpt)
|
||||
{
|
||||
return STAmount(mpt, noMPT());
|
||||
}
|
||||
|
||||
inline STAmount
|
||||
toSTAmount(MPTAmount const& mpt, Asset const& asset)
|
||||
{
|
||||
XRPL_ASSERT(asset.holds<MPTIssue>(), "xrpl::toSTAmount : is MPT");
|
||||
return STAmount(mpt, asset.get<MPTIssue>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T
|
||||
toAmount(STAmount const& amt) = delete;
|
||||
@@ -91,21 +76,6 @@ toAmount<XRPAmount>(STAmount const& amt)
|
||||
return XRPAmount(sMant);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline MPTAmount
|
||||
toAmount<MPTAmount>(STAmount const& amt)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
amt.holds<MPTIssue>() && amt.mantissa() <= maxMPTokenAmount && amt.exponent() == 0,
|
||||
"xrpl::toAmount<MPTAmount> : maximum mantissa");
|
||||
if (amt.mantissa() > maxMPTokenAmount || amt.exponent() != 0)
|
||||
Throw<std::runtime_error>("toAmount<MPTAmount>: invalid mantissa or exponent");
|
||||
bool const isNeg = amt.negative();
|
||||
std::int64_t const sMant = isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
|
||||
|
||||
return MPTAmount(sMant);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T
|
||||
toAmount(IOUAmount const& amt) = delete;
|
||||
@@ -128,36 +98,23 @@ toAmount<XRPAmount>(XRPAmount const& amt)
|
||||
return amt;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T
|
||||
toAmount(MPTAmount const& amt) = delete;
|
||||
|
||||
template <>
|
||||
inline MPTAmount
|
||||
toAmount<MPTAmount>(MPTAmount const& amt)
|
||||
{
|
||||
return amt;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T
|
||||
toAmount(Asset const& asset, Number const& n, Number::rounding_mode mode = Number::getround())
|
||||
toAmount(Issue const& issue, Number const& n, Number::rounding_mode mode = Number::getround())
|
||||
{
|
||||
saveNumberRoundMode const rm(Number::getround());
|
||||
if (isXRP(asset))
|
||||
if (isXRP(issue))
|
||||
Number::setround(mode);
|
||||
|
||||
if constexpr (std::is_same_v<IOUAmount, T>)
|
||||
return IOUAmount(n);
|
||||
else if constexpr (std::is_same_v<XRPAmount, T>)
|
||||
return XRPAmount(static_cast<std::int64_t>(n));
|
||||
else if constexpr (std::is_same_v<MPTAmount, T>)
|
||||
return MPTAmount(static_cast<std::int64_t>(n));
|
||||
else if constexpr (std::is_same_v<STAmount, T>)
|
||||
{
|
||||
if (isXRP(asset))
|
||||
return STAmount(asset, static_cast<std::int64_t>(n));
|
||||
return STAmount(asset, n);
|
||||
if (isXRP(issue))
|
||||
return STAmount(issue, static_cast<std::int64_t>(n));
|
||||
return STAmount(issue, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -168,23 +125,17 @@ toAmount(Asset const& asset, Number const& n, Number::rounding_mode mode = Numbe
|
||||
|
||||
template <typename T>
|
||||
T
|
||||
toMaxAmount(Asset const& asset)
|
||||
toMaxAmount(Issue const& issue)
|
||||
{
|
||||
if constexpr (std::is_same_v<IOUAmount, T>)
|
||||
return IOUAmount(STAmount::cMaxValue, STAmount::cMaxOffset);
|
||||
else if constexpr (std::is_same_v<XRPAmount, T>)
|
||||
return XRPAmount(static_cast<std::int64_t>(STAmount::cMaxNativeN));
|
||||
else if constexpr (std::is_same_v<MPTAmount, T>)
|
||||
return MPTAmount(maxMPTokenAmount);
|
||||
else if constexpr (std::is_same_v<STAmount, T>)
|
||||
{
|
||||
return asset.visit(
|
||||
[](Issue const& issue) {
|
||||
if (isXRP(issue))
|
||||
return STAmount(issue, static_cast<std::int64_t>(STAmount::cMaxNativeN));
|
||||
return STAmount(issue, STAmount::cMaxValue, STAmount::cMaxOffset);
|
||||
},
|
||||
[](MPTIssue const& issue) { return STAmount(issue, maxMPTokenAmount); });
|
||||
if (isXRP(issue))
|
||||
return STAmount(issue, static_cast<std::int64_t>(STAmount::cMaxNativeN));
|
||||
return STAmount(issue, STAmount::cMaxValue, STAmount::cMaxOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -194,23 +145,21 @@ toMaxAmount(Asset const& asset)
|
||||
}
|
||||
|
||||
inline STAmount
|
||||
toSTAmount(Asset const& asset, Number const& n, Number::rounding_mode mode = Number::getround())
|
||||
toSTAmount(Issue const& issue, Number const& n, Number::rounding_mode mode = Number::getround())
|
||||
{
|
||||
return toAmount<STAmount>(asset, n, mode);
|
||||
return toAmount<STAmount>(issue, n, mode);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Asset
|
||||
getAsset(T const& amt)
|
||||
Issue
|
||||
getIssue(T const& amt)
|
||||
{
|
||||
if constexpr (std::is_same_v<IOUAmount, T>)
|
||||
return noIssue();
|
||||
else if constexpr (std::is_same_v<XRPAmount, T>)
|
||||
return xrpIssue();
|
||||
else if constexpr (std::is_same_v<MPTAmount, T>)
|
||||
return noMPT();
|
||||
else if constexpr (std::is_same_v<STAmount, T>)
|
||||
return amt.asset();
|
||||
return amt.issue();
|
||||
else
|
||||
{
|
||||
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
|
||||
@@ -226,8 +175,6 @@ get(STAmount const& a)
|
||||
return a.iou();
|
||||
else if constexpr (std::is_same_v<XRPAmount, T>)
|
||||
return a.xrp();
|
||||
else if constexpr (std::is_same_v<MPTAmount, T>)
|
||||
return a.mpt();
|
||||
else if constexpr (std::is_same_v<STAmount, T>)
|
||||
return a;
|
||||
else
|
||||
|
||||
@@ -2,37 +2,20 @@
|
||||
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/protocol/Concepts.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class Asset;
|
||||
class STAmount;
|
||||
|
||||
template <typename T>
|
||||
requires(
|
||||
std::is_same_v<T, XRPAmount> || std::is_same_v<T, IOUAmount> ||
|
||||
std::is_same_v<T, MPTAmount>)
|
||||
struct AmountType
|
||||
{
|
||||
using amount_type = T;
|
||||
};
|
||||
template <typename TIss>
|
||||
concept ValidIssueType = std::is_same_v<TIss, Issue> || std::is_same_v<TIss, MPTIssue>;
|
||||
|
||||
/* Used to check for an asset with either badCurrency()
|
||||
* or MPT with 0 account.
|
||||
*/
|
||||
struct BadAsset
|
||||
{
|
||||
};
|
||||
|
||||
inline BadAsset const&
|
||||
badAsset()
|
||||
{
|
||||
static BadAsset const a;
|
||||
return a;
|
||||
}
|
||||
template <typename A>
|
||||
concept AssetType = std::is_convertible_v<A, Asset> || std::is_convertible_v<A, Issue> ||
|
||||
std::is_convertible_v<A, MPTIssue> || std::is_convertible_v<A, MPTID>;
|
||||
|
||||
/* Asset is an abstraction of three different issue types: XRP, IOU, MPT.
|
||||
* For historical reasons, two issue types XRP and IOU are wrapped in Issue
|
||||
@@ -43,9 +26,6 @@ class Asset
|
||||
{
|
||||
public:
|
||||
using value_type = std::variant<Issue, MPTIssue>;
|
||||
using token_type = std::variant<Currency, MPTID>;
|
||||
using AmtType =
|
||||
std::variant<AmountType<XRPAmount>, AmountType<IOUAmount>, AmountType<MPTAmount>>;
|
||||
|
||||
private:
|
||||
value_type issue_;
|
||||
@@ -89,42 +69,36 @@ public:
|
||||
constexpr value_type const&
|
||||
value() const;
|
||||
|
||||
constexpr token_type
|
||||
token() const;
|
||||
|
||||
void
|
||||
setJson(Json::Value& jv) const;
|
||||
|
||||
STAmount
|
||||
operator()(Number const&) const;
|
||||
|
||||
constexpr AmtType
|
||||
getAmountType() const;
|
||||
|
||||
// Custom, generic visit implementation
|
||||
template <typename... Visitors>
|
||||
constexpr auto
|
||||
visit(Visitors&&... visitors) const -> decltype(auto)
|
||||
{
|
||||
// Simple delegation to the reusable utility, passing the internal
|
||||
// variant data.
|
||||
return detail::visit(issue_, std::forward<Visitors>(visitors)...);
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
bool
|
||||
native() const
|
||||
{
|
||||
return visit(
|
||||
[&](Issue const& issue) { return issue.native(); },
|
||||
[&](MPTIssue const&) { return false; });
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
return issue.native();
|
||||
if constexpr (std::is_same_v<TIss, MPTIssue>)
|
||||
return false;
|
||||
},
|
||||
issue_);
|
||||
}
|
||||
|
||||
bool
|
||||
integral() const
|
||||
{
|
||||
return visit(
|
||||
[&](Issue const& issue) { return issue.native(); },
|
||||
[&](MPTIssue const&) { return true; });
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
return issue.native();
|
||||
if constexpr (std::is_same_v<TIss, MPTIssue>)
|
||||
return true;
|
||||
},
|
||||
issue_);
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
@@ -136,10 +110,6 @@ public:
|
||||
friend constexpr bool
|
||||
operator==(Currency const& lhs, Asset const& rhs);
|
||||
|
||||
// rhs is either badCurrency() or MPT issuer is 0
|
||||
friend constexpr bool
|
||||
operator==(BadAsset const& lhs, Asset const& rhs);
|
||||
|
||||
/** Return true if both assets refer to the same currency (regardless of
|
||||
* issuer) or MPT issuance. Otherwise return false.
|
||||
*/
|
||||
@@ -147,12 +117,6 @@ public:
|
||||
equalTokens(Asset const& lhs, Asset const& rhs);
|
||||
};
|
||||
|
||||
template <ValidIssueType TIss>
|
||||
constexpr bool is_issue_v = std::is_same_v<TIss, Issue>;
|
||||
|
||||
template <ValidIssueType TIss>
|
||||
constexpr bool is_mptissue_v = std::is_same_v<TIss, MPTIssue>;
|
||||
|
||||
inline Json::Value
|
||||
to_json(Asset const& asset)
|
||||
{
|
||||
@@ -192,29 +156,6 @@ Asset::value() const
|
||||
return issue_;
|
||||
}
|
||||
|
||||
constexpr Asset::token_type
|
||||
Asset::token() const
|
||||
{
|
||||
return visit(
|
||||
[&](Issue const& issue) -> Asset::token_type { return issue.currency; },
|
||||
[&](MPTIssue const& issue) -> Asset::token_type { return issue.getMptID(); });
|
||||
}
|
||||
|
||||
constexpr Asset::AmtType
|
||||
Asset::getAmountType() const
|
||||
{
|
||||
return visit(
|
||||
[&](Issue const& issue) -> Asset::AmtType {
|
||||
constexpr AmountType<XRPAmount> xrp;
|
||||
constexpr AmountType<IOUAmount> iou;
|
||||
return native() ? AmtType(xrp) : AmtType(iou);
|
||||
},
|
||||
[&](MPTIssue const& issue) -> Asset::AmtType {
|
||||
constexpr AmountType<MPTAmount> mpt;
|
||||
return AmtType(mpt);
|
||||
});
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
operator==(Asset const& lhs, Asset const& rhs)
|
||||
{
|
||||
@@ -236,7 +177,7 @@ operator<=>(Asset const& lhs, Asset const& rhs)
|
||||
[]<ValidIssueType TLhs, ValidIssueType TRhs>(TLhs const& lhs_, TRhs const& rhs_) {
|
||||
if constexpr (std::is_same_v<TLhs, TRhs>)
|
||||
return std::weak_ordering(lhs_ <=> rhs_);
|
||||
else if constexpr (is_issue_v<TLhs> && is_mptissue_v<TRhs>)
|
||||
else if constexpr (std::is_same_v<TLhs, Issue> && std::is_same_v<TRhs, MPTIssue>)
|
||||
return std::weak_ordering::greater;
|
||||
else
|
||||
return std::weak_ordering::less;
|
||||
@@ -248,17 +189,7 @@ operator<=>(Asset const& lhs, Asset const& rhs)
|
||||
constexpr bool
|
||||
operator==(Currency const& lhs, Asset const& rhs)
|
||||
{
|
||||
return rhs.visit(
|
||||
[&](Issue const& issue) { return issue.currency == lhs; },
|
||||
[](MPTIssue const& issue) { return false; });
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
operator==(BadAsset const&, Asset const& rhs)
|
||||
{
|
||||
return rhs.visit(
|
||||
[](Issue const& issue) -> bool { return badCurrency() == issue.currency; },
|
||||
[](MPTIssue const& issue) -> bool { return issue.getIssuer() == xrpAccount(); });
|
||||
return rhs.holds<Issue>() && rhs.get<Issue>().currency == lhs;
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
@@ -292,36 +223,4 @@ validJSONAsset(Json::Value const& jv);
|
||||
Asset
|
||||
assetFromJson(Json::Value const& jv);
|
||||
|
||||
Json::Value
|
||||
to_json(Asset const& asset);
|
||||
|
||||
inline bool
|
||||
isConsistent(Asset const& asset)
|
||||
{
|
||||
return asset.visit(
|
||||
[](Issue const& issue) { return isConsistent(issue); },
|
||||
[](MPTIssue const&) { return true; });
|
||||
}
|
||||
|
||||
inline bool
|
||||
validAsset(Asset const& asset)
|
||||
{
|
||||
return asset.visit(
|
||||
[](Issue const& issue) { return isConsistent(issue) && issue.currency != badCurrency(); },
|
||||
[](MPTIssue const& issue) { return issue.getIssuer() != xrpAccount(); });
|
||||
}
|
||||
|
||||
template <class Hasher>
|
||||
void
|
||||
hash_append(Hasher& h, Asset const& r)
|
||||
{
|
||||
using beast::hash_append;
|
||||
r.visit(
|
||||
[&](Issue const& issue) { hash_append(h, issue); },
|
||||
[&](MPTIssue const& issue) { hash_append(h, issue); });
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, Asset const& x);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/STVector256.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
|
||||
@@ -15,15 +15,15 @@ namespace xrpl {
|
||||
class Book final : public CountedObject<Book>
|
||||
{
|
||||
public:
|
||||
Asset in;
|
||||
Asset out;
|
||||
Issue in;
|
||||
Issue out;
|
||||
std::optional<uint256> domain;
|
||||
|
||||
Book()
|
||||
{
|
||||
}
|
||||
|
||||
Book(Asset const& in_, Asset const& out_, std::optional<uint256> const& domain_)
|
||||
Book(Issue const& in_, Issue const& out_, std::optional<uint256> const& domain_)
|
||||
: in(in_), out(out_), domain(domain_)
|
||||
{
|
||||
}
|
||||
@@ -112,67 +112,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<xrpl::MPTIssue> : private boost::base_from_member<std::hash<xrpl::MPTID>, 0>
|
||||
{
|
||||
private:
|
||||
using id_hash_type = boost::base_from_member<std::hash<xrpl::MPTID>, 0>;
|
||||
|
||||
public:
|
||||
explicit hash() = default;
|
||||
|
||||
using value_type = std::size_t;
|
||||
using argument_type = xrpl::MPTIssue;
|
||||
|
||||
value_type
|
||||
operator()(argument_type const& value) const
|
||||
{
|
||||
value_type const result(id_hash_type::member(value.getMptID()));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<xrpl::Asset>
|
||||
{
|
||||
private:
|
||||
using value_type = std::size_t;
|
||||
using argument_type = xrpl::Asset;
|
||||
|
||||
using issue_hasher = std::hash<xrpl::Issue>;
|
||||
using mptissue_hasher = std::hash<xrpl::MPTIssue>;
|
||||
|
||||
issue_hasher m_issue_hasher;
|
||||
mptissue_hasher m_mptissue_hasher;
|
||||
|
||||
public:
|
||||
explicit hash() = default;
|
||||
|
||||
value_type
|
||||
operator()(argument_type const& asset) const
|
||||
{
|
||||
return asset.visit(
|
||||
[&](xrpl::Issue const& issue) {
|
||||
value_type const result(m_issue_hasher(issue));
|
||||
return result;
|
||||
},
|
||||
[&](xrpl::MPTIssue const& issue) {
|
||||
value_type const result(m_mptissue_hasher(issue));
|
||||
return result;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <>
|
||||
struct hash<xrpl::Book>
|
||||
{
|
||||
private:
|
||||
using asset_hasher = std::hash<xrpl::Asset>;
|
||||
using issue_hasher = std::hash<xrpl::Issue>;
|
||||
using uint256_hasher = xrpl::uint256::hasher;
|
||||
|
||||
asset_hasher m_asset_hasher;
|
||||
issue_hasher m_issue_hasher;
|
||||
uint256_hasher m_uint256_hasher;
|
||||
|
||||
public:
|
||||
@@ -184,8 +133,8 @@ public:
|
||||
value_type
|
||||
operator()(argument_type const& value) const
|
||||
{
|
||||
value_type result(m_asset_hasher(value.in));
|
||||
boost::hash_combine(result, m_asset_hasher(value.out));
|
||||
value_type result(m_issue_hasher(value.in));
|
||||
boost::hash_combine(result, m_issue_hasher(value.out));
|
||||
|
||||
if (value.domain)
|
||||
boost::hash_combine(result, m_uint256_hasher(*value.domain));
|
||||
@@ -210,22 +159,6 @@ struct hash<xrpl::Issue> : std::hash<xrpl::Issue>
|
||||
// using Base::Base; // inherit ctors
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<xrpl::MPTIssue> : std::hash<xrpl::MPTIssue>
|
||||
{
|
||||
explicit hash() = default;
|
||||
|
||||
using Base = std::hash<xrpl::MPTIssue>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<xrpl::Asset> : std::hash<xrpl::Asset>
|
||||
{
|
||||
explicit hash() = default;
|
||||
|
||||
using Base = std::hash<xrpl::Asset>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<xrpl::Book> : std::hash<xrpl::Book>
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@ getFullVersionString();
|
||||
X: 16 bits identifying the particular implementation
|
||||
Y: 48 bits of data specific to the implementation
|
||||
|
||||
The xrpld-specific format (implementation ID is: 0x18 0x3B) is:
|
||||
The rippled-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 an xrpld software version.
|
||||
/** Check if the encoded software version is a rippled software version.
|
||||
|
||||
@param version another node's encoded software version
|
||||
@return true if the version is an xrpld software version, false otherwise
|
||||
@return true if the version is a rippled software version, false otherwise
|
||||
*/
|
||||
bool
|
||||
isXrpldVersion(std::uint64_t version);
|
||||
isRippledVersion(std::uint64_t version);
|
||||
|
||||
/** Check if the version is newer than the local node's xrpld software
|
||||
/** Check if the version is newer than the local node's rippled software
|
||||
version.
|
||||
|
||||
@param version another node's encoded software version
|
||||
@return true if the version is newer than the local node's xrpld software
|
||||
@return true if the version is newer than the local node's rippled software
|
||||
version, false otherwise.
|
||||
|
||||
@note This function only understands version numbers that are generated by
|
||||
xrpld. Please see the encodeSoftwareVersion() function for detail.
|
||||
rippled. Please see the encodeSoftwareVersion() function for detail.
|
||||
*/
|
||||
bool
|
||||
isNewerVersion(std::uint64_t version);
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class STAmount;
|
||||
class Asset;
|
||||
class Issue;
|
||||
class MPTIssue;
|
||||
class IOUAmount;
|
||||
class XRPAmount;
|
||||
class MPTAmount;
|
||||
|
||||
template <typename A>
|
||||
concept StepAmount =
|
||||
std::is_same_v<A, XRPAmount> || std::is_same_v<A, IOUAmount> || std::is_same_v<A, MPTAmount>;
|
||||
|
||||
template <typename TIss>
|
||||
concept ValidIssueType = std::is_same_v<TIss, Issue> || std::is_same_v<TIss, MPTIssue>;
|
||||
|
||||
template <typename A>
|
||||
concept AssetType = std::is_convertible_v<A, Asset> || std::is_convertible_v<A, Issue> ||
|
||||
std::is_convertible_v<A, MPTIssue> || std::is_convertible_v<A, MPTID>;
|
||||
|
||||
template <typename T>
|
||||
concept ValidPathAsset = (std::is_same_v<T, Currency> || std::is_same_v<T, MPTID>);
|
||||
|
||||
template <class TTakerPays, class TTakerGets>
|
||||
concept ValidTaker =
|
||||
((std::is_same_v<TTakerPays, IOUAmount> || std::is_same_v<TTakerPays, XRPAmount> ||
|
||||
std::is_same_v<TTakerPays, MPTAmount>) &&
|
||||
(std::is_same_v<TTakerGets, IOUAmount> || std::is_same_v<TTakerGets, XRPAmount> ||
|
||||
std::is_same_v<TTakerGets, MPTAmount>) &&
|
||||
(!std::is_same_v<TTakerPays, XRPAmount> || !std::is_same_v<TTakerGets, XRPAmount>));
|
||||
|
||||
namespace detail {
|
||||
|
||||
// This template combines multiple callable objects (lambdas) into a single
|
||||
// object that std::visit can use for overload resolution.
|
||||
template <typename... Ts>
|
||||
struct CombineVisitors : Ts...
|
||||
{
|
||||
// Bring all operator() overloads from base classes into this scope.
|
||||
// It's the mechanism that makes the CombineVisitors struct function
|
||||
// as a single callable object with multiple overloads.
|
||||
using Ts::operator()...;
|
||||
|
||||
// Perfect forwarding constructor to correctly initialize the base class
|
||||
// lambdas
|
||||
constexpr CombineVisitors(Ts&&... ts) : Ts(std::forward<Ts>(ts))...
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// This function forces function template argument deduction, which is more
|
||||
// robust than class template argument deduction (CTAD) via the deduction guide.
|
||||
template <typename... Ts>
|
||||
constexpr CombineVisitors<std::decay_t<Ts>...>
|
||||
make_combine_visitors(Ts&&... ts)
|
||||
{
|
||||
// std::decay_t<Ts> is used to remove references/constness from the lambda
|
||||
// types before they are passed as template arguments to the CombineVisitors
|
||||
// struct.
|
||||
return CombineVisitors<std::decay_t<Ts>...>{std::forward<Ts>(ts)...};
|
||||
}
|
||||
|
||||
// This function takes ANY variant and ANY number of visitors, and performs the
|
||||
// visit. It is the reusable core logic.
|
||||
template <typename Variant, typename... Visitors>
|
||||
constexpr auto
|
||||
visit(Variant&& v, Visitors&&... visitors) -> decltype(auto)
|
||||
{
|
||||
// Use the function template helper instead of raw CTAD.
|
||||
auto visitor_set = make_combine_visitors(std::forward<Visitors>(visitors)...);
|
||||
|
||||
// Delegate to std::visit, perfectly forwarding the variant and the visitor
|
||||
// set.
|
||||
return std::visit(visitor_set, std::forward<Variant>(v));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace xrpl
|
||||
460
include/xrpl/protocol/ConfidentialTransfer.h
Normal file
460
include/xrpl/protocol/ConfidentialTransfer.h
Normal file
@@ -0,0 +1,460 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/Rate.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
#include <xrpl/protocol/detail/secp256k1.h>
|
||||
|
||||
#include <secp256k1_mpt.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* @brief Bundles an ElGamal public key with its associated encrypted amount.
|
||||
*
|
||||
* Used to represent a recipient in confidential transfers, containing both
|
||||
* the recipient's ElGamal public key and the ciphertext encrypting the
|
||||
* transfer amount under that key.
|
||||
*/
|
||||
struct ConfidentialRecipient
|
||||
{
|
||||
Slice publicKey; ///< The recipient's ElGamal public key (size=xrpl::ecPubKeyLength).
|
||||
Slice encryptedAmount; ///< The encrypted amount ciphertext
|
||||
///< (size=xrpl::ecGamalEncryptedTotalLength).
|
||||
};
|
||||
|
||||
/// Holds two secp256k1 public key components representing an ElGamal ciphertext (C1, C2).
|
||||
struct EcPair
|
||||
{
|
||||
secp256k1_pubkey c1;
|
||||
secp256k1_pubkey c2;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Increments the confidential balance version counter on an MPToken.
|
||||
*
|
||||
* The version counter is used to prevent replay attacks by binding proofs
|
||||
* to a specific state of the account's confidential balance. Wraps to 0
|
||||
* on overflow (defined behavior for unsigned integers).
|
||||
*
|
||||
* @param mptoken The MPToken ledger entry to update.
|
||||
*/
|
||||
inline void
|
||||
incrementConfidentialVersion(STObject& mptoken)
|
||||
{
|
||||
// Retrieve current version and increment.
|
||||
// Unsigned integer overflow is defined behavior in C++ (wraps to 0),
|
||||
// which is acceptable here.
|
||||
mptoken[sfConfidentialBalanceVersion] =
|
||||
mptoken[~sfConfidentialBalanceVersion].value_or(0u) + 1u;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generates the context hash for ConfidentialMPTSend transactions.
|
||||
*
|
||||
* Creates a unique 256-bit hash that binds the zero-knowledge proofs to
|
||||
* this specific send transaction, preventing proof reuse across transactions.
|
||||
*
|
||||
* @param account The sender's account ID.
|
||||
* @param issuanceID The MPToken Issuance ID.
|
||||
* @param sequence The transaction sequence number or ticket number.
|
||||
* @param destination The destination account ID.
|
||||
* @param version The sender's confidential balance version.
|
||||
* @return A 256-bit context hash unique to this transaction.
|
||||
*/
|
||||
uint256
|
||||
getSendContextHash(
|
||||
AccountID const& account,
|
||||
uint192 const& issuanceID,
|
||||
std::uint32_t sequence,
|
||||
AccountID const& destination,
|
||||
std::uint32_t version);
|
||||
|
||||
/**
|
||||
* @brief Generates the context hash for ConfidentialMPTClawback transactions.
|
||||
*
|
||||
* Creates a unique 256-bit hash that binds the equality proof to this
|
||||
* specific clawback transaction.
|
||||
*
|
||||
* @param account The issuer's account ID.
|
||||
* @param issuanceID The MPToken Issuance ID.
|
||||
* @param sequence The transaction sequence number or ticket number.
|
||||
* @param holder The holder's account ID being clawed back from.
|
||||
* @return A 256-bit context hash unique to this transaction.
|
||||
*/
|
||||
uint256
|
||||
getClawbackContextHash(
|
||||
AccountID const& account,
|
||||
uint192 const& issuanceID,
|
||||
std::uint32_t sequence,
|
||||
AccountID const& holder);
|
||||
|
||||
/**
|
||||
* @brief Generates the context hash for ConfidentialMPTConvert transactions.
|
||||
*
|
||||
* Creates a unique 256-bit hash that binds the Schnorr proof (for key
|
||||
* registration) to this specific convert transaction.
|
||||
*
|
||||
* @param account The holder's account ID.
|
||||
* @param issuanceID The MPToken Issuance ID.
|
||||
* @param sequence The transaction sequence number or a ticket number.
|
||||
* @return A 256-bit context hash unique to this transaction.
|
||||
*/
|
||||
uint256
|
||||
getConvertContextHash(AccountID const& account, uint192 const& issuanceID, std::uint32_t sequence);
|
||||
|
||||
/**
|
||||
* @brief Generates the context hash for ConfidentialMPTConvertBack transactions.
|
||||
*
|
||||
* Creates a unique 256-bit hash that binds the zero-knowledge proofs to
|
||||
* this specific convert-back transaction.
|
||||
*
|
||||
* @param account The holder's account ID.
|
||||
* @param issuanceID The MPToken Issuance ID.
|
||||
* @param sequence The transaction sequence number or a ticket number.
|
||||
* @param version The holder's confidential balance version.
|
||||
* @return A 256-bit context hash unique to this transaction.
|
||||
*/
|
||||
uint256
|
||||
getConvertBackContextHash(
|
||||
AccountID const& account,
|
||||
uint192 const& issuanceID,
|
||||
std::uint32_t sequence,
|
||||
std::uint32_t version);
|
||||
|
||||
/**
|
||||
* @brief Parses an ElGamal ciphertext into two secp256k1 public key components.
|
||||
*
|
||||
* Breaks a 66-byte encrypted amount (two 33-byte compressed EC points) into
|
||||
* a pair containing (C1, C2) for use in cryptographic operations.
|
||||
*
|
||||
* @param buffer The 66-byte buffer containing the compressed ciphertext.
|
||||
* @return The parsed pair (c1, c2) if successful, std::nullopt if the buffer is invalid.
|
||||
*/
|
||||
std::optional<EcPair>
|
||||
makeEcPair(Slice const& buffer);
|
||||
|
||||
/**
|
||||
* @brief Serializes an EcPair into compressed form.
|
||||
*
|
||||
* Converts an EcPair (C1, C2) back into a 66-byte buffer containing
|
||||
* two 33-byte compressed EC points.
|
||||
*
|
||||
* @param pair The EcPair to serialize.
|
||||
* @return The 66-byte buffer, or std::nullopt if serialization fails.
|
||||
*/
|
||||
std::optional<Buffer>
|
||||
serializeEcPair(EcPair const& pair);
|
||||
|
||||
/**
|
||||
* @brief Verifies that a buffer contains two valid, parsable EC public keys.
|
||||
*
|
||||
* @param buffer The input buffer containing two concatenated components.
|
||||
* @return true if both components can be parsed successfully, false otherwise.
|
||||
*/
|
||||
bool
|
||||
isValidCiphertext(Slice const& buffer);
|
||||
|
||||
/**
|
||||
* @brief Verifies that a buffer contains a valid, parsable compressed EC point.
|
||||
*
|
||||
* Can be used to validate both compressed public keys and Pedersen commitments.
|
||||
* Fails early if the prefix byte is not 0x02 or 0x03.
|
||||
*
|
||||
* @param buffer The input buffer containing a compressed EC point (33 bytes).
|
||||
* @return true if the point can be parsed successfully, false otherwise.
|
||||
*/
|
||||
bool
|
||||
isValidCompressedECPoint(Slice const& buffer);
|
||||
|
||||
/**
|
||||
* @brief Homomorphically adds two ElGamal ciphertexts.
|
||||
*
|
||||
* Uses the additive homomorphic property of ElGamal encryption to compute
|
||||
* Enc(a + b) from Enc(a) and Enc(b) without decryption.
|
||||
*
|
||||
* @param a The first ciphertext (66 bytes).
|
||||
* @param b The second ciphertext (66 bytes).
|
||||
* @return The resulting ciphertext Enc(a + b), or std::nullopt on failure.
|
||||
*/
|
||||
std::optional<Buffer>
|
||||
homomorphicAdd(Slice const& a, Slice const& b);
|
||||
|
||||
/**
|
||||
* @brief Homomorphically subtracts two ElGamal ciphertexts.
|
||||
*
|
||||
* Uses the additive homomorphic property of ElGamal encryption to compute
|
||||
* Enc(a - b) from Enc(a) and Enc(b) without decryption.
|
||||
*
|
||||
* @param a The minuend ciphertext (66 bytes).
|
||||
* @param b The subtrahend ciphertext (66 bytes).
|
||||
* @return The resulting ciphertext Enc(a - b), or std::nullopt on failure.
|
||||
*/
|
||||
std::optional<Buffer>
|
||||
homomorphicSubtract(Slice const& a, Slice const& b);
|
||||
|
||||
/**
|
||||
* @brief Encrypts an amount using ElGamal encryption.
|
||||
*
|
||||
* Produces a ciphertext C = (C1, C2) where C1 = r*G and C2 = m*G + r*Pk,
|
||||
* using the provided blinding factor r.
|
||||
*
|
||||
* @param amt The plaintext amount to encrypt.
|
||||
* @param pubKeySlice The recipient's ElGamal public key (size=xrpl::ecPubKeyLength).
|
||||
* @param blindingFactor The randomness used as blinding factor r
|
||||
* (size=xrpl::ecBlindingFactorLength).
|
||||
* @return The ciphertext (size=xrpl::ecGamalEncryptedTotalLength), or std::nullopt on failure.
|
||||
*/
|
||||
std::optional<Buffer>
|
||||
encryptAmount(uint64_t const amt, Slice const& pubKeySlice, Slice const& blindingFactor);
|
||||
|
||||
/**
|
||||
* @brief Generates the canonical zero encryption for a specific MPToken.
|
||||
*
|
||||
* Creates a deterministic encryption of zero that is unique to the account
|
||||
* and MPT issuance. Used to initialize confidential balance fields.
|
||||
*
|
||||
* @param pubKeySlice The holder's ElGamal public key (size=xrpl::ecPubKeyLength).
|
||||
* @param account The account ID of the token holder.
|
||||
* @param mptId The MPToken Issuance ID.
|
||||
* @return The canonical zero ciphertext (size=xrpl::ecGamalEncryptedTotalLength), or std::nullopt
|
||||
* on failure.
|
||||
*/
|
||||
std::optional<Buffer>
|
||||
encryptCanonicalZeroAmount(Slice const& pubKeySlice, AccountID const& account, MPTID const& mptId);
|
||||
|
||||
/**
|
||||
* @brief Verifies a Schnorr proof of knowledge of an ElGamal private key.
|
||||
*
|
||||
* Proves that the submitter knows the secret key corresponding to the
|
||||
* provided public key, without revealing the secret key itself.
|
||||
*
|
||||
* @param pubKeySlice The ElGamal public key (size=xrpl::ecPubKeyLength).
|
||||
* @param proofSlice The Schnorr proof (size=xrpl::ecSchnorrProofLength).
|
||||
* @param contextHash The 256-bit context hash binding the proof.
|
||||
* @return tesSUCCESS if valid, or an error code otherwise.
|
||||
*/
|
||||
TER
|
||||
verifySchnorrProof(Slice const& pubKeySlice, Slice const& proofSlice, uint256 const& contextHash);
|
||||
|
||||
/**
|
||||
* @brief Validates the format of encrypted amount fields in a transaction.
|
||||
*
|
||||
* Checks that all ciphertext fields in the transaction object have the
|
||||
* correct length and contain valid EC points. This function is only used
|
||||
* by ConfidentialMPTConvert and ConfidentialMPTConvertBack transactions.
|
||||
*
|
||||
* @param object The transaction object containing encrypted amount fields.
|
||||
* @return tesSUCCESS if all formats are valid, temMALFORMED if required fields
|
||||
* are missing, or temBAD_CIPHERTEXT if format validation fails.
|
||||
*/
|
||||
NotTEC
|
||||
checkEncryptedAmountFormat(STObject const& object);
|
||||
|
||||
/**
|
||||
* @brief Verifies revealed amount encryptions for all recipients.
|
||||
*
|
||||
* Validates that the same amount was correctly encrypted for the holder,
|
||||
* issuer, and optionally the auditor using their respective public keys.
|
||||
*
|
||||
* @param amount The revealed plaintext amount.
|
||||
* @param blindingFactor The blinding factor used in all encryptions
|
||||
* (size=xrpl::ecBlindingFactorLength).
|
||||
* @param holder The holder's public key and encrypted amount.
|
||||
* @param issuer The issuer's public key and encrypted amount.
|
||||
* @param auditor Optional auditor's public key and encrypted amount.
|
||||
* @return tesSUCCESS if all encryptions are valid, or an error code otherwise.
|
||||
*/
|
||||
TER
|
||||
verifyRevealedAmount(
|
||||
uint64_t const amount,
|
||||
Slice const& blindingFactor,
|
||||
ConfidentialRecipient const& holder,
|
||||
ConfidentialRecipient const& issuer,
|
||||
std::optional<ConfidentialRecipient> const& auditor);
|
||||
|
||||
/**
|
||||
* @brief Returns the number of recipients in a confidential transfer.
|
||||
*
|
||||
* Returns 4 if an auditor is present (sender, destination, issuer, auditor),
|
||||
* or 3 if no auditor (sender, destination, issuer).
|
||||
*
|
||||
* @param hasAuditor Whether the issuance has an auditor configured.
|
||||
* @return The number of recipients (3 or 4).
|
||||
*/
|
||||
constexpr std::size_t
|
||||
getConfidentialRecipientCount(bool hasAuditor)
|
||||
{
|
||||
return hasAuditor ? 4 : 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the size of a multi-ciphertext equality proof.
|
||||
*
|
||||
* Computes the byte size required for a zero-knowledge proof that demonstrates
|
||||
* multiple ciphertexts encrypt the same plaintext value. The size depends on
|
||||
* the number of recipients.
|
||||
*
|
||||
* @param nRecipients The number of recipients (typically 3 or 4).
|
||||
* @return The proof size in bytes.
|
||||
*/
|
||||
inline std::size_t
|
||||
getEqualityProofSize(std::size_t nRecipients)
|
||||
{
|
||||
return secp256k1_mpt_proof_equality_shared_r_size(nRecipients);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Verifies a clawback equality proof.
|
||||
*
|
||||
* Proves that the issuer knows the exact amount encrypted in the holder's
|
||||
* balance ciphertext. Used in ConfidentialMPTClawback to verify the issuer
|
||||
* can decrypt the balance using their private key.
|
||||
*
|
||||
* @param amount The revealed plaintext amount.
|
||||
* @param proof The zero-knowledge proof bytes.
|
||||
* @param pubKeySlice The issuer's ElGamal public key (64 bytes).
|
||||
* @param ciphertext The issuer's encrypted balance on the holder's account (66 bytes).
|
||||
* @param contextHash The 256-bit context hash binding the proof.
|
||||
* @return tesSUCCESS if the proof is valid, or an error code otherwise.
|
||||
*/
|
||||
TER
|
||||
verifyClawbackEqualityProof(
|
||||
uint64_t const amount,
|
||||
Slice const& proof,
|
||||
Slice const& pubKeySlice,
|
||||
Slice const& ciphertext,
|
||||
uint256 const& contextHash);
|
||||
|
||||
/**
|
||||
* @brief Generates a cryptographically secure 32-byte blinding factor.
|
||||
*
|
||||
* Produces random bytes suitable for use as an ElGamal blinding factor
|
||||
* or Pedersen commitment randomness.
|
||||
*
|
||||
* @return A 32-byte buffer containing the random blinding factor.
|
||||
*/
|
||||
Buffer
|
||||
generateBlindingFactor();
|
||||
|
||||
/**
|
||||
* @brief Verifies all zero-knowledge proofs for a ConfidentialMPTSend transaction.
|
||||
*
|
||||
* This function calls mpt_verify_send_proof API in the mpt-crypto utility lib, which verifies the
|
||||
* equality proof, amount linkage, balance linkage, and range proof.
|
||||
* Equality proof: Proves the same value is encrypted for the sender, receiver, issuer, and auditor.
|
||||
* Amount linkage: Proves the send amount matches the amount Pedersen commitment.
|
||||
* Balance linkage: Proves the sender's balance matches the balance Pedersen
|
||||
* commitment.
|
||||
* Range proof: Proves the amount and the remaining balance are within range [0, 2^64-1].
|
||||
*
|
||||
* @param proof The full proof blob.
|
||||
* @param sender The sender's public key and encrypted amount.
|
||||
* @param destination The destination's public key and encrypted amount.
|
||||
* @param issuer The issuer's public key and encrypted amount.
|
||||
* @param auditor The auditor's public key and encrypted amount if present.
|
||||
* @param spendingBalance The sender's current spending balance ciphertext.
|
||||
* @param amountCommitment The Pedersen commitment to the send amount.
|
||||
* @param balanceCommitment The Pedersen commitment to the sender's balance.
|
||||
* @param contextHash The context hash binding the proof.
|
||||
* @return tesSUCCESS if all proofs are valid, or an error code otherwise.
|
||||
*/
|
||||
TER
|
||||
verifySendProof(
|
||||
Slice const& proof,
|
||||
ConfidentialRecipient const& sender,
|
||||
ConfidentialRecipient const& destination,
|
||||
ConfidentialRecipient const& issuer,
|
||||
std::optional<ConfidentialRecipient> const& auditor,
|
||||
Slice const& spendingBalance,
|
||||
Slice const& amountCommitment,
|
||||
Slice const& balanceCommitment,
|
||||
uint256 const& contextHash);
|
||||
|
||||
/**
|
||||
* @brief Verifies all zero-knowledge proofs for a ConfidentialMPTConvertBack transaction.
|
||||
*
|
||||
* This function calls mpt_verify_convert_back_proof API in the mpt-crypto utility lib, which
|
||||
* verifies the balance linkage proof and range proof. Balance linkage proof: proves the balance
|
||||
* commitment matches the spending ciphertext. Range proof: proves the remaining balance after
|
||||
* convert back is within range [0, 2^64-1].
|
||||
*
|
||||
* @param proof The full proof blob.
|
||||
* @param pubKeySlice The holder's public key.
|
||||
* @param spendingBalance The holder's spending balance ciphertext.
|
||||
* @param balanceCommitment The Pedersen commitment to the balance.
|
||||
* @param amount The amount being converted back to public.
|
||||
* @param contextHash The context hash binding the proof.
|
||||
* @return tesSUCCESS if all proofs are valid, or an error code otherwise.
|
||||
*/
|
||||
TER
|
||||
verifyConvertBackProof(
|
||||
Slice const& proof,
|
||||
Slice const& pubKeySlice,
|
||||
Slice const& spendingBalance,
|
||||
Slice const& balanceCommitment,
|
||||
uint64_t amount,
|
||||
uint256 const& contextHash);
|
||||
|
||||
/**
|
||||
* @brief Sequential reader for extracting proof components from a ZKProof blob.
|
||||
*
|
||||
* Encapsulates the offset-based arithmetic for slicing a concatenated proof
|
||||
* blob into its individual components (equality proofs, Pedersen linkage
|
||||
* proofs, bulletproofs, etc.). Performs bounds checking on every read and
|
||||
* tracks whether the entire blob has been consumed.
|
||||
*
|
||||
* Usage:
|
||||
* @code
|
||||
* ProofReader reader(tx[sfZKProof]);
|
||||
* auto equalityProof = reader.read(sizeEquality);
|
||||
* auto pedersenProof = reader.read(ecPedersenProofLength);
|
||||
* if (!equalityProof || !pedersenProof || !reader.done())
|
||||
* return tecINTERNAL;
|
||||
* @endcode
|
||||
*/
|
||||
class ProofReader
|
||||
{
|
||||
Slice data_;
|
||||
std::size_t offset_ = 0;
|
||||
|
||||
public:
|
||||
explicit ProofReader(Slice data) : data_(data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the next @p length bytes from the proof blob.
|
||||
*
|
||||
* @param length Number of bytes to read.
|
||||
* @return A Slice of the requested bytes, or std::nullopt if there are
|
||||
* not enough remaining bytes.
|
||||
*/
|
||||
[[nodiscard]] std::optional<Slice>
|
||||
read(std::size_t length)
|
||||
{
|
||||
if (offset_ + length > data_.size())
|
||||
return std::nullopt;
|
||||
auto result = data_.substr(offset_, length);
|
||||
offset_ += length;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true when every byte has been consumed.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
done() const
|
||||
{
|
||||
return offset_ == data_.size();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -153,7 +153,7 @@ enum warning_code_i {
|
||||
warnRPC_AMENDMENT_BLOCKED = 1002,
|
||||
warnRPC_EXPIRED_VALIDATOR_LIST = 1003,
|
||||
// unused = 1004
|
||||
warnRPC_FIELDS_DEPRECATED = 2004, // xrpld needs to maintain
|
||||
warnRPC_FIELDS_DEPRECATED = 2004, // rippled 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 `xrpld` to become amendment blocked.
|
||||
* versions of `rippled` 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 `xrpld` built with that setting, but will still
|
||||
* by any versions of `rippled` 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
|
||||
|
||||
@@ -8,9 +8,6 @@ namespace xrpl {
|
||||
// This was the reference fee units used in the old fee calculation.
|
||||
inline constexpr std::uint32_t FEE_UNITS_DEPRECATED = 10;
|
||||
|
||||
// Number of micro-drops in one drop.
|
||||
constexpr std::uint32_t MICRO_DROPS_PER_DROP{1'000'000};
|
||||
|
||||
/** Reflects the fee settings for a particular ledger.
|
||||
|
||||
The fees are always the same for any transactions applied
|
||||
@@ -27,15 +24,6 @@ struct Fees
|
||||
/** @brief Additional XRP reserve required per owned ledger object. */
|
||||
XRPAmount increment{0};
|
||||
|
||||
/** @brief Compute limit for Feature Extensions (instructions). */
|
||||
std::uint32_t extensionComputeLimit{0};
|
||||
|
||||
/** @brief Size limit for Feature Extensions (bytes). */
|
||||
std::uint32_t extensionSizeLimit{0};
|
||||
|
||||
/** @brief Price of WASM gas (micro-drops). */
|
||||
std::uint32_t gasPrice{0};
|
||||
|
||||
explicit Fees() = default;
|
||||
Fees(Fees const&) = default;
|
||||
Fees&
|
||||
|
||||
@@ -207,12 +207,6 @@ page(Keylet const& root, std::uint64_t index = 0) noexcept
|
||||
Keylet
|
||||
escrow(AccountID const& src, std::uint32_t seq) noexcept;
|
||||
|
||||
inline Keylet
|
||||
escrow(uint256 const& key) noexcept
|
||||
{
|
||||
return {ltESCROW, key};
|
||||
}
|
||||
|
||||
/** A PaymentChannel */
|
||||
Keylet
|
||||
payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept;
|
||||
|
||||
@@ -173,7 +173,8 @@ enum LedgerEntryType : std::uint16_t {
|
||||
LSF_FLAG(lsfMPTCanEscrow, 0x00000008) \
|
||||
LSF_FLAG(lsfMPTCanTrade, 0x00000010) \
|
||||
LSF_FLAG(lsfMPTCanTransfer, 0x00000020) \
|
||||
LSF_FLAG(lsfMPTCanClawback, 0x00000040)) \
|
||||
LSF_FLAG(lsfMPTCanClawback, 0x00000040) \
|
||||
LSF_FLAG(lsfMPTCanConfidentialAmount, 0x00000080)) \
|
||||
\
|
||||
LEDGER_OBJECT(MPTokenIssuanceMutable, \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanLock, 0x00000002) \
|
||||
@@ -183,12 +184,12 @@ enum LedgerEntryType : std::uint16_t {
|
||||
LSF_FLAG(lsmfMPTCanMutateCanTransfer, 0x00000020) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanClawback, 0x00000040) \
|
||||
LSF_FLAG(lsmfMPTCanMutateMetadata, 0x00010000) \
|
||||
LSF_FLAG(lsmfMPTCanMutateTransferFee, 0x00020000)) \
|
||||
LSF_FLAG(lsmfMPTCanMutateTransferFee, 0x00020000) \
|
||||
LSF_FLAG(lsmfMPTCannotMutateCanConfidentialAmount, 0x00040000)) \
|
||||
\
|
||||
LEDGER_OBJECT(MPToken, \
|
||||
LSF_FLAG2(lsfMPTLocked, 0x00000001) \
|
||||
LSF_FLAG(lsfMPTAuthorized, 0x00000002) \
|
||||
LSF_FLAG(lsfMPTAMM, 0x00000004)) \
|
||||
LSF_FLAG(lsfMPTAuthorized, 0x00000002)) \
|
||||
\
|
||||
LEDGER_OBJECT(Credential, \
|
||||
LSF_FLAG(lsfAccepted, 0x00010000)) \
|
||||
|
||||
@@ -22,12 +22,11 @@ public:
|
||||
using value_type = std::int64_t;
|
||||
|
||||
protected:
|
||||
value_type value_{};
|
||||
value_type value_;
|
||||
|
||||
public:
|
||||
MPTAmount() = default;
|
||||
constexpr MPTAmount(MPTAmount const& other) = default;
|
||||
constexpr MPTAmount(beast::Zero);
|
||||
constexpr MPTAmount&
|
||||
operator=(MPTAmount const& other) = default;
|
||||
|
||||
@@ -86,11 +85,6 @@ constexpr MPTAmount::MPTAmount(value_type value) : value_(value)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr MPTAmount::MPTAmount(beast::Zero)
|
||||
{
|
||||
*this = beast::zero;
|
||||
}
|
||||
|
||||
constexpr MPTAmount&
|
||||
MPTAmount::operator=(beast::Zero)
|
||||
{
|
||||
@@ -122,14 +116,6 @@ MPTAmount::value() const
|
||||
return value_;
|
||||
}
|
||||
|
||||
// Output MPTAmount as just the value.
|
||||
template <class Char, class Traits>
|
||||
std::basic_ostream<Char, Traits>&
|
||||
operator<<(std::basic_ostream<Char, Traits>& os, MPTAmount const& q)
|
||||
{
|
||||
return os << q.value();
|
||||
}
|
||||
|
||||
inline std::string
|
||||
to_string(MPTAmount const& amount)
|
||||
{
|
||||
|
||||
@@ -17,14 +17,7 @@ private:
|
||||
public:
|
||||
MPTIssue() = default;
|
||||
|
||||
MPTIssue(MPTID const& issuanceID);
|
||||
|
||||
MPTIssue(std::uint32_t sequence, AccountID const& account);
|
||||
|
||||
operator MPTID const&() const
|
||||
{
|
||||
return mptID_;
|
||||
}
|
||||
explicit MPTIssue(MPTID const& issuanceID);
|
||||
|
||||
AccountID const&
|
||||
getIssuer() const;
|
||||
@@ -80,47 +73,6 @@ isXRP(MPTID const&)
|
||||
return false;
|
||||
}
|
||||
|
||||
inline AccountID
|
||||
getMPTIssuer(MPTID const& mptid)
|
||||
{
|
||||
static_assert(sizeof(MPTID) == (sizeof(std::uint32_t) + sizeof(AccountID)));
|
||||
// Extract the 20 bytes for the AccountID
|
||||
std::array<std::uint8_t, sizeof(AccountID)> bytes{};
|
||||
std::copy_n(mptid.data() + sizeof(std::uint32_t), sizeof(AccountID), bytes.begin());
|
||||
|
||||
// bit_cast is a "magic" compiler intrinsic that is
|
||||
// usually optimized away to nothing in the final assembly.
|
||||
return std::bit_cast<AccountID>(bytes);
|
||||
}
|
||||
|
||||
// Disallow temporary
|
||||
inline AccountID const&
|
||||
getMPTIssuer(MPTID const&&) = delete;
|
||||
inline AccountID const&
|
||||
getMPTIssuer(MPTID&&) = delete;
|
||||
|
||||
inline MPTID
|
||||
noMPT()
|
||||
{
|
||||
static MPTIssue const mpt{0, noAccount()};
|
||||
return mpt.getMptID();
|
||||
}
|
||||
|
||||
inline MPTID
|
||||
badMPT()
|
||||
{
|
||||
static MPTIssue const mpt{0, xrpAccount()};
|
||||
return mpt.getMptID();
|
||||
}
|
||||
|
||||
template <class Hasher>
|
||||
void
|
||||
hash_append(Hasher& h, MPTIssue const& r)
|
||||
{
|
||||
using beast::hash_append;
|
||||
hash_append(h, r.getMptID());
|
||||
}
|
||||
|
||||
Json::Value
|
||||
to_json(MPTIssue const& mptIssue);
|
||||
|
||||
@@ -130,17 +82,4 @@ to_string(MPTIssue const& mptIssue);
|
||||
MPTIssue
|
||||
mptIssueFromJson(Json::Value const& jv);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, MPTIssue const& x);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash<xrpl::MPTID> : xrpl::MPTID::hasher
|
||||
{
|
||||
explicit hash() = default;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Concepts.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/* Represent STPathElement's asset, which can be Currency or MPTID.
|
||||
*/
|
||||
class PathAsset
|
||||
{
|
||||
private:
|
||||
std::variant<Currency, MPTID> easset_;
|
||||
|
||||
public:
|
||||
PathAsset() = default;
|
||||
// Enables comparing Asset and PathAsset
|
||||
PathAsset(Asset const& asset);
|
||||
PathAsset(Currency const& currency) : easset_(currency)
|
||||
{
|
||||
}
|
||||
PathAsset(MPTID const& mpt) : easset_(mpt)
|
||||
{
|
||||
}
|
||||
|
||||
template <ValidPathAsset T>
|
||||
constexpr bool
|
||||
holds() const;
|
||||
|
||||
constexpr bool
|
||||
isXRP() const;
|
||||
|
||||
template <ValidPathAsset T>
|
||||
T const&
|
||||
get() const;
|
||||
|
||||
constexpr std::variant<Currency, MPTID> const&
|
||||
value() const;
|
||||
|
||||
// Custom, generic visit implementation
|
||||
template <typename... Visitors>
|
||||
constexpr auto
|
||||
visit(Visitors&&... visitors) const -> decltype(auto)
|
||||
{
|
||||
// Simple delegation to the reusable utility, passing the internal
|
||||
// variant data.
|
||||
return detail::visit(easset_, std::forward<Visitors>(visitors)...);
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator==(PathAsset const& lhs, PathAsset const& rhs);
|
||||
};
|
||||
|
||||
template <ValidPathAsset PA>
|
||||
constexpr bool is_currency_v = std::is_same_v<PA, Currency>;
|
||||
|
||||
template <ValidPathAsset PA>
|
||||
constexpr bool is_mptid_v = std::is_same_v<PA, MPTID>;
|
||||
|
||||
inline PathAsset::PathAsset(Asset const& asset)
|
||||
{
|
||||
asset.visit(
|
||||
[&](Issue const& issue) { easset_ = issue.currency; },
|
||||
[&](MPTIssue const& issue) { easset_ = issue.getMptID(); });
|
||||
}
|
||||
|
||||
template <ValidPathAsset T>
|
||||
constexpr bool
|
||||
PathAsset::holds() const
|
||||
{
|
||||
return std::holds_alternative<T>(easset_);
|
||||
}
|
||||
|
||||
template <ValidPathAsset T>
|
||||
T const&
|
||||
PathAsset::get() const
|
||||
{
|
||||
if (!holds<T>())
|
||||
Throw<std::runtime_error>("PathAsset doesn't hold requested asset.");
|
||||
return std::get<T>(easset_);
|
||||
}
|
||||
|
||||
constexpr std::variant<Currency, MPTID> const&
|
||||
PathAsset::value() const
|
||||
{
|
||||
return easset_;
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
PathAsset::isXRP() const
|
||||
{
|
||||
return visit(
|
||||
[&](Currency const& currency) { return xrpl::isXRP(currency); },
|
||||
[](MPTID const&) { return false; });
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
operator==(PathAsset const& lhs, PathAsset const& rhs)
|
||||
{
|
||||
return std::visit(
|
||||
[]<ValidPathAsset TLhs, ValidPathAsset TRhs>(TLhs const& lhs_, TRhs const& rhs_) {
|
||||
if constexpr (std::is_same_v<TLhs, TRhs>)
|
||||
return lhs_ == rhs_;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
lhs.value(),
|
||||
rhs.value());
|
||||
}
|
||||
|
||||
template <typename Hasher>
|
||||
void
|
||||
hash_append(Hasher& h, PathAsset const& pathAsset)
|
||||
{
|
||||
std::visit([&]<ValidPathAsset T>(T const& e) { hash_append(h, e); }, pathAsset.value());
|
||||
}
|
||||
|
||||
inline bool
|
||||
isXRP(PathAsset const& asset)
|
||||
{
|
||||
return asset.isXRP();
|
||||
}
|
||||
|
||||
std::string
|
||||
to_string(PathAsset const& asset);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, PathAsset const& x);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -251,12 +251,6 @@ std::uint8_t constexpr vaultMaximumIOUScale = 18;
|
||||
* another vault; counted from 0 */
|
||||
std::uint8_t constexpr maxAssetCheckDepth = 5;
|
||||
|
||||
/** Maximum length of a Data field in Escrow object that can be updated by WASM code. */
|
||||
std::size_t constexpr maxWasmDataLength = 4 * 1024; // 4KB
|
||||
|
||||
/** Maximum length of parameters passed from WASM code to host functions. */
|
||||
std::size_t constexpr maxWasmParamLength = 1024; // 1KB
|
||||
|
||||
/** A ledger index. */
|
||||
using LedgerIndex = std::uint32_t;
|
||||
|
||||
@@ -313,4 +307,46 @@ std::size_t constexpr permissionMaxSize = 10;
|
||||
/** The maximum number of transactions that can be in a batch. */
|
||||
std::size_t constexpr maxBatchTxCount = 8;
|
||||
|
||||
/** Length of one component of EC ElGamal ciphertext */
|
||||
std::size_t constexpr ecGamalEncryptedLength = 33;
|
||||
|
||||
/** EC ElGamal ciphertext length: two 33-byte components concatenated */
|
||||
std::size_t constexpr ecGamalEncryptedTotalLength = ecGamalEncryptedLength * 2;
|
||||
|
||||
/** Length of equality ZKProof in bytes */
|
||||
std::size_t constexpr ecEqualityProofLength = 98;
|
||||
|
||||
/** Length of EC point (compressed) */
|
||||
std::size_t constexpr compressedECPointLength = 33;
|
||||
|
||||
/** Length of EC public key (compressed) */
|
||||
std::size_t constexpr ecPubKeyLength = compressedECPointLength;
|
||||
|
||||
/** Length of EC private key in bytes */
|
||||
std::size_t constexpr ecPrivKeyLength = 32;
|
||||
|
||||
/** Length of the EC blinding factor in bytes */
|
||||
std::size_t constexpr ecBlindingFactorLength = 32;
|
||||
|
||||
/** Length of Schnorr ZKProof for public key registration in bytes */
|
||||
std::size_t constexpr ecSchnorrProofLength = 65;
|
||||
|
||||
/** Length of ElGamal Pedersen linkage proof in bytes */
|
||||
std::size_t constexpr ecPedersenProofLength = 195;
|
||||
|
||||
/** Length of Pedersen Commitment (compressed) */
|
||||
std::size_t constexpr ecPedersenCommitmentLength = compressedECPointLength;
|
||||
|
||||
/** Length of single bulletproof (range proof for 1 commitment) in bytes */
|
||||
std::size_t constexpr ecSingleBulletproofLength = 688;
|
||||
|
||||
/** Length of double bulletproof (range proof for 2 commitments) in bytes */
|
||||
std::size_t constexpr ecDoubleBulletproofLength = 754;
|
||||
|
||||
/** Compressed EC point prefix for even y-coordinate */
|
||||
std::uint8_t constexpr ecCompressedPrefixEvenY = 0x02;
|
||||
|
||||
/** Compressed EC point prefix for odd y-coordinate */
|
||||
std::uint8_t constexpr ecCompressedPrefixOddY = 0x03;
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -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 XRPL specific,
|
||||
The format of the public key is Ripple 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
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// XRPL specific constant used for parsing qualities and other things
|
||||
// Ripple 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
|
||||
`xrpld` codebase.
|
||||
`rippled` 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/XRPLF/rippled/blob/35f4698aed5dce02f771b34cfbb690495cb5efcc/src/ripple/app/tx/impl/PayChan.cpp#L229-L236))
|
||||
([Real example](https://github.com/ripple/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 an xrpl::uint160. However, so the serialized format of the
|
||||
// overhead in a xrpl::uint160. However, so the serialized format of the
|
||||
// STAccount stays unchanged, we serialize and deserialize like an STBlob.
|
||||
AccountID value_;
|
||||
bool default_;
|
||||
|
||||
@@ -164,9 +164,12 @@ public:
|
||||
constexpr TIss const&
|
||||
get() const;
|
||||
|
||||
template <ValidIssueType TIss>
|
||||
TIss&
|
||||
get();
|
||||
Issue const&
|
||||
issue() const;
|
||||
|
||||
// These three are deprecated
|
||||
Currency const&
|
||||
getCurrency() const;
|
||||
|
||||
AccountID const&
|
||||
getIssuer() const;
|
||||
@@ -222,6 +225,9 @@ public:
|
||||
void
|
||||
clear(Asset const& asset);
|
||||
|
||||
void
|
||||
setIssuer(AccountID const& uIssuer);
|
||||
|
||||
/** Set the Issue for this amount. */
|
||||
void
|
||||
setIssue(Asset const& asset);
|
||||
@@ -460,11 +466,16 @@ STAmount::get() const
|
||||
return mAsset.get<TIss>();
|
||||
}
|
||||
|
||||
template <ValidIssueType TIss>
|
||||
TIss&
|
||||
STAmount::get()
|
||||
inline Issue const&
|
||||
STAmount::issue() const
|
||||
{
|
||||
return mAsset.get<TIss>();
|
||||
return get<Issue>();
|
||||
}
|
||||
|
||||
inline Currency const&
|
||||
STAmount::getCurrency() const
|
||||
{
|
||||
return mAsset.get<Issue>().currency;
|
||||
}
|
||||
|
||||
inline AccountID const&
|
||||
@@ -494,13 +505,11 @@ operator bool() const noexcept
|
||||
inline STAmount::
|
||||
operator Number() const
|
||||
{
|
||||
return asset().visit(
|
||||
[&](Issue const& issue) -> Number {
|
||||
if (issue.native())
|
||||
return xrp();
|
||||
return iou();
|
||||
},
|
||||
[&](MPTIssue const&) -> Number { return mpt(); });
|
||||
if (native())
|
||||
return xrp();
|
||||
if (mAsset.holds<MPTIssue>())
|
||||
return mpt();
|
||||
return iou();
|
||||
}
|
||||
|
||||
inline STAmount&
|
||||
@@ -559,6 +568,12 @@ STAmount::clear(Asset const& asset)
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void
|
||||
STAmount::setIssuer(AccountID const& uIssuer)
|
||||
{
|
||||
mAsset.get<Issue>().account = uIssuer;
|
||||
}
|
||||
|
||||
inline STAmount const&
|
||||
STAmount::value() const noexcept
|
||||
{
|
||||
|
||||
@@ -349,8 +349,6 @@ public:
|
||||
void
|
||||
setFieldH128(SField const& field, uint128 const&);
|
||||
void
|
||||
setFieldH192(SField const& field, uint192 const&);
|
||||
void
|
||||
setFieldH256(SField const& field, uint256 const&);
|
||||
void
|
||||
setFieldI32(SField const& field, std::int32_t);
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/PathAsset.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
@@ -18,7 +16,7 @@ class STPathElement final : public CountedObject<STPathElement>
|
||||
{
|
||||
unsigned int mType;
|
||||
AccountID mAccountID;
|
||||
PathAsset mAssetID;
|
||||
Currency mCurrencyID;
|
||||
AccountID mIssuerID;
|
||||
|
||||
bool is_offer_;
|
||||
@@ -30,10 +28,8 @@ public:
|
||||
typeAccount = 0x01, // Rippling through an account (vs taking an offer).
|
||||
typeCurrency = 0x10, // Currency follows.
|
||||
typeIssuer = 0x20, // Issuer follows.
|
||||
typeMPT = 0x40, // MPT follows.
|
||||
typeBoundary = 0xFF, // Boundary between alternate paths.
|
||||
typeAsset = typeCurrency | typeMPT,
|
||||
typeAll = typeAccount | typeCurrency | typeIssuer | typeMPT,
|
||||
typeAll = typeAccount | typeCurrency | typeIssuer,
|
||||
// Combination of all types.
|
||||
};
|
||||
|
||||
@@ -44,19 +40,19 @@ public:
|
||||
|
||||
STPathElement(
|
||||
std::optional<AccountID> const& account,
|
||||
std::optional<PathAsset> const& asset,
|
||||
std::optional<Currency> const& currency,
|
||||
std::optional<AccountID> const& issuer);
|
||||
|
||||
STPathElement(
|
||||
AccountID const& account,
|
||||
PathAsset const& asset,
|
||||
Currency const& currency,
|
||||
AccountID const& issuer,
|
||||
bool forceAsset = false);
|
||||
bool forceCurrency = false);
|
||||
|
||||
STPathElement(
|
||||
unsigned int uType,
|
||||
AccountID const& account,
|
||||
PathAsset const& asset,
|
||||
Currency const& currency,
|
||||
AccountID const& issuer);
|
||||
|
||||
auto
|
||||
@@ -74,12 +70,6 @@ public:
|
||||
bool
|
||||
hasCurrency() const;
|
||||
|
||||
bool
|
||||
hasMPT() const;
|
||||
|
||||
bool
|
||||
hasAsset() const;
|
||||
|
||||
bool
|
||||
isNone() const;
|
||||
|
||||
@@ -88,21 +78,12 @@ public:
|
||||
AccountID const&
|
||||
getAccountID() const;
|
||||
|
||||
PathAsset const&
|
||||
getPathAsset() const;
|
||||
|
||||
Currency const&
|
||||
getCurrency() const;
|
||||
|
||||
MPTID const&
|
||||
getMPTID() const;
|
||||
|
||||
AccountID const&
|
||||
getIssuerID() const;
|
||||
|
||||
bool
|
||||
isType(Type const& pe) const;
|
||||
|
||||
bool
|
||||
operator==(STPathElement const& t) const;
|
||||
|
||||
@@ -137,7 +118,7 @@ public:
|
||||
emplace_back(Args&&... args);
|
||||
|
||||
bool
|
||||
hasSeen(AccountID const& account, PathAsset const& asset, AccountID const& issuer) const;
|
||||
hasSeen(AccountID const& account, Currency const& currency, AccountID const& issuer) const;
|
||||
|
||||
Json::Value getJson(JsonOptions) const;
|
||||
|
||||
@@ -240,7 +221,7 @@ inline STPathElement::STPathElement() : mType(typeNone), is_offer_(true)
|
||||
|
||||
inline STPathElement::STPathElement(
|
||||
std::optional<AccountID> const& account,
|
||||
std::optional<PathAsset> const& asset,
|
||||
std::optional<Currency> const& currency,
|
||||
std::optional<AccountID> const& issuer)
|
||||
: mType(typeNone)
|
||||
{
|
||||
@@ -257,10 +238,10 @@ inline STPathElement::STPathElement(
|
||||
mAccountID != noAccount(), "xrpl::STPathElement::STPathElement : account is set");
|
||||
}
|
||||
|
||||
if (asset)
|
||||
if (currency)
|
||||
{
|
||||
mAssetID = *asset;
|
||||
mType |= mAssetID.holds<Currency>() ? typeCurrency : typeMPT;
|
||||
mCurrencyID = *currency;
|
||||
mType |= typeCurrency;
|
||||
}
|
||||
|
||||
if (issuer)
|
||||
@@ -275,20 +256,20 @@ inline STPathElement::STPathElement(
|
||||
|
||||
inline STPathElement::STPathElement(
|
||||
AccountID const& account,
|
||||
PathAsset const& asset,
|
||||
Currency const& currency,
|
||||
AccountID const& issuer,
|
||||
bool forceAsset)
|
||||
bool forceCurrency)
|
||||
: mType(typeNone)
|
||||
, mAccountID(account)
|
||||
, mAssetID(asset)
|
||||
, mCurrencyID(currency)
|
||||
, mIssuerID(issuer)
|
||||
, is_offer_(isXRP(mAccountID))
|
||||
{
|
||||
if (!is_offer_)
|
||||
mType |= typeAccount;
|
||||
|
||||
if (forceAsset || !isXRP(mAssetID))
|
||||
mType |= asset.holds<Currency>() ? typeCurrency : typeMPT;
|
||||
if (forceCurrency || !isXRP(currency))
|
||||
mType |= typeCurrency;
|
||||
|
||||
if (!isXRP(issuer))
|
||||
mType |= typeIssuer;
|
||||
@@ -299,19 +280,14 @@ inline STPathElement::STPathElement(
|
||||
inline STPathElement::STPathElement(
|
||||
unsigned int uType,
|
||||
AccountID const& account,
|
||||
PathAsset const& asset,
|
||||
Currency const& currency,
|
||||
AccountID const& issuer)
|
||||
: mType(uType)
|
||||
, mAccountID(account)
|
||||
, mAssetID(asset)
|
||||
, mCurrencyID(currency)
|
||||
, mIssuerID(issuer)
|
||||
, is_offer_(isXRP(mAccountID))
|
||||
{
|
||||
// uType could be assetType; i.e. either Currency or MPTID.
|
||||
// Get the actual type.
|
||||
mAssetID.visit(
|
||||
[&](Currency const&) { mType = mType & (~Type::typeMPT); },
|
||||
[&](MPTID const&) { mType = mType & (~Type::typeCurrency); });
|
||||
hash_value_ = get_hash(*this);
|
||||
}
|
||||
|
||||
@@ -333,34 +309,16 @@ STPathElement::isAccount() const
|
||||
return !isOffer();
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::isType(Type const& pe) const
|
||||
{
|
||||
return (mType & pe) != 0u;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::hasIssuer() const
|
||||
{
|
||||
return isType(STPathElement::typeIssuer);
|
||||
return getNodeType() & STPathElement::typeIssuer;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::hasCurrency() const
|
||||
{
|
||||
return isType(STPathElement::typeCurrency);
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::hasMPT() const
|
||||
{
|
||||
return isType(STPathElement::typeMPT);
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::hasAsset() const
|
||||
{
|
||||
return isType(STPathElement::typeAsset);
|
||||
return getNodeType() & STPathElement::typeCurrency;
|
||||
}
|
||||
|
||||
inline bool
|
||||
@@ -377,22 +335,10 @@ STPathElement::getAccountID() const
|
||||
return mAccountID;
|
||||
}
|
||||
|
||||
inline PathAsset const&
|
||||
STPathElement::getPathAsset() const
|
||||
{
|
||||
return mAssetID;
|
||||
}
|
||||
|
||||
inline Currency const&
|
||||
STPathElement::getCurrency() const
|
||||
{
|
||||
return mAssetID.get<Currency>();
|
||||
}
|
||||
|
||||
inline MPTID const&
|
||||
STPathElement::getMPTID() const
|
||||
{
|
||||
return mAssetID.get<MPTID>();
|
||||
return mCurrencyID;
|
||||
}
|
||||
|
||||
inline AccountID const&
|
||||
@@ -405,7 +351,7 @@ inline bool
|
||||
STPathElement::operator==(STPathElement const& t) const
|
||||
{
|
||||
return (mType & typeAccount) == (t.mType & typeAccount) && hash_value_ == t.hash_value_ &&
|
||||
mAccountID == t.mAccountID && mAssetID == t.mAssetID && mIssuerID == t.mIssuerID;
|
||||
mAccountID == t.mAccountID && mCurrencyID == t.mCurrencyID && mIssuerID == t.mIssuerID;
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
||||
@@ -153,13 +153,16 @@ private:
|
||||
Expected<void, std::string>
|
||||
checkBatchMultiSign(STObject const& batchSigner, Rules const& rules) const;
|
||||
|
||||
void
|
||||
buildBatchTxnIds();
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
mutable std::vector<uint256> batchTxnIds_;
|
||||
std::vector<uint256> batchTxnIds_;
|
||||
};
|
||||
|
||||
bool
|
||||
|
||||
@@ -118,7 +118,7 @@ derivePublicKey(KeyType type, SecretKey const& sk);
|
||||
|
||||
/** Generate a key pair deterministically.
|
||||
|
||||
This algorithm is specific to the XRPL:
|
||||
This algorithm is specific to Ripple:
|
||||
|
||||
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 the XRPL:
|
||||
The algorithm is specific to Ripple:
|
||||
|
||||
The seed is calculated as the first 128 bits
|
||||
of the SHA512-Half of the string text excluding
|
||||
|
||||
@@ -121,10 +121,7 @@ enum TEMcodes : TERUnderlyingType {
|
||||
temARRAY_TOO_LARGE,
|
||||
temBAD_TRANSFER_FEE,
|
||||
temINVALID_INNER_BATCH,
|
||||
|
||||
temBAD_MPT,
|
||||
temBAD_WASM,
|
||||
temTEMP_DISABLED,
|
||||
temBAD_CIPHERTEXT,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -169,8 +166,6 @@ enum TEFcodes : TERUnderlyingType {
|
||||
tefNO_TICKET,
|
||||
tefNFTOKEN_IS_NOT_TRANSFERABLE,
|
||||
tefINVALID_LEDGER_FIX_TYPE,
|
||||
tefNO_WASM,
|
||||
tefWASM_FIELD_NOT_INCLUDED,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -214,7 +209,6 @@ enum TERcodes : TERUnderlyingType {
|
||||
terADDRESS_COLLISION, // Failed to allocate AccountID when trying to
|
||||
// create a pseudo-account
|
||||
terNO_DELEGATE_PERMISSION, // Delegate does not have permission
|
||||
terLOCKED, // MPT is locked
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -353,7 +347,7 @@ enum TECcodes : TERUnderlyingType {
|
||||
// backward compatibility with historical data on non-prod networks, can be
|
||||
// reclaimed after those networks reset.
|
||||
tecNO_DELEGATE_PERMISSION = 198,
|
||||
tecWASM_REJECTED = 199,
|
||||
tecBAD_PROOF = 199,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -138,7 +138,8 @@ inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
|
||||
TF_FLAG(tfMPTCanEscrow, lsfMPTCanEscrow) \
|
||||
TF_FLAG(tfMPTCanTrade, lsfMPTCanTrade) \
|
||||
TF_FLAG(tfMPTCanTransfer, lsfMPTCanTransfer) \
|
||||
TF_FLAG(tfMPTCanClawback, lsfMPTCanClawback), \
|
||||
TF_FLAG(tfMPTCanClawback, lsfMPTCanClawback) \
|
||||
TF_FLAG(tfMPTCanConfidentialAmount, lsfMPTCanConfidentialAmount), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(MPTokenAuthorize, \
|
||||
@@ -347,10 +348,12 @@ inline constexpr FlagValue tmfMPTCanMutateCanTransfer = lsmfMPTCanMutateCanTrans
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanClawback = lsmfMPTCanMutateCanClawback;
|
||||
inline constexpr FlagValue tmfMPTCanMutateMetadata = lsmfMPTCanMutateMetadata;
|
||||
inline constexpr FlagValue tmfMPTCanMutateTransferFee = lsmfMPTCanMutateTransferFee;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceCreateMutableMask =
|
||||
~(tmfMPTCanMutateCanLock | tmfMPTCanMutateRequireAuth | tmfMPTCanMutateCanEscrow |
|
||||
tmfMPTCanMutateCanTrade | tmfMPTCanMutateCanTransfer | tmfMPTCanMutateCanClawback |
|
||||
tmfMPTCanMutateMetadata | tmfMPTCanMutateTransferFee);
|
||||
inline constexpr FlagValue tmfMPTCannotMutateCanConfidentialAmount =
|
||||
lsmfMPTCannotMutateCanConfidentialAmount;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceCreateMutableMask = ~(
|
||||
tmfMPTCanMutateCanLock | tmfMPTCanMutateRequireAuth | tmfMPTCanMutateCanEscrow |
|
||||
tmfMPTCanMutateCanTrade | tmfMPTCanMutateCanTransfer | tmfMPTCanMutateCanClawback |
|
||||
tmfMPTCanMutateMetadata | tmfMPTCanMutateTransferFee | tmfMPTCannotMutateCanConfidentialAmount);
|
||||
|
||||
// MPTokenIssuanceSet MutableFlags:
|
||||
// Set or Clear flags.
|
||||
@@ -367,10 +370,13 @@ inline constexpr FlagValue tmfMPTSetCanTransfer = 0x00000100;
|
||||
inline constexpr FlagValue tmfMPTClearCanTransfer = 0x00000200;
|
||||
inline constexpr FlagValue tmfMPTSetCanClawback = 0x00000400;
|
||||
inline constexpr FlagValue tmfMPTClearCanClawback = 0x00000800;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceSetMutableMask = ~(
|
||||
tmfMPTSetCanLock | tmfMPTClearCanLock | tmfMPTSetRequireAuth | tmfMPTClearRequireAuth |
|
||||
tmfMPTSetCanEscrow | tmfMPTClearCanEscrow | tmfMPTSetCanTrade | tmfMPTClearCanTrade |
|
||||
tmfMPTSetCanTransfer | tmfMPTClearCanTransfer | tmfMPTSetCanClawback | tmfMPTClearCanClawback);
|
||||
inline constexpr FlagValue tmfMPTSetCanConfidentialAmount = 0x00001000;
|
||||
inline constexpr FlagValue tmfMPTClearCanConfidentialAmount = 0x00002000;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceSetMutableMask =
|
||||
~(tmfMPTSetCanLock | tmfMPTClearCanLock | tmfMPTSetRequireAuth | tmfMPTClearRequireAuth |
|
||||
tmfMPTSetCanEscrow | tmfMPTClearCanEscrow | tmfMPTSetCanTrade | tmfMPTClearCanTrade |
|
||||
tmfMPTSetCanTransfer | tmfMPTClearCanTransfer | tmfMPTSetCanClawback |
|
||||
tmfMPTClearCanClawback | tmfMPTSetCanConfidentialAmount | tmfMPTClearCanConfidentialAmount);
|
||||
|
||||
// Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between accounts allowed a
|
||||
// TrustLine to be added to the issuer of that token without explicit permission from that issuer.
|
||||
|
||||
@@ -84,12 +84,6 @@ public:
|
||||
|
||||
if (obj.isFieldPresent(sfParentBatchID))
|
||||
parentBatchID_ = obj.getFieldH256(sfParentBatchID);
|
||||
|
||||
if (obj.isFieldPresent(sfGasUsed))
|
||||
gasUsed_ = obj.getFieldU32(sfGasUsed);
|
||||
|
||||
if (obj.isFieldPresent(sfWasmReturnCode))
|
||||
wasmReturnCode_ = obj.getFieldI32(sfWasmReturnCode);
|
||||
}
|
||||
|
||||
std::optional<STAmount> const&
|
||||
@@ -110,30 +104,6 @@ public:
|
||||
parentBatchID_ = id;
|
||||
}
|
||||
|
||||
void
|
||||
setGasUsed(std::optional<std::uint32_t> const gasUsed)
|
||||
{
|
||||
gasUsed_ = gasUsed;
|
||||
}
|
||||
|
||||
std::optional<std::uint32_t> const&
|
||||
getGasUsed() const
|
||||
{
|
||||
return gasUsed_;
|
||||
}
|
||||
|
||||
void
|
||||
setWasmReturnCode(std::optional<std::int32_t> const wasmReturnCode)
|
||||
{
|
||||
wasmReturnCode_ = wasmReturnCode;
|
||||
}
|
||||
|
||||
std::optional<std::int32_t> const&
|
||||
getWasmReturnCode() const
|
||||
{
|
||||
return wasmReturnCode_;
|
||||
}
|
||||
|
||||
private:
|
||||
uint256 transactionID_;
|
||||
std::uint32_t ledgerSeq_;
|
||||
@@ -142,8 +112,6 @@ private:
|
||||
|
||||
std::optional<STAmount> deliveredAmount_;
|
||||
std::optional<uint256> parentBatchID_;
|
||||
std::optional<std::uint32_t> gasUsed_;
|
||||
std::optional<std::int32_t> wasmReturnCode_;
|
||||
|
||||
STArray nodes_;
|
||||
};
|
||||
|
||||
@@ -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/xrpld/app/misc/FeeEscalation.md#fee-level */
|
||||
See also: src/ripple/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. */
|
||||
|
||||
@@ -15,12 +15,11 @@
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
|
||||
XRPL_FEATURE(SmartEscrow, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(MPTokensV2, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(BatchV1_1, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(ConfidentialTransfer, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Security3_1_3, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PermissionedDomainInvariant, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (ExpiredNFTokenOfferRemoval, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (BatchInnerSigs, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(LendingProtocol, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionDelegationV1_1, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (DirectoryLimit, Supported::yes, VoteBehavior::DefaultNo)
|
||||
@@ -34,7 +33,6 @@ XRPL_FEATURE(TokenEscrow, Supported::yes, VoteBehavior::DefaultN
|
||||
XRPL_FIX (EnforceNFTokenTrustlineV2, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (AMMv1_3, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionedDEX, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(Batch, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(SingleAssetVault, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo)
|
||||
// Check flags in Credential transactions
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user