mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-27 05:57:09 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1218e75e03 | ||
|
|
1b16b17364 | ||
|
|
a9241a02f0 | ||
|
|
e18621e923 | ||
|
|
e6971b9eab | ||
|
|
4251071ef1 | ||
|
|
6823a9c729 | ||
|
|
dcf03f9d2d | ||
|
|
4a0d2e74a5 | ||
|
|
acbaadbb62 | ||
|
|
cf268a8a61 | ||
|
|
b6531dd532 | ||
|
|
ed9f859059 | ||
|
|
efad8c63b9 | ||
|
|
f4473147b7 | ||
|
|
fabd2070bd | ||
|
|
1f2a0d7991 | ||
|
|
73611f8b20 | ||
|
|
297f255988 | ||
|
|
89c01342c5 | ||
|
|
8f49ff629d | ||
|
|
1f46f75318 | ||
|
|
097cb5e89b | ||
|
|
a818f25203 | ||
|
|
3fa2accfdf | ||
|
|
d3a71b2b42 | ||
|
|
025aa71930 | ||
|
|
ef5064eeb9 | ||
|
|
c2e739f670 | ||
|
|
15fac6250d | ||
|
|
3608433514 | ||
|
|
7939339a65 | ||
|
|
4ea2db2eda | ||
|
|
d4ffe32534 | ||
|
|
7354816f65 | ||
|
|
12cb3932f3 | ||
|
|
dc64a8daac | ||
|
|
dc524e9cc6 | ||
|
|
4060b1bcd4 | ||
|
|
bfbb440fc2 | ||
|
|
4087861411 | ||
|
|
dc43faafed | ||
|
|
6af97c07d9 | ||
|
|
4c7d920e66 | ||
|
|
8b59d9d307 | ||
|
|
b0fa295595 | ||
|
|
9af432cb0e | ||
|
|
4435ca4cbf | ||
|
|
cd72a11786 | ||
|
|
b398b88385 | ||
|
|
31f6f90206 | ||
|
|
1d8c2f9172 | ||
|
|
f105418bdb | ||
|
|
4a134eb883 | ||
|
|
ec3f251ad8 | ||
|
|
5faa861226 | ||
|
|
88fd1222d6 | ||
|
|
f1ce9449f2 | ||
|
|
7237b3321c | ||
|
|
84d980d883 | ||
|
|
791c96faad | ||
|
|
31473e7e6d | ||
|
|
aa70b368b5 | ||
|
|
d3db569b34 | ||
|
|
94d6b7daf8 | ||
|
|
e089abe982 | ||
|
|
33289e882b | ||
|
|
1ed0bccb07 | ||
|
|
1da55e3989 | ||
|
|
166e97e12b | ||
|
|
33e5a6fa7c | ||
|
|
b1f9dc6919 | ||
|
|
38965af055 | ||
|
|
b010d4a563 | ||
|
|
eedd6604d1 | ||
|
|
59ff04b648 | ||
|
|
fcb3ee6425 | ||
|
|
77eacbb52c | ||
|
|
5ce85b2799 | ||
|
|
4538d198e1 | ||
|
|
4c39b05f94 | ||
|
|
c2478f509c | ||
|
|
c908ed7839 | ||
|
|
fc57311c81 | ||
|
|
818de49264 | ||
|
|
1318b1e58b | ||
|
|
617c816ec8 | ||
|
|
34fc86f585 | ||
|
|
e071f0a28d | ||
|
|
8faa624ade | ||
|
|
6d6ab2d067 | ||
|
|
00e6407514 | ||
|
|
00c06edffb | ||
|
|
de5053ae0d | ||
|
|
1940ec5c2a | ||
|
|
19c94c73f4 | ||
|
|
cd005ff60d | ||
|
|
578224f2e6 | ||
|
|
3857ce21cd | ||
|
|
aa490df46b | ||
|
|
88c1f1e7ac | ||
|
|
ede8af8191 | ||
|
|
3c24b605a1 | ||
|
|
d343b542f1 | ||
|
|
7acd719bf7 | ||
|
|
b4564d5301 | ||
|
|
60195e6d37 | ||
|
|
3d526d456e | ||
|
|
f05c9f7913 | ||
|
|
c2a4bc3aa1 | ||
|
|
718185e3b2 | ||
|
|
1d7783bb86 | ||
|
|
9fd2c552f5 | ||
|
|
70b8fd301b | ||
|
|
e6564f553d | ||
|
|
ed96e60ce3 | ||
|
|
2ebd745a1b | ||
|
|
cfcbe45b60 | ||
|
|
9cbf78ba99 | ||
|
|
b8d8738f81 | ||
|
|
63c97e719f | ||
|
|
3ac26f23c7 | ||
|
|
ff9410bc56 | ||
|
|
1798262d7a | ||
|
|
cd633b9ac9 | ||
|
|
5c5f7d315a | ||
|
|
0f7493ce50 | ||
|
|
40f61f828a | ||
|
|
108277f4b7 |
No files matched your search
+16
-1
@@ -5,7 +5,10 @@ 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,
|
||||||
@@ -14,6 +17,7 @@ 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,
|
||||||
@@ -32,6 +36,7 @@ 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,
|
||||||
@@ -45,6 +50,8 @@ 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-*,
|
||||||
@@ -53,6 +60,7 @@ 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,
|
||||||
@@ -65,7 +73,10 @@ 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
|
||||||
"
|
"
|
||||||
# ---
|
# ---
|
||||||
@@ -129,5 +140,9 @@ CheckOptions:
|
|||||||
readability-identifier-naming.GlobalFunctionIgnoredRegexp: "^(to_string|hash_append|tuple_hash)$"
|
readability-identifier-naming.GlobalFunctionIgnoredRegexp: "^(to_string|hash_append|tuple_hash)$"
|
||||||
|
|
||||||
HeaderFilterRegex: '^.*/(tests?|xrpl|xrpld)/.*\.(h|hpp|ipp)$'
|
HeaderFilterRegex: '^.*/(tests?|xrpl|xrpld)/.*\.(h|hpp|ipp)$'
|
||||||
ExcludeHeaderFilterRegex: '^.*/protocol_autogen/.*\.(h|hpp)$|^.*\.pb\.h$'
|
# Skip headers reached via add_module's symlinks (<build-dir>/modules/xrpl.lib*/...).
|
||||||
|
# verify_headers already checks each one under its real path,
|
||||||
|
# so reporting it twice would also apply its fixes twice.
|
||||||
|
# .ipp files are kept: they are only ever reached via the symlink.
|
||||||
|
ExcludeHeaderFilterRegex: '^.*/protocol_autogen/.*\.(h|hpp)$|^.*\.pb\.h$|^.*/modules/xrpl\.lib[^/]+/.*\.(h|hpp)$'
|
||||||
WarningsAsErrors: "*"
|
WarningsAsErrors: "*"
|
||||||
+3
-2
@@ -103,6 +103,7 @@ words:
|
|||||||
- dearmor
|
- dearmor
|
||||||
- decryptor
|
- decryptor
|
||||||
- dedented
|
- dedented
|
||||||
|
- dedup
|
||||||
- deleteme
|
- deleteme
|
||||||
- demultiplexer
|
- demultiplexer
|
||||||
- deserializaton
|
- deserializaton
|
||||||
@@ -197,6 +198,7 @@ words:
|
|||||||
- mptokens
|
- mptokens
|
||||||
- mpts
|
- mpts
|
||||||
- mtgox
|
- mtgox
|
||||||
|
- mudhra
|
||||||
- multisig
|
- multisig
|
||||||
- multisign
|
- multisign
|
||||||
- multisigned
|
- multisigned
|
||||||
@@ -317,7 +319,6 @@ words:
|
|||||||
- sttx
|
- sttx
|
||||||
- stvar
|
- stvar
|
||||||
- stvector
|
- stvector
|
||||||
- stxchainattestations
|
|
||||||
- summands
|
- summands
|
||||||
- superpeer
|
- superpeer
|
||||||
- superpeers
|
- superpeers
|
||||||
@@ -344,6 +345,7 @@ words:
|
|||||||
- unambiguity
|
- unambiguity
|
||||||
- unauthorizes
|
- unauthorizes
|
||||||
- unauthorizing
|
- unauthorizing
|
||||||
|
- undeserializable
|
||||||
- unergonomic
|
- unergonomic
|
||||||
- unfetched
|
- unfetched
|
||||||
- unfindable
|
- unfindable
|
||||||
@@ -375,7 +377,6 @@ words:
|
|||||||
- writeme
|
- writeme
|
||||||
- wsrch
|
- wsrch
|
||||||
- wthread
|
- wthread
|
||||||
- xbridge
|
|
||||||
- xchain
|
- xchain
|
||||||
- xcrun
|
- xcrun
|
||||||
- ximinez
|
- ximinez
|
||||||
|
|||||||
@@ -108,3 +108,75 @@ 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."
|
description: 'The logging verbosity ("quiet", "verbose"), or empty to use the Conan defaults.'
|
||||||
required: false
|
required: false
|
||||||
default: "verbose"
|
default: ""
|
||||||
sanitizers:
|
sanitizers:
|
||||||
description: "The sanitizers to enable."
|
description: "The sanitizers to enable."
|
||||||
required: false
|
required: false
|
||||||
@@ -35,6 +35,16 @@ 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}" \
|
||||||
@@ -42,6 +52,13 @@ 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} \
|
||||||
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
|
"${VERBOSITY_ARGS[@]}" \
|
||||||
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
|
--format=json \
|
||||||
.
|
. >"${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"
|
||||||
@@ -36,3 +36,18 @@ updates:
|
|||||||
rust-dependencies:
|
rust-dependencies:
|
||||||
patterns:
|
patterns:
|
||||||
- "*"
|
- "*"
|
||||||
|
|
||||||
|
- package-ecosystem: uv
|
||||||
|
directory: /cmake/scripts/codegen
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
day: monday
|
||||||
|
time: "04:00"
|
||||||
|
timezone: Etc/GMT
|
||||||
|
commit-message:
|
||||||
|
prefix: "chore: [DEPENDABOT] "
|
||||||
|
target-branch: develop
|
||||||
|
groups:
|
||||||
|
codegen-dependencies:
|
||||||
|
patterns:
|
||||||
|
- "*"
|
||||||
@@ -62,6 +62,7 @@ libxrpl.tx > xrpl.protocol
|
|||||||
libxrpl.tx > xrpl.server
|
libxrpl.tx > xrpl.server
|
||||||
libxrpl.tx > xrpl.tx
|
libxrpl.tx > xrpl.tx
|
||||||
test.app > test.jtx
|
test.app > test.jtx
|
||||||
|
test.app > tests.libxrpl
|
||||||
test.app > test.unit_test
|
test.app > test.unit_test
|
||||||
test.app > xrpl.basics
|
test.app > xrpl.basics
|
||||||
test.app > xrpl.config
|
test.app > xrpl.config
|
||||||
@@ -174,8 +175,10 @@ 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-060957e",
|
"image_tag": "sha-d3a71b2",
|
||||||
"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-3a2d19f"
|
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-d3a71b2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -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-3a2d19f",
|
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-d3a71b2",
|
||||||
"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-3a2d19f"
|
"image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-d3a71b2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ on:
|
|||||||
- "!nix/docker/README.md"
|
- "!nix/docker/README.md"
|
||||||
- "!nix/devshell.nix"
|
- "!nix/devshell.nix"
|
||||||
- "!nix/check-tools/**"
|
- "!nix/check-tools/**"
|
||||||
- "bin/default-loader-path.sh"
|
- "bin/nix/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"
|
||||||
@@ -25,8 +24,9 @@ on:
|
|||||||
- "!nix/devshell.nix"
|
- "!nix/devshell.nix"
|
||||||
- "!nix/check-tools/**"
|
- "!nix/check-tools/**"
|
||||||
- "bin/check-tools.sh"
|
- "bin/check-tools.sh"
|
||||||
- "bin/default-loader-path.sh"
|
- "bin/check-distrusted-roots.sh"
|
||||||
- "bin/install-sanitizer-libs.sh"
|
- "bin/nix/default-loader-path.sh"
|
||||||
|
- "bin/install/sanitizer-libs.sh"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- develop
|
- develop
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/build-packaging-images.yml"
|
- "bin/install/packaging-tools.sh"
|
||||||
- "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/check-distrusted-roots.sh"
|
||||||
|
- "bin/install/packaging-tools.sh"
|
||||||
- "package/images/packaging/**"
|
- "package/images/packaging/**"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ 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:
|
||||||
paths:
|
paths:
|
||||||
- ".github/workflows/build-pre-commit-image.yml"
|
- ".github/workflows/build-pre-commit-image.yml"
|
||||||
|
- "bin/check-distrusted-roots.sh"
|
||||||
- "bin/pre-commit/Dockerfile"
|
- "bin/pre-commit/Dockerfile"
|
||||||
- "rust-toolchain.toml"
|
- "rust-toolchain.toml"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- "develop"
|
- "develop"
|
||||||
- "release/*"
|
- "release/*"
|
||||||
|
- "staging/*"
|
||||||
paths:
|
paths:
|
||||||
- "crates/**/Cargo.toml"
|
- "crates/**/Cargo.toml"
|
||||||
- "crates/Cargo.lock"
|
- "crates/Cargo.lock"
|
||||||
@@ -34,7 +35,7 @@ permissions:
|
|||||||
jobs:
|
jobs:
|
||||||
audit:
|
audit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
# Needed to open an issue on scheduled failures.
|
# Needed to open an issue on scheduled failures.
|
||||||
@@ -66,7 +67,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@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
|
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
|
||||||
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@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
|
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
|
||||||
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@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||||
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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||||
with:
|
with:
|
||||||
name: check-tools-${{ runner.os }}-${{ runner.arch }}
|
name: check-tools-${{ runner.os }}-${{ runner.arch }}
|
||||||
path: ${{ matrix.snapshot }}
|
path: ${{ matrix.snapshot }}
|
||||||
@@ -93,9 +93,8 @@ 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/default-loader-path.sh
|
bin/nix/**
|
||||||
cfg/**
|
cfg/**
|
||||||
cmake/**
|
cmake/**
|
||||||
conan/**
|
conan/**
|
||||||
@@ -244,7 +243,7 @@ jobs:
|
|||||||
- should-run
|
- should-run
|
||||||
- build-test
|
- build-test
|
||||||
# Only run when committing to a PR that targets a release branch.
|
# Only run when committing to a PR that targets a release branch.
|
||||||
if: ${{ github.repository == 'XRPLF/rippled' && needs.should-run.outputs.go == 'true' && github.event_name == 'pull_request' && startsWith(github.event.pull_request.base.ref, 'release') }}
|
if: ${{ github.repository == 'XRPLF/rippled' && needs.should-run.outputs.go == 'true' && github.event_name == 'pull_request' && startsWith(github.event.pull_request.base.ref, 'release/') }}
|
||||||
uses: ./.github/workflows/reusable-upload-recipe.yml
|
uses: ./.github/workflows/reusable-upload-recipe.yml
|
||||||
secrets:
|
secrets:
|
||||||
remote_username: ${{ secrets.NEXUS_REMOTE_USERNAME }}
|
remote_username: ${{ secrets.NEXUS_REMOTE_USERNAME }}
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
# This workflow runs all workflows to build and test the code on various Linux
|
# This workflow runs all workflows to build and test the code on various Linux
|
||||||
# flavors, as well as on MacOS and Windows, on a scheduled basis, on merge into
|
# flavors, as well as on MacOS and Windows, on a scheduled basis, on merge into
|
||||||
# the 'develop' or 'release*' branches, or when requested manually. Upon pushes
|
# the 'develop', 'release/*' or 'staging/*' branches, or when requested
|
||||||
# to the develop branch it also uploads the libxrpl recipe to the Conan remote.
|
# manually. Upon pushes to the develop branch, it also uploads the libxrpl
|
||||||
|
# recipe to the Conan remote.
|
||||||
name: Trigger
|
name: Trigger
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "develop"
|
- "develop"
|
||||||
- "release*"
|
- "release/*"
|
||||||
|
- "staging/*"
|
||||||
paths:
|
paths:
|
||||||
# These paths are unique to `on-trigger.yml`.
|
# These paths are unique to `on-trigger.yml`.
|
||||||
- ".github/workflows/on-trigger.yml"
|
- ".github/workflows/on-trigger.yml"
|
||||||
@@ -31,9 +33,8 @@ 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/default-loader-path.sh"
|
- "bin/nix/**"
|
||||||
- "cfg/**"
|
- "cfg/**"
|
||||||
- "cmake/**"
|
- "cmake/**"
|
||||||
- "conan/**"
|
- "conan/**"
|
||||||
@@ -63,9 +64,9 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
# When a PR is merged into the develop branch it will be assigned a unique
|
# When a PR is merged into the develop branch, it will be assigned a unique
|
||||||
# group identifier, so execution will continue even if another PR is merged
|
# group identifier, so execution will continue even if another PR is merged
|
||||||
# while it is still running. In all other cases the group identifier is shared
|
# while it is still running. In all other cases, the group identifier is shared
|
||||||
# per branch, so that any in-progress runs are cancelled when a new commit is
|
# per branch, so that any in-progress runs are cancelled when a new commit is
|
||||||
# pushed.
|
# pushed.
|
||||||
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' && github.sha || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' && github.sha || github.ref }}
|
||||||
@@ -99,7 +100,7 @@ jobs:
|
|||||||
# However, we do not enable ccache for events targeting a release branch,
|
# However, we do not enable ccache for events targeting a release branch,
|
||||||
# to protect against the rare case that the output produced by ccache is
|
# to protect against the rare case that the output produced by ccache is
|
||||||
# not identical to a regular compilation.
|
# not identical to a regular compilation.
|
||||||
ccache_enabled: ${{ github.repository_owner == 'XRPLF' && !startsWith(github.ref, 'refs/heads/release') }}
|
ccache_enabled: ${{ github.repository_owner == 'XRPLF' && !startsWith(github.ref, 'refs/heads/release/') }}
|
||||||
os: ${{ matrix.os }}
|
os: ${{ matrix.os }}
|
||||||
secrets:
|
secrets:
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "develop"
|
- "develop"
|
||||||
- "release*"
|
- "release/*"
|
||||||
|
- "staging/*"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
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@279ec358f4a1be4088be3e024b07916fa97c75b6
|
uses: XRPLF/actions/.github/workflows/pre-commit.yml@6a52459a658649a0aeaab4ebd6a8f25173f6f16f
|
||||||
with:
|
with:
|
||||||
runs_on: ubuntu-latest
|
runs_on: ubuntu-latest
|
||||||
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-473fe44" }'
|
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-d3a71b2" }'
|
||||||
@@ -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-060957e
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||||
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@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||||
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@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||||
with:
|
with:
|
||||||
enable_ccache: ${{ inputs.ccache_enabled }}
|
enable_ccache: ${{ inputs.ccache_enabled }}
|
||||||
|
|
||||||
@@ -186,9 +186,6 @@ 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
|
||||||
@@ -257,20 +254,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/check-nix-store-refs.sh "${BUILD_DIR}"
|
run: ./bin/nix/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/check-nix-store-refs.sh "${CONAN_HOME}"
|
run: ./bin/nix/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/check-nix-store-refs.sh "${BUILD_DIR}/xrpld"
|
./bin/nix/check-nix-store-refs.sh "${BUILD_DIR}/xrpld"
|
||||||
./bin/check-nix-store-refs.sh "${BUILD_DIR}/xrpl_tests"
|
./bin/nix/check-nix-store-refs.sh "${BUILD_DIR}/xrpl_tests"
|
||||||
./bin/check-nix-store-refs.sh "${BUILD_DIR}/xrpld_tests"
|
./bin/nix/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 }}
|
||||||
@@ -283,7 +280,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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||||
with:
|
with:
|
||||||
name: xrpld-${{ inputs.config_name }}
|
name: xrpld-${{ inputs.config_name }}
|
||||||
path: ${{ env.BUILD_DIR }}/xrpld
|
path: ${{ env.BUILD_DIR }}/xrpld
|
||||||
@@ -297,7 +294,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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||||
with:
|
with:
|
||||||
name: validator-keys-${{ inputs.config_name }}
|
name: validator-keys-${{ inputs.config_name }}
|
||||||
path: |
|
path: |
|
||||||
@@ -308,7 +305,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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||||
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
|
||||||
@@ -324,7 +321,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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||||
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-060957e"
|
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-d3a71b2"
|
||||||
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@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||||
with:
|
with:
|
||||||
enable_ccache: false
|
enable_ccache: false
|
||||||
|
|
||||||
@@ -73,7 +73,6 @@ 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 }}
|
||||||
@@ -110,7 +109,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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||||
with:
|
with:
|
||||||
path: ${{ env.OUTPUT_FILE }}
|
path: ${{ env.OUTPUT_FILE }}
|
||||||
archive: false
|
archive: false
|
||||||
@@ -124,17 +123,23 @@ jobs:
|
|||||||
|
|
||||||
- name: Fix style
|
- name: Fix style
|
||||||
if: ${{ steps.files_changed.outcome != 'success' }}
|
if: ${{ steps.files_changed.outcome != 'success' }}
|
||||||
|
# pre-commit installs every hook's environment, even for hooks that match
|
||||||
|
# no files, and node-based hooks need libatomic, which this image lacks.
|
||||||
|
# Exit code 1 just means hooks modified files or found issues.
|
||||||
|
env:
|
||||||
|
SKIP: prettier,cspell
|
||||||
run: |
|
run: |
|
||||||
pre-commit run --all-files || true
|
git add --update
|
||||||
|
pre-commit run || [ $? -eq 1 ]
|
||||||
|
|
||||||
- name: Generate git diff
|
- name: Generate git diff
|
||||||
if: ${{ steps.files_changed.outcome != 'success' }}
|
if: ${{ steps.files_changed.outcome != 'success' }}
|
||||||
run: |
|
run: |
|
||||||
git diff | tee "${DIFF_FILE}"
|
git diff HEAD | tee "${DIFF_FILE}"
|
||||||
|
|
||||||
- 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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||||
with:
|
with:
|
||||||
path: ${{ env.DIFF_FILE }}
|
path: ${{ env.DIFF_FILE }}
|
||||||
archive: false
|
archive: false
|
||||||
@@ -186,7 +191,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@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
|
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
|
||||||
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@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||||
with:
|
with:
|
||||||
pattern: "*-pkg"
|
pattern: "*-pkg"
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -95,11 +95,15 @@ jobs:
|
|||||||
apt-get update -qq
|
apt-get update -qq
|
||||||
apt-get install -y "./${PACKAGE}"
|
apt-get install -y "./${PACKAGE}"
|
||||||
|
|
||||||
|
# Rocky Linux and AlmaLinux pick a mirror from a mirrorlist, and now and
|
||||||
|
# then get one that serves the repository metadata at a few hundred kB/s,
|
||||||
|
# which alone outlasts the job's timeout. dnf only abandons a mirror below
|
||||||
|
# 1000 B/s for 30 s, so raise that floor to fail over to the next one fast.
|
||||||
- name: Install the RPM
|
- name: Install the RPM
|
||||||
if: ${{ inputs.package_type == 'rpm' }}
|
if: ${{ inputs.package_type == 'rpm' }}
|
||||||
env:
|
env:
|
||||||
PACKAGE: ${{ steps.find.outputs.package }}
|
PACKAGE: ${{ steps.find.outputs.package }}
|
||||||
run: dnf install -y "./${PACKAGE}"
|
run: dnf install -y --setopt=minrate=1M --setopt=timeout=10 "./${PACKAGE}"
|
||||||
|
|
||||||
- name: Run xrpld
|
- name: Run xrpld
|
||||||
run: xrpld --version
|
run: xrpld --version
|
||||||
|
|||||||
@@ -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@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||||
with:
|
with:
|
||||||
enable_ccache: false
|
enable_ccache: false
|
||||||
|
|
||||||
- name: Download pre-built xrpld binary
|
- name: Download pre-built xrpld binary
|
||||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||||
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@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||||
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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||||
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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||||
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@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||||
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@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||||
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@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||||
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@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||||
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-060957e
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||||
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-060957e
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||||
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-060957e
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||||
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-060957e
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||||
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@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||||
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@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||||
with:
|
with:
|
||||||
enable_ccache: false
|
enable_ccache: false
|
||||||
|
|
||||||
@@ -108,14 +108,11 @@ 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/check-nix-store-refs.sh "${CONAN_HOME}"
|
run: ./bin/nix/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: e2b496dc2bd8340c2524cb9a2d2a943cde1bb6df # frozen: v23.1.1
|
rev: a9a8a861f30ed207ead7d5a3b7e8032283ba5da7 # frozen: v23.1.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: clang-format
|
- id: clang-format
|
||||||
args: [--style=file]
|
args: [--style=file]
|
||||||
@@ -82,9 +82,10 @@ repos:
|
|||||||
files: ^crates/.*\.rs$
|
files: ^crates/.*\.rs$
|
||||||
|
|
||||||
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
|
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
|
||||||
rev: f1c4833f8cf23c6d952673abc73525411a5719e8 # frozen: 0.29.1
|
rev: 28010ddd6016e1a0f7bd232acb6536ef996ae897 # frozen: 0.29.2
|
||||||
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
|
||||||
@@ -95,19 +96,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: a56c0b927e6465d37cae3e97d35d4d18ab2b96cd # frozen: v0.16.9
|
rev: f12be1ebaa5351c1fc76472de98db2c3446c8253 # frozen: v0.16.10
|
||||||
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: 4160603246a6b365d4a2af661c6d71b0a0f50478 # frozen: 26.5.1
|
rev: 96ae3e5802f3fe2d551e703e18f0a367d1a81ac2 # frozen: 26.10.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: 7ff8d35ae36a7d2b968f2f90b4c723e292e594ee # frozen: v2.3.1
|
rev: 2834ec6639549dd6796205c8f011dedcd587288b # frozen: v2.4.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
args: [--strict]
|
args: [--strict]
|
||||||
|
|||||||
+54
-1
@@ -22,13 +22,65 @@ 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
|
||||||
|
|
||||||
|
- A JSON string holding a NUL character, written as `\u0000` or as a raw byte, now makes the request unparsable, on every transport and at every API version, and is answered as any other body that does not parse. The server stored a string only through its first NUL, so `"ripplerpc": "3.0\u0000junk"` was read as `"3.0"` and any other field was cut short the same way. The two configuration sections read by the same parser, `[rpc_startup]` and `[validator_token]`, refuse it too.
|
||||||
|
- 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. Two things it does not reach: a WebSocket session, which reads the field only to echo it back, and API version 3, where the field selects nothing and so is neither read nor checked, `ripplerpc: "banana"` and no `ripplerpc` at all being served alike. 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.
|
||||||
|
- `subscribe`: every subscription a connection holds must name the same `api_version`. The first `subscribe` establishes it, and a later one naming a different version is refused with `apiVersionConflict`, registering nothing; the message names the version the connection's subscriptions are served at. The HTTP status is 400 where the envelope derives it from the error, with `ripplerpc: "3.0"` or at API version 3, and 200 with `ripplerpc` `"1.0"` or `"2.0"`, as for every error; a WebSocket frame carries no status. A `subscribe` refused for another reason, a stream name the server does not have for one, still fixes that version, since the registrations it makes are spread through the handler. A connection that subscribed one stream at `api_version` 2 and another at 1, in two calls, was previously served both at version 1, the later call's, so the first stream's shape changed under it. The version is fixed for the connection's life: a client that wants another version opens another connection. On the webhook path the subscriber is keyed on its `url` alone, so the refusal reaches a second admin because of a first admin's version, and the message names the version the url's subscriptions are served at, and no remedy: releasing a url means unsubscribing its streams, which would remove that first admin's subscription, and the server cannot tell the two callers apart. Naming the url alone does not release it, a subscriber a stream map still holds not being evicted. This reaches every API version, since version 1 and version 2 content is not interchangeable either: version 2 renames `transaction` to `tx_json` and hoists `hash`, so a version 1 client handed version 2 content finds no `transaction` member.
|
||||||
|
- `batch`: An entry of a `"method": "batch"` request that names `api_version` both inside `params` and at its own top level is now served at the version inside `params`. It was previously served at the top-level version whenever the one inside `params` resolved to version 1, so an entry asking for version 1 explicitly and something else at the top level changes which version answers it. A lone request can name both values too, and for it the version inside `params` has always won; reversing that precedence was confined to a batch entry.
|
||||||
|
- `batch`: every entry of one batch request is now served at the same API version. An entry may name the version the body names, or name none and inherit it, and a body whose entries name two different versions is refused whole with `Batch entries name different versions` at HTTP 400, charged as a malformed request. **This is visible to a version 1 or 2 client:** a `"method": "batch"` body could mix versions across its entries, each entry being dispatched at its own, and the difference is observable because the reply shape changes with the version. Three bodies change. One whose entries name two different versions is now refused instead of answered. One where some entries name a version and others name none now serves all of them at the named version, where an entry naming none was served at version 1; the same applies to a version named on the request's own top level, which the entries now inherit. One whose top level names a version and whose entries name a different one is now refused, where the top-level value was ignored and each entry was served at the version it named. A body whose top level names no version or the same version as its entries, and whose entries agree with one another or name none at all, is unaffected. A `"method": "batch"` body naming at its own top level a version the server does not serve is refused with `invalid_API_version` at HTTP 400, where it was previously served at version 1 as if it had named none. The line that produced the mixing was a fallback about where the field sits rather than a decision that entries may differ, so this is a correction rather than a removal of a feature. develop's `Version_test` batch case mixed an unversioned entry with a version 2 entry and is rewritten to name one version. One body is answered in one envelope, which a per-entry version leaves no way to choose. The command line client stamps `api_version` 1 into an entry naming none, so a `json2` batch mixing an unversioned entry with a versioned one is refused and must name the version on every entry.
|
||||||
|
- `batch`: A `"method": "batch"` request holding more than 100 entries is now refused with `Batch has too many entries` at HTTP 400 before any entry is dispatched and before the entries' versions are compared, at every API version. A body served at version 3 answers the JSON-RPC error object and an earlier version the plain text body. The top-level array form, accepted from version 3, takes the same limit.
|
||||||
|
|
||||||
|
### 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, and is dispatched on that object, as a lone request is; a one-element array holding the object is unpacked the same way, and any other `params` answers `params unparsable` for that entry, apart from `null`, an empty string, an empty array and an array holding one `null`, which read as an empty parameter object, as they do for a lone request; from API version 3, `null` and an empty string there answer `params unparsable` instead, as the version 3 paragraphs above describe. Such an entry's top-level `jsonrpc`, `ripplerpc` and `id` are read as if they sat inside that object, where the object does not name them itself, so the reply carries the entry's id and takes the envelope it named. An entry naming no `params` is dispatched as before, the entry itself being the object a handler reads. Previously such an entry was dispatched on its own members whatever `params` held, had its `api_version` read from its top level, and had its credentials ignored, since credentials were read only from an array-form `params`.
|
||||||
|
- A JSON-RPC (HTTP) request may name its `api_version` at its own top level, beside `method` and `id`, as well as inside `params`. The member is an XRPL extension, which the JSON-RPC 2.0 specification does not define; placing it beside the specification's own members is what lets a version 3 client send a specification-shaped request. This is honored from API version 3 up, so it needs `[beta_rpc_api]`; a version below that named at the top level is ignored, exactly as it always has been. Previously only an entry of a `"method": "batch"` request had its own top level read; a WebSocket request, which is one flat object, has always been read there.
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- Every credential-bearing field is masked wherever a request or a reply is echoed, logged or printed: `admin_password`, `admin_user`, `master_key`, `master_seed`, `master_seed_hex`, `passphrase`, `password`, `secret`, `seed`, `seed_hex`, `url_password`, `url_username`, `username`, `validation_key`, `validation_private_key` and `validation_seed`. The one list applies to a request echoed back in an error reply and to every request and reply written to the log. Nesting no longer matters, so a credential inside `params` is masked too. Six of the sixteen names, `master_key`, `master_seed`, `master_seed_hex`, `validation_key`, `validation_private_key` and `validation_seed`, occur only in a reply, which is how `wallet_propose` and `validation_create` used to write a live private key to the log. The `id`, `jsonrpc`, `ripplerpc` and `api_version` members a legacy reply echoes from the request are masked the same way. The command line client's trace of a reply's header covers the header only, not the body bytes read with it. 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 alone, never by its text or by the parser's message, 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. **Only API version 3 reports these four.** A request sending `ripplerpc: "3.0"` at API version 1 or 2 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 for those clients 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"`, or API version 3, which are the envelopes that derive 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`. From API version 3 the fifteen `malformed*` tokens `ledger_entry` names each report the code they own instead of 31.
|
||||||
|
- 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` 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 what was wrong. A body over the size limit answers `Request is too large`, and a body that parses to `{}` or `null` answers `Request is empty`; both previously answered `Unable to parse request: ` with nothing after the colon, the parser having recorded no error for them. Any other body that is not an array 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 three, as before, and this reaches every API version. The command line client reports `Request is too large` and `Request is empty` as the same class of rejection as an unparsable body, under `invalidParams` with the text in `error_what`. A top-level array, the one other body nothing can read a request from, is answered with a JSON error object instead, which the entry on top-level arrays below describes.
|
||||||
|
- `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.
|
||||||
|
- `batch`: Every entry of a `"method": "batch"` request is now charged against the sender's resource allowance, including one rejected before it reaches a handler, and the request stops at the first entry the connection is too loaded to serve. A reply array can therefore be shorter than the request array, and its last element depends on where the batch stopped. An entry that is not a JSON object, or names an API version the server does not serve, is charged before its role is known and answered with its own rejection; if that charge took the connection over the drop threshold, the batch stops there and that rejection is the last answer. Every other entry met over the threshold is answered `Server is overloaded` and nothing follows. A client should read any reply array shorter than its request as a connection over the drop threshold, whatever the last element says. A well-behaved client is unaffected; one that sends thousands of entries in a single body no longer gets every one of them answered.
|
||||||
|
- A body the server rejects before it reads a request out of it is now charged against the sender's resource allowance, as a malformed request already was. Eleven conditions were free: a body over the size limit, one that does not parse, one carrying no document, one that is neither a JSON object nor an array, a `"method": "batch"` naming no entry array, a lone request naming an `api_version` the server does not serve, and six ways a top-level array is not a batch this server can serve. The answer to the first six is unchanged; an array's answer changes as the entry on top-level arrays below describes, the one generic rejection it received having become six. A well-behaved client is unaffected; one that repeats such a body exhausts its allowance and is refused the next request a handler would have served. A WebSocket frame that does not parse, or exceeds the request size limit, is charged the same way, and a connection that sends only such frames is closed once it crosses the drop threshold.
|
||||||
|
- `subscribe`, `path_find`: A subscription is now served at the API version its own `subscribe` call named, rather than at the version of the most recent `subscribe` or `path_find` on the same connection. A `path_find` no longer changes the version anything that connection has subscribed is served at. An ordinary request is unaffected: it names its own version and is answered at it, so a connection subscribed at `api_version` 3 still calls `account_info` at version 1 and reads the version 1 shape.
|
||||||
|
- A top-level JSON array, which is the JSON-RPC 2.0 batch form accepted from API version 3, is now rejected with a JSON-RPC error object rather than a plain text body when it cannot be served: when it is empty, holds more than 100 entries, holds nothing that could be a request, names no API version of 3 or above that the server serves, or names two different versions the server serves. An array naming no served version of 3 or above is refused for requiring version 3, or, where every version it names is one the server does not serve, with `invalid_API_version`. One entry naming a version the server does not serve does not reject an array in which another entry names a served version: it is answered on its own, inside the reply array, with the same `-32606` code. This reaches every API version, since no earlier version accepts an array at all: a client that sent one received HTTP 400 with `Unable to parse request: ` and now receives the same status with a JSON body. The message also names the version rather than the shape where the version is what is wrong, which is what a client with `[beta_rpc_api]` disabled receives.
|
||||||
|
|
||||||
## 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.
|
||||||
|
|
||||||
|
### Breaking changes in 3.5.0
|
||||||
|
|
||||||
|
- The `XChainBridge` amendment and its ledger entries and transactions are removed. `XChainBridge` and `fixXChainRewardRounding` are now obsolete and can no longer be voted for; neither was ever enabled on Mainnet. `ledger_entry` no longer accepts `bridge`, `xchain_owned_claim_id`, or `xchain_owned_create_account_claim_id`; `account_objects` no longer accepts those values in `type`; and `server_definitions` no longer lists the removed ledger entry types, transaction types, fields, and the `XChainBridge` serialized type.
|
||||||
|
- `subscribe` (`ledger` stream): The deprecated `fee_ref` field has been removed unconditionally from both the `subscribe` response and the `ledgerClosed` stream messages. It was previously only omitted when the `XRPFees` amendment was enabled; that amendment has now been retired, so the field is never returned. This applies to all API versions.
|
||||||
|
|
||||||
### 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 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))
|
- `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))
|
||||||
|
- `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)
|
||||||
|
- `account_currencies`, `account_nfts`, `account_offers`: A request with more than one problem may now report a different one of them. An invalid `ledger_hash` or `ledger_index` is reported before an invalid or missing `account`. An invalid `limit` or `marker` is reported before `lgrNotFound` or `actNotFound`, and for `account_offers` also before `actMalformed`. A request with a single problem returns the same error as before. [#8561](https://github.com/XRPLF/rippled/pull/8561)
|
||||||
|
- `deposit_authorized`: A `credentials` entry that is all zeros (for example `"0"` or 64 `0` characters) now returns a `badCredentials` error instead of looking up a credential that can never exist.
|
||||||
|
- `account_info`, `account_lines`, `account_channels`: A request with more than one problem may now report a different one of them. An invalid `ledger_hash` or `ledger_index` is reported before a missing or invalid `account`, or `ident` for `account_info`. For `account_lines`, a `peer` that is not a string, or an invalid `limit` or `marker`, is reported before `lgrNotFound`, `actNotFound` or a malformed `account`, and an invalid `limit` or `marker` also before a malformed `peer`. For `account_channels`, a malformed `account` is reported before `lgrNotFound`, and an invalid `destination_account`, `limit` or `marker` before `lgrNotFound` or `actNotFound`. A request with a single problem returns the same error as before. [#8573](https://github.com/XRPLF/rippled/pull/8573)
|
||||||
|
- `deposit_authorized`, `nft_buy_offers`, `nft_sell_offers`: A request with more than one problem may now report a different one of them. An invalid `ledger_hash` or `ledger_index` is reported before a missing or invalid `source_account`, `destination_account` or `nft_id`, and for `nft_buy_offers` / `nft_sell_offers` also before an invalid `limit`. For `deposit_authorized`, an invalid `credentials` array is reported before `lgrNotFound`, `srcActNotFound`, `dstActNotFound` or `badCredentials`. For `nft_buy_offers` and `nft_sell_offers`, an invalid `marker` is reported before `lgrNotFound` or `objectNotFound`. A request with a single problem returns the same error as before. [#8613](https://github.com/XRPLF/rippled/pull/8613)
|
||||||
|
- `nft_buy_offers`, `nft_sell_offers`: An `nft_id` that is an array or an object now returns an `invalidParams` error instead of an `internal` error. [#8613](https://github.com/XRPLF/rippled/pull/8613)
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
@@ -50,6 +102,7 @@ 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
|
||||||
|
|
||||||
|
|||||||
@@ -2,33 +2,12 @@
|
|||||||
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| These instructions assume you have a C++ development environment ready with Git, Python, Conan, CMake, and a C++ compiler. For help setting one up on Linux, macOS, or Windows, [see this guide](./docs/build/environment.md).<br><br>These instructions also assume a basic familiarity with Conan and CMake. If you are unfamiliar with Conan, you can read our [crash course](./docs/build/conan.md) or the official [Getting Started][conan-getting-started] walkthrough. |
|
| These instructions assume you have a C++ development environment ready with Git, Python, Conan, CMake, and a C++ compiler. For help setting one up on Linux, macOS, or Windows, [see this guide](./docs/build/environment.md).<br><br>These instructions also assume a basic familiarity with Conan and CMake. If you are unfamiliar with Conan, you can read our [crash course](./docs/build/conan.md) or the official [Getting Started][conan-getting-started] walkthrough. |
|
||||||
|
|
||||||
## Minimum Requirements
|
## Supported platforms
|
||||||
|
|
||||||
For the hardware needed to run a node, see
|
Building and testing are supported on Linux, macOS, and (best effort) Windows;
|
||||||
[System Requirements](https://xrpl.org/system-requirements.html).
|
see [Supported development platforms](./docs/build/environment.md#supported-development-platforms).
|
||||||
|
Running `xrpld` is officially supported on Linux only;
|
||||||
For the software needed to build xrpld, see the
|
see [Requirements](./docs/install.md#requirements).
|
||||||
[environment setup guide](./docs/build/environment.md).
|
|
||||||
|
|
||||||
## Operating Systems
|
|
||||||
|
|
||||||
### Linux
|
|
||||||
|
|
||||||
The Ubuntu Linux distribution has received the highest level of quality
|
|
||||||
assurance, testing, and support. We also support Red Hat and use Debian
|
|
||||||
internally.
|
|
||||||
Our Linux CI tooling is distro-independent and uses a Nix-based environment, so it should be possible to build on other Linux distributions as well, although we have not tested them.
|
|
||||||
|
|
||||||
### macOS
|
|
||||||
|
|
||||||
Many `xrpld` engineers use macOS for development.
|
|
||||||
The minimum supported version is macOS 15 (Sequoia).
|
|
||||||
CI testing is done in macOS 26 (Tahoe), but the build defaults `CMAKE_OSX_DEPLOYMENT_TARGET` to 15.
|
|
||||||
|
|
||||||
### Windows
|
|
||||||
|
|
||||||
Windows is used by some engineers for development only, and is not recommended
|
|
||||||
for production use.
|
|
||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ if(is_gcc)
|
|||||||
# GCC-specific fixes
|
# GCC-specific fixes
|
||||||
add_compile_options(-Wno-unknown-pragmas -Wno-subobject-linkage)
|
add_compile_options(-Wno-unknown-pragmas -Wno-subobject-linkage)
|
||||||
# -Wno-subobject-linkage can be removed when we upgrade GCC version to at least 13.3
|
# -Wno-subobject-linkage can be removed when we upgrade GCC version to at least 13.3
|
||||||
elseif(is_clang)
|
elseif(is_any_clang)
|
||||||
# Clang-specific fixes
|
# Clang-specific fixes
|
||||||
add_compile_options(-Wno-unknown-warning-option) # Ignore unknown warning options
|
add_compile_options(-Wno-unknown-warning-option) # Ignore unknown warning options
|
||||||
elseif(is_msvc)
|
elseif(is_msvc)
|
||||||
|
|||||||
+5
-4
@@ -332,7 +332,7 @@ This ensures that configuration changes don't introduce new warnings across the
|
|||||||
|
|
||||||
### Installing clang-tidy
|
### Installing clang-tidy
|
||||||
|
|
||||||
See the [environment setup guide](./docs/build/environment.md#clang-tidy) for how to get clang-tidy.
|
The [Nix development shell](./docs/build/nix.md) provides `clang-tidy` at the [tested version](./docs/build/environment.md#tested-compiler-versions).
|
||||||
|
|
||||||
### Running clang-tidy locally
|
### Running clang-tidy locally
|
||||||
|
|
||||||
@@ -365,14 +365,15 @@ With this set, the hook will run as part of `git commit` alongside the other pre
|
|||||||
Then run clang-tidy on your local changes:
|
Then run clang-tidy on your local changes:
|
||||||
|
|
||||||
```
|
```
|
||||||
run-clang-tidy -p build -allow-no-checks src tests
|
run-clang-tidy -p build -allow-no-checks include src tests
|
||||||
```
|
```
|
||||||
|
|
||||||
This will check all source files in the `src`, `include` and `tests` directories using the compile commands from your `build` directory.
|
This will check all source files in the `include`, `src` and `tests` directories using the compile commands from your `build` directory.
|
||||||
|
Headers are checked on their own, which requires the `verify_headers` CMake option (ON by default).
|
||||||
If you wish to automatically fix whatever clang-tidy finds _and_ is capable of fixing, add `-fix -format` to the above command:
|
If you wish to automatically fix whatever clang-tidy finds _and_ is capable of fixing, add `-fix -format` to the above command:
|
||||||
|
|
||||||
```
|
```
|
||||||
run-clang-tidy -p build -quiet -fix -format -allow-no-checks src tests
|
run-clang-tidy -p build -quiet -fix -format -allow-no-checks include src tests
|
||||||
```
|
```
|
||||||
|
|
||||||
`-format` reformats the fixed code with [`.clang-format`](./.clang-format); without it the fixes are inserted in LLVM style and the `clang-format` hook rewrites them afterwards.
|
`-format` reformats the fixed code with [`.clang-format`](./.clang-format); without it the fixes are inserted in LLVM style and the `clang-format` hook rewrites them afterwards.
|
||||||
|
|||||||
+15
-9
@@ -34,7 +34,7 @@ so tools can filter them and protection rules can target `release/*` and `stagin
|
|||||||
- **Branches only move forward.**
|
- **Branches only move forward.**
|
||||||
`develop`, `staging/X.Y.x`, and `release/X.Y.x` are never rewritten.
|
`develop`, `staging/X.Y.x`, and `release/X.Y.x` are never rewritten.
|
||||||
- **Cherry-picking only goes from `develop` to a staging branch**,
|
- **Cherry-picking only goes from `develop` to a staging branch**,
|
||||||
for fixes that must get into a release after the code freeze
|
for fixes that must get into a release after the [code freeze](#release-candidates)
|
||||||
(see [Emergency Fixes From `develop`](#emergency-fixes-from-develop)).
|
(see [Emergency Fixes From `develop`](#emergency-fixes-from-develop)).
|
||||||
- **Security fixes are prepared privately and published with the release that contains them**,
|
- **Security fixes are prepared privately and published with the release that contains them**,
|
||||||
so vulnerabilities are not disclosed prematurely.
|
so vulnerabilities are not disclosed prematurely.
|
||||||
@@ -49,6 +49,7 @@ develop staging/X.Y.x & release/X.Y.x
|
|||||||
│
|
│
|
||||||
├── Tag: X.Y.0-b1
|
├── Tag: X.Y.0-b1
|
||||||
├── Tag: X.Y.0-bN
|
├── Tag: X.Y.0-bN
|
||||||
|
│ (2 weeks before rc1: freeze on large changes starts)
|
||||||
├── Tag: X.Y.0-rc1 ───────────────┐ (branches created)
|
├── Tag: X.Y.0-rc1 ───────────────┐ (branches created)
|
||||||
│ │
|
│ │
|
||||||
│ (development continues) ├── Fixes
|
│ (development continues) ├── Fixes
|
||||||
@@ -75,16 +76,20 @@ develop staging/X.Y.x & release/X.Y.x
|
|||||||
3. **Branches:** `staging/X.Y.x` and `release/X.Y.x` are created from `develop`
|
3. **Branches:** `staging/X.Y.x` and `release/X.Y.x` are created from `develop`
|
||||||
at the commit tagged `X.Y.0-rc1`.
|
at the commit tagged `X.Y.0-rc1`.
|
||||||
The first RC also kicks off the QE process.
|
The first RC also kicks off the QE process.
|
||||||
4. **Code freeze:** No new features or unrelated changes are pulled from `develop`
|
|
||||||
into `staging/X.Y.x` or `release/X.Y.x`.
|
### Freeze on Large Changes
|
||||||
Only critical stabilization fixes go into the line.
|
|
||||||
5. **No large changes on `develop`:** Until `X.Y.0` is [merged back](#merging-back-into-develop),
|
From two weeks before `X.Y.0-rc1` until `X.Y.0` is [merged back](#merging-back-into-develop),
|
||||||
large changes (e.g., big refactors, moving or renaming many files, mass reformatting)
|
large changes (e.g., big refactors, moving or renaming many files, mass reformatting)
|
||||||
are not merged into `develop`,
|
are not merged into `develop`.
|
||||||
so that fixes on the line and the merge back don't run into conflicts.
|
|
||||||
|
|
||||||
### Release Candidates
|
### Release Candidates
|
||||||
|
|
||||||
|
After branching, the line is in code freeze:
|
||||||
|
no new features or unrelated changes are pulled from `develop`
|
||||||
|
into `staging/X.Y.x` or `release/X.Y.x`.
|
||||||
|
Only critical stabilization fixes go into the line.
|
||||||
|
|
||||||
1. Fixes are developed against `staging/X.Y.x`.
|
1. Fixes are developed against `staging/X.Y.x`.
|
||||||
2. When ready, a new RC is created on `staging/X.Y.x`,
|
2. When ready, a new RC is created on `staging/X.Y.x`,
|
||||||
and `release/X.Y.x` is fast-forwarded to it.
|
and `release/X.Y.x` is fast-forwarded to it.
|
||||||
@@ -106,7 +111,8 @@ one right after the other.
|
|||||||
2. `release/X.Y.x` is fast-forwarded to `staging/X.Y.x`,
|
2. `release/X.Y.x` is fast-forwarded to `staging/X.Y.x`,
|
||||||
and the release is tagged on it.
|
and the release is tagged on it.
|
||||||
3. The release is immediately [merged back into `develop`](#merging-back-into-develop).
|
3. The release is immediately [merged back into `develop`](#merging-back-into-develop).
|
||||||
For a major-minor release, this lifts the freeze on large changes in `develop`.
|
For a major-minor release, this lifts the [freeze on large changes](#freeze-on-large-changes)
|
||||||
|
in `develop`.
|
||||||
|
|
||||||
### Merging Back Into `develop`
|
### Merging Back Into `develop`
|
||||||
|
|
||||||
@@ -127,7 +133,7 @@ After the merge, `git log develop..<tag>` must be empty.
|
|||||||
### Emergency Fixes From `develop`
|
### Emergency Fixes From `develop`
|
||||||
|
|
||||||
If a commit was merged to `develop`
|
If a commit was merged to `develop`
|
||||||
and needs to be included in a release after the code freeze:
|
and needs to be included in a release after the [code freeze](#release-candidates):
|
||||||
|
|
||||||
1. Create a PR that cherry-picks the commit onto `staging/X.Y.x`.
|
1. Create a PR that cherry-picks the commit onto `staging/X.Y.x`.
|
||||||
2. Leave `develop` as it is, with no reverts.
|
2. Leave `develop` as it is, with no reverts.
|
||||||
|
|||||||
Executable
+60
@@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# check-distrusted-roots.sh — fail if a CA bundle trusts a root of the
|
||||||
|
# compromised eMudhra intermediates; see https://emudhra.we-have-a-problem.com/.
|
||||||
|
#
|
||||||
|
# Usage: check-distrusted-roots.sh [ca-bundle]
|
||||||
|
# Defaults to the system bundle (Debian or RHEL path).
|
||||||
|
#
|
||||||
|
# Roots are matched by SHA-256 fingerprint, needing only bash, base64 and
|
||||||
|
# sha256sum (nixos/nix has no awk). Only plain CERTIFICATE blocks are checked:
|
||||||
|
# OpenSSL's TRUSTED CERTIFICATE blocks carry their own trust settings, which is
|
||||||
|
# how nixpkgs' cacert marks a blacklisted root as rejected.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
declare -A ROOTS=(
|
||||||
|
[d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4]="AAA Certificate Services"
|
||||||
|
[86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b]="emSign ECC Root CA - G3"
|
||||||
|
)
|
||||||
|
|
||||||
|
BUNDLE="${1:-}"
|
||||||
|
if [ -z "${BUNDLE}" ]; then
|
||||||
|
for CANDIDATE in /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt; do
|
||||||
|
if [ -f "${CANDIDATE}" ]; then
|
||||||
|
BUNDLE="${CANDIDATE}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
STATUS=0
|
||||||
|
COUNT=0
|
||||||
|
PEM=""
|
||||||
|
while IFS= read -r LINE || [ -n "${LINE}" ]; do
|
||||||
|
case "${LINE}" in
|
||||||
|
"-----BEGIN CERTIFICATE-----") PEM="" ;;
|
||||||
|
"-----END CERTIFICATE-----")
|
||||||
|
COUNT=$((COUNT + 1))
|
||||||
|
FINGERPRINT="$(base64 -d <<<"${PEM}" | sha256sum)" || {
|
||||||
|
echo "ERROR: certificate ${COUNT} in ${BUNDLE} is not valid base64" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
ROOT="${ROOTS[${FINGERPRINT%% *}]:-}"
|
||||||
|
if [ -n "${ROOT}" ]; then
|
||||||
|
echo "ERROR: ${BUNDLE} trusts '${ROOT}'" >&2
|
||||||
|
STATUS=1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
# Lines outside a CERTIFICATE block only collect until the next BEGIN.
|
||||||
|
*) PEM+="${LINE}" ;;
|
||||||
|
esac
|
||||||
|
done <"${BUNDLE:?no system CA bundle found}"
|
||||||
|
|
||||||
|
# An empty or unparsable bundle would otherwise pass.
|
||||||
|
if [ "${COUNT}" -eq 0 ]; then
|
||||||
|
echo "ERROR: ${BUNDLE} has no certificates" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "${BUNDLE}: checked ${COUNT} certificates"
|
||||||
|
exit "${STATUS}"
|
||||||
+17
-6
@@ -20,9 +20,11 @@
|
|||||||
# 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 (`clang-tidy-22`,
|
# Tools that Nix also exposes under a version-suffixed name
|
||||||
# `g++-15`, ...) are probed under both names: a suffixed name can break while
|
# (`clang-tidy-<v>`, `g++-<v>`, ...) are probed under both names:
|
||||||
# the plain one still works (see mkVersionedToolLinks in nix/packages.nix).
|
# a suffixed name can break while the plain one still works
|
||||||
|
# (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.
|
||||||
@@ -34,9 +36,16 @@
|
|||||||
|
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
|
|
||||||
# Version suffixes of the Nix tool links, tracking nix/packages.nix.
|
# major_version <compiler>
|
||||||
gcc_version=15
|
# Major version of a compiler on PATH, or "unknown" when it isn't there.
|
||||||
llvm_version=22
|
major_version() {
|
||||||
|
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
|
||||||
@@ -112,6 +121,7 @@ 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
|
||||||
@@ -180,6 +190,7 @@ 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++
|
||||||
|
|||||||
@@ -58,6 +58,14 @@ function install() {
|
|||||||
rpm-build \
|
rpm-build \
|
||||||
rpm-sign \
|
rpm-sign \
|
||||||
systemd-rpm-macros
|
systemd-rpm-macros
|
||||||
|
|
||||||
|
# AlmaLinux's ca-certificates still trusts the root of the compromised
|
||||||
|
# eMudhra intermediates; see https://emudhra.we-have-a-problem.com/.
|
||||||
|
# TODO: drop once it ships a fix.
|
||||||
|
trust extract --format=pem-bundle \
|
||||||
|
--filter="pkcs11:object=emSign%20ECC%20Root%20CA%20-%20G3;type=cert" \
|
||||||
|
/etc/pki/ca-trust/source/blocklist/emSign_ECC_Root_CA_-_G3.pem
|
||||||
|
update-ca-trust
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
File renamed without changes.
Executable
+65
@@ -0,0 +1,65 @@
|
|||||||
|
#!/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 ]
|
||||||
@@ -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/check-nix-store-refs.sh <path>
|
# Usage: bin/nix/check-nix-store-refs.sh <path>
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
File renamed without changes.
@@ -9,12 +9,13 @@ ARG DEBIAN_FRONTEND=noninteractive
|
|||||||
|
|
||||||
RUN <<EOF
|
RUN <<EOF
|
||||||
pkgs=()
|
pkgs=()
|
||||||
|
pkgs+=(ca-certificates) # Trust store for curl, git, pip and nix.
|
||||||
pkgs+=(curl) # Required to install nix.
|
pkgs+=(curl) # Required to install nix.
|
||||||
pkgs+=(doxygen) # Needed for Clio's check-doxygen-docs.sh.
|
pkgs+=(doxygen) # Needed for Clio's check-doxygen-docs.sh.
|
||||||
pkgs+=(git) # Required for prepare-runner.
|
pkgs+=(git) # Required for prepare-runner.
|
||||||
pkgs+=(libatomic1) # Required to run pre-commit provided `node`.
|
pkgs+=(libatomic1) # Required to run pre-commit provided `node`.
|
||||||
pkgs+=(python3) # Python 3 interpreter.
|
pkgs+=(python3) # Python 3 interpreter.
|
||||||
pkgs+=(python3-pip) # Package manager for Python applications.
|
pkgs+=(python3-venv) # Virtual environment for Python applications.
|
||||||
pkgs+=(xz-utils) # Required to install nix
|
pkgs+=(xz-utils) # Required to install nix
|
||||||
|
|
||||||
apt-get update
|
apt-get update
|
||||||
@@ -23,9 +24,21 @@ apt-get clean
|
|||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
ARG PRE_COMMIT_VERSION=4.6.0
|
# Sanity-check that the system CA bundle distrusts the compromised eMudhra roots,
|
||||||
RUN pip install --no-cache --break-system-packages \
|
# before pip and the nix installer download anything with it.
|
||||||
pre-commit==${PRE_COMMIT_VERSION}
|
RUN --mount=type=bind,source=bin/check-distrusted-roots.sh,target=/check-distrusted-roots.sh \
|
||||||
|
/check-distrusted-roots.sh
|
||||||
|
|
||||||
|
# Ahead of the system Python on PATH,
|
||||||
|
# so `python3` and `pip` resolve to the venv and installs stay out of the system Python.
|
||||||
|
ENV VIRTUAL_ENV="/opt/venv"
|
||||||
|
ENV PATH="${VIRTUAL_ENV}/bin:${PATH}"
|
||||||
|
|
||||||
|
ARG PRE_COMMIT_VERSION=4.6.2
|
||||||
|
RUN <<EOF
|
||||||
|
python3 -m venv "${VIRTUAL_ENV}"
|
||||||
|
pip install --no-cache pre-commit==${PRE_COMMIT_VERSION}
|
||||||
|
EOF
|
||||||
|
|
||||||
RUN sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon --yes
|
RUN sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon --yes
|
||||||
|
|
||||||
@@ -33,7 +46,9 @@ RUN sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --dae
|
|||||||
# so nix is available in all shells including non-interactive shells (e.g., GitHub Actions).
|
# so nix is available in all shells including non-interactive shells (e.g., GitHub Actions).
|
||||||
ENV PATH="/nix/var/nix/profiles/default/bin:${PATH}"
|
ENV PATH="/nix/var/nix/profiles/default/bin:${PATH}"
|
||||||
ENV NIX_PROFILES="/nix/var/nix/profiles/default"
|
ENV NIX_PROFILES="/nix/var/nix/profiles/default"
|
||||||
ENV NIX_SSL_CERT_FILE="/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
# The system bundle gets security updates through apt;
|
||||||
|
# the one in the Nix profile is frozen at the installer's nixpkgs.
|
||||||
|
ENV NIX_SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt"
|
||||||
|
|
||||||
# Verify nix installation
|
# Verify nix installation
|
||||||
RUN nix --version
|
RUN nix --version
|
||||||
|
|||||||
@@ -5,15 +5,6 @@ The script determines the staged files itself (see `pass_filenames: false` in
|
|||||||
.pre-commit-config.yaml) so run-clang-tidy is run once and handles parallelism
|
.pre-commit-config.yaml) so run-clang-tidy is run once and handles parallelism
|
||||||
internally: pre-commit would otherwise split the files across parallel hook
|
internally: pre-commit would otherwise split the files across parallel hook
|
||||||
invocations that race when fixes edit a shared header.
|
invocations that race when fixes edit a shared header.
|
||||||
|
|
||||||
Fixes are collected with `-export-fixes` and applied by clang-apply-replacements
|
|
||||||
in a separate step rather than with run-clang-tidy's `-fix`. The `add_module`
|
|
||||||
build isolates each module's headers behind a per-module symlink directory
|
|
||||||
(build/modules/<module>/...), so a header reachable from several translation
|
|
||||||
units is referenced through different paths that all resolve to the same source
|
|
||||||
file. clang-apply-replacements deduplicates identical replacements by their
|
|
||||||
literal path, so those paths must be canonicalised to the real source path
|
|
||||||
first; otherwise the same fix is applied once per path and corrupts the header.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
@@ -23,24 +14,29 @@ import re
|
|||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
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.
|
||||||
TIDY_EXTENSIONS = {".cpp", ".h", ".hpp"}
|
TIDY_EXTENSIONS = {".cpp", ".h", ".hpp"}
|
||||||
|
|
||||||
# A single-quoted `FilePath:` entry in an -export-fixes YAML file, allowing the
|
|
||||||
# `- ` marker that precedes it inside a `Replacements:` sequence. clang-tidy
|
def clang_tidy_major() -> str | None:
|
||||||
# emits paths single-quoted and doubles any embedded quote per YAML rules.
|
"""Major version of the `clang-tidy` on PATH, which run-clang-tidy invokes."""
|
||||||
FILEPATH_RE = re.compile(r"^(\s*(?:-\s+)?FilePath:\s*)'((?:[^']|'')*)'\s*$")
|
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) -> str | None:
|
def find_tool(name: str, version: str | None) -> str | None:
|
||||||
for candidate in (f"{name}-{CLANG_TIDY_VERSION}", name):
|
"""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
|
||||||
@@ -68,25 +64,6 @@ def staged_files(repo_root: Path) -> list[Path]:
|
|||||||
return [repo_root / rel for rel in output.splitlines() if rel]
|
return [repo_root / rel for rel in output.splitlines() if rel]
|
||||||
|
|
||||||
|
|
||||||
def canonicalize_fix_paths(fixes_dir: Path) -> None:
|
|
||||||
"""Rewrite every `FilePath` in the exported fixes to its real source path.
|
|
||||||
|
|
||||||
A header included through a module's isolation symlink is recorded under that
|
|
||||||
symlink's path; collapsing all paths to the same real file lets
|
|
||||||
clang-apply-replacements recognise the per-translation-unit duplicates and
|
|
||||||
apply each fix once.
|
|
||||||
"""
|
|
||||||
for yaml in fixes_dir.glob("*.yaml"):
|
|
||||||
lines = []
|
|
||||||
for line in yaml.read_text().splitlines():
|
|
||||||
if m := FILEPATH_RE.match(line):
|
|
||||||
path = m.group(2).replace("''", "'")
|
|
||||||
real = os.path.realpath(path).replace("'", "''")
|
|
||||||
line = f"{m.group(1)}'{real}'"
|
|
||||||
lines.append(line)
|
|
||||||
yaml.write_text("\n".join(lines) + "\n")
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not os.environ.get("TIDY"):
|
if not os.environ.get("TIDY"):
|
||||||
return 0
|
return 0
|
||||||
@@ -103,20 +80,13 @@ def main():
|
|||||||
if not files:
|
if not files:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
run_clang_tidy = find_tool("run-clang-tidy")
|
version = clang_tidy_major()
|
||||||
clang_apply_replacements = find_tool("clang-apply-replacements")
|
run_clang_tidy = find_tool("run-clang-tidy", version)
|
||||||
missing = [
|
if not run_clang_tidy:
|
||||||
name
|
tried = f" (tried the '-{version}' suffix too)" if version else ""
|
||||||
for name, path in (
|
|
||||||
("run-clang-tidy", run_clang_tidy),
|
|
||||||
("clang-apply-replacements", clang_apply_replacements),
|
|
||||||
)
|
|
||||||
if not path
|
|
||||||
]
|
|
||||||
if missing:
|
|
||||||
print(
|
print(
|
||||||
f"clang-tidy check failed: TIDY is enabled but {' and '.join(missing)} "
|
f"clang-tidy check failed: TIDY is enabled but run-clang-tidy "
|
||||||
f"was not found in PATH (tried the '-{CLANG_TIDY_VERSION}' suffix too).",
|
f"was not found in PATH{tried}.",
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
return 1
|
return 1
|
||||||
@@ -130,27 +100,19 @@ def main():
|
|||||||
)
|
)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory() as fixes_dir:
|
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
[
|
[
|
||||||
run_clang_tidy,
|
run_clang_tidy,
|
||||||
"-quiet",
|
"-quiet",
|
||||||
"-p",
|
"-p",
|
||||||
build_dir,
|
build_dir,
|
||||||
"-export-fixes",
|
"-fix",
|
||||||
fixes_dir,
|
"-format",
|
||||||
"-allow-no-checks",
|
"-allow-no-checks",
|
||||||
]
|
]
|
||||||
+ files
|
+ files
|
||||||
)
|
)
|
||||||
canonicalize_fix_paths(Path(fixes_dir))
|
return result.returncode
|
||||||
# `FormatStyle` in .clang-tidy does not reach this path,
|
|
||||||
# so ask for the repository style here.
|
|
||||||
applied = subprocess.run(
|
|
||||||
[clang_apply_replacements, "--format", "--style=file", fixes_dir]
|
|
||||||
)
|
|
||||||
|
|
||||||
return result.returncode or applied.returncode
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1360,6 +1360,39 @@
|
|||||||
# Example:
|
# Example:
|
||||||
# owner_reserve = 200000 # 0.2 XRP
|
# owner_reserve = 200000 # 0.2 XRP
|
||||||
#
|
#
|
||||||
|
# gas_limit = <gas>
|
||||||
|
#
|
||||||
|
# The gas limit is the maximum amount of gas that can be
|
||||||
|
# consumed by a single transaction. The gas limit is used to prevent
|
||||||
|
# transactions from consuming too many resources.
|
||||||
|
#
|
||||||
|
# If this parameter is unspecified, xrpld will use an internal
|
||||||
|
# default. Don't change this without understanding the consequences.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# gas_limit = 1000000 # 1 million gas
|
||||||
|
#
|
||||||
|
# bytecode_size_limit = <bytes>
|
||||||
|
#
|
||||||
|
# The bytecode size limit is the maximum size of a WASM extension in
|
||||||
|
# bytes. The size limit is used to prevent extensions from consuming
|
||||||
|
# too many resources.
|
||||||
|
#
|
||||||
|
# If this parameter is unspecified, xrpld will use an internal
|
||||||
|
# default. Don't change this without understanding the consequences.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# bytecode_size_limit = 100000 # 100 kb
|
||||||
|
#
|
||||||
|
# gas_price = <micro-drops>
|
||||||
|
#
|
||||||
|
# The gas price is the conversion between WASM gas and its price in drops.
|
||||||
|
#
|
||||||
|
# If this parameter is unspecified, xrpld will use an internal
|
||||||
|
# default. Don't change this without understanding the consequences.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# gas_price = 1000000 # 1 drop per gas
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# 9. Misc Settings
|
# 9. Misc Settings
|
||||||
|
|||||||
@@ -9,13 +9,21 @@ include_guard(GLOBAL)
|
|||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# Compiler detection (C++)
|
# Compiler detection (C++)
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
set(is_clang FALSE)
|
# is_any_clang is true for both LLVM Clang and AppleClang. Their version numbers
|
||||||
|
# and feature sets differ, so use is_llvm_clang or is_apple_clang when it matters.
|
||||||
|
set(is_any_clang FALSE)
|
||||||
|
set(is_llvm_clang FALSE)
|
||||||
|
set(is_apple_clang FALSE)
|
||||||
set(is_gcc FALSE)
|
set(is_gcc FALSE)
|
||||||
set(is_msvc FALSE)
|
set(is_msvc FALSE)
|
||||||
set(is_xcode FALSE)
|
set(is_xcode FALSE)
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") # Clang or AppleClang
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
set(is_clang TRUE)
|
set(is_any_clang TRUE)
|
||||||
|
set(is_llvm_clang TRUE)
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||||
|
set(is_any_clang TRUE)
|
||||||
|
set(is_apple_clang TRUE)
|
||||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
set(is_gcc TRUE)
|
set(is_gcc TRUE)
|
||||||
elseif(MSVC)
|
elseif(MSVC)
|
||||||
|
|||||||
@@ -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/default-loader-path.sh.
|
The default loader is resolved by bin/nix/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/default-loader-path.sh")
|
set(_loader_path_script "${CMAKE_SOURCE_DIR}/bin/nix/default-loader-path.sh")
|
||||||
|
|
||||||
if(
|
if(
|
||||||
is_linux
|
is_linux
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ else()
|
|||||||
INTERFACE
|
INTERFACE
|
||||||
-Wall
|
-Wall
|
||||||
-Wdeprecated
|
-Wdeprecated
|
||||||
$<$<BOOL:${is_clang}>:-Wno-deprecated-declarations>
|
$<$<BOOL:${is_any_clang}>:-Wno-deprecated-declarations>
|
||||||
$<$<BOOL:${wextra}>:-Wextra
|
$<$<BOOL:${wextra}>:-Wextra
|
||||||
-Wno-unused-parameter>
|
-Wno-unused-parameter>
|
||||||
$<$<BOOL:${werr}>:-Werror>
|
$<$<BOOL:${werr}>:-Werror>
|
||||||
@@ -177,7 +177,7 @@ else()
|
|||||||
if(
|
if(
|
||||||
is_nix_compiler
|
is_nix_compiler
|
||||||
AND is_linux
|
AND is_linux
|
||||||
AND is_clang
|
AND is_any_clang
|
||||||
AND CMAKE_CXX_FLAGS MATCHES "stdlib=libstdc"
|
AND CMAKE_CXX_FLAGS MATCHES "stdlib=libstdc"
|
||||||
)
|
)
|
||||||
string(
|
string(
|
||||||
@@ -204,7 +204,10 @@ if(voidstar)
|
|||||||
"Antithesis instrumentation requires Linux, aborting..."
|
"Antithesis instrumentation requires Linux, aborting..."
|
||||||
)
|
)
|
||||||
elseif(
|
elseif(
|
||||||
NOT (is_clang AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
|
NOT (
|
||||||
|
is_llvm_clang
|
||||||
|
AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0
|
||||||
|
)
|
||||||
)
|
)
|
||||||
message(
|
message(
|
||||||
FATAL_ERROR
|
FATAL_ERROR
|
||||||
|
|||||||
@@ -292,6 +292,25 @@ 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
|
||||||
|
account_channels
|
||||||
|
account_currencies
|
||||||
|
account_info
|
||||||
|
account_lines
|
||||||
|
account_nfts
|
||||||
|
account_offers
|
||||||
|
book_changes
|
||||||
|
deposit_authorized
|
||||||
|
ledger
|
||||||
|
nft_offers_common
|
||||||
|
transaction_entry
|
||||||
|
)
|
||||||
|
target_sources(xrpld PRIVATE ${rpcspec_instantiations})
|
||||||
|
|
||||||
if(tests)
|
if(tests)
|
||||||
file(
|
file(
|
||||||
GLOB_RECURSE sources
|
GLOB_RECURSE sources
|
||||||
@@ -322,6 +341,7 @@ 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()
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ target_link_options(common INTERFACE ${sanitizers_linker_flags})
|
|||||||
# This module appends -fsanitize-ignorelist=<path> for Clang builds.
|
# This module appends -fsanitize-ignorelist=<path> for Clang builds.
|
||||||
# The ignorelist path contains CMAKE_SOURCE_DIR, so it must be set here, rather than in the Conan profile.
|
# The ignorelist path contains CMAKE_SOURCE_DIR, so it must be set here, rather than in the Conan profile.
|
||||||
# GCC does not support -fsanitize-ignorelist.
|
# GCC does not support -fsanitize-ignorelist.
|
||||||
if(is_clang)
|
if(is_any_clang)
|
||||||
set(ignorelist_path
|
set(ignorelist_path
|
||||||
"${CMAKE_SOURCE_DIR}/sanitizers/suppressions/sanitizer-ignorelist.txt"
|
"${CMAKE_SOURCE_DIR}/sanitizers/suppressions/sanitizer-ignorelist.txt"
|
||||||
)
|
)
|
||||||
@@ -77,19 +77,24 @@ if(is_clang)
|
|||||||
message(STATUS " Ignorelist: ${ignorelist_path}")
|
message(STATUS " Ignorelist: ${ignorelist_path}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Define SANITIZERS macro for BuildInfo.cpp
|
# Define the SANITIZERS macro for BuildInfo.cpp, plus one of XRPL_ASAN,
|
||||||
|
# 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)
|
||||||
|
|||||||
@@ -23,11 +23,8 @@ if(NOT is_multiconfig)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(is_clang) # both Clang and AppleClang
|
if(is_llvm_clang)
|
||||||
if(
|
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0)
|
||||||
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang"
|
|
||||||
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0
|
|
||||||
)
|
|
||||||
message(FATAL_ERROR "This project requires clang 16 or later")
|
message(FATAL_ERROR "This project requires clang 16 or later")
|
||||||
endif()
|
endif()
|
||||||
elseif(is_gcc)
|
elseif(is_gcc)
|
||||||
|
|||||||
@@ -62,11 +62,11 @@ if(unity)
|
|||||||
set(CMAKE_UNITY_BUILD ON CACHE BOOL "Do a unity build")
|
set(CMAKE_UNITY_BUILD ON CACHE BOOL "Do a unity build")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(is_clang AND is_linux)
|
if(is_llvm_clang AND is_linux)
|
||||||
option(voidstar "Enable Antithesis instrumentation." OFF)
|
option(voidstar "Enable Antithesis instrumentation." OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(is_gcc OR is_clang)
|
if(is_gcc OR is_any_clang)
|
||||||
include(ProcessorCount)
|
include(ProcessorCount)
|
||||||
ProcessorCount(PROCESSOR_COUNT)
|
ProcessorCount(PROCESSOR_COUNT)
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ else()
|
|||||||
set(use_mold OFF CACHE BOOL "mold linker, linux only" FORCE)
|
set(use_mold OFF CACHE BOOL "mold linker, linux only" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(is_clang)
|
if(is_any_clang)
|
||||||
option(use_lld "enables detection of lld linker" ON)
|
option(use_lld "enables detection of lld linker" ON)
|
||||||
else()
|
else()
|
||||||
set(use_lld OFF CACHE BOOL "try lld linker, clang only" FORCE)
|
set(use_lld OFF CACHE BOOL "try lld linker, clang only" FORCE)
|
||||||
|
|||||||
@@ -34,11 +34,12 @@ include(create_symbolic_link)
|
|||||||
# sometimes `PUBLIC` and sometimes `PRIVATE`.
|
# sometimes `PUBLIC` and sometimes `PRIVATE`.
|
||||||
# The Cs are all guaranteed to be unique.
|
# The Cs are all guaranteed to be unique.
|
||||||
# We can guarantee a unique X per target by using
|
# We can guarantee a unique X per target by using
|
||||||
# `${CMAKE_CURRENT_BINARY_DIR}/include/${target}`.
|
# `${CMAKE_CURRENT_BINARY_DIR}/modules/${target}`.
|
||||||
#
|
#
|
||||||
# isolate_headers(target A B scope)
|
# isolate_headers(target A B scope)
|
||||||
function(isolate_headers target A B scope)
|
function(isolate_headers target A B scope)
|
||||||
file(RELATIVE_PATH C "${A}" "${B}")
|
file(RELATIVE_PATH C "${A}" "${B}")
|
||||||
|
# Keep in sync with ExcludeHeaderFilterRegex in .clang-tidy.
|
||||||
set(X "${CMAKE_CURRENT_BINARY_DIR}/modules/${target}")
|
set(X "${CMAKE_CURRENT_BINARY_DIR}/modules/${target}")
|
||||||
set(Y "${X}/${C}")
|
set(Y "${X}/${C}")
|
||||||
cmake_path(GET Y PARENT_PATH parent)
|
cmake_path(GET Y PARENT_PATH parent)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
pcpp>=1.30
|
pcpp>=1.30
|
||||||
|
|
||||||
# Parser combinator library - used to parse the macro DSL
|
# Parser combinator library - used to parse the macro DSL
|
||||||
pyparsing>=3.0.0
|
pyparsing>=3.3.3
|
||||||
|
|
||||||
# Template engine - used to generate C++ code from templates
|
# Template engine - used to generate C++ code from templates
|
||||||
Mako>=1.2.2
|
Mako>=1.4.2
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
# This file was autogenerated by uv via the following command:
|
# This file was autogenerated by uv via the following command:
|
||||||
# uv pip compile requirements.in --generate-hashes --output-file requirements.txt
|
# uv pip compile requirements.in --generate-hashes --output-file requirements.txt
|
||||||
mako==1.3.12 \
|
mako==1.4.3 \
|
||||||
--hash=sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9 \
|
--hash=sha256:723296007c870bfd6b3f0c3230dba7198096e5269297ebf5e4eff9e7ffa39d4f \
|
||||||
--hash=sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a
|
--hash=sha256:cd6537fe88d5fec315c55c2f8529bc4ce7a9a352ad7db3eeaa6a66e2dd4ec37a
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
markupsafe==3.0.3 \
|
markupsafe==3.0.3 \
|
||||||
--hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \
|
--hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \
|
||||||
@@ -99,7 +99,7 @@ pcpp==1.30 \
|
|||||||
--hash=sha256:05fe08292b6da57f385001c891a87f40d6aa7f46787b03e8ba326d20a3297c6e \
|
--hash=sha256:05fe08292b6da57f385001c891a87f40d6aa7f46787b03e8ba326d20a3297c6e \
|
||||||
--hash=sha256:5af9fbce55f136d7931ae915fae03c34030a3b36c496e72d9636cedc8e2543a1
|
--hash=sha256:5af9fbce55f136d7931ae915fae03c34030a3b36c496e72d9636cedc8e2543a1
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
pyparsing==3.3.2 \
|
pyparsing==3.3.3 \
|
||||||
--hash=sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d \
|
--hash=sha256:928ae7e20211f3b6f3915a72f06a0cfd29ab9d24279dd6346b6b1a7146397d36 \
|
||||||
--hash=sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc
|
--hash=sha256:ece8c00a69cf01b45d0b1dedabb469c90d8caf996d4fda40f147627a122849a4
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
+7
-3
@@ -3,11 +3,11 @@
|
|||||||
"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.19#870b2d3abcfbbf13b61c2d3c69495060%1790348286.187549",
|
"xrpl-rpc-spec/0.1.29#852afc87cac32aca93cc50a985d73fe0%1792359643.19817",
|
||||||
"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",
|
||||||
"secp256k1/0.7.1#b1f450b7f78a36fff75bb6934a356f3a%1782338841.3729",
|
"secp256k1/0.7.1#f4d16a4d907dd057598954476ca6f88c%1792234329.790275",
|
||||||
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1782392413.075713",
|
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1782392413.075713",
|
||||||
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1782392402.431897",
|
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1782392402.431897",
|
||||||
"protobuf/6.33.5#ff253ead763bd8d9904a52979cd21e81%1782392410.233933",
|
"protobuf/6.33.5#ff253ead763bd8d9904a52979cd21e81%1782392410.233933",
|
||||||
@@ -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#b87796a4269034856cbc1a2522db16eb%1788275071.530512",
|
"grpc/1.81.1#aaa93ab6cda2f2baa6a84490582c8adf%1791284951.826256",
|
||||||
"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,11 +34,15 @@
|
|||||||
"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",
|
||||||
|
|||||||
+9
-1
@@ -3,5 +3,13 @@
|
|||||||
core:non_interactive=True
|
core:non_interactive=True
|
||||||
core.download:parallel={{ os.cpu_count() }}
|
core.download:parallel={{ os.cpu_count() }}
|
||||||
core.upload:parallel={{ os.cpu_count() }}
|
core.upload:parallel={{ os.cpu_count() }}
|
||||||
tools.files.download:retry=5
|
# Fall back to Conan Center's source backups when a recipe's upstream URL is down
|
||||||
|
# (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)
|
||||||
+31
-4
@@ -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++-15`) before plain `g++`. #}
|
{# and its fallback probes a version-suffixed binary (e.g. `g++-<major>`) before plain `g++`. #}
|
||||||
{# Inside the Nix shell the wrapper only provides `g++`/`gcc` (no `-15` suffix), #}
|
{# Inside the Nix shell the wrapper only provides `g++`/`gcc` (no `-<major>` suffix), #}
|
||||||
{# so on a host that also has a system `g++-15` the probe escapes Nix #}
|
{# so on a host that also has a system `g++-<major>` 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,8 +49,31 @@ 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 == "Macos" %}
|
{% 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]
|
[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" %}
|
||||||
{# 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. #}
|
||||||
@@ -58,3 +81,7 @@ tools.info.package_id:confs+=["user.package:cppstd_version"]
|
|||||||
{# 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,6 +5,9 @@ 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" %}
|
||||||
|
|||||||
+8
-3
@@ -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.19",
|
"xrpl-rpc-spec/0.1.29",
|
||||||
"zlib/1.3.2",
|
"zlib/1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -49,7 +49,8 @@ class Xrpl(ConanFile):
|
|||||||
]
|
]
|
||||||
|
|
||||||
tool_requires = [
|
tool_requires = [
|
||||||
"protobuf/6.33.5",
|
"grpc/<host_version>",
|
||||||
|
"protobuf/<host_version>",
|
||||||
]
|
]
|
||||||
|
|
||||||
default_options = {
|
default_options = {
|
||||||
@@ -123,6 +124,10 @@ 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
|
||||||
|
|
||||||
@@ -149,7 +154,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/default-loader-path.sh",
|
"bin/nix/default-loader-path.sh",
|
||||||
"CMakeLists.txt",
|
"CMakeLists.txt",
|
||||||
"cfg/*",
|
"cfg/*",
|
||||||
"cmake/*",
|
"cmake/*",
|
||||||
|
|||||||
@@ -80,13 +80,12 @@ 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(
|
corrosion_set_env_vars(${ARG_CRATE} "$<$<CONFIG:Debug>:CXXFLAGS=-MTd>")
|
||||||
${ARG_CRATE}
|
|
||||||
"$<$<CONFIG:Debug>:CXXFLAGS=-MTd>"
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
corrosion_add_cxxbridge(${name}_cxxbridge CRATE ${ARG_CRATE} FILES
|
corrosion_add_cxxbridge(
|
||||||
${ARG_FILES}
|
${name}_cxxbridge
|
||||||
|
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.202"
|
version = "1.0.205"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13f6de320895f42e6e081abb5c7983bedcf0b6d0ff9323de0d33f620c8ac1199"
|
checksum = "c8a02bfeba9074b2bbb39492c9b0908ec854f455a3cccdcde7a1de55e2315e40"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cxx-build",
|
"cxx-build",
|
||||||
@@ -72,9 +72,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-build"
|
name = "cxx-build"
|
||||||
version = "1.0.202"
|
version = "1.0.205"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fde53ca86b9704a943fef0f1e1d836239a6aedca5de3c65fa9f97ec0bd46d39"
|
checksum = "bbc2ac76997619d2d888b58ad79488f1c835de41ca4dd3dd7082acf4ecb0a50f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
@@ -87,9 +87,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-cmd"
|
name = "cxxbridge-cmd"
|
||||||
version = "1.0.202"
|
version = "1.0.205"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07bae89236c811fd4d08ed3441759ac4ac98d752cbfd3de341315ba16ad20ec3"
|
checksum = "54a486ed16a3f2a053fe7f5b98db4c1a59846a23e8cb9e49f9d1bd48830d51a2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
@@ -101,15 +101,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-flags"
|
name = "cxxbridge-flags"
|
||||||
version = "1.0.202"
|
version = "1.0.205"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49045042e5fced01b80742aba5508de82aa4f13677ed3fa2b4cda709c40c5918"
|
checksum = "c72569be94e2283764d334cd285980b747dbe221e27e315484eb6bcd93fa808a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-macro"
|
name = "cxxbridge-macro"
|
||||||
version = "1.0.202"
|
version = "1.0.205"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b181252e2e3d3b5d183afbdc033a3958b445eb3e1a0ae65fc3d4f5259f5da6fd"
|
checksum = "423e795284a7f7b3f843c956a5322c4bc497b60c2dd1a6339da10313cb18d575"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|||||||
Vendored
+38
-81
@@ -4,6 +4,18 @@ This document explains how to set one up.
|
|||||||
|
|
||||||
[BUILD.md]: ../../BUILD.md
|
[BUILD.md]: ../../BUILD.md
|
||||||
|
|
||||||
|
## Supported development platforms
|
||||||
|
|
||||||
|
- **Linux**: the [Nix development shell](./nix.md),
|
||||||
|
which provides the same toolchain CI uses on any distribution.
|
||||||
|
- **macOS** 15 (Sequoia) or newer: the [Nix development shell](./nix.md),
|
||||||
|
or the system [Apple Clang](#macos-apple-clang).
|
||||||
|
CI runs on macOS 26 (Tahoe), but the build defaults `CMAKE_OSX_DEPLOYMENT_TARGET` to 15.
|
||||||
|
- **Windows**: best effort, see [Windows](#windows).
|
||||||
|
|
||||||
|
For the platforms supported for running `xrpld`,
|
||||||
|
see [Requirements](../install.md#requirements).
|
||||||
|
|
||||||
## Tested compiler versions
|
## Tested compiler versions
|
||||||
|
|
||||||
`xrpld` is built in the **C++23** dialect by default, so your toolchain has to
|
`xrpld` is built in the **C++23** dialect by default, so your toolchain has to
|
||||||
@@ -11,13 +23,14 @@ 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 | 15.2 |
|
| GCC | `gccVersion` in [packages.nix] |
|
||||||
| Clang | 22 |
|
| Clang | `llvmVersion` in [packages.nix] |
|
||||||
| Apple Clang | 21 |
|
| Apple Clang | 21 |
|
||||||
| MSVC | Visual Studio 2026 |
|
| MSVC | Visual Studio 2026 |
|
||||||
|
|
||||||
LLVM tools (`clang-tidy` and `clang-format`) are also pinned to version 22.
|
LLVM tools (`clang-tidy` and `clang-format`)
|
||||||
|
come from the same LLVM release as Clang.
|
||||||
|
|
||||||
### Older compilers
|
### Older compilers
|
||||||
|
|
||||||
@@ -34,20 +47,16 @@ compiler building. Treat support for anything outside the table as best-effort.
|
|||||||
|
|
||||||
## Required tools
|
## Required tools
|
||||||
|
|
||||||
Besides a compiler, building `xrpld` requires:
|
Besides a compiler, building `xrpld` requires
|
||||||
|
[Git](https://git-scm.com/downloads),
|
||||||
| Tool | Minimum version |
|
[Python](https://www.python.org/downloads/),
|
||||||
| ------------------------------------------- | --------------- |
|
[Conan](https://conan.io/downloads.html),
|
||||||
| [Git](https://git-scm.com/downloads) | any recent |
|
and [CMake](https://cmake.org/download/).
|
||||||
| [Python](https://www.python.org/downloads/) | 3.11 |
|
Building with `-Drust=ON` additionally requires a Rust toolchain,
|
||||||
| [Conan](https://conan.io/downloads.html) | 2.17 |
|
see [Rust](#rust).
|
||||||
| [CMake](https://cmake.org/download/) | 3.16 |
|
|
||||||
|
|
||||||
On Linux and macOS, the [Nix development shell](./nix.md) provides all of them
|
On Linux and macOS, the [Nix development shell](./nix.md) provides all of them
|
||||||
(see below). On Windows they have to be installed manually.
|
at the versions CI uses, recorded in [`nix/check-tools/`](../../nix/check-tools).
|
||||||
|
|
||||||
Building with `-Drust=ON` additionally requires a Rust toolchain, see
|
|
||||||
[Rust](#rust). A default build does not, so it is not in the table above.
|
|
||||||
|
|
||||||
Once they are in place, verify that everything is installed and runnable with:
|
Once they are in place, verify that everything is installed and runnable with:
|
||||||
|
|
||||||
@@ -57,60 +66,19 @@ Once they are in place, verify that everything is installed and runnable with:
|
|||||||
|
|
||||||
## Linux and macOS
|
## Linux and macOS
|
||||||
|
|
||||||
The **recommended way** to get a development environment on Linux and macOS is
|
Use the [Nix development shell](./nix.md):
|
||||||
the Nix development shell. It provides the exact tooling used in CI — `git`,
|
it provides the compiler and every tool CI uses,
|
||||||
`python`, `conan`, `cmake`, `clang-tidy`, `clang-format`, and everything else —
|
without installing anything system-wide.
|
||||||
with a single command and without installing anything system-wide:
|
|
||||||
|
|
||||||
```bash
|
### macOS: Apple Clang
|
||||||
nix --experimental-features 'nix-command flakes' develop
|
|
||||||
```
|
|
||||||
|
|
||||||
On **Linux**, Nix also provides the compiler (GCC); on **macOS**, it provides
|
You can also build with the system Apple Clang,
|
||||||
Clang. If you instead opt to use your system-wide Apple Clang (via
|
installing the other [required tools](#required-tools) any way you like
|
||||||
`nix develop .#apple-clang`), you need to manage its version yourself (see
|
(or getting them from `nix develop .#apple-clang`).
|
||||||
below).
|
Its version is whatever your installed Xcode (or Command Line Tools) provides,
|
||||||
|
so check that `clang --version` is at least the [tested one](#tested-compiler-versions).
|
||||||
See [Using the Nix development shell](./nix.md) for installation and usage
|
If several Xcode versions are installed,
|
||||||
details, including how to select a different compiler and why we recommend Nix
|
select one with `sudo xcode-select -s <path>` or the `DEVELOPER_DIR` environment variable.
|
||||||
over a hand-maintained environment.
|
|
||||||
|
|
||||||
### macOS: managing the Apple Clang version
|
|
||||||
|
|
||||||
If you use your system-wide Apple Clang on macOS (via `nix develop .#apple-clang`),
|
|
||||||
the compiler version is whatever your installed Xcode (or Command Line Tools)
|
|
||||||
provides. The following command should return a version greater than or equal to
|
|
||||||
the [tested one](#tested-compiler-versions):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
clang --version
|
|
||||||
```
|
|
||||||
|
|
||||||
If you develop other applications using Xcode, you might be consistently
|
|
||||||
updating to the newest version of Apple Clang, which will likely cause issues
|
|
||||||
building xrpld. You may want to install and pin a specific version of Xcode:
|
|
||||||
|
|
||||||
1. **Download Xcode**
|
|
||||||
- Visit [Apple Developer Downloads](https://developer.apple.com/download/more/)
|
|
||||||
- Sign in with your Apple Developer account
|
|
||||||
- Search for an Xcode version that includes the expected Apple Clang version
|
|
||||||
- Download the `.xip` file
|
|
||||||
|
|
||||||
2. **Install and configure Xcode**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Extract the .xip file and rename for version management
|
|
||||||
# Example: Xcode_16.2.app
|
|
||||||
|
|
||||||
# Move to Applications directory
|
|
||||||
sudo mv Xcode_16.2.app /Applications/
|
|
||||||
|
|
||||||
# Set as default toolchain (persistent)
|
|
||||||
sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
|
|
||||||
|
|
||||||
# Set as environment variable (temporary)
|
|
||||||
export DEVELOPER_DIR=/Applications/Xcode_16.2.app/Contents/Developer
|
|
||||||
```
|
|
||||||
|
|
||||||
## Windows
|
## Windows
|
||||||
|
|
||||||
@@ -122,8 +90,7 @@ manually:
|
|||||||
"x64 Native Tools Command Prompt". CI configures CMake with the
|
"x64 Native Tools Command Prompt". CI configures CMake with the
|
||||||
`Visual Studio 18 2026` generator.
|
`Visual Studio 18 2026` generator.
|
||||||
- [Git for Windows](https://git-scm.com/download/win)
|
- [Git for Windows](https://git-scm.com/download/win)
|
||||||
- Python, Conan, and CMake, at the versions listed in
|
- recent releases of Python, Conan, and CMake
|
||||||
[Required tools](#required-tools).
|
|
||||||
- a [Rust toolchain](https://rustup.rs) — only needed to build with
|
- a [Rust toolchain](https://rustup.rs) — only needed to build with
|
||||||
`-Drust=ON`, see [Rust](#rust)
|
`-Drust=ON`, see [Rust](#rust)
|
||||||
|
|
||||||
@@ -144,15 +111,5 @@ version.
|
|||||||
Everything else the Rust build needs on the CMake side comes from Conan along
|
Everything else the Rust build needs on the CMake side comes from Conan along
|
||||||
with the rest of the dependencies, so there is nothing further to install.
|
with the rest of the dependencies, so there is nothing further to install.
|
||||||
|
|
||||||
## Clang-tidy
|
|
||||||
|
|
||||||
`clang-tidy` is required to run static analysis checks locally (see
|
|
||||||
[CONTRIBUTING.md](../../CONTRIBUTING.md)). It is not required to build the
|
|
||||||
project. The version this project uses is listed in
|
|
||||||
[Tested compiler versions](#tested-compiler-versions).
|
|
||||||
|
|
||||||
On Linux and macOS, the [Nix development shell](./nix.md) provides that exact
|
|
||||||
version out of the box — run it via `run-clang-tidy`. No separate installation
|
|
||||||
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
+23
-18
@@ -9,9 +9,7 @@ This guide explains how to use Nix to set up a reproducible development environm
|
|||||||
- **Reproducible environment**: Everyone gets the same versions of tools and compilers
|
- **Reproducible environment**: Everyone gets the same versions of tools and compilers
|
||||||
- **Matches CI**: The Linux CI runs in Docker images built from this exact Nix environment, and CI builds some macOS configurations in it as well
|
- **Matches CI**: The Linux CI runs in Docker images built from this exact Nix environment, and CI builds some macOS configurations in it as well
|
||||||
- **No system pollution**: Dependencies are isolated and don't affect your system packages
|
- **No system pollution**: Dependencies are isolated and don't affect your system packages
|
||||||
- **Consistent compilers**: The GCC and Clang shells use the same versions as CI
|
|
||||||
- **Quick setup**: Get started with a single command
|
- **Quick setup**: Get started with a single command
|
||||||
- **Works on Linux and macOS**: Consistent experience across platforms
|
|
||||||
|
|
||||||
## Install Nix
|
## Install Nix
|
||||||
|
|
||||||
@@ -27,13 +25,8 @@ From the root of the xrpld repository, enter the default development shell:
|
|||||||
nix --experimental-features 'nix-command flakes' develop
|
nix --experimental-features 'nix-command flakes' develop
|
||||||
```
|
```
|
||||||
|
|
||||||
This will:
|
This downloads and sets up all required development tools (CMake, Ninja, Conan, etc.)
|
||||||
|
and the compiler for your platform (see [Platform notes](#platform-notes)).
|
||||||
- Download and set up all required development tools (CMake, Ninja, Conan, etc.)
|
|
||||||
- Configure the appropriate compiler for your platform:
|
|
||||||
- **Linux**: GCC (provided by Nix)
|
|
||||||
- **macOS**: Clang (provided by Nix)
|
|
||||||
|
|
||||||
The first time you run this command, it will take a few minutes to download and build the environment. Subsequent runs will be much faster.
|
The first time you run this command, it will take a few minutes to download and build the environment. Subsequent runs will be much faster.
|
||||||
|
|
||||||
### Platform notes
|
### Platform notes
|
||||||
@@ -183,24 +176,36 @@ 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/check-nix-store-refs.sh`](../../bin/check-nix-store-refs.sh) takes one file
|
[`bin/nix/check-nix-store-refs.sh`](../../bin/nix/check-nix-store-refs.sh) takes one
|
||||||
or directory and fails if a binary under it resolves a store path at run time.
|
file 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/check-nix-store-refs.sh build
|
bin/nix/check-nix-store-refs.sh build
|
||||||
bin/check-nix-store-refs.sh ~/.conan2-nix
|
bin/nix/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`, and CI builds inside an image
|
writes the store into `PT_INTERP` and `RUNPATH`. That is fine for the pinned
|
||||||
whose store is fixed for its lifetime, so that is fine. Only the binaries
|
glibc, whose path does not move, but not for the GCC runtime, which moves with
|
||||||
[`PatchNixBinary.cmake`](../../cmake/PatchNixBinary.cmake) retargets to the
|
every GCC update. So [`conan/profiles/default`](../../conan/profiles/default)
|
||||||
system loader have to be clean, and those are what CI checks:
|
links build-context packages, whose executables run during the build, with
|
||||||
|
`-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/check-nix-store-refs.sh build/xrpld
|
bin/nix/check-build-context-runtime.sh graph.json
|
||||||
|
```
|
||||||
|
|
||||||
|
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/check-nix-store-refs.sh`](../../bin/check-nix-store-refs.sh) finds the same
|
[`bin/nix/check-nix-store-refs.sh`](../../bin/nix/check-nix-store-refs.sh) finds the
|
||||||
thing without having to run anything, and names the file:
|
same thing without having to run anything, and names the file:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ bin/check-nix-store-refs.sh ~/.conan2-nix
|
$ bin/nix/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
|
||||||
|
|||||||
@@ -10,6 +10,19 @@ and DNF on Red Hat-based distributions such as RHEL, AlmaLinux, and Rocky Linux,
|
|||||||
where `yum` is a symlink to `dnf`.
|
where `yum` is a symlink to `dnf`.
|
||||||
To build from source instead, see [BUILD.md](../BUILD.md).
|
To build from source instead, see [BUILD.md](../BUILD.md).
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Linux is the only operating system officially supported for running `xrpld`;
|
||||||
|
macOS and Windows builds are for development only.
|
||||||
|
|
||||||
|
Any x86-64 Linux distribution with APT or DNF and glibc 2.31 or newer should work
|
||||||
|
(see [How libc is handled](../nix/docker/README.md#how-libc-is-handled)).
|
||||||
|
CI tests the packages on Debian 11–13, Ubuntu 20.04–26.04,
|
||||||
|
RHEL (UBI) 9–10, AlmaLinux 9–10, and Rocky Linux 9–10.
|
||||||
|
|
||||||
|
For the hardware needed to run a node,
|
||||||
|
see [System Requirements](https://xrpl.org/system-requirements.html).
|
||||||
|
|
||||||
## Release channels
|
## Release channels
|
||||||
|
|
||||||
Packages are published to four channels:
|
Packages are published to four channels:
|
||||||
|
|||||||
+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 INTERFACE
|
target_include_directories(antithesis-sdk-cpp SYSTEM 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": 1781173989,
|
"lastModified": 1791130267,
|
||||||
"narHash": "sha256-fnzKKPvS+oieI/pTzotA5tkoM47EB1NpaBcgk4R97hE=",
|
"narHash": "sha256-1sjwcQMcgAbmiip/VivBSiK8p2bTkQGOvCuO7vnwfx4=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "8c91a71d13451abc40eb9dae8910f972f979852f",
|
"rev": "9013764fcc0ea99fa16cf7aa7decf8a5c3889dd2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -47,11 +47,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1784611586,
|
"lastModified": 1791189933,
|
||||||
"narHash": "sha256-OfqgY+0hp/zseZB7uyH0U8kIDPS4scZZCyAurEplvG0=",
|
"narHash": "sha256-Y8eN7ki0Urx4Ojf4w1xSpWg8uk/3lJqK+E0Oth77rH0=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "14f58845249f3552a89b07772626b8d3c632fa86",
|
"rev": "e60029353d0c48d216bc4b065168ccd4079c166f",
|
||||||
"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 compressedSize = LZ4_compress_default(
|
auto const 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,12 +20,14 @@ 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;
|
||||||
}()}
|
}(),
|
||||||
|
}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,12 +35,14 @@ 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;
|
||||||
}()}
|
}(),
|
||||||
|
}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,12 +144,14 @@ 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;
|
||||||
}()}
|
}(),
|
||||||
|
}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,12 +165,14 @@ 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;
|
||||||
}()}
|
}(),
|
||||||
|
}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +268,7 @@ SharedIntrusive<T>::unsafeReleaseAndStore(T* next)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
using enum ReleaseStrongRefAction;
|
using enum ReleaseStrongRefAction;
|
||||||
auto action = prev->releaseStrongRef();
|
auto const action = prev->releaseStrongRef();
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case NoOp:
|
case NoOp:
|
||||||
@@ -361,7 +369,7 @@ WeakIntrusive<T>::unsafeReleaseNoStore()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
using enum ReleaseWeakRefAction;
|
using enum ReleaseWeakRefAction;
|
||||||
auto action = ptr_->releaseWeakRef();
|
auto const action = ptr_->releaseWeakRef();
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case NoOp:
|
case NoOp:
|
||||||
@@ -580,7 +588,7 @@ SharedWeakUnion<T>::convertToStrong()
|
|||||||
auto p = unsafeGetRawPtr();
|
auto p = unsafeGetRawPtr();
|
||||||
if (p && p->checkoutStrongRefFromWeak())
|
if (p && p->checkoutStrongRefFromWeak())
|
||||||
{
|
{
|
||||||
[[maybe_unused]] auto action = p->releaseWeakRef();
|
[[maybe_unused]] auto const action = p->releaseWeakRef();
|
||||||
XRPL_ASSERT(
|
XRPL_ASSERT(
|
||||||
(action == ReleaseWeakRefAction::NoOp),
|
(action == ReleaseWeakRefAction::NoOp),
|
||||||
"xrpl::SharedWeakUnion::convertToStrong : "
|
"xrpl::SharedWeakUnion::convertToStrong : "
|
||||||
@@ -603,7 +611,7 @@ SharedWeakUnion<T>::convertToWeak()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
using enum ReleaseStrongRefAction;
|
using enum ReleaseStrongRefAction;
|
||||||
auto action = p->addWeakReleaseStrongRef();
|
auto const action = p->addWeakReleaseStrongRef();
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case NoOp:
|
case NoOp:
|
||||||
@@ -670,7 +678,7 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
|
|||||||
if (isStrong())
|
if (isStrong())
|
||||||
{
|
{
|
||||||
using enum ReleaseStrongRefAction;
|
using enum ReleaseStrongRefAction;
|
||||||
auto strongAction = p->releaseStrongRef();
|
auto const strongAction = p->releaseStrongRef();
|
||||||
switch (strongAction)
|
switch (strongAction)
|
||||||
{
|
{
|
||||||
case NoOp:
|
case NoOp:
|
||||||
@@ -688,7 +696,7 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
using enum ReleaseWeakRefAction;
|
using enum ReleaseWeakRefAction;
|
||||||
auto weakAction = p->releaseWeakRef();
|
auto const 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 v = refCounts_.load(std::memory_order_acquire);
|
auto const 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 t = v & kTagMask;
|
auto const 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,9 +3,156 @@
|
|||||||
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply two signed 64-bit integers, returning std::nullopt when the exact
|
||||||
|
* mathematical product is not representable in std::int64_t.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] constexpr std::optional<std::int64_t>
|
||||||
|
checkedMul(std::int64_t a, std::int64_t b) noexcept
|
||||||
|
{
|
||||||
|
using L = std::numeric_limits<std::int64_t>;
|
||||||
|
|
||||||
|
if (a == 0 || b == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (a > 0)
|
||||||
|
{
|
||||||
|
if (b > 0 ? a > L::max() / b : b < L::min() / a)
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
else if (b > 0 ? a < L::min() / b : b < L::max() / a)
|
||||||
|
{
|
||||||
|
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());
|
||||||
|
|
||||||
|
static_assert(checkedMul(0, std::numeric_limits<std::int64_t>::min()) == 0);
|
||||||
|
static_assert(checkedMul(std::numeric_limits<std::int64_t>::min(), 0) == 0);
|
||||||
|
static_assert(checkedMul(-1, -1) == 1);
|
||||||
|
// a > 0, b > 0
|
||||||
|
static_assert(
|
||||||
|
checkedMul(std::numeric_limits<std::int64_t>::max(), 1) ==
|
||||||
|
std::numeric_limits<std::int64_t>::max());
|
||||||
|
static_assert(
|
||||||
|
checkedMul(std::numeric_limits<std::int64_t>::max() / 2, 2) ==
|
||||||
|
std::numeric_limits<std::int64_t>::max() - 1);
|
||||||
|
static_assert(!checkedMul((std::numeric_limits<std::int64_t>::max() / 2) + 1, 2).has_value());
|
||||||
|
static_assert(!checkedMul(2, (std::numeric_limits<std::int64_t>::max() / 2) + 1).has_value());
|
||||||
|
// a > 0, b < 0
|
||||||
|
static_assert(
|
||||||
|
checkedMul(std::numeric_limits<std::int64_t>::max(), -1) ==
|
||||||
|
-std::numeric_limits<std::int64_t>::max());
|
||||||
|
static_assert(
|
||||||
|
checkedMul((std::numeric_limits<std::int64_t>::max() / 2) + 1, -2) ==
|
||||||
|
std::numeric_limits<std::int64_t>::min());
|
||||||
|
static_assert(!checkedMul((std::numeric_limits<std::int64_t>::max() / 2) + 2, -2).has_value());
|
||||||
|
static_assert(
|
||||||
|
checkedMul(1, std::numeric_limits<std::int64_t>::min()) ==
|
||||||
|
std::numeric_limits<std::int64_t>::min());
|
||||||
|
static_assert(
|
||||||
|
checkedMul(2, std::numeric_limits<std::int64_t>::min() / 2) ==
|
||||||
|
std::numeric_limits<std::int64_t>::min());
|
||||||
|
static_assert(!checkedMul(2, (std::numeric_limits<std::int64_t>::min() / 2) - 1).has_value());
|
||||||
|
// a < 0, b > 0
|
||||||
|
static_assert(
|
||||||
|
checkedMul(std::numeric_limits<std::int64_t>::min(), 1) ==
|
||||||
|
std::numeric_limits<std::int64_t>::min());
|
||||||
|
static_assert(
|
||||||
|
checkedMul(std::numeric_limits<std::int64_t>::min() / 2, 2) ==
|
||||||
|
std::numeric_limits<std::int64_t>::min());
|
||||||
|
static_assert(!checkedMul((std::numeric_limits<std::int64_t>::min() / 2) - 1, 2).has_value());
|
||||||
|
static_assert(!checkedMul(std::numeric_limits<std::int64_t>::min(), 2).has_value());
|
||||||
|
// a < 0, b < 0
|
||||||
|
static_assert(
|
||||||
|
checkedMul(-(std::numeric_limits<std::int64_t>::max() / 2), -2) ==
|
||||||
|
std::numeric_limits<std::int64_t>::max() - 1);
|
||||||
|
static_assert(!checkedMul(std::numeric_limits<std::int64_t>::min() / 2, -2).has_value());
|
||||||
|
static_assert(
|
||||||
|
checkedMul(-1, -std::numeric_limits<std::int64_t>::max()) ==
|
||||||
|
std::numeric_limits<std::int64_t>::max());
|
||||||
|
static_assert(!checkedMul(std::numeric_limits<std::int64_t>::min(), -1).has_value());
|
||||||
|
static_assert(!checkedMul(-1, std::numeric_limits<std::int64_t>::min()).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]
|
||||||
|
|||||||
@@ -352,9 +352,9 @@ class Number final
|
|||||||
using rep = std::int64_t;
|
using rep = std::int64_t;
|
||||||
using InternalRep = MantissaRange::rep;
|
using InternalRep = MantissaRange::rep;
|
||||||
|
|
||||||
bool negative_{false};
|
|
||||||
InternalRep mantissa_{0};
|
InternalRep mantissa_{0};
|
||||||
int exponent_{std::numeric_limits<int>::lowest()};
|
int exponent_{std::numeric_limits<int>::lowest()};
|
||||||
|
bool negative_{false};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// The range for the exponent when normalized
|
// The range for the exponent when normalized
|
||||||
@@ -650,8 +650,12 @@ private:
|
|||||||
shiftExponent(int exponentDelta) const;
|
shiftExponent(int exponentDelta) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The number class currently has 3 tail padding bytes. If you are adding new
|
||||||
|
// members, try to fit them there before expanding the size of the class.
|
||||||
|
static_assert(sizeof(Number) == 16);
|
||||||
|
|
||||||
constexpr Number::Number(bool negative, InternalRep mantissa, int exponent, Unchecked) noexcept
|
constexpr Number::Number(bool negative, InternalRep mantissa, int exponent, Unchecked) noexcept
|
||||||
: negative_(negative), mantissa_{mantissa}, exponent_{exponent}
|
: mantissa_{mantissa}, exponent_{exponent}, negative_(negative)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ public:
|
|||||||
|
|
||||||
for (auto const& c : cfg)
|
for (auto const& c : cfg)
|
||||||
{
|
{
|
||||||
auto& a = allocators_.emplace_back(c.extra_, c.alloc_, c.align_);
|
auto const& 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)
|
||||||
|
|||||||
@@ -153,6 +153,24 @@ private:
|
|||||||
Policy policy,
|
Policy policy,
|
||||||
Callback&& replaceCallback = nullptr);
|
Callback&& replaceCallback = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* canonicalizeImpl variant for callers that already hold `mutex_`.
|
||||||
|
*
|
||||||
|
* The unnamed `scoped_lock<MutexType> const&` parameter is proof of
|
||||||
|
* ownership; this overload does not acquire the lock. Use it from other
|
||||||
|
* methods (e.g. fetchAndModify) that need to compose canonicalize with
|
||||||
|
* additional work under a single critical section, without relying on
|
||||||
|
* recursive-mutex re-entry.
|
||||||
|
*/
|
||||||
|
template <class Policy, class Callback = std::nullptr_t>
|
||||||
|
bool
|
||||||
|
canonicalizeImpl(
|
||||||
|
std::scoped_lock<MutexType> const&,
|
||||||
|
key_type const& key,
|
||||||
|
CanonicalizeClientPointerType<Policy> data,
|
||||||
|
Policy policy,
|
||||||
|
Callback&& replaceCallback = nullptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Replace aliased objects with originals.
|
* Replace aliased objects with originals.
|
||||||
@@ -239,9 +257,6 @@ public:
|
|||||||
bool
|
bool
|
||||||
retrieve(key_type const& key, T& data);
|
retrieve(key_type const& key, T& data);
|
||||||
|
|
||||||
MutexType&
|
|
||||||
peekMutex();
|
|
||||||
|
|
||||||
std::vector<key_type>
|
std::vector<key_type>
|
||||||
getKeys() const;
|
getKeys() const;
|
||||||
|
|
||||||
@@ -263,6 +278,22 @@ public:
|
|||||||
fetch(key_type const& digest, Handler const& h);
|
fetch(key_type const& digest, Handler const& h);
|
||||||
// End CachedSLEs functions.
|
// End CachedSLEs functions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch or create an entry and execute a callback while holding the lock.
|
||||||
|
*
|
||||||
|
* The entry for the given key is fetched from the cache or created if it
|
||||||
|
* doesn't exist. The callback is then invoked with a reference to the
|
||||||
|
* entry while the cache mutex is still held, allowing safe modification
|
||||||
|
* of the cached object.
|
||||||
|
*
|
||||||
|
* @param key The key to fetch or create
|
||||||
|
* @param callback Function to call with the entry under lock.
|
||||||
|
* Signature: void(T&)
|
||||||
|
*/
|
||||||
|
template <class Callback>
|
||||||
|
void
|
||||||
|
fetchAndModify(key_type const& key, Callback&& callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SharedPointerType
|
SharedPointerType
|
||||||
initialFetch(key_type const& key, std::scoped_lock<MutexType> const& l);
|
initialFetch(key_type const& key, std::scoped_lock<MutexType> const& l);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <xrpl/basics/Log.h> // IWYU pragma: keep
|
#include <xrpl/basics/Log.h> // IWYU pragma: keep
|
||||||
#include <xrpl/basics/TaggedCache.h>
|
#include <xrpl/basics/TaggedCache.h>
|
||||||
#include <xrpl/basics/scope.h>
|
#include <xrpl/basics/scope.h>
|
||||||
|
#include <xrpl/beast/utility/instrumentation.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@@ -300,7 +301,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 cit = cache_.find(key);
|
auto const cit = cache_.find(key);
|
||||||
|
|
||||||
if (cit == cache_.end())
|
if (cit == cache_.end())
|
||||||
return false;
|
return false;
|
||||||
@@ -335,6 +336,29 @@ template <class Policy, class Callback>
|
|||||||
inline bool
|
inline bool
|
||||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||||
canonicalizeImpl(
|
canonicalizeImpl(
|
||||||
|
key_type const& key,
|
||||||
|
CanonicalizeClientPointerType<Policy> data,
|
||||||
|
Policy policy,
|
||||||
|
Callback&& replaceCallback)
|
||||||
|
{
|
||||||
|
std::scoped_lock<MutexType> const lock(mutex_);
|
||||||
|
return canonicalizeImpl(lock, key, data, policy, std::forward<Callback>(replaceCallback));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Key,
|
||||||
|
class T,
|
||||||
|
bool IsKeyCache,
|
||||||
|
class SharedWeakUnionPointer,
|
||||||
|
class SharedPointerType,
|
||||||
|
class Hash,
|
||||||
|
class KeyEqual,
|
||||||
|
class Mutex>
|
||||||
|
template <class Policy, class Callback>
|
||||||
|
inline bool
|
||||||
|
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||||
|
canonicalizeImpl(
|
||||||
|
std::scoped_lock<MutexType> const&,
|
||||||
key_type const& key,
|
key_type const& key,
|
||||||
CanonicalizeClientPointerType<Policy> data,
|
CanonicalizeClientPointerType<Policy> data,
|
||||||
[[maybe_unused]] Policy policy,
|
[[maybe_unused]] Policy policy,
|
||||||
@@ -354,9 +378,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
// passing a const argument is a compile error.
|
// passing a const argument is a compile error.
|
||||||
constexpr bool replaceCached = std::is_same_v<Policy, detail::ReplaceCached>;
|
constexpr bool replaceCached = std::is_same_v<Policy, detail::ReplaceCached>;
|
||||||
|
|
||||||
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 +393,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 shouldReplaceCached = [&] {
|
auto const shouldReplaceCached = [&] {
|
||||||
if constexpr (replaceCached)
|
if constexpr (replaceCached)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -400,7 +422,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cachedData = entry.lock();
|
auto const cachedData = entry.lock();
|
||||||
|
|
||||||
if (cachedData)
|
if (cachedData)
|
||||||
{
|
{
|
||||||
@@ -563,7 +585,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 entry = fetch(key);
|
auto const entry = fetch(key);
|
||||||
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return false;
|
return false;
|
||||||
@@ -572,22 +594,6 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
|
||||||
class Key,
|
|
||||||
class T,
|
|
||||||
bool IsKeyCache,
|
|
||||||
class SharedWeakUnionPointer,
|
|
||||||
class SharedPointerType,
|
|
||||||
class Hash,
|
|
||||||
class KeyEqual,
|
|
||||||
class Mutex>
|
|
||||||
inline auto
|
|
||||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
|
||||||
peekMutex() -> MutexType&
|
|
||||||
{
|
|
||||||
return mutex_;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class Key,
|
class Key,
|
||||||
class T,
|
class T,
|
||||||
@@ -687,7 +693,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sle = h();
|
auto const sle = h();
|
||||||
if (!sle)
|
if (!sle)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
@@ -700,6 +706,49 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
}
|
}
|
||||||
// End CachedSLEs functions.
|
// End CachedSLEs functions.
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Key,
|
||||||
|
class T,
|
||||||
|
bool IsKeyCache,
|
||||||
|
class SharedWeakUnionPointer,
|
||||||
|
class SharedPointerType,
|
||||||
|
class Hash,
|
||||||
|
class KeyEqual,
|
||||||
|
class Mutex>
|
||||||
|
template <class Callback>
|
||||||
|
inline void
|
||||||
|
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||||
|
fetchAndModify(key_type const& key, Callback&& callback)
|
||||||
|
{
|
||||||
|
static_assert(
|
||||||
|
!IsKeyCache, "fetchAndModify is only supported for value caches, not key-only caches");
|
||||||
|
static_assert(
|
||||||
|
std::is_same_v<std::shared_ptr<T>, SharedPointerType> ||
|
||||||
|
std::is_same_v<intr_ptr::SharedPtr<T>, SharedPointerType>,
|
||||||
|
"fetchAndModify requires std::shared_ptr<T> or intr_ptr::SharedPtr<T>");
|
||||||
|
|
||||||
|
std::scoped_lock<MutexType> const lock(mutex_);
|
||||||
|
|
||||||
|
// Same pointer-type dispatch as insert(): the placeholder must have exactly
|
||||||
|
// SharedPointerType so canonicalizeImpl can write the cached pointer back.
|
||||||
|
SharedPointerType entry = [] {
|
||||||
|
if constexpr (std::is_same_v<std::shared_ptr<T>, SharedPointerType>)
|
||||||
|
{
|
||||||
|
return std::make_shared<T>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return intr_ptr::makeShared<T>();
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
canonicalizeImpl(lock, key, entry, detail::ReplaceClient{});
|
||||||
|
|
||||||
|
ALWAYS(
|
||||||
|
entry != nullptr, "xrpl::TaggedCache::fetchAndModify : entry present after canonicalize");
|
||||||
|
|
||||||
|
callback(*entry);
|
||||||
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class Key,
|
class Key,
|
||||||
class T,
|
class T,
|
||||||
@@ -713,7 +762,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 cit = cache_.find(key);
|
auto const cit = cache_.find(key);
|
||||||
if (cit == cache_.end())
|
if (cit == cache_.end())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
@@ -783,7 +832,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 +912,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,7 +195,8 @@ 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 hexCharToUInt = [](char c, std::uint32_t shift, std::uint32_t& accum) -> ParseResult {
|
auto const hexCharToUInt =
|
||||||
|
[](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;
|
||||||
@@ -453,7 +454,7 @@ public:
|
|||||||
{
|
{
|
||||||
for (int i = kWidth - 1; i >= 0; --i)
|
for (int i = kWidth - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
auto prev = data_[i];
|
auto const 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>
|
||||||
static std::size_t
|
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& p : map_)
|
for (auto const& 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 otherIter(other.find(extract(*iter)));
|
auto const 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 ret = std::from_chars(first, last, out);
|
auto const 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(void)>;
|
using HandlerType = std::function<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 first(begin(s));
|
auto const 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>
|
||||||
static std::string
|
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(void)> b = [f = std::forward<F>(f),
|
std::function<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(void)> f)
|
run(std::function<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 p = parsePreamble(s, ec);
|
auto const 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 stat = getIfExists(section, name, intVal);
|
auto const stat = getIfExists(section, name, intVal);
|
||||||
if (stat)
|
if (stat)
|
||||||
v = bool(intVal);
|
v = bool(intVal);
|
||||||
return stat;
|
return stat;
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ struct Keys
|
|||||||
static constexpr auto kBbtOptions = "bbt_options";
|
static constexpr auto kBbtOptions = "bbt_options";
|
||||||
static constexpr auto kBgThreads = "bg_threads";
|
static constexpr auto kBgThreads = "bg_threads";
|
||||||
static constexpr auto kBlockSize = "block_size";
|
static constexpr auto kBlockSize = "block_size";
|
||||||
|
static constexpr auto kBytecodeSizeLimit = "bytecode_size_limit";
|
||||||
static constexpr auto kCacheAge = "cache_age";
|
static constexpr auto kCacheAge = "cache_age";
|
||||||
static constexpr auto kCacheMb = "cache_mb";
|
static constexpr auto kCacheMb = "cache_mb";
|
||||||
static constexpr auto kCacheSize = "cache_size";
|
static constexpr auto kCacheSize = "cache_size";
|
||||||
@@ -108,6 +109,8 @@ struct Keys
|
|||||||
static constexpr auto kFileSizeMult = "file_size_mult";
|
static constexpr auto kFileSizeMult = "file_size_mult";
|
||||||
static constexpr auto kFilterBits = "filter_bits";
|
static constexpr auto kFilterBits = "filter_bits";
|
||||||
static constexpr auto kFilterFull = "filter_full";
|
static constexpr auto kFilterFull = "filter_full";
|
||||||
|
static constexpr auto kGasLimit = "gas_limit";
|
||||||
|
static constexpr auto kGasPrice = "gas_price";
|
||||||
static constexpr auto kHardSet = "hard_set";
|
static constexpr auto kHardSet = "hard_set";
|
||||||
static constexpr auto kHighThreads = "high_threads";
|
static constexpr auto kHighThreads = "high_threads";
|
||||||
static constexpr auto kHoldTime = "hold_time";
|
static constexpr auto kHoldTime = "hold_time";
|
||||||
|
|||||||
@@ -93,14 +93,14 @@ public:
|
|||||||
void
|
void
|
||||||
check(std::vector<TxID> accepted, Predicate&& pred)
|
check(std::vector<TxID> accepted, Predicate&& pred)
|
||||||
{
|
{
|
||||||
auto acceptTxid = accepted.begin();
|
auto const 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 i = removeIfIntersectOrMatch(
|
auto const 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 peerPosIt = currPeerPositions_.find(peerID);
|
auto const 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 netLgr = adaptor_.getPrevLedger(prevLedgerID_, previousLedger_, mode_.get());
|
auto const 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 proposersClosed = currPeerPositions_.size();
|
auto const proposersClosed = currPeerPositions_.size();
|
||||||
auto proposersValidated = adaptor_.proposersValidated(prevLedgerID_);
|
auto const 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 ourPosition = result_->position.position();
|
auto const 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 currentFinished = adaptor_.proposersFinished(previousLedger_, prevLedgerID_);
|
auto const 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 differences = result_->txns.compare(o);
|
auto const 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 txID = tx.id();
|
auto const txID = tx.id();
|
||||||
|
|
||||||
if (result_->disputes.find(txID) != result_->disputes.end())
|
if (result_->disputes.find(txID) != result_->disputes.end())
|
||||||
continue;
|
continue;
|
||||||
@@ -1837,7 +1837,8 @@ 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,18 +145,26 @@ 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,
|
{
|
||||||
{.consensusTime = 0, .consensusPct = 50, .next = AvalancheState::Mid}},
|
AvalancheState::Init,
|
||||||
|
{.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,
|
{
|
||||||
{.consensusTime = 50, .consensusPct = 65, .next = AvalancheState::Late}},
|
AvalancheState::Mid,
|
||||||
|
{.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,
|
{
|
||||||
{.consensusTime = 85, .consensusPct = 70, .next = AvalancheState::Stuck}},
|
AvalancheState::Late,
|
||||||
|
{.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,
|
{
|
||||||
{.consensusTime = 200, .consensusPct = 95, .next = AvalancheState::Stuck}},
|
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 step = [&](time_point t, std::int64_t w) {
|
auto const 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 it = votes_.find(peer);
|
auto const 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 it = std::ranges::find_if(
|
auto const 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 it = acquiring_.find(std::make_pair(val.seq(), val.ledgerID()));
|
auto const 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 it = lastLedger_.find(nodeID);
|
auto const 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 it = acquiring_.find(*prior);
|
auto const 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 it = acquiring_.find(valPair);
|
auto const 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 cit = typename decltype(current_)::const_iterator{it};
|
auto const 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 it = byLedger_.find(ledgerID);
|
auto const 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 it = std::ranges::max_element(acquiring_, [](auto const& a, auto const& b) {
|
auto const 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 it = std::ranges::max_element(peerCounts, [](auto const& a, auto const& b) {
|
auto const 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 stream = j.error())
|
if (auto const 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
|
||||||
Loaded 100 of 979 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user