Merge remote-tracking branch 'upstream/develop' into confidential-transfer

This commit is contained in:
Shawn Xie
2025-11-03 18:42:41 -05:00
356 changed files with 10392 additions and 7071 deletions

View File

@@ -10,10 +10,17 @@ inputs:
build_type:
description: 'The build type to use ("Debug", "Release").'
required: true
build_nproc:
description: "The number of processors to use for building."
required: true
force_build:
description: 'Force building of all dependencies ("true", "false").'
required: false
default: "false"
log_verbosity:
description: "The logging verbosity."
required: false
default: "verbose"
runs:
using: composite
@@ -22,16 +29,21 @@ runs:
shell: bash
env:
BUILD_DIR: ${{ inputs.build_dir }}
BUILD_NPROC: ${{ inputs.build_nproc }}
BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }}
BUILD_TYPE: ${{ inputs.build_type }}
LOG_VERBOSITY: ${{ inputs.log_verbosity }}
run: |
echo 'Installing dependencies.'
mkdir -p '${{ env.BUILD_DIR }}'
cd '${{ env.BUILD_DIR }}'
mkdir -p "${BUILD_DIR}"
cd "${BUILD_DIR}"
conan install \
--output-folder . \
--build=${{ env.BUILD_OPTION }} \
--build="${BUILD_OPTION}" \
--options:host='&:tests=True' \
--options:host='&:xrpld=True' \
--settings:all build_type='${{ env.BUILD_TYPE }}' \
--settings:all build_type="${BUILD_TYPE}" \
--conf:all tools.build:jobs=${BUILD_NPROC} \
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
..

View File

@@ -39,8 +39,8 @@ runs:
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
CONAN_REMOTE_URL: ${{ inputs.conan_remote_url }}
run: |
echo "Adding Conan remote '${{ env.CONAN_REMOTE_NAME }}' at '${{ env.CONAN_REMOTE_URL }}'."
conan remote add --index 0 --force '${{ env.CONAN_REMOTE_NAME }}' '${{ env.CONAN_REMOTE_URL }}'
echo "Adding Conan remote '${CONAN_REMOTE_NAME}' at '${CONAN_REMOTE_URL}'."
conan remote add --index 0 --force "${CONAN_REMOTE_NAME}" "${CONAN_REMOTE_URL}"
echo 'Listing Conan remotes.'
conan remote list

View File

@@ -17,7 +17,7 @@ Loop: xrpld.app xrpld.rpc
xrpld.rpc > xrpld.app
Loop: xrpld.app xrpld.shamap
xrpld.app > xrpld.shamap
xrpld.shamap ~= xrpld.app
Loop: xrpld.core xrpld.perflog
xrpld.perflog == xrpld.core

View File

@@ -8,6 +8,10 @@ libxrpl.ledger > xrpl.ledger
libxrpl.ledger > xrpl.protocol
libxrpl.net > xrpl.basics
libxrpl.net > xrpl.net
libxrpl.nodestore > xrpl.basics
libxrpl.nodestore > xrpl.json
libxrpl.nodestore > xrpl.nodestore
libxrpl.nodestore > xrpl.protocol
libxrpl.protocol > xrpl.basics
libxrpl.protocol > xrpl.json
libxrpl.protocol > xrpl.protocol
@@ -18,6 +22,9 @@ libxrpl.server > xrpl.basics
libxrpl.server > xrpl.json
libxrpl.server > xrpl.protocol
libxrpl.server > xrpl.server
libxrpl.shamap > xrpl.basics
libxrpl.shamap > xrpl.protocol
libxrpl.shamap > xrpl.shamap
test.app > test.jtx
test.app > test.rpc
test.app > test.toplevel
@@ -25,11 +32,11 @@ test.app > test.unit_test
test.app > xrpl.basics
test.app > xrpld.app
test.app > xrpld.core
test.app > xrpld.nodestore
test.app > xrpld.overlay
test.app > xrpld.rpc
test.app > xrpl.json
test.app > xrpl.ledger
test.app > xrpl.nodestore
test.app > xrpl.protocol
test.app > xrpl.resource
test.basics > test.jtx
@@ -86,8 +93,7 @@ test.nodestore > test.toplevel
test.nodestore > test.unit_test
test.nodestore > xrpl.basics
test.nodestore > xrpld.core
test.nodestore > xrpld.nodestore
test.nodestore > xrpld.unity
test.nodestore > xrpl.nodestore
test.overlay > test.jtx
test.overlay > test.toplevel
test.overlay > test.unit_test
@@ -95,8 +101,8 @@ test.overlay > xrpl.basics
test.overlay > xrpld.app
test.overlay > xrpld.overlay
test.overlay > xrpld.peerfinder
test.overlay > xrpld.shamap
test.overlay > xrpl.protocol
test.overlay > xrpl.shamap
test.peerfinder > test.beast
test.peerfinder > test.unit_test
test.peerfinder > xrpl.basics
@@ -131,18 +137,21 @@ test.server > xrpl.json
test.server > xrpl.server
test.shamap > test.unit_test
test.shamap > xrpl.basics
test.shamap > xrpld.nodestore
test.shamap > xrpld.shamap
test.shamap > xrpl.nodestore
test.shamap > xrpl.protocol
test.shamap > xrpl.shamap
test.toplevel > test.csf
test.toplevel > xrpl.json
test.unit_test > xrpl.basics
tests.libxrpl > xrpl.basics
tests.libxrpl > xrpl.json
tests.libxrpl > xrpl.net
xrpl.json > xrpl.basics
xrpl.ledger > xrpl.basics
xrpl.ledger > xrpl.protocol
xrpl.net > xrpl.basics
xrpl.nodestore > xrpl.basics
xrpl.nodestore > xrpl.protocol
xrpl.protocol > xrpl.basics
xrpl.protocol > xrpl.json
xrpl.resource > xrpl.basics
@@ -151,17 +160,21 @@ xrpl.resource > xrpl.protocol
xrpl.server > xrpl.basics
xrpl.server > xrpl.json
xrpl.server > xrpl.protocol
xrpl.shamap > xrpl.basics
xrpl.shamap > xrpl.nodestore
xrpl.shamap > xrpl.protocol
xrpld.app > test.unit_test
xrpld.app > xrpl.basics
xrpld.app > xrpld.conditions
xrpld.app > xrpld.consensus
xrpld.app > xrpld.nodestore
xrpld.app > xrpld.perflog
xrpld.app > xrpl.json
xrpld.app > xrpl.ledger
xrpld.app > xrpl.net
xrpld.app > xrpl.nodestore
xrpld.app > xrpl.protocol
xrpld.app > xrpl.resource
xrpld.app > xrpl.shamap
xrpld.conditions > xrpl.basics
xrpld.conditions > xrpl.protocol
xrpld.consensus > xrpl.basics
@@ -171,11 +184,6 @@ xrpld.core > xrpl.basics
xrpld.core > xrpl.json
xrpld.core > xrpl.net
xrpld.core > xrpl.protocol
xrpld.nodestore > xrpl.basics
xrpld.nodestore > xrpld.core
xrpld.nodestore > xrpld.unity
xrpld.nodestore > xrpl.json
xrpld.nodestore > xrpl.protocol
xrpld.overlay > xrpl.basics
xrpld.overlay > xrpld.core
xrpld.overlay > xrpld.peerfinder
@@ -191,13 +199,11 @@ xrpld.perflog > xrpl.basics
xrpld.perflog > xrpl.json
xrpld.rpc > xrpl.basics
xrpld.rpc > xrpld.core
xrpld.rpc > xrpld.nodestore
xrpld.rpc > xrpl.json
xrpld.rpc > xrpl.ledger
xrpld.rpc > xrpl.net
xrpld.rpc > xrpl.nodestore
xrpld.rpc > xrpl.protocol
xrpld.rpc > xrpl.resource
xrpld.rpc > xrpl.server
xrpld.shamap > xrpl.basics
xrpld.shamap > xrpld.nodestore
xrpld.shamap > xrpl.protocol
xrpld.shamap > xrpl.shamap

View File

@@ -74,14 +74,14 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue
# RHEL:
# - 9.4 using GCC 12: Debug and Unity on linux/amd64.
# - 9.6 using Clang: Release and no Unity on linux/amd64.
# - 9 using GCC 12: Debug and Unity on linux/amd64.
# - 10 using Clang: Release and no Unity on linux/amd64.
if os['distro_name'] == 'rhel':
skip = True
if os['distro_version'] == '9.4':
if os['distro_version'] == '9':
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
skip = False
elif os['distro_version'] == '9.6':
elif os['distro_version'] == '10':
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-any' and build_type == 'Release' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
skip = False
if skip:

View File

@@ -14,139 +14,169 @@
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "12"
"compiler_version": "12",
"image_sha": "97ba375"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "13"
"compiler_version": "13",
"image_sha": "97ba375"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "14"
"compiler_version": "14",
"image_sha": "97ba375"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "15"
"compiler_version": "15",
"image_sha": "97ba375"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "16"
"compiler_version": "16",
"image_sha": "97ba375"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "17"
"compiler_version": "17",
"image_sha": "97ba375"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "18"
"compiler_version": "18",
"image_sha": "97ba375"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "19"
"compiler_version": "19",
"image_sha": "97ba375"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "20"
"compiler_version": "20",
"image_sha": "97ba375"
},
{
"distro_name": "rhel",
"distro_version": "9.4",
"distro_version": "8",
"compiler_name": "gcc",
"compiler_version": "12"
"compiler_version": "14",
"image_sha": "97ba375"
},
{
"distro_name": "rhel",
"distro_version": "9.4",
"compiler_name": "gcc",
"compiler_version": "13"
},
{
"distro_name": "rhel",
"distro_version": "9.4",
"compiler_name": "gcc",
"compiler_version": "14"
},
{
"distro_name": "rhel",
"distro_version": "9.6",
"compiler_name": "gcc",
"compiler_version": "13"
},
{
"distro_name": "rhel",
"distro_version": "9.6",
"compiler_name": "gcc",
"compiler_version": "14"
},
{
"distro_name": "rhel",
"distro_version": "9.4",
"distro_version": "8",
"compiler_name": "clang",
"compiler_version": "any"
"compiler_version": "any",
"image_sha": "97ba375"
},
{
"distro_name": "rhel",
"distro_version": "9.6",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "97ba375"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "97ba375"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "97ba375"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "clang",
"compiler_version": "any"
"compiler_version": "any",
"image_sha": "97ba375"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "97ba375"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "97ba375"
},
{
"distro_name": "ubuntu",
"distro_version": "jammy",
"compiler_name": "gcc",
"compiler_version": "12"
"compiler_version": "12",
"image_sha": "97ba375"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "13"
"compiler_version": "13",
"image_sha": "97ba375"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "14"
"compiler_version": "14",
"image_sha": "97ba375"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "16"
"compiler_version": "16",
"image_sha": "97ba375"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "17"
"compiler_version": "17",
"image_sha": "97ba375"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "18"
"compiler_version": "18",
"image_sha": "97ba375"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "19"
"compiler_version": "19",
"image_sha": "97ba375"
}
],
"build_type": ["Debug", "Release"],

View File

@@ -10,7 +10,8 @@
"distro_name": "macos",
"distro_version": "",
"compiler_name": "",
"compiler_version": ""
"compiler_version": "",
"image_sha": ""
}
],
"build_type": ["Debug", "Release"],

View File

@@ -10,7 +10,8 @@
"distro_name": "windows",
"distro_version": "",
"compiler_name": "",
"compiler_version": ""
"compiler_version": "",
"image_sha": ""
}
],
"build_type": ["Debug", "Release"],

View File

@@ -103,6 +103,7 @@ jobs:
if: ${{ needs.should-run.outputs.go == 'true' }}
uses: ./.github/workflows/reusable-build-test.yml
strategy:
fail-fast: false
matrix:
os: [linux, macos, windows]
with:

View File

