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: build_type:
description: 'The build type to use ("Debug", "Release").' description: 'The build type to use ("Debug", "Release").'
required: true required: true
build_nproc:
description: "The number of processors to use for building."
required: true
force_build: force_build:
description: 'Force building of all dependencies ("true", "false").' description: 'Force building of all dependencies ("true", "false").'
required: false required: false
default: "false" default: "false"
log_verbosity:
description: "The logging verbosity."
required: false
default: "verbose"
runs: runs:
using: composite using: composite
@@ -22,16 +29,21 @@ runs:
shell: bash shell: bash
env: env:
BUILD_DIR: ${{ inputs.build_dir }} BUILD_DIR: ${{ inputs.build_dir }}
BUILD_NPROC: ${{ inputs.build_nproc }}
BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }} BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }}
BUILD_TYPE: ${{ inputs.build_type }} BUILD_TYPE: ${{ inputs.build_type }}
LOG_VERBOSITY: ${{ inputs.log_verbosity }}
run: | run: |
echo 'Installing dependencies.' echo 'Installing dependencies.'
mkdir -p '${{ env.BUILD_DIR }}' mkdir -p "${BUILD_DIR}"
cd '${{ env.BUILD_DIR }}' cd "${BUILD_DIR}"
conan install \ conan install \
--output-folder . \ --output-folder . \
--build=${{ env.BUILD_OPTION }} \ --build="${BUILD_OPTION}" \
--options:host='&:tests=True' \ --options:host='&:tests=True' \
--options:host='&:xrpld=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_NAME: ${{ inputs.conan_remote_name }}
CONAN_REMOTE_URL: ${{ inputs.conan_remote_url }} CONAN_REMOTE_URL: ${{ inputs.conan_remote_url }}
run: | run: |
echo "Adding Conan remote '${{ env.CONAN_REMOTE_NAME }}' at '${{ env.CONAN_REMOTE_URL }}'." echo "Adding Conan remote '${CONAN_REMOTE_NAME}' at '${CONAN_REMOTE_URL}'."
conan remote add --index 0 --force '${{ env.CONAN_REMOTE_NAME }}' '${{ env.CONAN_REMOTE_URL }}' conan remote add --index 0 --force "${CONAN_REMOTE_NAME}" "${CONAN_REMOTE_URL}"
echo 'Listing Conan remotes.' echo 'Listing Conan remotes.'
conan remote list conan remote list

View File

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

View File

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

View File

@@ -74,14 +74,14 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue continue
# RHEL: # RHEL:
# - 9.4 using GCC 12: Debug and Unity on linux/amd64. # - 9 using GCC 12: Debug and Unity on linux/amd64.
# - 9.6 using Clang: Release and no Unity on linux/amd64. # - 10 using Clang: Release and no Unity on linux/amd64.
if os['distro_name'] == 'rhel': if os['distro_name'] == 'rhel':
skip = True 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': 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 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': 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 skip = False
if skip: if skip:

View File

@@ -14,139 +14,169 @@
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "12" "compiler_version": "12",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "13" "compiler_version": "13",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "14" "compiler_version": "14",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "15" "compiler_version": "15",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "16" "compiler_version": "16",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "17" "compiler_version": "17",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "18" "compiler_version": "18",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "19" "compiler_version": "19",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "20" "compiler_version": "20",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "rhel", "distro_name": "rhel",
"distro_version": "9.4", "distro_version": "8",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "12" "compiler_version": "14",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "rhel", "distro_name": "rhel",
"distro_version": "9.4", "distro_version": "8",
"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",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "any" "compiler_version": "any",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "rhel", "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_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_name": "ubuntu",
"distro_version": "jammy", "distro_version": "jammy",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "12" "compiler_version": "12",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "13" "compiler_version": "13",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "14" "compiler_version": "14",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "16" "compiler_version": "16",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "17" "compiler_version": "17",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "18" "compiler_version": "18",
"image_sha": "97ba375"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "19" "compiler_version": "19",
"image_sha": "97ba375"
} }
], ],
"build_type": ["Debug", "Release"], "build_type": ["Debug", "Release"],

View File

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

View File

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

View File

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

View File

@@ -9,9 +9,9 @@ name: Trigger
on: on:
push: push:
branches: branches:
- develop - "develop"
- release - "release*"
- master - "master"
paths: paths:
# These paths are unique to `on-trigger.yml`. # These paths are unique to `on-trigger.yml`.
- ".github/workflows/reusable-check-missing-commits.yml" - ".github/workflows/reusable-check-missing-commits.yml"
@@ -50,7 +50,12 @@ on:
workflow_dispatch: workflow_dispatch:
concurrency: 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 cancel-in-progress: true
defaults: defaults:
@@ -65,6 +70,7 @@ jobs:
build-test: build-test:
uses: ./.github/workflows/reusable-build-test.yml uses: ./.github/workflows/reusable-build-test.yml
strategy: strategy:
fail-fast: ${{ github.event_name == 'merge_group' }}
matrix: matrix:
os: [linux, macos, windows] os: [linux, macos, windows]
with: with:

View File

@@ -9,7 +9,7 @@ on:
jobs: jobs:
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks. # Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
run-hooks: run-hooks:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@af1b0f0d764cda2e5435f5ac97b240d4bd4d95d3 uses: XRPLF/actions/.github/workflows/pre-commit.yml@34790936fae4c6c751f62ec8c06696f9c1a5753a
with: with:
runs_on: ubuntu-latest 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: env:
BUILD_DIR: .build BUILD_DIR: .build
NPROC_SUBTRACT: 2
jobs: jobs:
publish: publish:
runs-on: ubuntu-latest 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: permissions:
contents: write contents: write
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 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 - name: Check configuration
run: | run: |
echo 'Checking path.' echo 'Checking path.'
@@ -46,12 +54,16 @@ jobs:
echo 'Checking Doxygen version.' echo 'Checking Doxygen version.'
doxygen --version doxygen --version
- name: Build documentation - name: Build documentation
env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
run: | run: |
mkdir -p ${{ env.BUILD_DIR }} mkdir -p "${BUILD_DIR}"
cd ${{ env.BUILD_DIR }} cd "${BUILD_DIR}"
cmake -Donly_docs=ON .. cmake -Donly_docs=ON ..
cmake --build . --target docs --parallel $(nproc) cmake --build . --target docs --parallel ${BUILD_NPROC}
- name: Publish documentation - name: Publish documentation
if: ${{ github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }} if: ${{ github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }}
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0

