mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-22 03:27:08 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16389dcb2e | ||
|
|
97a780b29f | ||
|
|
654edc9a08 | ||
|
|
658d04f694 | ||
|
|
93498952b1 | ||
|
|
269f79e568 | ||
|
|
e7a8e0336a | ||
|
|
1d7e40777a | ||
|
|
7bb43a243b | ||
|
|
d697b7843c | ||
|
|
2de5140f20 | ||
|
|
edf085a697 | ||
|
|
c35ac1339b | ||
|
|
dc1cfbc474 | ||
|
|
3044073401 |
No files matched your search
-11
@@ -5,10 +5,7 @@ Checks: "-*,
|
|||||||
-bugprone-exception-escape,
|
-bugprone-exception-escape,
|
||||||
-bugprone-implicit-widening-of-multiplication-result,
|
-bugprone-implicit-widening-of-multiplication-result,
|
||||||
-bugprone-narrowing-conversions,
|
-bugprone-narrowing-conversions,
|
||||||
-bugprone-signed-bitwise,
|
|
||||||
-bugprone-std-exception-baseclass,
|
|
||||||
-bugprone-throwing-static-initialization,
|
-bugprone-throwing-static-initialization,
|
||||||
-bugprone-unhandled-code-paths,
|
|
||||||
|
|
||||||
cppcoreguidelines-*,
|
cppcoreguidelines-*,
|
||||||
-cppcoreguidelines-avoid-c-arrays,
|
-cppcoreguidelines-avoid-c-arrays,
|
||||||
@@ -17,7 +14,6 @@ Checks: "-*,
|
|||||||
-cppcoreguidelines-avoid-magic-numbers,
|
-cppcoreguidelines-avoid-magic-numbers,
|
||||||
-cppcoreguidelines-avoid-non-const-global-variables,
|
-cppcoreguidelines-avoid-non-const-global-variables,
|
||||||
-cppcoreguidelines-c-copy-assignment-signature,
|
-cppcoreguidelines-c-copy-assignment-signature,
|
||||||
-cppcoreguidelines-explicit-constructor,
|
|
||||||
-cppcoreguidelines-interfaces-global-init,
|
-cppcoreguidelines-interfaces-global-init,
|
||||||
-cppcoreguidelines-macro-usage,
|
-cppcoreguidelines-macro-usage,
|
||||||
-cppcoreguidelines-missing-std-forward,
|
-cppcoreguidelines-missing-std-forward,
|
||||||
@@ -36,7 +32,6 @@ Checks: "-*,
|
|||||||
llvm-namespace-comment,
|
llvm-namespace-comment,
|
||||||
|
|
||||||
misc-*,
|
misc-*,
|
||||||
-misc-explicit-constructor,
|
|
||||||
-misc-multiple-inheritance,
|
-misc-multiple-inheritance,
|
||||||
-misc-no-recursion,
|
-misc-no-recursion,
|
||||||
-misc-non-private-member-variables-in-classes,
|
-misc-non-private-member-variables-in-classes,
|
||||||
@@ -50,8 +45,6 @@ Checks: "-*,
|
|||||||
-modernize-avoid-c-style-cast,
|
-modernize-avoid-c-style-cast,
|
||||||
-modernize-return-braced-init-list,
|
-modernize-return-braced-init-list,
|
||||||
-modernize-use-integer-sign-comparison,
|
-modernize-use-integer-sign-comparison,
|
||||||
-modernize-use-string-view,
|
|
||||||
-modernize-use-structured-binding,
|
|
||||||
-modernize-use-trailing-return-type,
|
-modernize-use-trailing-return-type,
|
||||||
|
|
||||||
performance-*,
|
performance-*,
|
||||||
@@ -60,7 +53,6 @@ Checks: "-*,
|
|||||||
-performance-noexcept-move-constructor,
|
-performance-noexcept-move-constructor,
|
||||||
-performance-unnecessary-copy-initialization,
|
-performance-unnecessary-copy-initialization,
|
||||||
-performance-unnecessary-value-param,
|
-performance-unnecessary-value-param,
|
||||||
-performance-use-std-move,
|
|
||||||
|
|
||||||
readability-*,
|
readability-*,
|
||||||
-readability-avoid-const-params-in-decls,
|
-readability-avoid-const-params-in-decls,
|
||||||
@@ -73,10 +65,7 @@ Checks: "-*,
|
|||||||
-readability-named-parameter,
|
-readability-named-parameter,
|
||||||
-readability-qualified-auto,
|
-readability-qualified-auto,
|
||||||
-readability-redundant-access-specifiers,
|
-readability-redundant-access-specifiers,
|
||||||
-readability-redundant-nested-if,
|
|
||||||
-readability-redundant-qualified-alias,
|
|
||||||
-readability-static-accessed-through-instance,
|
-readability-static-accessed-through-instance,
|
||||||
-readability-trivial-switch,
|
|
||||||
-readability-uppercase-literal-suffix
|
-readability-uppercase-literal-suffix
|
||||||
"
|
"
|
||||||
# ---
|
# ---
|
||||||
|
|||||||
@@ -108,75 +108,3 @@ endfunction()
|
|||||||
|
|
||||||
function(patch_nix_binary target)
|
function(patch_nix_binary target)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(rpcspec_generate_instantiations)
|
|
||||||
set(options)
|
|
||||||
set(oneValueArgs OUT_VAR VALUE_TYPE VIEW_HEADER INCLUDE_DIR)
|
|
||||||
set(multiValueArgs HANDLERS)
|
|
||||||
cmake_parse_arguments(
|
|
||||||
THIS_FUNCTION_PREFIX
|
|
||||||
"${options}"
|
|
||||||
"${oneValueArgs}"
|
|
||||||
"${multiValueArgs}"
|
|
||||||
${ARGN}
|
|
||||||
)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(corrosion_import_crate)
|
|
||||||
set(options
|
|
||||||
ALL_FEATURES
|
|
||||||
NO_DEFAULT_FEATURES
|
|
||||||
NO_STD
|
|
||||||
NO_LINKER_OVERRIDE
|
|
||||||
NO_USES_TERMINAL
|
|
||||||
LOCKED
|
|
||||||
FROZEN
|
|
||||||
)
|
|
||||||
set(oneValueArgs MANIFEST_PATH PROFILE IMPORTED_CRATES)
|
|
||||||
set(multiValueArgs
|
|
||||||
CRATE_TYPES
|
|
||||||
CRATES
|
|
||||||
FEATURES
|
|
||||||
FLAGS
|
|
||||||
OVERRIDE_CRATE_TYPE
|
|
||||||
)
|
|
||||||
cmake_parse_arguments(
|
|
||||||
THIS_FUNCTION_PREFIX
|
|
||||||
"${options}"
|
|
||||||
"${oneValueArgs}"
|
|
||||||
"${multiValueArgs}"
|
|
||||||
${ARGN}
|
|
||||||
)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(corrosion_set_env_vars target_name env_var)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(corrosion_add_cxxbridge cxx_target)
|
|
||||||
set(options)
|
|
||||||
set(oneValueArgs CRATE)
|
|
||||||
set(multiValueArgs FILES)
|
|
||||||
cmake_parse_arguments(
|
|
||||||
THIS_FUNCTION_PREFIX
|
|
||||||
"${options}"
|
|
||||||
"${oneValueArgs}"
|
|
||||||
"${multiValueArgs}"
|
|
||||||
${ARGN}
|
|
||||||
)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(_unlink_libgcc_s crate)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(add_xrpl_crate name)
|
|
||||||
set(options)
|
|
||||||
set(oneValueArgs CRATE)
|
|
||||||
set(multiValueArgs FILES)
|
|
||||||
cmake_parse_arguments(
|
|
||||||
THIS_FUNCTION_PREFIX
|
|
||||||
"${options}"
|
|
||||||
"${oneValueArgs}"
|
|
||||||
"${multiValueArgs}"
|
|
||||||
${ARGN}
|
|
||||||
)
|
|
||||||
endfunction()
|
|
||||||
@@ -15,9 +15,9 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
default: "false"
|
default: "false"
|
||||||
log_verbosity:
|
log_verbosity:
|
||||||
description: 'The logging verbosity ("quiet", "verbose"), or empty to use the Conan defaults.'
|
description: "The logging verbosity."
|
||||||
required: false
|
required: false
|
||||||
default: ""
|
default: "verbose"
|
||||||
sanitizers:
|
sanitizers:
|
||||||
description: "The sanitizers to enable."
|
description: "The sanitizers to enable."
|
||||||
required: false
|
required: false
|
||||||
@@ -35,16 +35,6 @@ runs:
|
|||||||
LOG_VERBOSITY: ${{ inputs.log_verbosity }}
|
LOG_VERBOSITY: ${{ inputs.log_verbosity }}
|
||||||
SANITIZERS: ${{ inputs.sanitizers }}
|
SANITIZERS: ${{ inputs.sanitizers }}
|
||||||
run: |
|
run: |
|
||||||
# By default, leave the verbosity unset, so CMake configure output is
|
|
||||||
# shown, but compile commands and Boost's b2 debug output (~85k lines
|
|
||||||
# when "verbose") are not.
|
|
||||||
VERBOSITY_ARGS=()
|
|
||||||
if [[ -n "${LOG_VERBOSITY}" ]]; then
|
|
||||||
VERBOSITY_ARGS=(
|
|
||||||
--conf:all tools.build:verbosity="${LOG_VERBOSITY}"
|
|
||||||
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}"
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
conan install \
|
conan install \
|
||||||
--profile:all ci \
|
--profile:all ci \
|
||||||
--build="${BUILD_OPTION}" \
|
--build="${BUILD_OPTION}" \
|
||||||
@@ -52,13 +42,6 @@ runs:
|
|||||||
--options:host='&:xrpld=True' \
|
--options:host='&:xrpld=True' \
|
||||||
--settings:all build_type="${BUILD_TYPE}" \
|
--settings:all build_type="${BUILD_TYPE}" \
|
||||||
--conf:all tools.build:jobs=${BUILD_NPROC} \
|
--conf:all tools.build:jobs=${BUILD_NPROC} \
|
||||||
"${VERBOSITY_ARGS[@]}" \
|
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
|
||||||
--format=json \
|
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
|
||||||
. >"${RUNNER_TEMP}/conan-graph.json"
|
.
|
||||||
|
|
||||||
# Tools that run during the build may only load glibc from the Nix store,
|
|
||||||
# as their package ID survives a GCC runtime update.
|
|
||||||
- name: Check build-context packages for Nix store dependencies (Linux)
|
|
||||||
if: ${{ runner.os == 'Linux' }}
|
|
||||||
shell: bash
|
|
||||||
run: ./bin/nix/check-build-context-runtime.sh "${RUNNER_TEMP}/conan-graph.json"
|
|
||||||
@@ -174,10 +174,8 @@ test.server > xrpl.basics
|
|||||||
test.server > xrpl.config
|
test.server > xrpl.config
|
||||||
test.server > xrpld.app
|
test.server > xrpld.app
|
||||||
test.server > xrpld.core
|
test.server > xrpld.core
|
||||||
test.server > xrpld.rpc
|
|
||||||
test.server > xrpl.json
|
test.server > xrpl.json
|
||||||
test.server > xrpl.protocol
|
test.server > xrpl.protocol
|
||||||
test.server > xrpl.resource
|
|
||||||
test.server > xrpl.server
|
test.server > xrpl.server
|
||||||
test.unit_test > xrpl.basics
|
test.unit_test > xrpl.basics
|
||||||
test.unit_test > xrpl.protocol
|
test.unit_test > xrpl.protocol
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"image_tag": "sha-3d526d4",
|
"image_tag": "sha-060957e",
|
||||||
"configs": {
|
"configs": {
|
||||||
"ubuntu": [
|
"ubuntu": [
|
||||||
{
|
{
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"extra_cmake_args": "-Dvalidator_keys=ON",
|
"extra_cmake_args": "-Dvalidator_keys=ON",
|
||||||
"package": {
|
"package": {
|
||||||
"type": "deb",
|
"type": "deb",
|
||||||
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-e6055dd"
|
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-3a2d19f"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
"extra_cmake_args": "-Dvalidator_keys=ON -Dassert=ON",
|
"extra_cmake_args": "-Dvalidator_keys=ON -Dassert=ON",
|
||||||
"package": {
|
"package": {
|
||||||
"type": "deb",
|
"type": "deb",
|
||||||
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-e6055dd",
|
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-3a2d19f",
|
||||||
"variant": "assert"
|
"variant": "assert"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
"extra_cmake_args": "-Dvalidator_keys=ON",
|
"extra_cmake_args": "-Dvalidator_keys=ON",
|
||||||
"package": {
|
"package": {
|
||||||
"type": "rpm",
|
"type": "rpm",
|
||||||
"image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-e6055dd"
|
"image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-3a2d19f"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ on:
|
|||||||
- "!nix/docker/README.md"
|
- "!nix/docker/README.md"
|
||||||
- "!nix/devshell.nix"
|
- "!nix/devshell.nix"
|
||||||
- "!nix/check-tools/**"
|
- "!nix/check-tools/**"
|
||||||
- "bin/nix/default-loader-path.sh"
|
- "bin/default-loader-path.sh"
|
||||||
|
- "bin/install-sanitizer-libs.sh"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/build-nix-images.yml"
|
- ".github/workflows/build-nix-images.yml"
|
||||||
@@ -24,8 +25,8 @@ on:
|
|||||||
- "!nix/devshell.nix"
|
- "!nix/devshell.nix"
|
||||||
- "!nix/check-tools/**"
|
- "!nix/check-tools/**"
|
||||||
- "bin/check-tools.sh"
|
- "bin/check-tools.sh"
|
||||||
- "bin/nix/default-loader-path.sh"
|
- "bin/default-loader-path.sh"
|
||||||
- "bin/install/sanitizer-libs.sh"
|
- "bin/install-sanitizer-libs.sh"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- develop
|
- develop
|
||||||
paths:
|
paths:
|
||||||
- "bin/install/packaging-tools.sh"
|
- ".github/workflows/build-packaging-images.yml"
|
||||||
|
- "bin/install-packaging-tools.sh"
|
||||||
- "package/images/packaging/**"
|
- "package/images/packaging/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/build-packaging-images.yml"
|
- ".github/workflows/build-packaging-images.yml"
|
||||||
- "bin/install/packaging-tools.sh"
|
- "bin/install-packaging-tools.sh"
|
||||||
- "package/images/packaging/**"
|
- "package/images/packaging/**"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- develop
|
- develop
|
||||||
paths:
|
paths:
|
||||||
|
- ".github/workflows/build-pre-commit-image.yml"
|
||||||
- "bin/pre-commit/Dockerfile"
|
- "bin/pre-commit/Dockerfile"
|
||||||
- "rust-toolchain.toml"
|
- "rust-toolchain.toml"
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ permissions:
|
|||||||
jobs:
|
jobs:
|
||||||
audit:
|
audit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
# Needed to open an issue on scheduled failures.
|
# Needed to open an issue on scheduled failures.
|
||||||
@@ -66,7 +66,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create issue
|
- name: Create issue
|
||||||
if: ${{ steps.audit.outcome != 'success' && github.event_name == 'schedule' }}
|
if: ${{ steps.audit.outcome != 'success' && github.event_name == 'schedule' }}
|
||||||
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
|
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
|
||||||
with:
|
with:
|
||||||
title: "cargo audit found vulnerabilities"
|
title: "cargo audit found vulnerabilities"
|
||||||
body_file: /tmp/cargo-audit-issue.md
|
body_file: /tmp/cargo-audit-issue.md
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create issue
|
- name: Create issue
|
||||||
if: ${{ failure() && github.event_name == 'schedule' && github.repository == 'XRPLF/rippled' }}
|
if: ${{ failure() && github.event_name == 'schedule' && github.repository == 'XRPLF/rippled' }}
|
||||||
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
|
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
|
||||||
with:
|
with:
|
||||||
title: "Releases not merged back into develop"
|
title: "Releases not merged back into develop"
|
||||||
body_file: ${{ env.ISSUE_FILE }}
|
body_file: ${{ env.ISSUE_FILE }}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ jobs:
|
|||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||||
with:
|
with:
|
||||||
enable_ccache: false
|
enable_ccache: false
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload regenerated snapshot
|
- name: Upload regenerated snapshot
|
||||||
if: failure()
|
if: failure()
|
||||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: check-tools-${{ runner.os }}-${{ runner.arch }}
|
name: check-tools-${{ runner.os }}-${{ runner.arch }}
|
||||||
path: ${{ matrix.snapshot }}
|
path: ${{ matrix.snapshot }}
|
||||||
@@ -93,8 +93,9 @@ jobs:
|
|||||||
.github/workflows/reusable-upload-recipe.yml
|
.github/workflows/reusable-upload-recipe.yml
|
||||||
.clang-tidy
|
.clang-tidy
|
||||||
.codecov.yml
|
.codecov.yml
|
||||||
|
bin/check-nix-store-refs.sh
|
||||||
bin/check-tools.sh
|
bin/check-tools.sh
|
||||||
bin/nix/**
|
bin/default-loader-path.sh
|
||||||
cfg/**
|
cfg/**
|
||||||
cmake/**
|
cmake/**
|
||||||
conan/**
|
conan/**
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ on:
|
|||||||
- ".github/workflows/reusable-upload-recipe.yml"
|
- ".github/workflows/reusable-upload-recipe.yml"
|
||||||
- ".clang-tidy"
|
- ".clang-tidy"
|
||||||
- ".codecov.yml"
|
- ".codecov.yml"
|
||||||
|
- "bin/check-nix-store-refs.sh"
|
||||||
- "bin/check-tools.sh"
|
- "bin/check-tools.sh"
|
||||||
- "bin/nix/**"
|
- "bin/default-loader-path.sh"
|
||||||
- "cfg/**"
|
- "cfg/**"
|
||||||
- "cmake/**"
|
- "cmake/**"
|
||||||
- "conan/**"
|
- "conan/**"
|
||||||
|
|||||||
@@ -14,7 +14,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@d7f2acb47d9662e1e2f8b1f5feffa6d21cc3290a
|
uses: XRPLF/actions/.github/workflows/pre-commit.yml@279ec358f4a1be4088be3e024b07916fa97c75b6
|
||||||
with:
|
with:
|
||||||
runs_on: ubuntu-latest
|
runs_on: ubuntu-latest
|
||||||
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-70b8fd3" }'
|
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-473fe44" }'
|
||||||
@@ -41,13 +41,13 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||||
with:
|
with:
|
||||||
enable_ccache: false
|
enable_ccache: false
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ jobs:
|
|||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||||
with:
|
with:
|
||||||
enable_ccache: ${{ inputs.ccache_enabled }}
|
enable_ccache: ${{ inputs.ccache_enabled }}
|
||||||
|
|
||||||
@@ -186,6 +186,9 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
build_nproc: ${{ steps.nproc.outputs.nproc }}
|
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' }}
|
||||||
sanitizers: ${{ inputs.sanitizers }}
|
sanitizers: ${{ inputs.sanitizers }}
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
@@ -254,20 +257,20 @@ jobs:
|
|||||||
# cache included, since what it holds is what gets uploaded and reused.
|
# cache included, since what it holds is what gets uploaded and reused.
|
||||||
- name: Check the build output for Nix store references (Nix toolchain)
|
- name: Check the build output for Nix store references (Nix toolchain)
|
||||||
if: ${{ inputs.toolchain == 'nix' }}
|
if: ${{ inputs.toolchain == 'nix' }}
|
||||||
run: ./bin/nix/check-nix-store-refs.sh "${BUILD_DIR}"
|
run: ./bin/check-nix-store-refs.sh "${BUILD_DIR}"
|
||||||
|
|
||||||
- name: Check the Conan cache for Nix store references (Nix toolchain)
|
- name: Check the Conan cache for Nix store references (Nix toolchain)
|
||||||
if: ${{ inputs.toolchain == 'nix' }}
|
if: ${{ inputs.toolchain == 'nix' }}
|
||||||
run: ./bin/nix/check-nix-store-refs.sh "${CONAN_HOME}"
|
run: ./bin/check-nix-store-refs.sh "${CONAN_HOME}"
|
||||||
|
|
||||||
# Only what PatchNixBinary.cmake retargets: the toolchain in the Linux
|
# Only what PatchNixBinary.cmake retargets: the toolchain in the Linux
|
||||||
# images always references the store. Same condition it uses.
|
# images always references the store. Same condition it uses.
|
||||||
- name: Check for Nix store references (Linux)
|
- name: Check for Nix store references (Linux)
|
||||||
if: ${{ runner.os == 'Linux' && env.SANITIZERS_ENABLED == 'false' }}
|
if: ${{ runner.os == 'Linux' && env.SANITIZERS_ENABLED == 'false' }}
|
||||||
run: |
|
run: |
|
||||||
./bin/nix/check-nix-store-refs.sh "${BUILD_DIR}/xrpld"
|
./bin/check-nix-store-refs.sh "${BUILD_DIR}/xrpld"
|
||||||
./bin/nix/check-nix-store-refs.sh "${BUILD_DIR}/xrpl_tests"
|
./bin/check-nix-store-refs.sh "${BUILD_DIR}/xrpl_tests"
|
||||||
./bin/nix/check-nix-store-refs.sh "${BUILD_DIR}/xrpld_tests"
|
./bin/check-nix-store-refs.sh "${BUILD_DIR}/xrpld_tests"
|
||||||
|
|
||||||
- name: Show ccache statistics
|
- name: Show ccache statistics
|
||||||
if: ${{ inputs.ccache_enabled }}
|
if: ${{ inputs.ccache_enabled }}
|
||||||
@@ -280,7 +283,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload the binary (Linux)
|
- name: Upload the binary (Linux)
|
||||||
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && runner.os == 'Linux' }}
|
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && runner.os == 'Linux' }}
|
||||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: xrpld-${{ inputs.config_name }}
|
name: xrpld-${{ inputs.config_name }}
|
||||||
path: ${{ env.BUILD_DIR }}/xrpld
|
path: ${{ env.BUILD_DIR }}/xrpld
|
||||||
@@ -294,7 +297,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload the validator-keys binary
|
- name: Upload the validator-keys binary
|
||||||
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && env.VALIDATOR_KEYS_ENABLED == 'true' }}
|
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && env.VALIDATOR_KEYS_ENABLED == 'true' }}
|
||||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: validator-keys-${{ inputs.config_name }}
|
name: validator-keys-${{ inputs.config_name }}
|
||||||
path: |
|
path: |
|
||||||
@@ -305,7 +308,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload the test binary (Linux)
|
- name: Upload the test binary (Linux)
|
||||||
if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }}
|
if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }}
|
||||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: xrpl_tests-${{ inputs.config_name }}
|
name: xrpl_tests-${{ inputs.config_name }}
|
||||||
path: ${{ env.BUILD_DIR }}/xrpl_tests
|
path: ${{ env.BUILD_DIR }}/xrpl_tests
|
||||||
@@ -321,7 +324,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload server definitions
|
- name: Upload server definitions
|
||||||
if: ${{ github.event.repository.visibility == 'public' && inputs.config_name == 'ubuntu-gcc-debug-amd64-coverage' }}
|
if: ${{ github.event.repository.visibility == 'public' && inputs.config_name == 'ubuntu-gcc-debug-amd64-coverage' }}
|
||||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: server-definitions
|
name: server-definitions
|
||||||
path: ${{ env.BUILD_DIR }}/server_definitions.json
|
path: ${{ env.BUILD_DIR }}/server_definitions.json
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
needs: [determine-files]
|
needs: [determine-files]
|
||||||
if: ${{ needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.need_full_run == 'true' }}
|
if: ${{ needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.need_full_run == 'true' }}
|
||||||
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
|
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
|
||||||
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-3d526d4"
|
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-060957e"
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
issues: write
|
issues: write
|
||||||
@@ -43,7 +43,7 @@ jobs:
|
|||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||||
with:
|
with:
|
||||||
enable_ccache: false
|
enable_ccache: false
|
||||||
|
|
||||||
@@ -73,6 +73,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
build_nproc: ${{ steps.nproc.outputs.nproc }}
|
build_nproc: ${{ steps.nproc.outputs.nproc }}
|
||||||
build_type: ${{ env.BUILD_TYPE }}
|
build_type: ${{ env.BUILD_TYPE }}
|
||||||
|
log_verbosity: verbose
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
working-directory: ${{ env.BUILD_DIR }}
|
working-directory: ${{ env.BUILD_DIR }}
|
||||||
@@ -109,7 +110,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload clang-tidy output
|
- name: Upload clang-tidy output
|
||||||
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
|
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
|
||||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
path: ${{ env.OUTPUT_FILE }}
|
path: ${{ env.OUTPUT_FILE }}
|
||||||
archive: false
|
archive: false
|
||||||
@@ -133,7 +134,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload clang-tidy diff output
|
- name: Upload clang-tidy diff output
|
||||||
if: ${{ github.event.repository.visibility == 'public' && steps.files_changed.outcome != 'success' }}
|
if: ${{ github.event.repository.visibility == 'public' && steps.files_changed.outcome != 'success' }}
|
||||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
path: ${{ env.DIFF_FILE }}
|
path: ${{ env.DIFF_FILE }}
|
||||||
archive: false
|
archive: false
|
||||||
@@ -185,7 +186,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create issue
|
- name: Create issue
|
||||||
if: ${{ steps.run_clang_tidy.outcome != 'success' && inputs.create_issue_on_failure }}
|
if: ${{ steps.run_clang_tidy.outcome != 'success' && inputs.create_issue_on_failure }}
|
||||||
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
|
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
|
||||||
with:
|
with:
|
||||||
title: "Clang-tidy check failed"
|
title: "Clang-tidy check failed"
|
||||||
body_file: ${{ env.ISSUE_FILE }}
|
body_file: ${{ env.ISSUE_FILE }}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
# Every package lands in one directory; the step below picks its own,
|
# Every package lands in one directory; the step below picks its own,
|
||||||
# which keeps this independent of the artifact names.
|
# which keeps this independent of the artifact names.
|
||||||
- name: Download package artifacts
|
- name: Download package artifacts
|
||||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
with:
|
with:
|
||||||
pattern: "*-pkg"
|
pattern: "*-pkg"
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|||||||
@@ -100,18 +100,18 @@ jobs:
|
|||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||||
with:
|
with:
|
||||||
enable_ccache: false
|
enable_ccache: false
|
||||||
|
|
||||||
- name: Download pre-built xrpld binary
|
- name: Download pre-built xrpld binary
|
||||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.xrpld_artifact_name }}
|
name: ${{ matrix.xrpld_artifact_name }}
|
||||||
path: ${{ env.BUILD_DIR }}
|
path: ${{ env.BUILD_DIR }}
|
||||||
|
|
||||||
- name: Download pre-built validator-keys binary
|
- name: Download pre-built validator-keys binary
|
||||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.validator_keys_artifact_name }}
|
name: ${{ matrix.validator_keys_artifact_name }}
|
||||||
path: ${{ env.BUILD_DIR }}
|
path: ${{ env.BUILD_DIR }}
|
||||||
@@ -151,7 +151,7 @@ jobs:
|
|||||||
# version starts with a digit and a longer name does not, so that one digit
|
# version starts with a digit and a longer name does not, so that one digit
|
||||||
# is what tells 'xrpld-3.4.1-...' from 'xrpld-assert-3.4.1-...'.
|
# is what tells 'xrpld-3.4.1-...' from 'xrpld-assert-3.4.1-...'.
|
||||||
- name: Upload package artifact
|
- name: Upload package artifact
|
||||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.xrpld_artifact_name }}-pkg
|
name: ${{ matrix.xrpld_artifact_name }}-pkg
|
||||||
path: |
|
path: |
|
||||||
@@ -160,7 +160,7 @@ jobs:
|
|||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload debug symbol artifact
|
- name: Upload debug symbol artifact
|
||||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.xrpld_artifact_name }}-pkg-debug
|
name: ${{ matrix.xrpld_artifact_name }}-pkg-debug
|
||||||
path: |
|
path: |
|
||||||
@@ -225,13 +225,13 @@ jobs:
|
|||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||||
with:
|
with:
|
||||||
enable_ccache: false
|
enable_ccache: false
|
||||||
|
|
||||||
# Both artifacts, so the debug symbols are published alongside the package.
|
# Both artifacts, so the debug symbols are published alongside the package.
|
||||||
- name: Download package artifacts
|
- name: Download package artifacts
|
||||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
with:
|
with:
|
||||||
pattern: ${{ matrix.xrpld_artifact_name }}-pkg*
|
pattern: ${{ matrix.xrpld_artifact_name }}-pkg*
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -287,7 +287,7 @@ jobs:
|
|||||||
run: echo "PUSH=${PUSH}" | tee -a "${GITHUB_ENV}"
|
run: echo "PUSH=${PUSH}" | tee -a "${GITHUB_ENV}"
|
||||||
|
|
||||||
- name: Download package artifacts
|
- name: Download package artifacts
|
||||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
with:
|
with:
|
||||||
pattern: "*-pkg"
|
pattern: "*-pkg"
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -295,7 +295,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Download voidstar binary
|
- name: Download voidstar binary
|
||||||
if: ${{ matrix.target == 'voidstar' }}
|
if: ${{ matrix.target == 'voidstar' }}
|
||||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
with:
|
with:
|
||||||
name: xrpld-ubuntu-clang-debug-amd64-voidstar
|
name: xrpld-ubuntu-clang-debug-amd64-voidstar
|
||||||
path: ${{ env.CONTEXT }}
|
path: ${{ env.CONTEXT }}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ permissions:
|
|||||||
jobs:
|
jobs:
|
||||||
clippy:
|
clippy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
@@ -41,7 +41,7 @@ jobs:
|
|||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
|
|
||||||
doc:
|
doc:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ defaults:
|
|||||||
jobs:
|
jobs:
|
||||||
upload:
|
upload:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
|
||||||
env:
|
env:
|
||||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||||
CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.remote_username }}
|
CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.remote_username }}
|
||||||
@@ -50,7 +50,7 @@ jobs:
|
|||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||||
with:
|
with:
|
||||||
enable_ccache: false
|
enable_ccache: false
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ jobs:
|
|||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||||
with:
|
with:
|
||||||
enable_ccache: false
|
enable_ccache: false
|
||||||
|
|
||||||
@@ -108,11 +108,14 @@ jobs:
|
|||||||
build_nproc: ${{ steps.nproc.outputs.nproc }}
|
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' }}
|
||||||
sanitizers: ${{ matrix.sanitizers }}
|
sanitizers: ${{ matrix.sanitizers }}
|
||||||
|
|
||||||
- name: Check the Conan cache for Nix store references (Nix toolchain)
|
- name: Check the Conan cache for Nix store references (Nix toolchain)
|
||||||
if: ${{ matrix.toolchain == 'nix' }}
|
if: ${{ matrix.toolchain == 'nix' }}
|
||||||
run: ./bin/nix/check-nix-store-refs.sh "${CONAN_HOME}"
|
run: ./bin/check-nix-store-refs.sh "${CONAN_HOME}"
|
||||||
|
|
||||||
- name: Log into Conan remote
|
- name: Log into Conan remote
|
||||||
if: ${{ github.repository == 'XRPLF/rippled' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
|
if: ${{ github.repository == 'XRPLF/rippled' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ repos:
|
|||||||
types_or: [c++, c]
|
types_or: [c++, c]
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
rev: a9a8a861f30ed207ead7d5a3b7e8032283ba5da7 # frozen: v23.1.2
|
rev: e2b496dc2bd8340c2524cb9a2d2a943cde1bb6df # frozen: v23.1.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: clang-format
|
- id: clang-format
|
||||||
args: [--style=file]
|
args: [--style=file]
|
||||||
@@ -82,10 +82,9 @@ repos:
|
|||||||
files: ^crates/.*\.rs$
|
files: ^crates/.*\.rs$
|
||||||
|
|
||||||
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
|
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
|
||||||
rev: 28010ddd6016e1a0f7bd232acb6536ef996ae897 # frozen: 0.29.2
|
rev: f1c4833f8cf23c6d952673abc73525411a5719e8 # frozen: 0.29.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: gersemi
|
- id: gersemi
|
||||||
args: [-i, --warnings-as-errors]
|
|
||||||
|
|
||||||
- repo: https://github.com/rbubley/mirrors-prettier
|
- repo: https://github.com/rbubley/mirrors-prettier
|
||||||
rev: ef4a397f916211b4a39ccf9d3d9cbb6562157251 # frozen: v3.9.9
|
rev: ef4a397f916211b4a39ccf9d3d9cbb6562157251 # frozen: v3.9.9
|
||||||
@@ -96,19 +95,19 @@ repos:
|
|||||||
# Scoped to package/: the rest of the repo's Python has pre-existing findings,
|
# Scoped to package/: the rest of the repo's Python has pre-existing findings,
|
||||||
# so widening these is its own change.
|
# so widening these is its own change.
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: f12be1ebaa5351c1fc76472de98db2c3446c8253 # frozen: v0.16.10
|
rev: a56c0b927e6465d37cae3e97d35d4d18ab2b96cd # frozen: v0.16.9
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff-check
|
- id: ruff-check
|
||||||
args: [--fix]
|
args: [--fix]
|
||||||
files: ^package/.*\.py$
|
files: ^package/.*\.py$
|
||||||
|
|
||||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||||
rev: 96ae3e5802f3fe2d551e703e18f0a367d1a81ac2 # frozen: 26.10.0
|
rev: 4160603246a6b365d4a2af661c6d71b0a0f50478 # frozen: 26.5.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: 2834ec6639549dd6796205c8f011dedcd587288b # frozen: v2.4.0
|
rev: 7ff8d35ae36a7d2b968f2f90b4c723e292e594ee # frozen: v2.3.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
args: [--strict]
|
args: [--strict]
|
||||||
|
|||||||
+1
-34
@@ -22,45 +22,13 @@ API version 2 is available in `xrpld` version 2.0.0 and later. See [API-VERSION-
|
|||||||
|
|
||||||
This version is supported by all `xrpld` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
|
This version is supported by all `xrpld` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
|
||||||
|
|
||||||
## Unreleased
|
|
||||||
|
|
||||||
### Breaking changes
|
|
||||||
|
|
||||||
- The `ripplerpc` request field, which selects the shape of the JSON-RPC reply envelope, is now validated, and a value that is not exactly `"1.0"`, `"2.0"` or `"3.0"` is rejected. This reaches the JSON-RPC transport at every API version. It does not reach a WebSocket session, which reads the field only to echo it back. A request sending `"2"`, `" 2.0"`, `"2.00"`, `"02.0"`, `"2.0.0"`, `"10.0"` or any other text, such as `"abc"` or `"x2"`, gets a working reply today. After this ships, such a request sent alone gets HTTP 400 with `ripplerpc is not a supported version`, charged as a malformed request, and such an entry of a `"method": "batch"` body gets that error in its own reply while the batch answers 200. A client that spells the version loosely must therefore be corrected to one of the three exact values, or omit the field. Previously the value was compared as a string, which both accepted values that name no version and ordered multi-digit versions incorrectly: `"abc"` and `"x2"` sorted above `"3.0"` and so selected version 3, and `"10.0"` sorted below `"2.0"` and so selected version 1. Requests that send one of the three supported values, or omit the field, are unaffected.
|
|
||||||
|
|
||||||
### Additions
|
|
||||||
|
|
||||||
- A JSON-RPC (HTTP) request may send its parameters as an object, `"params": {"account": "r..."}`, as well as the array of one object that was already accepted. This reaches every API version: such a request was previously rejected with HTTP 400 and `params unparsable`, and is now served. A request that already sends the array form is unaffected. An entry of a `"method": "batch"` request that carries a by-name `params` object is read for `api_version` and credentials from that object. Previously such an entry had its `api_version` read from its top level and its credentials ignored, since credentials were read only from an array-form `params`.
|
|
||||||
|
|
||||||
### Bugfixes
|
|
||||||
|
|
||||||
- A request echoed back in an error reply now has every credential-bearing field masked: `admin_password`, `admin_user`, `passphrase`, `password`, `secret`, `seed`, `seed_hex`, `url_password`, `url_username` and `username`. Nesting no longer matters, so a credential inside `params` is masked too. The same masking is applied to every request and reply written to the log, and it covers six further names that only a reply carries: `master_key`, `master_seed`, `master_seed_hex`, `validation_key`, `validation_private_key` and `validation_seed`, which is how `wallet_propose` and `validation_create` used to write a live private key to the log. A request or reply written to the log is truncated at 10,000 characters. An `[rpc_startup]` line that does not parse is reported by its position in the section and the parser's message, never by its text, and no command runs for it.
|
|
||||||
- The command line client no longer prints a credential the operator did not type. A failing command echoes the request it built under `request_sent`, which carries the `admin_password` the client copies out of `[port_rpc]` in the config, so `./xrpld account_info rBogus` printed that password to stdout and into any captured output. `request_sent` is now masked. The `rpc` member beside it, which echoes the arguments as they were typed, is unchanged. The command line client also no longer writes an unparsed `json` or `ripple_path_find` argument to its trace log before parsing it, where a `secret` inside that argument could not be masked; it logs the parsed request instead, masked. The reply it receives is logged the same way, parsed and masked, where the raw body was written before, a `validation_create` answer included.
|
|
||||||
- A WebSocket frame that does not parse, or exceeds the request size limit, is answered `{"type": "error", "error": "jsonInvalid", "size": <bytes>}`. The frame's body is reported by size rather than echoed back in a `value` member, since a body that does not parse has no fields to mask. A client that read `value` gets `size` instead.
|
|
||||||
- Four error codes that named no HTTP status of their own, and so answered 200 on a reply reporting an error, now name one: `actMalformed`, `alreadyMultisig` and `alreadySingleSig` answer 400, and `actNotFound` answers 404. **No shipped envelope reports these four.** A request sending `ripplerpc: "3.0"` still receives 200 for all four, as it always has, so `account_info` on a malformed account or one the ledger does not hold answers 200 exactly as before.
|
|
||||||
- `submit`, `simulate`, `transaction_entry`, `ledger_entry` and `ledger_accept`: Errors from these methods now include `error_code` and `error_message` alongside the `error` token, as every other method already did. Each error now answers the status its code names: 400 for a malformed request, 404 for `transactionNotFound`, 500 for an internal failure, and 501 for `notYetImplemented` and `notStandAlone`. That status change reaches only a request sending `ripplerpc: "3.0"`, which is the envelope that derives the status from the error. With `ripplerpc` `"1.0"` the status stays 200 and the two new members appear beside `error`; with `"2.0"` the status stays 200, `error_code` appears, and the `code` and `message` members carry the code and the message rather than null, since that envelope copies them from `error_code` and `error_message` and drops `error_message`.
|
|
||||||
- A reply reporting HTTP 402 or 502 now carries a status line. Those two statuses named no case in the switch that writes one, so such a reply began with a header instead and did not parse as an HTTP response at all. Both are reachable at any API version with `ripplerpc: "3.0"`, which derives the status from the error code: 402 through `highFee` from `sign`, `sign_for` or `submit` with a low `fee_mult_max`, and 502 through `dbDeserialization` from `tx`. The eleven statuses that already named a case report the same phrase they always have.
|
|
||||||
- An error reply to a request sending `ripplerpc: "2.0"` or `"3.0"` no longer carries a stray `"error_message": null` beside the error it reports. The member appeared only when the `Server` log partition was set to debug or lower, because the log statement read `error_message` after the reply had renamed it to `message`, and reading it put it back as null. So the reply a client received depended on the server's log level, and the log line itself printed an empty message. Both are fixed.
|
|
||||||
- A body the server rejects before it reads a request out of it now says which of four things was wrong. A body over the size limit answers `Request is too large`. A body that parses to `{}`, `[]` or `null` answers `Request is empty`. A body that parses to a non-empty array answers `Request is not a JSON object`; that is the only other document the parser accepts at the top level. All three previously answered `Unable to parse request: ` with nothing after the colon, the parser having recorded no error for them. Any other body does not parse, which includes one that is only whitespace and one whose top-level value is a string, number or boolean; it answers `Unable to parse request: ` followed by the parser's own reason, as it did before. The status is 400 for all four, as before, and this reaches every API version.
|
|
||||||
- `batch`: An entry that is not identified through a secure gateway no longer clears the connection's `X-User` and forwarded-for values for the entries after it, so every entry of one body reports the role and username it would have reported on its own.
|
|
||||||
|
|
||||||
## XRP Ledger server version 3.5.0
|
## XRP Ledger server version 3.5.0
|
||||||
|
|
||||||
Version 3.5.0 is not yet released.
|
Version 3.5.0 is not yet released.
|
||||||
|
|
||||||
### Additions in 3.5.0
|
### Additions in 3.5.0
|
||||||
|
|
||||||
- `subscribe`, `unsubscribe`: Added an optional `mpt_issuances` request field, an array of MPT issuance IDs (hex strings). Subscribers receive the same `transaction` message as the `transactions` stream for each validated transaction whose metadata affects a subscribed issuance. MPT issuance subscriptions count toward the per-connection subscription limit. An empty array, a non-array value, or an invalid ID returns `invalidParams`. ([#5671](https://github.com/XRPLF/rippled/pull/5671))
|
- `subscribe`, `unsubscribe`: Added an optional `mpt_issuances` request field, an array of MPT issuance IDs (hex strings). Subscribers receive a message with `type` `mptTransaction` for each validated transaction whose metadata affects a subscribed issuance; the message has the same fields as the `transactions` stream. MPT issuance subscriptions count toward the per-connection subscription limit. An empty array, a non-array value, or an invalid ID returns `invalidParams`. ([#5671](https://github.com/XRPLF/rippled/pull/5671))
|
||||||
- `ledger_entry`: Add full support for checks, NFT offers, payment channels, and signer lists. ([#6319](https://github.com/XRPLF/rippled/pull/6319))
|
|
||||||
|
|
||||||
### Bugfixes in 3.5.0
|
|
||||||
|
|
||||||
- `channel_authorize`: The `channel_id` field now returns an `invalidParams` error if the value is not a string. [#7582](https://github.com/XRPLF/rippled/pull/7582)
|
|
||||||
- `channel_verify`: The `channel_id` and `signature` fields now return an `invalidParams` error if the value is not a string. [#7582](https://github.com/XRPLF/rippled/pull/7582)
|
|
||||||
|
|
||||||
### Bugfixes in 3.5.0
|
|
||||||
|
|
||||||
- `feature`: The admin-only `vetoed` field now returns `invalidParams` unless its value is a boolean. [#7583](https://github.com/XRPLF/rippled/pull/7583)
|
|
||||||
|
|
||||||
## XRP Ledger server version 3.4.0
|
## XRP Ledger server version 3.4.0
|
||||||
|
|
||||||
@@ -82,7 +50,6 @@ Version 3.4.0 is not yet released. These changes are available in the 3.4.0 beta
|
|||||||
- `account_lines`: The `peer` field now returns an error if the value is not a string. [#7728](https://github.com/XRPLF/rippled/pull/7728)
|
- `account_lines`: The `peer` field now returns an error if the value is not a string. [#7728](https://github.com/XRPLF/rippled/pull/7728)
|
||||||
- `ledger`: `delivered_amount` is now included in the metadata of successful `AccountDelete` transactions when transactions are expanded (`expand`, or admin-only `full`). Previously it was only added for `Payment` and `CheckCash`, which made `ledger` inconsistent with `tx` and `account_tx`. [#5706](https://github.com/XRPLF/rippled/pull/5706)
|
- `ledger`: `delivered_amount` is now included in the metadata of successful `AccountDelete` transactions when transactions are expanded (`expand`, or admin-only `full`). Previously it was only added for `Payment` and `CheckCash`, which made `ledger` inconsistent with `tx` and `account_tx`. [#5706](https://github.com/XRPLF/rippled/pull/5706)
|
||||||
- `noripple_check`: The `transactions` field is no longer included in error responses; it is still returned (possibly as an empty array) whenever `transactions` is `true` and the request succeeds. A malformed `account` is now rejected before the ledger is looked up, so that error response no longer carries the `ledger_hash`, `ledger_index`, and `validated` fields ([#6303](https://github.com/XRPLF/rippled/pull/6303)).
|
- `noripple_check`: The `transactions` field is no longer included in error responses; it is still returned (possibly as an empty array) whenever `transactions` is `true` and the request succeeds. A malformed `account` is now rejected before the ledger is looked up, so that error response no longer carries the `ledger_hash`, `ledger_index`, and `validated` fields ([#6303](https://github.com/XRPLF/rippled/pull/6303)).
|
||||||
- `transaction_entry`: An object or an array in `tx_hash` now returns `malformedRequest`, like any other value that is not a hex hash, instead of an `internal` error.
|
|
||||||
|
|
||||||
## XRP Ledger server version 3.3.0
|
## XRP Ledger server version 3.3.0
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# alone; the scripts in a Conan cache are all git hook samples and autotools
|
# alone; the scripts in a Conan cache are all git hook samples and autotools
|
||||||
# scratch, 36 false positives to 0 real.
|
# scratch, 36 false positives to 0 real.
|
||||||
#
|
#
|
||||||
# Usage: bin/nix/check-nix-store-refs.sh <path>
|
# Usage: bin/check-nix-store-refs.sh <path>
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
+6
-17
@@ -20,11 +20,9 @@
|
|||||||
# development setups, but not in the macOS CI environment. They are checked
|
# development setups, but not in the macOS CI environment. They are checked
|
||||||
# everywhere except when running in CI on macOS.
|
# everywhere except when running in CI on macOS.
|
||||||
#
|
#
|
||||||
# Tools that Nix also exposes under a version-suffixed name
|
# Tools that Nix also exposes under a version-suffixed name (`clang-tidy-22`,
|
||||||
# (`clang-tidy-<v>`, `g++-<v>`, ...) are probed under both names:
|
# `g++-15`, ...) are probed under both names: a suffixed name can break while
|
||||||
# a suffixed name can break while the plain one still works
|
# the plain one still works (see mkVersionedToolLinks in nix/packages.nix).
|
||||||
# (see mkVersionedToolLinks in nix/packages.nix).
|
|
||||||
# The suffix is the major version of the plain `clang` / `gcc` on PATH.
|
|
||||||
#
|
#
|
||||||
# Tools scoped to a single dev shell rather than to commonPackages are checked
|
# Tools scoped to a single dev shell rather than to commonPackages are checked
|
||||||
# only in that shell, keyed off XRPL_DEVSHELL.
|
# only in that shell, keyed off XRPL_DEVSHELL.
|
||||||
@@ -36,16 +34,9 @@
|
|||||||
|
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
|
|
||||||
# major_version <compiler>
|
# Version suffixes of the Nix tool links, tracking nix/packages.nix.
|
||||||
# Major version of a compiler on PATH, or "unknown" when it isn't there.
|
gcc_version=15
|
||||||
major_version() {
|
llvm_version=22
|
||||||
local version
|
|
||||||
version="$("$1" -dumpversion 2>/dev/null)" || version=""
|
|
||||||
version="${version%%.*}"
|
|
||||||
printf '%s' "${version:-unknown}"
|
|
||||||
}
|
|
||||||
|
|
||||||
llvm_version="$(major_version clang)"
|
|
||||||
|
|
||||||
missing=()
|
missing=()
|
||||||
checked=0
|
checked=0
|
||||||
@@ -121,7 +112,6 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
|
|||||||
check ClangBuildAnalyzer
|
check ClangBuildAnalyzer
|
||||||
check curl
|
check curl
|
||||||
check file
|
check file
|
||||||
check jq
|
|
||||||
check less
|
check less
|
||||||
check make
|
check make
|
||||||
# net-tools netstat reports "net-tools X.Y"; macOS ships BSD netstat with no
|
# net-tools netstat reports "net-tools X.Y"; macOS ships BSD netstat with no
|
||||||
@@ -190,7 +180,6 @@ fi
|
|||||||
if [ "${os}" = "linux" ]; then
|
if [ "${os}" = "linux" ]; then
|
||||||
echo
|
echo
|
||||||
echo "GCC toolchain:"
|
echo "GCC toolchain:"
|
||||||
gcc_version="$(major_version gcc)"
|
|
||||||
check gcc
|
check gcc
|
||||||
check "gcc-${gcc_version}"
|
check "gcc-${gcc_version}"
|
||||||
check g++
|
check g++
|
||||||
|
|||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,65 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Fail if a binary of a build-context Conan package loads anything from the Nix
|
|
||||||
# store other than glibc, or cannot resolve a library at all.
|
|
||||||
#
|
|
||||||
# Only binaries linked by the Nix toolchain are checked, i.e. those recording a
|
|
||||||
# store path as their interpreter or RUNPATH. Prebuilt upstream binaries (such
|
|
||||||
# as the ones the cmake package ships) use the system loader instead.
|
|
||||||
#
|
|
||||||
# Build-context packages provide the tools that run during the build (protoc,
|
|
||||||
# grpc_cpp_plugin, ...). Their package ID does not change when a Nix toolchain
|
|
||||||
# update moves the GCC runtime to a new store path, so a cached binary has to
|
|
||||||
# get by with the pinned glibc alone. See docs/build/nix.md.
|
|
||||||
#
|
|
||||||
# Usage: bin/nix/check-build-context-runtime.sh <graph.json>
|
|
||||||
# <graph.json> is the output of `conan install --format=json`.
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
if [ "$#" -ne 1 ]; then
|
|
||||||
echo "usage: $0 <graph.json>" >&2
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$(uname -s)" != "Linux" ]; then
|
|
||||||
echo "$0: Linux only" >&2
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
folders="$(jq -r '.graph.nodes[] | select(.context == "build" and .package_folder) | .package_folder' "$1" | sort -u)"
|
|
||||||
|
|
||||||
checked=0
|
|
||||||
failed=0
|
|
||||||
|
|
||||||
while IFS= read -r file; do
|
|
||||||
case "$(file -b "${file}")" in
|
|
||||||
ELF*) ;;
|
|
||||||
*) continue ;;
|
|
||||||
esac
|
|
||||||
[[ "$(readelf -ldW "${file}")" == */nix/store/* ]] || continue
|
|
||||||
checked=$((checked + 1))
|
|
||||||
|
|
||||||
# `ldd` lists the interpreter and every library as the loader resolves them.
|
|
||||||
if deps="$(ldd "${file}" 2>&1)"; then
|
|
||||||
bad="$(printf '%s\n' "${deps}" |
|
|
||||||
grep -E 'not found|/nix/store/' |
|
|
||||||
grep -vE '/nix/store/[^/]+-glibc-[^/]+/' || true)"
|
|
||||||
else
|
|
||||||
case "${deps}" in
|
|
||||||
*"not a dynamic executable"*) continue ;;
|
|
||||||
esac
|
|
||||||
bad="${deps}"
|
|
||||||
fi
|
|
||||||
if [ -n "${bad}" ]; then
|
|
||||||
failed=$((failed + 1))
|
|
||||||
echo "::error file=${file}::loads a library from the Nix store other than glibc"
|
|
||||||
echo "${file}"
|
|
||||||
echo "${bad}" | sed 's/^/ /'
|
|
||||||
fi
|
|
||||||
done < <(
|
|
||||||
# shellcheck disable=SC2086 # one folder per line, no spaces in Conan paths
|
|
||||||
[ -z "${folders}" ] || find ${folders} -type f \( -perm -u+x -o -name '*.so*' \)
|
|
||||||
)
|
|
||||||
|
|
||||||
echo "Build-context packages: checked ${checked} binaries, ${failed} failed."
|
|
||||||
[ "${failed}" -eq 0 ]
|
|
||||||
@@ -23,7 +23,7 @@ apt-get clean
|
|||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
ARG PRE_COMMIT_VERSION=4.6.2
|
ARG PRE_COMMIT_VERSION=4.6.0
|
||||||
RUN pip install --no-cache --break-system-packages \
|
RUN pip install --no-cache --break-system-packages \
|
||||||
pre-commit==${PRE_COMMIT_VERSION}
|
pre-commit==${PRE_COMMIT_VERSION}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import sys
|
|||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
CLANG_TIDY_VERSION = 22
|
||||||
|
|
||||||
# Extensions run-clang-tidy can analyse: `.cpp` translation units and, thanks to
|
# Extensions run-clang-tidy can analyse: `.cpp` translation units and, thanks to
|
||||||
# the `verify_headers` build option, `.h`/`.hpp` headers (each has its own
|
# the `verify_headers` build option, `.h`/`.hpp` headers (each has its own
|
||||||
# compile_commands.json entry). `.ipp` fragments have no entry and are skipped.
|
# compile_commands.json entry). `.ipp` fragments have no entry and are skipped.
|
||||||
@@ -37,21 +39,8 @@ TIDY_EXTENSIONS = {".cpp", ".h", ".hpp"}
|
|||||||
FILEPATH_RE = re.compile(r"^(\s*(?:-\s+)?FilePath:\s*)'((?:[^']|'')*)'\s*$")
|
FILEPATH_RE = re.compile(r"^(\s*(?:-\s+)?FilePath:\s*)'((?:[^']|'')*)'\s*$")
|
||||||
|
|
||||||
|
|
||||||
def clang_tidy_major() -> str | None:
|
def find_tool(name: str) -> str | None:
|
||||||
"""Major version of the `clang-tidy` on PATH, which run-clang-tidy invokes."""
|
for candidate in (f"{name}-{CLANG_TIDY_VERSION}", name):
|
||||||
if not (clang_tidy := shutil.which("clang-tidy")):
|
|
||||||
return None
|
|
||||||
output = subprocess.run(
|
|
||||||
[clang_tidy, "--version"], capture_output=True, text=True
|
|
||||||
).stdout
|
|
||||||
m = re.search(r"LLVM version (\d+)", output)
|
|
||||||
return m.group(1) if m else None
|
|
||||||
|
|
||||||
|
|
||||||
def find_tool(name: str, version: str | None) -> str | None:
|
|
||||||
"""Prefer `<name>-<version>`, so a host tool of another version can't win."""
|
|
||||||
candidates = ([f"{name}-{version}"] if version else []) + [name]
|
|
||||||
for candidate in candidates:
|
|
||||||
if path := shutil.which(candidate):
|
if path := shutil.which(candidate):
|
||||||
return path
|
return path
|
||||||
return None
|
return None
|
||||||
@@ -114,9 +103,8 @@ def main():
|
|||||||
if not files:
|
if not files:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
version = clang_tidy_major()
|
run_clang_tidy = find_tool("run-clang-tidy")
|
||||||
run_clang_tidy = find_tool("run-clang-tidy", version)
|
clang_apply_replacements = find_tool("clang-apply-replacements")
|
||||||
clang_apply_replacements = find_tool("clang-apply-replacements", version)
|
|
||||||
missing = [
|
missing = [
|
||||||
name
|
name
|
||||||
for name, path in (
|
for name, path in (
|
||||||
@@ -126,10 +114,9 @@ def main():
|
|||||||
if not path
|
if not path
|
||||||
]
|
]
|
||||||
if missing:
|
if missing:
|
||||||
tried = f" (tried the '-{version}' suffix too)" if version else ""
|
|
||||||
print(
|
print(
|
||||||
f"clang-tidy check failed: TIDY is enabled but {' and '.join(missing)} "
|
f"clang-tidy check failed: TIDY is enabled but {' and '.join(missing)} "
|
||||||
f"was not found in PATH{tried}.",
|
f"was not found in PATH (tried the '-{CLANG_TIDY_VERSION}' suffix too).",
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
(runtime libraries resolved through the rpath) are skipped too.
|
(runtime libraries resolved through the rpath) are skipped too.
|
||||||
Everywhere else `patch_nix_binary` is a no-op.
|
Everywhere else `patch_nix_binary` is a no-op.
|
||||||
|
|
||||||
The default loader is resolved by bin/nix/default-loader-path.sh.
|
The default loader is resolved by bin/default-loader-path.sh.
|
||||||
#]===================================================================]
|
#]===================================================================]
|
||||||
|
|
||||||
include_guard(GLOBAL)
|
include_guard(GLOBAL)
|
||||||
@@ -25,7 +25,7 @@ include_guard(GLOBAL)
|
|||||||
include(CompilationEnv)
|
include(CompilationEnv)
|
||||||
|
|
||||||
# Resolves the system default ELF loader path for the current architecture.
|
# Resolves the system default ELF loader path for the current architecture.
|
||||||
set(_loader_path_script "${CMAKE_SOURCE_DIR}/bin/nix/default-loader-path.sh")
|
set(_loader_path_script "${CMAKE_SOURCE_DIR}/bin/default-loader-path.sh")
|
||||||
|
|
||||||
if(
|
if(
|
||||||
is_linux
|
is_linux
|
||||||
|
|||||||
@@ -292,14 +292,6 @@ if(xrpld)
|
|||||||
)
|
)
|
||||||
target_sources(xrpld PRIVATE ${sources})
|
target_sources(xrpld PRIVATE ${sources})
|
||||||
|
|
||||||
rpcspec_generate_instantiations(
|
|
||||||
OUT_VAR rpcspec_instantiations
|
|
||||||
VALUE_TYPE "::json::Value"
|
|
||||||
VIEW_HEADER "xrpld/rpc/detail/JsonObjectView.hpp"
|
|
||||||
HANDLERS book_changes ledger transaction_entry
|
|
||||||
)
|
|
||||||
target_sources(xrpld PRIVATE ${rpcspec_instantiations})
|
|
||||||
|
|
||||||
if(tests)
|
if(tests)
|
||||||
file(
|
file(
|
||||||
GLOB_RECURSE sources
|
GLOB_RECURSE sources
|
||||||
@@ -330,7 +322,6 @@ if(xrpld)
|
|||||||
# antithesis_instrumentation.h, which is not exported as INTERFACE
|
# antithesis_instrumentation.h, which is not exported as INTERFACE
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
xrpld
|
xrpld
|
||||||
SYSTEM
|
|
||||||
PRIVATE ${CMAKE_SOURCE_DIR}/external/antithesis-sdk
|
PRIVATE ${CMAKE_SOURCE_DIR}/external/antithesis-sdk
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -77,24 +77,19 @@ if(is_clang)
|
|||||||
message(STATUS " Ignorelist: ${ignorelist_path}")
|
message(STATUS " Ignorelist: ${ignorelist_path}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Define the SANITIZERS macro for BuildInfo.cpp, plus one of XRPL_ASAN,
|
# Define SANITIZERS macro for BuildInfo.cpp
|
||||||
# XRPL_TSAN and XRPL_UBSAN per active sanitizer, so that code can test for a
|
|
||||||
# specific one with #ifdef instead of parsing the dot-joined SANITIZERS string.
|
|
||||||
set(sanitizers_list)
|
set(sanitizers_list)
|
||||||
if(SANITIZERS MATCHES "address")
|
if(SANITIZERS MATCHES "address")
|
||||||
set(enable_asan ON)
|
set(enable_asan ON)
|
||||||
list(APPEND sanitizers_list "ASAN")
|
list(APPEND sanitizers_list "ASAN")
|
||||||
target_compile_definitions(common INTERFACE XRPL_ASAN)
|
|
||||||
endif()
|
endif()
|
||||||
if(SANITIZERS MATCHES "thread")
|
if(SANITIZERS MATCHES "thread")
|
||||||
set(enable_tsan ON)
|
set(enable_tsan ON)
|
||||||
list(APPEND sanitizers_list "TSAN")
|
list(APPEND sanitizers_list "TSAN")
|
||||||
target_compile_definitions(common INTERFACE XRPL_TSAN)
|
|
||||||
endif()
|
endif()
|
||||||
if(SANITIZERS MATCHES "undefinedbehavior")
|
if(SANITIZERS MATCHES "undefinedbehavior")
|
||||||
set(enable_ubsan ON)
|
set(enable_ubsan ON)
|
||||||
list(APPEND sanitizers_list "UBSAN")
|
list(APPEND sanitizers_list "UBSAN")
|
||||||
target_compile_definitions(common INTERFACE XRPL_UBSAN)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(sanitizers_list)
|
if(sanitizers_list)
|
||||||
|
|||||||
+2
-6
@@ -3,7 +3,7 @@
|
|||||||
"requires": [
|
"requires": [
|
||||||
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708",
|
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708",
|
||||||
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1782392402.420688",
|
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1782392402.420688",
|
||||||
"xrpl-rpc-spec/0.1.21#d536f87a2ae7d313452746cfa3ac4404%1790869005.122975",
|
"xrpl-rpc-spec/0.1.19#870b2d3abcfbbf13b61c2d3c69495060%1790348286.187549",
|
||||||
"sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1782392403.185447",
|
"sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1782392403.185447",
|
||||||
"soci/4.0.3#e726491a03468795453f7c83fc924a96%1782392402.679521",
|
"soci/4.0.3#e726491a03468795453f7c83fc924a96%1782392402.679521",
|
||||||
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1782307151.633168",
|
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1782307151.633168",
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
"libarchive/3.8.7#c446109bd1f1d8ba7936c94189bc50e6%1782392403.066892",
|
"libarchive/3.8.7#c446109bd1f1d8ba7936c94189bc50e6%1782392403.066892",
|
||||||
"jemalloc/5.3.1#1fc58d55316041f10fbc1e8a2eae632a%1776700028.228",
|
"jemalloc/5.3.1#1fc58d55316041f10fbc1e8a2eae632a%1776700028.228",
|
||||||
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1782392402.791979",
|
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1782392402.791979",
|
||||||
"grpc/1.81.1#aaa93ab6cda2f2baa6a84490582c8adf%1791284951.826256",
|
"grpc/1.81.1#b87796a4269034856cbc1a2522db16eb%1788275071.530512",
|
||||||
"fast_float/8.2.10#f6f28d6bb22112078e7dbda611caf681%1785888854.601666",
|
"fast_float/8.2.10#f6f28d6bb22112078e7dbda611caf681%1785888854.601666",
|
||||||
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1782307148.15562",
|
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1782307148.15562",
|
||||||
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1782392402.538492",
|
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1782392402.538492",
|
||||||
@@ -34,15 +34,11 @@
|
|||||||
"build_requires": [
|
"build_requires": [
|
||||||
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708",
|
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708",
|
||||||
"strawberryperl/5.32.1.1#8d114504d172cfea8ea1662d09b6333e%1782395692.540639",
|
"strawberryperl/5.32.1.1#8d114504d172cfea8ea1662d09b6333e%1782395692.540639",
|
||||||
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1782392402.431897",
|
|
||||||
"protobuf/6.33.5#ff253ead763bd8d9904a52979cd21e81%1782392410.233933",
|
"protobuf/6.33.5#ff253ead763bd8d9904a52979cd21e81%1782392410.233933",
|
||||||
"openssl/3.6.3#f806de8933e3bf6f01016c6a888cee2e%1783945160.863288",
|
|
||||||
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1782395690.33162",
|
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1782395690.33162",
|
||||||
"msys2/cci.latest#d22fe7b2808f5fd34d0a7923ace9c54f%1770657326.649",
|
"msys2/cci.latest#d22fe7b2808f5fd34d0a7923ace9c54f%1770657326.649",
|
||||||
"m4/1.4.19#1727f439cf74e83826ec96d0b4904eee%1784541921.659",
|
"m4/1.4.19#1727f439cf74e83826ec96d0b4904eee%1784541921.659",
|
||||||
"grpc/1.81.1#aaa93ab6cda2f2baa6a84490582c8adf%1791284951.826256",
|
|
||||||
"cmake/4.3.3#840cf00ea09777e05c2050a50a82c722%1782392418.696091",
|
"cmake/4.3.3#840cf00ea09777e05c2050a50a82c722%1782392418.696091",
|
||||||
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1782392402.681654",
|
|
||||||
"b2/5.4.2#ffd6084a119587e70f11cd45d1a386e2%1782392402.624226",
|
"b2/5.4.2#ffd6084a119587e70f11cd45d1a386e2%1782392402.624226",
|
||||||
"automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56",
|
"automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56",
|
||||||
"autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86",
|
"autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86",
|
||||||
|
|||||||
+1
-9
@@ -3,13 +3,5 @@
|
|||||||
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() }}
|
||||||
# Fall back to Conan Center's source backups when a recipe's upstream URL is down
|
tools.files.download:retry=5
|
||||||
# (e.g. the GNU FTP mirrors), see
|
|
||||||
# https://github.com/conan-io/conan-center-index/issues/28147#issuecomment-3183544772
|
|
||||||
# The backups are only tried once every upstream URL has used up its retries,
|
|
||||||
# so keep the retries low.
|
|
||||||
core.sources:download_urls=["origin", "https://c3i.jfrog.io/artifactory/conan-center-backup-sources"]
|
|
||||||
tools.files.download:retry=1
|
|
||||||
tools.files.download:retry_wait=10
|
tools.files.download:retry_wait=10
|
||||||
# Fail fast on unreachable hosts (default connect timeout is 30s), keep the 60s read timeout.
|
|
||||||
core.net.http:timeout=(5, 60)
|
|
||||||
+4
-31
@@ -29,9 +29,9 @@ os.version={{ min_macos_version }}
|
|||||||
[conf]
|
[conf]
|
||||||
{# The Boost recipe builds with b2, which doesn't use Conan's toolchain files. #}
|
{# The Boost recipe builds with b2, which doesn't use Conan's toolchain files. #}
|
||||||
{# Instead it hand-rolls the compiler for user-config.jam, #}
|
{# Instead it hand-rolls the compiler for user-config.jam, #}
|
||||||
{# and its fallback probes a version-suffixed binary (e.g. `g++-<major>`) before plain `g++`. #}
|
{# and its fallback probes a version-suffixed binary (e.g. `g++-15`) before plain `g++`. #}
|
||||||
{# Inside the Nix shell the wrapper only provides `g++`/`gcc` (no `-<major>` suffix), #}
|
{# Inside the Nix shell the wrapper only provides `g++`/`gcc` (no `-15` suffix), #}
|
||||||
{# so on a host that also has a system `g++-<major>` the probe escapes Nix #}
|
{# so on a host that also has a system `g++-15` the probe escapes Nix #}
|
||||||
{# and picks the system compiler, which is mismatched with the Nix libraries #}
|
{# and picks the system compiler, which is mismatched with the Nix libraries #}
|
||||||
{# and breaks the build (e.g. Boost.Stacktrace link checks fail). #}
|
{# and breaks the build (e.g. Boost.Stacktrace link checks fail). #}
|
||||||
{# Pinning the executables here short-circuits that probe so Boost (and the rest of the toolchain) #}
|
{# Pinning the executables here short-circuits that probe so Boost (and the rest of the toolchain) #}
|
||||||
@@ -49,31 +49,8 @@ tools.build:compiler_executables={'c':'{{ cc_exe }}','cpp':'{{ cxx_exe }}'}
|
|||||||
user.package:cppstd_version=23
|
user.package:cppstd_version=23
|
||||||
tools.info.package_id:confs+=["user.package:cppstd_version"]
|
tools.info.package_id:confs+=["user.package:cppstd_version"]
|
||||||
|
|
||||||
{% if os == "Linux" and context == "build" %}
|
|
||||||
{# Build-context executables (protoc, grpc_cpp_plugin, build tools) run during the build #}
|
|
||||||
{# and would otherwise load libstdc++/libgcc from a Nix store path #}
|
|
||||||
{# that might change with a Nix toolchain update. #}
|
|
||||||
{# --as-needed drops the ones they link but don't use, #}
|
|
||||||
{# such as libatomic for grpc_cpp_plugin on arm64. #}
|
|
||||||
{% set static_runtime_flags = ["-static-libstdc++", "-static-libgcc", "-Wl,--as-needed"] %}
|
|
||||||
tools.build:exelinkflags+={{ static_runtime_flags }}
|
|
||||||
tools.info.package_id:confs+=["tools.build:exelinkflags"]
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if os == "Linux" and context == "build" %}
|
|
||||||
{# b2 links itself with its own script, which ignores exelinkflags #}
|
|
||||||
{# and only takes CXXFLAGS when use_cxx_env is set (see [buildenv] below). #}
|
|
||||||
[options]
|
|
||||||
b2/*:use_cxx_env=True
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
[buildenv]
|
|
||||||
{# gRPC emits thousands of compiler warnings that we cannot act on. #}
|
|
||||||
{# CMake picks up CXXFLAGS, and unlike tools.build:cxxflags, #}
|
|
||||||
{# this is not part of the package ID, so binaries stay shareable. #}
|
|
||||||
grpc/*:CXXFLAGS=-w
|
|
||||||
|
|
||||||
{% if os == "Macos" %}
|
{% if os == "Macos" %}
|
||||||
|
[buildenv]
|
||||||
{# os.version adds -mmacosx-version-min to compiler command lines, #}
|
{# os.version adds -mmacosx-version-min to compiler command lines, #}
|
||||||
{# but Boost.Context's b2 assembly (.S) rule ignores it, #}
|
{# but Boost.Context's b2 assembly (.S) rule ignores it, #}
|
||||||
{# so those objects keep the host SDK version and still warn at link time. #}
|
{# so those objects keep the host SDK version and still warn at link time. #}
|
||||||
@@ -81,7 +58,3 @@ grpc/*:CXXFLAGS=-w
|
|||||||
{# Scoped to boost/* since it is the only gap. #}
|
{# Scoped to boost/* since it is the only gap. #}
|
||||||
boost/*:MACOSX_DEPLOYMENT_TARGET={{ min_macos_version }}
|
boost/*:MACOSX_DEPLOYMENT_TARGET={{ min_macos_version }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if os == "Linux" and context == "build" %}
|
|
||||||
b2/*:CXXFLAGS={{ static_runtime_flags | join(" ") }}
|
|
||||||
{% endif %}
|
|
||||||
@@ -5,9 +5,6 @@ include(default)
|
|||||||
|
|
||||||
{% if not sanitizers %}
|
{% if not sanitizers %}
|
||||||
{# Sanitizers not configured; no additional settings needed #}
|
{# Sanitizers not configured; no additional settings needed #}
|
||||||
{% elif context == "build" %}
|
|
||||||
{# Build-context packages are tools we run, not code we test, #}
|
|
||||||
{# so don't instrument them #}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
{% if compiler == "msvc" %}
|
{% if compiler == "msvc" %}
|
||||||
|
|||||||
+3
-8
@@ -40,7 +40,7 @@ class Xrpl(ConanFile):
|
|||||||
"nudb/2.0.9",
|
"nudb/2.0.9",
|
||||||
"openssl/3.6.3",
|
"openssl/3.6.3",
|
||||||
"soci/4.0.3",
|
"soci/4.0.3",
|
||||||
"xrpl-rpc-spec/0.1.21",
|
"xrpl-rpc-spec/0.1.19",
|
||||||
"zlib/1.3.2",
|
"zlib/1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -49,8 +49,7 @@ class Xrpl(ConanFile):
|
|||||||
]
|
]
|
||||||
|
|
||||||
tool_requires = [
|
tool_requires = [
|
||||||
"grpc/<host_version>",
|
"protobuf/6.33.5",
|
||||||
"protobuf/<host_version>",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
default_options = {
|
default_options = {
|
||||||
@@ -124,10 +123,6 @@ class Xrpl(ConanFile):
|
|||||||
"xxhash/*:shared": False,
|
"xxhash/*:shared": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
# default_options only reach the host context;
|
|
||||||
# give tool_requires (and their dependencies) the same dependency options.
|
|
||||||
default_build_options = {k: v for k, v in default_options.items() if "/" in k}
|
|
||||||
|
|
||||||
def set_version(self):
|
def set_version(self):
|
||||||
self.version = self.version or DEV_VERSION
|
self.version = self.version or DEV_VERSION
|
||||||
|
|
||||||
@@ -154,7 +149,7 @@ class Xrpl(ConanFile):
|
|||||||
self.requires("xxhash/0.8.3", transitive_headers=True)
|
self.requires("xxhash/0.8.3", transitive_headers=True)
|
||||||
|
|
||||||
exports_sources = (
|
exports_sources = (
|
||||||
"bin/nix/default-loader-path.sh",
|
"bin/default-loader-path.sh",
|
||||||
"CMakeLists.txt",
|
"CMakeLists.txt",
|
||||||
"cfg/*",
|
"cfg/*",
|
||||||
"cmake/*",
|
"cmake/*",
|
||||||
|
|||||||
@@ -80,12 +80,13 @@ function(add_xrpl_crate name)
|
|||||||
# `cc` picks its runtime flag from `crt-static` alone, so it compiles a
|
# `cc` picks its runtime flag from `crt-static` alone, so it compiles a
|
||||||
# crate's C++ with `-MT`; Debug needs `-MTd` (to match cmake/XrplCompiler.cmake).
|
# crate's C++ with `-MT`; Debug needs `-MTd` (to match cmake/XrplCompiler.cmake).
|
||||||
if(is_msvc)
|
if(is_msvc)
|
||||||
corrosion_set_env_vars(${ARG_CRATE} "$<$<CONFIG:Debug>:CXXFLAGS=-MTd>")
|
corrosion_set_env_vars(
|
||||||
|
${ARG_CRATE}
|
||||||
|
"$<$<CONFIG:Debug>:CXXFLAGS=-MTd>"
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
corrosion_add_cxxbridge(
|
corrosion_add_cxxbridge(${name}_cxxbridge CRATE ${ARG_CRATE} FILES
|
||||||
${name}_cxxbridge
|
${ARG_FILES}
|
||||||
CRATE ${ARG_CRATE}
|
|
||||||
FILES ${ARG_FILES}
|
|
||||||
)
|
)
|
||||||
# Generated cxxbridge headers don't exist at configure time; CMake 3.28+
|
# Generated cxxbridge headers don't exist at configure time; CMake 3.28+
|
||||||
# validates INTERFACE_SOURCES on consuming targets. Clear it to skip the
|
# validates INTERFACE_SOURCES on consuming targets. Clear it to skip the
|
||||||
|
|||||||
Generated
+10
-10
@@ -57,9 +57,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx"
|
name = "cxx"
|
||||||
version = "1.0.205"
|
version = "1.0.202"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c8a02bfeba9074b2bbb39492c9b0908ec854f455a3cccdcde7a1de55e2315e40"
|
checksum = "13f6de320895f42e6e081abb5c7983bedcf0b6d0ff9323de0d33f620c8ac1199"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cxx-build",
|
"cxx-build",
|
||||||
@@ -72,9 +72,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-build"
|
name = "cxx-build"
|
||||||
version = "1.0.205"
|
version = "1.0.202"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbc2ac76997619d2d888b58ad79488f1c835de41ca4dd3dd7082acf4ecb0a50f"
|
checksum = "4fde53ca86b9704a943fef0f1e1d836239a6aedca5de3c65fa9f97ec0bd46d39"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
@@ -87,9 +87,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-cmd"
|
name = "cxxbridge-cmd"
|
||||||
version = "1.0.205"
|
version = "1.0.202"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "54a486ed16a3f2a053fe7f5b98db4c1a59846a23e8cb9e49f9d1bd48830d51a2"
|
checksum = "07bae89236c811fd4d08ed3441759ac4ac98d752cbfd3de341315ba16ad20ec3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
@@ -101,15 +101,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-flags"
|
name = "cxxbridge-flags"
|
||||||
version = "1.0.205"
|
version = "1.0.202"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c72569be94e2283764d334cd285980b747dbe221e27e315484eb6bcd93fa808a"
|
checksum = "49045042e5fced01b80742aba5508de82aa4f13677ed3fa2b4cda709c40c5918"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-macro"
|
name = "cxxbridge-macro"
|
||||||
version = "1.0.205"
|
version = "1.0.202"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "423e795284a7f7b3f843c956a5322c4bc497b60c2dd1a6339da10313cb18d575"
|
checksum = "b181252e2e3d3b5d183afbdc033a3958b445eb3e1a0ae65fc3d4f5259f5da6fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|||||||
Vendored
+7
-9
@@ -10,15 +10,14 @@ This document explains how to set one up.
|
|||||||
support it — see [compiler support for C++23][cpp23-support].
|
support it — see [compiler support for C++23][cpp23-support].
|
||||||
The versions currently tested in CI are:
|
The versions currently tested in CI are:
|
||||||
|
|
||||||
| Compiler | Version |
|
| Compiler | Version |
|
||||||
| ----------- | ------------------------------- |
|
| ----------- | ------------------ |
|
||||||
| GCC | `gccVersion` in [packages.nix] |
|
| GCC | 15.2 |
|
||||||
| Clang | `llvmVersion` in [packages.nix] |
|
| Clang | 22 |
|
||||||
| Apple Clang | 21 |
|
| Apple Clang | 21 |
|
||||||
| MSVC | Visual Studio 2026 |
|
| MSVC | Visual Studio 2026 |
|
||||||
|
|
||||||
LLVM tools (`clang-tidy` and `clang-format`)
|
LLVM tools (`clang-tidy` and `clang-format`) are also pinned to version 22.
|
||||||
come from the same LLVM release as Clang.
|
|
||||||
|
|
||||||
### Older compilers
|
### Older compilers
|
||||||
|
|
||||||
@@ -157,4 +156,3 @@ version out of the box — run it via `run-clang-tidy`. No separate installation
|
|||||||
is needed.
|
is needed.
|
||||||
|
|
||||||
[cpp23-support]: https://en.cppreference.com/w/cpp/compiler_support/23
|
[cpp23-support]: https://en.cppreference.com/w/cpp/compiler_support/23
|
||||||
[packages.nix]: ../../nix/packages.nix
|
|
||||||
Vendored
+9
-21
@@ -183,36 +183,24 @@ at link or run time.
|
|||||||
> configuration CI covers, and no dependency binaries are published for it.
|
> configuration CI covers, and no dependency binaries are published for it.
|
||||||
|
|
||||||
This is checked rather than assumed.
|
This is checked rather than assumed.
|
||||||
[`bin/nix/check-nix-store-refs.sh`](../../bin/nix/check-nix-store-refs.sh) takes one
|
[`bin/check-nix-store-refs.sh`](../../bin/check-nix-store-refs.sh) takes one file
|
||||||
file or directory and fails if a binary under it resolves a store path at run time.
|
or directory and fails if a binary under it resolves a store path at run time.
|
||||||
CI runs it over the build output and the Conan cache, and again in the upload job
|
CI runs it over the build output and the Conan cache, and again in the upload job
|
||||||
before anything is published. You can run it yourself:
|
before anything is published. You can run it yourself:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bin/nix/check-nix-store-refs.sh build
|
bin/check-nix-store-refs.sh build
|
||||||
bin/nix/check-nix-store-refs.sh ~/.conan2-nix
|
bin/check-nix-store-refs.sh ~/.conan2-nix
|
||||||
```
|
```
|
||||||
|
|
||||||
It works on Linux too, but asserts something narrower there: the toolchain always
|
It works on Linux too, but asserts something narrower there: the toolchain always
|
||||||
writes the store into `PT_INTERP` and `RUNPATH`. That is fine for the pinned
|
writes the store into `PT_INTERP` and `RUNPATH`, and CI builds inside an image
|
||||||
glibc, whose path does not move, but not for the GCC runtime, which moves with
|
whose store is fixed for its lifetime, so that is fine. Only the binaries
|
||||||
every GCC update. So [`conan/profiles/default`](../../conan/profiles/default)
|
[`PatchNixBinary.cmake`](../../cmake/PatchNixBinary.cmake) retargets to the
|
||||||
links build-context packages, whose executables run during the build, with
|
system loader have to be clean, and those are what CI checks:
|
||||||
`-static-libstdc++ -static-libgcc -Wl,--as-needed`, and
|
|
||||||
[`conan/profiles/sanitizers`](../../conan/profiles/sanitizers) does not
|
|
||||||
instrument them. CI checks that they load nothing from the store but glibc, from
|
|
||||||
the graph `conan install --format=json` writes:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bin/nix/check-build-context-runtime.sh graph.json
|
bin/check-nix-store-refs.sh build/xrpld
|
||||||
```
|
|
||||||
|
|
||||||
Only the binaries [`PatchNixBinary.cmake`](../../cmake/PatchNixBinary.cmake)
|
|
||||||
retargets to the system loader have to be fully clean, and those are what CI
|
|
||||||
checks:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bin/nix/check-nix-store-refs.sh build/xrpld
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### The libresolv stub
|
### The libresolv stub
|
||||||
|
|||||||
Vendored
+3
-3
@@ -178,11 +178,11 @@ A binary stops starting after a `nix flake update`, or after
|
|||||||
dyld[57271]: Library not loaded: /nix/store/…-libresolv-93/lib/libresolv.9.dylib
|
dyld[57271]: Library not loaded: /nix/store/…-libresolv-93/lib/libresolv.9.dylib
|
||||||
```
|
```
|
||||||
|
|
||||||
[`bin/nix/check-nix-store-refs.sh`](../../bin/nix/check-nix-store-refs.sh) finds the
|
[`bin/check-nix-store-refs.sh`](../../bin/check-nix-store-refs.sh) finds the same
|
||||||
same thing without having to run anything, and names the file:
|
thing without having to run anything, and names the file:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ bin/nix/check-nix-store-refs.sh ~/.conan2-nix
|
$ bin/check-nix-store-refs.sh ~/.conan2-nix
|
||||||
::error file=/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig::references the Nix store at run time
|
::error file=/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig::references the Nix store at run time
|
||||||
/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig
|
/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig
|
||||||
/nix/store/p4lp3xq4imd1qzqh08x8vcq2zfhi7rca-libresolv-93/lib/libresolv.9.dylib
|
/nix/store/p4lp3xq4imd1qzqh08x8vcq2zfhi7rca-libresolv-93/lib/libresolv.9.dylib
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ project(antithesis-sdk-cpp VERSION 0.4.4 LANGUAGES CXX)
|
|||||||
add_library(antithesis-sdk-cpp INTERFACE antithesis_sdk.h)
|
add_library(antithesis-sdk-cpp INTERFACE antithesis_sdk.h)
|
||||||
|
|
||||||
# Note, both sections below created by xrpld project
|
# Note, both sections below created by xrpld project
|
||||||
target_include_directories(antithesis-sdk-cpp SYSTEM INTERFACE
|
target_include_directories(antithesis-sdk-cpp INTERFACE
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||||
)
|
)
|
||||||
|
|||||||
Generated
+6
-6
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1791130267,
|
"lastModified": 1781173989,
|
||||||
"narHash": "sha256-1sjwcQMcgAbmiip/VivBSiK8p2bTkQGOvCuO7vnwfx4=",
|
"narHash": "sha256-fnzKKPvS+oieI/pTzotA5tkoM47EB1NpaBcgk4R97hE=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9013764fcc0ea99fa16cf7aa7decf8a5c3889dd2",
|
"rev": "8c91a71d13451abc40eb9dae8910f972f979852f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -47,11 +47,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1791189933,
|
"lastModified": 1784611586,
|
||||||
"narHash": "sha256-Y8eN7ki0Urx4Ojf4w1xSpWg8uk/3lJqK+E0Oth77rH0=",
|
"narHash": "sha256-OfqgY+0hp/zseZB7uyH0U8kIDPS4scZZCyAurEplvG0=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "e60029353d0c48d216bc4b065168ccd4079c166f",
|
"rev": "14f58845249f3552a89b07772626b8d3c632fa86",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ lz4Compress(void const* in, std::size_t inSize, BufferFactory&& bf)
|
|||||||
// data
|
// data
|
||||||
auto compressed = bf(outCapacity);
|
auto compressed = bf(outCapacity);
|
||||||
|
|
||||||
auto const compressedSize = LZ4_compress_default(
|
auto compressedSize = LZ4_compress_default(
|
||||||
reinterpret_cast<char const*>(in),
|
reinterpret_cast<char const*>(in),
|
||||||
reinterpret_cast<char*>(compressed),
|
reinterpret_cast<char*>(compressed),
|
||||||
inSize,
|
inSize,
|
||||||
|
|||||||
@@ -20,14 +20,12 @@ SharedIntrusive<T>::SharedIntrusive(T* p, TAdoptTag) noexcept : ptr_{p}
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive const& rhs)
|
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive const& rhs)
|
||||||
: ptr_{
|
: ptr_{[&] {
|
||||||
[&] {
|
auto p = rhs.unsafeGetRawPtr();
|
||||||
auto p = rhs.unsafeGetRawPtr();
|
if (p)
|
||||||
if (p)
|
p->addStrongRef();
|
||||||
p->addStrongRef();
|
return p;
|
||||||
return p;
|
}()}
|
||||||
}(),
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,14 +33,12 @@ template <class T>
|
|||||||
template <class TT>
|
template <class TT>
|
||||||
requires std::convertible_to<TT*, T*>
|
requires std::convertible_to<TT*, T*>
|
||||||
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive<TT> const& rhs)
|
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive<TT> const& rhs)
|
||||||
: ptr_{
|
: ptr_{[&] {
|
||||||
[&] {
|
auto p = rhs.unsafeGetRawPtr();
|
||||||
auto p = rhs.unsafeGetRawPtr();
|
if (p)
|
||||||
if (p)
|
p->addStrongRef();
|
||||||
p->addStrongRef();
|
return p;
|
||||||
return p;
|
}()}
|
||||||
}(),
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,14 +140,12 @@ SharedIntrusive<T>::~SharedIntrusive()
|
|||||||
template <class T>
|
template <class T>
|
||||||
template <class TT>
|
template <class TT>
|
||||||
SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs)
|
SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs)
|
||||||
: ptr_{
|
: ptr_{[&] {
|
||||||
[&] {
|
auto p = static_cast<T*>(rhs.unsafeGetRawPtr());
|
||||||
auto p = static_cast<T*>(rhs.unsafeGetRawPtr());
|
if (p)
|
||||||
if (p)
|
p->addStrongRef();
|
||||||
p->addStrongRef();
|
return p;
|
||||||
return p;
|
}()}
|
||||||
}(),
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,14 +159,12 @@ SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusiv
|
|||||||
template <class T>
|
template <class T>
|
||||||
template <class TT>
|
template <class TT>
|
||||||
SharedIntrusive<T>::SharedIntrusive(DynamicCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs)
|
SharedIntrusive<T>::SharedIntrusive(DynamicCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs)
|
||||||
: ptr_{
|
: ptr_{[&] {
|
||||||
[&] {
|
auto p = dynamic_cast<T*>(rhs.unsafeGetRawPtr());
|
||||||
auto p = dynamic_cast<T*>(rhs.unsafeGetRawPtr());
|
if (p)
|
||||||
if (p)
|
p->addStrongRef();
|
||||||
p->addStrongRef();
|
return p;
|
||||||
return p;
|
}()}
|
||||||
}(),
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +260,7 @@ SharedIntrusive<T>::unsafeReleaseAndStore(T* next)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
using enum ReleaseStrongRefAction;
|
using enum ReleaseStrongRefAction;
|
||||||
auto const action = prev->releaseStrongRef();
|
auto action = prev->releaseStrongRef();
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case NoOp:
|
case NoOp:
|
||||||
@@ -369,7 +361,7 @@ WeakIntrusive<T>::unsafeReleaseNoStore()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
using enum ReleaseWeakRefAction;
|
using enum ReleaseWeakRefAction;
|
||||||
auto const action = ptr_->releaseWeakRef();
|
auto action = ptr_->releaseWeakRef();
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case NoOp:
|
case NoOp:
|
||||||
@@ -588,7 +580,7 @@ SharedWeakUnion<T>::convertToStrong()
|
|||||||
auto p = unsafeGetRawPtr();
|
auto p = unsafeGetRawPtr();
|
||||||
if (p && p->checkoutStrongRefFromWeak())
|
if (p && p->checkoutStrongRefFromWeak())
|
||||||
{
|
{
|
||||||
[[maybe_unused]] auto const action = p->releaseWeakRef();
|
[[maybe_unused]] auto action = p->releaseWeakRef();
|
||||||
XRPL_ASSERT(
|
XRPL_ASSERT(
|
||||||
(action == ReleaseWeakRefAction::NoOp),
|
(action == ReleaseWeakRefAction::NoOp),
|
||||||
"xrpl::SharedWeakUnion::convertToStrong : "
|
"xrpl::SharedWeakUnion::convertToStrong : "
|
||||||
@@ -611,7 +603,7 @@ SharedWeakUnion<T>::convertToWeak()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
using enum ReleaseStrongRefAction;
|
using enum ReleaseStrongRefAction;
|
||||||
auto const action = p->addWeakReleaseStrongRef();
|
auto action = p->addWeakReleaseStrongRef();
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case NoOp:
|
case NoOp:
|
||||||
@@ -678,7 +670,7 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
|
|||||||
if (isStrong())
|
if (isStrong())
|
||||||
{
|
{
|
||||||
using enum ReleaseStrongRefAction;
|
using enum ReleaseStrongRefAction;
|
||||||
auto const strongAction = p->releaseStrongRef();
|
auto strongAction = p->releaseStrongRef();
|
||||||
switch (strongAction)
|
switch (strongAction)
|
||||||
{
|
{
|
||||||
case NoOp:
|
case NoOp:
|
||||||
@@ -696,7 +688,7 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
using enum ReleaseWeakRefAction;
|
using enum ReleaseWeakRefAction;
|
||||||
auto const weakAction = p->releaseWeakRef();
|
auto weakAction = p->releaseWeakRef();
|
||||||
switch (weakAction)
|
switch (weakAction)
|
||||||
{
|
{
|
||||||
case NoOp:
|
case NoOp:
|
||||||
|
|||||||
@@ -406,10 +406,10 @@ IntrusiveRefCounts::useCount() const noexcept
|
|||||||
inline IntrusiveRefCounts::~IntrusiveRefCounts() noexcept
|
inline IntrusiveRefCounts::~IntrusiveRefCounts() noexcept
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
auto const v = refCounts_.load(std::memory_order_acquire);
|
auto v = refCounts_.load(std::memory_order_acquire);
|
||||||
XRPL_ASSERT(
|
XRPL_ASSERT(
|
||||||
(!(v & kValueMask)), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero");
|
(!(v & kValueMask)), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero");
|
||||||
auto const t = v & kTagMask;
|
auto t = v & kTagMask;
|
||||||
XRPL_ASSERT((!t || t == kTagMask), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag");
|
XRPL_ASSERT((!t || t == kTagMask), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,84 +3,9 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
|
||||||
#include <limits>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
namespace xrpl {
|
namespace xrpl {
|
||||||
|
|
||||||
/**
|
|
||||||
* Add two signed 64-bit integers, returning std::nullopt when the exact
|
|
||||||
* mathematical sum is not representable in std::int64_t.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] constexpr std::optional<std::int64_t>
|
|
||||||
checkedAdd(std::int64_t a, std::int64_t b) noexcept
|
|
||||||
{
|
|
||||||
using L = std::numeric_limits<std::int64_t>;
|
|
||||||
|
|
||||||
if ((b > 0 && a > L::max() - b) || (b < 0 && a < L::min() - b))
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
return a + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subtract two signed 64-bit integers, returning std::nullopt when the exact
|
|
||||||
* mathematical difference is not representable in std::int64_t.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] constexpr std::optional<std::int64_t>
|
|
||||||
checkedSub(std::int64_t a, std::int64_t b) noexcept
|
|
||||||
{
|
|
||||||
using L = std::numeric_limits<std::int64_t>;
|
|
||||||
|
|
||||||
if ((b > 0 && a < L::min() + b) || (b < 0 && a > L::max() + b))
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
return a - b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static_assert(checkedAdd(0, 0) == 0);
|
|
||||||
static_assert(checkedAdd(1, -1) == 0);
|
|
||||||
static_assert(checkedAdd(-5, 2) == -3);
|
|
||||||
static_assert(!checkedAdd(std::numeric_limits<std::int64_t>::max(), 1).has_value());
|
|
||||||
static_assert(!checkedAdd(std::numeric_limits<std::int64_t>::min(), -1).has_value());
|
|
||||||
static_assert(
|
|
||||||
checkedAdd(std::numeric_limits<std::int64_t>::max() - 1, 1) ==
|
|
||||||
std::numeric_limits<std::int64_t>::max());
|
|
||||||
static_assert(
|
|
||||||
checkedAdd(
|
|
||||||
std::numeric_limits<std::int64_t>::min(),
|
|
||||||
std::numeric_limits<std::int64_t>::max()) == -1);
|
|
||||||
static_assert(
|
|
||||||
checkedAdd(
|
|
||||||
std::numeric_limits<std::int64_t>::max(),
|
|
||||||
std::numeric_limits<std::int64_t>::min()) == -1);
|
|
||||||
static_assert(
|
|
||||||
!checkedAdd(std::numeric_limits<std::int64_t>::max(), std::numeric_limits<std::int64_t>::max())
|
|
||||||
.has_value());
|
|
||||||
static_assert(
|
|
||||||
!checkedAdd(std::numeric_limits<std::int64_t>::min(), std::numeric_limits<std::int64_t>::min())
|
|
||||||
.has_value());
|
|
||||||
|
|
||||||
static_assert(checkedSub(0, 0) == 0);
|
|
||||||
static_assert(checkedSub(1, 1) == 0);
|
|
||||||
static_assert(checkedSub(-5, 2) == -7);
|
|
||||||
static_assert(checkedSub(-5, -2) == -3);
|
|
||||||
static_assert(!checkedSub(std::numeric_limits<std::int64_t>::min(), 1).has_value());
|
|
||||||
static_assert(!checkedSub(std::numeric_limits<std::int64_t>::max(), -1).has_value());
|
|
||||||
static_assert(
|
|
||||||
checkedSub(std::numeric_limits<std::int64_t>::min() + 1, 1) ==
|
|
||||||
std::numeric_limits<std::int64_t>::min());
|
|
||||||
static_assert(
|
|
||||||
checkedSub(-1, std::numeric_limits<std::int64_t>::max()) ==
|
|
||||||
std::numeric_limits<std::int64_t>::min());
|
|
||||||
static_assert(
|
|
||||||
!checkedSub(std::numeric_limits<std::int64_t>::max(), std::numeric_limits<std::int64_t>::min())
|
|
||||||
.has_value());
|
|
||||||
static_assert(
|
|
||||||
!checkedSub(std::numeric_limits<std::int64_t>::min(), std::numeric_limits<std::int64_t>::max())
|
|
||||||
.has_value());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate one number divided by another number in percentage.
|
* Calculate one number divided by another number in percentage.
|
||||||
* The result is rounded up to the next integer, and capped in the range [0,100]
|
* The result is rounded up to the next integer, and capped in the range [0,100]
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ public:
|
|||||||
|
|
||||||
for (auto const& c : cfg)
|
for (auto const& c : cfg)
|
||||||
{
|
{
|
||||||
auto const& a = allocators_.emplace_back(c.extra_, c.alloc_, c.align_);
|
auto& a = allocators_.emplace_back(c.extra_, c.alloc_, c.align_);
|
||||||
|
|
||||||
if (a.size() > maxSize_)
|
if (a.size() > maxSize_)
|
||||||
maxSize_ = a.size();
|
maxSize_ = a.size();
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ template <typename T>
|
|||||||
concept SomeChar = std::same_as<std::remove_cvref_t<T>, int8_t> ||
|
concept SomeChar = std::same_as<std::remove_cvref_t<T>, int8_t> ||
|
||||||
std::same_as<std::remove_cvref_t<T>, char> || std::same_as<std::remove_cvref_t<T>, uint8_t>;
|
std::same_as<std::remove_cvref_t<T>, char> || std::same_as<std::remove_cvref_t<T>, uint8_t>;
|
||||||
|
|
||||||
inline constexpr std::array<std::optional<int>, 256> const kDigitLookupTable = [] {
|
inline constexpr std::array<std::optional<int>, 256> const kDigitLookupTable = []() {
|
||||||
std::array<std::optional<int>, 256> t{};
|
std::array<std::optional<int>, 256> t{};
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
// Remove from cache, if !valid, remove from map too. Returns true if removed from cache
|
// Remove from cache, if !valid, remove from map too. Returns true if removed from cache
|
||||||
std::scoped_lock const lock(mutex_);
|
std::scoped_lock const lock(mutex_);
|
||||||
|
|
||||||
auto const cit = cache_.find(key);
|
auto cit = cache_.find(key);
|
||||||
|
|
||||||
if (cit == cache_.end())
|
if (cit == cache_.end())
|
||||||
return false;
|
return false;
|
||||||
@@ -356,7 +356,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
|
|
||||||
std::scoped_lock const lock(mutex_);
|
std::scoped_lock const lock(mutex_);
|
||||||
|
|
||||||
auto const cit = cache_.find(key);
|
auto cit = cache_.find(key);
|
||||||
|
|
||||||
if (cit == cache_.end())
|
if (cit == cache_.end())
|
||||||
{
|
{
|
||||||
@@ -371,7 +371,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
Entry& entry = cit->second;
|
Entry& entry = cit->second;
|
||||||
entry.touch(clock_.now());
|
entry.touch(clock_.now());
|
||||||
|
|
||||||
auto const shouldReplaceCached = [&] {
|
auto shouldReplaceCached = [&] {
|
||||||
if constexpr (replaceCached)
|
if constexpr (replaceCached)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -400,7 +400,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const cachedData = entry.lock();
|
auto cachedData = entry.lock();
|
||||||
|
|
||||||
if (cachedData)
|
if (cachedData)
|
||||||
{
|
{
|
||||||
@@ -563,7 +563,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
retrieve(key_type const& key, T& data)
|
retrieve(key_type const& key, T& data)
|
||||||
{
|
{
|
||||||
// retrieve the value of the stored data
|
// retrieve the value of the stored data
|
||||||
auto const entry = fetch(key);
|
auto entry = fetch(key);
|
||||||
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return false;
|
return false;
|
||||||
@@ -687,7 +687,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const sle = h();
|
auto sle = h();
|
||||||
if (!sle)
|
if (!sle)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
@@ -713,7 +713,7 @@ inline SharedPointerType
|
|||||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||||
initialFetch(key_type const& key, std::scoped_lock<MutexType> const& l)
|
initialFetch(key_type const& key, std::scoped_lock<MutexType> const& l)
|
||||||
{
|
{
|
||||||
auto const cit = cache_.find(key);
|
auto cit = cache_.find(key);
|
||||||
if (cit == cache_.end())
|
if (cit == cache_.end())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
@@ -783,7 +783,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
std::atomic<int>& allRemovals,
|
std::atomic<int>& allRemovals,
|
||||||
std::scoped_lock<std::recursive_mutex> const&)
|
std::scoped_lock<std::recursive_mutex> const&)
|
||||||
{
|
{
|
||||||
return std::thread([&, this] {
|
return std::thread([&, this]() {
|
||||||
int cacheRemovals = 0;
|
int cacheRemovals = 0;
|
||||||
int mapRemovals = 0;
|
int mapRemovals = 0;
|
||||||
|
|
||||||
@@ -863,7 +863,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
std::atomic<int>& allRemovals,
|
std::atomic<int>& allRemovals,
|
||||||
std::scoped_lock<std::recursive_mutex> const&)
|
std::scoped_lock<std::recursive_mutex> const&)
|
||||||
{
|
{
|
||||||
return std::thread([&, this] {
|
return std::thread([&, this]() {
|
||||||
// NOLINTBEGIN https://github.com/XRPLF/rippled/issues/7056
|
// NOLINTBEGIN https://github.com/XRPLF/rippled/issues/7056
|
||||||
int cacheRemovals = 0;
|
int cacheRemovals = 0;
|
||||||
int mapRemovals = 0;
|
int mapRemovals = 0;
|
||||||
|
|||||||
@@ -195,8 +195,7 @@ private:
|
|||||||
{
|
{
|
||||||
// Local lambda that converts a single hex char to four bits and
|
// Local lambda that converts a single hex char to four bits and
|
||||||
// ORs those bits into a uint32_t.
|
// ORs those bits into a uint32_t.
|
||||||
auto const hexCharToUInt =
|
auto hexCharToUInt = [](char c, std::uint32_t shift, std::uint32_t& accum) -> ParseResult {
|
||||||
[](char c, std::uint32_t shift, std::uint32_t& accum) -> ParseResult {
|
|
||||||
std::uint32_t nibble = 0xFFu;
|
std::uint32_t nibble = 0xFFu;
|
||||||
if (c < '0' || c > 'f')
|
if (c < '0' || c > 'f')
|
||||||
return ParseResult::BadChar;
|
return ParseResult::BadChar;
|
||||||
@@ -454,7 +453,7 @@ public:
|
|||||||
{
|
{
|
||||||
for (int i = kWidth - 1; i >= 0; --i)
|
for (int i = kWidth - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
auto const prev = data_[i];
|
auto prev = data_[i];
|
||||||
data_[i] = boost::endian::native_to_big(boost::endian::big_to_native(data_[i]) - 1);
|
data_[i] = boost::endian::native_to_big(boost::endian::big_to_native(data_[i]) - 1);
|
||||||
|
|
||||||
if (prev != 0)
|
if (prev != 0)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
namespace xrpl {
|
namespace xrpl {
|
||||||
|
|
||||||
template <typename Key>
|
template <typename Key>
|
||||||
std::size_t
|
static std::size_t
|
||||||
extract(Key const& key)
|
extract(Key const& key)
|
||||||
{
|
{
|
||||||
return key;
|
return key;
|
||||||
@@ -365,7 +365,7 @@ public:
|
|||||||
size() const
|
size() const
|
||||||
{
|
{
|
||||||
std::size_t ret = 0;
|
std::size_t ret = 0;
|
||||||
for (auto const& p : map_)
|
for (auto& p : map_)
|
||||||
ret += p.size();
|
ret += p.size();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1604,7 +1604,7 @@ AgedOrderedContainer<IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::erase(
|
|||||||
beast::detail::AgedContainerIterator<IsConst, Iterator> pos)
|
beast::detail::AgedContainerIterator<IsConst, Iterator> pos)
|
||||||
requires(!IsBoostReverseIterator<Iterator>::value)
|
requires(!IsBoostReverseIterator<Iterator>::value)
|
||||||
{
|
{
|
||||||
unlinkAndDeleteElement(&*(pos++).iterator());
|
unlinkAndDeleteElement(&*((pos++).iterator()));
|
||||||
return beast::detail::AgedContainerIterator<false, Iterator>(pos.iterator());
|
return beast::detail::AgedContainerIterator<false, Iterator>(pos.iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1617,7 +1617,7 @@ AgedOrderedContainer<IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::erase(
|
|||||||
requires(!IsBoostReverseIterator<Iterator>::value)
|
requires(!IsBoostReverseIterator<Iterator>::value)
|
||||||
{
|
{
|
||||||
for (; first != last;)
|
for (; first != last;)
|
||||||
unlinkAndDeleteElement(&*(first++).iterator());
|
unlinkAndDeleteElement(&*((first++).iterator()));
|
||||||
|
|
||||||
return beast::detail::AgedContainerIterator<false, Iterator>(first.iterator());
|
return beast::detail::AgedContainerIterator<false, Iterator>(first.iterator());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2404,7 +2404,7 @@ beast::detail::AgedContainerIterator<false, Iterator>
|
|||||||
AgedUnorderedContainer<IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>::erase(
|
AgedUnorderedContainer<IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>::erase(
|
||||||
beast::detail::AgedContainerIterator<IsConst, Iterator> pos)
|
beast::detail::AgedContainerIterator<IsConst, Iterator> pos)
|
||||||
{
|
{
|
||||||
unlinkAndDeleteElement(&*(pos++).iterator());
|
unlinkAndDeleteElement(&*((pos++).iterator()));
|
||||||
return beast::detail::AgedContainerIterator<false, Iterator>(pos.iterator());
|
return beast::detail::AgedContainerIterator<false, Iterator>(pos.iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2424,7 +2424,7 @@ AgedUnorderedContainer<IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>
|
|||||||
beast::detail::AgedContainerIterator<IsConst, Iterator> last)
|
beast::detail::AgedContainerIterator<IsConst, Iterator> last)
|
||||||
{
|
{
|
||||||
for (; first != last;)
|
for (; first != last;)
|
||||||
unlinkAndDeleteElement(&*(first++).iterator());
|
unlinkAndDeleteElement(&*((first++).iterator()));
|
||||||
|
|
||||||
return beast::detail::AgedContainerIterator<false, Iterator>(first.iterator());
|
return beast::detail::AgedContainerIterator<false, Iterator>(first.iterator());
|
||||||
}
|
}
|
||||||
@@ -2536,7 +2536,7 @@ AgedUnorderedContainer<IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>
|
|||||||
return false;
|
return false;
|
||||||
for (auto iter(cbegin()), last(cend()), otherLast(other.cend()); iter != last; ++iter)
|
for (auto iter(cbegin()), last(cend()), otherLast(other.cend()); iter != last; ++iter)
|
||||||
{
|
{
|
||||||
auto const otherIter(other.find(extract(*iter)));
|
auto otherIter(other.find(extract(*iter)));
|
||||||
if (otherIter == otherLast)
|
if (otherIter == otherLast)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ struct LexicalCast<Out, std::string_view>
|
|||||||
if (first != last && *first == '+')
|
if (first != last && *first == '+')
|
||||||
++first;
|
++first;
|
||||||
|
|
||||||
auto const ret = std::from_chars(first, last, out);
|
auto ret = std::from_chars(first, last, out);
|
||||||
|
|
||||||
return ret.ec == std::errc() && ret.ptr == last;
|
return ret.ec == std::errc() && ret.ptr == last;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ void
|
|||||||
hash_append(Hasher& h, boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept
|
hash_append(Hasher& h, boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept
|
||||||
requires(IsContiguouslyHashable<Key, Hasher>::value)
|
requires(IsContiguouslyHashable<Key, Hasher>::value)
|
||||||
{
|
{
|
||||||
h(&v.begin(), v.size() * sizeof(Key));
|
h(&(v.begin()), v.size() * sizeof(Key));
|
||||||
}
|
}
|
||||||
// tuple
|
// tuple
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace beast::insight {
|
|||||||
class HookImpl : public std::enable_shared_from_this<HookImpl>
|
class HookImpl : public std::enable_shared_from_this<HookImpl>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using HandlerType = std::function<void()>;
|
using HandlerType = std::function<void(void)>;
|
||||||
|
|
||||||
virtual ~HookImpl() = 0;
|
virtual ~HookImpl() = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ isMulticast(Address const& addr)
|
|||||||
inline bool
|
inline bool
|
||||||
isPrivate(Address const& addr)
|
isPrivate(Address const& addr)
|
||||||
{
|
{
|
||||||
return addr.is_v4() ? isPrivate(addr.to_v4()) : isPrivate(addr.to_v6());
|
return (addr.is_v4()) ? isPrivate(addr.to_v4()) : isPrivate(addr.to_v6());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,7 +70,7 @@ isPrivate(Address const& addr)
|
|||||||
inline bool
|
inline bool
|
||||||
isPublic(Address const& addr)
|
isPublic(Address const& addr)
|
||||||
{
|
{
|
||||||
return addr.is_v4() ? isPublic(addr.to_v4()) : isPublic(addr.to_v6());
|
return (addr.is_v4()) ? isPublic(addr.to_v4()) : isPublic(addr.to_v6());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ip
|
} // namespace ip
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ trimRight(String const& s)
|
|||||||
{
|
{
|
||||||
using std::begin;
|
using std::begin;
|
||||||
using std::end;
|
using std::end;
|
||||||
auto const first(begin(s));
|
auto first(begin(s));
|
||||||
auto last(end(s));
|
auto last(end(s));
|
||||||
last = trimRight(first, last);
|
last = trimRight(first, last);
|
||||||
return {first, last};
|
return {first, last};
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ typeName()
|
|||||||
name += " volatile";
|
name += " volatile";
|
||||||
if (std::is_lvalue_reference_v<T>)
|
if (std::is_lvalue_reference_v<T>)
|
||||||
{
|
{
|
||||||
name += '&';
|
name += "&";
|
||||||
}
|
}
|
||||||
else if (std::is_rvalue_reference_v<T>)
|
else if (std::is_rvalue_reference_v<T>)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public:
|
|||||||
Module,
|
Module,
|
||||||
|
|
||||||
// Match nothing (used internally)
|
// Match nothing (used internally)
|
||||||
None,
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace beast::unit_test {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
std::string
|
static std::string
|
||||||
makeReason(String const& reason, char const* file, int line)
|
makeReason(String const& reason, char const* file, int line)
|
||||||
{
|
{
|
||||||
std::string s(reason);
|
std::string s(reason);
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ public:
|
|||||||
template <class F, class... Args>
|
template <class F, class... Args>
|
||||||
explicit Thread(Suite& s, F&& f, Args&&... args) : s_(&s)
|
explicit Thread(Suite& s, F&& f, Args&&... args) : s_(&s)
|
||||||
{
|
{
|
||||||
std::function<void()> b = [f = std::forward<F>(f),
|
std::function<void(void)> b = [f = std::forward<F>(f),
|
||||||
... args = std::forward<Args>(args)] mutable {
|
... args = std::forward<Args>(args)]() mutable {
|
||||||
std::invoke(f, args...);
|
std::invoke(f, args...);
|
||||||
};
|
};
|
||||||
t_ = std::thread(&Thread::run, this, std::move(b));
|
t_ = std::thread(&Thread::run, this, std::move(b));
|
||||||
@@ -94,7 +94,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void
|
void
|
||||||
run(std::function<void()> f)
|
run(std::function<void(void)> f)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ enum class Severity : std::uint8_t {
|
|||||||
Fatal = 5,
|
Fatal = 5,
|
||||||
|
|
||||||
Disabled = 6,
|
Disabled = 6,
|
||||||
None = Disabled,
|
None = Disabled
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ enum class Type : std::uint8_t {
|
|||||||
PrefixSha256 = 1,
|
PrefixSha256 = 1,
|
||||||
ThresholdSha256 = 2,
|
ThresholdSha256 = 2,
|
||||||
RsaSha256 = 3,
|
RsaSha256 = 3,
|
||||||
Ed25519Sha256 = 4,
|
Ed25519Sha256 = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
class Condition
|
class Condition
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public:
|
|||||||
|
|
||||||
using namespace der;
|
using namespace der;
|
||||||
|
|
||||||
auto const p = parsePreamble(s, ec);
|
auto p = parsePreamble(s, ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ enum class Error {
|
|||||||
UnexpectedTag,
|
UnexpectedTag,
|
||||||
LongTag,
|
LongTag,
|
||||||
LargeSize,
|
LargeSize,
|
||||||
PreimageTooLong,
|
PreimageTooLong
|
||||||
};
|
};
|
||||||
|
|
||||||
std::error_code
|
std::error_code
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ inline bool
|
|||||||
getIfExists<bool>(Section const& section, std::string const& name, bool& v)
|
getIfExists<bool>(Section const& section, std::string const& name, bool& v)
|
||||||
{
|
{
|
||||||
int intVal = 0;
|
int intVal = 0;
|
||||||
auto const stat = getIfExists(section, name, intVal);
|
auto stat = getIfExists(section, name, intVal);
|
||||||
if (stat)
|
if (stat)
|
||||||
v = bool(intVal);
|
v = bool(intVal);
|
||||||
return stat;
|
return stat;
|
||||||
|
|||||||
@@ -93,14 +93,14 @@ public:
|
|||||||
void
|
void
|
||||||
check(std::vector<TxID> accepted, Predicate&& pred)
|
check(std::vector<TxID> accepted, Predicate&& pred)
|
||||||
{
|
{
|
||||||
auto const acceptTxid = accepted.begin();
|
auto acceptTxid = accepted.begin();
|
||||||
auto const ae = accepted.end();
|
auto const ae = accepted.end();
|
||||||
std::sort(acceptTxid, ae);
|
std::sort(acceptTxid, ae);
|
||||||
|
|
||||||
// We want to remove all tracking entries for transactions that were
|
// We want to remove all tracking entries for transactions that were
|
||||||
// accepted as well as those which match the predicate.
|
// accepted as well as those which match the predicate.
|
||||||
|
|
||||||
auto const i = removeIfIntersectOrMatch(
|
auto i = removeIfIntersectOrMatch(
|
||||||
tracker_.begin(),
|
tracker_.begin(),
|
||||||
tracker_.end(),
|
tracker_.end(),
|
||||||
accepted.begin(),
|
accepted.begin(),
|
||||||
|
|||||||
@@ -779,7 +779,7 @@ Consensus<Adaptor>::peerProposalInternal(
|
|||||||
|
|
||||||
{
|
{
|
||||||
// update current position
|
// update current position
|
||||||
auto const peerPosIt = currPeerPositions_.find(peerID);
|
auto peerPosIt = currPeerPositions_.find(peerID);
|
||||||
|
|
||||||
if (peerPosIt != currPeerPositions_.end())
|
if (peerPosIt != currPeerPositions_.end())
|
||||||
{
|
{
|
||||||
@@ -1110,7 +1110,7 @@ Consensus<Adaptor>::checkLedger(std::unique_ptr<std::stringstream> const& clog)
|
|||||||
{
|
{
|
||||||
CLOG(clog) << "checkLedger. ";
|
CLOG(clog) << "checkLedger. ";
|
||||||
|
|
||||||
auto const netLgr = adaptor_.getPrevLedger(prevLedgerID_, previousLedger_, mode_.get());
|
auto netLgr = adaptor_.getPrevLedger(prevLedgerID_, previousLedger_, mode_.get());
|
||||||
CLOG(clog) << "network ledgerid " << netLgr << ", "
|
CLOG(clog) << "network ledgerid " << netLgr << ", "
|
||||||
<< "previous ledger " << prevLedgerID_ << ". ";
|
<< "previous ledger " << prevLedgerID_ << ". ";
|
||||||
|
|
||||||
@@ -1159,8 +1159,8 @@ Consensus<Adaptor>::phaseOpen(std::unique_ptr<std::stringstream> const& clog)
|
|||||||
|
|
||||||
// it is shortly before ledger close time
|
// it is shortly before ledger close time
|
||||||
bool const anyTransactions = adaptor_.hasOpenTransactions();
|
bool const anyTransactions = adaptor_.hasOpenTransactions();
|
||||||
auto const proposersClosed = currPeerPositions_.size();
|
auto proposersClosed = currPeerPositions_.size();
|
||||||
auto const proposersValidated = adaptor_.proposersValidated(prevLedgerID_);
|
auto proposersValidated = adaptor_.proposersValidated(prevLedgerID_);
|
||||||
|
|
||||||
openTime_.tick(clock_.now());
|
openTime_.tick(clock_.now());
|
||||||
|
|
||||||
@@ -1669,7 +1669,7 @@ Consensus<Adaptor>::haveConsensus(std::unique_ptr<std::stringstream> const& clog
|
|||||||
// CHECKME: should possibly count unacquired TX sets as disagreeing
|
// CHECKME: should possibly count unacquired TX sets as disagreeing
|
||||||
int agree = 0, disagree = 0;
|
int agree = 0, disagree = 0;
|
||||||
|
|
||||||
auto const ourPosition = result_->position.position();
|
auto ourPosition = result_->position.position();
|
||||||
|
|
||||||
// Count number of agreements/disagreements with our position
|
// Count number of agreements/disagreements with our position
|
||||||
for (auto const& [nodeId, peerPos] : currPeerPositions_)
|
for (auto const& [nodeId, peerPos] : currPeerPositions_)
|
||||||
@@ -1686,7 +1686,7 @@ Consensus<Adaptor>::haveConsensus(std::unique_ptr<std::stringstream> const& clog
|
|||||||
++disagree;
|
++disagree;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto const currentFinished = adaptor_.proposersFinished(previousLedger_, prevLedgerID_);
|
auto currentFinished = adaptor_.proposersFinished(previousLedger_, prevLedgerID_);
|
||||||
|
|
||||||
JLOG(j_.debug()) << "Checking for TX consensus: agree=" << agree << ", disagree=" << disagree;
|
JLOG(j_.debug()) << "Checking for TX consensus: agree=" << agree << ", disagree=" << disagree;
|
||||||
|
|
||||||
@@ -1812,7 +1812,7 @@ Consensus<Adaptor>::createDisputes(TxSetT const& o, std::unique_ptr<std::strings
|
|||||||
<< ". ";
|
<< ". ";
|
||||||
JLOG(j_.debug()) << "createDisputes " << result_->txns.id() << " to " << o.id();
|
JLOG(j_.debug()) << "createDisputes " << result_->txns.id() << " to " << o.id();
|
||||||
|
|
||||||
auto const differences = result_->txns.compare(o);
|
auto differences = result_->txns.compare(o);
|
||||||
|
|
||||||
int dc = 0;
|
int dc = 0;
|
||||||
|
|
||||||
@@ -1826,7 +1826,7 @@ Consensus<Adaptor>::createDisputes(TxSetT const& o, std::unique_ptr<std::strings
|
|||||||
"xrpl::Consensus::createDisputes : has disputed transactions");
|
"xrpl::Consensus::createDisputes : has disputed transactions");
|
||||||
|
|
||||||
TxT const tx = inThisSet ? result_->txns.find(txId) : o.find(txId);
|
TxT const tx = inThisSet ? result_->txns.find(txId) : o.find(txId);
|
||||||
auto const txID = tx.id();
|
auto txID = tx.id();
|
||||||
|
|
||||||
if (result_->disputes.find(txID) != result_->disputes.end())
|
if (result_->disputes.find(txID) != result_->disputes.end())
|
||||||
continue;
|
continue;
|
||||||
@@ -1837,8 +1837,7 @@ Consensus<Adaptor>::createDisputes(TxSetT const& o, std::unique_ptr<std::strings
|
|||||||
tx,
|
tx,
|
||||||
result_->txns.exists(txID),
|
result_->txns.exists(txID),
|
||||||
std::max(prevProposers_, currPeerPositions_.size()),
|
std::max(prevProposers_, currPeerPositions_.size()),
|
||||||
j_,
|
j_};
|
||||||
};
|
|
||||||
|
|
||||||
// Update all of the available peer's votes on the disputed transaction
|
// Update all of the available peer's votes on the disputed transaction
|
||||||
for (auto const& [nodeId, peerPos] : currPeerPositions_)
|
for (auto const& [nodeId, peerPos] : currPeerPositions_)
|
||||||
|
|||||||
@@ -145,26 +145,18 @@ struct ConsensusParms
|
|||||||
std::map<AvalancheState, AvalancheCutoff> const avalancheCutoffs{
|
std::map<AvalancheState, AvalancheCutoff> const avalancheCutoffs{
|
||||||
// {state, {time, percent, nextState}},
|
// {state, {time, percent, nextState}},
|
||||||
// Initial state: 50% of nodes must vote yes
|
// Initial state: 50% of nodes must vote yes
|
||||||
{
|
{AvalancheState::Init,
|
||||||
AvalancheState::Init,
|
{.consensusTime = 0, .consensusPct = 50, .next = AvalancheState::Mid}},
|
||||||
{.consensusTime = 0, .consensusPct = 50, .next = AvalancheState::Mid},
|
|
||||||
},
|
|
||||||
// mid-consensus starts after 50% of the previous round time, and
|
// mid-consensus starts after 50% of the previous round time, and
|
||||||
// requires 65% yes
|
// requires 65% yes
|
||||||
{
|
{AvalancheState::Mid,
|
||||||
AvalancheState::Mid,
|
{.consensusTime = 50, .consensusPct = 65, .next = AvalancheState::Late}},
|
||||||
{.consensusTime = 50, .consensusPct = 65, .next = AvalancheState::Late},
|
|
||||||
},
|
|
||||||
// late consensus starts after 85% time, and requires 70% yes
|
// late consensus starts after 85% time, and requires 70% yes
|
||||||
{
|
{AvalancheState::Late,
|
||||||
AvalancheState::Late,
|
{.consensusTime = 85, .consensusPct = 70, .next = AvalancheState::Stuck}},
|
||||||
{.consensusTime = 85, .consensusPct = 70, .next = AvalancheState::Stuck},
|
|
||||||
},
|
|
||||||
// we're stuck after 2x time, requires 95% yes votes
|
// we're stuck after 2x time, requires 95% yes votes
|
||||||
{
|
{AvalancheState::Stuck,
|
||||||
AvalancheState::Stuck,
|
{.consensusTime = 200, .consensusPct = 95, .next = AvalancheState::Stuck}},
|
||||||
{.consensusTime = 200, .consensusPct = 95, .next = AvalancheState::Stuck},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ enum class ConsensusMode {
|
|||||||
* if we entered the round observing, but is used to indicate we did
|
* if we entered the round observing, but is used to indicate we did
|
||||||
* have the wrongLedger at some point.
|
* have the wrongLedger at some point.
|
||||||
*/
|
*/
|
||||||
SwitchedLedger,
|
SwitchedLedger
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::string
|
inline std::string
|
||||||
@@ -222,7 +222,7 @@ medianCloseOffset(ConsensusCloseTimes const& times)
|
|||||||
|
|
||||||
// Accumulate weight in time order; the first bin to reach halfWeight is
|
// Accumulate weight in time order; the first bin to reach halfWeight is
|
||||||
// the (lower) weighted median. Returns true once that bin is found.
|
// the (lower) weighted median. Returns true once that bin is found.
|
||||||
auto const step = [&](time_point t, std::int64_t w) {
|
auto step = [&](time_point t, std::int64_t w) {
|
||||||
XRPL_ASSERT(tally < halfWeight, "xrpl::medianCloseOffset::step : median not yet found");
|
XRPL_ASSERT(tally < halfWeight, "xrpl::medianCloseOffset::step : median not yet found");
|
||||||
tally += w;
|
tally += w;
|
||||||
if (tally >= halfWeight)
|
if (tally >= halfWeight)
|
||||||
@@ -267,7 +267,7 @@ enum class ConsensusState {
|
|||||||
No, ///< We do not have consensus
|
No, ///< We do not have consensus
|
||||||
MovedOn, ///< The network has consensus without us
|
MovedOn, ///< The network has consensus without us
|
||||||
Expired, ///< Consensus time limit has hard-expired
|
Expired, ///< Consensus time limit has hard-expired
|
||||||
Yes, ///< We have consensus along with the network
|
Yes ///< We have consensus along with the network
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ template <class Tx, class NodeId>
|
|||||||
void
|
void
|
||||||
DisputedTx<Tx, NodeId>::unVote(NodeId const& peer)
|
DisputedTx<Tx, NodeId>::unVote(NodeId const& peer)
|
||||||
{
|
{
|
||||||
auto const it = votes_.find(peer);
|
auto it = votes_.find(peer);
|
||||||
|
|
||||||
if (it != votes_.end())
|
if (it != votes_.end())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ struct Node
|
|||||||
void
|
void
|
||||||
erase(Node const* child)
|
erase(Node const* child)
|
||||||
{
|
{
|
||||||
auto const it = std::ranges::find_if(
|
auto it = std::ranges::find_if(
|
||||||
children, [child](std::unique_ptr<Node> const& curr) { return curr.get() == child; });
|
children, [child](std::unique_ptr<Node> const& curr) { return curr.get() == child; });
|
||||||
XRPL_ASSERT(it != children.end(), "xrpl::Node::erase : valid input");
|
XRPL_ASSERT(it != children.end(), "xrpl::Node::erase : valid input");
|
||||||
std::swap(*it, children.back());
|
std::swap(*it, children.back());
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ enum class ValStatus {
|
|||||||
/**
|
/**
|
||||||
* Multiple validations by a validator for different ledgers
|
* Multiple validations by a validator for different ledgers
|
||||||
*/
|
*/
|
||||||
Conflicting,
|
Conflicting
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::string
|
inline std::string
|
||||||
@@ -366,7 +366,7 @@ private:
|
|||||||
removeTrie(std::scoped_lock<Mutex> const&, NodeID const& nodeID, Validation const& val)
|
removeTrie(std::scoped_lock<Mutex> const&, NodeID const& nodeID, Validation const& val)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
auto const it = acquiring_.find(std::make_pair(val.seq(), val.ledgerID()));
|
auto it = acquiring_.find(std::make_pair(val.seq(), val.ledgerID()));
|
||||||
if (it != acquiring_.end())
|
if (it != acquiring_.end())
|
||||||
{
|
{
|
||||||
it->second.erase(nodeID);
|
it->second.erase(nodeID);
|
||||||
@@ -375,7 +375,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto const it = lastLedger_.find(nodeID);
|
auto it = lastLedger_.find(nodeID);
|
||||||
if (it != lastLedger_.end() && it->second.id() == val.ledgerID())
|
if (it != lastLedger_.end() && it->second.id() == val.ledgerID())
|
||||||
{
|
{
|
||||||
trie_.remove(it->second);
|
trie_.remove(it->second);
|
||||||
@@ -443,7 +443,7 @@ private:
|
|||||||
// Clear any prior acquiring ledger for this node
|
// Clear any prior acquiring ledger for this node
|
||||||
if (prior)
|
if (prior)
|
||||||
{
|
{
|
||||||
auto const it = acquiring_.find(*prior);
|
auto it = acquiring_.find(*prior);
|
||||||
if (it != acquiring_.end())
|
if (it != acquiring_.end())
|
||||||
{
|
{
|
||||||
it->second.erase(nodeID);
|
it->second.erase(nodeID);
|
||||||
@@ -455,7 +455,7 @@ private:
|
|||||||
checkAcquired(lock);
|
checkAcquired(lock);
|
||||||
|
|
||||||
std::pair<Seq, ID> const valPair{val.seq(), val.ledgerID()};
|
std::pair<Seq, ID> const valPair{val.seq(), val.ledgerID()};
|
||||||
auto const it = acquiring_.find(valPair);
|
auto it = acquiring_.find(valPair);
|
||||||
if (it != acquiring_.end())
|
if (it != acquiring_.end())
|
||||||
{
|
{
|
||||||
it->second.insert(nodeID);
|
it->second.insert(nodeID);
|
||||||
@@ -529,7 +529,7 @@ private:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto const cit = typename decltype(current_)::const_iterator{it};
|
auto cit = typename decltype(current_)::const_iterator{it};
|
||||||
// contains a live record
|
// contains a live record
|
||||||
f(cit->first, cit->second);
|
f(cit->first, cit->second);
|
||||||
++it;
|
++it;
|
||||||
@@ -554,7 +554,7 @@ private:
|
|||||||
void
|
void
|
||||||
byLedger(std::scoped_lock<Mutex> const&, ID const& ledgerID, Pre&& pre, F&& f)
|
byLedger(std::scoped_lock<Mutex> const&, ID const& ledgerID, Pre&& pre, F&& f)
|
||||||
{
|
{
|
||||||
auto const it = byLedger_.find(ledgerID);
|
auto it = byLedger_.find(ledgerID);
|
||||||
if (it != byLedger_.end())
|
if (it != byLedger_.end())
|
||||||
{
|
{
|
||||||
// Update set time since it is being used
|
// Update set time since it is being used
|
||||||
@@ -857,7 +857,7 @@ public:
|
|||||||
if (!preferred)
|
if (!preferred)
|
||||||
{
|
{
|
||||||
// fall back to majority over acquiring ledgers
|
// fall back to majority over acquiring ledgers
|
||||||
auto const it = std::ranges::max_element(acquiring_, [](auto const& a, auto const& b) {
|
auto it = std::ranges::max_element(acquiring_, [](auto const& a, auto const& b) {
|
||||||
std::pair<Seq, ID> const& aKey = a.first;
|
std::pair<Seq, ID> const& aKey = a.first;
|
||||||
typename HashSet<NodeID>::size_type const& aSize = a.second.size();
|
typename HashSet<NodeID>::size_type const& aSize = a.second.size();
|
||||||
std::pair<Seq, ID> const& bKey = b.first;
|
std::pair<Seq, ID> const& bKey = b.first;
|
||||||
@@ -937,7 +937,7 @@ public:
|
|||||||
return (preferred->first >= minSeq) ? preferred->second : lcl.id();
|
return (preferred->first >= minSeq) ? preferred->second : lcl.id();
|
||||||
|
|
||||||
// Otherwise, rely on peer ledgers
|
// Otherwise, rely on peer ledgers
|
||||||
auto const it = std::ranges::max_element(peerCounts, [](auto const& a, auto const& b) {
|
auto it = std::ranges::max_element(peerCounts, [](auto const& a, auto const& b) {
|
||||||
// Prefer larger counts, then larger ids on ties
|
// Prefer larger counts, then larger ids on ties
|
||||||
// (max_element expects this to return true if a < b)
|
// (max_element expects this to return true if a < b)
|
||||||
return std::tie(a.second, a.first) < std::tie(b.second, b.first);
|
return std::tie(a.second, a.first) < std::tie(b.second, b.first);
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (!allClosuresDoneCond_.wait_for(lock, wait, [this] { return closureCount_ == 0; }))
|
if (!allClosuresDoneCond_.wait_for(lock, wait, [this] { return closureCount_ == 0; }))
|
||||||
{
|
{
|
||||||
if (auto const stream = j.error())
|
if (auto stream = j.error())
|
||||||
stream << name << " waiting for ClosureCounter::join().";
|
stream << name << " waiting for ClosureCounter::join().";
|
||||||
allClosuresDoneCond_.wait(lock, [this] { return closureCount_ == 0; });
|
allClosuresDoneCond_.wait(lock, [this] { return closureCount_ == 0; });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ JobQueue::Coro::post()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sp keeps 'this' alive
|
// sp keeps 'this' alive
|
||||||
if (jq_.addJob(type_, name_, [this, sp = shared_from_this()] { resume(); }))
|
if (jq_.addJob(type_, name_, [this, sp = shared_from_this()]() { resume(); }))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ inline void
|
|||||||
JobQueue::Coro::join()
|
JobQueue::Coro::join()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(mutexRun_);
|
std::unique_lock<std::mutex> lk(mutexRun_);
|
||||||
cv_.wait(lk, [this] { return !running_; });
|
cv_.wait(lk, [this]() { return !running_; });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace xrpl
|
} // namespace xrpl
|
||||||
@@ -37,7 +37,7 @@ enum class HashRouterFlags : std::uint16_t {
|
|||||||
PRIVATE6 = 0x2000,
|
PRIVATE6 = 0x2000,
|
||||||
// Used in apply.cpp
|
// Used in apply.cpp
|
||||||
PRIVATE7 = 0x4000,
|
PRIVATE7 = 0x4000,
|
||||||
PRIVATE8 = 0x8000,
|
PRIVATE8 = 0x8000
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr HashRouterFlags
|
constexpr HashRouterFlags
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ private:
|
|||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
int const maxLimit = std::numeric_limits<int>::max();
|
int const maxLimit = std::numeric_limits<int>::max();
|
||||||
|
|
||||||
auto const add = [this](
|
auto add = [this](
|
||||||
JobType jt,
|
JobType jt,
|
||||||
std::string name,
|
std::string name,
|
||||||
int limit,
|
int limit,
|
||||||
std::chrono::milliseconds avgLatency,
|
std::chrono::milliseconds avgLatency,
|
||||||
std::chrono::milliseconds peakLatency) {
|
std::chrono::milliseconds peakLatency) {
|
||||||
XRPL_ASSERT(!map.contains(jt), "xrpl::JobTypes::JobTypes::add : unique job type input");
|
XRPL_ASSERT(!map.contains(jt), "xrpl::JobTypes::JobTypes::add : unique job type input");
|
||||||
|
|
||||||
[[maybe_unused]] auto const inserted =
|
[[maybe_unused]] auto const inserted =
|
||||||
|
|||||||
@@ -177,13 +177,12 @@ measureDurationAndLog(
|
|||||||
std::chrono::duration<Rep, Period> maxDelay,
|
std::chrono::duration<Rep, Period> maxDelay,
|
||||||
beast::Journal const& journal)
|
beast::Journal const& journal)
|
||||||
{
|
{
|
||||||
auto const startTime = std::chrono::high_resolution_clock::now();
|
auto startTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
auto result = func();
|
auto result = func();
|
||||||
|
|
||||||
auto const endTime = std::chrono::high_resolution_clock::now();
|
auto endTime = std::chrono::high_resolution_clock::now();
|
||||||
auto const duration =
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
|
||||||
std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
|
|
||||||
if (duration > maxDelay)
|
if (duration > maxDelay)
|
||||||
{
|
{
|
||||||
JLOG(journal.warn()) << actionDescription << " took " << duration.count() << " ms";
|
JLOG(journal.warn()) << actionDescription << " took " << duration.count() << " ms";
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ private:
|
|||||||
ArraySeparator,
|
ArraySeparator,
|
||||||
MemberSeparator,
|
MemberSeparator,
|
||||||
Comment,
|
Comment,
|
||||||
Error,
|
Error
|
||||||
};
|
};
|
||||||
|
|
||||||
class Token
|
class Token
|
||||||
|
|||||||
@@ -3,13 +3,11 @@
|
|||||||
#include <xrpl/basics/Number.h>
|
#include <xrpl/basics/Number.h>
|
||||||
#include <xrpl/json/json_forwards.h>
|
#include <xrpl/json/json_forwards.h>
|
||||||
|
|
||||||
#include <concepts>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,7 +26,7 @@ enum class ValueType {
|
|||||||
String, ///< UTF-8 string value
|
String, ///< UTF-8 string value
|
||||||
Boolean, ///< bool value
|
Boolean, ///< bool value
|
||||||
Array, ///< array value (ordered list)
|
Array, ///< array value (ordered list)
|
||||||
Object, ///< object value (collection of name/value pairs).
|
Object ///< object value (collection of name/value pairs).
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -200,15 +198,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
Value(StaticString const& value);
|
Value(StaticString const& value);
|
||||||
Value(std::string const& value);
|
Value(std::string const& value);
|
||||||
/**
|
|
||||||
* @brief Constructs a value from a string view.
|
|
||||||
*
|
|
||||||
* The characters are copied, so the view need not outlive the call and need
|
|
||||||
* not be NUL-terminated.
|
|
||||||
*
|
|
||||||
* @param value The characters to copy.
|
|
||||||
*/
|
|
||||||
Value(std::string_view value);
|
|
||||||
Value(bool value);
|
Value(bool value);
|
||||||
Value(Value const& other);
|
Value(Value const& other);
|
||||||
~Value();
|
~Value();
|
||||||
@@ -483,32 +472,6 @@ toJson(xrpl::Number const& number)
|
|||||||
bool
|
bool
|
||||||
operator==(Value const&, Value const&);
|
operator==(Value const&, Value const&);
|
||||||
|
|
||||||
/**
|
|
||||||
* Compares a value with a string view, reading the value's characters in place
|
|
||||||
* rather than building a Value from the view.
|
|
||||||
*
|
|
||||||
* Constrained to the exact type: a string literal converts equally well to a
|
|
||||||
* view and to a Value, so a plain overload makes `value == "literal"`
|
|
||||||
* ambiguous.
|
|
||||||
*
|
|
||||||
* @param x The value to compare.
|
|
||||||
* @param y The characters to compare it against.
|
|
||||||
* @return Whether `x` is a string whose characters up to its first NUL are
|
|
||||||
* exactly the characters of `y`.
|
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
requires std::same_as<T, std::string_view>
|
|
||||||
bool
|
|
||||||
operator==(Value const& x, T y)
|
|
||||||
{
|
|
||||||
if (!x.isString())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// A string `Value` can hold a null pointer, which names no characters, so it equals no view.
|
|
||||||
char const* const s = x.asCString();
|
|
||||||
return s != nullptr && std::string_view{s} == y;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
operator<(Value const&, Value const&);
|
operator<(Value const&, Value const&);
|
||||||
|
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ public:
|
|||||||
beast::Journal j)
|
beast::Journal j)
|
||||||
{
|
{
|
||||||
// Ask implementation what to do
|
// Ask implementation what to do
|
||||||
auto const actions = doVoting(
|
auto actions = doVoting(
|
||||||
lastClosedLedger->rules(),
|
lastClosedLedger->rules(),
|
||||||
lastClosedLedger->parentCloseTime(),
|
lastClosedLedger->parentCloseTime(),
|
||||||
getEnabledAmendments(*lastClosedLedger),
|
getEnabledAmendments(*lastClosedLedger),
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ enum ApplyFlags : std::uint32_t {
|
|||||||
// afterward, so signature-presence checks (e.g. Batch signer matching)
|
// afterward, so signature-presence checks (e.g. Batch signer matching)
|
||||||
// are skipped at proposal-creation time (On-Chain Cosigner spec
|
// are skipped at proposal-creation time (On-Chain Cosigner spec
|
||||||
// §5.3.1.2).
|
// §5.3.1.2).
|
||||||
TapProposal = 0x2000,
|
TapProposal = 0x2000
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr ApplyFlags
|
constexpr ApplyFlags
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ constexpr std::chrono::seconds kLedgerPossibleTimeResolutions[] = {
|
|||||||
std::chrono::seconds{30},
|
std::chrono::seconds{30},
|
||||||
std::chrono::seconds{60},
|
std::chrono::seconds{60},
|
||||||
std::chrono::seconds{90},
|
std::chrono::seconds{90},
|
||||||
std::chrono::seconds{120},
|
std::chrono::seconds{120}};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initial resolution of ledger close time.
|
* Initial resolution of ledger close time.
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
{
|
{
|
||||||
std::scoped_lock const lock(mutex_);
|
std::scoped_lock const lock(mutex_);
|
||||||
|
|
||||||
auto const it = map_.find(seq);
|
auto it = map_.find(seq);
|
||||||
|
|
||||||
if ((it == map_.end()) || it->second)
|
if ((it == map_.end()) || it->second)
|
||||||
{
|
{
|
||||||
@@ -88,7 +88,7 @@ public:
|
|||||||
std::unique_lock<std::mutex> lock(mutex_);
|
std::unique_lock<std::mutex> lock(mutex_);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
auto const it = map_.find(seq);
|
auto it = map_.find(seq);
|
||||||
|
|
||||||
if (it == map_.end())
|
if (it == map_.end())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <xrpl/beast/utility/Journal.h>
|
#include <xrpl/beast/utility/Journal.h>
|
||||||
#include <xrpl/ledger/ApplyView.h>
|
#include <xrpl/ledger/ApplyView.h>
|
||||||
#include <xrpl/ledger/ReadView.h>
|
#include <xrpl/ledger/ReadView.h>
|
||||||
|
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||||
#include <xrpl/protocol/AccountID.h>
|
#include <xrpl/protocol/AccountID.h>
|
||||||
#include <xrpl/protocol/Asset.h>
|
#include <xrpl/protocol/Asset.h>
|
||||||
#include <xrpl/protocol/Keylet.h>
|
#include <xrpl/protocol/Keylet.h>
|
||||||
@@ -164,7 +165,7 @@ getCandidateLedger(LedgerIndex requested)
|
|||||||
areCompatible(
|
areCompatible(
|
||||||
ReadView const& validLedger,
|
ReadView const& validLedger,
|
||||||
ReadView const& testLedger,
|
ReadView const& testLedger,
|
||||||
beast::Journal::Stream const& s,
|
beast::Journal::Stream& s,
|
||||||
char const* reason);
|
char const* reason);
|
||||||
|
|
||||||
[[nodiscard]] bool
|
[[nodiscard]] bool
|
||||||
@@ -172,7 +173,7 @@ areCompatible(
|
|||||||
UInt256 const& validHash,
|
UInt256 const& validHash,
|
||||||
LedgerIndex validIndex,
|
LedgerIndex validIndex,
|
||||||
ReadView const& testLedger,
|
ReadView const& testLedger,
|
||||||
beast::Journal::Stream const& s,
|
beast::Journal::Stream& s,
|
||||||
char const* reason);
|
char const* reason);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -185,7 +186,7 @@ areCompatible(
|
|||||||
dirLink(
|
dirLink(
|
||||||
ApplyView& view,
|
ApplyView& view,
|
||||||
AccountID const& owner,
|
AccountID const& owner,
|
||||||
SLE::pointer const& object,
|
SLE::pointer& object,
|
||||||
SF_UINT64 const& node = sfOwnerNode);
|
SF_UINT64 const& node = sfOwnerNode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,7 +212,7 @@ canWithdraw(
|
|||||||
ReadView const& view,
|
ReadView const& view,
|
||||||
AccountID const& from,
|
AccountID const& from,
|
||||||
AccountID const& to,
|
AccountID const& to,
|
||||||
SLE::ConstRef toSle,
|
AccountRootEntryR const& toSle,
|
||||||
STAmount const& amount,
|
STAmount const& amount,
|
||||||
bool hasDestinationTag,
|
bool hasDestinationTag,
|
||||||
std::optional<std::vector<UInt256>> const& credentialIDs = std::nullopt);
|
std::optional<std::vector<UInt256>> const& credentialIDs = std::nullopt);
|
||||||
|
|||||||
@@ -30,17 +30,13 @@ public:
|
|||||||
static constexpr size_t kInitialBufferSize = kilobytes(256);
|
static constexpr size_t kInitialBufferSize = kilobytes(256);
|
||||||
|
|
||||||
RawStateTable()
|
RawStateTable()
|
||||||
: monotonicResource_{
|
: monotonicResource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
|
||||||
std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
|
kInitialBufferSize)}
|
||||||
kInitialBufferSize),
|
|
||||||
}
|
|
||||||
, items_{monotonicResource_.get()} {};
|
, items_{monotonicResource_.get()} {};
|
||||||
|
|
||||||
RawStateTable(RawStateTable const& rhs)
|
RawStateTable(RawStateTable const& rhs)
|
||||||
: monotonicResource_{
|
: monotonicResource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
|
||||||
std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
|
kInitialBufferSize)}
|
||||||
kInitialBufferSize),
|
|
||||||
}
|
|
||||||
, items_{rhs.items_, monotonicResource_.get()}
|
, items_{rhs.items_, monotonicResource_.get()}
|
||||||
, dropsDestroyed_{rhs.dropsDestroyed_} {};
|
, dropsDestroyed_{rhs.dropsDestroyed_} {};
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,20 @@
|
|||||||
#include <xrpl/protocol/AccountID.h>
|
#include <xrpl/protocol/AccountID.h>
|
||||||
#include <xrpl/protocol/Indexes.h>
|
#include <xrpl/protocol/Indexes.h>
|
||||||
#include <xrpl/protocol/LedgerFormats.h>
|
#include <xrpl/protocol/LedgerFormats.h>
|
||||||
|
#include <xrpl/protocol/TER.h>
|
||||||
|
#include <xrpl/protocol/XRPAmount.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace xrpl {
|
namespace xrpl {
|
||||||
|
|
||||||
|
struct Adjustment
|
||||||
|
{
|
||||||
|
std::int32_t ownerCountDelta = 0;
|
||||||
|
std::int32_t accountCountDelta = 0;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename ViewT>
|
template <typename ViewT>
|
||||||
class AccountRootEntry : public SLEBase<ViewT, ltACCOUNT_ROOT>
|
class AccountRootEntry : public SLEBase<ViewT, ltACCOUNT_ROOT>
|
||||||
{
|
{
|
||||||
@@ -27,6 +38,123 @@ public:
|
|||||||
: Base(keylet::account(id), view, j)
|
: Base(keylet::account(id), view, j)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the account reserve, in drops.
|
||||||
|
*
|
||||||
|
* Actual owner count can be adjusted by delta in ownerCountAdj
|
||||||
|
* Actual reserve count can be adjusted by delta in accountCountAdj
|
||||||
|
* The reserve is calculated as:
|
||||||
|
* (ownerCount + "sponsoring object count" - "sponsored object count" + additionalOwnerCount) *
|
||||||
|
* increment + (1 if not sponsored account + sponsoringAccountCount) * "reserve base"
|
||||||
|
*
|
||||||
|
* @param adj Adjustment to the owner/account count (default: 0/0). Positive to add, negative
|
||||||
|
* to subtract.
|
||||||
|
* @return The account reserve amount in drops
|
||||||
|
*/
|
||||||
|
[[nodiscard]] XRPAmount
|
||||||
|
reserve(Adjustment adj = {}) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return number of the objects which reserve is covered by the account (so called "owner
|
||||||
|
* count"). Actual owner count can be adjusted by delta in ownerCountAdj.
|
||||||
|
*
|
||||||
|
* @param ownerCountAdj Adjustment to the owner count (default: 0)
|
||||||
|
* @return The adjusted owner count
|
||||||
|
*/
|
||||||
|
[[nodiscard]] std::uint32_t
|
||||||
|
ownerCount(std::int32_t ownerCountAdj = 0) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this account has sufficient reserve.
|
||||||
|
*
|
||||||
|
* @param ctx The apply-view context (view + tx)
|
||||||
|
* @param accBalance The account's balance
|
||||||
|
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
||||||
|
* @param adj Adjustment to the owner/account count (default: 0/0). Positive to add, negative
|
||||||
|
* to subtract.
|
||||||
|
* @param insufReserveCode The transaction result code to return if the reserve is
|
||||||
|
* insufficient (default: tecINSUFFICIENT_RESERVE).
|
||||||
|
* @return Transaction result code
|
||||||
|
*/
|
||||||
|
[[nodiscard]] TER
|
||||||
|
checkReserve(
|
||||||
|
ApplyViewContext ctx,
|
||||||
|
XRPAmount accBalance,
|
||||||
|
std::optional<AccountRootEntry<ReadView>> const& sponsorSle,
|
||||||
|
Adjustment adj,
|
||||||
|
TER insufReserveCode = tecINSUFFICIENT_RESERVE) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this account has sufficient reserve, deriving the sponsor internally.
|
||||||
|
*
|
||||||
|
* Equivalent to the overload above, but resolves the sponsor via
|
||||||
|
* getEffectiveTxReserveSponsor(ctx, *this) instead of taking it explicitly. Use this
|
||||||
|
* in the common case where the sponsor is simply the transaction's reserve
|
||||||
|
* sponsor for this account. Callers that must force the account's-own-reserve branch
|
||||||
|
* (passing a null sponsor) or supply a different sponsor should use the
|
||||||
|
* explicit overload above.
|
||||||
|
*
|
||||||
|
* @param ctx The apply-view context (view + tx)
|
||||||
|
* @param accBalance The account's balance
|
||||||
|
* @param adj Reserve adjustments (owner/account count deltas)
|
||||||
|
* @return Transaction result code
|
||||||
|
*/
|
||||||
|
[[nodiscard]] TER
|
||||||
|
checkReserve(ApplyViewContext ctx, XRPAmount accBalance, Adjustment adj) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase owner-count fields when the caller supplies the sponsor.
|
||||||
|
*
|
||||||
|
* This helper does not create a ledger object. It updates reserve accounting
|
||||||
|
* after the caller has created/updated an object.
|
||||||
|
* If sponsorSle is provided, this also adjusts the account's sponsored count
|
||||||
|
* and the sponsor's sponsoring count.
|
||||||
|
*
|
||||||
|
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
||||||
|
* @param count Amount to add to the owner count
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
increaseOwnerCount(std::optional<AccountRootEntry<ApplyView>>& sponsorSle, std::uint32_t count)
|
||||||
|
requires Base::kIsWritable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase owner-count fields, deriving the tx reserve sponsor internally.
|
||||||
|
*
|
||||||
|
* Equivalent to the overload above, but resolves the sponsor via
|
||||||
|
* getEffectiveTxReserveSponsor(ctx, *this) instead of taking it explicitly. Use
|
||||||
|
* this when the sponsor is the transaction's reserve sponsor for this account
|
||||||
|
* (the common create path). Deletion paths, which derive the sponsor from an
|
||||||
|
* object's sfSponsor field, should keep using the explicit overload.
|
||||||
|
*
|
||||||
|
* @param ctx The apply-view context (view + tx)
|
||||||
|
* @param count Amount to add to the owner count
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
increaseOwnerCount(ApplyViewContext ctx, std::uint32_t count)
|
||||||
|
requires Base::kIsWritable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrease owner-count fields when the caller supplies the sponsor.
|
||||||
|
*
|
||||||
|
* This helper does not delete a ledger object. It updates reserve accounting
|
||||||
|
* after the caller has removed an owner-counted reserve, or for special
|
||||||
|
* owner-count changes whose sponsor cannot be derived from an object's
|
||||||
|
* sfSponsor field.
|
||||||
|
*
|
||||||
|
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
||||||
|
* @param count Amount to remove from the owner count
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
decreaseOwnerCount(std::optional<AccountRootEntry<ApplyView>>& sponsorSle, std::uint32_t count)
|
||||||
|
requires Base::kIsWritable;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void
|
||||||
|
adjustOwnerCountSigned(
|
||||||
|
std::optional<AccountRootEntry<ApplyView>>& sponsorSle,
|
||||||
|
std::int32_t adjustment)
|
||||||
|
requires Base::kIsWritable;
|
||||||
};
|
};
|
||||||
|
|
||||||
using AccountRootEntryR = AccountRootEntry<ReadView>;
|
using AccountRootEntryR = AccountRootEntry<ReadView>;
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <xrpl/basics/base_uint.h>
|
|
||||||
#include <xrpl/basics/chrono.h>
|
|
||||||
#include <xrpl/beast/utility/Journal.h>
|
#include <xrpl/beast/utility/Journal.h>
|
||||||
#include <xrpl/ledger/ApplyView.h>
|
#include <xrpl/ledger/ApplyView.h>
|
||||||
#include <xrpl/ledger/ReadView.h>
|
#include <xrpl/ledger/ReadView.h>
|
||||||
#include <xrpl/ledger/entries/SLEBase.h>
|
#include <xrpl/ledger/entries/SLEBase.h>
|
||||||
#include <xrpl/protocol/Indexes.h>
|
#include <xrpl/protocol/Indexes.h>
|
||||||
#include <xrpl/protocol/LedgerFormats.h>
|
#include <xrpl/protocol/LedgerFormats.h>
|
||||||
#include <xrpl/protocol/SField.h>
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
namespace xrpl {
|
namespace xrpl {
|
||||||
|
|
||||||
@@ -31,52 +25,6 @@ public:
|
|||||||
: Base(keylet::amendments(), view, j)
|
: Base(keylet::amendments(), view, j)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the set of amendments this entry reports as enabled.
|
|
||||||
*
|
|
||||||
* @return the set of enabled amendments.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] std::set<UInt256>
|
|
||||||
enabledAmendments() const
|
|
||||||
{
|
|
||||||
std::set<UInt256> amendments;
|
|
||||||
|
|
||||||
if (this->exists() && (*this)->isFieldPresent(sfAmendments))
|
|
||||||
{
|
|
||||||
auto const& v = (*this)->getFieldV256(sfAmendments);
|
|
||||||
amendments.insert_range(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
return amendments;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a map of amendments that have achieved majority, to the time
|
|
||||||
* majority was reached.
|
|
||||||
*
|
|
||||||
* @return a map of amendment to the time majority was reached.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] std::map<UInt256, NetClock::time_point>
|
|
||||||
majorityAmendments() const
|
|
||||||
{
|
|
||||||
std::map<UInt256, NetClock::time_point> ret;
|
|
||||||
|
|
||||||
if (this->exists() && (*this)->isFieldPresent(sfMajorities))
|
|
||||||
{
|
|
||||||
using TimePoint = NetClock::time_point;
|
|
||||||
using Duration = TimePoint::duration;
|
|
||||||
|
|
||||||
auto const majorities = (*this)->getFieldArray(sfMajorities);
|
|
||||||
|
|
||||||
for (auto const& m : majorities)
|
|
||||||
{
|
|
||||||
ret[m.getFieldH256(sfAmendment)] = TimePoint(Duration(m.getFieldU32(sfCloseTime)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using AmendmentsEntryR = AmendmentsEntry<ReadView>;
|
using AmendmentsEntryR = AmendmentsEntry<ReadView>;
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <xrpl/basics/base_uint.h>
|
|
||||||
#include <xrpl/beast/utility/Journal.h>
|
#include <xrpl/beast/utility/Journal.h>
|
||||||
#include <xrpl/ledger/ApplyView.h>
|
#include <xrpl/ledger/ApplyView.h>
|
||||||
#include <xrpl/ledger/ReadView.h>
|
#include <xrpl/ledger/ReadView.h>
|
||||||
#include <xrpl/ledger/entries/SLEBase.h>
|
#include <xrpl/ledger/entries/SLEBase.h>
|
||||||
#include <xrpl/protocol/Indexes.h>
|
#include <xrpl/protocol/Indexes.h>
|
||||||
#include <xrpl/protocol/LedgerFormats.h>
|
#include <xrpl/protocol/LedgerFormats.h>
|
||||||
#include <xrpl/protocol/SField.h>
|
|
||||||
#include <xrpl/protocol/STVector256.h>
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
namespace xrpl {
|
namespace xrpl {
|
||||||
|
|
||||||
@@ -31,31 +25,6 @@ public:
|
|||||||
: Base(keylet::skip(), view, j)
|
: Base(keylet::skip(), view, j)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks up a hash `diff` slots back from the most recent entry in the
|
|
||||||
* sfHashes vector (diff == 0 is the most recent entry).
|
|
||||||
*
|
|
||||||
* Callers decide which skip list entry to read and how to translate a
|
|
||||||
* target ledger sequence into `diff`; this only does the bounds check
|
|
||||||
* and vector indexing shared by both the recent (stride 1) and distant
|
|
||||||
* (stride 256) skip lists.
|
|
||||||
*
|
|
||||||
* @param diff how many slots back from the most recent hash to look up;
|
|
||||||
* 0 is the most recent hash.
|
|
||||||
* @return the hash at that slot, or std::nullopt if the entry does not
|
|
||||||
* exist or `diff` is out of range.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] std::optional<UInt256>
|
|
||||||
hashAt(std::size_t diff) const
|
|
||||||
{
|
|
||||||
if (!this->exists())
|
|
||||||
return std::nullopt;
|
|
||||||
STVector256 const vec = (*this)->getFieldV256(sfHashes);
|
|
||||||
if (vec.size() > diff)
|
|
||||||
return vec[vec.size() - diff - 1];
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using LedgerHashesEntryR = LedgerHashesEntry<ReadView>;
|
using LedgerHashesEntryR = LedgerHashesEntry<ReadView>;
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ getAMMOfferStartWithTakerGets(
|
|||||||
if (nTakerGetsConstraint < *nTakerGets)
|
if (nTakerGetsConstraint < *nTakerGets)
|
||||||
nTakerGets = nTakerGetsConstraint;
|
nTakerGets = nTakerGetsConstraint;
|
||||||
|
|
||||||
auto const getAmounts = [&pool, &tfee](Number const& nTakerGetsProposed) {
|
auto getAmounts = [&pool, &tfee](Number const& nTakerGetsProposed) {
|
||||||
// Round downward to minimize the offer and to maximize the quality.
|
// Round downward to minimize the offer and to maximize the quality.
|
||||||
// This has the most impact when takerGets is integral.
|
// This has the most impact when takerGets is integral.
|
||||||
auto const takerGets =
|
auto const takerGets =
|
||||||
@@ -292,7 +292,7 @@ getAMMOfferStartWithTakerPays(
|
|||||||
if (nTakerPaysConstraint < *nTakerPays)
|
if (nTakerPaysConstraint < *nTakerPays)
|
||||||
nTakerPays = nTakerPaysConstraint;
|
nTakerPays = nTakerPaysConstraint;
|
||||||
|
|
||||||
auto const getAmounts = [&pool, &tfee](Number const& nTakerPaysProposed) {
|
auto getAmounts = [&pool, &tfee](Number const& nTakerPaysProposed) {
|
||||||
// Round downward to minimize the offer and to maximize the quality.
|
// Round downward to minimize the offer and to maximize the quality.
|
||||||
// This has the most impact when takerPays is integral.
|
// This has the most impact when takerPays is integral.
|
||||||
auto const takerPays =
|
auto const takerPays =
|
||||||
@@ -353,7 +353,7 @@ changeSpotPriceQuality(
|
|||||||
}
|
}
|
||||||
if (auto const nTakerPaysPropose = (-b + root2(res)) / (2 * a); nTakerPaysPropose > 0)
|
if (auto const nTakerPaysPropose = (-b + root2(res)) / (2 * a); nTakerPaysPropose > 0)
|
||||||
{
|
{
|
||||||
auto const nTakerPays = [&] {
|
auto const nTakerPays = [&]() {
|
||||||
// The fee might make the AMM offer quality less than CLOB
|
// The fee might make the AMM offer quality less than CLOB
|
||||||
// quality. Therefore, AMM offer has to satisfy this constraint:
|
// quality. Therefore, AMM offer has to satisfy this constraint:
|
||||||
// o / i >= q. Substituting o with swapAssetIn() gives: i <= O /
|
// o / i >= q. Substituting o with swapAssetIn() gives: i <= O /
|
||||||
@@ -372,8 +372,8 @@ changeSpotPriceQuality(
|
|||||||
auto const takerPays =
|
auto const takerPays =
|
||||||
toAmount<TIn>(getAsset(pool.in), nTakerPays, Number::RoundingMode::Upward);
|
toAmount<TIn>(getAsset(pool.in), nTakerPays, Number::RoundingMode::Upward);
|
||||||
// should not fail
|
// should not fail
|
||||||
auto amounts = TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
|
if (auto amounts = TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
|
||||||
if (Quality{amounts} < quality &&
|
Quality{amounts} < quality &&
|
||||||
!withinRelativeDistance(Quality{amounts}, quality, Number(1, -7)))
|
!withinRelativeDistance(Quality{amounts}, quality, Number(1, -7)))
|
||||||
{
|
{
|
||||||
JLOG(j.error()) << "changeSpotPriceQuality failed: " << to_string(pool.in) << " "
|
JLOG(j.error()) << "changeSpotPriceQuality failed: " << to_string(pool.in) << " "
|
||||||
@@ -382,19 +382,21 @@ changeSpotPriceQuality(
|
|||||||
<< " " << to_string(amounts.out);
|
<< " " << to_string(amounts.out);
|
||||||
Throw<std::runtime_error>("changeSpotPriceQuality failed");
|
Throw<std::runtime_error>("changeSpotPriceQuality failed");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
JLOG(j.trace()) << "changeSpotPriceQuality succeeded: " << to_string(pool.in) << " "
|
{
|
||||||
<< to_string(pool.out) << " "
|
JLOG(j.trace()) << "changeSpotPriceQuality succeeded: " << to_string(pool.in) << " "
|
||||||
<< " " << quality << " " << tfee << " " << to_string(amounts.in) << " "
|
<< to_string(pool.out) << " "
|
||||||
<< to_string(amounts.out);
|
<< " " << quality << " " << tfee << " " << to_string(amounts.in)
|
||||||
return amounts;
|
<< " " << to_string(amounts.out);
|
||||||
|
return amounts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
JLOG(j.trace()) << "changeSpotPriceQuality calc failed: " << to_string(pool.in) << " "
|
JLOG(j.trace()) << "changeSpotPriceQuality calc failed: " << to_string(pool.in) << " "
|
||||||
<< to_string(pool.out) << " " << quality << " " << tfee;
|
<< to_string(pool.out) << " " << quality << " " << tfee;
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto amounts = [&] {
|
auto amounts = [&]() {
|
||||||
bool const inIntegral = getAsset(pool.in).integral();
|
bool const inIntegral = getAsset(pool.in).integral();
|
||||||
bool const outIntegral = getAsset(pool.out).integral();
|
bool const outIntegral = getAsset(pool.out).integral();
|
||||||
|
|
||||||
@@ -870,8 +872,8 @@ deleteAMMAccount(Sandbox& view, Asset const& asset, Asset const& asset2, beast::
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
initializeFeeAuctionVote(
|
initializeFeeAuctionVote(
|
||||||
ApplyView const& view,
|
ApplyView& view,
|
||||||
SLE::pointer const& ammSle,
|
SLE::pointer& ammSle,
|
||||||
AccountID const& account,
|
AccountID const& account,
|
||||||
Asset const& lptAsset,
|
Asset const& lptAsset,
|
||||||
std::uint16_t tfee);
|
std::uint16_t tfee);
|
||||||
@@ -893,7 +895,7 @@ std::expected<bool, TER>
|
|||||||
verifyAndAdjustLPTokenBalance(
|
verifyAndAdjustLPTokenBalance(
|
||||||
Sandbox& sb,
|
Sandbox& sb,
|
||||||
STAmount const& lpTokens,
|
STAmount const& lpTokens,
|
||||||
SLE::pointer const& ammSle,
|
SLE::pointer& ammSle,
|
||||||
AccountID const& account);
|
AccountID const& account);
|
||||||
|
|
||||||
} // namespace xrpl
|
} // namespace xrpl
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
#include <xrpl/beast/utility/Journal.h>
|
#include <xrpl/beast/utility/Journal.h>
|
||||||
#include <xrpl/ledger/ApplyView.h>
|
#include <xrpl/ledger/ApplyView.h>
|
||||||
#include <xrpl/ledger/ReadView.h>
|
#include <xrpl/ledger/ReadView.h>
|
||||||
|
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||||
#include <xrpl/protocol/AccountID.h>
|
#include <xrpl/protocol/AccountID.h>
|
||||||
#include <xrpl/protocol/Indexes.h>
|
|
||||||
#include <xrpl/protocol/Rate.h>
|
#include <xrpl/protocol/Rate.h>
|
||||||
#include <xrpl/protocol/SField.h>
|
#include <xrpl/protocol/SField.h>
|
||||||
#include <xrpl/protocol/STLedgerEntry.h>
|
#include <xrpl/protocol/STLedgerEntry.h>
|
||||||
@@ -46,30 +46,55 @@ isGlobalFrozen(ReadView const& view, AccountID const& issuer);
|
|||||||
[[nodiscard]] XRPAmount
|
[[nodiscard]] XRPAmount
|
||||||
xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j);
|
xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j);
|
||||||
|
|
||||||
struct Adjustment
|
namespace detail {
|
||||||
{
|
|
||||||
std::int32_t ownerCountDelta = 0;
|
|
||||||
std::int32_t accountCountDelta = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the account reserve, in drops.
|
* An owner count cannot be negative. If adjustment would cause a negative
|
||||||
|
* owner count, clamp the owner count at 0. Similarly for overflow. This
|
||||||
|
* adjustment allows the ownerCount to be adjusted up or down in multiple steps.
|
||||||
|
* If id != std::nullopt, then do error reporting.
|
||||||
*
|
*
|
||||||
* Actual owner count can be adjusted by delta in ownerCountAdj
|
* Shared by AccountRootEntry::ownerCount() and the owner-count helpers.
|
||||||
* Actual reserve count can be adjusted by delta in accountCountAdj
|
|
||||||
* The reserve is calculated as:
|
|
||||||
* (ownerCount + "sponsoring object count" - "sponsored object count" + additionalOwnerCount) *
|
|
||||||
* increment + (1 if not sponsored account + sponsoringAccountCount) * "reserve base"
|
|
||||||
*
|
*
|
||||||
* @param view The ledger view to read from
|
* @param currentOwnerCount The owner count before adjustment
|
||||||
* @param sle The ledger entry for the account
|
* @param ownerCountAdj Positive to add to count, negative to reduce count
|
||||||
|
* @param id The account ID to use for error reporting, or std::nullopt to
|
||||||
|
* skip error reporting
|
||||||
* @param j Journal for logging
|
* @param j Journal for logging
|
||||||
* @param adj Adjustment to the owner/account count (default: 0/0). Positive to add, negative to
|
* @return The adjusted owner count
|
||||||
* subtract.
|
|
||||||
* @return The account reserve amount in drops
|
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] XRPAmount
|
std::uint32_t
|
||||||
accountReserve(ReadView const& view, SLE::ConstRef sle, beast::Journal j, Adjustment adj = {});
|
confineOwnerCount(
|
||||||
|
std::uint32_t currentOwnerCount,
|
||||||
|
std::int32_t ownerCountAdj,
|
||||||
|
std::optional<AccountID> const& id = std::nullopt,
|
||||||
|
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamps and writes an owner-count field of sle, then updates sle in view.
|
||||||
|
*
|
||||||
|
* Shared by AccountRootEntry and adjustLoanBrokerOwnerCount().
|
||||||
|
*
|
||||||
|
* @return The adjusted owner count
|
||||||
|
*/
|
||||||
|
std::uint32_t
|
||||||
|
adjustOwnerCountImpl(
|
||||||
|
ApplyView& view,
|
||||||
|
SLE::Ref sle,
|
||||||
|
SF_UINT32 const& sfield,
|
||||||
|
AccountID const& accID,
|
||||||
|
std::int32_t ownerCountAdj,
|
||||||
|
beast::Journal j);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of account reserves funded by this account: 1 for itself
|
||||||
|
* (0 if sponsored by another account) plus the count of accounts it sponsors.
|
||||||
|
* Shared by AccountRootEntry::reserve() and xrpLiquid().
|
||||||
|
*/
|
||||||
|
std::uint32_t
|
||||||
|
accountCountImpl(AccountRootEntryR const& sle, std::int32_t accountCountAdj, beast::Journal j);
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience overload that accepts AccountID instead of SLE.
|
* Convenience overload that accepts AccountID instead of SLE.
|
||||||
@@ -84,114 +109,9 @@ accountReserve(ReadView const& view, SLE::ConstRef sle, beast::Journal j, Adjust
|
|||||||
[[nodiscard]] inline XRPAmount
|
[[nodiscard]] inline XRPAmount
|
||||||
accountReserve(ReadView const& view, AccountID const& id, beast::Journal j, Adjustment adj = {})
|
accountReserve(ReadView const& view, AccountID const& id, beast::Journal j, Adjustment adj = {})
|
||||||
{
|
{
|
||||||
return accountReserve(view, view.read(keylet::account(id)), j, adj);
|
return AccountRootEntryR(id, view, j).reserve(adj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if an account has sufficient reserve.
|
|
||||||
*
|
|
||||||
* @param view The ledger view to read from
|
|
||||||
* @param tx The transaction being processed
|
|
||||||
* @param accSle The account's ledger entry
|
|
||||||
* @param accBalance The account's balance
|
|
||||||
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
|
||||||
* @param adj Adjustment to the owner/account count (default: 0/0). Positive to add, negative to
|
|
||||||
* subtract.
|
|
||||||
* @param j Journal for logging (default: null sink)
|
|
||||||
* @param insufReserveCode The transaction result code to return if the reserve is insufficient
|
|
||||||
* (default: tecINSUFFICIENT_RESERVE).
|
|
||||||
* @return Transaction result code
|
|
||||||
*/
|
|
||||||
[[nodiscard]] TER
|
|
||||||
checkReserve(
|
|
||||||
ApplyViewContext ctx,
|
|
||||||
SLE::ConstRef accSle,
|
|
||||||
XRPAmount accBalance,
|
|
||||||
SLE::ConstRef sponsorSle,
|
|
||||||
Adjustment adj,
|
|
||||||
beast::Journal j,
|
|
||||||
TER insufReserveCode = tecINSUFFICIENT_RESERVE);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if an account has sufficient reserve, deriving the sponsor internally.
|
|
||||||
*
|
|
||||||
* Equivalent to the overload above, but resolves the sponsor via
|
|
||||||
* getEffectiveTxReserveSponsor(ctx, accSle) instead of taking it explicitly. Use this
|
|
||||||
* in the common case where the sponsor is simply the transaction's reserve
|
|
||||||
* sponsor for accSle. Callers that must force the account's-own-reserve branch
|
|
||||||
* (passing a null sponsor) or supply a different sponsor should use the
|
|
||||||
* explicit overload above.
|
|
||||||
*
|
|
||||||
* @param ctx The apply-view context (view + tx)
|
|
||||||
* @param accSle The account's ledger entry
|
|
||||||
* @param accBalance The account's balance
|
|
||||||
* @param adj Reserve adjustments (owner/account count deltas)
|
|
||||||
* @param j Journal for logging (default: null sink)
|
|
||||||
* @return Transaction result code
|
|
||||||
*/
|
|
||||||
[[nodiscard]] TER
|
|
||||||
checkReserve(
|
|
||||||
ApplyViewContext ctx,
|
|
||||||
SLE::ConstRef accSle,
|
|
||||||
XRPAmount accBalance,
|
|
||||||
Adjustment adj,
|
|
||||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return number of the objects which reserve is covered by the account(sle) (so called "owner
|
|
||||||
* count"). Actual owner count can be adjusted by delta in ownerCountAdj.
|
|
||||||
*
|
|
||||||
* @param sle The account's ledger entry
|
|
||||||
* @param j Journal for logging
|
|
||||||
* @param ownerCountAdj Adjustment to the owner count (default: 0)
|
|
||||||
* @return The adjusted owner count
|
|
||||||
*/
|
|
||||||
std::uint32_t
|
|
||||||
ownerCount(SLE::ConstRef sle, beast::Journal j, std::int32_t ownerCountAdj = 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Increase owner-count fields when the caller supplies the sponsor.
|
|
||||||
*
|
|
||||||
* This helper does not create a ledger object. It updates reserve accounting
|
|
||||||
* after the caller has created/updated an object.
|
|
||||||
* If sponsorSle is provided, this also adjusts the account's sponsored count
|
|
||||||
* and the sponsor's sponsoring count.
|
|
||||||
*
|
|
||||||
* @param view The apply view for making changes
|
|
||||||
* @param accountSle The account's ledger entry
|
|
||||||
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
|
||||||
* @param count Amount to add to the owner count
|
|
||||||
* @param j Journal for logging
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
increaseOwnerCount(
|
|
||||||
ApplyView& view,
|
|
||||||
SLE::Ref accountSle,
|
|
||||||
SLE::Ref sponsorSle,
|
|
||||||
std::uint32_t count,
|
|
||||||
beast::Journal j);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Increase owner-count fields, deriving the tx reserve sponsor internally.
|
|
||||||
*
|
|
||||||
* Equivalent to the overload above, but resolves the sponsor via
|
|
||||||
* getEffectiveTxReserveSponsor(ctx, accountSle) instead of taking it explicitly. Use
|
|
||||||
* this when the sponsor is the transaction's reserve sponsor for accountSle
|
|
||||||
* (the common create path). Deletion paths, which derive the sponsor from an
|
|
||||||
* object's sfSponsor field, should keep using the explicit overload.
|
|
||||||
*
|
|
||||||
* @param ctx The apply-view context (view + tx)
|
|
||||||
* @param accountSle The account's ledger entry
|
|
||||||
* @param count Amount to add to the owner count
|
|
||||||
* @param j Journal for logging
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
increaseOwnerCount(
|
|
||||||
ApplyViewContext ctx,
|
|
||||||
SLE::Ref accountSle,
|
|
||||||
std::uint32_t count,
|
|
||||||
beast::Journal j);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience overload that accepts AccountID instead of SLE references.
|
* Convenience overload that accepts AccountID instead of SLE references.
|
||||||
*
|
*
|
||||||
@@ -209,36 +129,13 @@ increaseOwnerCount(
|
|||||||
std::uint32_t count,
|
std::uint32_t count,
|
||||||
beast::Journal j)
|
beast::Journal j)
|
||||||
{
|
{
|
||||||
increaseOwnerCount(
|
AccountRootEntryW accountSle(account, view, j);
|
||||||
view,
|
std::optional<AccountRootEntryW> sponsorSle;
|
||||||
view.peek(keylet::account(account)),
|
if (sponsor)
|
||||||
sponsor ? view.peek(keylet::account(*sponsor)) : SLE::pointer(),
|
sponsorSle.emplace(*sponsor, view);
|
||||||
count,
|
accountSle.increaseOwnerCount(sponsorSle, count);
|
||||||
j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrease owner-count fields when the caller supplies the sponsor.
|
|
||||||
*
|
|
||||||
* This helper does not delete a ledger object. It updates reserve accounting
|
|
||||||
* after the caller has removed an owner-counted reserve, or for special
|
|
||||||
* owner-count changes whose sponsor cannot be derived from an object's
|
|
||||||
* sfSponsor field.
|
|
||||||
*
|
|
||||||
* @param view The apply view for making changes
|
|
||||||
* @param accountSle The account's ledger entry
|
|
||||||
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
|
||||||
* @param count Amount to remove from the owner count
|
|
||||||
* @param j Journal for logging
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
decreaseOwnerCount(
|
|
||||||
ApplyView& view,
|
|
||||||
SLE::Ref accountSle,
|
|
||||||
SLE::Ref sponsorSle,
|
|
||||||
std::uint32_t count,
|
|
||||||
beast::Journal j);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience overload that accepts AccountID instead of SLE references.
|
* Convenience overload that accepts AccountID instead of SLE references.
|
||||||
*
|
*
|
||||||
@@ -256,12 +153,11 @@ decreaseOwnerCount(
|
|||||||
std::uint32_t count,
|
std::uint32_t count,
|
||||||
beast::Journal j)
|
beast::Journal j)
|
||||||
{
|
{
|
||||||
decreaseOwnerCount(
|
AccountRootEntryW accountSle(account, view, j);
|
||||||
view,
|
std::optional<AccountRootEntryW> sponsorSle;
|
||||||
view.peek(keylet::account(account)),
|
if (sponsor)
|
||||||
sponsor ? view.peek(keylet::account(*sponsor)) : SLE::pointer(),
|
sponsorSle.emplace(*sponsor, view);
|
||||||
count,
|
accountSle.decreaseOwnerCount(sponsorSle, count);
|
||||||
j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -281,7 +177,7 @@ decreaseOwnerCount(
|
|||||||
void
|
void
|
||||||
decreaseOwnerCountForObject(
|
decreaseOwnerCountForObject(
|
||||||
ApplyView& view,
|
ApplyView& view,
|
||||||
SLE::Ref accountSle,
|
AccountRootEntryW& accountSle,
|
||||||
SLE::Ref objectSle,
|
SLE::Ref objectSle,
|
||||||
std::uint32_t count,
|
std::uint32_t count,
|
||||||
beast::Journal j);
|
beast::Journal j);
|
||||||
@@ -303,7 +199,7 @@ decreaseOwnerCountForObject(
|
|||||||
std::uint32_t count,
|
std::uint32_t count,
|
||||||
beast::Journal j)
|
beast::Journal j)
|
||||||
{
|
{
|
||||||
SLE::Ref accountSle = view.peek(keylet::account(account));
|
AccountRootEntryW accountSle(account, view);
|
||||||
decreaseOwnerCountForObject(view, accountSle, objectSle, count, j);
|
decreaseOwnerCountForObject(view, accountSle, objectSle, count, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,7 +263,7 @@ getPseudoAccountFields();
|
|||||||
* - null pointer
|
* - null pointer
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool
|
[[nodiscard]] bool
|
||||||
isPseudoAccount(SLE::const_pointer sleAcct);
|
isPseudoAccount(AccountRootEntryR const& sleAcct);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience overload that reads the account from the view.
|
* Convenience overload that reads the account from the view.
|
||||||
@@ -375,7 +271,7 @@ isPseudoAccount(SLE::const_pointer sleAcct);
|
|||||||
[[nodiscard]] inline bool
|
[[nodiscard]] inline bool
|
||||||
isPseudoAccount(ReadView const& view, AccountID const& accountId)
|
isPseudoAccount(ReadView const& view, AccountID const& accountId)
|
||||||
{
|
{
|
||||||
return isPseudoAccount(view.read(keylet::account(accountId)));
|
return isPseudoAccount(AccountRootEntryR(accountId, view));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -396,6 +292,6 @@ createPseudoAccount(ApplyView& view, UInt256 const& pseudoOwnerKey, SField const
|
|||||||
* - If the SLE requires a destination tag, checks that there is a tag.
|
* - If the SLE requires a destination tag, checks that there is a tag.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] TER
|
[[nodiscard]] TER
|
||||||
checkDestinationAndTag(SLE::ConstRef toSle, bool hasDestinationTag);
|
checkDestinationAndTag(AccountRootEntryR const& toSle, bool hasDestinationTag);
|
||||||
|
|
||||||
} // namespace xrpl
|
} // namespace xrpl
|
||||||
@@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
#include <xrpl/basics/Log.h>
|
#include <xrpl/basics/Log.h>
|
||||||
#include <xrpl/beast/utility/Journal.h>
|
#include <xrpl/beast/utility/Journal.h>
|
||||||
#include <xrpl/beast/utility/Zero.h>
|
|
||||||
#include <xrpl/beast/utility/instrumentation.h>
|
#include <xrpl/beast/utility/instrumentation.h>
|
||||||
#include <xrpl/ledger/ApplyView.h>
|
#include <xrpl/ledger/ApplyView.h>
|
||||||
#include <xrpl/ledger/ReadView.h>
|
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
|
||||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||||
@@ -29,290 +27,31 @@
|
|||||||
|
|
||||||
namespace xrpl {
|
namespace xrpl {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate that @p account may lock @p amount of a token for later delivery
|
* Before fixCleanup3_2_0, EscrowCancel passes the escrow SLE as sleDest.
|
||||||
* to @p dest.
|
* Return what the old reserve check returned for it, without adopting a
|
||||||
|
* non-AccountRoot SLE into an AccountRootEntry: the tx reserve sponsor's
|
||||||
|
* error if the escrow owner submitted the tx, else tefINTERNAL.
|
||||||
*
|
*
|
||||||
* The lock-side counterpart of escrowUnlockPreclaimHelper: every issuer
|
* @param ctx the apply view context for the escrow transaction.
|
||||||
* control (locking opt-in, authorization, freeze/lock, transferability,
|
* @param sleDest the non-AccountRoot SLE that was passed as the destination.
|
||||||
* spendable balance) that gates locking token value lives here, so any
|
* @return the tx reserve sponsor's error code if the escrow owner submitted
|
||||||
* transactor that locks funds applies the same rules. The signature is
|
* the tx, else tefINTERNAL.
|
||||||
* view-based rather than PreclaimContext-based so it can also run from
|
|
||||||
* doApply.
|
|
||||||
*/
|
*/
|
||||||
template <ValidIssueType T>
|
|
||||||
TER
|
|
||||||
escrowLockPreclaimHelper(
|
|
||||||
ReadView const& view,
|
|
||||||
AccountID const& account,
|
|
||||||
AccountID const& dest,
|
|
||||||
STAmount const& amount,
|
|
||||||
beast::Journal j);
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline TER
|
inline TER
|
||||||
escrowLockPreclaimHelper<Issue>(
|
escrowDestNotAccountResult(ApplyViewContext ctx, SLE::ConstRef sleDest)
|
||||||
ReadView const& view,
|
|
||||||
AccountID const& account,
|
|
||||||
AccountID const& dest,
|
|
||||||
STAmount const& amount,
|
|
||||||
beast::Journal j)
|
|
||||||
{
|
{
|
||||||
auto const& issue = amount.get<Issue>();
|
if (sleDest->getAccountID(sfAccount) == ctx.tx[sfAccount])
|
||||||
auto const& issuer = amount.getIssuer();
|
{
|
||||||
// If the issuer is the same as the account, return tecNO_PERMISSION
|
if (auto const sponsor = getTxReserveSponsor(ctx); !sponsor)
|
||||||
if (issuer == account)
|
return sponsor.error(); // LCOV_EXCL_LINE
|
||||||
return tecNO_PERMISSION;
|
}
|
||||||
|
return tefINTERNAL;
|
||||||
// If the lsfAllowTrustLineLocking is not enabled, return tecNO_PERMISSION
|
|
||||||
auto const sleIssuer = view.read(keylet::account(issuer));
|
|
||||||
if (!sleIssuer)
|
|
||||||
return tecNO_ISSUER;
|
|
||||||
if (!sleIssuer->isFlag(lsfAllowTrustLineLocking))
|
|
||||||
return tecNO_PERMISSION;
|
|
||||||
|
|
||||||
// If the account does not have a trustline to the issuer, return tecNO_LINE
|
|
||||||
auto const sleRippleState = view.read(keylet::trustLine(account, issuer, issue.currency));
|
|
||||||
if (!sleRippleState)
|
|
||||||
return tecNO_LINE;
|
|
||||||
|
|
||||||
STAmount const balance = (*sleRippleState)[sfBalance];
|
|
||||||
|
|
||||||
// If balance is positive, issuer must have higher address than account
|
|
||||||
if (balance > beast::kZero && issuer < account)
|
|
||||||
return tecNO_PERMISSION; // LCOV_EXCL_LINE
|
|
||||||
|
|
||||||
// If balance is negative, issuer must have lower address than account
|
|
||||||
if (balance < beast::kZero && issuer > account)
|
|
||||||
return tecNO_PERMISSION; // LCOV_EXCL_LINE
|
|
||||||
|
|
||||||
// If the issuer has requireAuth set, check if the account is authorized
|
|
||||||
if (auto const ter = requireAuth(view, issue, account); !isTesSuccess(ter))
|
|
||||||
return ter;
|
|
||||||
|
|
||||||
// If the issuer has requireAuth set, check if the destination is authorized
|
|
||||||
if (auto const ter = requireAuth(view, issue, dest); !isTesSuccess(ter))
|
|
||||||
return ter;
|
|
||||||
|
|
||||||
// If the issuer has frozen the account, return tecFROZEN
|
|
||||||
if (isFrozen(view, account, issue))
|
|
||||||
return tecFROZEN;
|
|
||||||
|
|
||||||
// If the issuer has frozen the destination, return tecFROZEN
|
|
||||||
if (isFrozen(view, dest, issue))
|
|
||||||
return tecFROZEN;
|
|
||||||
|
|
||||||
STAmount const spendableAmount =
|
|
||||||
accountHolds(view, account, issue.currency, issuer, FreezeHandling::IgnoreFreeze, j);
|
|
||||||
|
|
||||||
// If the balance is less than or equal to 0, return tecINSUFFICIENT_FUNDS
|
|
||||||
if (spendableAmount <= beast::kZero)
|
|
||||||
return tecINSUFFICIENT_FUNDS;
|
|
||||||
|
|
||||||
// If the spendable amount is less than the amount, return
|
|
||||||
// tecINSUFFICIENT_FUNDS
|
|
||||||
if (spendableAmount < amount)
|
|
||||||
return tecINSUFFICIENT_FUNDS;
|
|
||||||
|
|
||||||
// If the amount is not addable to the balance, return tecPRECISION_LOSS
|
|
||||||
if (!canAdd(spendableAmount, amount))
|
|
||||||
return tecPRECISION_LOSS;
|
|
||||||
|
|
||||||
return tesSUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
} // namespace detail
|
||||||
inline TER
|
|
||||||
escrowLockPreclaimHelper<MPTIssue>(
|
|
||||||
ReadView const& view,
|
|
||||||
AccountID const& account,
|
|
||||||
AccountID const& dest,
|
|
||||||
STAmount const& amount,
|
|
||||||
beast::Journal j)
|
|
||||||
{
|
|
||||||
AccountID const issuer = amount.getIssuer();
|
|
||||||
// If the issuer is the same as the account, return tecNO_PERMISSION
|
|
||||||
if (issuer == account)
|
|
||||||
return tecNO_PERMISSION;
|
|
||||||
|
|
||||||
// If the mpt does not exist, return tecOBJECT_NOT_FOUND
|
|
||||||
auto const issuanceKey = keylet::mptokenIssuance(amount.get<MPTIssue>().getMptID());
|
|
||||||
auto const sleIssuance = view.read(issuanceKey);
|
|
||||||
if (!sleIssuance)
|
|
||||||
return tecOBJECT_NOT_FOUND;
|
|
||||||
|
|
||||||
// If the lsfMPTCanEscrow is not enabled, return tecNO_PERMISSION
|
|
||||||
if (!sleIssuance->isFlag(lsfMPTCanEscrow))
|
|
||||||
return tecNO_PERMISSION;
|
|
||||||
|
|
||||||
// If the issuer is not the same as the issuer of the mpt, return
|
|
||||||
// tecNO_PERMISSION
|
|
||||||
if (sleIssuance->getAccountID(sfIssuer) != issuer)
|
|
||||||
return tecNO_PERMISSION; // LCOV_EXCL_LINE
|
|
||||||
|
|
||||||
// If the account does not have the mpt, return tecOBJECT_NOT_FOUND
|
|
||||||
if (!view.exists(keylet::mptoken(issuanceKey.key, account)))
|
|
||||||
return tecOBJECT_NOT_FOUND;
|
|
||||||
|
|
||||||
// If the issuer has requireAuth set, check if the account is
|
|
||||||
// authorized
|
|
||||||
auto const& mptIssue = amount.get<MPTIssue>();
|
|
||||||
if (auto const ter = requireAuth(view, mptIssue, account, AuthType::WeakAuth);
|
|
||||||
!isTesSuccess(ter))
|
|
||||||
return ter;
|
|
||||||
|
|
||||||
// If the issuer has requireAuth set, check if the destination is
|
|
||||||
// authorized
|
|
||||||
if (auto const ter = requireAuth(view, mptIssue, dest, AuthType::WeakAuth); !isTesSuccess(ter))
|
|
||||||
return ter;
|
|
||||||
|
|
||||||
// If the issuer has frozen the account, return tecLOCKED
|
|
||||||
if (isFrozen(view, account, *sleIssuance))
|
|
||||||
return tecLOCKED;
|
|
||||||
|
|
||||||
// If the issuer has frozen the destination, return tecLOCKED
|
|
||||||
if (isFrozen(view, dest, *sleIssuance))
|
|
||||||
return tecLOCKED;
|
|
||||||
|
|
||||||
// If the mpt cannot be transferred, return tecNO_AUTH
|
|
||||||
if (auto const ter = canTransfer(view, mptIssue, account, dest); !isTesSuccess(ter))
|
|
||||||
return ter;
|
|
||||||
|
|
||||||
STAmount const spendableAmount = accountHolds(
|
|
||||||
view,
|
|
||||||
account,
|
|
||||||
amount.get<MPTIssue>(),
|
|
||||||
FreezeHandling::IgnoreFreeze,
|
|
||||||
AuthHandling::IgnoreAuth,
|
|
||||||
j);
|
|
||||||
|
|
||||||
// If the balance is less than or equal to 0, return tecINSUFFICIENT_FUNDS
|
|
||||||
if (spendableAmount <= beast::kZero)
|
|
||||||
return tecINSUFFICIENT_FUNDS;
|
|
||||||
|
|
||||||
// If the spendable amount is less than the amount, return
|
|
||||||
// tecINSUFFICIENT_FUNDS
|
|
||||||
if (spendableAmount < amount)
|
|
||||||
return tecINSUFFICIENT_FUNDS;
|
|
||||||
|
|
||||||
return tesSUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <ValidIssueType T>
|
|
||||||
TER
|
|
||||||
escrowLockApplyHelper(
|
|
||||||
ApplyView& view,
|
|
||||||
AccountID const& issuer,
|
|
||||||
AccountID const& sender,
|
|
||||||
STAmount const& amount,
|
|
||||||
beast::Journal journal);
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline TER
|
|
||||||
escrowLockApplyHelper<Issue>(
|
|
||||||
ApplyView& view,
|
|
||||||
AccountID const& issuer,
|
|
||||||
AccountID const& sender,
|
|
||||||
STAmount const& amount,
|
|
||||||
beast::Journal journal)
|
|
||||||
{
|
|
||||||
// Defensive: Issuer cannot create an escrow
|
|
||||||
if (issuer == sender)
|
|
||||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
|
||||||
|
|
||||||
auto const ter =
|
|
||||||
directSendNoFee(view, sender, issuer, amount, !amount.holds<MPTIssue>(), journal);
|
|
||||||
if (!isTesSuccess(ter))
|
|
||||||
return ter; // LCOV_EXCL_LINE
|
|
||||||
return tesSUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline TER
|
|
||||||
escrowLockApplyHelper<MPTIssue>(
|
|
||||||
ApplyView& view,
|
|
||||||
AccountID const& issuer,
|
|
||||||
AccountID const& sender,
|
|
||||||
STAmount const& amount,
|
|
||||||
beast::Journal journal)
|
|
||||||
{
|
|
||||||
// Defensive: Issuer cannot create an escrow
|
|
||||||
if (issuer == sender)
|
|
||||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
|
||||||
|
|
||||||
auto const ter = lockEscrowMPT(view, sender, amount, journal);
|
|
||||||
if (!isTesSuccess(ter))
|
|
||||||
return ter; // LCOV_EXCL_LINE
|
|
||||||
return tesSUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <ValidIssueType T>
|
|
||||||
TER
|
|
||||||
escrowUnlockPreclaimHelper(
|
|
||||||
ReadView const& view,
|
|
||||||
AccountID const& account,
|
|
||||||
STAmount const& amount,
|
|
||||||
bool checkFreeze = true);
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline TER
|
|
||||||
escrowUnlockPreclaimHelper<Issue>(
|
|
||||||
ReadView const& view,
|
|
||||||
AccountID const& account,
|
|
||||||
STAmount const& amount,
|
|
||||||
bool checkFreeze)
|
|
||||||
{
|
|
||||||
AccountID const& issuer = amount.getIssuer();
|
|
||||||
// If the issuer is the same as the account, return tesSUCCESS
|
|
||||||
if (issuer == account)
|
|
||||||
return tesSUCCESS;
|
|
||||||
|
|
||||||
// If the issuer has requireAuth set, check if the destination is authorized
|
|
||||||
if (auto const ter = requireAuth(view, amount.get<Issue>(), account); !isTesSuccess(ter))
|
|
||||||
return ter;
|
|
||||||
|
|
||||||
// If the issuer has deep frozen the destination, return tecFROZEN
|
|
||||||
if (checkFreeze &&
|
|
||||||
isDeepFrozen(view, account, amount.get<Issue>().currency, amount.getIssuer()))
|
|
||||||
return tecFROZEN;
|
|
||||||
|
|
||||||
return tesSUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline TER
|
|
||||||
escrowUnlockPreclaimHelper<MPTIssue>(
|
|
||||||
ReadView const& view,
|
|
||||||
AccountID const& account,
|
|
||||||
STAmount const& amount,
|
|
||||||
bool checkFreeze)
|
|
||||||
{
|
|
||||||
AccountID const& issuer = amount.getIssuer();
|
|
||||||
// If the issuer is the same as the account, return tesSUCCESS
|
|
||||||
if (issuer == account)
|
|
||||||
return tesSUCCESS;
|
|
||||||
|
|
||||||
// If the mpt does not exist, return tecOBJECT_NOT_FOUND
|
|
||||||
auto const issuanceKey = keylet::mptokenIssuance(amount.get<MPTIssue>().getMptID());
|
|
||||||
auto const sleIssuance = view.read(issuanceKey);
|
|
||||||
if (!sleIssuance)
|
|
||||||
return tecOBJECT_NOT_FOUND;
|
|
||||||
|
|
||||||
// If the issuer has requireAuth set, check if the account is
|
|
||||||
// authorized
|
|
||||||
auto const& mptIssue = amount.get<MPTIssue>();
|
|
||||||
if (auto const ter = requireAuth(view, mptIssue, account, AuthType::WeakAuth);
|
|
||||||
!isTesSuccess(ter))
|
|
||||||
return ter;
|
|
||||||
|
|
||||||
// If the issuer has frozen the account, return tecLOCKED
|
|
||||||
if (checkFreeze && isFrozen(view, account, *sleIssuance))
|
|
||||||
return tecLOCKED;
|
|
||||||
|
|
||||||
return tesSUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <ValidIssueType T>
|
template <ValidIssueType T>
|
||||||
TER
|
TER
|
||||||
@@ -342,6 +81,9 @@ escrowUnlockApplyHelper<Issue>(
|
|||||||
bool createAsset,
|
bool createAsset,
|
||||||
beast::Journal journal)
|
beast::Journal journal)
|
||||||
{
|
{
|
||||||
|
auto const& issue = amount.get<Issue>();
|
||||||
|
Keylet const trustLineKey = keylet::trustLine(receiver, issue);
|
||||||
|
bool const recvLow = issuer > receiver;
|
||||||
bool const senderIssuer = issuer == sender;
|
bool const senderIssuer = issuer == sender;
|
||||||
bool const receiverIssuer = issuer == receiver;
|
bool const receiverIssuer = issuer == receiver;
|
||||||
|
|
||||||
@@ -351,25 +93,20 @@ escrowUnlockApplyHelper<Issue>(
|
|||||||
if (receiverIssuer)
|
if (receiverIssuer)
|
||||||
return tesSUCCESS;
|
return tesSUCCESS;
|
||||||
|
|
||||||
auto const& issue = amount.get<Issue>();
|
|
||||||
Keylet const trustLineKey = keylet::trustLine(receiver, issue);
|
|
||||||
bool const recvLow = issuer > receiver;
|
|
||||||
|
|
||||||
if (!ctx.view.exists(trustLineKey) && createAsset)
|
if (!ctx.view.exists(trustLineKey) && createAsset)
|
||||||
{
|
{
|
||||||
// Can the account cover the trust line's reserve?
|
// Can the account cover the trust line's reserve?
|
||||||
auto const sponsorSle = getEffectiveTxReserveSponsor(ctx, sleDest);
|
if (sleDest->getType() != ltACCOUNT_ROOT)
|
||||||
|
return detail::escrowDestNotAccountResult(ctx, sleDest);
|
||||||
|
auto const destSle = AccountRootEntryR(sleDest, ctx.view, journal);
|
||||||
|
auto sponsorSle = getEffectiveTxReserveSponsor(ctx, destSle);
|
||||||
if (!sponsorSle)
|
if (!sponsorSle)
|
||||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||||
|
|
||||||
if (auto const ret = checkReserve(
|
auto& sponsor = *sponsorSle;
|
||||||
ctx,
|
|
||||||
sleDest,
|
if (auto const ret = destSle.checkReserve(
|
||||||
xrpBalance,
|
ctx, xrpBalance, sponsor, {.ownerCountDelta = 1}, tecNO_LINE_INSUF_RESERVE);
|
||||||
*sponsorSle,
|
|
||||||
{.ownerCountDelta = 1},
|
|
||||||
journal,
|
|
||||||
tecNO_LINE_INSUF_RESERVE);
|
|
||||||
!isTesSuccess(ret))
|
!isTesSuccess(ret))
|
||||||
{
|
{
|
||||||
JLOG(journal.trace()) << "Trust line does not exist. "
|
JLOG(journal.trace()) << "Trust line does not exist. "
|
||||||
@@ -382,22 +119,22 @@ escrowUnlockApplyHelper<Issue>(
|
|||||||
initialBalance.get<Issue>().account = noAccount();
|
initialBalance.get<Issue>().account = noAccount();
|
||||||
|
|
||||||
if (TER const ter = trustCreate(
|
if (TER const ter = trustCreate(
|
||||||
ctx.view, // payment sandbox
|
ctx.view, // payment sandbox
|
||||||
recvLow, // is dest low?
|
recvLow, // is dest low?
|
||||||
issuer, // source
|
issuer, // source
|
||||||
receiver, // destination
|
receiver, // destination
|
||||||
trustLineKey.key, // ledger index
|
trustLineKey.key, // ledger index
|
||||||
sleDest, // Account to add to
|
sleDest, // Account to add to
|
||||||
false, // authorize account
|
false, // authorize account
|
||||||
!sleDest->isFlag(lsfDefaultRipple), //
|
!sleDest->isFlag(lsfDefaultRipple), //
|
||||||
false, // freeze trust line
|
false, // freeze trust line
|
||||||
false, // deep freeze trust line
|
false, // deep freeze trust line
|
||||||
initialBalance, // zero initial balance
|
initialBalance, // zero initial balance
|
||||||
Issue(currency, receiver), // limit of zero
|
Issue(currency, receiver), // limit of zero
|
||||||
0, // quality in
|
0, // quality in
|
||||||
0, // quality out
|
0, // quality out
|
||||||
*sponsorSle, // sponsor
|
sponsor ? sponsor->mutableRawSle() : SLE::pointer(), // sponsor
|
||||||
journal); // journal
|
journal); // journal
|
||||||
!isTesSuccess(ter))
|
!isTesSuccess(ter))
|
||||||
{
|
{
|
||||||
return ter; // LCOV_EXCL_LINE
|
return ter; // LCOV_EXCL_LINE
|
||||||
@@ -492,23 +229,29 @@ escrowUnlockApplyHelper<MPTIssue>(
|
|||||||
auto const mptKeylet = keylet::mptoken(issuanceKey.key, receiver);
|
auto const mptKeylet = keylet::mptoken(issuanceKey.key, receiver);
|
||||||
if (!ctx.view.exists(mptKeylet) && createAsset && !receiverIssuer)
|
if (!ctx.view.exists(mptKeylet) && createAsset && !receiverIssuer)
|
||||||
{
|
{
|
||||||
auto const sponsorSle = getEffectiveTxReserveSponsor(ctx, sleDest);
|
if (sleDest->getType() != ltACCOUNT_ROOT)
|
||||||
|
return detail::escrowDestNotAccountResult(ctx, sleDest);
|
||||||
|
auto const destSle = AccountRootEntryR(sleDest, ctx.view, journal);
|
||||||
|
auto sponsorSle = getEffectiveTxReserveSponsor(ctx, destSle);
|
||||||
if (!sponsorSle)
|
if (!sponsorSle)
|
||||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||||
|
|
||||||
if (auto const ret = checkReserve(
|
auto& sponsor = *sponsorSle;
|
||||||
ctx, sleDest, xrpBalance, *sponsorSle, {.ownerCountDelta = 1}, journal);
|
|
||||||
|
if (auto const ret = destSle.checkReserve(ctx, xrpBalance, sponsor, {.ownerCountDelta = 1});
|
||||||
!isTesSuccess(ret))
|
!isTesSuccess(ret))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (auto const ter = createMPToken(ctx.view, mptID, receiver, *sponsorSle, 0);
|
if (auto const ter = createMPToken(
|
||||||
|
ctx.view, mptID, receiver, sponsor ? sponsor->mutableRawSle() : SLE::pointer(), 0);
|
||||||
!isTesSuccess(ter))
|
!isTesSuccess(ter))
|
||||||
{
|
{
|
||||||
return ter; // LCOV_EXCL_LINE
|
return ter; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
|
|
||||||
// update owner count.
|
// update owner count.
|
||||||
increaseOwnerCount(ctx.view, sleDest, *sponsorSle, 1, journal);
|
AccountRootEntryW receiverSle(receiver, ctx.view, journal);
|
||||||
|
receiverSle.increaseOwnerCount(sponsor, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx.view.exists(mptKeylet) && !receiverIssuer)
|
if (!ctx.view.exists(mptKeylet) && !receiverIssuer)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <xrpl/ledger/ApplyView.h>
|
#include <xrpl/ledger/ApplyView.h>
|
||||||
#include <xrpl/ledger/ReadView.h>
|
#include <xrpl/ledger/ReadView.h>
|
||||||
|
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||||
#include <xrpl/protocol/AccountID.h>
|
#include <xrpl/protocol/AccountID.h>
|
||||||
#include <xrpl/protocol/SField.h>
|
#include <xrpl/protocol/SField.h>
|
||||||
#include <xrpl/protocol/STLedgerEntry.h>
|
#include <xrpl/protocol/STLedgerEntry.h>
|
||||||
@@ -54,11 +55,11 @@ getTxReserveSponsorID(STTx const& tx);
|
|||||||
* Return a mutable SLE for the transaction's reserve sponsor account.
|
* Return a mutable SLE for the transaction's reserve sponsor account.
|
||||||
*
|
*
|
||||||
* @param ctx The apply-view context (view + tx)
|
* @param ctx The apply-view context (view + tx)
|
||||||
* @return The sponsor account SLE, a null pointer if the tx is not
|
* @return The sponsor account entry, nullopt if the tx is not
|
||||||
* reserve-sponsored, or tecINTERNAL if the sponsor account cannot
|
* reserve-sponsored, or tecINTERNAL if the sponsor account cannot
|
||||||
* be loaded (an already-checked invariant).
|
* be loaded (an already-checked invariant).
|
||||||
*/
|
*/
|
||||||
std::expected<SLE::pointer, TER>
|
std::expected<std::optional<AccountRootEntryW>, TER>
|
||||||
getTxReserveSponsor(ApplyViewContext ctx);
|
getTxReserveSponsor(ApplyViewContext ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,29 +67,29 @@ getTxReserveSponsor(ApplyViewContext ctx);
|
|||||||
*
|
*
|
||||||
* @param view The ledger read view
|
* @param view The ledger read view
|
||||||
* @param tx The transaction to inspect
|
* @param tx The transaction to inspect
|
||||||
* @return The sponsor account SLE, a null pointer if the tx is not
|
* @return The sponsor account entry, nullopt if the tx is not
|
||||||
* reserve-sponsored, or tecINTERNAL if the sponsor account cannot
|
* reserve-sponsored, or tecINTERNAL if the sponsor account cannot
|
||||||
* be loaded (an already-checked invariant).
|
* be loaded (an already-checked invariant).
|
||||||
*/
|
*/
|
||||||
std::expected<SLE::const_pointer, TER>
|
std::expected<std::optional<AccountRootEntryR>, TER>
|
||||||
getTxReserveSponsor(ReadView const& view, STTx const& tx);
|
getTxReserveSponsor(ReadView const& view, STTx const& tx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The transaction's reserve sponsor for the given account, if applicable.
|
* The transaction's reserve sponsor for the given account, if applicable.
|
||||||
*
|
*
|
||||||
* A reserve sponsor only covers the transaction submitter's own objects, so
|
* A reserve sponsor only covers the transaction submitter's own objects, so
|
||||||
* this returns the tx reserve sponsor SLE only when accountSle is the tx's own
|
* this returns the tx reserve sponsor entry only when accountSle is the tx's
|
||||||
* (non-pseudo) account; otherwise it returns a null sponsor pointer. This is
|
* own (non-pseudo) account; otherwise it returns nullopt. This is
|
||||||
* the single source of truth for the "sponsor applies to tx.Account only" rule
|
* the single source of truth for the "sponsor applies to tx.Account only" rule
|
||||||
* that the sponsor-deriving helper overloads in AccountRootHelpers rely on.
|
* that the sponsor-deriving helper overloads in AccountRootHelpers rely on.
|
||||||
*
|
*
|
||||||
* @param ctx The apply-view context (view + tx)
|
* @param ctx The apply-view context (view + tx)
|
||||||
* @param accountSle The account whose sponsor is being resolved
|
* @param accountSle The account whose sponsor is being resolved
|
||||||
* @return The sponsor SLE (nullptr if unsponsored), or tecINTERNAL if the
|
* @return The sponsor entry (nullopt if unsponsored), or tecINTERNAL if the
|
||||||
* sponsor account cannot be loaded (an already-checked invariant)
|
* sponsor account cannot be loaded (an already-checked invariant)
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] std::expected<SLE::pointer, TER>
|
[[nodiscard]] std::expected<std::optional<AccountRootEntryW>, TER>
|
||||||
getEffectiveTxReserveSponsor(ApplyViewContext ctx, SLE::ConstRef accountSle);
|
getEffectiveTxReserveSponsor(ApplyViewContext ctx, AccountRootEntryR const& accountSle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the AccountID stored in the given sponsor field of a ledger entry, or nullopt if absent.
|
* Return the AccountID stored in the given sponsor field of a ledger entry, or nullopt if absent.
|
||||||
@@ -105,9 +106,9 @@ getLedgerEntryReserveSponsorID(SLE::ConstRef sle, SF_ACCOUNT const& field = sfSp
|
|||||||
* @param view The mutable apply view
|
* @param view The mutable apply view
|
||||||
* @param sle The ledger entry whose sponsor field is inspected
|
* @param sle The ledger entry whose sponsor field is inspected
|
||||||
* @param field The field that holds the sponsor AccountID (defaults to sfSponsor)
|
* @param field The field that holds the sponsor AccountID (defaults to sfSponsor)
|
||||||
* @return The sponsor account SLE, or a null pointer if the entry is unsponsored.
|
* @return The sponsor account entry, or nullopt if the entry is unsponsored.
|
||||||
*/
|
*/
|
||||||
SLE::pointer
|
std::optional<AccountRootEntryW>
|
||||||
getLedgerEntryReserveSponsor(
|
getLedgerEntryReserveSponsor(
|
||||||
ApplyView& view,
|
ApplyView& view,
|
||||||
SLE::ConstRef sle,
|
SLE::ConstRef sle,
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ public:
|
|||||||
void
|
void
|
||||||
asyncHandshake(HandshakeType type, Callback cbFunc)
|
asyncHandshake(HandshakeType type, Callback cbFunc)
|
||||||
{
|
{
|
||||||
if ((type == SslSocket::client) || secure_)
|
if ((type == SslSocket::client) || (secure_))
|
||||||
{
|
{
|
||||||
// must be ssl
|
// must be ssl
|
||||||
secure_ = true;
|
secure_ = true;
|
||||||
|
|||||||
Loaded 100 of 804 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user