@@ -9,9 +9,9 @@ name: Trigger
on:
push:
branches:
- develop
- release
- master
- "develop"
- "release*"
- "master"
paths:
# These paths are unique to `on-trigger.yml`.
- ".github/workflows/reusable-check-missing-commits.yml"
@@ -50,7 +50,12 @@ on:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
# When a PR is merged into the develop branch it will be assigned a unique
# group identifier, so execution will continue even if another PR is merged
# while it is still running. In all other cases the group identifier is shared
# per branch, so that any in-progress runs are cancelled when a new commit is
# pushed.
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' && github.sha || github.ref }}
cancel-in-progress: true
defaults:
@@ -65,6 +70,7 @@ jobs:
build-test:
uses: ./.github/workflows/reusable-build-test.yml
strategy:
fail-fast: ${{ github.event_name == 'merge_group' }}
matrix:
os: [linux, macos, windows]
with:

View File

@@ -9,7 +9,7 @@ on:
jobs:
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
run-hooks:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@af1b0f0d764cda2e5435f5ac97b240d4bd4d95d3
uses: XRPLF/actions/.github/workflows/pre-commit.yml@34790936fae4c6c751f62ec8c06696f9c1a5753a
with:
runs_on: ubuntu-latest
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-d1496b8" }'
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-a8c7be1" }'

View File

@@ -23,16 +23,24 @@ defaults:
env:
BUILD_DIR: .build
NPROC_SUBTRACT: 2
jobs:
publish:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/ci/tools-rippled-documentation:sha-d1496b8
container: ghcr.io/xrplf/ci/tools-rippled-documentation:sha-a8c7be1
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Get number of processors
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
id: nproc
with:
subtract: ${{ env.NPROC_SUBTRACT }}
- name: Check configuration
run: |
echo 'Checking path.'
@@ -46,12 +54,16 @@ jobs:
echo 'Checking Doxygen version.'
doxygen --version
- name: Build documentation
env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
run: |
mkdir -p ${{ env.BUILD_DIR }}
cd ${{ env.BUILD_DIR }}
mkdir -p "${BUILD_DIR}"
cd "${BUILD_DIR}"
cmake -Donly_docs=ON ..
cmake --build . --target docs --parallel $(nproc)
cmake --build . --target docs --parallel ${BUILD_NPROC}
- name: Publish documentation
if: ${{ github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }}
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0

View File

@@ -39,6 +39,12 @@ on:
required: true
type: string
nproc_subtract:
description: "The number of processors to subtract when calculating parallelism."
required: false
type: number
default: 2
secrets:
CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports."
@@ -55,6 +61,7 @@ jobs:
runs_on: ${{ inputs.runs_on }}
image: ${{ inputs.image }}
config_name: ${{ inputs.config_name }}
nproc_subtract: ${{ inputs.nproc_subtract }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
@@ -67,3 +74,4 @@ jobs:
runs_on: ${{ inputs.runs_on }}
image: ${{ inputs.image }}
config_name: ${{ inputs.config_name }}
nproc_subtract: ${{ inputs.nproc_subtract }}

View File

@@ -42,7 +42,7 @@ jobs:
- generate-matrix
uses: ./.github/workflows/reusable-build-test-config.yml
strategy:
fail-fast: false
fail-fast: ${{ github.event_name == 'merge_group' }}
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
max-parallel: 10
with:
@@ -52,7 +52,7 @@ jobs:
cmake_args: ${{ matrix.cmake_args }}
cmake_target: ${{ matrix.cmake_target }}
runs_on: ${{ toJSON(matrix.architecture.runner) }}
image: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-5dd7158', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version) || '' }}
image: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-{4}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version, matrix.os.image_sha) || '' }}
config_name: ${{ matrix.config_name }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -34,6 +34,11 @@ on:
required: true
type: string
nproc_subtract:
description: "The number of processors to subtract when calculating parallelism."
required: true
type: number
secrets:
CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports."
@@ -48,6 +53,7 @@ jobs:
name: Build ${{ inputs.config_name }}
runs-on: ${{ fromJSON(inputs.runs_on) }}
container: ${{ inputs.image != '' && inputs.image || null }}
timeout-minutes: 60
steps:
- name: Cleanup workspace
if: ${{ runner.os == 'macOS' }}
@@ -57,13 +63,19 @@ jobs:
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5
uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
with:
disable_ccache: false
- name: Print build environment
uses: ./.github/actions/print-env
- name: Get number of processors
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
id: nproc
with:
subtract: ${{ inputs.nproc_subtract }}
- name: Setup Conan
uses: ./.github/actions/setup-conan
@@ -71,7 +83,11 @@ jobs:
uses: ./.github/actions/build-deps
with:
build_dir: ${{ inputs.build_dir }}
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ inputs.build_type }}
# Set the verbosity to "quiet" for Windows to avoid an excessive
# amount of logs. For other OSes, the "verbose" logs are more useful.
log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
- name: Configure CMake
shell: bash
@@ -83,33 +99,50 @@ jobs:
cmake \
-G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
${{ env.CMAKE_ARGS }} \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
${CMAKE_ARGS} \
..
- name: Build the binary
shell: bash
working-directory: ${{ inputs.build_dir }}
env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
BUILD_TYPE: ${{ inputs.build_type }}
CMAKE_TARGET: ${{ inputs.cmake_target }}
run: |
cmake \
--build . \
--config ${{ env.BUILD_TYPE }} \
--parallel $(nproc) \
--target ${{ env.CMAKE_TARGET }}
--config "${BUILD_TYPE}" \
--parallel ${BUILD_NPROC} \
--target "${CMAKE_TARGET}"
- name: Put built binaries in one location
shell: bash
working-directory: ${{ inputs.build_dir }}
env:
BUILD_TYPE_DIR: ${{ runner.os == 'Windows' && inputs.build_type || '' }}
CMAKE_TARGET: ${{ inputs.cmake_target }}
run: |
mkdir -p ./binaries/doctest/
cp ./${BUILD_TYPE_DIR}/rippled* ./binaries/
if [ "${CMAKE_TARGET}" != 'coverage' ]; then
cp ./src/tests/libxrpl/${BUILD_TYPE_DIR}/xrpl.test.* ./binaries/doctest/
fi
- name: Upload rippled artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
env:
BUILD_DIR: ${{ inputs.build_dir }}
with:
name: rippled-${{ inputs.config_name }}
path: ${{ inputs.build_dir }}/${{ runner.os == 'Windows' && inputs.build_type || '' }}/rippled${{ runner.os == 'Windows' && '.exe' || '' }}
path: ${{ env.BUILD_DIR }}/binaries/
retention-days: 3
if-no-files-found: error
- name: Upload coverage report
if: ${{ inputs.cmake_target == 'coverage' }}
if: ${{ github.repository_owner == 'XRPLF' && inputs.cmake_target == 'coverage' }}
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
disable_search: true

View File

@@ -51,7 +51,7 @@ jobs:
run: |
echo 'Generating user and channel.'
echo "user=clio" >> "${GITHUB_OUTPUT}"
echo "channel=pr_${{ env.PR_NUMBER }}" >> "${GITHUB_OUTPUT}"
echo "channel=pr_${PR_NUMBER}" >> "${GITHUB_OUTPUT}"
echo 'Extracting version.'
echo "version=$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" >> "${GITHUB_OUTPUT}"
- name: Calculate conan reference
@@ -64,13 +64,15 @@ jobs:
conan_remote_name: ${{ inputs.conan_remote_name }}
conan_remote_url: ${{ inputs.conan_remote_url }}
- name: Log into Conan remote
run: conan remote login ${{ inputs.conan_remote_name }} "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}"
env:
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}"
- name: Upload package
env:
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
run: |
conan export --user=${{ steps.generate.outputs.user }} --channel=${{ steps.generate.outputs.channel }} .
conan upload --confirm --check --remote=${{ env.CONAN_REMOTE_NAME }} xrpl/${{ steps.conan_ref.outputs.conan_ref }}
conan upload --confirm --check --remote="${CONAN_REMOTE_NAME}" xrpl/${{ steps.conan_ref.outputs.conan_ref }}
outputs:
conan_ref: ${{ steps.conan_ref.outputs.conan_ref }}
@@ -86,4 +88,4 @@ jobs:
gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
/repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \
-F "client_payload[conan_ref]=${{ needs.upload.outputs.conan_ref }}" \
-F "client_payload[pr_url]=${{ env.PR_URL }}"
-F "client_payload[pr_url]=${PR_URL}"

View File

@@ -38,4 +38,4 @@ jobs:
env:
GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }}
GENERATE_OPTION: ${{ inputs.strategy_matrix == 'all' && '--all' || '' }}
run: ./generate.py ${{ env.GENERATE_OPTION }} ${{ env.GENERATE_CONFIG }} >> "${GITHUB_OUTPUT}"
run: ./generate.py ${GENERATE_OPTION} ${GENERATE_CONFIG} >> "${GITHUB_OUTPUT}"

View File