View File

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

View File

@@ -42,7 +42,7 @@ jobs:
- generate-matrix - generate-matrix
uses: ./.github/workflows/reusable-build-test-config.yml uses: ./.github/workflows/reusable-build-test-config.yml
strategy: strategy:
fail-fast: false fail-fast: ${{ github.event_name == 'merge_group' }}
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
max-parallel: 10 max-parallel: 10
with: with:
@@ -52,7 +52,7 @@ jobs:
cmake_args: ${{ matrix.cmake_args }} cmake_args: ${{ matrix.cmake_args }}
cmake_target: ${{ matrix.cmake_target }} cmake_target: ${{ matrix.cmake_target }}
runs_on: ${{ toJSON(matrix.architecture.runner) }} 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 }} config_name: ${{ matrix.config_name }}
secrets: secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -34,6 +34,11 @@ on:
required: true required: true
type: string type: string
nproc_subtract:
description: "The number of processors to subtract when calculating parallelism."
required: true
type: number
secrets: secrets:
CODECOV_TOKEN: CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports." description: "The Codecov token to use for uploading coverage reports."
@@ -48,6 +53,7 @@ jobs:
name: Build ${{ inputs.config_name }} name: Build ${{ inputs.config_name }}
runs-on: ${{ fromJSON(inputs.runs_on) }} runs-on: ${{ fromJSON(inputs.runs_on) }}
container: ${{ inputs.image != '' && inputs.image || null }} container: ${{ inputs.image != '' && inputs.image || null }}
timeout-minutes: 60
steps: steps:
- name: Cleanup workspace - name: Cleanup workspace
if: ${{ runner.os == 'macOS' }} if: ${{ runner.os == 'macOS' }}
@@ -57,13 +63,19 @@ jobs:
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5 uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
with: with:
disable_ccache: false disable_ccache: false
- name: Print build environment - name: Print build environment
uses: ./.github/actions/print-env 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 - name: Setup Conan
uses: ./.github/actions/setup-conan uses: ./.github/actions/setup-conan
@@ -71,7 +83,11 @@ jobs:
uses: ./.github/actions/build-deps uses: ./.github/actions/build-deps
with: with:
build_dir: ${{ inputs.build_dir }} build_dir: ${{ inputs.build_dir }}
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ inputs.build_type }} 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 - name: Configure CMake
shell: bash shell: bash
@@ -83,33 +99,50 @@ jobs:
cmake \ cmake \
-G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \ -G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \ -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
${{ env.CMAKE_ARGS }} \ ${CMAKE_ARGS} \
.. ..
- name: Build the binary - name: Build the binary
shell: bash shell: bash
working-directory: ${{ inputs.build_dir }} working-directory: ${{ inputs.build_dir }}
env: env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
BUILD_TYPE: ${{ inputs.build_type }} BUILD_TYPE: ${{ inputs.build_type }}
CMAKE_TARGET: ${{ inputs.cmake_target }} CMAKE_TARGET: ${{ inputs.cmake_target }}
run: | run: |
cmake \ cmake \
--build . \ --build . \
--config ${{ env.BUILD_TYPE }} \ --config "${BUILD_TYPE}" \
--parallel $(nproc) \ --parallel ${BUILD_NPROC} \
--target ${{ env.CMAKE_TARGET }} --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 - name: Upload rippled artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
env:
BUILD_DIR: ${{ inputs.build_dir }}
with: with:
name: rippled-${{ inputs.config_name }} 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 retention-days: 3
if-no-files-found: error if-no-files-found: error
- name: Upload coverage report - 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 uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with: with:
disable_search: true disable_search: true

View File

