Compare commits

...
Author SHA1 Message Date
Ed Hennis a7add7ce15 Merge remote-tracking branch 'XRPLF/develop' into ximinez/acquireAsyncDispatch
* XRPLF/develop: (22 commits)
  chore: Bump version to 3.4.1 and make pkg_release 2
  build: Reduce number of conan logs (8548)
  chore: Fix readability-redundant-lambda-parameter-list (8544)
  fix: Reject Batch inner txs with the wrong wrapper (fixBatchV1_2)
  ci: Update Nexus packaging URL
  fix: Assorted integer-arithmetic hardening in the payment engine and ledger helpers
  fix: Change mpt subscription msg type back to `transaction` (8539)
  chore: Update clang-tidy image to v23 (8536)
  feat: Integrate Permissioned Domain & Credential Checks for Lending Protocol (6517)
  refactor: Group binaries in subdirectories (8535)
  chore: Split multiple-in-one into individual tests (8025)
  refactor: Migrate handlers to rpc-spec (B) (8484)
  build: Use images with Clang 23 except for clang-tidy (8530)
  chore: Update pre-commit hooks and image (8528)
  fix: Fix MPT partial payment overflow (8302)
  build: Use LLVM 23 (8522)
  refactor: Extract escrow lock helpers and paychan test helpers (7882)
  fix: Validate vetoed parameter type in feature RPC (7583)
  refactor: Use CheckEntry everywhere (8349)
  build: Make conan retry with Conan Center's source backups (8524)
  ...