@@ -26,12 +26,28 @@ on:
required: true
type: string
nproc_subtract:
description: "The number of processors to subtract when calculating parallelism."
required: true
type: number
jobs:
test:
name: Test ${{ inputs.config_name }}
runs-on: ${{ fromJSON(inputs.runs_on) }}
container: ${{ inputs.image != '' && inputs.image || null }}
timeout-minutes: 30
steps:
- name: Cleanup workspace
if: ${{ runner.os == 'macOS' }}
uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
- name: Get number of processors
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
id: nproc
with:
subtract: ${{ inputs.nproc_subtract }}
- name: Download rippled artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
@@ -61,9 +77,35 @@ jobs:
run: |
./rippled --version | grep libvoidstar
- name: Test the binary
- name: Run the embedded tests
if: ${{ inputs.run_tests }}
shell: bash
env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
run: |
./rippled --unittest --unittest-jobs $(nproc)
ctest -j $(nproc) --output-on-failure
./rippled --unittest --unittest-jobs ${BUILD_NPROC}
- name: Run the separate tests
if: ${{ inputs.run_tests }}
env:
EXT: ${{ runner.os == 'Windows' && '.exe' || '' }}
shell: bash
run: |
for test_file in ./doctest/*${EXT}; do
echo "Executing $test_file"
chmod +x "$test_file"
if [[ "${{ runner.os }}" == "Windows" && "$test_file" == "./doctest/xrpl.test.net.exe" ]]; then
echo "Skipping $test_file on Windows"
else
"$test_file"
fi
done
- name: Debug failure (Linux)
if: ${{ failure() && runner.os == 'Linux' && inputs.run_tests }}
shell: bash
run: |
echo "IPv4 local port range:"
cat /proc/sys/net/ipv4/ip_local_port_range
echo "Netstat:"
netstat -an

View File

@@ -34,17 +34,20 @@ on:
env:
CONAN_REMOTE_NAME: xrplf
CONAN_REMOTE_URL: https://conan.ripplex.io
NPROC_SUBTRACT: 2
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Generate the strategy matrix to be used by the following job.
generate-matrix:
uses: ./.github/workflows/reusable-strategy-matrix.yml
with:
strategy_matrix: ${{ github.event_name == 'pull_request' && 'minimal' || 'all' }}
# Build and upload the dependencies for each configuration.
run-upload-conan-deps:
needs:
- generate-matrix
@@ -53,19 +56,29 @@ jobs:
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
max-parallel: 10
runs-on: ${{ matrix.architecture.runner }}
container: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-5dd7158', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version) || null }}
container: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-{4}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version, matrix.os.image_sha) || null }}
steps:
- name: Cleanup workspace
if: ${{ runner.os == 'macOS' }}
uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5
uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
with:
disable_ccache: false
- name: Print build environment
uses: ./.github/actions/print-env
- name: Get number of processors
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
id: nproc
with:
subtract: ${{ env.NPROC_SUBTRACT }}
- name: Setup Conan
uses: ./.github/actions/setup-conan
with:
@@ -76,15 +89,19 @@ jobs:
uses: ./.github/actions/build-deps
with:
build_dir: .build
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ matrix.build_type }}
force_build: ${{ github.event_name == 'schedule' || github.event.inputs.force_source_build == 'true' }}
# Set the verbosity to "quiet" for Windows to avoid an excessive
# amount of logs. For other OSes, the "verbose" logs are more useful.
log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
- name: Log into Conan remote
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' }}
run: conan remote login ${{ env.CONAN_REMOTE_NAME }} "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}"
if: ${{ github.repository_owner == 'XRPLF' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}"
- name: Upload Conan packages
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' && github.event_name != 'schedule' }}
if: ${{ github.repository_owner == 'XRPLF' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
env:
FORCE_OPTION: ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }}
run: conan upload "*" --remote='${{ env.CONAN_REMOTE_NAME }}' --confirm ${{ env.FORCE_OPTION }}
run: conan upload "*" --remote="${CONAN_REMOTE_NAME}" --confirm ${FORCE_OPTION}

View File

@@ -39,17 +39,12 @@ found here](./docs/build/environment.md).
- [Python 3.11](https://www.python.org/downloads/), or higher
- [Conan 2.17](https://conan.io/downloads.html)[^1], or higher
- [CMake 3.22](https://cmake.org/download/)[^2], or higher
- [CMake 3.22](https://cmake.org/download/), or higher
[^1]:
It is possible to build with Conan 1.60+, but the instructions are
significantly different, which is why we are not recommending it.
[^2]:
CMake 4 is not yet supported by all dependencies required by this project.
If you are affected by this issue, follow [conan workaround for cmake
4](#workaround-for-cmake-4)
`rippled` is written in the C++20 dialect and includes the `<concepts>` header.
The [minimum compiler versions][2] required are:
@@ -282,21 +277,6 @@ sed -i.bak -e 's|^arch=.*$|arch=x86_64|' $(conan config home)/profiles/default
sed -i.bak -e 's|^compiler\.runtime=.*$|compiler.runtime=static|' $(conan config home)/profiles/default
```
#### Workaround for CMake 4
If your system CMake is version 4 rather than 3, you may have to configure Conan
profile to use CMake version 3 for dependencies, by adding the following two
lines to your profile:
```text
[tool_requires]
!cmake/*: cmake/[>=3 <4]
```
This will force Conan to download and use a locally cached CMake 3 version, and
is needed because some of the dependencies used by this project do not support
CMake 4.
#### Clang workaround for grpc
If your compiler is clang, version 19 or later, or apple-clang, version 17 or

View File

@@ -975,6 +975,47 @@
# number of ledger records online. Must be greater
# than or equal to ledger_history.
#
# Optional keys for NuDB only:
#
# nudb_block_size EXPERIMENTAL: Block size in bytes for NuDB storage.
# Must be a power of 2 between 4096 and 32768. Default is 4096.
#
# This parameter controls the fundamental storage unit
# size for NuDB's internal data structures. The choice
# of block size can significantly impact performance
# depending on your storage hardware and filesystem:
#
# - 4096 bytes: Optimal for most standard SSDs and
# traditional filesystems (ext4, NTFS, HFS+).
# Provides good balance of performance and storage
# efficiency. Recommended for most deployments.
# Minimizes memory footprint and provides consistent
# low-latency access patterns across diverse hardware.
#
# - 8192-16384 bytes: May improve performance on
# high-end NVMe SSDs and copy-on-write filesystems
# like ZFS or Btrfs that benefit from larger block
# alignment. Can reduce metadata overhead for large
# databases. Offers better sequential throughput and
# reduced I/O operations at the cost of higher memory
# usage per operation.
#
# - 32768 bytes (32K): Maximum supported block size
# for high-performance scenarios with very fast
# storage. May increase memory usage and reduce
# efficiency for smaller databases. Best suited for
# enterprise environments with abundant RAM.
#
# Performance testing is recommended before deploying
# any non-default block size in production environments.
#
# Note: This setting cannot be changed after database
# creation without rebuilding the entire database.
# Choose carefully based on your hardware and expected
# database size.
#
# Example: nudb_block_size=4096
#
# These keys modify the behavior of online_delete, and thus are only
# relevant if online_delete is defined and non-zero:
#
@@ -1471,6 +1512,7 @@ secure_gateway = 127.0.0.1
[node_db]
type=NuDB
path=/var/lib/rippled/db/nudb
nudb_block_size=4096
online_delete=512
advisory_delete=0

View File

@@ -45,7 +45,7 @@ if (static OR APPLE OR MSVC)
set (OPENSSL_USE_STATIC_LIBS ON)
endif ()
set (OPENSSL_MSVC_STATIC_RT ON)
find_dependency (OpenSSL 1.1.1 REQUIRED)
find_dependency (OpenSSL REQUIRED)
find_dependency (ZLIB)
find_dependency (date)
if (TARGET ZLIB::ZLIB)

View File

@@ -16,13 +16,16 @@ set(CMAKE_CXX_EXTENSIONS OFF)
target_compile_definitions (common
INTERFACE
$<$<CONFIG:Debug>:DEBUG _DEBUG>
$<$<AND:$<BOOL:${profile}>,$<NOT:$<BOOL:${assert}>>>:NDEBUG>)
# ^^^^ NOTE: CMAKE release builds already have NDEBUG
# defined, so no need to add it explicitly except for
# this special case of (profile ON) and (assert OFF)
# -- presumably this is because we don't want profile
# builds asserting unless asserts were specifically
# requested
#[===[
NOTE: CMAKE release builds already have NDEBUG defined, so no need to add it
explicitly except for the special case of (profile ON) and (assert OFF).
Presumably this is because we don't want profile builds asserting unless
asserts were specifically requested.
]===]
$<$<AND:$<BOOL:${profile}>,$<NOT:$<BOOL:${assert}>>>:NDEBUG>
# TODO: Remove once we have migrated functions from OpenSSL 1.x to 3.x.
OPENSSL_SUPPRESS_DEPRECATED
)
if (MSVC)
# remove existing exception flag since we set it to -EHa

View File

@@ -53,14 +53,15 @@ add_library(xrpl.imports.main INTERFACE)
target_link_libraries(xrpl.imports.main
INTERFACE
LibArchive::LibArchive
OpenSSL::Crypto
Ripple::boost
Ripple::opts
Ripple::syslibs
absl::random_random
date::date
ed25519::ed25519
LibArchive::LibArchive
OpenSSL::Crypto
Ripple::boost
Ripple::libs
Ripple::opts
Ripple::syslibs
secp256k1::secp256k1
xrpl.libpb
xxHash::xxhash
@@ -111,6 +112,21 @@ target_link_libraries(xrpl.libxrpl.net PUBLIC
add_module(xrpl server)
target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol)
add_module(xrpl nodestore)
target_link_libraries(xrpl.libxrpl.nodestore PUBLIC
xrpl.libxrpl.basics
xrpl.libxrpl.json
xrpl.libxrpl.protocol
)
add_module(xrpl shamap)
target_link_libraries(xrpl.libxrpl.shamap PUBLIC
xrpl.libxrpl.basics
xrpl.libxrpl.crypto
xrpl.libxrpl.protocol
xrpl.libxrpl.nodestore
)
add_module(xrpl ledger)
target_link_libraries(xrpl.libxrpl.ledger PUBLIC
xrpl.libxrpl.basics
@@ -136,6 +152,8 @@ target_link_modules(xrpl PUBLIC
protocol
resource
server
nodestore
shamap
net
ledger
)

View File

@@ -8,20 +8,23 @@ install (
TARGETS
common
opts
ripple_syslibs
ripple_boost
ripple_libs
ripple_syslibs
xrpl.imports.main
xrpl.libpb
xrpl.libxrpl
xrpl.libxrpl.basics
xrpl.libxrpl.beast
xrpl.libxrpl.crypto
xrpl.libxrpl.json
xrpl.libxrpl.ledger
xrpl.libxrpl.net
xrpl.libxrpl.nodestore
xrpl.libxrpl.protocol
xrpl.libxrpl.resource
xrpl.libxrpl.ledger
xrpl.libxrpl.server
xrpl.libxrpl.net
xrpl.libxrpl
xrpl.libxrpl.shamap
antithesis-sdk-cpp
EXPORT RippleExports
LIBRARY DESTINATION lib
@@ -38,7 +41,7 @@ install(CODE "
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
include(create_symbolic_link)
create_symbolic_link(xrpl \
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple)
\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple)
")
install (EXPORT RippleExports
@@ -72,7 +75,7 @@ if (is_root_project AND TARGET rippled)
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
include(create_symbolic_link)
create_symbolic_link(rippled${suffix} \
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix})
\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix})
")
endif ()

View File

@@ -1,4 +1,4 @@
option (validator_keys "Enables building of validator-keys-tool as a separate target (imported via FetchContent)" OFF)
option (validator_keys "Enables building of validator-keys tool as a separate target (imported via FetchContent)" OFF)
if (validator_keys)
git_branch (current_branch)
@@ -6,17 +6,15 @@ if (validator_keys)
if (NOT (current_branch STREQUAL "release"))
set (current_branch "master")
endif ()
message (STATUS "tracking ValidatorKeys branch: ${current_branch}")
message (STATUS "Tracking ValidatorKeys branch: ${current_branch}")
FetchContent_Declare (
validator_keys_src
validator_keys
GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git
GIT_TAG "${current_branch}"
)
FetchContent_GetProperties (validator_keys_src)
if (NOT validator_keys_src_POPULATED)
message (STATUS "Pausing to download ValidatorKeys...")
FetchContent_Populate (validator_keys_src)
endif ()
add_subdirectory (${validator_keys_src_SOURCE_DIR} ${CMAKE_BINARY_DIR}/validator-keys)
FetchContent_MakeAvailable(validator_keys)
set_target_properties(validator-keys PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif ()

View File

@@ -7,7 +7,7 @@ function(xrpl_add_test name)
"${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp"
)
add_executable(${target} EXCLUDE_FROM_ALL ${ARGN} ${sources})
add_executable(${target} ${ARGN} ${sources})
isolate_headers(
${target}

View File

@@ -9,7 +9,7 @@
"rocksdb/10.0.1#85537f46e538974d67da0c3977de48ac%1756234304.347",
"re2/20230301#dfd6e2bf050eb90ddd8729cfb4c844a4%1756234257.976",
"protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1756234251.614",
"openssl/1.1.1w#a8f0792d7c5121b954578a7149d23e03%1756223730.729",
"openssl/3.5.4#a1d5835cc6ed5c5b8f3cd5b9b5d24205%1759746684.671",
"nudb/2.0.9#c62cfd501e57055a7e0d8ee3d5e5427d%1756234237.107",
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1756234228.999",
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1756223727.64",

View File

@@ -1,9 +1,5 @@
# Global configuration for Conan. This is used to set the number of parallel
# downloads, uploads, and build jobs. The verbosity is set to verbose to
# provide more information during the build process.
# downloads and uploads.
core:non_interactive=True
core.download:parallel={{ os.cpu_count() }}
core.upload:parallel={{ os.cpu_count() }}
tools.build:jobs={{ (os.cpu_count() * 4/5) | int }}
tools.build:verbosity=verbose
tools.compilation:verbosity=verbose

View File

@@ -21,14 +21,11 @@ compiler.libcxx={{detect_api.detect_libcxx(compiler, version, compiler_exe)}}
[conf]
{% if compiler == "clang" and compiler_version >= 19 %}
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
{% endif %}
{% if compiler == "apple-clang" and compiler_version >= 17 %}
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
{% endif %}
{% if compiler == "gcc" and compiler_version < 13 %}
tools.build:cxxflags=['-Wno-restrict']
tools.build:cxxflags+=['-Wno-restrict']
{% endif %}
[tool_requires]
!cmake/*: cmake/[>=3 <4]

View File

@@ -27,7 +27,7 @@ class Xrpl(ConanFile):
'grpc/1.50.1',
'libarchive/3.8.1',
'nudb/2.0.9',
'openssl/1.1.1w',
'openssl/3.5.4',
'soci/4.0.3',
'zlib/1.3.1',
]

View File

@@ -654,12 +654,14 @@ SharedWeakUnion<T>::convertToWeak()
break;
case destroy:
// We just added a weak ref. How could we destroy?
// LCOV_EXCL_START
UNREACHABLE(
"ripple::SharedWeakUnion::convertToWeak : destroying freshly "
"added ref");
delete p;
unsafeSetRawPtr(nullptr);
return true; // Should never happen
// LCOV_EXCL_STOP
case partialDestroy:
// This is a weird case. We just converted the last strong
// pointer to a weak pointer.

View File

@@ -94,7 +94,11 @@ hash_append(Hasher& h, beast::IP::Address const& addr) noexcept
else if (addr.is_v6())
hash_append(h, addr.to_v6().to_bytes());
else
{
// LCOV_EXCL_START
UNREACHABLE("beast::hash_append : invalid address type");
// LCOV_EXCL_STOP
}
}
} // namespace beast

View File

@@ -46,7 +46,7 @@ public:
* without formatting (not human friendly).
*
* The JSON document is written in a single line. It is not intended for 'human'
* consumption, but may be useful to support feature such as RPC where bandwith
* consumption, but may be useful to support feature such as RPC where bandwidth
* is limited. \sa Reader, Value
*/