@@ -51,7 +51,7 @@ jobs:
run: | run: |
echo 'Generating user and channel.' echo 'Generating user and channel.'
echo "user=clio" >> "${GITHUB_OUTPUT}" echo "user=clio" >> "${GITHUB_OUTPUT}"
echo "channel=pr_${{ env.PR_NUMBER }}" >> "${GITHUB_OUTPUT}" echo "channel=pr_${PR_NUMBER}" >> "${GITHUB_OUTPUT}"
echo 'Extracting version.' echo 'Extracting version.'
echo "version=$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" >> "${GITHUB_OUTPUT}" echo "version=$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" >> "${GITHUB_OUTPUT}"
- name: Calculate conan reference - name: Calculate conan reference
@@ -64,13 +64,15 @@ jobs:
conan_remote_name: ${{ inputs.conan_remote_name }} conan_remote_name: ${{ inputs.conan_remote_name }}
conan_remote_url: ${{ inputs.conan_remote_url }} conan_remote_url: ${{ inputs.conan_remote_url }}
- name: Log into Conan remote - 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 - name: Upload package
env: env:
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }} CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
run: | run: |
conan export --user=${{ steps.generate.outputs.user }} --channel=${{ steps.generate.outputs.channel }} . 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: outputs:
conan_ref: ${{ steps.conan_ref.outputs.conan_ref }} 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" \ 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" \ /repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \
-F "client_payload[conan_ref]=${{ needs.upload.outputs.conan_ref }}" \ -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: env:
GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }} GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }}
GENERATE_OPTION: ${{ inputs.strategy_matrix == 'all' && '--all' || '' }} 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 required: true
type: string type: string
nproc_subtract:
description: "The number of processors to subtract when calculating parallelism."
required: true
type: number
jobs: jobs:
test: test:
name: Test ${{ inputs.config_name }} name: Test ${{ inputs.config_name }}
runs-on: ${{ fromJSON(inputs.runs_on) }} runs-on: ${{ fromJSON(inputs.runs_on) }}
container: ${{ inputs.image != '' && inputs.image || null }} container: ${{ inputs.image != '' && inputs.image || null }}
timeout-minutes: 30
steps: 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 - name: Download rippled artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with: with:
@@ -61,9 +77,35 @@ jobs:
run: | run: |
./rippled --version | grep libvoidstar ./rippled --version | grep libvoidstar
- name: Test the binary - name: Run the embedded tests
if: ${{ inputs.run_tests }} if: ${{ inputs.run_tests }}
shell: bash shell: bash
env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
run: | run: |
./rippled --unittest --unittest-jobs $(nproc) ./rippled --unittest --unittest-jobs ${BUILD_NPROC}
ctest -j $(nproc) --output-on-failure
- 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: env:
CONAN_REMOTE_NAME: xrplf CONAN_REMOTE_NAME: xrplf
CONAN_REMOTE_URL: https://conan.ripplex.io CONAN_REMOTE_URL: https://conan.ripplex.io
NPROC_SUBTRACT: 2
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
# Generate the strategy matrix to be used by the following job.
generate-matrix: generate-matrix:
uses: ./.github/workflows/reusable-strategy-matrix.yml uses: ./.github/workflows/reusable-strategy-matrix.yml
with: with:
strategy_matrix: ${{ github.event_name == 'pull_request' && 'minimal' || 'all' }} strategy_matrix: ${{ github.event_name == 'pull_request' && 'minimal' || 'all' }}
# Build and upload the dependencies for each configuration.
run-upload-conan-deps: run-upload-conan-deps:
needs: needs:
- generate-matrix - generate-matrix
@@ -53,19 +56,29 @@ jobs:
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
max-parallel: 10 max-parallel: 10
runs-on: ${{ matrix.architecture.runner }} 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: steps:
- name: Cleanup workspace - name: Cleanup workspace
if: ${{ runner.os == 'macOS' }} if: ${{ runner.os == 'macOS' }}
uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e 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 - name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5 uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
with: with:
disable_ccache: false 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 - name: Setup Conan
uses: ./.github/actions/setup-conan uses: ./.github/actions/setup-conan
with: with:
@@ -76,15 +89,19 @@ jobs:
uses: ./.github/actions/build-deps uses: ./.github/actions/build-deps
with: with:
build_dir: .build build_dir: .build
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ matrix.build_type }} build_type: ${{ matrix.build_type }}
force_build: ${{ github.event_name == 'schedule' || github.event.inputs.force_source_build == 'true' }} 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 - name: Log into Conan remote
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' }} if: ${{ github.repository_owner == 'XRPLF' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
run: conan remote login ${{ env.CONAN_REMOTE_NAME }} "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}" run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}"
- name: Upload Conan packages - 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: env:
FORCE_OPTION: ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }} 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 - [Python 3.11](https://www.python.org/downloads/), or higher
- [Conan 2.17](https://conan.io/downloads.html)[^1], 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]: [^1]:
It is possible to build with Conan 1.60+, but the instructions are It is possible to build with Conan 1.60+, but the instructions are
significantly different, which is why we are not recommending it. 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. `rippled` is written in the C++20 dialect and includes the `<concepts>` header.
The [minimum compiler versions][2] required are: 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 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 #### Clang workaround for grpc
If your compiler is clang, version 19 or later, or apple-clang, version 17 or 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 # number of ledger records online. Must be greater
# than or equal to ledger_history. # 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 # These keys modify the behavior of online_delete, and thus are only
# relevant if online_delete is defined and non-zero: # relevant if online_delete is defined and non-zero:
# #
@@ -1471,6 +1512,7 @@ secure_gateway = 127.0.0.1
[node_db] [node_db]
type=NuDB type=NuDB
path=/var/lib/rippled/db/nudb path=/var/lib/rippled/db/nudb
nudb_block_size=4096
online_delete=512 online_delete=512
advisory_delete=0 advisory_delete=0

View File

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

View File

@@ -16,13 +16,16 @@ set(CMAKE_CXX_EXTENSIONS OFF)
target_compile_definitions (common target_compile_definitions (common
INTERFACE INTERFACE
$<$<CONFIG:Debug>:DEBUG _DEBUG> $<$<CONFIG:Debug>:DEBUG _DEBUG>
$<$<AND:$<BOOL:${profile}>,$<NOT:$<BOOL:${assert}>>>:NDEBUG>) #[===[
# ^^^^ NOTE: CMAKE release builds already have NDEBUG NOTE: CMAKE release builds already have NDEBUG defined, so no need to add it
# defined, so no need to add it explicitly except for explicitly except for the special case of (profile ON) and (assert OFF).
# this special case of (profile ON) and (assert OFF) Presumably this is because we don't want profile builds asserting unless
# -- presumably this is because we don't want profile asserts were specifically requested.
# 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) if (MSVC)
# remove existing exception flag since we set it to -EHa # 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 target_link_libraries(xrpl.imports.main
INTERFACE INTERFACE
LibArchive::LibArchive
OpenSSL::Crypto
Ripple::boost
Ripple::opts
Ripple::syslibs
absl::random_random absl::random_random
date::date date::date
ed25519::ed25519 ed25519::ed25519
LibArchive::LibArchive
OpenSSL::Crypto
Ripple::boost
Ripple::libs
Ripple::opts
Ripple::syslibs
secp256k1::secp256k1 secp256k1::secp256k1
xrpl.libpb xrpl.libpb
xxHash::xxhash xxHash::xxhash
@@ -111,6 +112,21 @@ target_link_libraries(xrpl.libxrpl.net PUBLIC
add_module(xrpl server) add_module(xrpl server)
target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol) 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) add_module(xrpl ledger)
target_link_libraries(xrpl.libxrpl.ledger PUBLIC target_link_libraries(xrpl.libxrpl.ledger PUBLIC
xrpl.libxrpl.basics xrpl.libxrpl.basics
@@ -136,6 +152,8 @@ target_link_modules(xrpl PUBLIC
protocol protocol
resource resource
server server
nodestore
shamap
net net
ledger ledger
) )

View File

@@ -8,20 +8,23 @@ install (
TARGETS TARGETS
common common
opts opts
ripple_syslibs
ripple_boost ripple_boost
ripple_libs
ripple_syslibs
xrpl.imports.main xrpl.imports.main
xrpl.libpb xrpl.libpb
xrpl.libxrpl
xrpl.libxrpl.basics xrpl.libxrpl.basics
xrpl.libxrpl.beast xrpl.libxrpl.beast
xrpl.libxrpl.crypto xrpl.libxrpl.crypto
xrpl.libxrpl.json xrpl.libxrpl.json
xrpl.libxrpl.ledger
xrpl.libxrpl.net
xrpl.libxrpl.nodestore
xrpl.libxrpl.protocol xrpl.libxrpl.protocol
xrpl.libxrpl.resource xrpl.libxrpl.resource
xrpl.libxrpl.ledger
xrpl.libxrpl.server xrpl.libxrpl.server
xrpl.libxrpl.net xrpl.libxrpl.shamap
xrpl.libxrpl
antithesis-sdk-cpp antithesis-sdk-cpp
EXPORT RippleExports EXPORT RippleExports
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
@@ -38,7 +41,7 @@ install(CODE "
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\") set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
include(create_symbolic_link) include(create_symbolic_link)
create_symbolic_link(xrpl \ create_symbolic_link(xrpl \
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple) \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple)
") ")
install (EXPORT RippleExports install (EXPORT RippleExports
@@ -72,7 +75,7 @@ if (is_root_project AND TARGET rippled)
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\") set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
include(create_symbolic_link) include(create_symbolic_link)
create_symbolic_link(rippled${suffix} \ create_symbolic_link(rippled${suffix} \
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix}) \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix})
") ")
endif () 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) if (validator_keys)
git_branch (current_branch) git_branch (current_branch)
@@ -6,17 +6,15 @@ if (validator_keys)
if (NOT (current_branch STREQUAL "release")) if (NOT (current_branch STREQUAL "release"))
set (current_branch "master") set (current_branch "master")
endif () endif ()
message (STATUS "tracking ValidatorKeys branch: ${current_branch}") message (STATUS "Tracking ValidatorKeys branch: ${current_branch}")
FetchContent_Declare ( FetchContent_Declare (
validator_keys_src validator_keys
GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git
GIT_TAG "${current_branch}" GIT_TAG "${current_branch}"
) )
FetchContent_GetProperties (validator_keys_src) FetchContent_MakeAvailable(validator_keys)
if (NOT validator_keys_src_POPULATED) set_target_properties(validator-keys PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
message (STATUS "Pausing to download ValidatorKeys...") install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
FetchContent_Populate (validator_keys_src)
endif ()
add_subdirectory (${validator_keys_src_SOURCE_DIR} ${CMAKE_BINARY_DIR}/validator-keys)
endif () endif ()

View File

@@ -7,7 +7,7 @@ function(xrpl_add_test name)
"${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp"
"${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( isolate_headers(
${target} ${target}

View File

@@ -9,7 +9,7 @@
"rocksdb/10.0.1#85537f46e538974d67da0c3977de48ac%1756234304.347", "rocksdb/10.0.1#85537f46e538974d67da0c3977de48ac%1756234304.347",
"re2/20230301#dfd6e2bf050eb90ddd8729cfb4c844a4%1756234257.976", "re2/20230301#dfd6e2bf050eb90ddd8729cfb4c844a4%1756234257.976",
"protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1756234251.614", "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", "nudb/2.0.9#c62cfd501e57055a7e0d8ee3d5e5427d%1756234237.107",
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1756234228.999", "lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1756234228.999",
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1756223727.64", "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 # 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 # downloads and uploads.
# provide more information during the build process.
core:non_interactive=True core:non_interactive=True
core.download:parallel={{ os.cpu_count() }} core.download:parallel={{ os.cpu_count() }}
core.upload: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] [conf]
{% if compiler == "clang" and compiler_version >= 19 %} {% 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 %} {% endif %}
{% if compiler == "apple-clang" and compiler_version >= 17 %} {% 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 %} {% endif %}
{% if compiler == "gcc" and compiler_version < 13 %} {% if compiler == "gcc" and compiler_version < 13 %}
tools.build:cxxflags=['-Wno-restrict'] tools.build:cxxflags+=['-Wno-restrict']
{% endif %} {% endif %}
[tool_requires]
!cmake/*: cmake/[>=3 <4]

View File

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

View File

@@ -654,12 +654,14 @@ SharedWeakUnion<T>::convertToWeak()
break; break;
case destroy: case destroy:
// We just added a weak ref. How could we destroy? // We just added a weak ref. How could we destroy?
// LCOV_EXCL_START
UNREACHABLE( UNREACHABLE(
"ripple::SharedWeakUnion::convertToWeak : destroying freshly " "ripple::SharedWeakUnion::convertToWeak : destroying freshly "
"added ref"); "added ref");
delete p; delete p;
unsafeSetRawPtr(nullptr); unsafeSetRawPtr(nullptr);
return true; // Should never happen return true; // Should never happen
// LCOV_EXCL_STOP
case partialDestroy: case partialDestroy:
// This is a weird case. We just converted the last strong // This is a weird case. We just converted the last strong
// pointer to a weak pointer. // 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()) else if (addr.is_v6())
hash_append(h, addr.to_v6().to_bytes()); hash_append(h, addr.to_v6().to_bytes());
else else
{
// LCOV_EXCL_START
UNREACHABLE("beast::hash_append : invalid address type"); UNREACHABLE("beast::hash_append : invalid address type");
// LCOV_EXCL_STOP
}
} }
} // namespace beast } // namespace beast

View File

@@ -46,7 +46,7 @@ public:
* without formatting (not human friendly). * without formatting (not human friendly).
* *
* The JSON document is written in a single line. It is not intended for 'human' * 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 * is limited. \sa Reader, Value
*/ */

View File

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

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_NODESTORE_BACKEND_H_INCLUDED #ifndef RIPPLE_NODESTORE_BACKEND_H_INCLUDED
#define RIPPLE_NODESTORE_BACKEND_H_INCLUDED #define RIPPLE_NODESTORE_BACKEND_H_INCLUDED
#include <xrpld/nodestore/Types.h> #include <xrpl/nodestore/Types.h>
#include <cstdint> #include <cstdint>
@@ -53,6 +53,14 @@ public:
virtual std::string virtual std::string
getName() = 0; 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. /** Open the backend.
@param createIfMissing Create the database files if necessary. @param createIfMissing Create the database files if necessary.
This allows the caller to catch exceptions. This allows the caller to catch exceptions.

View File

@@ -20,13 +20,12 @@
#ifndef RIPPLE_NODESTORE_DATABASE_H_INCLUDED #ifndef RIPPLE_NODESTORE_DATABASE_H_INCLUDED
#define 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/BasicConfig.h>
#include <xrpl/basics/Log.h> #include <xrpl/basics/Log.h>
#include <xrpl/basics/TaggedCache.ipp> #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 <xrpl/protocol/SystemParameters.h>
#include <condition_variable> #include <condition_variable>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,6 +20,11 @@
#ifndef RIPPLE_PROTOCOL_APIVERSION_H_INCLUDED #ifndef RIPPLE_PROTOCOL_APIVERSION_H_INCLUDED
#define 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 <type_traits>
#include <utility> #include <utility>
@@ -72,6 +77,77 @@ static_assert(apiMaximumSupportedVersion >= apiMinimumSupportedVersion);
static_assert(apiBetaVersion >= apiMaximumSupportedVersion); static_assert(apiBetaVersion >= apiMaximumSupportedVersion);
static_assert(apiMaximumValidVersion >= 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 } // namespace RPC
template <unsigned minVer, unsigned maxVer, typename Fn, typename... Args> 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 */ /** The maximum number of entries per directory page */
std::size_t constexpr dirNodeMaxEntries = 32; 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; std::uint64_t constexpr dirNodeMaxPages = 262144;
/** The maximum number of items in an NFT page */ /** The maximum number of items in an NFT page */

View File

@@ -21,6 +21,7 @@
#define RIPPLE_PROTOCOL_PUBLICKEY_H_INCLUDED #define RIPPLE_PROTOCOL_PUBLICKEY_H_INCLUDED
#include <xrpl/basics/Slice.h> #include <xrpl/basics/Slice.h>
#include <xrpl/beast/net/IPEndpoint.h>
#include <xrpl/protocol/KeyType.h> #include <xrpl/protocol/KeyType.h>
#include <xrpl/protocol/STExchange.h> #include <xrpl/protocol/STExchange.h>
#include <xrpl/protocol/UintTypes.h> #include <xrpl/protocol/UintTypes.h>
@@ -264,6 +265,24 @@ calcNodeID(PublicKey const&);
AccountID AccountID
calcAccountID(PublicKey const& pk); 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 } // namespace ripple
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@@ -709,37 +709,6 @@ canAdd(STAmount const& amt1, STAmount const& amt2);
bool bool
canSubtract(STAmount const& amt1, STAmount const& amt2); 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 } // namespace ripple
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@@ -244,6 +244,9 @@ public:
getFieldPathSet(SField const& field) const; getFieldPathSet(SField const& field) const;
STVector256 const& STVector256 const&
getFieldV256(SField const& field) 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& STArray const&
getFieldArray(SField const& field) const; getFieldArray(SField const& field) const;
STCurrency const& STCurrency const&
@@ -390,6 +393,8 @@ public:
setFieldV256(SField const& field, STVector256 const& v); setFieldV256(SField const& field, STVector256 const& v);
void void
setFieldArray(SField const& field, STArray const& v); setFieldArray(SField const& field, STArray const& v);
void
setFieldObject(SField const& field, STObject const& v);
template <class Tag> template <class Tag>
void void

