This commit is contained in:
Valentin Balaschenko
2025-08-25 14:47:11 +01:00
47 changed files with 433 additions and 431 deletions

View File

@@ -1,4 +1,20 @@
---
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: AlwaysBreak
@@ -18,20 +34,7 @@ AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
BreakBeforeBinaryOperators: false
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 80
@@ -66,8 +69,6 @@ IndentFunctionDeclarationAfterType: false
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
@@ -96,11 +97,6 @@ TabWidth: 8
UseTab: Never
QualifierAlignment: Right
---
Language: JavaScript
---
Language: Json
IndentWidth: 2
---
Language: Proto
BasedOnStyle: Google
ColumnLimit: 0

View File

@@ -12,3 +12,5 @@ fe9a5365b8a52d4acc42eb27369247e6f238a4f9
9a93577314e6a8d4b4a8368cc9d2b15a5d8303e8
552377c76f55b403a1c876df873a23d780fcc81c
97f0747e103f13e26e45b731731059b32f7679ac
b13370ac0d207217354f1fc1c29aef87769fb8a1
896b8c3b54a22b0497cb0d1ce95e1095f9a227ce

View File

@@ -7,33 +7,33 @@ name: Build Conan dependencies
# https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs.
inputs:
build_dir:
description: 'The directory where to build.'
description: "The directory where to build."
required: true
build_type:
description: 'The build type to use ("Debug", "Release").'
required: true
conan_remote_name:
description: 'The name of the Conan remote to use.'
description: "The name of the Conan remote to use."
required: true
conan_remote_url:
description: 'The URL of the Conan endpoint to use.'
description: "The URL of the Conan endpoint to use."
required: true
conan_remote_username:
description: 'The username for logging into the Conan remote. If not provided, the dependencies will not be uploaded.'
description: "The username for logging into the Conan remote. If not provided, the dependencies will not be uploaded."
required: false
default: ''
default: ""
conan_remote_password:
description: 'The password for logging into the Conan remote. If not provided, the dependencies will not be uploaded.'
description: "The password for logging into the Conan remote. If not provided, the dependencies will not be uploaded."
required: false
default: ''
default: ""
force_build:
description: 'Force building of all dependencies ("true", "false").'
required: false
default: 'false'
default: "false"
force_upload:
description: 'Force uploading of all dependencies ("true", "false").'
required: false
default: 'false'
default: "false"
runs:
using: composite

View File

@@ -6,26 +6,26 @@ name: Build and Test
# https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs.
inputs:
build_dir:
description: 'The directory where to build.'
description: "The directory where to build."
required: true
build_only:
description: 'Whether to only build or to build and test the code ("true", "false").'
required: false
default: 'false'
default: "false"
build_type:
description: 'The build type to use ("Debug", "Release").'
required: true
cmake_args:
description: 'Additional arguments to pass to CMake.'
description: "Additional arguments to pass to CMake."
required: false
default: ''
default: ""
cmake_target:
description: 'The CMake target to build.'
description: "The CMake target to build."
required: true
codecov_token:
description: 'The Codecov token to use for uploading coverage reports.'
description: "The Codecov token to use for uploading coverage reports."
required: false
default: ''
default: ""
os:
description: 'The operating system to use for the build ("linux", "macos", "windows").'
required: true
@@ -83,7 +83,7 @@ runs:
./rippled --unittest --unittest-jobs $(nproc)
ctest -j $(nproc) --output-on-failure
- name: Upload coverage report
if: ${{ inputs.cmake_target == 'coverage' && inputs.codecov_token }}
if: ${{ inputs.cmake_target == 'coverage' }}
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
disable_search: true

View File