View File

@@ -284,12 +284,14 @@ public:
{
if (key.type != ltOFFER)
{
// LCOV_EXCL_START
UNREACHABLE(
"ripple::ApplyView::dirAppend : only Offers are appended to "
"book directories");
// Only Offers are appended to book directories. Call dirInsert()
// instead
return std::nullopt;
// LCOV_EXCL_STOP
}
return dirAdd(true, directory, key.key, describe);
}

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_NODESTORE_BACKEND_H_INCLUDED
#define RIPPLE_NODESTORE_BACKEND_H_INCLUDED
#include <xrpld/nodestore/Types.h>
#include <xrpl/nodestore/Types.h>
#include <cstdint>
@@ -53,6 +53,14 @@ public:
virtual std::string
getName() = 0;
/** Get the block size for backends that support it
*/
virtual std::optional<std::size_t>
getBlockSize() const
{
return std::nullopt;
}
/** Open the backend.
@param createIfMissing Create the database files if necessary.
This allows the caller to catch exceptions.

View File

@@ -20,13 +20,12 @@
#ifndef RIPPLE_NODESTORE_DATABASE_H_INCLUDED
#define RIPPLE_NODESTORE_DATABASE_H_INCLUDED
#include <xrpld/nodestore/Backend.h>
#include <xrpld/nodestore/NodeObject.h>
#include <xrpld/nodestore/Scheduler.h>
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/TaggedCache.ipp>
#include <xrpl/nodestore/Backend.h>
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/protocol/SystemParameters.h>
#include <condition_variable>

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_NODESTORE_DATABASEROTATING_H_INCLUDED
#define RIPPLE_NODESTORE_DATABASEROTATING_H_INCLUDED
#include <xrpld/nodestore/Database.h>
#include <xrpl/nodestore/Database.h>
namespace ripple {
namespace NodeStore {

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_NODESTORE_DUMMYSCHEDULER_H_INCLUDED
#define RIPPLE_NODESTORE_DUMMYSCHEDULER_H_INCLUDED
#include <xrpld/nodestore/Scheduler.h>
#include <xrpl/nodestore/Scheduler.h>
namespace ripple {
namespace NodeStore {

View File

@@ -20,11 +20,10 @@
#ifndef RIPPLE_NODESTORE_FACTORY_H_INCLUDED
#define RIPPLE_NODESTORE_FACTORY_H_INCLUDED
#include <xrpld/nodestore/Backend.h>
#include <xrpld/nodestore/Scheduler.h>
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/nodestore/Backend.h>
#include <xrpl/nodestore/Scheduler.h>
#include <nudb/store.hpp>

View File

@@ -20,8 +20,8 @@
#ifndef RIPPLE_NODESTORE_MANAGER_H_INCLUDED
#define RIPPLE_NODESTORE_MANAGER_H_INCLUDED
#include <xrpld/nodestore/DatabaseRotating.h>
#include <xrpld/nodestore/Factory.h>
#include <xrpl/nodestore/DatabaseRotating.h>
#include <xrpl/nodestore/Factory.h>
namespace ripple {

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_NODESTORE_SCHEDULER_H_INCLUDED
#define RIPPLE_NODESTORE_SCHEDULER_H_INCLUDED
#include <xrpld/nodestore/Task.h>
#include <xrpl/nodestore/Task.h>
#include <chrono>

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_NODESTORE_TYPES_H_INCLUDED
#define RIPPLE_NODESTORE_TYPES_H_INCLUDED
#include <xrpld/nodestore/NodeObject.h>
#include <xrpl/nodestore/NodeObject.h>
#include <vector>

View File

@@ -20,9 +20,9 @@
#ifndef RIPPLE_NODESTORE_BATCHWRITER_H_INCLUDED
#define RIPPLE_NODESTORE_BATCHWRITER_H_INCLUDED
#include <xrpld/nodestore/Scheduler.h>
#include <xrpld/nodestore/Task.h>
#include <xrpld/nodestore/Types.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Task.h>
#include <xrpl/nodestore/Types.h>
#include <condition_variable>
#include <mutex>

View File

@@ -20,10 +20,9 @@
#ifndef RIPPLE_NODESTORE_DATABASENODEIMP_H_INCLUDED
#define RIPPLE_NODESTORE_DATABASENODEIMP_H_INCLUDED
#include <xrpld/nodestore/Database.h>
#include <xrpl/basics/TaggedCache.h>
#include <xrpl/basics/chrono.h>
#include <xrpl/nodestore/Database.h>
namespace ripple {
namespace NodeStore {

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_NODESTORE_DATABASEROTATINGIMP_H_INCLUDED
#define RIPPLE_NODESTORE_DATABASEROTATINGIMP_H_INCLUDED
#include <xrpld/nodestore/DatabaseRotating.h>
#include <xrpl/nodestore/DatabaseRotating.h>
#include <mutex>

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_NODESTORE_DECODEDBLOB_H_INCLUDED
#define RIPPLE_NODESTORE_DECODEDBLOB_H_INCLUDED
#include <xrpld/nodestore/NodeObject.h>
#include <xrpl/nodestore/NodeObject.h>
namespace ripple {
namespace NodeStore {

View File

@@ -20,9 +20,8 @@
#ifndef RIPPLE_NODESTORE_ENCODEDBLOB_H_INCLUDED
#define RIPPLE_NODESTORE_ENCODEDBLOB_H_INCLUDED
#include <xrpld/nodestore/NodeObject.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/nodestore/NodeObject.h>
#include <boost/align/align_up.hpp>

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_NODESTORE_MANAGERIMP_H_INCLUDED
#define RIPPLE_NODESTORE_MANAGERIMP_H_INCLUDED
#include <xrpld/nodestore/Manager.h>
#include <xrpl/nodestore/Manager.h>
namespace ripple {
@@ -39,7 +39,7 @@ public:
static void
missing_backend();
ManagerImp() = default;
ManagerImp();
~ManagerImp() = default;

View File

@@ -23,11 +23,10 @@
// Disable lz4 deprecation warning due to incompatibility with clang attributes
#define LZ4_DISABLE_DEPRECATE_WARNINGS
#include <xrpld/nodestore/NodeObject.h>
#include <xrpld/nodestore/detail/varint.h>
#include <xrpl/basics/contract.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/detail/varint.h>
#include <xrpl/protocol/HashPrefix.h>
#include <nudb/detail/field.hpp>

View File

@@ -20,6 +20,11 @@
#ifndef RIPPLE_PROTOCOL_APIVERSION_H_INCLUDED
#define RIPPLE_PROTOCOL_APIVERSION_H_INCLUDED
#include <xrpl/beast/core/SemanticVersion.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/jss.h>
#include <type_traits>
#include <utility>
@@ -72,6 +77,77 @@ static_assert(apiMaximumSupportedVersion >= apiMinimumSupportedVersion);
static_assert(apiBetaVersion >= apiMaximumSupportedVersion);
static_assert(apiMaximumValidVersion >= apiMaximumSupportedVersion);
template <class JsonObject>
void
setVersion(JsonObject& parent, unsigned int apiVersion, bool betaEnabled)
{
XRPL_ASSERT(
apiVersion != apiInvalidVersion,
"ripple::RPC::setVersion : input is valid");
auto& retObj = addObject(parent, jss::version);
if (apiVersion == apiVersionIfUnspecified)
{
// API version numbers used in API version 1
static beast::SemanticVersion const firstVersion{"1.0.0"};
static beast::SemanticVersion const goodVersion{"1.0.0"};
static beast::SemanticVersion const lastVersion{"1.0.0"};
retObj[jss::first] = firstVersion.print();
retObj[jss::good] = goodVersion.print();
retObj[jss::last] = lastVersion.print();
}
else
{
retObj[jss::first] = apiMinimumSupportedVersion.value;
retObj[jss::last] =
betaEnabled ? apiBetaVersion : apiMaximumSupportedVersion;
}
}
/**
* Retrieve the api version number from the json value
*
* Note that APIInvalidVersion will be returned if
* 1) the version number field has a wrong format
* 2) the version number retrieved is out of the supported range
* 3) the version number is unspecified and
* APIVersionIfUnspecified is out of the supported range
*
* @param jv a Json value that may or may not specifies
* the api version number
* @param betaEnabled if the beta API version is enabled
* @return the api version number
*/
inline unsigned int
getAPIVersionNumber(Json::Value const& jv, bool betaEnabled)
{
static Json::Value const minVersion(RPC::apiMinimumSupportedVersion);
Json::Value const maxVersion(
betaEnabled ? RPC::apiBetaVersion : RPC::apiMaximumSupportedVersion);
if (jv.isObject())
{
if (jv.isMember(jss::api_version))
{
auto const specifiedVersion = jv[jss::api_version];
if (!specifiedVersion.isInt() && !specifiedVersion.isUInt())
{
return RPC::apiInvalidVersion;
}
auto const specifiedVersionInt = specifiedVersion.asInt();
if (specifiedVersionInt < minVersion ||
specifiedVersionInt > maxVersion)
{
return RPC::apiInvalidVersion;
}
return specifiedVersionInt;
}
}
return RPC::apiVersionIfUnspecified;
}
} // namespace RPC
template <unsigned minVer, unsigned maxVer, typename Fn, typename... Args>

View File

@@ -55,7 +55,10 @@ std::size_t constexpr oversizeMetaDataCap = 5200;
/** The maximum number of entries per directory page */
std::size_t constexpr dirNodeMaxEntries = 32;
/** The maximum number of pages allowed in a directory */
/** The maximum number of pages allowed in a directory
Made obsolete by fixDirectoryLimit amendment.
*/
std::uint64_t constexpr dirNodeMaxPages = 262144;
/** The maximum number of items in an NFT page */

View File

@@ -21,6 +21,7 @@
#define RIPPLE_PROTOCOL_PUBLICKEY_H_INCLUDED
#include <xrpl/basics/Slice.h>
#include <xrpl/beast/net/IPEndpoint.h>
#include <xrpl/protocol/KeyType.h>
#include <xrpl/protocol/STExchange.h>
#include <xrpl/protocol/UintTypes.h>
@@ -264,6 +265,24 @@ calcNodeID(PublicKey const&);
AccountID
calcAccountID(PublicKey const& pk);
inline std::string
getFingerprint(
beast::IP::Endpoint const& address,
std::optional<PublicKey> const& publicKey = std::nullopt,
std::optional<std::string> const& id = std::nullopt)
{
std::stringstream ss;
ss << "IP Address: " << address;
if (publicKey.has_value())
{
ss << ", Public Key: " << toBase58(TokenType::NodePublic, *publicKey);
}
if (id.has_value())
{
ss << ", Id: " << id.value();
}
return ss.str();
}
} // namespace ripple
//------------------------------------------------------------------------------

View File