View File

@@ -87,8 +87,14 @@ public:
getFullText() const override; getFullText() const override;
// Outer transaction functions / signature functions. // Outer transaction functions / signature functions.
static Blob
getSignature(STObject const& sigObject);
Blob Blob
getSignature() const; getSignature() const
{
return getSignature(*this);
}
uint256 uint256
getSigningHash() const; getSigningHash() const;
@@ -119,13 +125,20 @@ public:
getJson(JsonOptions options, bool binary) const; getJson(JsonOptions options, bool binary) const;
void 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 }; 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> Expected<void, std::string>
checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const& rules) checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const& rules)
const; const;
@@ -150,17 +163,34 @@ public:
char status, char status,
std::string const& escapedMetaData) const; std::string const& escapedMetaData) const;
std::vector<uint256> std::vector<uint256> const&
getBatchTransactionIDs() const; getBatchTransactionIDs() const;
private: 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> 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> Expected<void, std::string>
checkMultiSign( checkMultiSign(
RequireFullyCanonicalSig requireCanonicalSig, RequireFullyCanonicalSig requireCanonicalSig,
Rules const& rules) const; Rules const& rules,
STObject const& sigObject) const;
Expected<void, std::string> Expected<void, std::string>
checkBatchSingleSign( checkBatchSingleSign(
@@ -179,7 +209,7 @@ private:
move(std::size_t n, void* buf) override; move(std::size_t n, void* buf) override;
friend class detail::STVar; friend class detail::STVar;
mutable std::vector<uint256> batch_txn_ids_; mutable std::vector<uint256> batchTxnIds_;
}; };
bool bool