@@ -111,4 +111,4 @@ get those details locally.
1. Run `levelization.sh`
2. Grep the modules in `paths.txt`.
- For example, if a cycle is found `A ~= B`, simply `grep -w
A .github/scripts/levelization/results/paths.txt | grep -w B`
A .github/scripts/levelization/results/paths.txt | grep -w B`

View File

@@ -123,6 +123,10 @@ def generate_strategy_matrix(all: bool, architecture: list[dict], os: list[dict]
if os['distro_name'] == 'rhel' and architecture['platform'] == 'linux/arm64':
continue
# We skip all clang-20 on arm64 due to boost 1.86 build error
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-20' and architecture['platform'] == 'linux/arm64':
continue
# Generate a unique name for the configuration, e.g. macos-arm64-debug
# or debian-bookworm-gcc-12-amd64-release-unity.
config_name = os['distro_name']

View File

@@ -2,21 +2,11 @@
"architecture": [
{
"platform": "linux/amd64",
"runner": [
"self-hosted",
"Linux",
"X64",
"heavy"
]
"runner": ["self-hosted", "Linux", "X64", "heavy"]
},
{
"platform": "linux/arm64",
"runner": [
"self-hosted",
"Linux",
"ARM64",
"heavy-arm64"
]
"runner": ["self-hosted", "Linux", "ARM64", "heavy-arm64"]
}
],
"os": [
@@ -159,12 +149,6 @@
"compiler_version": "19"
}
],
"build_type": [
"Debug",
"Release"
],
"cmake_args": [
"-Dunity=OFF",
"-Dunity=ON"
]
"build_type": ["Debug", "Release"],
"cmake_args": ["-Dunity=OFF", "-Dunity=ON"]
}

View File

@@ -2,12 +2,7 @@
"architecture": [
{
"platform": "macos/arm64",
"runner": [
"self-hosted",
"macOS",
"ARM64",
"mac-runner-m1"
]
"runner": ["self-hosted", "macOS", "ARM64", "mac-runner-m1"]
}
],
"os": [
@@ -18,10 +13,7 @@
"compiler_version": ""
}
],
"build_type": [
"Debug",
"Release"
],
"build_type": ["Debug", "Release"],
"cmake_args": [
"-Dunity=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5",
"-Dunity=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5"

View File

@@ -2,9 +2,7 @@
"architecture": [
{
"platform": "windows/amd64",
"runner": [
"windows-latest"
]
"runner": ["windows-latest"]
}
],
"os": [
@@ -15,12 +13,6 @@
"compiler_version": ""
}
],
"build_type": [
"Debug",
"Release"
],
"cmake_args": [
"-Dunity=OFF",
"-Dunity=ON"
]
"build_type": ["Debug", "Release"],
"cmake_args": ["-Dunity=OFF", "-Dunity=ON"]
}

View File

@@ -9,25 +9,25 @@ on:
workflow_call:
inputs:
build_dir:
description: 'The directory where to build.'
description: "The directory where to build."
required: false
type: string
default: '.build'
default: ".build"
conan_remote_name:
description: 'The name of the Conan remote to use.'
description: "The name of the Conan remote to use."
required: true
type: string
conan_remote_url:
description: 'The URL of the Conan endpoint to use.'
description: "The URL of the Conan endpoint to use."
required: true
type: string
dependencies_force_build:
description: 'Force building of all dependencies.'
description: "Force building of all dependencies."
required: false
type: boolean
default: false
dependencies_force_upload:
description: 'Force uploading of all dependencies.'
description: "Force uploading of all dependencies."
required: false
type: boolean
default: false
@@ -40,16 +40,16 @@ on:
description: 'The strategy matrix to use for generating the configurations ("minimal", "all").'
required: false
type: string
default: 'minimal'
default: "minimal"
secrets:
codecov_token:
description: 'The Codecov token to use for uploading coverage reports.'
description: "The Codecov token to use for uploading coverage reports."
required: false
conan_remote_username:
description: 'The username for logging into the Conan remote. If not provided, the dependencies will not be uploaded.'
description: "The username for logging into the Conan remote. If not provided, the dependencies will not be uploaded."
required: false
conan_remote_password:
description: 'The password for logging into the Conan remote. If not provided, the dependencies will not be uploaded.'
description: "The password for logging into the Conan remote. If not provided, the dependencies will not be uploaded."
required: false
concurrency:

View File

@@ -13,9 +13,9 @@ defaults:
shell: bash
jobs:
clang-format:
pre-commit:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/ci/tools-rippled-clang-format
container: ghcr.io/xrplf/ci/tools-rippled-pre-commit
steps:
# The $GITHUB_WORKSPACE and ${{ github.workspace }} might not point to the
# same directory for jobs running in containers. The actions/checkout step
@@ -38,48 +38,11 @@ jobs:
echo 'Checking environment variables.'
env | sort
echo 'Checking pre-commit version.'
pre-commit --version
echo 'Checking clang-format version.'
clang-format --version
- name: Format code
run: find include src tests -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format -i {} +
- name: Check for differences
env:
MESSAGE: |
One or more files did not conform to the formatting specified in
.clang-format. Maybe you did not run 'git-clang-format' or
'clang-format' before committing, or your version of clang-format
has an incompatibility with the one used here (see the "Check
configuration" step above).
Run 'git-clang-format --extensions cpp,h,hpp,ipp develop' in your
repo, and then commit and push the changes.
run: |
DIFF=$(git status --porcelain)
if [ -n "${DIFF}" ]; then
# Print the files that changed to give the contributor a hint about
# what to expect when running git-clang-format on their own machine.
git status
echo "${MESSAGE}"
exit 1
fi
prettier:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/ci/tools-rippled-prettier
steps:
- name: Configure git safe.directory
run: |
git config --global --add safe.directory $GITHUB_WORKSPACE
git config --global --add safe.directory ${{ github.workspace }}
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Check configuration
run: |
echo 'Checking path.'
echo ${PATH} | tr ':' '\n'
echo 'Checking environment variables.'
env | sort
echo 'Checking NPM version.'
npm --version
@@ -90,22 +53,22 @@ jobs:
echo 'Checking prettier version.'
prettier --version
- name: Format code
run: prettier --check .
run: pre-commit run --show-diff-on-failure --color=always --all-files
- name: Check for differences
env:
MESSAGE: |
One or more files did not conform to the formatting rules specified
by Prettier. Maybe you did not run 'prettier' before committing, or
your version of prettier has an incompatibility with the one used
here (see the "Check configuration" step above).
One or more files did not conform to the formatting. Maybe you did
not run 'pre-commit' before committing, or your version of
'clang-format' or 'prettier' has an incompatibility with the ones
used here (see the "Check configuration" step above).
Run 'prettier --check .' in your repo, and then commit and push the
changes.
Run 'pre-commit run --all-files' in your repo, and then commit and
push the changes.
run: |
DIFF=$(git status --porcelain)
if [ -n "${DIFF}" ]; then
# Print the files that changed to give the contributor a hint about
# what to expect when running prettier on their own machine.
# what to expect when running pre-commit on their own machine.
git status
echo "${MESSAGE}"
exit 1

View File

@@ -18,45 +18,45 @@ jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
- name: Check for missing commits
env:
MESSAGE: |
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
- name: Check for missing commits
env:
MESSAGE: |
If you are reading this, then the commits indicated above are missing
from the "develop" and/or "release" branch. Do a reverse-merge as soon
as possible. See CONTRIBUTING.md for instructions.
run: |
set -o pipefail
# Branches are ordered by how "canonical" they are. Every commit in one
# branch should be in all the branches behind it.
order=(master release develop)
branches=()
for branch in "${order[@]}"; do
# Check that the branches exist so that this job will work on forked
# repos, which don't necessarily have master and release branches.
echo "Checking if ${branch} exists."
if git ls-remote --exit-code --heads origin \
refs/heads/${branch} > /dev/null; then
branches+=(origin/${branch})
fi
done
If you are reading this, then the commits indicated above are missing
from the "develop" and/or "release" branch. Do a reverse-merge as soon
as possible. See CONTRIBUTING.md for instructions.
run: |
set -o pipefail
# Branches are ordered by how "canonical" they are. Every commit in one
# branch should be in all the branches behind it.
order=(master release develop)
branches=()
for branch in "${order[@]}"; do
# Check that the branches exist so that this job will work on forked
# repos, which don't necessarily have master and release branches.
echo "Checking if ${branch} exists."
if git ls-remote --exit-code --heads origin \
refs/heads/${branch} > /dev/null; then
branches+=(origin/${branch})
fi
done
prior=()
for branch in "${branches[@]}"; do
if [[ ${#prior[@]} -ne 0 ]]; then
echo "Checking ${prior[@]} for commits missing from ${branch}."
git log --oneline --no-merges "${prior[@]}" \
^$branch | tee -a "missing-commits.txt"
echo
prior=()
for branch in "${branches[@]}"; do
if [[ ${#prior[@]} -ne 0 ]]; then
echo "Checking ${prior[@]} for commits missing from ${branch}."
git log --oneline --no-merges "${prior[@]}" \
^$branch | tee -a "missing-commits.txt"
echo
fi
prior+=("${branch}")
done
if [[ $(cat missing-commits.txt | wc -l) -ne 0 ]]; then
echo "${MESSAGE}"
exit 1
fi
prior+=("${branch}")
done
if [[ $(cat missing-commits.txt | wc -l) -ne 0 ]]; then
echo "${MESSAGE}"
exit 1
fi

View File

@@ -8,22 +8,22 @@ on:
workflow_call:
inputs:
conan_remote_name:
description: 'The name of the Conan remote to use.'
description: "The name of the Conan remote to use."
required: true
type: string
conan_remote_url:
description: 'The URL of the Conan endpoint to use.'
description: "The URL of the Conan endpoint to use."
required: true
type: string
secrets:
clio_notify_token:
description: 'The GitHub token to notify Clio about new versions.'
description: "The GitHub token to notify Clio about new versions."
required: true
conan_remote_username:
description: 'The username for logging into the Conan remote.'
description: "The username for logging into the Conan remote."
required: true
conan_remote_password:
description: 'The password for logging into the Conan remote.'
description: "The password for logging into the Conan remote."
required: true
concurrency:

View File

@@ -7,28 +7,28 @@ name: PR
on:
pull_request:
paths:
- '.github/actions/build-deps/**'
- '.github/actions/build-test/**'
- '.github/scripts/levelization/**'
- '.github/scripts/strategy-matrix/**'
- '.github/workflows/build-test.yml'
- '.github/workflows/check-format.yml'
- '.github/workflows/check-levelization.yml'
- '.github/workflows/notify-clio.yml'
- '.github/workflows/on-pr.yml'
- ".github/actions/build-deps/**"
- ".github/actions/build-test/**"
- ".github/scripts/levelization/**"
- ".github/scripts/strategy-matrix/**"
- ".github/workflows/build-test.yml"
- ".github/workflows/check-format.yml"
- ".github/workflows/check-levelization.yml"
- ".github/workflows/notify-clio.yml"
- ".github/workflows/on-pr.yml"
# Keep the list of paths below in sync with those in the `on-trigger.yml`
# file.
- 'cmake/**'
- 'conan/**'
- 'external/**'
- 'include/**'
- 'src/**'
- 'tests/**'
- '.clang-format'
- '.codecov.yml'
- '.pre-commit-config.yaml'
- 'CMakeLists.txt'
- 'conanfile.py'
- "cmake/**"
- "conan/**"
- "external/**"
- "include/**"
- "src/**"
- "tests/**"
- ".clang-format"
- ".codecov.yml"
- ".pre-commit-config.yaml"
- "CMakeLists.txt"
- "conanfile.py"
types:
- opened
- synchronize
@@ -69,7 +69,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: No-op
run: echo ''
run: true
check-format:
needs: should-run
@@ -86,7 +86,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: No-op
run: echo ''
run: true
outputs:
conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}
conan_remote_url: ${{ env.CONAN_REMOTE_URL }}

View File

@@ -13,31 +13,31 @@ on:
- release
- master
paths:
- '.github/actions/build-deps/**'
- '.github/actions/build-test/**'
- '.github/scripts/strategy-matrix/**'
- '.github/workflows/build-test.yml'
- '.github/workflows/check-missing-commits.yml'
- '.github/workflows/on-trigger.yml'
- '.github/workflows/publish-docs.yml'
- ".github/actions/build-deps/**"
- ".github/actions/build-test/**"
- ".github/scripts/strategy-matrix/**"
- ".github/workflows/build-test.yml"
- ".github/workflows/check-missing-commits.yml"
- ".github/workflows/on-trigger.yml"
- ".github/workflows/publish-docs.yml"
# Keep the list of paths below in sync with those in `on-pr.yml`.
- 'cmake/**'
- 'conan/**'
- 'external/**'
- 'include/**'
- 'src/**'
- 'tests/**'
- '.clang-format'
- '.codecov.yml'
- '.pre-commit-config.yaml'
- 'CMakeLists.txt'
- 'conanfile.py'
- "cmake/**"
- "conan/**"
- "external/**"
- "include/**"
- "src/**"
- "tests/**"
- ".clang-format"
- ".codecov.yml"
- ".pre-commit-config.yaml"
- "CMakeLists.txt"
- "conanfile.py"
# Run at 06:32 UTC on every day of the week from Monday through Friday. This
# will force all dependencies to be rebuilt, which is useful to verify that
# all dependencies can be built successfully. Only the dependencies that
# are actually missing from the remote will be uploaded.
schedule:
- cron: '32 6 * * 1-5'
- cron: "32 6 * * 1-5"
# Run when manually triggered via the GitHub UI or API. If `force_upload` is
# true, then the dependencies that were missing (`force_rebuild` is false) or
# rebuilt (`force_rebuild` is true) will be uploaded, overwriting existing
@@ -45,12 +45,12 @@ on:
workflow_dispatch:
inputs:
dependencies_force_build:
description: 'Force building of all dependencies.'
description: "Force building of all dependencies."
required: false
type: boolean
default: false
dependencies_force_upload:
description: 'Force uploading of all dependencies.'
description: "Force uploading of all dependencies."
required: false
type: boolean
default: false
@@ -109,7 +109,7 @@ jobs:
dependencies_force_build: ${{ needs.generate-outputs.outputs.dependencies_force_build == 'true' }}
dependencies_force_upload: ${{ needs.generate-outputs.outputs.dependencies_force_upload == 'true' }}
os: ${{ matrix.os }}
strategy_matrix: 'all'
strategy_matrix: "all"
secrets:
conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}

View File

@@ -5,13 +5,13 @@ name: Build and publish documentation
on:
push:
paths:
- '.github/workflows/publish-docs.yml'
- '*.md'
- '**/*.md'
- 'docs/**'
- 'include/**'
- 'src/libxrpl/**'
- 'src/xrpld/**'
- ".github/workflows/publish-docs.yml"
- "*.md"
- "**/*.md"
- "docs/**"
- "include/**"
- "src/libxrpl/**"
- "src/xrpld/**"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -22,7 +22,7 @@ defaults:
shell: bash
env:
BUILD_DIR: .build
BUILD_DIR: .build
jobs:
publish:

2
.gitignore vendored
View File

@@ -110,4 +110,4 @@ bld.rippled/
.vscode
# Suggested in-tree build directory
/.build/
/.build*/

View File

@@ -1,6 +1,64 @@
# .pre-commit-config.yaml
# To run pre-commit hooks, first install pre-commit:
# - `pip install pre-commit==${PRE_COMMIT_VERSION}`
# - `pip install pre-commit-hooks==${PRE_COMMIT_HOOKS_VERSION}`
#
# Depending on your system, you can use `brew install` or `apt install` as well
# for installing the pre-commit package, but `pip` is needed to install the
# hooks; you can also use `pipx` if you prefer.
# Next, install the required formatters:
# - `pip install clang-format==${CLANG_VERSION}`
# - `npm install prettier@${PRETTIER_VERSION}`
#
# See https://github.com/XRPLF/ci/blob/main/.github/workflows/tools-rippled.yml
# for the versions used in the CI pipeline. You will need to have the exact same
# versions of the tools installed on your system to produce the same results as
# the pipeline.
#
# Then, run the following command to install the git hook scripts:
# - `pre-commit install`
# You can run all configured hooks against all files with:
# - `pre-commit run --all-files`
# To manually run a specific hook, use:
# - `pre-commit run <hook_id> --all-files`
# To run the hooks against only the files changed in the current commit, use:
# - `pre-commit run`
repos:
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v18.1.8
- repo: local
hooks:
- id: clang-format
name: clang-format
language: system
entry: clang-format -i
files: '\.(cpp|hpp|h|ipp|proto)$'
- id: trailing-whitespace
name: trailing-whitespace
entry: trailing-whitespace-fixer
language: system
types: [text]
- id: end-of-file
name: end-of-file
entry: end-of-file-fixer
language: system
types: [text]
- id: mixed-line-ending
name: mixed-line-ending
entry: mixed-line-ending
language: system
types: [text]
- id: check-merge-conflict
name: check-merge-conflict
entry: check-merge-conflict --assume-in-merge
language: system
types: [text]
- repo: local
hooks:
- id: prettier
name: prettier
language: system
entry: prettier --ignore-unknown --write
exclude: |
(?x)^(
external/.*|
.github/scripts/levelization/results/.*\.txt
)$

View File

@@ -1,2 +1 @@
external
.*

View File

@@ -5,7 +5,7 @@ then
name=$( basename $0 )
cat <<- USAGE
Usage: $name <username>
Where <username> is the Github username of the upstream repo. e.g. XRPLF
USAGE
exit 0
@@ -83,4 +83,3 @@ fi
_run git fetch --jobs=$(nproc) upstreams
exit 0

View File

@@ -5,7 +5,7 @@ then
name=$( basename $0 )
cat <<- USAGE
Usage: $name workbranch base/branch user/branch [user/branch [...]]
* workbranch will be created locally from base/branch
* base/branch and user/branch may be specified as user:branch to allow
easy copying from Github PRs
@@ -66,4 +66,3 @@ git push $push HEAD:$b
git fetch $repo
-------------------------------------------------------------------
PUSH

View File

@@ -396,8 +396,8 @@
# true - enables compression
# false - disables compression [default].
#
# The rippled server can save bandwidth by compressing its peer-to-peer communications,
# at a cost of greater CPU usage. If you enable link compression,
# The rippled server can save bandwidth by compressing its peer-to-peer communications,
# at a cost of greater CPU usage. If you enable link compression,
# the server automatically compresses communications with peer servers
# that also have link compression enabled.
# https://xrpl.org/enable-link-compression.html
@@ -1011,7 +1011,7 @@
# that rippled is still in sync with the network,
# and that the validated ledger is less than
# 'age_threshold_seconds' old. If not, then continue
# sleeping for this number of seconds and
# sleeping for this number of seconds and
# checking until healthy.
# Default is 5.
#
@@ -1113,7 +1113,7 @@
# page_size Valid values: integer (MUST be power of 2 between 512 and 65536)
# The default is 4096 bytes. This setting determines
# the size of a page in the transaction.db file.
# See https://www.sqlite.org/pragma.html#pragma_page_size
# See https://www.sqlite.org/pragma.html#pragma_page_size
# for more details about the available options.
#
# journal_size_limit Valid values: integer

View File

@@ -101,7 +101,7 @@ target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol)
# Level 06
add_module(xrpl net)
target_link_libraries(xrpl.libxrpl.net PUBLIC
target_link_libraries(xrpl.libxrpl.net PUBLIC
xrpl.libxrpl.basics
xrpl.libxrpl.json
xrpl.libxrpl.protocol

View File

@@ -5,8 +5,8 @@ skinparam roundcorner 20
skinparam maxmessagesize 160
actor "Rippled Start" as RS
participant "Timer" as T
participant "NetworkOPs" as NOP
participant "Timer" as T
participant "NetworkOPs" as NOP
participant "ValidatorList" as VL #lightgreen
participant "Consensus" as GC
participant "ConsensusAdaptor" as CA #lightgreen
@@ -20,7 +20,7 @@ VL -> NOP
NOP -> VL: update trusted validators
activate VL
VL -> VL: re-calculate quorum
hnote over VL#lightgreen: ignore negative listed validators\nwhen calculate quorum
hnote over VL#lightgreen: ignore negative listed validators\nwhen calculate quorum
VL -> NOP
deactivate VL
NOP -> GC: start round
@@ -36,14 +36,14 @@ activate GC
end
alt phase == OPEN
alt should close ledger
alt should close ledger
GC -> GC: phase = ESTABLISH
GC -> CA: onClose
activate CA
alt sqn%256==0
alt sqn%256==0
CA -[#green]> RM: <font color=green>getValidations
CA -[#green]> CA: <font color=green>create UNLModify Tx
hnote over CA#lightgreen: use validatations of the last 256 ledgers\nto figure out UNLModify Tx candidates.\nIf any, create UNLModify Tx, and add to TxSet.
CA -[#green]> CA: <font color=green>create UNLModify Tx
hnote over CA#lightgreen: use validatations of the last 256 ledgers\nto figure out UNLModify Tx candidates.\nIf any, create UNLModify Tx, and add to TxSet.
end
CA -> GC
GC -> CA: propose
@@ -61,14 +61,14 @@ else phase == ESTABLISH
CA -> CA : build LCL
hnote over CA #lightgreen: copy negative UNL from parent ledger
alt sqn%256==0
CA -[#green]> CA: <font color=green>Adjust negative UNL
CA -[#green]> CA: <font color=green>Adjust negative UNL
CA -[#green]> CA: <font color=green>apply UNLModify Tx
end
CA -> CA : validate and send validation message
activate NOP
CA -> NOP : end consensus and\n<b>begin next consensus round
deactivate NOP
deactivate CA
deactivate CA
hnote over RM: receive validations
end
else phase == ACCEPTED
@@ -76,4 +76,4 @@ else phase == ACCEPTED
end
deactivate GC
@enduml
@enduml

View File

@@ -4,7 +4,7 @@ class TimeoutCounter {
#app_ : Application&
}
TimeoutCounter o-- "1" Application
TimeoutCounter o-- "1" Application
': app_
Stoppable <.. Application
@@ -14,13 +14,13 @@ class Application {
-m_inboundLedgers : uptr<InboundLedgers>
}
Application *-- "1" LedgerReplayer
Application *-- "1" LedgerReplayer
': m_ledgerReplayer
Application *-- "1" InboundLedgers
Application *-- "1" InboundLedgers
': m_inboundLedgers
Stoppable <.. InboundLedgers
Application "1" --o InboundLedgers
Application "1" --o InboundLedgers
': app_
class InboundLedgers {
@@ -28,9 +28,9 @@ class InboundLedgers {
}
Stoppable <.. LedgerReplayer
InboundLedgers "1" --o LedgerReplayer
InboundLedgers "1" --o LedgerReplayer
': inboundLedgers_
Application "1" --o LedgerReplayer
Application "1" --o LedgerReplayer
': app_
class LedgerReplayer {
@@ -42,17 +42,17 @@ class LedgerReplayer {
-skipLists_ : hash_map<u256, wptr<SkipListAcquire>>
}
LedgerReplayer *-- LedgerReplayTask
LedgerReplayer *-- LedgerReplayTask
': tasks_
LedgerReplayer o-- LedgerDeltaAcquire
LedgerReplayer o-- LedgerDeltaAcquire
': deltas_
LedgerReplayer o-- SkipListAcquire
LedgerReplayer o-- SkipListAcquire
': skipLists_
TimeoutCounter <.. LedgerReplayTask
InboundLedgers "1" --o LedgerReplayTask
InboundLedgers "1" --o LedgerReplayTask
': inboundLedgers_
LedgerReplayer "1" --o LedgerReplayTask
LedgerReplayer "1" --o LedgerReplayTask
': replayer_
class LedgerReplayTask {
@@ -63,15 +63,15 @@ class LedgerReplayTask {
+addDelta(sptr<LedgerDeltaAcquire>)
}
LedgerReplayTask *-- "1" SkipListAcquire
LedgerReplayTask *-- "1" SkipListAcquire
': skipListAcquirer_
LedgerReplayTask *-- LedgerDeltaAcquire
LedgerReplayTask *-- LedgerDeltaAcquire
': deltas_
TimeoutCounter <.. SkipListAcquire
InboundLedgers "1" --o SkipListAcquire
InboundLedgers "1" --o SkipListAcquire
': inboundLedgers_
LedgerReplayer "1" --o SkipListAcquire
LedgerReplayer "1" --o SkipListAcquire
': replayer_
LedgerReplayTask --o SkipListAcquire : implicit via callback
@@ -83,9 +83,9 @@ class SkipListAcquire {
}
TimeoutCounter <.. LedgerDeltaAcquire
InboundLedgers "1" --o LedgerDeltaAcquire
InboundLedgers "1" --o LedgerDeltaAcquire
': inboundLedgers_
LedgerReplayer "1" --o LedgerDeltaAcquire
LedgerReplayer "1" --o LedgerDeltaAcquire
': replayer_
LedgerReplayTask --o LedgerDeltaAcquire : implicit via callback
@@ -95,4 +95,4 @@ class LedgerDeltaAcquire {
-replayer_ : LedgerReplayer&
-dataReadyCallbacks_ : vector<callback>
}
@enduml
@enduml

View File

@@ -38,7 +38,7 @@ deactivate lr
loop
lr -> lda : make_shared(ledgerId, ledgerSeq)
return delta
lr -> lrt : addDelta(delta)
lr -> lrt : addDelta(delta)
lrt -> lda : addDataCallback(callback)
return
return
@@ -62,7 +62,7 @@ deactivate peer
lr -> lda : processData(ledgerHeader, txns)
lda -> lda : notify()
note over lda: call the callbacks added by\naddDataCallback(callback).
lda -> lrt : callback(ledgerId)
lda -> lrt : callback(ledgerId)
lrt -> lrt : deltaReady(ledgerId)
lrt -> lrt : tryAdvance()
loop as long as child can be built
@@ -82,4 +82,4 @@ deactivate peer
deactivate peer
@enduml
@enduml

View File

@@ -21,6 +21,7 @@
#define RIPPLE_BASICS_SHAMAP_HASH_H_INCLUDED
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/partitioned_unordered_map.h>
#include <ostream>

View File

@@ -90,6 +90,9 @@ public:
int
getCacheSize() const;
int
getTrackSize() const;
float
getHitRate();
@@ -167,6 +170,9 @@ public:
bool
retrieve(key_type const& key, T& data);
mutex_type&
peekMutex();
std::vector<key_type>
getKeys() const;
@@ -187,14 +193,11 @@ public:
private:
SharedPointerType
initialFetch(key_type const& key);
initialFetch(key_type const& key, std::lock_guard<mutex_type> const& l);
void
collect_metrics();
Mutex&
lockPartition(key_type const& key) const;
private:
struct Stats
{
@@ -297,8 +300,8 @@ private:
[[maybe_unused]] clock_type::time_point const& now,
typename KeyValueCacheType::map_type& partition,
SweptPointersVector& stuffToSweep,
std::atomic<int>& allRemoval,
Mutex& partitionLock);
std::atomic<int>& allRemovals,
std::lock_guard<std::recursive_mutex> const&);
[[nodiscard]] std::thread
sweepHelper(
@@ -307,12 +310,14 @@ private:
typename KeyOnlyCacheType::map_type& partition,
SweptPointersVector&,
std::atomic<int>& allRemovals,
Mutex& partitionLock);
std::lock_guard<std::recursive_mutex> const&);
beast::Journal m_journal;
clock_type& m_clock;
Stats m_stats;
mutex_type mutable m_mutex;
// Used for logging
std::string m_name;
@@ -323,11 +328,10 @@ private:
clock_type::duration const m_target_age;
// Number of items cached
std::atomic<int> m_cache_count;
int m_cache_count;
cache_type m_cache; // Hold strong reference to recent objects
std::atomic<std::uint64_t> m_hits;
std::atomic<std::uint64_t> m_misses;
mutable std::vector<mutex_type> partitionLocks_;
std::uint64_t m_hits;
std::uint64_t m_misses;
};
} // namespace ripple

View File

@@ -22,7 +22,6 @@
#include <xrpl/basics/IntrusivePointer.ipp>
#include <xrpl/basics/TaggedCache.h>
#include <xrpl/beast/core/CurrentThreadName.h>
namespace ripple {
@@ -61,7 +60,6 @@ inline TaggedCache<
, m_hits(0)
, m_misses(0)
{
partitionLocks_ = std::vector<mutex_type>(m_cache.partitions());
}
template <
@@ -110,14 +108,8 @@ TaggedCache<
static unsigned long call_count{0};
JLOG(m_journal.debug()) << "TaggedCache (" << m_name << ") lock stats,"
<< ", size, call_count = " << call_count++;
std::size_t totalSize = 0;
for (size_t i = 0; i < partitionLocks_.size(); ++i)
{
std::lock_guard<Mutex> lock(partitionLocks_[i]);
totalSize += m_cache.map()[i].size();
}
return totalSize;
std::lock_guard lock(m_mutex);
return m_cache.size();
}
template <
@@ -140,7 +132,32 @@ TaggedCache<
KeyEqual,
Mutex>::getCacheSize() const
{
return m_cache_count.load(std::memory_order_relaxed);
std::lock_guard lock(m_mutex);
return m_cache_count;
}
template <
class Key,
class T,
bool IsKeyCache,
class SharedWeakUnionPointer,
class SharedPointerType,
class Hash,
class KeyEqual,
class Mutex>
inline int
TaggedCache<
Key,
T,
IsKeyCache,
SharedWeakUnionPointer,
SharedPointerType,
Hash,
KeyEqual,
Mutex>::getTrackSize() const
{
std::lock_guard lock(m_mutex);
return m_cache.size();
}
template <
@@ -163,10 +180,9 @@ TaggedCache<
KeyEqual,
Mutex>::getHitRate()
{
auto const hits = m_hits.load(std::memory_order_relaxed);
auto const misses = m_misses.load(std::memory_order_relaxed);
float const total = float(hits + misses);
return hits * (100.0f / std::max(1.0f, total));
std::lock_guard lock(m_mutex);
auto const total = static_cast<float>(m_hits + m_misses);
return m_hits * (100.0f / std::max(1.0f, total));
}
template <
@@ -189,12 +205,9 @@ TaggedCache<
KeyEqual,
Mutex>::clear()
{
for (auto& mutex : partitionLocks_)
mutex.lock();
std::lock_guard lock(m_mutex);
m_cache.clear();
for (auto& mutex : partitionLocks_)
mutex.unlock();
m_cache_count.store(0, std::memory_order_relaxed);
m_cache_count = 0;
}
template <
@@ -217,9 +230,11 @@ TaggedCache<
KeyEqual,
Mutex>::reset()
{
clear();
m_hits.store(0, std::memory_order_relaxed);
m_misses.store(0, std::memory_order_relaxed);
std::lock_guard lock(m_mutex);
m_cache.clear();
m_cache_count = 0;
m_hits = 0;
m_misses = 0;
}
template <
@@ -248,7 +263,7 @@ TaggedCache<
<< "TaggedCache (" << m_name << ") lock stats,"
<< ", touch_if_exists, call_count = " << call_count++;
std::lock_guard<Mutex> lock(lockPartition(key));
std::lock_guard lock(m_mutex);
auto const iter(m_cache.find(key));
if (iter == m_cache.end())
{
@@ -290,6 +305,8 @@ TaggedCache<
auto const start = std::chrono::steady_clock::now();
{
std::lock_guard lock(m_mutex);
if (m_target_size == 0 ||
(static_cast<int>(m_cache.size()) <= m_target_size))
{
@@ -321,13 +338,12 @@ TaggedCache<
m_cache.map()[p],
allStuffToSweep[p],
allRemovals,
partitionLocks_[p]));
lock));
}
for (std::thread& worker : workers)
worker.join();
int removals = allRemovals.load(std::memory_order_relaxed);
m_cache_count.fetch_sub(removals, std::memory_order_relaxed);
m_cache_count -= allRemovals;
}
// At this point allStuffToSweep will go out of scope outside the lock
// and decrement the reference count on each strong pointer.
@@ -365,8 +381,7 @@ TaggedCache<
static unsigned long call_count{0};
JLOG(m_journal.debug()) << "TaggedCache (" << m_name << ") lock stats,"
<< ", del, call_count = " << call_count++;
std::lock_guard<Mutex> lock(lockPartition(key));
std::lock_guard lock(m_mutex);
auto cit = m_cache.find(key);
@@ -379,7 +394,7 @@ TaggedCache<
if (entry.isCached())
{
m_cache_count.fetch_sub(1, std::memory_order_relaxed);
--m_cache_count;
entry.ptr.convertToWeak();
ret = true;
}
@@ -417,20 +432,20 @@ TaggedCache<
{
// Return canonical value, store if needed, refresh in cache
// Return values: true=we had the data already
std::lock_guard lock(m_mutex);
static unsigned long call_count{0};
JLOG(m_journal.debug()) << "TaggedCache (" << m_name << ") lock stats,"
<< ", canonicalize, call_count = " << call_count++;
std::lock_guard<Mutex> lock(lockPartition(key));
auto cit = m_cache.find(key);
if (cit == m_cache.end())
{
m_cache.emplace(
std::piecewise_construct,
std::forward_as_tuple(key),
std::forward_as_tuple(m_clock.now(), data));
m_cache_count.fetch_add(1, std::memory_order_relaxed);
++m_cache_count;
return false;
}
@@ -479,12 +494,12 @@ TaggedCache<
data = cachedData;
}
m_cache_count.fetch_add(1, std::memory_order_relaxed);
++m_cache_count;
return true;
}
entry.ptr = data;
m_cache_count.fetch_add(1, std::memory_order_relaxed);
++m_cache_count;
return false;
}
@@ -564,11 +579,10 @@ TaggedCache<
JLOG(m_journal.debug()) << "TaggedCache (" << m_name << ") lock stats,"
<< ", fetch, call_count = " << call_count++;
std::lock_guard<Mutex> lock(lockPartition(key));
auto ret = initialFetch(key);
std::lock_guard<mutex_type> l(m_mutex);
auto ret = initialFetch(key, l);
if (!ret)
m_misses.fetch_add(1, std::memory_order_relaxed);
++m_misses;
return ret;
}
@@ -636,8 +650,8 @@ TaggedCache<
JLOG(m_journal.debug()) << "TaggedCache (" << m_name << ") lock stats,"
<< ", insert, call_count = " << call_count++;
std::lock_guard lock(m_mutex);
clock_type::time_point const now(m_clock.now());
std::lock_guard<Mutex> lock(lockPartition(key));
auto [it, inserted] = m_cache.emplace(
std::piecewise_construct,
std::forward_as_tuple(key),
@@ -677,6 +691,29 @@ TaggedCache<
return true;
}
template <
class Key,
class T,
bool IsKeyCache,
class SharedWeakUnionPointer,
class SharedPointerType,
class Hash,
class KeyEqual,
class Mutex>
inline auto
TaggedCache<
Key,
T,
IsKeyCache,
SharedWeakUnionPointer,
SharedPointerType,
Hash,
KeyEqual,
Mutex>::peekMutex() -> mutex_type&
{
return m_mutex;
}
template <
class Key,
class T,
@@ -704,13 +741,10 @@ TaggedCache<
std::vector<key_type> v;
{
std::lock_guard lock(m_mutex);
v.reserve(m_cache.size());
for (std::size_t i = 0; i < partitionLocks_.size(); ++i)
{
std::lock_guard<Mutex> lock(partitionLocks_[i]);
for (auto const& entry : m_cache.map()[i])
v.push_back(entry.first);
}
for (auto const& _ : m_cache)
v.push_back(_.first);
}
return v;
@@ -736,12 +770,11 @@ TaggedCache<
KeyEqual,
Mutex>::rate() const
{
auto const hits = m_hits.load(std::memory_order_relaxed);
auto const misses = m_misses.load(std::memory_order_relaxed);
auto const tot = hits + misses;
std::lock_guard lock(m_mutex);
auto const tot = m_hits + m_misses;
if (tot == 0)
return 0.0;
return double(hits) / tot;
return 0;
return double(m_hits) / tot;
}
template <
@@ -769,16 +802,18 @@ TaggedCache<
JLOG(m_journal.debug()) << "TaggedCache (" << m_name << ") lock stats,"
<< ", fetch, call_count = " << call_count++;
std::lock_guard<Mutex> lock(lockPartition(digest));
if (auto ret = initialFetch(digest))
return ret;
{
std::lock_guard l(m_mutex);
if (auto ret = initialFetch(digest, l))
return ret;
}
auto sle = h();
if (!sle)
return {};
m_misses.fetch_add(1, std::memory_order_relaxed);
std::lock_guard l(m_mutex);
++m_misses;
auto const [it, inserted] =
m_cache.emplace(digest, Entry(m_clock.now(), std::move(sle)));
if (!inserted)
@@ -805,10 +840,9 @@ TaggedCache<
SharedPointerType,
Hash,
KeyEqual,
Mutex>::initialFetch(key_type const& key)
Mutex>::
initialFetch(key_type const& key, std::lock_guard<mutex_type> const& l)
{
std::lock_guard<Mutex> lock(lockPartition(key));
auto cit = m_cache.find(key);
if (cit == m_cache.end())
return {};
@@ -816,7 +850,7 @@ TaggedCache<
Entry& entry = cit->second;
if (entry.isCached())
{
m_hits.fetch_add(1, std::memory_order_relaxed);
++m_hits;
entry.touch(m_clock.now());
return entry.ptr.getStrong();
}
@@ -824,13 +858,12 @@ TaggedCache<
if (entry.isCached())
{
// independent of cache size, so not counted as a hit
m_cache_count.fetch_add(1, std::memory_order_relaxed);
++m_cache_count;
entry.touch(m_clock.now());
return entry.ptr.getStrong();
}
m_cache.erase(cit);
return {};
}
@@ -859,11 +892,10 @@ TaggedCache<
{
beast::insight::Gauge::value_type hit_rate(0);
{
auto const hits = m_hits.load(std::memory_order_relaxed);
auto const misses = m_misses.load(std::memory_order_relaxed);
auto const total = hits + misses;
std::lock_guard lock(m_mutex);
auto const total(m_hits + m_misses);
if (total != 0)
hit_rate = (hits * 100) / total;
hit_rate = (m_hits * 100) / total;
}
m_stats.hit_rate.set(hit_rate);
}
@@ -894,11 +926,9 @@ TaggedCache<
typename KeyValueCacheType::map_type& partition,
SweptPointersVector& stuffToSweep,
std::atomic<int>& allRemovals,
Mutex& partitionLock)
std::lock_guard<std::recursive_mutex> const&)
{
return std::thread([&, this]() {
beast::setCurrentThreadName("sweep-KVCache");
int cacheRemovals = 0;
int mapRemovals = 0;
@@ -907,8 +937,6 @@ TaggedCache<
<< "TaggedCache (" << m_name << ") lock stats,"
<< ", sweep-KVCache, call_count = " << call_count++;
std::lock_guard<Mutex> lock(partitionLock);
// Keep references to all the stuff we sweep
// so that we can destroy them outside the lock.
stuffToSweep.reserve(partition.size());
@@ -992,11 +1020,9 @@ TaggedCache<
typename KeyOnlyCacheType::map_type& partition,
SweptPointersVector&,
std::atomic<int>& allRemovals,
Mutex& partitionLock)
std::lock_guard<std::recursive_mutex> const&)
{
return std::thread([&, this]() {
beast::setCurrentThreadName("sweep-KCache");
int cacheRemovals = 0;
int mapRemovals = 0;
@@ -1005,8 +1031,6 @@ TaggedCache<
<< "TaggedCache (" << m_name << ") lock stats,"
<< ", sweep-KCache, call_count = " << call_count++;
std::lock_guard<Mutex> lock(partitionLock);
// Keep references to all the stuff we sweep
// so that we can destroy them outside the lock.
{
@@ -1041,29 +1065,6 @@ TaggedCache<
});
}
template <
class Key,
class T,
bool IsKeyCache,
class SharedWeakUnionPointer,
class SharedPointerType,
class Hash,
class KeyEqual,
class Mutex>
inline Mutex&
TaggedCache<
Key,
T,
IsKeyCache,
SharedWeakUnionPointer,
SharedPointerType,
Hash,
KeyEqual,
Mutex>::lockPartition(key_type const& key) const
{
return partitionLocks_[m_cache.partition_index(key)];
}
} // namespace ripple
#endif

View File

@@ -277,12 +277,6 @@ public:
return map_;
}
partition_map_type const&
map() const
{
return map_;
}
iterator
begin()
{
@@ -327,12 +321,6 @@ public:
return cend();
}
std::size_t
partition_index(key_type const& key) const
{
return partitioner(key);
}
private:
template <class T>
void

View File

@@ -34,4 +34,4 @@ serializeBatch(
msg.addBitString(txid);
}
} // namespace ripple
} // namespace ripple

View File

@@ -22,6 +22,7 @@
#include <xrpl/basics/ByteUtilities.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/partitioned_unordered_map.h>
#include <cstdint>

View File

@@ -141,7 +141,7 @@ constexpr std::uint32_t const tfTransferable = 0x00000008;
constexpr std::uint32_t const tfMutable = 0x00000010;
// MPTokenIssuanceCreate flags:
// NOTE - there is intentionally no flag here for lsfMPTLocked, which this transaction cannot mutate.
// NOTE - there is intentionally no flag here for lsfMPTLocked, which this transaction cannot mutate.
constexpr std::uint32_t const tfMPTCanLock = lsfMPTCanLock;
constexpr std::uint32_t const tfMPTRequireAuth = lsfMPTRequireAuth;
constexpr std::uint32_t const tfMPTCanEscrow = lsfMPTCanEscrow;
@@ -243,7 +243,7 @@ constexpr std::uint32_t tfUntilFailure = 0x00040000;
constexpr std::uint32_t tfIndependent = 0x00080000;
/**
* @note If nested Batch transactions are supported in the future, the tfInnerBatchTxn flag
* will need to be removed from this mask to allow Batch transaction to be inside
* will need to be removed from this mask to allow Batch transaction to be inside
* the sfRawTransactions array.
*/
constexpr std::uint32_t const tfBatchMask =

View File

@@ -505,4 +505,3 @@ LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
#undef EXPAND
#undef LEDGER_ENTRY_DUPLICATE

View File

@@ -36,7 +36,7 @@ namespace BuildInfo {
// and follow the format described at http://semver.org/
//------------------------------------------------------------------------------
// clang-format off
char const* const versionString = "2.6.0-rc2"
char const* const versionString = "2.6.0-rc3"
// clang-format on
#if defined(DEBUG) || defined(SANITIZER)

View File

@@ -145,4 +145,4 @@ Permission::permissionToTxType(uint32_t const& value) const
return static_cast<TxType>(value - 1);
}
} // namespace ripple
} // namespace ripple

View File

@@ -1499,4 +1499,4 @@ class Delegate_test : public beast::unit_test::suite
};
BEAST_DEFINE_TESTSUITE(Delegate, app, ripple);
} // namespace test
} // namespace ripple
} // namespace ripple

View File

@@ -621,4 +621,4 @@ public:
BEAST_DEFINE_TESTSUITE_PRIO(NFTokenAuth, app, ripple, 2);
} // namespace ripple
} // namespace ripple

View File

@@ -58,10 +58,10 @@ public:
// Insert an item, retrieve it, and age it so it gets purged.
{
BEAST_EXPECT(c.getCacheSize() == 0);
BEAST_EXPECT(c.size() == 0);
BEAST_EXPECT(c.getTrackSize() == 0);
BEAST_EXPECT(!c.insert(1, "one"));
BEAST_EXPECT(c.getCacheSize() == 1);
BEAST_EXPECT(c.size() == 1);
BEAST_EXPECT(c.getTrackSize() == 1);
{
std::string s;
@@ -72,7 +72,7 @@ public:
++clock;
c.sweep();
BEAST_EXPECT(c.getCacheSize() == 0);
BEAST_EXPECT(c.size() == 0);
BEAST_EXPECT(c.getTrackSize() == 0);
}
// Insert an item, maintain a strong pointer, age it, and
@@ -80,7 +80,7 @@ public:
{
BEAST_EXPECT(!c.insert(2, "two"));
BEAST_EXPECT(c.getCacheSize() == 1);
BEAST_EXPECT(c.size() == 1);
BEAST_EXPECT(c.getTrackSize() == 1);
{
auto p = c.fetch(2);
@@ -88,14 +88,14 @@ public:
++clock;
c.sweep();
BEAST_EXPECT(c.getCacheSize() == 0);
BEAST_EXPECT(c.size() == 1);
BEAST_EXPECT(c.getTrackSize() == 1);
}
// Make sure its gone now that our reference is gone
++clock;
c.sweep();
BEAST_EXPECT(c.getCacheSize() == 0);
BEAST_EXPECT(c.size() == 0);
BEAST_EXPECT(c.getTrackSize() == 0);
}
// Insert the same key/value pair and make sure we get the same result
@@ -111,7 +111,7 @@ public:
++clock;
c.sweep();
BEAST_EXPECT(c.getCacheSize() == 0);
BEAST_EXPECT(c.size() == 0);
BEAST_EXPECT(c.getTrackSize() == 0);
}
// Put an object in but keep a strong pointer to it, advance the clock a
@@ -121,24 +121,24 @@ public:
// Put an object in
BEAST_EXPECT(!c.insert(4, "four"));
BEAST_EXPECT(c.getCacheSize() == 1);
BEAST_EXPECT(c.size() == 1);
BEAST_EXPECT(c.getTrackSize() == 1);
{
// Keep a strong pointer to it
auto const p1 = c.fetch(4);
BEAST_EXPECT(p1 != nullptr);
BEAST_EXPECT(c.getCacheSize() == 1);
BEAST_EXPECT(c.size() == 1);
BEAST_EXPECT(c.getTrackSize() == 1);
// Advance the clock a lot
++clock;
c.sweep();
BEAST_EXPECT(c.getCacheSize() == 0);
BEAST_EXPECT(c.size() == 1);
BEAST_EXPECT(c.getTrackSize() == 1);
// Canonicalize a new object with the same key
auto p2 = std::make_shared<std::string>("four");
BEAST_EXPECT(c.canonicalize_replace_client(4, p2));
BEAST_EXPECT(c.getCacheSize() == 1);
BEAST_EXPECT(c.size() == 1);
BEAST_EXPECT(c.getTrackSize() == 1);
// Make sure we get the original object
BEAST_EXPECT(p1.get() == p2.get());
}
@@ -146,7 +146,7 @@ public:
++clock;
c.sweep();
BEAST_EXPECT(c.getCacheSize() == 0);
BEAST_EXPECT(c.size() == 0);
BEAST_EXPECT(c.getTrackSize() == 0);
}
}
};

View File

@@ -720,4 +720,4 @@ struct JumpCollector
} // namespace test
} // namespace ripple
#endif
#endif

View File

@@ -59,4 +59,4 @@ public:
} // namespace delegate
} // namespace jtx
} // namespace test
} // namespace ripple
} // namespace ripple

View File

@@ -499,7 +499,16 @@ Env::meta()
close();
}
auto const item = closed()->txRead(txid_);
return item.second;
auto const result = item.second;
if (result == nullptr)
{
test.log << "Env::meta: no metadata for txid: " << txid_ << std::endl;
test.log << "This is probably because the transaction failed with a "
"non-tec error."
<< std::endl;
Throw<std::runtime_error>("Env::meta: no metadata for txid");
}
return result;
}
std::shared_ptr<STTx const>

View File

@@ -64,4 +64,4 @@ entry(jtx::Env& env, jtx::Account const& account, jtx::Account const& authorize)
} // namespace delegate
} // namespace jtx
} // namespace test
} // namespace ripple
} // namespace ripple

View File

@@ -67,6 +67,8 @@ LedgerHistory::insert(
ledger->stateMap().getHash().isNonZero(),
"ripple::LedgerHistory::insert : nonzero hash");
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
bool const alreadyHad = m_ledgers_by_hash.canonicalize_replace_cache(
ledger->info().hash, ledger);
if (validated)
@@ -82,6 +84,7 @@ LedgerHistory::getLedgerHash(LedgerIndex index)
JLOG(j_.debug()) << "LedgerHistory lock stats,"
<< ", getLedgerHash, call_count = " << call_count++;
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
if (auto it = mLedgersByIndex.find(index); it != mLedgersByIndex.end())
return it->second;
return {};
@@ -95,11 +98,13 @@ LedgerHistory::getLedgerBySeq(LedgerIndex index)
<< ", getLedgerBySeq, call_count = " << call_count++;
{
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
auto it = mLedgersByIndex.find(index);
if (it != mLedgersByIndex.end())
{
uint256 hash = it->second;
sl.unlock();
return getLedgerByHash(hash);
}
}
@@ -115,6 +120,7 @@ LedgerHistory::getLedgerBySeq(LedgerIndex index)
{
// Add this ledger to the local tracking by index
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
XRPL_ASSERT(
ret->isImmutable(),
@@ -464,6 +470,8 @@ LedgerHistory::builtLedger(
XRPL_ASSERT(
!hash.isZero(), "ripple::LedgerHistory::builtLedger : nonzero hash");
std::unique_lock sl(m_consensus_validated.peekMutex());
auto entry = std::make_shared<cv_entry>();
m_consensus_validated.canonicalize_replace_client(index, entry);
@@ -504,6 +512,8 @@ LedgerHistory::validatedLedger(
!hash.isZero(),
"ripple::LedgerHistory::validatedLedger : nonzero hash");
std::unique_lock sl(m_consensus_validated.peekMutex());
auto entry = std::make_shared<cv_entry>();
m_consensus_validated.canonicalize_replace_client(index, entry);
@@ -541,9 +551,10 @@ LedgerHistory::fixIndex(LedgerIndex ledgerIndex, LedgerHash const& ledgerHash)
JLOG(j_.debug()) << "LedgerHistory lock stats,"
<< ", fixIndex, call_count = " << call_count++;
auto ledger = m_ledgers_by_hash.fetch(ledgerHash);
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
auto it = mLedgersByIndex.find(ledgerIndex);
if (ledger && (it != mLedgersByIndex.end()) && (it->second != ledgerHash))
if ((it != mLedgersByIndex.end()) && (it->second != ledgerHash))
{
it->second = ledgerHash;
return false;

View File

@@ -159,4 +159,4 @@ DelegateSet::deleteDelegate(
return tesSUCCESS;
}
} // namespace ripple
} // namespace ripple

View File

@@ -53,4 +53,4 @@ public:
} // namespace ripple
#endif
#endif

View File

@@ -114,7 +114,7 @@ getCountsJson(Application& app, int minObjectCount)
ret[jss::treenode_cache_size] =
app.getNodeFamily().getTreeNodeCache()->getCacheSize();
ret[jss::treenode_track_size] =
static_cast<int>(app.getNodeFamily().getTreeNodeCache()->size());
app.getNodeFamily().getTreeNodeCache()->getTrackSize();
std::string uptime;
auto s = UptimeClock::now();