@@ -709,37 +709,6 @@ canAdd(STAmount const& amt1, STAmount const& amt2);
bool
canSubtract(STAmount const& amt1, STAmount const& amt2);
// Since `canonicalize` does not have access to a ledger, this is needed to put
// the low-level routine stAmountCanonicalize on an amendment switch. Only
// transactions need to use this switchover. Outside of a transaction it's safe
// to unconditionally use the new behavior.
bool
getSTAmountCanonicalizeSwitchover();
void
setSTAmountCanonicalizeSwitchover(bool v);
/** RAII class to set and restore the STAmount canonicalize switchover.
*/
class STAmountSO
{
public:
explicit STAmountSO(bool v) : saved_(getSTAmountCanonicalizeSwitchover())
{
setSTAmountCanonicalizeSwitchover(v);
}
~STAmountSO()
{
setSTAmountCanonicalizeSwitchover(saved_);
}
private:
bool saved_;
};
} // namespace ripple
//------------------------------------------------------------------------------

View File

@@ -244,6 +244,9 @@ public:
getFieldPathSet(SField const& field) const;
STVector256 const&
getFieldV256(SField const& field) const;
// If not found, returns an object constructed with the given field
STObject
getFieldObject(SField const& field) const;
STArray const&
getFieldArray(SField const& field) const;
STCurrency const&
@@ -390,6 +393,8 @@ public:
setFieldV256(SField const& field, STVector256 const& v);
void
setFieldArray(SField const& field, STArray const& v);
void
setFieldObject(SField const& field, STObject const& v);
template <class Tag>
void

View File

@@ -87,8 +87,14 @@ public:
getFullText() const override;
// Outer transaction functions / signature functions.
static Blob
getSignature(STObject const& sigObject);
Blob
getSignature() const;
getSignature() const
{
return getSignature(*this);
}
uint256
getSigningHash() const;
@@ -119,13 +125,20 @@ public:
getJson(JsonOptions options, bool binary) const;
void
sign(PublicKey const& publicKey, SecretKey const& secretKey);
sign(
PublicKey const& publicKey,
SecretKey const& secretKey,
std::optional<std::reference_wrapper<SField const>> signatureTarget =
{});
/** Check the signature.
@return `true` if valid signature. If invalid, the error message string.
*/
enum class RequireFullyCanonicalSig : bool { no, yes };
/** Check the signature.
@param requireCanonicalSig If `true`, check that the signature is fully
canonical. If `false`, only check that the signature is valid.
@param rules The current ledger rules.
@return `true` if valid signature. If invalid, the error message string.
*/
Expected<void, std::string>
checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const& rules)
const;
@@ -150,17 +163,34 @@ public:
char status,
std::string const& escapedMetaData) const;
std::vector<uint256>
std::vector<uint256> const&
getBatchTransactionIDs() const;
private:
/** Check the signature.
@param requireCanonicalSig If `true`, check that the signature is fully
canonical. If `false`, only check that the signature is valid.
@param rules The current ledger rules.
@param sigObject Reference to object that contains the signature fields.
Will be *this more often than not.
@return `true` if valid signature. If invalid, the error message string.
*/
Expected<void, std::string>
checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const;
checkSign(
RequireFullyCanonicalSig requireCanonicalSig,
Rules const& rules,
STObject const& sigObject) const;
Expected<void, std::string>
checkSingleSign(
RequireFullyCanonicalSig requireCanonicalSig,
STObject const& sigObject) const;
Expected<void, std::string>
checkMultiSign(
RequireFullyCanonicalSig requireCanonicalSig,
Rules const& rules) const;
Rules const& rules,
STObject const& sigObject) const;
Expected<void, std::string>
checkBatchSingleSign(
@@ -179,7 +209,7 @@ private:
move(std::size_t n, void* buf) override;
friend class detail::STVar;
mutable std::vector<uint256> batch_txn_ids_;
mutable std::vector<uint256> batchTxnIds_;
};
bool

View File

@@ -73,14 +73,8 @@ static constexpr std::uint32_t XRP_LEDGER_EARLIEST_SEQ{32570u};
* used in asserts and tests. */
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_FEES{562177u};
/** The minimum amount of support an amendment should have.
@note This value is used by legacy code and will become obsolete
once the fixAmendmentMajorityCalc amendment activates.
*/
constexpr std::ratio<204, 256> preFixAmendmentMajorityCalcThreshold;
constexpr std::ratio<80, 100> postFixAmendmentMajorityCalcThreshold;
/** The minimum amount of support an amendment should have. */
constexpr std::ratio<80, 100> amendmentMajorityCalcThreshold;
/** The minimum amount of time an amendment must hold a majority */
constexpr std::chrono::seconds const defaultAmendmentMajorityTime = weeks{2};

View File

@@ -228,6 +228,7 @@ enum TERcodes : TERUnderlyingType {
terNO_AMM, // AMM doesn't exist for the asset pair
terADDRESS_COLLISION, // Failed to allocate AccountID when trying to
// create a pseudo-account
terNO_DELEGATE_PERMISSION, // Delegate does not have permission
};
//------------------------------------------------------------------------------
@@ -362,6 +363,9 @@ enum TECcodes : TERUnderlyingType {
tecLIMIT_EXCEEDED = 195,
tecPSEUDO_ACCOUNT = 196,
tecPRECISION_LOSS = 197,
// DEPRECATED: This error code tecNO_DELEGATE_PERMISSION is reserved for
// backward compatibility with historical data on non-prod networks, can be
// reclaimed after those networks reset.
tecNO_DELEGATE_PERMISSION = 198,
tecBAD_PROOF = 199
};

View File

@@ -33,51 +33,35 @@ namespace ripple {
class TxMeta
{
private:
struct CtorHelper
{
explicit CtorHelper() = default;
};
template <class T>
TxMeta(
uint256 const& txID,
std::uint32_t ledger,
T const& data,
CtorHelper);
public:
TxMeta(
uint256 const& transactionID,
std::uint32_t ledger,
std::optional<uint256> parentBatchId = std::nullopt);
TxMeta(uint256 const& transactionID, std::uint32_t ledger);
TxMeta(uint256 const& txID, std::uint32_t ledger, Blob const&);
TxMeta(uint256 const& txID, std::uint32_t ledger, std::string const&);
TxMeta(uint256 const& txID, std::uint32_t ledger, STObject const&);
uint256 const&
getTxID() const
{
return mTransactionID;
return transactionID_;
}
std::uint32_t
getLgrSeq() const
{
return mLedger;
return ledgerSeq_;
}
int
getResult() const
{
return mResult;
return result_;
}
TER
getResultTER() const
{
return TER::fromInt(mResult);
return TER::fromInt(result_);
}
std::uint32_t
getIndex() const
{
return mIndex;
return index_;
}
void
@@ -104,66 +88,52 @@ public:
STArray&
getNodes()
{
return (mNodes);
return nodes_;
}
STArray const&
getNodes() const
{
return (mNodes);
return nodes_;
}
void
setDeliveredAmount(STAmount const& delivered)
setAdditionalFields(STObject const& obj)
{
mDelivered = delivered;
if (obj.isFieldPresent(sfDeliveredAmount))
deliveredAmount_ = obj.getFieldAmount(sfDeliveredAmount);
if (obj.isFieldPresent(sfParentBatchID))
parentBatchID_ = obj.getFieldH256(sfParentBatchID);
}
STAmount
std::optional<STAmount> const&
getDeliveredAmount() const
{
XRPL_ASSERT(
hasDeliveredAmount(),
"ripple::TxMeta::getDeliveredAmount : non-null delivered amount");
return *mDelivered;
}
bool
hasDeliveredAmount() const
{
return static_cast<bool>(mDelivered);
return deliveredAmount_;
}
void
setParentBatchId(uint256 const& parentBatchId)
setDeliveredAmount(std::optional<STAmount> const& amount)
{
mParentBatchId = parentBatchId;
deliveredAmount_ = amount;
}
uint256
getParentBatchId() const
void
setParentBatchID(std::optional<uint256> const& id)
{
XRPL_ASSERT(
hasParentBatchId(),
"ripple::TxMeta::getParentBatchId : non-null batch id");
return *mParentBatchId;
}
bool
hasParentBatchId() const
{
return static_cast<bool>(mParentBatchId);
parentBatchID_ = id;
}
private:
uint256 mTransactionID;
std::uint32_t mLedger;
std::uint32_t mIndex;
int mResult;
uint256 transactionID_;
std::uint32_t ledgerSeq_;
std::uint32_t index_;
int result_;
std::optional<STAmount> mDelivered;
std::optional<uint256> mParentBatchId;
std::optional<STAmount> deliveredAmount_;
std::optional<uint256> parentBatchID_;
STArray mNodes;
STArray nodes_;
};
} // namespace ripple

View File