View File

@@ -73,14 +73,8 @@ static constexpr std::uint32_t XRP_LEDGER_EARLIEST_SEQ{32570u};
* used in asserts and tests. */ * used in asserts and tests. */
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_FEES{562177u}; static constexpr std::uint32_t XRP_LEDGER_EARLIEST_FEES{562177u};
/** The minimum amount of support an amendment should have. /** The minimum amount of support an amendment should have. */
constexpr std::ratio<80, 100> amendmentMajorityCalcThreshold;
@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 time an amendment must hold a majority */ /** The minimum amount of time an amendment must hold a majority */
constexpr std::chrono::seconds const defaultAmendmentMajorityTime = weeks{2}; constexpr std::chrono::seconds const defaultAmendmentMajorityTime = weeks{2};

View File

@@ -226,8 +226,9 @@ enum TERcodes : TERUnderlyingType {
terQUEUED, // Transaction is being held in TxQ until fee drops terQUEUED, // Transaction is being held in TxQ until fee drops
terPRE_TICKET, // Ticket is not yet in ledger but might be on its way terPRE_TICKET, // Ticket is not yet in ledger but might be on its way
terNO_AMM, // AMM doesn't exist for the asset pair terNO_AMM, // AMM doesn't exist for the asset pair
terADDRESS_COLLISION, // Failed to allocate AccountID when trying to terADDRESS_COLLISION, // Failed to allocate AccountID when trying to
// create a pseudo-account // create a pseudo-account
terNO_DELEGATE_PERMISSION, // Delegate does not have permission
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -362,6 +363,9 @@ enum TECcodes : TERUnderlyingType {
tecLIMIT_EXCEEDED = 195, tecLIMIT_EXCEEDED = 195,
tecPSEUDO_ACCOUNT = 196, tecPSEUDO_ACCOUNT = 196,
tecPRECISION_LOSS = 197, 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, tecNO_DELEGATE_PERMISSION = 198,
tecBAD_PROOF = 199 tecBAD_PROOF = 199
}; };