2026-10-09 20:16:11 -04:00
Ayaz Salikhov 6d6ab2d067 Merge remote-tracking branch 'upstream/release/3.4.x' into develop 2026-10-10 00:20:39 +01:00
Ayaz Salikhov 00e6407514 chore: Bump version to 3.4.1 and make pkg_release 2 2026-10-09 23:50:58 +01:00
Ayaz Salikhov 00c06edffb Merge remote-tracking branch 'upstream/release/3.4.x' into develop 2026-10-09 22:45:18 +01:00
Ayaz Salikhov de5053ae0d build: Reduce number of conan logs (#8548) 2026-10-09 16:33:41 +00:00
Ayaz Salikhov 1940ec5c2a chore: Fix readability-redundant-lambda-parameter-list (#8544) 2026-10-09 16:20:45 +00:00
Denis Angell 19c94c73f4 fix: Reject Batch inner txs with the wrong wrapper (fixBatchV1_2) 2026-10-09 16:04:36 +01:00
Bart cd005ff60d ci: Update Nexus packaging URL 2026-10-09 16:04:36 +01:00
Gregory Tsipenyuk 578224f2e6 fix: Assorted integer-arithmetic hardening in the payment engine and ledger helpers 2026-10-09 16:04:35 +01:00
Shawn Xie 3857ce21cd fix: Change mpt subscription msg type back to transaction (#8539) 2026-10-09 13:33:13 +00:00
Ayaz Salikhov aa490df46b chore: Update clang-tidy image to v23 (#8536) 2026-10-09 10:19:07 +00:00
88c1f1e7ac feat: Integrate Permissioned Domain & Credential Checks for Lending Protocol (#6517)
Signed-off-by: JCW <[email protected]>
Co-authored-by: Vito <[email protected]>
Co-authored-by: Ed Hennis <[email protected]>
2026-10-09 10:18:31 +00:00
Ayaz SalikhovandCopilot Autofix powered by AI ede8af8191 refactor: Group binaries in subdirectories (#8535)
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-10-08 12:34:06 +00:00
Alex Kremer 3c24b605a1 chore: Split multiple-in-one into individual tests (#8025) 2026-10-08 09:57:38 +00:00
Ed Hennis 1a1924dd30 Merge remote-tracking branch 'XRPLF/develop' into ximinez/acquireAsyncDispatch
* XRPLF/develop: (281 commits)
  refactor: Use NegativeUNLEntry everywhere (8365)
  build: Make clang-tools custom in Nix, to match what's being built (8521)
  refactor: Migrate handlers to rpc-spec (A) (8345)
  test: Declare, not define, entry instantiations in SLEBase test (8357)
  test: Add more tests for granular permissions (8459)
  fix: Enforce that MPT issuance flags are never cleared (8152)
  feat: Allow lending transactions in Batch (8244)
  feat: Add full support for all objects in `ledger_entry` (6319)
  build: Define XRPL_ASAN, XRPL_TSAN, and XRPL_UBSAN compile definitions (8483)
  refactor: Use LedgerHashesEntry everywhere (8369)
  refactor: Use EscrowEntry everywhere (8354)
  chore: Update nix flake file (8479)
  refactor: Use FeeSettingsEntry everywhere (8370)
  fix: Add string type validation for channel_id and signature (7582)
  test: Migrate three beast suites from beast::unit_test to gtest (7993)
  refactor: Build Throw messages with std::format (8474)
  feat: Implement Confidential mpt holder key update (8266)
  fix: Do not block MPToken deletion on unrelated confidential balances (8209)
  fix: Enable the large Number mantissa with MPTokensV2 (8330)
  chore: Add ignore revs for recent style changes (8463)
  ...
2026-10-06 18:52:40 -04:00
Ed Hennis 99859d2458 Fix doxygen style issue 2026-08-05 22:54:41 -04:00
Ed Hennis 7642bc6671 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-08-05 12:17:07 -04:00
Ed Hennis add33d853c Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-07-14 20:13:11 -04:00
Ed Hennis be0baf1b53 Fix new header to use "#pragma once" 2026-07-10 11:41:11 -04:00
Ed Hennis b394730bd0 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-07-09 19:50:02 -04:00
Ed Hennis 8290eb3024 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-19 16:53:50 -04:00
Ed Hennis d537684df5 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-19 10:15:30 -04:00
Ed Hennis 4085361251 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-19 05:16:07 -04:00
Ed Hennis 1de7c130b0 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-15 21:43:33 -04:00
Ed Hennis 2a678a1157 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-14 20:39:23 -04:00
Ed Hennis 5c254aadf2 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-13 22:32:06 -04:00
Ed Hennis ad2db1962e Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-13 12:03:54 -04:00
Ed Hennis 4dae405762 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-12 19:19:01 -04:00
Ed Hennis b21b3596f8 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-12 16:26:24 -04:00
Ed Hennis d648539b62 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-11 13:34:26 -04:00
Ed Hennis 50644c6d30 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-07 18:10:17 -04:00
Ed Hennis 88c248077e Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-07 14:18:43 -04:00
Ed Hennis bad40d7e10 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-07 13:28:46 -04:00
Ed Hennis 74d0c375ec Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-06 22:34:37 -04:00
Ed Hennis 200ab3f694 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-06 14:18:16 -04:00
Ed Hennis a7a4357022 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-05 16:46:58 -04:00
Ed Hennis e0230a1e22 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-05 10:50:49 -04:00
Ed Hennis 5f1a98397c Merge remote-tracking branch 'XRPLF/develop' into ximinez/acquireAsyncDispatch
* XRPLF/develop:
  ci: Rewrite clang-tidy workflow(s) in a reusable manner (7062)
  chore: Ignore identifier-naming update in git blame (7066)
  refactor: Enable clang-tidy `readability-identifier-naming` check (6571)
2026-05-05 00:26:38 -04:00
Ed Hennis c8ca624974 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-05-01 13:59:18 -04:00
Ed Hennis 4489cda841 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-28 16:23:47 -04:00
Ed Hennis 784774005e Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-25 14:45:58 -04:00
Ed Hennis 904b39a3d3 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-23 15:56:15 -04:00
Ed Hennis eadfabfe4f Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-22 23:40:40 -04:00
Ed Hennis d991f81e87 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-22 14:49:17 -04:00
Ed Hennis a34a96e233 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-22 13:10:48 -04:00
Ed Hennis a3a277518b Merge remote-tracking branch 'XRPLF/develop' into ximinez/acquireAsyncDispatch
* XRPLF/develop:
  chore: Add -fix to clang-tidy invocation (6990)
  chore: Remove empty Taker.h (6984)
  chore: Enable clang-tidy modernize checks (6975)
  ci: Upload clang-tidy git diff (6983)
  fix: Add rounding to Vault invariants (6217) (6955)
2026-04-21 18:54:46 -04:00
Ed Hennis 8438698c54 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-20 17:49:51 -04:00
Ed Hennis 0597047d79 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-20 15:45:08 -04:00
Ed Hennis 992c6f525d Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-20 11:39:10 -04:00
Ed Hennis 9a870c36e2 Merge remote-tracking branch 'XRPLF/develop' into ximinez/acquireAsyncDispatch
* XRPLF/develop:
  chore: Enable clang-tidy include cleaner (6947)
  fix: Change AMMClawback return code to tecNO_PERMISSION (6946)
  ci: [DEPENDABOT] bump actions/upload-pages-artifact from 4.0.0 to 5.0.0 (6927)
  ci: [DEPENDABOT] bump actions/upload-artifact from 7.0.0 to 7.0.1 (6928)
  chore: Enable clang-tidy readability checks (6930)
2026-04-17 18:13:20 -04:00
Ed Hennis a4462e65bc Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-16 13:44:42 -04:00
Ed Hennis f0596c0a5d Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-15 19:06:33 -04:00
Ed Hennis dd99bc3ce8 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-15 14:29:00 -04:00
Ed Hennis 25cd7730e5 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-13 20:28:47 -04:00
Ed Hennis 8dcbcb22c2 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-04-10 12:12:54 -04:00
Ed Hennis f44dfc89cc refactor: acquireAsync will dispatch a job, not the other way around
- Improve job queue collision checks and logging
    - Improve logging related to ledger acquisition and operating mode
      changes
    - Class "CanProcess" to keep track of processing of distinct items
2026-04-10 10:31:21 -04:00
329 changed files with 5849 additions and 3615 deletions

No files matched your search

+16
View File
@@ -5,7 +5,10 @@ Checks: "-*,
-bugprone-exception-escape,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-narrowing-conversions,
-bugprone-signed-bitwise,
-bugprone-std-exception-baseclass,
-bugprone-throwing-static-initialization,
-bugprone-unhandled-code-paths,
cppcoreguidelines-*,
-cppcoreguidelines-avoid-c-arrays,
@@ -14,6 +17,7 @@ Checks: "-*,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-c-copy-assignment-signature,
-cppcoreguidelines-explicit-constructor,
-cppcoreguidelines-interfaces-global-init,
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-missing-std-forward,
@@ -32,6 +36,7 @@ Checks: "-*,
llvm-namespace-comment,
misc-*,
-misc-explicit-constructor,
-misc-multiple-inheritance,
-misc-no-recursion,
-misc-non-private-member-variables-in-classes,
@@ -45,6 +50,8 @@ Checks: "-*,
-modernize-avoid-c-style-cast,
-modernize-return-braced-init-list,
-modernize-use-integer-sign-comparison,
-modernize-use-string-view,
-modernize-use-structured-binding,
-modernize-use-trailing-return-type,
performance-*,
@@ -53,6 +60,7 @@ Checks: "-*,
-performance-noexcept-move-constructor,
-performance-unnecessary-copy-initialization,
-performance-unnecessary-value-param,
-performance-use-std-move,
readability-*,
-readability-avoid-const-params-in-decls,
@@ -65,7 +73,11 @@ Checks: "-*,
-readability-named-parameter,
-readability-qualified-auto,
-readability-redundant-access-specifiers,
-readability-redundant-nested-if,
-readability-redundant-qualified-alias,
-readability-static-accessed-through-instance,
-readability-trailing-comma,
-readability-trivial-switch,
-readability-uppercase-literal-suffix
"
# ---
@@ -81,6 +93,10 @@ CheckOptions:
bugprone-unsafe-functions.ReportMoreUnsafeFunctions: true
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
# New in clang-tidy 23; disabled until the code is updated
misc-const-correctness.AnalyzeAutoVariables: false
misc-const-correctness.AnalyzeLambdas: false
misc-const-correctness.AnalyzeParameters: false
misc-include-cleaner.IgnoreHeaders: ".*/(detail|impl)/.*;.*fwd\\.h(pp)?;time.h;stdlib.h;sqlite3.h;netinet/in\\.h;sys/resource\\.h;sys/sysinfo\\.h;linux/sysinfo\\.h;__chrono/.*;bits/.*;_abort\\.h;boost/.*;openssl/obj_mac\\.h"
readability-braces-around-statements.ShortStatementLines: 2
+14 -5
View File
@@ -15,9 +15,9 @@ inputs:
required: false
default: "false"
log_verbosity:
description: "The logging verbosity."
description: 'The logging verbosity ("quiet", "verbose"), or empty to use the Conan defaults.'
required: false
default: "verbose"
default: ""
sanitizers:
description: "The sanitizers to enable."
required: false
@@ -35,6 +35,16 @@ runs:
LOG_VERBOSITY: ${{ inputs.log_verbosity }}
SANITIZERS: ${{ inputs.sanitizers }}
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 \
--profile:all ci \
--build="${BUILD_OPTION}" \
@@ -42,8 +52,7 @@ runs:
--options:host='&:xrpld=True' \
--settings:all build_type="${BUILD_TYPE}" \
--conf:all tools.build:jobs=${BUILD_NPROC} \
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
"${VERBOSITY_ARGS[@]}" \
--format=json \
. >"${RUNNER_TEMP}/conan-graph.json"
@@ -52,4 +61,4 @@ runs:
- name: Check build-context packages for Nix store dependencies (Linux)
if: ${{ runner.os == 'Linux' }}
shell: bash
run: ./bin/check-build-context-runtime.sh "${RUNNER_TEMP}/conan-graph.json"
run: ./bin/nix/check-build-context-runtime.sh "${RUNNER_TEMP}/conan-graph.json"
+3 -3
View File
@@ -12,7 +12,7 @@ on:
- "!nix/docker/README.md"
- "!nix/devshell.nix"
- "!nix/check-tools/**"
- "bin/default-loader-path.sh"
- "bin/nix/default-loader-path.sh"
pull_request:
paths:
- ".github/workflows/build-nix-images.yml"
@@ -24,8 +24,8 @@ on:
- "!nix/devshell.nix"
- "!nix/check-tools/**"
- "bin/check-tools.sh"
- "bin/default-loader-path.sh"
- "bin/install-sanitizer-libs.sh"
- "bin/nix/default-loader-path.sh"
- "bin/install/sanitizer-libs.sh"
workflow_dispatch:
concurrency:
+2 -2
View File
@@ -5,12 +5,12 @@ on:
branches:
- develop
paths:
- "bin/install-packaging-tools.sh"
- "bin/install/packaging-tools.sh"
- "package/images/packaging/**"
pull_request:
paths:
- ".github/workflows/build-packaging-images.yml"
- "bin/install-packaging-tools.sh"
- "bin/install/packaging-tools.sh"
- "package/images/packaging/**"
workflow_dispatch:
+1 -2
View File
@@ -93,9 +93,8 @@ jobs:
.github/workflows/reusable-upload-recipe.yml
.clang-tidy
.codecov.yml
bin/check-nix-store-refs.sh
bin/check-tools.sh
bin/default-loader-path.sh
bin/nix/**
cfg/**
cmake/**
conan/**
+1 -2
View File
@@ -31,9 +31,8 @@ on:
- ".github/workflows/reusable-upload-recipe.yml"
- ".clang-tidy"
- ".codecov.yml"
- "bin/check-nix-store-refs.sh"
- "bin/check-tools.sh"
- "bin/default-loader-path.sh"
- "bin/nix/**"
- "cfg/**"
- "cmake/**"
- "conan/**"
@@ -186,9 +186,6 @@ jobs:
with:
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ inputs.build_type }}
# Set the verbosity to "quiet" for Windows to avoid an excessive
# amount of logs. For other OSes, the "verbose" logs are more useful.
log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
sanitizers: ${{ inputs.sanitizers }}
- name: Configure CMake
@@ -257,20 +254,20 @@ jobs:
# cache included, since what it holds is what gets uploaded and reused.
- name: Check the build output for Nix store references (Nix toolchain)
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)
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
# images always references the store. Same condition it uses.
- name: Check for Nix store references (Linux)
if: ${{ runner.os == 'Linux' && env.SANITIZERS_ENABLED == 'false' }}
run: |
./bin/check-nix-store-refs.sh "${BUILD_DIR}/xrpld"
./bin/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"
./bin/nix/check-nix-store-refs.sh "${BUILD_DIR}/xrpl_tests"
./bin/nix/check-nix-store-refs.sh "${BUILD_DIR}/xrpld_tests"
- name: Show ccache statistics
if: ${{ inputs.ccache_enabled }}
+1 -2
View File
@@ -34,7 +34,7 @@ jobs:
needs: [determine-files]
if: ${{ needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.need_full_run == 'true' }}
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-ed96e60"
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-3d526d4"
permissions:
contents: read
issues: write
@@ -73,7 +73,6 @@ jobs:
with:
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ env.BUILD_TYPE }}
log_verbosity: verbose
- name: Configure CMake
working-directory: ${{ env.BUILD_DIR }}
+1 -4
View File
@@ -108,14 +108,11 @@ jobs:
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ matrix.build_type }}
force_build: ${{ github.event_name == 'schedule' || github.event.inputs.force_source_build == 'true' }}
# Set the verbosity to "quiet" for Windows to avoid an excessive
# amount of logs. For other OSes, the "verbose" logs are more useful.
log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
sanitizers: ${{ matrix.sanitizers }}
- name: Check the Conan cache for Nix store references (Nix toolchain)
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
if: ${{ github.repository == 'XRPLF/rippled' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
+1 -1
View File
@@ -28,7 +28,7 @@ Version 3.5.0 is not yet released.
### 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
File renamed without changes.
File renamed without changes.
@@ -11,7 +11,7 @@
# 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/check-build-context-runtime.sh <graph.json>
# Usage: bin/nix/check-build-context-runtime.sh <graph.json>
# <graph.json> is the output of `conan install --format=json`.
set -euo pipefail
@@ -10,7 +10,7 @@
# alone; the scripts in a Conan cache are all git hook samples and autotools
# 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
File renamed without changes.
+2 -2
View File
@@ -17,7 +17,7 @@
(runtime libraries resolved through the rpath) are skipped too.
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)
@@ -25,7 +25,7 @@ include_guard(GLOBAL)
include(CompilationEnv)
# 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(
is_linux
+13 -7
View File
@@ -60,8 +60,20 @@ tools.build:exelinkflags+={{ static_runtime_flags }}
tools.info.package_id:confs+=["tools.build:exelinkflags"]
{% endif %}
{% if os == "Macos" %}
{% if os == "Linux" and context == "build" %}
{# b2 links itself with its own script, which ignores exelinkflags #}
{# and only takes CXXFLAGS when use_cxx_env is set (see [buildenv] below). #}
[options]
b2/*:use_cxx_env=True
{% endif %}
[buildenv]
{# gRPC emits thousands of compiler warnings that we cannot act on. #}
{# CMake picks up CXXFLAGS, and unlike tools.build:cxxflags, #}
{# this is not part of the package ID, so binaries stay shareable. #}
grpc/*:CXXFLAGS=-w
{% if os == "Macos" %}
{# os.version adds -mmacosx-version-min to compiler command lines, #}
{# but Boost.Context's b2 assembly (.S) rule ignores it, #}
{# so those objects keep the host SDK version and still warn at link time. #}
@@ -71,11 +83,5 @@ boost/*:MACOSX_DEPLOYMENT_TARGET={{ min_macos_version }}
{% 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. #}
[options]
b2/*:use_cxx_env=True
[buildenv]
b2/*:CXXFLAGS={{ static_runtime_flags | join(" ") }}
{% endif %}
+1 -1
View File
@@ -154,7 +154,7 @@ class Xrpl(ConanFile):
self.requires("xxhash/0.8.3", transitive_headers=True)
exports_sources = (
"bin/default-loader-path.sh",
"bin/nix/default-loader-path.sh",
"CMakeLists.txt",
"cfg/*",
"cmake/*",
+6 -6
View File
@@ -183,14 +183,14 @@ at link or run time.
> configuration CI covers, and no dependency binaries are published for it.
This is checked rather than assumed.
[`bin/check-nix-store-refs.sh`](../../bin/check-nix-store-refs.sh) takes one file
or directory and fails if a binary under it resolves a store path at run time.
[`bin/nix/check-nix-store-refs.sh`](../../bin/nix/check-nix-store-refs.sh) takes one
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
before anything is published. You can run it yourself:
```bash
bin/check-nix-store-refs.sh build
bin/check-nix-store-refs.sh ~/.conan2-nix
bin/nix/check-nix-store-refs.sh build
bin/nix/check-nix-store-refs.sh ~/.conan2-nix
```
It works on Linux too, but asserts something narrower there: the toolchain always
@@ -204,7 +204,7 @@ instrument them. CI checks that they load nothing from the store but glibc, from
the graph `conan install --format=json` writes:
```bash
bin/check-build-context-runtime.sh graph.json
bin/nix/check-build-context-runtime.sh graph.json
```
Only the binaries [`PatchNixBinary.cmake`](../../cmake/PatchNixBinary.cmake)
@@ -212,7 +212,7 @@ retargets to the system loader have to be fully clean, and those are what CI
checks:
```bash
bin/check-nix-store-refs.sh build/xrpld
bin/nix/check-nix-store-refs.sh build/xrpld
```
### The libresolv stub
+3 -3
View File
@@ -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
```
[`bin/check-nix-store-refs.sh`](../../bin/check-nix-store-refs.sh) finds the same
thing without having to run anything, and names the file:
[`bin/nix/check-nix-store-refs.sh`](../../bin/nix/check-nix-store-refs.sh) finds the
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
/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig
/nix/store/p4lp3xq4imd1qzqh08x8vcq2zfhi7rca-libresolv-93/lib/libresolv.9.dylib
+118
View File
@@ -0,0 +1,118 @@
#pragma once
#include <functional>
#include <mutex>
#include <set>
/**
* RAII class to check if an Item is already being processed on another thread,
* as indicated by it's presence in a Collection.
*
* If the Item is not in the Collection, it will be added under lock in the
* ctor, and removed under lock in the dtor. The object will be considered
* "usable" and evaluate to `true`.
*
* If the Item is in the Collection, no changes will be made to the collection,
* and the CanProcess object will be considered "unusable".
*
* It's up to the caller to decide what "usable" and "unusable" mean. (e.g.
* Process or skip a block of code, or set a flag.)
*
* The current use is to avoid lock contention that would be involved in
* processing something associated with the Item.
*
* Examples:
*
* void IncomingLedgers::acquireAsync(LedgerHash const& hash, ...)
* {
* if (CanProcess check{acquiresMutex_, pendingAcquires_, hash})
* {
* acquire(hash, ...);
* }
* }
*
* bool
* NetworkOPsImp::recvValidation(
* std::shared_ptr<STValidation> const& val,
* std::string const& source)
* {
* CanProcess check(
* validationsMutex_, pendingValidations_, val->getLedgerHash());
* BypassAccept bypassAccept =
* check ? BypassAccept::no : BypassAccept::yes;
* handleNewValidation(app_, val, source, bypassAccept, m_journal);
* }
*
*/
class CanProcess
{
public:
template <class Mutex, class Collection, class Item>
CanProcess(Mutex& mtx, Collection& collection, Item const& item)
: cleanup_(insert(mtx, collection, item))
{
}
~CanProcess()
{
if (cleanup_)
cleanup_();
}
CanProcess(CanProcess const&) = delete;
CanProcess&
operator=(CanProcess const&) = delete;
explicit
operator bool() const
{
return static_cast<bool>(cleanup_);
}
private:
template <bool useIterator, class Mutex, class Collection, class Item>
std::function<void()>
doInsert(Mutex& mtx, Collection& collection, Item const& item)
{
std::unique_lock<Mutex> lock(mtx);
// TODO: Use structured binding once LLVM 16 is the minimum supported
// version. See also: https://github.com/llvm/llvm-project/issues/48582
// https://github.com/llvm/llvm-project/commit/127bf44385424891eb04cff8e52d3f157fc2cb7c
auto const insertResult = collection.insert(item);
auto const it = insertResult.first;
if (!insertResult.second)
return {};
if constexpr (useIterator)
return [&, it]() {
std::unique_lock<Mutex> lock(mtx);
collection.erase(it);
};
else
return [&]() {
std::unique_lock<Mutex> lock(mtx);
collection.erase(item);
};
}
// Generic insert() function doesn't use iterators because they may get
// invalidated
template <class Mutex, class Collection, class Item>
std::function<void()>
insert(Mutex& mtx, Collection& collection, Item const& item)
{
return doInsert<false>(mtx, collection, item);
}
// Specialize insert() for std::set, which does not invalidate iterators for
// insert and erase
template <class Mutex, class Item>
std::function<void()>
insert(Mutex& mtx, std::set<Item>& collection, Item const& item)
{
return doInsert<true>(mtx, collection, item);
}
// If set, then the item is "usable"
std::function<void()> cleanup_;
};
+75
View File
@@ -3,9 +3,84 @@
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <optional>
namespace xrpl {
/**
* Add two signed 64-bit integers, returning std::nullopt when the exact
* mathematical sum is not representable in std::int64_t.
*/
[[nodiscard]] constexpr std::optional<std::int64_t>
checkedAdd(std::int64_t a, std::int64_t b) noexcept
{
using L = std::numeric_limits<std::int64_t>;
if ((b > 0 && a > L::max() - b) || (b < 0 && a < L::min() - b))
return std::nullopt;
return a + b;
}
/**
* Subtract two signed 64-bit integers, returning std::nullopt when the exact
* mathematical difference is not representable in std::int64_t.
*/
[[nodiscard]] constexpr std::optional<std::int64_t>
checkedSub(std::int64_t a, std::int64_t b) noexcept
{
using L = std::numeric_limits<std::int64_t>;
if ((b > 0 && a < L::min() + b) || (b < 0 && a > L::max() + b))
return std::nullopt;
return a - b;
}
static_assert(checkedAdd(0, 0) == 0);
static_assert(checkedAdd(1, -1) == 0);
static_assert(checkedAdd(-5, 2) == -3);
static_assert(!checkedAdd(std::numeric_limits<std::int64_t>::max(), 1).has_value());
static_assert(!checkedAdd(std::numeric_limits<std::int64_t>::min(), -1).has_value());
static_assert(
checkedAdd(std::numeric_limits<std::int64_t>::max() - 1, 1) ==
std::numeric_limits<std::int64_t>::max());
static_assert(
checkedAdd(
std::numeric_limits<std::int64_t>::min(),
std::numeric_limits<std::int64_t>::max()) == -1);
static_assert(
checkedAdd(
std::numeric_limits<std::int64_t>::max(),
std::numeric_limits<std::int64_t>::min()) == -1);
static_assert(
!checkedAdd(std::numeric_limits<std::int64_t>::max(), std::numeric_limits<std::int64_t>::max())
.has_value());
static_assert(
!checkedAdd(std::numeric_limits<std::int64_t>::min(), std::numeric_limits<std::int64_t>::min())
.has_value());
static_assert(checkedSub(0, 0) == 0);
static_assert(checkedSub(1, 1) == 0);
static_assert(checkedSub(-5, 2) == -7);
static_assert(checkedSub(-5, -2) == -3);
static_assert(!checkedSub(std::numeric_limits<std::int64_t>::min(), 1).has_value());
static_assert(!checkedSub(std::numeric_limits<std::int64_t>::max(), -1).has_value());
static_assert(
checkedSub(std::numeric_limits<std::int64_t>::min() + 1, 1) ==
std::numeric_limits<std::int64_t>::min());
static_assert(
checkedSub(-1, std::numeric_limits<std::int64_t>::max()) ==
std::numeric_limits<std::int64_t>::min());
static_assert(
!checkedSub(std::numeric_limits<std::int64_t>::max(), std::numeric_limits<std::int64_t>::min())
.has_value());
static_assert(
!checkedSub(std::numeric_limits<std::int64_t>::min(), std::numeric_limits<std::int64_t>::max())
.has_value());
/**
* Calculate one number divided by another number in percentage.
* The result is rounded up to the next integer, and capped in the range [0,100]
+1 -1
View File
@@ -36,7 +36,7 @@ template <typename 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>;
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{};
for (int i = 0; i < 10; ++i)
+2 -2
View File
@@ -783,7 +783,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
std::atomic<int>& allRemovals,
std::scoped_lock<std::recursive_mutex> const&)
{
return std::thread([&, this]() {
return std::thread([&, this] {
int cacheRemovals = 0;
int mapRemovals = 0;
@@ -863,7 +863,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
std::atomic<int>& allRemovals,
std::scoped_lock<std::recursive_mutex> const&)
{
return std::thread([&, this]() {
return std::thread([&, this] {
// NOLINTBEGIN https://github.com/XRPLF/rippled/issues/7056
int cacheRemovals = 0;
int mapRemovals = 0;
@@ -1604,7 +1604,7 @@ AgedOrderedContainer<IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::erase(
beast::detail::AgedContainerIterator<IsConst, Iterator> pos)
requires(!IsBoostReverseIterator<Iterator>::value)
{
unlinkAndDeleteElement(&*((pos++).iterator()));
unlinkAndDeleteElement(&*(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)
{
for (; first != last;)
unlinkAndDeleteElement(&*((first++).iterator()));
unlinkAndDeleteElement(&*(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(
beast::detail::AgedContainerIterator<IsConst, Iterator> pos)
{
unlinkAndDeleteElement(&*((pos++).iterator()));
unlinkAndDeleteElement(&*(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)
{
for (; first != last;)
unlinkAndDeleteElement(&*((first++).iterator()));
unlinkAndDeleteElement(&*(first++).iterator());
return beast::detail::AgedContainerIterator<false, Iterator>(first.iterator());
}
+1 -1
View File
@@ -390,7 +390,7 @@ void
hash_append(Hasher& h, boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept
requires(IsContiguouslyHashable<Key, Hasher>::value)
{
h(&(v.begin()), v.size() * sizeof(Key));
h(&v.begin(), v.size() * sizeof(Key));
}
// tuple
+1 -1
View File
@@ -8,7 +8,7 @@ namespace beast::insight {
class HookImpl : public std::enable_shared_from_this<HookImpl>
{
public:
using HandlerType = std::function<void(void)>;
using HandlerType = std::function<void()>;
virtual ~HookImpl() = 0;
};
+2 -2
View File
@@ -61,7 +61,7 @@ isMulticast(Address const& addr)
inline bool
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
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
+1 -1
View File
@@ -34,7 +34,7 @@ typeName()
name += " volatile";
if (std::is_lvalue_reference_v<T>)
{
name += "&";
name += '&';
}
else if (std::is_rvalue_reference_v<T>)
{
+3 -3
View File
@@ -47,8 +47,8 @@ public:
template <class F, class... Args>
explicit Thread(Suite& s, F&& f, Args&&... args) : s_(&s)
{
std::function<void(void)> b = [f = std::forward<F>(f),
... args = std::forward<Args>(args)]() mutable {
std::function<void()> b = [f = std::forward<F>(f),
... args = std::forward<Args>(args)] mutable {
std::invoke(f, args...);
};
t_ = std::thread(&Thread::run, this, std::move(b));
@@ -94,7 +94,7 @@ public:
private:
void
run(std::function<void(void)> f)
run(std::function<void()> f)
{
try
{
+2 -2
View File
@@ -54,7 +54,7 @@ JobQueue::Coro::post()
}
// 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;
}
@@ -130,7 +130,7 @@ inline void
JobQueue::Coro::join()
{
std::unique_lock<std::mutex> lk(mutexRun_);
cv_.wait(lk, [this]() { return !running_; });
cv_.wait(lk, [this] { return !running_; });
}
} // namespace xrpl
+1 -1
View File
@@ -221,7 +221,7 @@ public:
/**
* Add a suppression peer and get message's relay status.
* Return pair:
* element 1: true if the peer is added.
* element 1: true if the key is added.
* element 2: optional is seated to the relay time point or
* is unseated if has not relayed yet.
*/
+10 -12
View File
@@ -353,7 +353,7 @@ changeSpotPriceQuality(
}
if (auto const nTakerPaysPropose = (-b + root2(res)) / (2 * a); nTakerPaysPropose > 0)
{
auto const nTakerPays = [&]() {
auto const nTakerPays = [&] {
// The fee might make the AMM offer quality less than CLOB
// quality. Therefore, AMM offer has to satisfy this constraint:
// o / i >= q. Substituting o with swapAssetIn() gives: i <= O /
@@ -372,8 +372,8 @@ changeSpotPriceQuality(
auto const takerPays =
toAmount<TIn>(getAsset(pool.in), nTakerPays, Number::RoundingMode::Upward);
// should not fail
if (auto amounts = TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
Quality{amounts} < quality &&
auto amounts = TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
if (Quality{amounts} < quality &&
!withinRelativeDistance(Quality{amounts}, quality, Number(1, -7)))
{
JLOG(j.error()) << "changeSpotPriceQuality failed: " << to_string(pool.in) << " "
@@ -382,21 +382,19 @@ changeSpotPriceQuality(
<< " " << to_string(amounts.out);
Throw<std::runtime_error>("changeSpotPriceQuality failed");
}
else
{
JLOG(j.trace()) << "changeSpotPriceQuality succeeded: " << to_string(pool.in) << " "
<< to_string(pool.out) << " "
<< " " << quality << " " << tfee << " " << to_string(amounts.in)
<< " " << to_string(amounts.out);
return amounts;
}
JLOG(j.trace()) << "changeSpotPriceQuality succeeded: " << to_string(pool.in) << " "
<< to_string(pool.out) << " "
<< " " << quality << " " << tfee << " " << to_string(amounts.in) << " "
<< to_string(amounts.out);
return amounts;
}
JLOG(j.trace()) << "changeSpotPriceQuality calc failed: " << to_string(pool.in) << " "
<< to_string(pool.out) << " " << quality << " " << tfee;
return std::nullopt;
}
auto amounts = [&]() {
auto amounts = [&] {
bool const inIntegral = getAsset(pool.in).integral();
bool const outIntegral = getAsset(pool.out).integral();
+1 -1
View File
@@ -103,7 +103,7 @@ public:
void
asyncHandshake(HandshakeType type, Callback cbFunc)
{
if ((type == SslSocket::client) || (secure_))
if ((type == SslSocket::client) || secure_)
{
// must be ssl
secure_ = true;
+1 -1
View File
@@ -67,7 +67,7 @@ class EncodedBlob
public:
explicit EncodedBlob(std::shared_ptr<NodeObject> const& obj)
: size_([&obj]() {
: size_([&obj] {
XRPL_ASSERT(obj, "xrpl::node_store::EncodedBlob::EncodedBlob : non-null input");
if (!obj)
+1 -1
View File
@@ -55,7 +55,7 @@ hash_append(Hasher& h, Book const& b)
using beast::hash_append;
hash_append(h, b.in, b.out);
if (b.domain)
hash_append(h, *(b.domain));
hash_append(h, *b.domain);
}
Book
+4 -1
View File
@@ -208,7 +208,10 @@ enum LedgerEntryType : std::uint16_t {
\
LEDGER_OBJECT(Sponsorship, \
LSF_FLAG(lsfSponsorshipRequireSignForFee, 0x00010000) \
LSF_FLAG(lsfSponsorshipRequireSignForReserve, 0x00020000))
LSF_FLAG(lsfSponsorshipRequireSignForReserve, 0x00020000)) \
\
LEDGER_OBJECT(LoanBroker, \
LSF_FLAG(lsfLoanBrokerPrivate, 0x00010000))
// clang-format on
+2
View File
@@ -40,6 +40,8 @@ struct LedgerHeader
// If validated is false, it means "not yet validated."
// Once validated is true, it will never be set false at a later time.
// NOTE: If you are accessing this directly, you are probably doing it
// wrong. Use LedgerMaster::isValidated().
// VFALCO TODO Make this not mutable
bool mutable validated = false;
bool accepted = false;
+1 -3
View File
@@ -457,9 +457,7 @@ private:
// The remove_cv and remove_reference are necessitated by the STBitString
// types. Their value() returns by const ref. We return those types
// by value.
template <
typename T,
typename V = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<T>().value())>>>
template <typename T, typename V = std::remove_cvref_t<decltype(std::declval<T>().value())>>
V
getFieldByValue(SField const& field) const;
+1 -1
View File
@@ -188,7 +188,7 @@ private:
template <class LookupNodeID>
STValidation::STValidation(SerialIter& sit, LookupNodeID&& lookupNodeID, DeserializeOptions options)
: STObject(validationFormat(), sit, sfValidation, options.requireCanonicalOrder)
, signingPubKey_([this]() {
, signingPubKey_([this] {
auto const spk = getFieldVL(sfSigningPubKey);
if (publicKeyType(makeSlice(spk)) != KeyType::Secp256k1)
+1 -1
View File
@@ -252,7 +252,7 @@ public:
{
auto success = (offset + (Bits / 8)) <= data_.size();
if (success)
memcpy(data.begin(), &(data_.front()) + offset, (Bits / 8));
memcpy(data.begin(), &data_.front() + offset, (Bits / 8));
return success;
}
+1 -1
View File
@@ -449,7 +449,7 @@ public:
// Trait tells the requires-clause which types are allowed for construction.
template <typename T>
constexpr TERSubset(T rhs)
requires(Trait<std::remove_cv_t<std::remove_reference_t<T>>>::value)
requires(Trait<std::remove_cvref_t<T>>::value)
: code_(TERtoInt(rhs))
{
}
+4
View File
@@ -226,6 +226,10 @@ inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
TF_FLAG(tfLoanUnimpair, 0x00040000), \
MASK_ADJ(0)) \
\
TRANSACTION(LoanBrokerSet, \
TF_FLAG(tfLoanBrokerPrivate, 0x00010000), \
MASK_ADJ(0)) \
\
TRANSACTION(SponsorshipSet, \
TF_FLAG(tfSponsorshipSetRequireSignForFee, 0x00010000) \
TF_FLAG(tfSponsorshipClearRequireSignForFee, 0x00020000) \
@@ -20,6 +20,7 @@ XRPL_FEATURE(SmartEscrow, Supported::No, VoteBehavior::DefaultN
XRPL_FEATURE(LendingProtocolV1_2, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_5_0, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(ConfidentialMPTKeyRotation, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (BatchV1_2, Supported::Yes, VoteBehavior::DefaultYes)
XRPL_FIX (Cleanup3_4_0, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Sponsor, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(BatchV1_1, Supported::Yes, VoteBehavior::DefaultNo)
@@ -549,6 +549,7 @@ LEDGER_ENTRY(ltLOAN_BROKER, 0x0088, LoanBroker, loan_broker, ({
{sfCoverAvailable, SoeDefault},
{sfCoverRateMinimum, SoeDefault},
{sfCoverRateLiquidation, SoeDefault},
{sfDomainID, SoeOptional},
}))
/** A ledger object representing a loan between a Borrower and a Loan Broker
@@ -900,6 +900,7 @@ TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet,
{sfDebtMaximum, SoeOptional},
{sfCoverRateMinimum, SoeOptional},
{sfCoverRateLiquidation, SoeOptional},
{sfDomainID, SoeOptional},
}))
/** This transaction deletes a Loan Broker */
@@ -335,6 +335,30 @@ public:
{
return this->sle_->isFieldPresent(sfCoverRateLiquidation);
}
/**
* @brief Get sfDomainID (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT256::type::value_type>
getDomainID() const
{
if (hasDomainID())
return this->sle_->at(sfDomainID);
return std::nullopt;
}
/**
* @brief Check if sfDomainID is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasDomainID() const
{
return this->sle_->isFieldPresent(sfDomainID);
}
};
/**
@@ -578,6 +602,17 @@ public:
return *this;
}
/**
* @brief Set sfDomainID (SoeOptional)
* @return Reference to this builder for method chaining.
*/
LoanBrokerBuilder&
setDomainID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
{
object_[sfDomainID] = value;
return *this;
}
/**
* @brief Build and return the completed LoanBroker wrapper.
* @param index The ledger entry index.
@@ -213,6 +213,32 @@ public:
{
return this->tx_->isFieldPresent(sfCoverRateLiquidation);
}
/**
* @brief Get sfDomainID (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT256::type::value_type>
getDomainID() const
{
if (hasDomainID())
{
return this->tx_->at(sfDomainID);
}
return std::nullopt;
}
/**
* @brief Check if sfDomainID is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasDomainID() const
{
return this->tx_->isFieldPresent(sfDomainID);
}
};
/**
@@ -336,6 +362,17 @@ public:
return *this;
}
/**
* @brief Set sfDomainID (SoeOptional)
* @return Reference to this builder for method chaining.
*/
LoanBrokerSetBuilder&
setDomainID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
{
object_[sfDomainID] = value;
return *this;
}
/**
* @brief Build and return the LoanBrokerSet wrapper.
* @param publicKey The public key for signing.
+1 -1
View File
@@ -178,7 +178,7 @@ public:
{
using namespace std::chrono_literals;
LockedSociSession session = perf::measureDurationAndLog(
[&]() { return LockedSociSession(session_, lock_); }, "checkoutDb", 10ms, j_);
[&] { return LockedSociSession(session_, lock_); }, "checkoutDb", 10ms, j_);
return session;
}
+1 -1
View File
@@ -279,7 +279,7 @@ public:
virtual bool
unsubPeerStatus(std::uint64_t uListener) = 0;
virtual void
pubPeerStatus(std::function<json::Value(void)> const&) = 0;
pubPeerStatus(std::function<json::Value()> const&) = 0;
virtual bool
subConsensus(Ref ispListener) = 0;
+1 -1
View File
@@ -196,7 +196,7 @@ public:
virtual bool
isFull() = 0;
virtual void
setMode(OperatingMode om) = 0;
setMode(OperatingMode om, char const* reason) = 0;
virtual bool
isBlocked() = 0;
virtual bool
+1 -1
View File
@@ -41,7 +41,7 @@ public:
}
bool
prepare(std::size_t bytes, std::function<void(void)>) override
prepare(std::size_t bytes, std::function<void()>) override
{
return true;
}
+2 -2
View File
@@ -47,7 +47,7 @@ public:
* empty vector.
*/
virtual std::pair<boost::tribool, std::vector<boost::asio::const_buffer>>
prepare(std::size_t bytes, std::function<void(void)> resume) = 0;
prepare(std::size_t bytes, std::function<void()> resume) = 0;
};
template <class Streambuf>
@@ -62,7 +62,7 @@ public:
}
std::pair<boost::tribool, std::vector<boost::asio::const_buffer>>
prepare(std::size_t bytes, std::function<void(void)>) override
prepare(std::size_t bytes, std::function<void()>) override
{
if (sb_.size() == 0)
return {true, {}};
+1 -1
View File
@@ -34,7 +34,7 @@ public:
* @return `true` if the writer is ready to provide more data.
*/
virtual bool
prepare(std::size_t bytes, std::function<void(void)> resume) = 0;
prepare(std::size_t bytes, std::function<void()> resume) = 0;
/**
* Returns a ConstBufferSequence representing the input sequence.
+2 -2
View File
@@ -342,10 +342,10 @@ BaseHTTPPeer<Handler, Impl>::doWriter(
bool keepAlive,
YieldContext doYield)
{
std::function<void(void)> resume;
std::function<void()> resume;
{
auto const p = impl().shared_from_this();
resume = std::function<void(void)>([this, p, writer, keepAlive]() {
resume = std::function<void()>([this, p, writer, keepAlive] {
util::spawn(strand_, [p, writer, keepAlive](YieldContext doYield) {
p->doWriter(writer, keepAlive, doYield);
});
+1 -1
View File
@@ -99,7 +99,7 @@ private:
port_.protocol.contains("wss2") || port_.protocol.contains("peer")};
bool plain_{
port_.protocol.contains("http") || port_.protocol.contains("ws") ||
(port_.protocol.contains("ws2"))};
port_.protocol.contains("ws2")};
static constexpr std::chrono::milliseconds kInitialAcceptDelay{50};
static constexpr std::chrono::milliseconds kMaxAcceptDelay{2000};
std::chrono::milliseconds acceptDelay_{kInitialAcceptDelay};
+2 -2
View File
@@ -60,7 +60,7 @@ private:
bool closed_ = false;
std::condition_variable cv_;
boost::container::flat_map<Work*, std::weak_ptr<Work>> map_;
std::function<void(void)> f_;
std::function<void()> f_;
public:
IOList() = default;
@@ -171,7 +171,7 @@ IOList::Work::destroy()
{
if (!ios_)
return;
std::function<void(void)> f;
std::function<void()> f;
{
std::scoped_lock const lock(ios_->m_);
ios_->map_.erase(this);
+3 -1
View File
@@ -18,6 +18,8 @@
#include <xrpl/tx/invariants/SponsorshipInvariant.h>
#include <xrpl/tx/invariants/VaultInvariant.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <cstdint>
#include <set>
#include <string>
@@ -139,7 +141,7 @@ public:
*/
class XRPNotCreated
{
std::int64_t drops_ = 0;
boost::multiprecision::int128_t drops_ = 0;
public:
void
+43
View File
@@ -1,6 +1,8 @@
#pragma once
#include <xrpl/basics/MathUtilities.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/protocol/AccountID.h>
@@ -23,6 +25,7 @@
#include <ostream>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
@@ -502,6 +505,46 @@ public:
};
/** @endcond */
/** @cond INTERNAL */
template <class T>
[[nodiscard]] std::optional<T>
checkedStepAddOpt(T const& lhs, T const& rhs)
{
if constexpr (std::is_same_v<T, XRPAmount>)
{
if (auto const r = checkedAdd(lhs.drops(), rhs.drops()))
return XRPAmount{*r};
return std::nullopt;
}
else if constexpr (std::is_same_v<T, MPTAmount>)
{
if (auto const r = checkedAdd(lhs.value(), rhs.value()))
return MPTAmount{*r};
return std::nullopt;
}
else if constexpr (std::is_same_v<T, IOUAmount>)
{
// IOUAmount is Number-backed and throws on overflow.
return lhs + rhs;
}
else
{
// A new amount type must decide explicitly how to add; do not fall back
// to an unchecked add.
static_assert(sizeof(T) == 0, "checkedStepAddOpt: unsupported amount type");
}
}
template <class T>
[[nodiscard]] T
checkedStepAdd(T const& lhs, T const& rhs)
{
if (auto const r = checkedStepAddOpt(lhs, rhs))
return *r;
Throw<FlowException>(tecPATH_DRY);
}
/** @endcond */
/** @cond INTERNAL */
// Check equal with tolerance
bool
+30 -9
View File
@@ -31,7 +31,6 @@
#include <cstdint>
#include <iterator>
#include <memory>
#include <numeric>
#include <optional>
#include <tuple>
#include <type_traits>
@@ -408,7 +407,7 @@ limitOut(
if (!qf || qf->isConst())
return remainingOut;
auto const out = [&]() {
auto const out = [&] {
auto const out = qf->outFromAvgQ(limitQuality);
if (!out)
return remainingOut;
@@ -646,11 +645,21 @@ flow(
boost::container::flat_multiset<TOutAmt> savedOuts;
savedOuts.reserve(maxTries);
auto sum = [](auto const& col) {
// Returns std::nullopt if the aggregate overflows; callers treat that as a
// dry path.
auto sum = [](auto const& col) -> std::optional<std::decay_t<decltype(*col.begin())>> {
using TResult = std::decay_t<decltype(*col.begin())>;
if (col.empty())
return TResult{beast::kZero};
return std::accumulate(col.begin() + 1, col.end(), *col.begin());
TResult total = *col.begin();
for (auto it = col.begin() + 1; it != col.end(); ++it)
{
auto const next = checkedStepAddOpt(total, *it);
if (!next)
return std::nullopt;
total = *next;
}
return total;
};
// These offers only need to be removed if the payment is not
@@ -670,7 +679,7 @@ flow(
ammContext.setMultiPath(activeStrands.size() > 1);
// Limit only if one strand and limitQuality
auto const limitRemainingOut = [&]() {
auto const limitRemainingOut = [&] {
if (activeStrands.size() == 1 && limitQuality)
{
if (auto const strand = activeStrands.get(0))
@@ -749,9 +758,17 @@ flow(
{
savedIns.insert(best->in);
savedOuts.insert(best->out);
remainingOut = outReq - sum(savedOuts);
auto const sumOut = sum(savedOuts);
if (!sumOut)
return {tecPATH_DRY, std::move(ofrsToRmOnFail)};
remainingOut = outReq - *sumOut;
if (sendMax)
remainingIn = *sendMax - sum(savedIns);
{
auto const sumIn = sum(savedIns);
if (!sumIn)
return {tecPATH_DRY, std::move(ofrsToRmOnFail)};
remainingIn = *sendMax - *sumIn;
}
if (flowDebugInfo)
{
@@ -786,8 +803,12 @@ flow(
break;
}
auto const actualOut = sum(savedOuts);
auto const actualIn = sum(savedIns);
auto const actualOutOpt = sum(savedOuts);
auto const actualInOpt = sum(savedIns);
if (!actualOutOpt || !actualInOpt)
return {tecPATH_DRY, std::move(ofrsToRmOnFail)};
auto const actualOut = *actualOutOpt;
auto const actualIn = *actualInOpt;
JLOG(j.trace()) << "Total flow: in: " << to_string(actualIn)
<< " out: " << to_string(actualOut);
@@ -10,6 +10,7 @@
#include <xrpl/tx/ApplyContext.h>
#include <xrpl/tx/Transactor.h>
#include <cstdint>
#include <vector>
namespace xrpl {
@@ -32,6 +33,9 @@ public:
static std::vector<OptionaledField<STNumber>> const&
getValueFields();
static std::uint32_t
getFlagsMask(PreflightContext const& ctx);
static TER
preclaim(PreclaimContext const& ctx);
+3 -3
View File
@@ -60,10 +60,10 @@ ENV GIT_SSL_CAINFO="/nix/ci-env/etc/ssl/certs/ca-bundle.crt"
# Externally-built dynamically-linked ELF binaries hard-code the loader path
# (e.g. /lib64/ld-linux-x86-64.so.2) in their PT_INTERP header. Install it
# from the Nix store when the base image doesn't already provide one.
COPY bin/default-loader-path.sh /tmp/loader-path.sh
COPY bin/nix/default-loader-path.sh /usr/local/bin/default-loader-path.sh
RUN <<EOF
target="$(/tmp/loader-path.sh)"
target="$(/usr/local/bin/default-loader-path.sh)"
if [ ! -e "${target}" ]; then
# Use the loader from the same glibc that gcc links libc against, so
@@ -101,7 +101,7 @@ RUN if echo "${BASE_IMAGE}" | grep -qiE 'nixos'; then \
SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]
# Sanity-check that the built binaries run correctly in the vanilla base image, with the necessary sanitizer runtime libraries installed.
COPY bin/install-sanitizer-libs.sh /tmp/install-sanitizer-libs.sh
COPY bin/install/sanitizer-libs.sh /tmp/install-sanitizer-libs.sh
COPY nix/docker/test_files/cpp/run-binaries.sh /tmp/test_files/cpp/run-binaries.sh
COPY nix/docker/test_files/rust/run-binaries.sh /tmp/test_files/rust/run-binaries.sh
COPY --from=final /tmp/cpp-bins /tmp/cpp-bins
+15 -14
View File
@@ -52,10 +52,10 @@ work without `ca-certificates` being installed in the base image.
workspace with `cargo` to exercise proc-macro dylib loading.
3. **`tester`** — Start again from a clean `BASE_IMAGE` (no Nix toolchain),
install only the sanitizer runtime libraries
([`install-sanitizer-libs.sh`](./install-sanitizer-libs.sh)), and run the
binaries compiled in `final`. This proves the binaries built with the Nix
toolchain actually run on a vanilla base image. On `nixos/nix` this step is
skipped (the binaries are patched for a conventional FHS loader).
([`bin/install/sanitizer-libs.sh`](../../bin/install/sanitizer-libs.sh)),
and run the binaries compiled in `final`. This proves the binaries built with
the Nix toolchain actually run on a vanilla base image. On `nixos/nix` this
step is skipped (the binaries are patched for a conventional FHS loader).
4. **Output** — The final image is gated on the tester succeeding: it copies a
sentinel file out of `tester`, so a failed test run fails the whole build.
@@ -75,9 +75,10 @@ toolchain being present at runtime. Two pieces make that work:
- **An expected dynamic linker in the image.**
Binaries built in Nix environments reference a dynamic linker from Nix store paths, which won't be present in the base image. However,
[`bin/default-loader-path.sh`](../../bin/default-loader-path.sh) reports the
[`bin/nix/default-loader-path.sh`](../../bin/nix/default-loader-path.sh) reports the
expected loader path for the current architecture, so we can patch the binaries
to use the correct loader.
to use the correct loader. The image ships it as
`/usr/local/bin/default-loader-path.sh`.
The build then verifies all of this end to end, and the C++ and Rust programs
go through the same pipeline: each is compiled in `final`, has its `PT_INTERP`
@@ -91,11 +92,11 @@ whose resulting binary is patched and run like the others.
## Files
| File | Purpose |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| [`./Dockerfile`](./Dockerfile) | Multi-stage build described above. |
| [`./test_files/cpp/`](./test_files/cpp) | C++ sanitizer smoke test: sources + compile/run scripts. |
| [`./test_files/rust/`](./test_files/rust) | Rust smoke test: rustc sources + a cargo proc-macro workspace + compile/run scripts. |
| [`/bin/check-tools.sh`](../../bin/check-tools.sh) | Verify every expected tools are present and runnable. |
| [`/bin/default-loader-path.sh`](../../bin/default-loader-path.sh) | Print the dynamic-linker (`PT_INTERP`) path for the current architecture. |
| [`/bin/install-sanitizer-libs.sh`](../../bin/install-sanitizer-libs.sh) | Install `libasan`/`libtsan`/`libubsan` runtimes on the supported base images. |
| File | Purpose |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| [`./Dockerfile`](./Dockerfile) | Multi-stage build described above. |
| [`./test_files/cpp/`](./test_files/cpp) | C++ sanitizer smoke test: sources + compile/run scripts. |
| [`./test_files/rust/`](./test_files/rust) | Rust smoke test: rustc sources + a cargo proc-macro workspace + compile/run scripts. |
| [`/bin/check-tools.sh`](../../bin/check-tools.sh) | Verify every expected tools are present and runnable. |
| [`/bin/nix/default-loader-path.sh`](../../bin/nix/default-loader-path.sh) | Print the dynamic-linker (`PT_INTERP`) path for the current architecture. |
| [`/bin/install/sanitizer-libs.sh`](../../bin/install/sanitizer-libs.sh) | Install `libasan`/`libtsan`/`libubsan` runtimes on the supported base images. |
+1 -1
View File
@@ -8,7 +8,7 @@ set -eo pipefail
src_dir="${1:?usage: $0 <src_dir> <dst_dir>}"
dst_dir="${2:?usage: $0 <src_dir> <dst_dir>}"
loader="$(/tmp/loader-path.sh)"
loader="$(/usr/local/bin/default-loader-path.sh)"
mkdir -p "${dst_dir}"
@@ -8,7 +8,7 @@ set -eo pipefail
src_dir="${1:?usage: $0 <src_dir> <dst_dir>}"
dst_dir="${2:?usage: $0 <src_dir> <dst_dir>}"
loader="$(/tmp/loader-path.sh)"
loader="$(/usr/local/bin/default-loader-path.sh)"
mkdir -p "${dst_dir}"
+1 -1
View File
@@ -12,7 +12,7 @@ package/
sign_rpm.py Signs the built RPMs (called by CI when publishing)
images/
packaging/
Dockerfile Packaging image, built by `build-packaging-images.yml`; installs its tooling with `bin/install-packaging-tools.sh`
Dockerfile Packaging image, built by `build-packaging-images.yml`; installs its tooling with `bin/install/packaging-tools.sh`
publish_pkg.py Uploads built packages to the XRPLF Nexus repositories (called by CI, and shipped in that image)
xrpld/
Dockerfile The xrpld Docker images, installing the built DEB on Ubuntu (see "Docker images")
+1 -1
View File
@@ -2,7 +2,7 @@ ARG BASE_IMAGE=debian:trixie
FROM ${BASE_IMAGE}
RUN --mount=type=bind,source=bin/install-packaging-tools.sh,target=/install-packaging-tools.sh \
RUN --mount=type=bind,source=bin/install/packaging-tools.sh,target=/install-packaging-tools.sh \
/install-packaging-tools.sh
# See package/README.md, "Publishing from other repositories".
+7
View File
@@ -130,6 +130,13 @@ unsigned-integer-overflow:__chrono/duration.h
# distinct header from the bits/ directory so it needs its own entry.
unsigned-integer-overflow:include/c++/*/bit
# libstdc++ <format> takes the magnitude of a negative integer with
# -static_cast<make_unsigned_t<T>>(v), which wraps by design for the most
# negative value (std::format("{}", INT_MIN)). std::to_string avoids the report
# only because it spells the same thing (unsigned)~v + 1u. Like <bit>, <format>
# is a top-level header rather than one under bits/.
unsigned-integer-overflow:include/c++/*/format
# =============================================================================
# Rippled code suppressions
# =============================================================================
+1 -1
View File
@@ -259,7 +259,7 @@ Logs::format(
output = xrpl::to_string(std::chrono::system_clock::now());
output += " ";
output += ' ';
if (!partition.empty())
output += partition + ":";
+1 -1
View File
@@ -1557,7 +1557,7 @@ root(Number f, unsigned d)
// Scale f into the range (0, 1) such that f's exponent is a multiple of d
auto e = f.exponent_ + Number::mantissaLog() + 1;
auto const di = static_cast<int>(d);
auto ex = [e = e, di = di]() // Euclidean remainder of e/d
auto ex = [e = e, di = di] // Euclidean remainder of e/d
{
int const k = (e >= 0 ? e : e - (di - 1)) / di;
int const k2 = e - (k * di);
+3 -3
View File
@@ -94,7 +94,7 @@ initAnonymous(boost::asio::ssl::context& context)
{
using namespace openssl;
static auto kDefaultRsa = []() {
static auto kDefaultRsa = [] {
BIGNUM* bn = BN_new();
BN_set_word(bn, RSA_F4);
@@ -111,7 +111,7 @@ initAnonymous(boost::asio::ssl::context& context)
return rsa;
}();
static auto kDefaultEphemeralPrivateKey = []() {
static auto kDefaultEphemeralPrivateKey = [] {
auto pkey = EVP_PKEY_new();
if (!pkey)
@@ -128,7 +128,7 @@ initAnonymous(boost::asio::ssl::context& context)
return pkey;
}();
static auto kDefaultCert = []() {
static auto kDefaultCert = [] {
auto x509 = X509_new();
if (x509 == nullptr)
+3 -3
View File
@@ -22,7 +22,7 @@ printIdentifiers(SemanticVersion::IdentifierList const& list)
for (auto const& x : list)
{
if (!ret.empty())
ret += ".";
ret += '.';
ret += x;
}
@@ -219,13 +219,13 @@ SemanticVersion::print() const
if (!preReleaseIdentifiers.empty())
{
s += "-";
s += '-';
s += printIdentifiers(preReleaseIdentifiers);
}
if (!metaData.empty())
{
s += "+";
s += '+';
s += printIdentifiers(metaData);
}
+1 -1
View File
@@ -844,7 +844,7 @@ Reader::addErrorAndRecover(std::string const& message, Token& token, TokenType s
Value&
Reader::currentValue()
{
return *(nodes_.top());
return *nodes_.top();
}
Reader::Char
+4 -4
View File
@@ -111,7 +111,7 @@ Value::CZString::CZString(CZString const& other)
other.cstr_ != nullptr
? valueAllocator()->makeMemberName(other.cstr_)
: other.cstr_)
, index_([&]() -> int {
, index_([&] -> int {
if (!other.cstr_)
return other.index_;
return other.index_ == static_cast<int>(DuplicationPolicy::NoDuplication)
@@ -940,7 +940,7 @@ Value::resolveReference(char const* key, bool isStatic)
Value
Value::get(UInt index, Value const& defaultValue) const
{
Value const* value = &((*this)[index]);
Value const* value = &(*this)[index];
return value == &kNull ? defaultValue : *value;
}
@@ -1008,7 +1008,7 @@ Value::append(Value&& value)
Value
Value::get(char const* key, Value const& defaultValue) const
{
Value const* value = &((*this)[key]);
Value const* value = &(*this)[key];
return value == &kNull ? defaultValue : *value;
}
@@ -1051,7 +1051,7 @@ Value::isMember(char const* key) const
if (type_ != ValueType::Object)
return false;
Value const* value = &((*this)[key]);
Value const* value = &(*this)[key];
return value != &kNull;
}
+12 -12
View File
@@ -110,7 +110,7 @@ valueToQuotedString(char const* value)
unsigned const maxsize = (strlen(value) * 2) + 3; // all-escaped+quotes+NULL
std::string result;
result.reserve(maxsize); // to avoid lots of mallocs
result += "\"";
result += '"';
for (char const* c = value; *c != 0; ++c)
{
@@ -168,7 +168,7 @@ valueToQuotedString(char const* value)
}
}
result += "\"";
result += '"';
return result;
}
@@ -213,38 +213,38 @@ FastWriter::writeValue(Value const& value)
break;
case ValueType::Array: {
document_ += "[";
document_ += '[';
int const size = value.size();
for (int index = 0; index < size; ++index)
{
if (index > 0)
document_ += ",";
document_ += ',';
writeValue(value[index]);
}
document_ += "]";
document_ += ']';
}
break;
case ValueType::Object: {
Value::Members members(value.getMemberNames());
document_ += "{";
document_ += '{';
for (auto it = members.begin(); it != members.end(); ++it)
{
std::string const& name = *it;
if (it != members.begin())
document_ += ",";
document_ += ',';
document_ += valueToQuotedString(name.c_str());
document_ += ":";
document_ += ':';
writeValue(value[name]);
}
document_ += "}";
document_ += '}';
}
break;
}
@@ -262,7 +262,7 @@ StyledWriter::write(Value const& root)
addChildValues_ = false;
indentString_ = "";
writeValue(root);
document_ += "\n";
document_ += '\n';
return document_;
}
@@ -323,7 +323,7 @@ StyledWriter::writeValue(Value const& value)
if (++it; it == members.end())
break;
document_ += ",";
document_ += ',';
}
unindent();
@@ -371,7 +371,7 @@ StyledWriter::writeArrayValue(Value const& value)
if (++index == size)
break;
document_ += ",";
document_ += ',';
}
unindent();
+2 -2
View File
@@ -27,7 +27,7 @@ CachedViewImpl::read(Keylet const& k) const
bool cacheHit = false;
bool baseRead = false;
auto const digest = [&]() -> std::optional<UInt256> {
auto const digest = [&] -> std::optional<UInt256> {
{
std::scoped_lock const lock(mutex_);
auto const iter = map_.find(k.key);
@@ -41,7 +41,7 @@ CachedViewImpl::read(Keylet const& k) const
}();
if (!digest)
return nullptr;
auto sle = cache_.fetch(*digest, [&]() {
auto sle = cache_.fetch(*digest, [&] {
baseRead = true;
return base_.read(k);
});
+3 -3
View File
@@ -213,7 +213,7 @@ adjustAmountsByLPTokens(
if (lpTokensActual < lpTokens)
{
bool const ammRoundingEnabled = [&]() {
bool const ammRoundingEnabled = [&] {
if (auto const& rules = getCurrentTransactionRules();
rules && rules->enabled(fixAMMv1_1))
return true;
@@ -238,7 +238,7 @@ adjustAmountsByLPTokens(
}
// Single trade
auto const amountActual = [&]() {
auto const amountActual = [&] {
if (isDeposit == IsDeposit::Yes)
{
return ammAssetIn(amountBalance, lptAMMBalance, lpTokensActual, tfee);
@@ -481,7 +481,7 @@ ammHolds(
AuthHandling authHandling,
beast::Journal const j)
{
auto const assets = [&]() -> std::optional<std::pair<Asset, Asset>> {
auto const assets = [&] -> std::optional<std::pair<Asset, Asset>> {
auto const asset1 = ammSle[sfAsset];
auto const asset2 = ammSle[sfAsset2];
if (optAsset1 && optAsset2)
@@ -522,7 +522,7 @@ pseudoAccountAddress(ReadView const& view, UInt256 const& pseudoOwnerKey)
[[nodiscard]] std::vector<SField const*> const&
getPseudoAccountFields()
{
static std::vector<SField const*> const kPseudoFields = []() {
static std::vector<SField const*> const kPseudoFields = [] {
auto const ar = LedgerFormats::getInstance().findByType(ltACCOUNT_ROOT);
if (!ar)
{
@@ -744,7 +744,7 @@ tryOverpayment(
// Calculate what the new loan state should be with the new periodic payment,
// including the preserved rounding errors.
auto const newTheoreticalState = [&]() {
auto const newTheoreticalState = [&] {
auto const state = computeTheoreticalLoanState(
rules,
newLoanProperties.periodicPayment,
@@ -2179,7 +2179,7 @@ computeLoanProperties(
auto const periodicPayment =
detail::loanPeriodicPayment(rules, principalOutstanding, periodicRate, paymentsRemaining);
auto const [totalValueOutstanding, loanScale] = [&]() {
auto const [totalValueOutstanding, loanScale] = [&] {
// only round up if there should be interest
NumberRoundModeGuard const mg(
periodicRate == 0 ? Number::RoundingMode::ToNearest : Number::RoundingMode::Upward);
@@ -2221,7 +2221,7 @@ computeLoanProperties(
// Compute the principal part of the first payment. This is needed
// because the principal part may be rounded down to zero, which
// would prevent the principal from ever being paid down.
auto const firstPaymentPrincipal = [&]() {
auto const firstPaymentPrincipal = [&] {
// Compute the parts for the first payment. Ensure that the
// principal payment will actually change the principal.
auto const startingState = computeTheoreticalLoanState(
@@ -500,7 +500,7 @@ enforceMPTokenAuthorization(
auto const sleToken = ctx.view.read(keylet); // NOTE: might be null
auto const maybeDomainID = sleIssuance->at(~sfDomainID);
bool expired = false;
bool const authorizedByDomain = [&]() -> bool {
bool const authorizedByDomain = [&] -> bool {
// NOTE: defensive here, should be checked in preclaim
if (!maybeDomainID.has_value())
return false; // LCOV_EXCL_LINE
+12 -1
View File
@@ -1,6 +1,7 @@
#include <xrpl/ledger/helpers/TokenHelpers.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/MathUtilities.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/beast/utility/instrumentation.h>
@@ -1157,6 +1158,10 @@ accountSendMultiIOU(
if (receiver)
{
// Confirm the running debit will not overflow before crediting.
if (!checkedAdd(takeFromSender.xrp().drops(), amount.xrp().drops()))
return tecINTERNAL;
// Increment XRP balance.
auto const rcvBal = receiver->getFieldAmount(sfBalance);
receiver->setFieldAmount(sfBalance, rcvBal + amount);
@@ -1164,7 +1169,7 @@ accountSendMultiIOU(
view.update(receiver);
// Take what is actually sent
// Take what is actually sent.
takeFromSender += amount;
}
@@ -1457,6 +1462,8 @@ directSendNoLimitMultiMPT(
}
// Direct send: redeeming MPTs and/or sending own MPTs.
if (!checkedAdd(actual.mpt().value(), amount.mpt().value()))
return tecINTERNAL;
if (auto const ter = directSendNoFeeMPT(view, senderID, receiverID, amount, j);
!isTesSuccess(ter))
return ter;
@@ -1484,6 +1491,10 @@ directSendNoLimitMultiMPT(
actualSend = multiply(amount, rate);
}
}
// actual is a superset of takeFromSender, so checking it before both add
// sites also protects the debit accumulator.
if (!checkedAdd(actual.mpt().value(), actualSend.mpt().value()))
return tecINTERNAL;
actual += actualSend;
takeFromSender += actualSend;
+1 -1
View File
@@ -194,7 +194,7 @@ Database::importInternal(Backend& dstBackend, Database& srcDB)
{
Batch batch;
batch.reserve(kBatchWritePreallocationSize);
auto storeBatch = [&, fname = __func__]() {
auto storeBatch = [&, fname = __func__] {
try
{
dstBackend.storeBatch(batch);
+1 -1
View File
@@ -249,7 +249,7 @@ FeatureCollections::registerFeature(std::string const& name, Supported support,
features_.emplace_back(name, f);
auto const getAmendmentSupport = [=]() {
auto const getAmendmentSupport = [=] {
if (vote == VoteBehavior::Obsolete)
return AmendmentSupport::Retired;
return support == Supported::Yes ? AmendmentSupport::Supported
+1 -2
View File
@@ -240,8 +240,7 @@ skip(LedgerIndex ledger) noexcept
{
return {
ltLEDGER_HASHES,
indexHash(
LedgerNameSpace::SkipList, std::uint32_t(static_cast<std::uint32_t>(ledger) >> 16))};
indexHash(LedgerNameSpace::SkipList, static_cast<std::uint32_t>(ledger) >> 16)};
}
Keylet const&
+1 -1
View File
@@ -182,7 +182,7 @@ InnerObjectFormats::findSOTemplateBySField(SField const& sField) const
{
auto itemPtr = findByType(sField.getCode());
if (itemPtr != nullptr)
return &(itemPtr->getSOTemplate());
return &itemPtr->getSOTemplate();
return nullptr;
}
+3 -3
View File
@@ -23,15 +23,15 @@ Issue::getText() const
if (!isXRP(currency))
{
ret += "/";
ret += '/';
if (isXRP(account))
{
ret += "0";
ret += '0';
}
else if (account == noAccount())
{
ret += "1";
ret += '1';
}
else
{
+1 -1
View File
@@ -40,7 +40,7 @@ setCurrentTransactionRules(std::optional<Rules> r)
// the value is needed. That could get expensive fast.
// Declare the range this way to keep clang-tidy from complaining
auto const range = [&r]() {
auto const range = [&r] {
// If any new conditions with new amendments are added to "enableLargeNumbers", those
// amendments must also be added to useRulesGuards.
bool const enableLargeNumbers = !r ||
+2 -2
View File
@@ -111,7 +111,7 @@ SField::getField(int code)
if (it != knownCodeToField.end())
{
return *(it->second);
return *it->second;
}
return sfInvalid;
}
@@ -139,7 +139,7 @@ SField::getField(std::string const& fieldName)
if (it != knownNameToField.end())
{
return *(it->second);
return *it->second;
}
return sfInvalid;
}
+4 -4
View File
@@ -864,7 +864,7 @@ STAmount::canonicalize()
{
Throw<std::runtime_error>("Native currency amount out of range");
}
else if (!native() && value_ > kMaxMpTokenAmount)
if (!native() && value_ > kMaxMpTokenAmount)
{
Throw<std::runtime_error>("MPT amount out of range");
}
@@ -927,7 +927,7 @@ amountFromJson(SField const& name, json::Value const& v)
{
Throw<std::runtime_error>("XRP may not be specified with a null Json value");
}
else if (v.isObject())
if (v.isObject())
{
if (!validJSONAsset(v))
Throw<std::runtime_error>("Invalid Asset's Json specification");
@@ -1590,7 +1590,7 @@ mulRoundImpl(STAmount const& v1, STAmount const& v2, Asset const& asset, bool ro
{
CanonicalizeFunc(asset.integral(), amount, offset, roundUp);
}
STAmount result = [&]() {
STAmount result = [&] {
// If appropriate, tell Number to round down. This gives the desired
// result from STAmount::canonicalize.
MightSaveRound const savedRound(Number::RoundingMode::TowardsZero);
@@ -1695,7 +1695,7 @@ divRoundImpl(STAmount const& num, STAmount const& den, Asset const& asset, bool
if (resultNegative != roundUp)
canonicalizeRound(asset.integral(), amount, offset, roundUp);
STAmount result = [&]() {
STAmount result = [&] {
// If appropriate, tell Number the rounding mode we are using.
// Note that "roundUp == true" actually means "round away from zero".
// Otherwise, round toward zero.
+4 -4
View File
@@ -98,13 +98,13 @@ STArray::getFullText() const
for (auto const& obj : v_)
{
if (!first)
r += ",";
r += ',';
r += obj.getFullText();
first = false;
}
r += "]";
r += ']';
return r;
}
@@ -117,13 +117,13 @@ STArray::getText() const
for (STObject const& o : v_)
{
if (!first)
r += ",";
r += ',';
r += o.getText();
first = false;
}
r += "]";
r += ']';
return r;
}
+1 -1
View File
@@ -84,7 +84,7 @@ STLedgerEntry::getFullText() const
ret += format->getName();
ret += ", ";
ret += STObject::getFullText();
ret += "}";
ret += '}';
return ret;
}
+1 -1
View File
@@ -197,7 +197,7 @@ partsFromString(std::string const& number)
{
// integer and fraction
mantissa = boost::lexical_cast<std::uint64_t>(match[2] + match[4]);
exponent = -(match[4].length());
exponent = -match[4].length();
}
if (match[5].matched)
+3 -3
View File
@@ -262,7 +262,7 @@ STObject::set(SerialIter& sit, int depth, bool requireCanonicalOrder)
v_.emplace_back(sit, fn, depth + 1);
// If the object type has a known SOTemplate then set it.
if (auto const obj = dynamic_cast<STObject*>(&(v_.back().get())))
if (auto const obj = dynamic_cast<STObject*>(&v_.back().get()))
obj->applyTemplateFromSField(fn); // May throw
}
@@ -324,7 +324,7 @@ STObject::getFullText() const
}
}
ret += "}";
ret += '}';
return ret;
}
@@ -343,7 +343,7 @@ STObject::getText() const
ret += elem->getText();
}
ret += "}";
ret += '}';
return ret;
}
+2 -2
View File
@@ -138,7 +138,7 @@ STTx::getFullText() const
ret += to_string(getTransactionID());
ret += "\" = {";
ret += STObject::getFullText();
ret += "}";
ret += '}';
return ret;
}
@@ -739,7 +739,7 @@ isMemoOkay(STObject const& st, std::string& reason)
// The only allowed characters for MemoType and MemoFormat are the
// characters allowed in URLs per RFC 3986: alphanumerics and the
// following symbols: -._~:/?#[]@!$&'()*+,;=%
static constexpr std::array<char, 256> const kAllowedSymbols = []() {
static constexpr std::array<char, 256> const kAllowedSymbols = [] {
std::array<char, 256> a{};
std::string_view const symbols(
+1 -1
View File
@@ -136,7 +136,7 @@ template <typename... Args>
void
STVar::constructST(SerializedTypeID id, int depth, Args&&... args)
{
auto constructWithDepth = [&]<typename T>() {
auto constructWithDepth = [&]<typename T> {
if constexpr (std::is_same_v<std::tuple<std::remove_cvref_t<Args>...>, std::tuple<SField>>)
{
construct<T>(std::forward<Args>(args)...);
+1 -1
View File
@@ -185,7 +185,7 @@ public:
operator()(std::size_t ordinal) const
{
// Generates Nth secret key:
auto gsk = [this, tweak = calculateTweak(ordinal)]() {
auto gsk = [this, tweak = calculateTweak(ordinal)] {
auto rpk = root_;
if (secp256k1_ec_seckey_tweak_add(secp256k1Context(), rpk.data(), tweak.data()) == 1)
+1 -1
View File
@@ -226,7 +226,7 @@ TxMeta::getAffectedNode(UInt256 const& node)
// LCOV_EXCL_START
UNREACHABLE("xrpl::TxMeta::getAffectedNode(UInt256) : node not found");
Throw<std::runtime_error>("Affected node not found");
return *(nodes_.begin()); // Silence compiler warning.
return *nodes_.begin(); // Silence compiler warning.
// LCOV_EXCL_STOP
}
+9 -9
View File
@@ -126,7 +126,7 @@ namespace xrpl {
static constexpr char const* kAlphabetForward =
"rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz";
static constexpr std::array<int, 256> const kAlphabetReverse = []() {
static constexpr std::array<int, 256> const kAlphabetReverse = [] {
std::array<int, 256> map{};
for (auto& m : map)
m = -1;
@@ -226,7 +226,7 @@ encodeBase58(void const* message, std::size_t size, void* temp, std::size_t temp
// Apply "b58 = b58 * 256 + ch".
for (auto iter = b58end; iter != b58begin; --iter)
{
carry += 256 * (iter[-1]);
carry += 256 * iter[-1];
iter[-1] = carry % 58;
carry /= 58;
}
@@ -378,7 +378,7 @@ b256ToB58Be(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
// Allocate enough base 2^64 coeff for encoding 38 bytes
// log(2^(38*8),2^64)) ~= 4.75. So 5 coeff are enough
std::array<std::uint64_t, 5> base264CoeffBuf{};
std::span<std::uint64_t> const base264Coeff = [&]() -> std::span<std::uint64_t> {
std::span<std::uint64_t> const base264Coeff = [&] -> std::span<std::uint64_t> {
// convert input from big endian to native u64, lowest coeff first
std::size_t numCoeff = 0;
for (int i = 0; i < base264CoeffBuf.size(); ++i)
@@ -505,13 +505,13 @@ b58ToB256Be(std::string_view input, std::span<std::uint8_t> out)
// (33 bytes for nodepublic + 1 byte token + 4 bytes checksum)
// log(2^(38*8),58^10)) ~= 5.18. So 6 coeff are enough
std::array<std::uint64_t, 6> b5810Coeff{};
auto [num_full_coeffs, partial_coeff_len] = xrpl::b58_fast::detail::divRem(input.size(), 10);
auto const numPartialCoeffs = (partial_coeff_len != 0u) ? 1 : 0;
auto const numB5810Coeffs = num_full_coeffs + numPartialCoeffs;
auto [numFullCoeffs, partialCoeffLen] = xrpl::b58_fast::detail::divRem(input.size(), 10);
auto const numPartialCoeffs = (partialCoeffLen != 0u) ? 1 : 0;
auto const numB5810Coeffs = numFullCoeffs + numPartialCoeffs;
XRPL_ASSERT(
numB5810Coeffs <= b5810Coeff.size(),
"xrpl::b58_fast::detail::b58_to_b256_be : maximum coeff");
for (unsigned char const c : input.substr(0, partial_coeff_len))
for (unsigned char const c : input.substr(0, partialCoeffLen))
{
auto curVal = ::xrpl::kAlphabetReverse[c];
if (curVal < 0)
@@ -523,9 +523,9 @@ b58ToB256Be(std::string_view input, std::span<std::uint8_t> out)
}
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < num_full_coeffs; ++j)
for (int j = 0; j < numFullCoeffs; ++j)
{
unsigned char const c = input[partial_coeff_len + (j * 10) + i];
unsigned char const c = input[partialCoeffLen + (j * 10) + i];
auto curVal = ::xrpl::kAlphabetReverse[c];
if (curVal < 0)
{
+1 -1
View File
@@ -260,7 +260,7 @@ public:
// There is a separate check in `checkpoint` for a valid
// connection in the rare case when the DatabaseCon is destroyed
// after locking this weak_ptr
[wp = std::weak_ptr<Checkpointer>{shared_from_this()}]() {
[wp = std::weak_ptr<Checkpointer>{shared_from_this()}] {
if (auto self = wp.lock())
self->checkpoint();
}))
Loaded 100 of 329 files, more files were not shown because too many files have changed in this diff. Show more