@@ -129,10 +129,12 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
{
// should never happen, but if it does then it seems natural to define
// the a null set of numbers to be zero, so the remainder is also zero.
// LCOV_EXCL_START
UNREACHABLE(
"ripple::b58_fast::detail::inplace_bigint_div_rem : empty "
"numerator");
return 0;
// LCOV_EXCL_STOP
}
auto to_u128 = [](std::uint64_t high,

View File

@@ -29,16 +29,15 @@
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
// If you add an amendment here, then do not forget to increment `numFeatures`
// in include/xrpl/protocol/Feature.h.
XRPL_FEATURE(ConfidentialTransfer, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegationV1_1, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (DirectoryLimit, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (IncludeKeyletFields, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DynamicMPT, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (TokenEscrowV1, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (DelegateV1_1, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (PriceOracleOrder, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (MPTDeliveredAmount, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (MPTDeliveredAmount, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMClawbackRounding, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(TokenEscrow, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (EnforceNFTokenTrustlineV2, Supported::yes, VoteBehavior::DefaultNo)
@@ -46,7 +45,6 @@ XRPL_FIX (AMMv1_3, Supported::yes, VoteBehavior::DefaultNo
XRPL_FEATURE(PermissionedDEX, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Batch, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(SingleAssetVault, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegation, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo)
// Check flags in Credential transactions
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultNo)
@@ -80,45 +78,24 @@ XRPL_FIX (DisallowIncomingV1, Supported::yes, VoteBehavior::DefaultNo
XRPL_FEATURE(XChainBridge, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(AMM, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Clawback, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (ReducedOffersV1, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (NFTokenRemint, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (NonFungibleTokensV1_2, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (UniversalNumber, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(XRPFees, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DisallowIncoming, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(ImmediateOfferKilled, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (RemoveNFTokenAutoTrustLine, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (TrustLinesToSelf, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(NonFungibleTokensV1_1, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(ExpandedSignerList, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(CheckCashMakesTrustLine, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (RmSmallIncreasedQOffers, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (STAmountCanonicalize, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(FlowSortStrands, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(TicketBatch, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(NegativeUNL, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (AmendmentMajorityCalc, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(HardenedValidations, Supported::yes, VoteBehavior::DefaultYes)
// fix1781: XRPEndpointSteps should be included in the circular payment check
XRPL_FIX (1781, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(RequireFullyCanonicalSig, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (QualityUpperBound, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(DeletableAccounts, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (PayChanRecipientOwnerDir, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (CheckThreading, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (MasterKeyAsRegularKey, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (TakerDryOfferRemoval, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(MultiSignReserve, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (1578, Supported::yes, VoteBehavior::DefaultYes)
// fix1515: Use liquidity from strands that consume max offers, but mark as dry
XRPL_FIX (1515, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(DepositPreauth, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (1623, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (1543, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (1571, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(Checks, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(DepositAuth, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (1513, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(Flow, Supported::yes, VoteBehavior::DefaultYes)
// The following amendments are obsolete, but must remain supported
@@ -132,28 +109,46 @@ XRPL_FEATURE(Flow, Supported::yes, VoteBehavior::DefaultYe
//
// If a feature remains obsolete for long enough that no clients are able
// to vote for it, the feature can be removed (entirely?) from the code.
XRPL_FIX (NFTokenNegOffer, Supported::yes, VoteBehavior::Obsolete)
XRPL_FIX (NFTokenDirV1, Supported::yes, VoteBehavior::Obsolete)
XRPL_FEATURE(NonFungibleTokensV1, Supported::yes, VoteBehavior::Obsolete)
XRPL_FEATURE(CryptoConditionsSuite, Supported::yes, VoteBehavior::Obsolete)
// The following amendments have been active for at least two years. Their
// pre-amendment code has been removed and the identifiers are deprecated.
// All known amendments and amendments that may appear in a validated
// ledger must be registered either here or above with the "active" amendments
XRPL_RETIRE(MultiSign)
XRPL_RETIRE(TrustSetAuth)
XRPL_RETIRE(FeeEscalation)
XRPL_RETIRE(PayChan)
XRPL_RETIRE(CryptoConditions)
XRPL_RETIRE(TickSize)
XRPL_RETIRE(fix1368)
XRPL_RETIRE(Escrow)
XRPL_RETIRE(fix1373)
XRPL_RETIRE(EnforceInvariants)
XRPL_RETIRE(SortedDirectories)
// All known amendments and amendments that may appear in a validated ledger
// must be registered either here or above with the "active" amendments
//
// Please keep this list sorted alphabetically for convenience.
XRPL_RETIRE(fix1201)
XRPL_RETIRE(fix1368)
XRPL_RETIRE(fix1373)
XRPL_RETIRE(fix1512)
XRPL_RETIRE(fix1513)
XRPL_RETIRE(fix1515)
XRPL_RETIRE(fix1523)
XRPL_RETIRE(fix1528)
XRPL_RETIRE(fix1543)
XRPL_RETIRE(fix1571)
XRPL_RETIRE(fix1578)
XRPL_RETIRE(fix1623)
XRPL_RETIRE(fix1781)
XRPL_RETIRE(fixAmendmentMajorityCalc)
XRPL_RETIRE(fixCheckThreading)
XRPL_RETIRE(fixNonFungibleTokensV1_2)
XRPL_RETIRE(fixNFTokenRemint)
XRPL_RETIRE(fixMasterKeyAsRegularKey)
XRPL_RETIRE(fixQualityUpperBound)
XRPL_RETIRE(fixReducedOffersV1)
XRPL_RETIRE(fixRmSmallIncreasedQOffers)
XRPL_RETIRE(fixSTAmountCanonicalize)
XRPL_RETIRE(fixTakerDryOfferRemoval)
XRPL_RETIRE(CryptoConditions)
XRPL_RETIRE(Escrow)
XRPL_RETIRE(EnforceInvariants)
XRPL_RETIRE(FeeEscalation)
XRPL_RETIRE(FlowCross)
XRPL_RETIRE(ImmediateOfferKilled)
XRPL_RETIRE(MultiSign)
XRPL_RETIRE(NonFungibleTokensV1_1)
XRPL_RETIRE(PayChan)
XRPL_RETIRE(SortedDirectories)
XRPL_RETIRE(TickSize)
XRPL_RETIRE(TrustSetAuth)

View File

@@ -464,7 +464,7 @@ LEDGER_ENTRY(ltCREDENTIAL, 0x0081, Credential, credential, ({
{sfExpiration, soeOPTIONAL},
{sfURI, soeOPTIONAL},
{sfIssuerNode, soeREQUIRED},
{sfSubjectNode, soeREQUIRED},
{sfSubjectNode, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))

View File

@@ -316,7 +316,7 @@ TRANSACTION(ttTRUST_SET, 20, TrustSet,
#endif
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
Delegation::notDelegatable,
uint256{},
featureDeletableAccounts,
mustDeleteAcct,
({
{sfDestination, soeREQUIRED},
@@ -332,7 +332,7 @@ TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
#endif
TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint,
Delegation::delegatable,
featureNonFungibleTokensV1,
uint256{},
changeNFTCounts,
({
{sfNFTokenTaxon, soeREQUIRED},
@@ -350,7 +350,7 @@ TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint,
#endif
TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn,
Delegation::delegatable,
featureNonFungibleTokensV1,
uint256{},
changeNFTCounts,
({
{sfNFTokenID, soeREQUIRED},
@@ -363,7 +363,7 @@ TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn,
#endif
TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer,
Delegation::delegatable,
featureNonFungibleTokensV1,
uint256{},
noPriv,
({
{sfNFTokenID, soeREQUIRED},
@@ -379,7 +379,7 @@ TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer,
#endif
TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer,
Delegation::delegatable,
featureNonFungibleTokensV1,
uint256{},
noPriv,
({
{sfNFTokenOffers, soeREQUIRED},
@@ -391,7 +391,7 @@ TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer,
#endif
TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer,
Delegation::delegatable,
featureNonFungibleTokensV1,
uint256{},
noPriv,
({
{sfNFTokenBuyOffer, soeOPTIONAL},
@@ -838,7 +838,7 @@ TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete,
#endif
TRANSACTION(ttDELEGATE_SET, 64, DelegateSet,
Delegation::notDelegatable,
featurePermissionDelegation,
featurePermissionDelegationV1_1,
noPriv,
({
{sfAuthorize, soeREQUIRED},
@@ -852,7 +852,7 @@ TRANSACTION(ttDELEGATE_SET, 64, DelegateSet,
TRANSACTION(ttVAULT_CREATE, 65, VaultCreate,
Delegation::delegatable,
featureSingleAssetVault,
createPseudoAcct | createMPTIssuance,
createPseudoAcct | createMPTIssuance | mustModifyVault,
({
{sfAsset, soeREQUIRED, soeMPTSupported},
{sfAssetsMaximum, soeOPTIONAL},
@@ -870,7 +870,7 @@ TRANSACTION(ttVAULT_CREATE, 65, VaultCreate,
TRANSACTION(ttVAULT_SET, 66, VaultSet,
Delegation::delegatable,
featureSingleAssetVault,
noPriv,
mustModifyVault,
({
{sfVaultID, soeREQUIRED},
{sfAssetsMaximum, soeOPTIONAL},
@@ -885,7 +885,7 @@ TRANSACTION(ttVAULT_SET, 66, VaultSet,
TRANSACTION(ttVAULT_DELETE, 67, VaultDelete,
Delegation::delegatable,
featureSingleAssetVault,
mustDeleteAcct | destroyMPTIssuance,
mustDeleteAcct | destroyMPTIssuance | mustModifyVault,
({
{sfVaultID, soeREQUIRED},
}))
@@ -897,7 +897,7 @@ TRANSACTION(ttVAULT_DELETE, 67, VaultDelete,
TRANSACTION(ttVAULT_DEPOSIT, 68, VaultDeposit,
Delegation::delegatable,
featureSingleAssetVault,
mayAuthorizeMPT,
mayAuthorizeMPT | mustModifyVault,
({
{sfVaultID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
@@ -910,7 +910,7 @@ TRANSACTION(ttVAULT_DEPOSIT, 68, VaultDeposit,
TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw,
Delegation::delegatable,
featureSingleAssetVault,
mayDeleteMPT,
mayDeleteMPT | mayAuthorizeMPT | mustModifyVault,
({
{sfVaultID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
@@ -925,7 +925,7 @@ TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw,
TRANSACTION(ttVAULT_CLAWBACK, 70, VaultClawback,
Delegation::delegatable,
featureSingleAssetVault,
mayDeleteMPT,
mayDeleteMPT | mustModifyVault,
({
{sfVaultID, soeREQUIRED},
{sfHolder, soeREQUIRED},

View File

@@ -569,6 +569,7 @@ JSS(settle_delay); // out: AccountChannels
JSS(severity); // in: LogLevel
JSS(shares); // out: VaultInfo
JSS(signature); // out: NetworkOPs, ChannelAuthorize
JSS(signature_target); // in: TransactionSign
JSS(signature_verified); // out: ChannelVerify
JSS(signing_key); // out: NetworkOPs
JSS(signing_keys); // out: ValidatorList

View File

@@ -21,6 +21,7 @@
#define RIPPLE_RESOURCE_CONSUMER_H_INCLUDED
#include <xrpl/basics/Log.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/resource/Charge.h>
#include <xrpl/resource/Disposition.h>
@@ -87,6 +88,9 @@ public:
Entry&
entry();
void
setPublicKey(PublicKey const& publicKey);
private:
Logic* m_logic;
Entry* m_entry;

View File

@@ -53,7 +53,7 @@ struct Entry : public beast::List<Entry>::Node
std::string
to_string() const
{
return key->address.to_string();
return getFingerprint(key->address, publicKey);
}
/**
@@ -82,6 +82,9 @@ struct Entry : public beast::List<Entry>::Node
return local_balance.add(charge, now) + remote_balance;
}
// The public key of the peer
std::optional<PublicKey> publicKey;
// Back pointer to the map key (bit of a hack here)
Key const* key;

View File

@@ -436,10 +436,12 @@ public:
admin_.erase(admin_.iterator_to(entry));
break;
default:
// LCOV_EXCL_START
UNREACHABLE(
"ripple::Resource::Logic::release : invalid entry "
"kind");
break;
// LCOV_EXCL_STOP
}
inactive_.push_back(entry);
entry.whenExpires = m_clock.now() + secondsUntilExpiration;

View File

@@ -20,11 +20,10 @@
#ifndef RIPPLE_SHAMAP_FAMILY_H_INCLUDED
#define RIPPLE_SHAMAP_FAMILY_H_INCLUDED
#include <xrpld/nodestore/Database.h>
#include <xrpld/shamap/FullBelowCache.h>
#include <xrpld/shamap/TreeNodeCache.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/nodestore/Database.h>
#include <xrpl/shamap/FullBelowCache.h>
#include <xrpl/shamap/TreeNodeCache.h>
#include <cstdint>

View File

@@ -20,21 +20,19 @@
#ifndef RIPPLE_SHAMAP_SHAMAP_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAP_H_INCLUDED
#include <xrpld/nodestore/Database.h>
#include <xrpld/nodestore/NodeObject.h>
#include <xrpld/shamap/Family.h>
#include <xrpld/shamap/SHAMapAddNode.h>
#include <xrpld/shamap/SHAMapInnerNode.h>
#include <xrpld/shamap/SHAMapItem.h>
#include <xrpld/shamap/SHAMapLeafNode.h>
#include <xrpld/shamap/SHAMapMissingNode.h>
#include <xrpld/shamap/SHAMapTreeNode.h>
#include <xrpld/shamap/TreeNodeCache.h>
#include <xrpl/basics/IntrusivePointer.h>
#include <xrpl/basics/UnorderedContainers.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/nodestore/Database.h>
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/shamap/Family.h>
#include <xrpl/shamap/SHAMapAddNode.h>
#include <xrpl/shamap/SHAMapInnerNode.h>
#include <xrpl/shamap/SHAMapItem.h>
#include <xrpl/shamap/SHAMapLeafNode.h>
#include <xrpl/shamap/SHAMapMissingNode.h>
#include <xrpl/shamap/SHAMapTreeNode.h>
#include <set>
#include <stack>

View File

@@ -20,12 +20,11 @@
#ifndef RIPPLE_SHAMAP_SHAMAPACCOUNTSTATELEAFNODE_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPACCOUNTSTATELEAFNODE_H_INCLUDED
#include <xrpld/shamap/SHAMapItem.h>
#include <xrpld/shamap/SHAMapLeafNode.h>
#include <xrpl/basics/CountedObject.h>
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/shamap/SHAMapItem.h>
#include <xrpl/shamap/SHAMapLeafNode.h>
namespace ripple {

View File

@@ -20,10 +20,9 @@
#ifndef RIPPLE_SHAMAP_SHAMAPINNERNODE_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPINNERNODE_H_INCLUDED
#include <xrpld/shamap/SHAMapNodeID.h>
#include <xrpld/shamap/detail/TaggedPointer.h>
#include <xrpl/basics/IntrusivePointer.h>
#include <xrpl/shamap/SHAMapNodeID.h>
#include <xrpl/shamap/detail/TaggedPointer.h>
#include <atomic>
#include <cstdint>

View File

@@ -20,8 +20,8 @@
#ifndef RIPPLE_SHAMAP_SHAMAPLEAFNODE_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPLEAFNODE_H_INCLUDED
#include <xrpld/shamap/SHAMapItem.h>
#include <xrpld/shamap/SHAMapTreeNode.h>
#include <xrpl/shamap/SHAMapItem.h>
#include <xrpl/shamap/SHAMapTreeNode.h>
#include <cstdint>

View File

@@ -20,9 +20,8 @@
#ifndef RIPPLE_SHAMAP_SHAMAPMISSINGNODE_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPMISSINGNODE_H_INCLUDED
#include <xrpld/shamap/SHAMapTreeNode.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/shamap/SHAMapTreeNode.h>
#include <iosfwd>
#include <stdexcept>

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_SHAMAP_SHAMAPSYNCFILTER_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPSYNCFILTER_H_INCLUDED
#include <xrpld/shamap/SHAMapTreeNode.h>
#include <xrpl/shamap/SHAMapTreeNode.h>
#include <optional>

View File

@@ -20,13 +20,12 @@
#ifndef RIPPLE_SHAMAP_SHAMAPTREENODE_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPTREENODE_H_INCLUDED
#include <xrpld/shamap/SHAMapItem.h>
#include <xrpld/shamap/SHAMapNodeID.h>
#include <xrpl/basics/IntrusivePointer.h>
#include <xrpl/basics/IntrusiveRefCounts.h>
#include <xrpl/basics/SHAMapHash.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/shamap/SHAMapItem.h>
#include <xrpl/shamap/SHAMapNodeID.h>
#include <cstdint>
#include <string>

View File

@@ -20,12 +20,11 @@
#ifndef RIPPLE_SHAMAP_SHAMAPTXLEAFNODE_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPTXLEAFNODE_H_INCLUDED
#include <xrpld/shamap/SHAMapItem.h>
#include <xrpld/shamap/SHAMapLeafNode.h>
#include <xrpl/basics/CountedObject.h>
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/shamap/SHAMapItem.h>
#include <xrpl/shamap/SHAMapLeafNode.h>
namespace ripple {

View File

@@ -20,12 +20,11 @@
#ifndef RIPPLE_SHAMAP_SHAMAPLEAFTXPLUSMETANODE_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPLEAFTXPLUSMETANODE_H_INCLUDED
#include <xrpld/shamap/SHAMapItem.h>
#include <xrpld/shamap/SHAMapLeafNode.h>
#include <xrpl/basics/CountedObject.h>
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/shamap/SHAMapItem.h>
#include <xrpl/shamap/SHAMapLeafNode.h>
namespace ripple {

View File

@@ -20,10 +20,9 @@
#ifndef RIPPLE_SHAMAP_TREENODECACHE_H_INCLUDED
#define RIPPLE_SHAMAP_TREENODECACHE_H_INCLUDED
#include <xrpld/shamap/SHAMapTreeNode.h>
#include <xrpl/basics/IntrusivePointer.h>
#include <xrpl/basics/TaggedCache.h>
#include <xrpl/shamap/SHAMapTreeNode.h>
namespace ripple {

View File

@@ -20,9 +20,8 @@
#ifndef RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED
#define RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED
#include <xrpld/shamap/SHAMapTreeNode.h>
#include <xrpl/basics/IntrusivePointer.h>
#include <xrpl/shamap/SHAMapTreeNode.h>
#include <array>
#include <cstdint>

View File

@@ -17,10 +17,9 @@
*/
//==============================================================================
#include <xrpld/shamap/SHAMapInnerNode.h>
#include <xrpld/shamap/detail/TaggedPointer.h>
#include <xrpl/basics/ByteUtilities.h>
#include <xrpl/shamap/SHAMapInnerNode.h>
#include <xrpl/shamap/detail/TaggedPointer.h>
#include <boost/pool/pool_alloc.hpp>

View File

@@ -239,9 +239,11 @@ Logs::fromSeverity(beast::severities::Severity level)
case kError:
return lsERROR;
// LCOV_EXCL_START
default:
UNREACHABLE("ripple::Logs::fromSeverity : invalid severity");
[[fallthrough]];
// LCOV_EXCL_STOP
case kFatal:
break;
}
@@ -265,9 +267,11 @@ Logs::toSeverity(LogSeverity level)
return kWarning;
case lsERROR:
return kError;
// LCOV_EXCL_START
default:
UNREACHABLE("ripple::Logs::toSeverity : invalid severity");
[[fallthrough]];
// LCOV_EXCL_STOP
case lsFATAL:
break;
}
@@ -292,9 +296,11 @@ Logs::toString(LogSeverity s)
return "Error";
case lsFATAL:
return "Fatal";
// LCOV_EXCL_START
default:
UNREACHABLE("ripple::Logs::toString : invalid severity");
return "Unknown";
// LCOV_EXCL_STOP
}
}
@@ -356,9 +362,11 @@ Logs::format(
case kError:
output += "ERR ";
break;
// LCOV_EXCL_START
default:
UNREACHABLE("ripple::Logs::format : invalid severity");
[[fallthrough]];
// LCOV_EXCL_STOP
case kFatal:
output += "FTL ";
break;

View File

@@ -36,6 +36,7 @@ LogThrow(std::string const& title)
[[noreturn]] void
LogicError(std::string const& s) noexcept
{
// LCOV_EXCL_START
JLOG(debugLog().fatal()) << s;
std::cerr << "Logic error: " << s << std::endl;
// Use a non-standard contract naming here (without namespace) because
@@ -45,6 +46,7 @@ LogicError(std::string const& s) noexcept
// For the above reasons, we want this contract to stand out.
UNREACHABLE("LogicError", {{"message", s}});
std::abort();
// LCOV_EXCL_STOP
}
} // namespace ripple

View File

@@ -174,7 +174,7 @@ Array::append(Json::Value const& v)
return;
}
}
UNREACHABLE("Json::Array::append : invalid type");
UNREACHABLE("Json::Array::append : invalid type"); // LCOV_EXCL_LINE
}
void
@@ -209,7 +209,7 @@ Object::set(std::string const& k, Json::Value const& v)
return;
}
}
UNREACHABLE("Json::Object::set : invalid type");
UNREACHABLE("Json::Object::set : invalid type"); // LCOV_EXCL_LINE
}
//------------------------------------------------------------------------------

View File

@@ -213,8 +213,10 @@ Value::Value(ValueType type) : type_(type), allocated_(0)
value_.bool_ = false;
break;
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::Value(ValueType) : invalid type");
// LCOV_EXCL_STOP
}
}
@@ -290,8 +292,10 @@ Value::Value(Value const& other) : type_(other.type_)
value_.map_ = new ObjectValues(*other.value_.map_);
break;
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::Value(Value const&) : invalid type");
// LCOV_EXCL_STOP
}
}
@@ -318,8 +322,10 @@ Value::~Value()
delete value_.map_;
break;
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::~Value : invalid type");
// LCOV_EXCL_STOP
}
}
@@ -419,8 +425,10 @@ operator<(Value const& x, Value const& y)
return *x.value_.map_ < *y.value_.map_;
}
// LCOV_EXCL_START
default:
UNREACHABLE("Json::operator<(Value, Value) : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable
@@ -465,8 +473,10 @@ operator==(Value const& x, Value const& y)
return x.value_.map_->size() == y.value_.map_->size() &&
*x.value_.map_ == *y.value_.map_;
// LCOV_EXCL_START
default:
UNREACHABLE("Json::operator==(Value, Value) : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable
@@ -506,8 +516,10 @@ Value::asString() const
case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::asString : invalid type");
// LCOV_EXCL_STOP
}
return ""; // unreachable
@@ -548,8 +560,10 @@ Value::asInt() const
case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::asInt : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable;
@@ -590,8 +604,10 @@ Value::asUInt() const
case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::asUInt : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable;
@@ -622,8 +638,10 @@ Value::asDouble() const
case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::asDouble : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable;
@@ -654,8 +672,10 @@ Value::asBool() const
case objectValue:
return value_.map_->size() != 0;
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::asBool : invalid type");
// LCOV_EXCL_STOP
}
return false; // unreachable;
@@ -710,8 +730,10 @@ Value::isConvertibleTo(ValueType other) const
return other == objectValue ||
(other == nullValue && value_.map_->size() == 0);
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::isConvertible : invalid type");
// LCOV_EXCL_STOP
}
return false; // unreachable;
@@ -744,8 +766,10 @@ Value::size() const
case objectValue:
return Int(value_.map_->size());
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::size : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable;

View File

@@ -126,10 +126,10 @@ ApplyStateTable::apply(
std::optional<TxMeta> metadata;
if (!to.open() || isDryRun)
{
TxMeta meta(tx.getTransactionID(), to.seq(), parentBatchId);
TxMeta meta(tx.getTransactionID(), to.seq());
if (deliver)
meta.setDeliveredAmount(*deliver);
meta.setDeliveredAmount(deliver);
meta.setParentBatchID(parentBatchId);
Mods newMod;
for (auto& item : items_)
@@ -259,9 +259,11 @@ ApplyStateTable::apply(
}
else
{
// LCOV_EXCL_START
UNREACHABLE(
"ripple::detail::ApplyStateTable::apply : unsupported "
"operation type");
// LCOV_EXCL_STOP
}
}
@@ -680,12 +682,6 @@ ApplyStateTable::threadOwners(
if (auto const optSleAcct{(*sle)[~sfAccount]})
threadTx(base, meta, *optSleAcct, mods, j);
// Don't thread a check's sfDestination unless the amendment is
// enabled
if (ledgerType == ltCHECK &&
!base.rules().enabled(fixCheckThreading))
break;
// If sfDestination is present, thread to that account
if (auto const optSleDest{(*sle)[~sfDestination]})
threadTx(base, meta, *optSleDest, mods, j);

View File

@@ -22,6 +22,9 @@
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/protocol/Protocol.h>
#include <limits>
#include <type_traits>
namespace ripple {
std::optional<std::uint64_t>
@@ -91,8 +94,21 @@ ApplyView::dirAdd(
return page;
}
// We rely on modulo arithmetic of unsigned integers (guaranteed in
// [basic.fundamental] paragraph 2) to detect page representation overflow.
// For signed integers this would be UB, hence static_assert here.
static_assert(std::is_unsigned_v<decltype(page)>);
// Defensive check against breaking changes in compiler.
static_assert([]<typename T>(std::type_identity<T>) constexpr -> T {
T tmp = std::numeric_limits<T>::max();
return ++tmp;
}(std::type_identity<decltype(page)>{}) == 0);
++page;
// Check whether we're out of pages.
if (++page >= dirNodeMaxPages)
if (page == 0)
return std::nullopt;
if (!rules().enabled(fixDirectoryLimit) &&
page >= dirNodeMaxPages) // Old pages limit
return std::nullopt;
// We are about to create a new node; we'll link it to
@@ -133,8 +149,10 @@ ApplyView::emptyDirDelete(Keylet const& directory)
if (directory.type != ltDIR_NODE ||
node->getFieldH256(sfRootIndex) != directory.key)
{
// LCOV_EXCL_START
UNREACHABLE("ripple::ApplyView::emptyDirDelete : invalid node type");
return false;
// LCOV_EXCL_STOP
}
// The directory still contains entries and so it cannot be removed

View File

@@ -36,7 +36,9 @@ BookDirs::BookDirs(ReadView const& view, Book const& book)
{
if (!cdirFirst(*view_, key_, sle_, entry_, index_))
{
// LCOV_EXCL_START
UNREACHABLE("ripple::BookDirs::BookDirs : directory is empty");
// LCOV_EXCL_STOP
}
}
}
@@ -110,9 +112,11 @@ BookDirs::const_iterator::operator++()
}
else if (!cdirFirst(*view_, cur_key_, sle_, entry_, index_))
{
// LCOV_EXCL_START
UNREACHABLE(
"ripple::BookDirs::const_iterator::operator++ : directory is "
"empty");
// LCOV_EXCL_STOP
}
}

View File

@@ -77,19 +77,23 @@ deleteSLE(
AccountID const& account, SField const& node, bool isOwner) -> TER {
auto const sleAccount = view.peek(keylet::account(account));
if (!sleAccount)
{ // LCOV_EXCL_START
{
// LCOV_EXCL_START
JLOG(j.fatal()) << "Internal error: can't retrieve Owner account.";
return tecINTERNAL;
} // LCOV_EXCL_STOP
// LCOV_EXCL_STOP
}
// Remove object from owner directory
std::uint64_t const page = sleCredential->getFieldU64(node);
if (!view.dirRemove(
keylet::ownerDir(account), page, sleCredential->key(), false))
{ // LCOV_EXCL_START
{
// LCOV_EXCL_START
JLOG(j.fatal()) << "Unable to delete Credential from owner.";
return tefBAD_LEDGER;
} // LCOV_EXCL_STOP
// LCOV_EXCL_STOP
}
if (isOwner)
adjustOwnerCount(view, sleAccount, -1, j);

View File

@@ -324,10 +324,12 @@ isVaultPseudoAccountFrozen(
auto const issuer = mptIssuance->getAccountID(sfIssuer);
auto const mptIssuer = view.read(keylet::account(issuer));
if (mptIssuer == nullptr)
{ // LCOV_EXCL_START
{
// LCOV_EXCL_START
UNREACHABLE("ripple::isVaultPseudoAccountFrozen : null MPToken issuer");
return false;
} // LCOV_EXCL_STOP
// LCOV_EXCL_STOP
}
if (!mptIssuer->isFieldPresent(sfVaultID))
return false; // not a Vault pseudo-account, common case
@@ -338,7 +340,8 @@ isVaultPseudoAccountFrozen(
{ // LCOV_EXCL_START
UNREACHABLE("ripple::isVaultPseudoAccountFrozen : null vault");
return false;
} // LCOV_EXCL_STOP
// LCOV_EXCL_STOP
}
return isAnyFrozen(view, {issuer, account}, vault->at(sfAsset), depth + 1);
}
@@ -1132,7 +1135,7 @@ createPseudoAccount(
uint256 const& pseudoOwnerKey,
SField const& ownerField)
{
auto const& fields = getPseudoAccountFields();
[[maybe_unused]] auto const& fields = getPseudoAccountFields();
XRPL_ASSERT(
std::count_if(
fields.begin(),
@@ -1240,6 +1243,12 @@ addEmptyHolding(
// If the line already exists, don't create it again.
if (view.read(index))
return tecDUPLICATE;
// Can the account cover the trust line reserve ?
std::uint32_t const ownerCount = sleDst->at(sfOwnerCount);
if (priorBalance < view.fees().accountReserve(ownerCount + 1))
return tecNO_LINE_INSUF_RESERVE;
return trustCreate(
view,
high,
@@ -1290,7 +1299,7 @@ authorizeMPToken(
{
auto const sleAcct = view.peek(keylet::account(account));
if (!sleAcct)
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
// If the account that submitted the tx is a holder
// Note: `account_` is holder's account
@@ -1355,17 +1364,17 @@ authorizeMPToken(
auto const sleMptIssuance = view.read(keylet::mptIssuance(mptIssuanceID));
if (!sleMptIssuance)
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
// If the account that submitted this tx is the issuer of the MPT
// Note: `account_` is issuer's account
// `holderID` is holder's account
if (account != (*sleMptIssuance)[sfIssuer])
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
auto const sleMpt = view.peek(keylet::mptoken(mptIssuanceID, *holderID));
if (!sleMpt)
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
std::uint32_t const flagsIn = sleMpt->getFieldU32(sfFlags);
std::uint32_t flagsOut = flagsIn;
@@ -1422,7 +1431,7 @@ trustCreate(
describeOwnerDir(uLowAccountID));
if (!lowNode)
return tecDIR_FULL;
return tecDIR_FULL; // LCOV_EXCL_LINE
auto highNode = view.dirInsert(
keylet::ownerDir(uHighAccountID),
@@ -1430,14 +1439,14 @@ trustCreate(
describeOwnerDir(uHighAccountID));
if (!highNode)
return tecDIR_FULL;
return tecDIR_FULL; // LCOV_EXCL_LINE
bool const bSetDst = saLimit.getIssuer() == uDstAccountID;
bool const bSetHigh = bSrcHigh ^ bSetDst;
XRPL_ASSERT(sleAccount, "ripple::trustCreate : non-null SLE");
if (!sleAccount)
return tefINTERNAL;
return tefINTERNAL; // LCOV_EXCL_LINE
XRPL_ASSERT(
sleAccount->getAccountID(sfAccount) ==
@@ -1516,10 +1525,12 @@ removeEmptyHolding(
{
auto const sle = view.read(keylet::account(accountID));
if (!sle)
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
auto const balance = sle->getFieldAmount(sfBalance);
if (balance.xrp() != 0)
return tecHAS_OBLIGATIONS;
return tesSUCCESS;
}
@@ -1537,7 +1548,8 @@ removeEmptyHolding(
auto sleLowAccount =
view.peek(keylet::account(line->at(sfLowLimit)->getIssuer()));
if (!sleLowAccount)
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
adjustOwnerCount(view, sleLowAccount, -1, journal);
// It's not really necessary to clear the reserve flag, since the line
// is about to be deleted, but this will make the metadata reflect an
@@ -1551,7 +1563,8 @@ removeEmptyHolding(
auto sleHighAccount =
view.peek(keylet::account(line->at(sfHighLimit)->getIssuer()));
if (!sleHighAccount)
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
adjustOwnerCount(view, sleHighAccount, -1, journal);
// It's not really necessary to clear the reserve flag, since the line
// is about to be deleted, but this will make the metadata reflect an
@@ -1611,7 +1624,7 @@ trustDelete(
sleRippleState->key(),
false))
{
return tefBAD_LEDGER;
return tefBAD_LEDGER; // LCOV_EXCL_LINE
}
JLOG(j.trace()) << "trustDelete: Deleting ripple line: high";
@@ -1622,7 +1635,7 @@ trustDelete(
sleRippleState->key(),
false))
{
return tefBAD_LEDGER;
return tefBAD_LEDGER; // LCOV_EXCL_LINE
}
JLOG(j.trace()) << "trustDelete: Deleting ripple line: state";
@@ -1648,7 +1661,7 @@ offerDelete(ApplyView& view, std::shared_ptr<SLE> const& sle, beast::Journal j)
offerIndex,
false))
{
return tefBAD_LEDGER;
return tefBAD_LEDGER; // LCOV_EXCL_LINE
}
if (!view.dirRemove(
@@ -1657,7 +1670,7 @@ offerDelete(ApplyView& view, std::shared_ptr<SLE> const& sle, beast::Journal j)
offerIndex,
false))
{
return tefBAD_LEDGER;
return tefBAD_LEDGER; // LCOV_EXCL_LINE
}
if (sle->isFieldPresent(sfAdditionalBooks))
@@ -1821,7 +1834,7 @@ rippleCreditIOU(
auto const sleAccount = view.peek(keylet::account(uReceiverID));
if (!sleAccount)
return tefINTERNAL;
return tefINTERNAL; // LCOV_EXCL_LINE
bool const noRipple = (sleAccount->getFlags() & lsfDefaultRipple) == 0;
@@ -1911,14 +1924,16 @@ accountSendIOU(
{
if (saAmount < beast::zero || saAmount.holds<MPTIssue>())
{
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
}
}
else
{
// LCOV_EXCL_START
XRPL_ASSERT(
saAmount >= beast::zero && !saAmount.holds<MPTIssue>(),
"ripple::accountSendIOU : minimum amount and not MPT");
// LCOV_EXCL_STOP
}
/* If we aren't sending anything or if the sender is the same as the
@@ -1975,8 +1990,10 @@ accountSendIOU(
{
// VFALCO Its laborious to have to mutate the
// TER based on params everywhere
// LCOV_EXCL_START
terResult = view.open() ? TER{telFAILED_PROCESSING}
: TER{tecFAILED_PROCESSING};
// LCOV_EXCL_STOP
}
else
{
@@ -2063,7 +2080,7 @@ rippleCreditMPT(
view.update(sleIssuance);
}
else
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
}
else
{
@@ -2323,7 +2340,7 @@ issueIOU(
auto const receiverAccount = view.peek(keylet::account(account));
if (!receiverAccount)
return tefINTERNAL;
return tefINTERNAL; // LCOV_EXCL_LINE
bool noRipple = (receiverAccount->getFlags() & lsfDefaultRipple) == 0;
@@ -2411,11 +2428,13 @@ redeemIOU(
// In order to hold an IOU, a trust line *MUST* exist to track the
// balance. If it doesn't, then something is very wrong. Don't try
// to continue.
// LCOV_EXCL_START
JLOG(j.fatal()) << "redeemIOU: " << to_string(account)
<< " attempts to redeem " << amount.getFullText()
<< " but no trust line exists!";
return tefINTERNAL;
// LCOV_EXCL_STOP
}
TER
@@ -2435,7 +2454,7 @@ transferXRP(
SLE::pointer const sender = view.peek(keylet::account(from));
SLE::pointer const receiver = view.peek(keylet::account(to));
if (!sender || !receiver)
return tefINTERNAL;
return tefINTERNAL; // LCOV_EXCL_LINE
JLOG(j.trace()) << "transferXRP: " << to_string(from) << " -> "
<< to_string(to) << ") : " << amount.getFullText();
@@ -2445,8 +2464,10 @@ transferXRP(
// VFALCO Its unfortunate we have to keep
// mutating these TER everywhere
// FIXME: this logic should be moved to callers maybe?
// LCOV_EXCL_START
return view.open() ? TER{telFAILED_PROCESSING}
: TER{tecFAILED_PROCESSING};
// LCOV_EXCL_STOP
}
// Decrement XRP balance.
@@ -2677,7 +2698,8 @@ enforceMPTokenAuthorization(
UNREACHABLE(
"ripple::enforceMPTokenAuthorization : condition list is incomplete");
return tefINTERNAL;
} // LCOV_EXCL_STOP
// LCOV_EXCL_STOP
}
TER
canTransfer(
@@ -2726,11 +2748,13 @@ cleanupOnAccountDelete(
if (!sleItem)
{
// Directory node has an invalid index. Bail out.
// LCOV_EXCL_START
JLOG(j.fatal())
<< "DeleteAccount: Directory node in ledger " << view.seq()
<< " has index to object that is missing: "
<< to_string(dirEntry);
return tefBAD_LEDGER;
// LCOV_EXCL_STOP
}
LedgerEntryType const nodeType{safe_cast<LedgerEntryType>(
@@ -2763,9 +2787,11 @@ cleanupOnAccountDelete(
"ripple::cleanupOnAccountDelete : minimum dir entries");
if (uDirEntry == 0)
{
// LCOV_EXCL_START
JLOG(j.error())
<< "DeleteAccount iterator re-validation failed.";
return tefBAD_LEDGER;
// LCOV_EXCL_STOP
}
if (skipEntry == SkipEntry::No)
uDirEntry--;
@@ -2785,7 +2811,7 @@ deleteAMMTrustLine(
beast::Journal j)
{
if (!sleState || sleState->getType() != ltRIPPLE_STATE)
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
auto const& [low, high] = std::minmax(
sleState->getFieldAmount(sfLowLimit).getIssuer(),
@@ -2793,13 +2819,14 @@ deleteAMMTrustLine(
auto sleLow = view.peek(keylet::account(low));
auto sleHigh = view.peek(keylet::account(high));
if (!sleLow || !sleHigh)
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
bool const ammLow = sleLow->isFieldPresent(sfAMMID);
bool const ammHigh = sleHigh->isFieldPresent(sfAMMID);
// can't both be AMM
if (ammLow && ammHigh)
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
// at least one must be
if (!ammLow && !ammHigh)
@@ -2819,7 +2846,7 @@ deleteAMMTrustLine(
auto const uFlags = !ammLow ? lsfLowReserve : lsfHighReserve;
if (!(sleState->getFlags() & uFlags))
return tecINTERNAL;
return tecINTERNAL; // LCOV_EXCL_LINE
adjustOwnerCount(view, !ammLow ? sleLow : sleHigh, -1, j);

View File

@@ -17,7 +17,7 @@
*/
//==============================================================================
#include <xrpld/nodestore/detail/BatchWriter.h>
#include <xrpl/nodestore/detail/BatchWriter.h>
namespace ripple {
namespace NodeStore {

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