View File

@@ -33,51 +33,35 @@ namespace ripple {
class TxMeta class TxMeta
{ {
private:
struct CtorHelper
{
explicit CtorHelper() = default;
};
template <class T>
TxMeta(
uint256 const& txID,
std::uint32_t ledger,
T const& data,
CtorHelper);
public: public:
TxMeta( TxMeta(uint256 const& transactionID, std::uint32_t ledger);
uint256 const& transactionID,
std::uint32_t ledger,
std::optional<uint256> parentBatchId = std::nullopt);
TxMeta(uint256 const& txID, std::uint32_t ledger, Blob const&); 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&); TxMeta(uint256 const& txID, std::uint32_t ledger, STObject const&);
uint256 const& uint256 const&
getTxID() const getTxID() const
{ {
return mTransactionID; return transactionID_;
} }
std::uint32_t std::uint32_t
getLgrSeq() const getLgrSeq() const
{ {
return mLedger; return ledgerSeq_;
} }
int int
getResult() const getResult() const
{ {
return mResult; return result_;
} }
TER TER
getResultTER() const getResultTER() const
{ {
return TER::fromInt(mResult); return TER::fromInt(result_);
} }
std::uint32_t std::uint32_t
getIndex() const getIndex() const
{ {
return mIndex; return index_;
} }
void void
@@ -104,66 +88,52 @@ public:
STArray& STArray&
getNodes() getNodes()
{ {
return (mNodes); return nodes_;
} }
STArray const& STArray const&
getNodes() const getNodes() const
{ {
return (mNodes); return nodes_;
} }
void 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 getDeliveredAmount() const
{ {
XRPL_ASSERT( return deliveredAmount_;
hasDeliveredAmount(),
"ripple::TxMeta::getDeliveredAmount : non-null delivered amount");
return *mDelivered;
}
bool
hasDeliveredAmount() const
{
return static_cast<bool>(mDelivered);
} }
void void
setParentBatchId(uint256 const& parentBatchId) setDeliveredAmount(std::optional<STAmount> const& amount)
{ {
mParentBatchId = parentBatchId; deliveredAmount_ = amount;
} }
uint256 void
getParentBatchId() const setParentBatchID(std::optional<uint256> const& id)
{ {
XRPL_ASSERT( parentBatchID_ = id;
hasParentBatchId(),
"ripple::TxMeta::getParentBatchId : non-null batch id");
return *mParentBatchId;
}
bool
hasParentBatchId() const
{
return static_cast<bool>(mParentBatchId);
} }
private: private:
uint256 mTransactionID; uint256 transactionID_;
std::uint32_t mLedger; std::uint32_t ledgerSeq_;
std::uint32_t mIndex; std::uint32_t index_;
int mResult; int result_;
std::optional<STAmount> mDelivered; std::optional<STAmount> deliveredAmount_;
std::optional<uint256> mParentBatchId; std::optional<uint256> parentBatchID_;
STArray mNodes; STArray nodes_;
}; };
} // namespace ripple } // 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 // 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. // the a null set of numbers to be zero, so the remainder is also zero.
// LCOV_EXCL_START
UNREACHABLE( UNREACHABLE(
"ripple::b58_fast::detail::inplace_bigint_div_rem : empty " "ripple::b58_fast::detail::inplace_bigint_div_rem : empty "
"numerator"); "numerator");
return 0; return 0;
// LCOV_EXCL_STOP
} }
auto to_u128 = [](std::uint64_t high, auto to_u128 = [](std::uint64_t high,

View File

@@ -29,16 +29,15 @@
// Add new amendments to the top of this list. // Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order. // 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(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_FIX (IncludeKeyletFields, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DynamicMPT, Supported::no, VoteBehavior::DefaultNo) XRPL_FEATURE(DynamicMPT, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (TokenEscrowV1, Supported::yes, 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 (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_FIX (AMMClawbackRounding, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(TokenEscrow, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(TokenEscrow, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (EnforceNFTokenTrustlineV2, 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(PermissionedDEX, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Batch, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(Batch, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(SingleAssetVault, Supported::no, VoteBehavior::DefaultNo) XRPL_FEATURE(SingleAssetVault, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegation, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo) XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo)
// Check flags in Credential transactions // Check flags in Credential transactions
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultNo) 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(XChainBridge, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(AMM, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(AMM, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Clawback, 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_FIX (UniversalNumber, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(XRPFees, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(XRPFees, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DisallowIncoming, 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 (RemoveNFTokenAutoTrustLine, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (TrustLinesToSelf, Supported::yes, VoteBehavior::DefaultNo) XRPL_FIX (TrustLinesToSelf, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(NonFungibleTokensV1_1, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(ExpandedSignerList, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(ExpandedSignerList, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(CheckCashMakesTrustLine, 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(FlowSortStrands, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(TicketBatch, Supported::yes, VoteBehavior::DefaultYes) XRPL_FEATURE(TicketBatch, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(NegativeUNL, 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) 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_FEATURE(RequireFullyCanonicalSig, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (QualityUpperBound, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(DeletableAccounts, Supported::yes, VoteBehavior::DefaultYes) XRPL_FEATURE(DeletableAccounts, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (PayChanRecipientOwnerDir, 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_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_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(Checks, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(DepositAuth, 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) XRPL_FEATURE(Flow, Supported::yes, VoteBehavior::DefaultYes)
// The following amendments are obsolete, but must remain supported // 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 // 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. // 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) XRPL_FEATURE(CryptoConditionsSuite, Supported::yes, VoteBehavior::Obsolete)
// The following amendments have been active for at least two years. Their // The following amendments have been active for at least two years. Their
// pre-amendment code has been removed and the identifiers are deprecated. // pre-amendment code has been removed and the identifiers are deprecated.
// All known amendments and amendments that may appear in a validated // All known amendments and amendments that may appear in a validated ledger
// ledger must be registered either here or above with the "active" amendments // must be registered either here or above with the "active" amendments
XRPL_RETIRE(MultiSign) //
XRPL_RETIRE(TrustSetAuth) // Please keep this list sorted alphabetically for convenience.
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)
XRPL_RETIRE(fix1201) XRPL_RETIRE(fix1201)
XRPL_RETIRE(fix1368)
XRPL_RETIRE(fix1373)
XRPL_RETIRE(fix1512) XRPL_RETIRE(fix1512)
XRPL_RETIRE(fix1513)
XRPL_RETIRE(fix1515)
XRPL_RETIRE(fix1523) XRPL_RETIRE(fix1523)
XRPL_RETIRE(fix1528) 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(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}, {sfExpiration, soeOPTIONAL},
{sfURI, soeOPTIONAL}, {sfURI, soeOPTIONAL},
{sfIssuerNode, soeREQUIRED}, {sfIssuerNode, soeREQUIRED},
{sfSubjectNode, soeREQUIRED}, {sfSubjectNode, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED}, {sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED}, {sfPreviousTxnLgrSeq, soeREQUIRED},
})) }))

View File

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

View File

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

View File

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

View File

@@ -53,7 +53,7 @@ struct Entry : public beast::List<Entry>::Node
std::string std::string
to_string() const 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; 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) // Back pointer to the map key (bit of a hack here)
Key const* key; Key const* key;

View File

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

View File

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

View File

@@ -20,21 +20,19 @@
#ifndef RIPPLE_SHAMAP_SHAMAP_H_INCLUDED #ifndef RIPPLE_SHAMAP_SHAMAP_H_INCLUDED
#define 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/IntrusivePointer.h>
#include <xrpl/basics/UnorderedContainers.h> #include <xrpl/basics/UnorderedContainers.h>
#include <xrpl/beast/utility/Journal.h> #include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.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 <set>
#include <stack> #include <stack>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,9 +20,8 @@
#ifndef RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED #ifndef RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED
#define RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED #define RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED
#include <xrpld/shamap/SHAMapTreeNode.h>
#include <xrpl/basics/IntrusivePointer.h> #include <xrpl/basics/IntrusivePointer.h>
#include <xrpl/shamap/SHAMapTreeNode.h>
#include <array> #include <array>
#include <cstdint> #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/basics/ByteUtilities.h>
#include <xrpl/shamap/SHAMapInnerNode.h>
#include <xrpl/shamap/detail/TaggedPointer.h>
#include <boost/pool/pool_alloc.hpp> #include <boost/pool/pool_alloc.hpp>

View File

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

View File

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

View File

@@ -174,7 +174,7 @@ Array::append(Json::Value const& v)
return; return;
} }
} }
UNREACHABLE("Json::Array::append : invalid type"); UNREACHABLE("Json::Array::append : invalid type"); // LCOV_EXCL_LINE
} }
void void
@@ -209,7 +209,7 @@ Object::set(std::string const& k, Json::Value const& v)
return; 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; value_.bool_ = false;
break; break;
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::Value::Value(ValueType) : invalid type"); 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_); value_.map_ = new ObjectValues(*other.value_.map_);
break; break;
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::Value::Value(Value const&) : invalid type"); UNREACHABLE("Json::Value::Value(Value const&) : invalid type");
// LCOV_EXCL_STOP
} }
} }
@@ -318,8 +322,10 @@ Value::~Value()
delete value_.map_; delete value_.map_;
break; break;
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::Value::~Value : invalid type"); 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_; return *x.value_.map_ < *y.value_.map_;
} }
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::operator<(Value, Value) : invalid type"); UNREACHABLE("Json::operator<(Value, Value) : invalid type");
// LCOV_EXCL_STOP
} }
return 0; // unreachable return 0; // unreachable
@@ -465,8 +473,10 @@ operator==(Value const& x, Value const& y)
return x.value_.map_->size() == y.value_.map_->size() && return x.value_.map_->size() == y.value_.map_->size() &&
*x.value_.map_ == *y.value_.map_; *x.value_.map_ == *y.value_.map_;
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::operator==(Value, Value) : invalid type"); UNREACHABLE("Json::operator==(Value, Value) : invalid type");
// LCOV_EXCL_STOP
} }
return 0; // unreachable return 0; // unreachable
@@ -506,8 +516,10 @@ Value::asString() const
case objectValue: case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to string"); JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::Value::asString : invalid type"); UNREACHABLE("Json::Value::asString : invalid type");
// LCOV_EXCL_STOP
} }
return ""; // unreachable return ""; // unreachable
@@ -548,8 +560,10 @@ Value::asInt() const
case objectValue: case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to int"); JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::Value::asInt : invalid type"); UNREACHABLE("Json::Value::asInt : invalid type");
// LCOV_EXCL_STOP
} }
return 0; // unreachable; return 0; // unreachable;
@@ -590,8 +604,10 @@ Value::asUInt() const
case objectValue: case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint"); JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::Value::asUInt : invalid type"); UNREACHABLE("Json::Value::asUInt : invalid type");
// LCOV_EXCL_STOP
} }
return 0; // unreachable; return 0; // unreachable;
@@ -622,8 +638,10 @@ Value::asDouble() const
case objectValue: case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to double"); JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::Value::asDouble : invalid type"); UNREACHABLE("Json::Value::asDouble : invalid type");
// LCOV_EXCL_STOP
} }
return 0; // unreachable; return 0; // unreachable;
@@ -654,8 +672,10 @@ Value::asBool() const
case objectValue: case objectValue:
return value_.map_->size() != 0; return value_.map_->size() != 0;
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::Value::asBool : invalid type"); UNREACHABLE("Json::Value::asBool : invalid type");
// LCOV_EXCL_STOP
} }
return false; // unreachable; return false; // unreachable;
@@ -710,8 +730,10 @@ Value::isConvertibleTo(ValueType other) const
return other == objectValue || return other == objectValue ||
(other == nullValue && value_.map_->size() == 0); (other == nullValue && value_.map_->size() == 0);
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::Value::isConvertible : invalid type"); UNREACHABLE("Json::Value::isConvertible : invalid type");
// LCOV_EXCL_STOP
} }
return false; // unreachable; return false; // unreachable;
@@ -744,8 +766,10 @@ Value::size() const
case objectValue: case objectValue:
return Int(value_.map_->size()); return Int(value_.map_->size());
// LCOV_EXCL_START
default: default:
UNREACHABLE("Json::Value::size : invalid type"); UNREACHABLE("Json::Value::size : invalid type");
// LCOV_EXCL_STOP
} }
return 0; // unreachable; return 0; // unreachable;

View File

@@ -126,10 +126,10 @@ ApplyStateTable::apply(
std::optional<TxMeta> metadata; std::optional<TxMeta> metadata;
if (!to.open() || isDryRun) 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; Mods newMod;
for (auto& item : items_) for (auto& item : items_)
@@ -259,9 +259,11 @@ ApplyStateTable::apply(
} }
else else
{ {
// LCOV_EXCL_START
UNREACHABLE( UNREACHABLE(
"ripple::detail::ApplyStateTable::apply : unsupported " "ripple::detail::ApplyStateTable::apply : unsupported "
"operation type"); "operation type");
// LCOV_EXCL_STOP
} }
} }
@@ -680,12 +682,6 @@ ApplyStateTable::threadOwners(
if (auto const optSleAcct{(*sle)[~sfAccount]}) if (auto const optSleAcct{(*sle)[~sfAccount]})
threadTx(base, meta, *optSleAcct, mods, j); 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 sfDestination is present, thread to that account
if (auto const optSleDest{(*sle)[~sfDestination]}) if (auto const optSleDest{(*sle)[~sfDestination]})
threadTx(base, meta, *optSleDest, mods, j); threadTx(base, meta, *optSleDest, mods, j);

View File

@@ -22,6 +22,9 @@
#include <xrpl/ledger/ApplyView.h> #include <xrpl/ledger/ApplyView.h>
#include <xrpl/protocol/Protocol.h> #include <xrpl/protocol/Protocol.h>
#include <limits>
#include <type_traits>
namespace ripple { namespace ripple {
std::optional<std::uint64_t> std::optional<std::uint64_t>
@@ -91,8 +94,21 @@ ApplyView::dirAdd(
return page; 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. // 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; return std::nullopt;
// We are about to create a new node; we'll link it to // 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 || if (directory.type != ltDIR_NODE ||
node->getFieldH256(sfRootIndex) != directory.key) node->getFieldH256(sfRootIndex) != directory.key)
{ {
// LCOV_EXCL_START
UNREACHABLE("ripple::ApplyView::emptyDirDelete : invalid node type"); UNREACHABLE("ripple::ApplyView::emptyDirDelete : invalid node type");
return false; return false;
// LCOV_EXCL_STOP
} }
// The directory still contains entries and so it cannot be removed // 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_)) if (!cdirFirst(*view_, key_, sle_, entry_, index_))
{ {
// LCOV_EXCL_START
UNREACHABLE("ripple::BookDirs::BookDirs : directory is empty"); 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_)) else if (!cdirFirst(*view_, cur_key_, sle_, entry_, index_))
{ {
// LCOV_EXCL_START
UNREACHABLE( UNREACHABLE(
"ripple::BookDirs::const_iterator::operator++ : directory is " "ripple::BookDirs::const_iterator::operator++ : directory is "
"empty"); "empty");
// LCOV_EXCL_STOP
} }
} }

View File

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

View File

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

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