Compare commits

..
Author SHA1 Message Date
Ed Hennis 66c6f21c60 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop: (315 commits)
  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)
  refactor: Use AmendmentsEntry everywhere (8368)
  chore: Update docker images; link Conan-built tools with a static runtime (8520)
  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)
  ...
2026-10-06 19:17:11 -04:00
Ed Hennis 81e06a9ba8 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  fix: Update PermissionedDEX invariant domain tracking for valid offer replacement (7387)
  feat: Check default fields are not default when serializing (6267)
  test: Migrate csf and xrpld-consensus Beast non-JTx tests to GTest (7046)
  test: Modularize Peerfinder component and migrate Peerfinder tests from Beast to GTest and GMock (7054)
  test: Add an RAII class to manage the env.parseFailureExpected flag (7669)
  build: Use custom libc in a devshell by default (7852)
  feat: Add fixCleanup3_4_0 amendment (no functionality yet) (7854)
  ci: Add llvm-tools-preview to rust toolchain (7853)
  ci: Update CI image (7850)
  ci: Update XRPLF/actions (7849)
  chore: Clean up grammar in PR template (7846)
  build: Create versioned compiler/tooling symlinks in nix environments (7844)
  ci: Use rust-overlay to bring Rust into nix (7837)
2026-07-23 21:03:45 -04:00
Ed Hennis b3141d91fa Merge branch 'develop' into ximinez/directory 2026-07-21 19:29:00 -04:00
Ed Hennis 1b1cd4c260 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop: (21 commits)
  fix: Re-store nodes missing from both backends during online_delete rotation (7763)
  fix: Add amendment sponsor for AccountRootsDeletedClean (7801)
  fix: Update base_uint and test changes released in 3.1.3 (7570)
  fix: Handle rounding just above kMaxRep more accurately (7389)
  fix: Document and assert "after" is never null in invariants (7354)
  ci: Run full matrix only on `Ready to merge` or `Full CI build` labeled PRs (7689)
  fix: Strengthen Clawback invariant checks for MPT balances (7285)
  test: Add unit tests for IP address related functions (7744)
  ci: Add Rust to Nix docker image (7571)
  docs: Add more information about pre-commit hooks and how to set them up (7802)
  test: Add JSON array size tests (7592)
  chore: Enable most readability checks (7772)
  ci: Do not run conflict checker when label is applied (7774)
  chore: Run clang_tidy_check with `pass_filenames: false` from pre-commit (7800)
  feat: Add delegate filter param for account_tx RPC (6126)
  refactor: Move `jss.h` `include` out of `Indexes.h` (7799)
  test: Add tests for check doxygen style (7795)
  style: Add pre-commit hook to check doxygen style (7794)
  style: Unify style for all Doxygen comments (7776)
  fix: Improve Number addition/subtraction rounding (7369)
  ...
2026-07-14 20:37:19 -04:00
Ed Hennis a482d6aced Merge branch 'develop' into ximinez/directory 2026-07-09 19:50:00 -04:00
Ed Hennis 299627298f Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  chore: Enable most cppcoreguidelines checks (7660)
  test: Migrate basics Beast tests to GTest (7136)
  test: Migrate resource, shamap Beast tests to GTest (7133)
  chore: Enable most misc checks (7663)
  chore: Fix unity build (7730)
  chore: Enable most modernize checks (7664)
  chore: Delete dead code (7718)
  chore: Enable modernize-use-constraints (7715)
  chore: Enable modernize-avoid-bind (7711)
  chore: Enable modernize-use-auto (7707)
  build: Add protobuf dependencies to Nix (7706)
  feat: Enable ConfidentialTransfer and BatchV1_1 (7698)
  chore: Enable modernize-unary-static-assert (7705)
  chore: Make clang-tidy happy on macOS (7701)
  chore: Improve pre-commit hooks (7702)
  refactor: Retire DisallowIncomingV1 fix (7364)
  build: Add verify-headers target to cleanup headers (7670)
2026-07-07 18:17:50 -04:00
Ed Hennis 640798696b Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  refactor: Retire InnerObjTemplate fix (7368)
  fix: Disable AMM creation with Vault shares (7666)
  test: Add tests for TMProofPathResponse and TMReplayDeltaResponse invalid hash/key sizes (7593)
  ci: [DEPENDABOT] bump actions/setup-python from 6.2.0 to 6.3.0 (7657)
  build: Don't reuse binaries between different C++ versions (7681)
  chore: Update pre-commit hooks && actions (7686)
  feat: Add an invariant to ensure object deletion also deletes its pseudo-account (7445)
  feat: Add Batch (XLS-56) V1_1 (6446)
  feat: Introduce lending 1.1 amendment and add `MemoData` field to `VaultDelete` transaction (6324)
2026-07-01 16:10:38 -04:00
Ed Hennis 47512afad5 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop: (69 commits)
  chore: Use std::ranges where possible (7634)
  ci: Use macOS 26 Tahoe with apple-clang 21 (7601)
  build: Mark sec256k1 and mpt-crypto as transitive headers (7658)
  chore: Add a script to nicely format clang-tidy output (7650)
  chore: Enable most bugprone checks (7643)
  feat: Confidential Transfer for MPT (5860)
  fix: Use trustline balance direction to validate IOU PaymentMint/PaymentBurn (7584)
  fix: Unify freeze checks for pseudo-account deposit/withdraw (7382)
  fix: Block delegate tx from being queued (7640)
  chore: Enable groups of clang-tidy checks by default (7637)
  ci: Better determine when we need to run full clang-tidy (7635)
  refactor: Retire NFTokenReserve fix (7367)
  refactor: Retire Clawback amendment (7353)
  refactor: Rename (mostly keylet) functions to more closely match the docs (7059)
  build: Switch to a new conan XRPLF remote, again (7638)
  chore: Revert "build: Switch to a new conan XRPLF remote (7622)" (7623)
  build: Switch to a new conan XRPLF remote (7622)
  build: Align xrpld RPM packaging with DEB package (7529)
  chore: Use clang-tidy v22 new features (7427)
  build: Patch nix binaries in CMake (7539)
  ...
2026-06-30 17:16:29 -04:00
Ed Hennis ff3708a757 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop: (48 commits)
  test: Add null check unit test for `Oracle::aggregatePrice` (7306)
  ci: Patch conan recipe for Nix to be able to use on macOS (7532)
  ci: Run sanitizers on release builds too (7527)
  fix: Correct hybrid offer deletion on credential expiry (6843)
  ci: Make sanitizer flags lists in the profile, not a string (7449)
  ci: Make configurations launch on certain event types (7447)
  fix: Add [[maybe_unused]] to fix320Enabled for assert=OFF builds (7446)
  ci: Add `gh` and `file` to nix packages (7444)
  fix: Disable transaction invariants (7409)
  perf: Dispatch "hasInvalidAmount()" on type tag instead of dynamic_cast (7402)
  refactor: Retire fixUniversalNumber amendment (5962)
  test: Do not create data directory for memory databases (7323)
  ci: Launch upload-conan-deps on profile change (7442)
  fix: Fix Number comparison operator (7406)
  feat: Use C++ 23 standard (7431)
  refactor: Introduce XRPL_ASSERT_IF for amendment-gated assertions (7378)
  refactor: Change config section and key string literals into constants (7095)
  refactor: Use `std::move` and `std::string_view` where possible (7424)
  refactor: Use const function arguments where possible (7423)
  ci: Use XRPLF/actions build-multiarch-image workflow (7428)
  ...
2026-06-12 11:50:43 -04:00
Ed Hennis 391a1e442c Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop: (41 commits)
  release: Bump version to 3.2.0-rc2 (7348)
  refactor: Enable support for `fixCleanup3_2_0` amendment (7347)
  release: Bump version to 3.2.0-rc1 (7335)
  fix: Fix a rounding error at the `Number::maxRep` cusp (7051)
  ci: Only push docker images in XRPLF/rippled (7330)
  ci: [DEPENDABOT] bump docker/setup-buildx-action from 4.0.0 to 4.1.0 (7322)
  ci: [DEPENDABOT] bump codecov/codecov-action from 6.0.0 to 6.0.1 (7321)
  ci: [DEPENDABOT] bump docker/build-push-action from 7.1.0 to 7.2.0 (7320)
  ci: [DEPENDABOT] bump docker/metadata-action from 6.0.0 to 6.1.0 (7319)
  ci: [DEPENDABOT] bump docker/login-action from 4.1.0 to 4.2.0 (7318)
  fix: Update `clang-tidy` to include `src/tests` directory header check (7307)
  chore: Pin Python packages for codegen using uv (7329)
  style: Use shfmt instead of bashate (7326)
  fix: Fix edge-case where vault-depositor may get stuck (7139)
  fix: Fix `VaultInvariant` and `VaultDeposit` precision bugs at IOU scale boundaries (7272)
  ci: Add clang to nix images (7308)
  fix: Include management-fee delta in doOverpayment assertion (7039)
  fix: Fix clang-tidy pre-commit hook to locate compile_commands.json from repo root (7325)
  fix: Use consistent scale for `debtTotal` (7093)
  fix: Skip deleted book directories and non-root modifications in `ValidBookDirectory` invariant (7312)
  ...
2026-05-27 15:33:45 -04:00
Ed Hennis 9e77212900 Merge branch 'develop' into ximinez/directory 2026-05-19 16:53:55 -04:00
Ed Hennis 93f5a0e217 Merge branch 'develop' into ximinez/directory 2026-05-19 10:15:35 -04:00
Ed Hennis 71367f361c Merge branch 'develop' into ximinez/directory 2026-05-19 05:16:12 -04:00
Ed Hennis 931d21b2a7 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  refactor: Clean up comments post-clang-tidy changes (7283)
  release: Set version to 3.3.0-b0 (7280)
  refactor: Rename static constants (7120)
  refactor: Use `isFlag` where possible instead of bitwise math (7278)
  ci: Update XRPLF/actions (7281)
2026-05-16 09:49:20 -04:00
Ed Hennis c99feb82e7 Merge branch 'develop' into ximinez/directory 2026-05-14 20:39:26 -04:00
Ed Hennis 7b53a5e0c5 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  chore: Consolidate fix amendments (7134)
  ci: Add Conan retry (7147)
  fix: Backport Permissioned Domains fixes (7016)
  refactor: Move unhex lookup table out of function (7104)
  refactor: Improve Forwarded header field parsing (7126)
  fix: Check network ID in `transactionSignFor` (7102)
  feat: Implement nix-based Dockerfile for CI (7083)
2026-05-14 10:46:04 -04:00
Ed Hennis 4a02518497 Merge branch 'develop' into ximinez/directory 2026-05-13 12:03:59 -04:00
Ed Hennis 0b6c3630cc Merge branch 'develop' into ximinez/directory 2026-05-12 19:19:05 -04:00
Ed Hennis 4d04ba5be5 Merge branch 'develop' into ximinez/directory 2026-05-12 16:26:28 -04:00
Ed Hennis ed53557d41 Merge branch 'develop' into ximinez/directory 2026-05-11 13:34:31 -04:00
Ed Hennis e4d10393f3 Merge branch 'develop' into ximinez/directory 2026-05-07 18:10:21 -04:00
Ed Hennis fcc7f57e82 Merge branch 'develop' into ximinez/directory 2026-05-07 14:18:48 -04:00
Ed Hennis a25229f154 Merge branch 'develop' into ximinez/directory 2026-05-07 13:28:50 -04:00
Ed Hennis eb6eaf2532 Merge branch 'develop' into ximinez/directory 2026-05-06 22:34:41 -04:00
Ed Hennis ff987fc7c6 Merge branch 'develop' into ximinez/directory 2026-05-06 14:18:20 -04:00
Ed Hennis d21137c4c1 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  fix: Fix regressions in `server_definitions` (7008)
  chore: Do not duplicate sanitizer flags (7058)
  ci: Run pre-commit on diff in clang-tidy workflow (7078)
  ci: Use XRPLF/create-issue (7076)
  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 16:45:19 -04:00
Ed Hennis ac7db2e621 Remove orphaned code that was introduced by a bad merge or rebase 2026-05-05 15:48:00 -04:00
Ed Hennis 42005a8080 Merge branch 'develop' into ximinez/directory 2026-05-01 13:59:22 -04:00
Ed Hennis 1f7b1b3a78 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  feat: Create new transaction testing framework `TxTest` (6537)
  feat: Add cleanup amendment for 3.2.0 (7037)
  fix: Fix ubsan flagged issues (6151)
2026-04-28 15:28:15 -05:00
Ed Hennis 80b90544c5 Merge branch 'develop' into ximinez/directory 2026-04-25 14:46:02 -04:00
Ed Hennis 00b9a8cd67 Merge branch 'develop' into ximinez/directory 2026-04-23 15:56:20 -04:00
Ed Hennis 3be49f814a Merge branch 'develop' into ximinez/directory 2026-04-22 23:40:54 -04:00
Ed Hennis 1674fabe81 Merge branch 'develop' into ximinez/directory 2026-04-22 14:49:21 -04:00
Ed Hennis 6dfa47ce7a Merge branch 'develop' into ximinez/directory 2026-04-22 13:10:52 -04:00
Ed Hennis bef095be65 Merge branch 'develop' into ximinez/directory 2026-04-21 18:58:08 -04:00
Ed Hennis 8e5d774c36 Merge branch 'develop' into ximinez/directory 2026-04-20 17:49:55 -04:00
Ed Hennis fb8fb30f6c Merge branch 'develop' into ximinez/directory 2026-04-20 15:45:12 -04:00
Ed Hennis a553001125 Merge branch 'develop' into ximinez/directory 2026-04-20 11:39:16 -04:00
Ed Hennis 57782e84ee Merge branch 'develop' into ximinez/directory 2026-04-17 18:14:35 -04:00
Ed Hennis 9d5076c8a9 Merge branch 'develop' into ximinez/directory 2026-04-16 13:44:45 -04:00
Ed Hennis 1af379e09f Merge branch 'develop' into ximinez/directory 2026-04-15 19:06:37 -04:00
Ed Hennis 1ced0875ae Merge branch 'develop' into ximinez/directory 2026-04-15 14:29:04 -04:00
Ed Hennis 53e6d7580a rabbit hole: refactor dirAdd to find gaps in "full" directories.
- This would potentially be very expensive to implement, so don't.
- However, it might be a good start for a ledger fix option.
2026-04-13 19:50:28 -04:00
753 changed files with 20747 additions and 36126 deletions

No files matched your search

-11
View File
@@ -5,10 +5,7 @@ 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,
@@ -17,7 +14,6 @@ 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,
@@ -36,7 +32,6 @@ Checks: "-*,
llvm-namespace-comment,
misc-*,
-misc-explicit-constructor,
-misc-multiple-inheritance,
-misc-no-recursion,
-misc-non-private-member-variables-in-classes,
@@ -50,8 +45,6 @@ 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-*,
@@ -60,7 +53,6 @@ Checks: "-*,
-performance-noexcept-move-constructor,
-performance-unnecessary-copy-initialization,
-performance-unnecessary-value-param,
-performance-use-std-move,
readability-*,
-readability-avoid-const-params-in-decls,
@@ -73,10 +65,7 @@ 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-trivial-switch,
-readability-uppercase-literal-suffix
"
# ---
-72
View File
@@ -108,75 +108,3 @@ endfunction()
function(patch_nix_binary target)
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()
+5 -14
View File
@@ -15,9 +15,9 @@ inputs:
required: false
default: "false"
log_verbosity:
description: 'The logging verbosity ("quiet", "verbose"), or empty to use the Conan defaults.'
description: "The logging verbosity."
required: false
default: ""
default: "verbose"
sanitizers:
description: "The sanitizers to enable."
required: false
@@ -35,16 +35,6 @@ 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}" \
@@ -52,7 +42,8 @@ runs:
--options:host='&:xrpld=True' \
--settings:all build_type="${BUILD_TYPE}" \
--conf:all tools.build:jobs=${BUILD_NPROC} \
"${VERBOSITY_ARGS[@]}" \
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
--format=json \
. >"${RUNNER_TEMP}/conan-graph.json"
@@ -61,4 +52,4 @@ runs:
- 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"
run: ./bin/check-build-context-runtime.sh "${RUNNER_TEMP}/conan-graph.json"
@@ -174,10 +174,8 @@ test.server > xrpl.basics
test.server > xrpl.config
test.server > xrpld.app
test.server > xrpld.core
test.server > xrpld.rpc
test.server > xrpl.json
test.server > xrpl.protocol
test.server > xrpl.resource
test.server > xrpl.server
test.unit_test > xrpl.basics
test.unit_test > xrpl.protocol
+1 -1
View File
@@ -1,5 +1,5 @@
{
"image_tag": "sha-3d526d4",
"image_tag": "sha-ed96e60",
"configs": {
"ubuntu": [
{
+3 -3
View File
@@ -12,7 +12,7 @@ on:
- "!nix/docker/README.md"
- "!nix/devshell.nix"
- "!nix/check-tools/**"
- "bin/nix/default-loader-path.sh"
- "bin/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/nix/default-loader-path.sh"
- "bin/install/sanitizer-libs.sh"
- "bin/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:
+2 -2
View File
@@ -34,7 +34,7 @@ permissions:
jobs:
audit:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-ed96e60
permissions:
contents: read
# Needed to open an issue on scheduled failures.
@@ -66,7 +66,7 @@ jobs:
- name: Create issue
if: ${{ steps.audit.outcome != 'success' && github.event_name == 'schedule' }}
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
with:
title: "cargo audit found vulnerabilities"
body_file: /tmp/cargo-audit-issue.md
+1 -1
View File
@@ -53,7 +53,7 @@ jobs:
- name: Create issue
if: ${{ failure() && github.event_name == 'schedule' && github.repository == 'XRPLF/rippled' }}
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
with:
title: "Releases not merged back into develop"
body_file: ${{ env.ISSUE_FILE }}
+2 -2
View File
@@ -79,7 +79,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
@@ -108,7 +108,7 @@ jobs:
- name: Upload regenerated snapshot
if: failure()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: check-tools-${{ runner.os }}-${{ runner.arch }}
path: ${{ matrix.snapshot }}
+2 -1
View File
@@ -93,8 +93,9 @@ jobs:
.github/workflows/reusable-upload-recipe.yml
.clang-tidy
.codecov.yml
bin/check-nix-store-refs.sh
bin/check-tools.sh
bin/nix/**
bin/default-loader-path.sh
cfg/**
cmake/**
conan/**
+2 -1
View File
@@ -31,8 +31,9 @@ on:
- ".github/workflows/reusable-upload-recipe.yml"
- ".clang-tidy"
- ".codecov.yml"
- "bin/check-nix-store-refs.sh"
- "bin/check-tools.sh"
- "bin/nix/**"
- "bin/default-loader-path.sh"
- "cfg/**"
- "cmake/**"
- "conan/**"
+2 -2
View File
@@ -14,7 +14,7 @@ on:
jobs:
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
run-hooks:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@d7f2acb47d9662e1e2f8b1f5feffa6d21cc3290a
uses: XRPLF/actions/.github/workflows/pre-commit.yml@279ec358f4a1be4088be3e024b07916fa97c75b6
with:
runs_on: ubuntu-latest
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-70b8fd3" }'
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-3a2d19f" }'
+2 -2
View File
@@ -41,13 +41,13 @@ env:
jobs:
build:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-ed96e60
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
@@ -129,7 +129,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: ${{ inputs.ccache_enabled }}
@@ -186,6 +186,9 @@ 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
@@ -254,20 +257,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/nix/check-nix-store-refs.sh "${BUILD_DIR}"
run: ./bin/check-nix-store-refs.sh "${BUILD_DIR}"
- name: Check the Conan cache for Nix store references (Nix toolchain)
if: ${{ inputs.toolchain == 'nix' }}
run: ./bin/nix/check-nix-store-refs.sh "${CONAN_HOME}"
run: ./bin/check-nix-store-refs.sh "${CONAN_HOME}"
# Only what PatchNixBinary.cmake retargets: the toolchain in the Linux
# 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/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"
./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"
- name: Show ccache statistics
if: ${{ inputs.ccache_enabled }}
@@ -280,7 +283,7 @@ jobs:
- name: Upload the binary (Linux)
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && runner.os == 'Linux' }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: xrpld-${{ inputs.config_name }}
path: ${{ env.BUILD_DIR }}/xrpld
@@ -294,7 +297,7 @@ jobs:
- name: Upload the validator-keys binary
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && env.VALIDATOR_KEYS_ENABLED == 'true' }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: validator-keys-${{ inputs.config_name }}
path: |
@@ -305,7 +308,7 @@ jobs:
- name: Upload the test binary (Linux)
if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: xrpl_tests-${{ inputs.config_name }}
path: ${{ env.BUILD_DIR }}/xrpl_tests
@@ -321,7 +324,7 @@ jobs:
- name: Upload server definitions
if: ${{ github.event.repository.visibility == 'public' && inputs.config_name == 'ubuntu-gcc-debug-amd64-coverage' }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: server-definitions
path: ${{ env.BUILD_DIR }}/server_definitions.json
+6 -5
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-3d526d4"
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-ed96e60"
permissions:
contents: read
issues: write
@@ -43,7 +43,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
@@ -73,6 +73,7 @@ jobs:
with:
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ env.BUILD_TYPE }}
log_verbosity: verbose
- name: Configure CMake
working-directory: ${{ env.BUILD_DIR }}
@@ -109,7 +110,7 @@ jobs:
- name: Upload clang-tidy output
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
path: ${{ env.OUTPUT_FILE }}
archive: false
@@ -133,7 +134,7 @@ jobs:
- name: Upload clang-tidy diff output
if: ${{ github.event.repository.visibility == 'public' && steps.files_changed.outcome != 'success' }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
path: ${{ env.DIFF_FILE }}
archive: false
@@ -185,7 +186,7 @@ jobs:
- name: Create issue
if: ${{ steps.run_clang_tidy.outcome != 'success' && inputs.create_issue_on_failure }}
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
with:
title: "Clang-tidy check failed"
body_file: ${{ env.ISSUE_FILE }}
@@ -44,7 +44,7 @@ jobs:
# Every package lands in one directory; the step below picks its own,
# which keeps this independent of the artifact names.
- name: Download package artifacts
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: "*-pkg"
merge-multiple: true
+9 -9
View File
@@ -100,18 +100,18 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
- name: Download pre-built xrpld binary
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ matrix.xrpld_artifact_name }}
path: ${{ env.BUILD_DIR }}
- name: Download pre-built validator-keys binary
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ matrix.validator_keys_artifact_name }}
path: ${{ env.BUILD_DIR }}
@@ -151,7 +151,7 @@ jobs:
# 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-...'.
- name: Upload package artifact
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ matrix.xrpld_artifact_name }}-pkg
path: |
@@ -160,7 +160,7 @@ jobs:
if-no-files-found: error
- name: Upload debug symbol artifact
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ matrix.xrpld_artifact_name }}-pkg-debug
path: |
@@ -225,13 +225,13 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
# Both artifacts, so the debug symbols are published alongside the package.
- name: Download package artifacts
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: ${{ matrix.xrpld_artifact_name }}-pkg*
merge-multiple: true
@@ -287,7 +287,7 @@ jobs:
run: echo "PUSH=${PUSH}" | tee -a "${GITHUB_ENV}"
- name: Download package artifacts
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: "*-pkg"
merge-multiple: true
@@ -295,7 +295,7 @@ jobs:
- name: Download voidstar binary
if: ${{ matrix.target == 'voidstar' }}
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: xrpld-ubuntu-clang-debug-amd64-voidstar
path: ${{ env.CONTEXT }}
+3 -3
View File
@@ -28,7 +28,7 @@ permissions:
jobs:
clippy:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-ed96e60
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -41,7 +41,7 @@ jobs:
coverage:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-ed96e60
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -70,7 +70,7 @@ jobs:
doc:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-ed96e60
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+2 -2
View File
@@ -40,7 +40,7 @@ defaults:
jobs:
upload:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-ed96e60
env:
REMOTE_NAME: ${{ inputs.remote_name }}
CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.remote_username }}
@@ -50,7 +50,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
+5 -2
View File
@@ -68,7 +68,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
@@ -108,11 +108,14 @@ 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/nix/check-nix-store-refs.sh "${CONAN_HOME}"
run: ./bin/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') }}
+5 -6
View File
@@ -60,7 +60,7 @@ repos:
types_or: [c++, c]
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: a9a8a861f30ed207ead7d5a3b7e8032283ba5da7 # frozen: v23.1.2
rev: e2b496dc2bd8340c2524cb9a2d2a943cde1bb6df # frozen: v23.1.1
hooks:
- id: clang-format
args: [--style=file]
@@ -82,10 +82,9 @@ repos:
files: ^crates/.*\.rs$
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
rev: 28010ddd6016e1a0f7bd232acb6536ef996ae897 # frozen: 0.29.2
rev: f1c4833f8cf23c6d952673abc73525411a5719e8 # frozen: 0.29.1
hooks:
- id: gersemi
args: [-i, --warnings-as-errors]
- repo: https://github.com/rbubley/mirrors-prettier
rev: ef4a397f916211b4a39ccf9d3d9cbb6562157251 # frozen: v3.9.9
@@ -96,19 +95,19 @@ repos:
# Scoped to package/: the rest of the repo's Python has pre-existing findings,
# so widening these is its own change.
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: f12be1ebaa5351c1fc76472de98db2c3446c8253 # frozen: v0.16.10
rev: a56c0b927e6465d37cae3e97d35d4d18ab2b96cd # frozen: v0.16.9
hooks:
- id: ruff-check
args: [--fix]
files: ^package/.*\.py$
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 96ae3e5802f3fe2d551e703e18f0a367d1a81ac2 # frozen: 26.10.0
rev: 4160603246a6b365d4a2af661c6d71b0a0f50478 # frozen: 26.5.1
hooks:
- id: black
- repo: https://github.com/pre-commit/mirrors-mypy
rev: 2834ec6639549dd6796205c8f011dedcd587288b # frozen: v2.4.0
rev: 7ff8d35ae36a7d2b968f2f90b4c723e292e594ee # frozen: v2.3.1
hooks:
- id: mypy
args: [--strict]
+3 -41
View File
@@ -6,19 +6,13 @@ For info about how [API versioning](https://xrpl.org/request-formatting.html#api
The API version controls the API behavior you see. This includes what properties you see in responses, what parameters you're permitted to send in requests, and so on. You specify the API version in each of your requests. When a breaking change is introduced to the `xrpld` API, a new version is released. To avoid breaking your code, you should set (or increase) your version when you're ready to upgrade.
The [commandline](https://xrpl.org/docs/references/http-websocket-apis/api-conventions/request-formatting/#commandline-format) sends `api_version` 1 unless the request names one. `kApiCommandLineVersion` is stamped on a request naming none, and a static assert holds it at or below the highest non-beta version, so the default cannot reach 3; the `json` and `json2` commands pass a caller-supplied `api_version` through as given. The command line is intended for ad-hoc usage by humans, not programs or automated scripts. The command line is not meant for use in production code.
The [commandline](https://xrpl.org/docs/references/http-websocket-apis/api-conventions/request-formatting/#commandline-format) always uses the latest API version. The command line is intended for ad-hoc usage by humans, not programs or automated scripts. The command line is not meant for use in production code.
For a log of breaking changes, see the **API Version [number]** headings. In general, breaking changes are associated with a particular API Version number. For non-breaking changes, scroll to the **XRP Ledger version [x.y.z]** headings. Non-breaking changes are associated with a particular XRP Ledger (`xrpld`) release.
## API Version 3 (Beta)
API version 3 is currently a beta API. It requires `[beta_rpc_api]` set to `1` in the xrpld configuration to use; the section takes one value line, and a bare header leaves the flag off. See [API-VERSION-3.md](API-VERSION-3.md) for the full list of changes in API version 3.
From this version, replies take the JSON-RPC 2.0 envelope on both transports, with the deviations [API-VERSION-3.md](API-VERSION-3.md) lists, a top-level array is accepted as a batch, and subscription messages are sent as notifications. The `ripplerpc` field no longer selects the reply envelope and is ignored.
A request that is rejected before it reaches a method is answered with a JSON-RPC error object carrying `jsonrpc`, `id` and `error`, whether it was sent alone or as an entry in a batch; the `id` is the request's own, or `null` where the `id` itself was the unusable member. The HTTP status is the one the matching rejection reports at earlier versions; the two rejections version 3 adds, an unusable `id` and a `method` disagreeing with the one inside `params`, answer 400. On the JSON-RPC transport three classes of rejection stay a plain text body, because the server cannot tell which envelope the client speaks: a body it could not parse or that exceeds the size limit, a body that parses to `{}` or `null` and so carries no request, and a request whose `api_version`, where the server reads it, names a version it does not serve, unless it is an entry of a batch. That place is inside `params` for a lone JSON-RPC request, a top-level value naming such a version being ignored there and the request served as version 1. The WebSocket transport never answers plain text: a message naming such a version at its top level, where that transport reads it, is answered in the legacy frame those versions have always used, and a frame the server cannot read is answered with the `jsonInvalid` frame, at every version. An empty array `[]` is not in the second class: only a version 3 client sends an array, so it is answered with a `-32600` error object and `Request is empty`. A batch entry is not in the third: an entry of a top-level array naming such a version is answered in place with a `-32606` error object in the array's envelope, and an entry of a `"method": "batch"` request is answered with an error object in the body's envelope, so neither takes the body down with it. A version 3 client must therefore tolerate a non-JSON body for the three classes.
A JSON-RPC (HTTP) request may also name `api_version` at its top level, beside `method` and `id`, and may send `params` as the object itself rather than an array holding it. Neither reaches the WebSocket transport, whose message is one flat object that has always carried `api_version` at its top level and whose members are the parameters themselves, so a `params` member there is not unpacked. The `params` object is the specification's own spelling; `api_version` is an XRPL extension, which the specification does not define, placed beside the members it does. Both are additive: for a lone request a top-level `api_version` is honored only when it names version 3 or above, since a lower one has been answered as version 1 for years. An entry of either batch form honors any version it names at its top level: a `"method": "batch"` entry carries its parameters at its own top level, so that is where its version sits, and one that carries a by-name `params` object is read for `api_version` and credentials from that object instead; an array entry is read the same way so that the two forms agree, and an entry naming a served version other than the body's refuses the body, while one naming a version the server does not serve is answered on its own.
API version 3 is currently a beta API. It requires enabling `[beta_rpc_api]` in the xrpld configuration to use. See [API-VERSION-3.md](API-VERSION-3.md) for the full list of changes in API version 3.
## API Version 2
@@ -28,44 +22,13 @@ API version 2 is available in `xrpld` version 2.0.0 and later. See [API-VERSION-
This version is supported by all `xrpld` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
## Unreleased
### Breaking changes
- The `ripplerpc` request field, which selects the shape of the JSON-RPC reply envelope, is now validated, and a value that is not exactly `"1.0"`, `"2.0"` or `"3.0"` is rejected. 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. `API-VERSION-3.md` describes the procedure and that risk. 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. No test pinned the mixing behavior and the line that produced it 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: a per-entry version made the entry cap above unanswerable, since a cap can only ask about a body that has one version.
### Additions
- A JSON-RPC (HTTP) request may send its parameters as an object, `"params": {"account": "r..."}`, as well as the array of one object that was already accepted. This reaches every API version: such a request was previously rejected with HTTP 400 and `params unparsable`, and is now served. A request that already sends the array form is unaffected. An entry of a `"method": "batch"` request that carries a by-name `params` object is read for `api_version` and credentials from that object. Previously such an entry had its `api_version` read from its top level and its credentials ignored, since credentials were read only from an array-form `params`.
- A lone JSON-RPC (HTTP) request naming `api_version` 3 or above at its own top level, beside `method` and `id`, is now answered at that version. The member is an XRPL extension, which the JSON-RPC 2.0 specification does not define, placed beside the members it does. It was previously answered at version 1, the version being read from inside `params` alone; a WebSocket request, which is one flat object, has always been read there. This is deliberate: reading the version beside the specification's own members is what lets a version 3 client send a specification-shaped request. A top-level value below version 3, or one the server does not serve, is still ignored for a lone request, since `"api_version": 2` there has been answered as version 1 for years and honoring it now would change a shipped reply shape. Only API version 3 is reachable this way, and it is gated behind `[beta_rpc_api]`.
### Bugfixes
- A request echoed back in an error reply now has every credential-bearing field masked: `admin_password`, `admin_user`, `passphrase`, `password`, `secret`, `seed`, `seed_hex`, `url_password`, `url_username` and `username`. Nesting no longer matters, so a credential inside `params` is masked too. The same masking is applied to every request and reply written to the log, and it covers six further names that only a reply carries: `master_key`, `master_seed`, `master_seed_hex`, `validation_key`, `validation_private_key` and `validation_seed`, which is how `wallet_propose` and `validation_create` used to write a live private key to the log. A request or reply written to the log is truncated at 10,000 characters. An `[rpc_startup]` line that does not parse is reported by its position in the section and the parser's message, never by its text, and no command runs for it.
- The command line client no longer prints a credential the operator did not type. A failing command echoes the request it built under `request_sent`, which carries the `admin_password` the client copies out of `[port_rpc]` in the config, so `./xrpld account_info rBogus` printed that password to stdout and into any captured output. `request_sent` is now masked. The `rpc` member beside it, which echoes the arguments as they were typed, is unchanged. The command line client also no longer writes an unparsed `json` or `ripple_path_find` argument to its trace log before parsing it, where a `secret` inside that argument could not be masked; it logs the parsed request instead, masked. The reply it receives is logged the same way, parsed and masked, where the raw body was written before, a `validation_create` answer included.
- A WebSocket frame that does not parse, or exceeds the request size limit, is answered `{"type": "error", "error": "jsonInvalid", "size": <bytes>}`. The frame's body is reported by size rather than echoed back in a `value` member, since a body that does not parse has no fields to mask. A client that read `value` gets `size` instead.
- Four error codes that named no HTTP status of their own, and so answered 200 on a reply reporting an error, now name one: `actMalformed`, `alreadyMultisig` and `alreadySingleSig` answer 400, and `actNotFound` answers 404. **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 twenty-one `malformed*` tokens `ledger_entry` names each report the code they own instead of 31. See [API-VERSION-3.md](API-VERSION-3.md).
- A reply reporting HTTP 402 or 502 now carries a status line. Those two statuses named no case in the switch that writes one, so such a reply began with a header instead and did not parse as an HTTP response at all. Both are reachable at any API version with `ripplerpc: "3.0"`, which derives the status from the error code: 402 through `highFee` from `sign`, `sign_for` or `submit` with a low `fee_mult_max`, and 502 through `dbDeserialization` from `tx`. The eleven statuses that already named a case report the same phrase they always have.
- An error reply to a request sending `ripplerpc: "2.0"` or `"3.0"` no longer carries a stray `"error_message": null` beside the error it reports. The member appeared only when the `Server` log partition was set to debug or lower, because the log statement read `error_message` after the reply had renamed it to `message`, and reading it put it back as null. So the reply a client received depended on the server's log level, and the log line itself printed an empty message. Both are fixed.
- A body the server rejects before it reads a request out of it now says 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. 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. Ten 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, and six ways a top-level array is not a batch this server can serve. The answer to the first five 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.
- `batch`: A batch request served at API version 3 or above is now refused when it holds more than 100 entries, before any entry is dispatched. The cap reads the one version the body is served at, so no ordering of the entries evades it. A body served below version 3 is unaffected and stays bounded only by the request size limit.
- 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
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 the same `transaction` message as the `transactions` stream for each validated transaction whose metadata affects a subscribed issuance. MPT issuance subscriptions count toward the per-connection subscription limit. An empty array, a non-array value, or an invalid ID returns `invalidParams`. ([#5671](https://github.com/XRPLF/rippled/pull/5671))
- `subscribe`, `unsubscribe`: Added an optional `mpt_issuances` request field, an array of MPT issuance IDs (hex strings). Subscribers receive a message with `type` `mptTransaction` for each validated transaction whose metadata affects a subscribed issuance; the message has the same fields as the `transactions` stream. MPT issuance subscriptions count toward the per-connection subscription limit. An empty array, a non-array value, or an invalid ID returns `invalidParams`. ([#5671](https://github.com/XRPLF/rippled/pull/5671))
- `ledger_entry`: Add full support for checks, NFT offers, payment channels, and signer lists. ([#6319](https://github.com/XRPLF/rippled/pull/6319))
### Bugfixes in 3.5.0
@@ -97,7 +60,6 @@ Version 3.4.0 is not yet released. These changes are available in the 3.4.0 beta
- `account_lines`: The `peer` field now returns an error if the value is not a string. [#7728](https://github.com/XRPLF/rippled/pull/7728)
- `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)).
- `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
+1 -244
View File
@@ -1,220 +1,11 @@
# API Version 3
API version 3 is currently a **beta API**. It requires `[beta_rpc_api]` set to `1` in the xrpld configuration to use; the section takes one value line, and a bare header leaves the flag off. To use this API, clients specify `"api_version" : 3` in each request.
API version 3 is currently a **beta API**. It requires enabling `[beta_rpc_api]` in the xrpld configuration to use. To use this API, clients specify `"api_version" : 3` in each request.
For info about how [API versioning](https://xrpl.org/request-formatting.html#api-versioning) works, including examples, please view the [XLS-22d spec](https://github.com/XRPLF/XRPL-Standards/discussions/54). For details about the implementation of API versioning, view the [implementation PR](https://github.com/XRPLF/rippled/pull/3155). API versioning ensures existing integrations and users continue to receive existing behavior, while those that request a higher API version will experience new behavior.
## Breaking Changes
### Replies take the JSON-RPC 2.0 envelope
Every reply the server can attribute to API version 3 takes the envelope the [JSON-RPC 2.0 specification](https://www.jsonrpc.org/specification) defines, on both the JSON-RPC and WebSocket transports. The Deviations section below lists where the content departs from the specification, and the rejections that stay a plain text body. This replaces the three envelope shapes selected by the `ripplerpc` request field, none of which conformed to the specification that the field is named after.
A successful reply carries the payload under `result`:
```json
{
"jsonrpc": "2.0",
"id": 7,
"result": { "ledger_hash": "F742...", "ledger_index": 2 }
}
```
A failure carries it under `error` instead:
```json
{
"jsonrpc": "2.0",
"id": 7,
"error": {
"code": -32000,
"message": "Account malformed.",
"data": { "error": "actMalformed", "error_code": 35 }
}
}
```
Compared with earlier versions:
- **`jsonrpc` is always present** and names the protocol version.
- **`id` is echoed from the top level of the request**, where the specification puts it. This changes the JSON-RPC transport only. Earlier versions of that transport echoed `id` only when it was nested inside `params`, so a client that placed it correctly received no `id` and could not correlate the reply with its request. A WebSocket session has always echoed a top-level `id`, and is unaffected. A request that names no `id` receives `"id": null`, so that a reply is always distinguishable from a notification; the specification would send nothing, which the Deviations section below records. The specification allows a string, a number or null there, so a request naming anything else there, an object, an array or a boolean, is rejected as an invalid request, on both transports; that reply names `"id": null` too, the id being the thing that was wrong. A number is read as this server reads every JSON number: an integer from -2147483648 to 4294967295, or a fraction. An integer outside that range fails to parse, and the body is refused as unreadable before any envelope is chosen, so a client using a millisecond timestamp as an `id` should send it as a string; the Deviations section below records the bound. Earlier versions echo whatever they are given, whatever its shape, and continue to.
- **`status` is gone from the reply envelope**, at both levels. Whether the call succeeded is already carried by which of `result` or `error` is present. Earlier versions also let `path_find`'s `status` subcommand report one inside `result`; that one is dropped too. A subscription notification is not a reply and keeps whatever the event carries: the `transactions` stream reports `"closed"` or `"proposed"` in a `status` member of the event itself, so a version 3 subscriber still receives it under `params`.
- **`error.code` is `-32000`** for any request that reaches a command, the specification's reserved code for an implementation-defined server error. The XRPL error token and numeric code move into `error.data`, so the two code spaces stay separate and renumbering an XRPL error can never change a JSON-RPC code. Everything else the handler reported about the failure also travels in `data`. A request naming a method this server does not have reaches no command, and the specification gives that one condition a code of its own, so it reports `-32601` instead, with `unknownCmd` and its code still under `data`.
- **A notice stays at the top level.** Three member names are notices: `warning`, `warnings` and `deprecated`. The rule is positional, not a judgment about what each one says: any of the three that a handler puts at the **top level of its result** is moved beside the specification's members, and one nested deeper is left where the handler put it. So `ledger`'s `warnings` is moved, while `server_info`'s, nested under `info`, and `server_state`'s, nested under `state`, are not. Two of the three moved members do describe one outcome rather than the server: `wallet_propose`'s `warning` describes the wallet the call just produced, and `subscribe`'s describes an experimental feature. Both are moved, because they sit at that top level.
- **`error_exception` is gone; its text is `error.message`.** `submit` and `simulate` reported the specific detail of a failure in an `error_exception` member of their own, leaving a generic `error_message` beside it: a `tx_blob` that fails to parse reported both `"Transaction is invalid."` and `"Transaction length invalid"`. The specific text is now the `message`, which is where every other handler puts it, and the token and code in `data` still say what kind of failure it was. A client that read `error_exception` must read `error.message`.
- **The request is not echoed back.** Earlier versions echoed it on version 1 errors. A request rejected before it reaches a command is not echoed either, and the shape its reply takes is described below.
- **`ripplerpc` is ignored.** It no longer selects the envelope. The field is ignored rather than rejected, as any other field the server does not honor is.
The envelope above describes a request that reaches a command. A request the server rejects before then (one naming no method, or a method that is not a string, or one refused for permissions or load) is answered differently, since there is no handler result to shape. One case has no reply at all: a WebSocket sender over the resource drop threshold is disconnected, whatever its message carried, as it has been at every version, while the JSON-RPC transport answers that sender with 503 and `Server is overloaded`. A request whose `api_version`, where the server reads it, names a version it does not serve is rejected before then too, but is answered outside the envelope, as plain text on the JSON-RPC transport and in the legacy frame on WebSocket, unless it is an entry of a batch, as described below: the server cannot tell which envelope that client speaks. That place is inside `params` for a lone JSON-RPC request, a top-level value naming such a version being ignored there and the request served as version 1, as the request section below describes, and the top level of a WebSocket message.
Such a rejection is a specification error object, whether the request was sent alone or as an entry in a batch, correlated by the request's own `id`, or naming `"id": null` where the `id` itself was the unusable member:
```json
{
"jsonrpc": "2.0",
"id": 2,
"error": { "code": -32602, "message": "params unparsable" }
}
```
The HTTP status is the one the rejection has always reported: 400 for a malformed request, 403 for a forbidden one and 503 for an overloaded server. Earlier versions receive that status with the message as a bare text body (`Null method`, `params unparsable`), and continue to. A request sent as an entry of a batch reports no status of its own, the body carrying several outcomes; the batch section below says where its outcome is stated instead.
The rejected request is **not** echoed back. Earlier versions echo a rejected batch entry with its credentials masked and continue to do so; the specification makes `error.data` optional, a client already knows what it sent, and copying a whole entry per rejection is what an overloaded server must not do.
The codes reported here are the specification's own: `-32600` for a request that names no usable `method`, or is not a JSON object at all, and `-32602` for invalid parameters. Earlier versions report `-32601`, method not found, for such an entry of a `"method": "batch"` request, where version 3 reports `-32600`; a lone request there is answered as plain text, with no code at all. `-32601` is what they have always sent for the entry and moving it would change `error.code` for their clients. Version 3 keeps `-32601` for the one condition the specification defines it for, a request naming a method this server does not have, which is answered from the reply path above rather than as a rejection: a request naming no usable method names nothing that could be found or not found. A request naming one method at its top level and another inside `params` names two, which is not that condition either, so it reports `-32600` from version 3 up on the JSON-RPC transport, the WebSocket transport having no `params` to disagree with, its `command` and `method` disagreement being described below; earlier versions of the JSON-RPC transport answer it as `unknownCmd` with `error_code` 32 at HTTP 200 in the `ripplerpc` `"1.0"` and `"2.0"` envelopes, and at 405 in the `"3.0"` envelope, and continue to. They also report `-32604` for an overloaded server, `-32605` for a forbidden request and `-32606` for an unsupported API version, which lie in the range the specification reserves for the protocol rather than the `-32000..-32099` range it leaves to implementations. Those are unchanged at every version, for the same reason.
Those three codes belong to a rejection the server makes before it dispatches a request. Load and permission can also be reported once a request has been read, and then they carry an XRPL token and so report `-32000` like any other: a request refused because the job queue is full reports `-32000` with `tooBusy` under `data` and HTTP 503, and an admin-only command called without the role reports `-32000` with `noPermission` and HTTP 401. The rule is not which subject the failure is about: **every error carrying an XRPL token reports `-32000`, with the one exception of `unknownCmd`, which reports `-32601`.**
On the JSON-RPC transport three classes of rejection are answered as plain text at every version, including this one, because the server cannot tell which envelope the client speaks:
- a body it could not parse, and one larger than the request size limit;
- a body that parses but carries no request: `{}` or `null`;
- a request whose `api_version`, read from inside `params` for a lone request, names a version the server does not serve, unless it is an entry of a batch.
The first two name no version anywhere. The third names one, but not one this server has, so it cannot know what that client expects. A lone request naming such a version at its top level only is not in the third: that value is ignored, as the request section below describes, and the request is served as version 1. A version 3 client must therefore tolerate a non-JSON body for these. A top-level value that is neither an object nor an array, such as `42` or `"text"`, does not parse at all and falls in the first class.
The WebSocket transport never answers plain text. A frame the server cannot read is answered with the `jsonInvalid` frame described below, and a frame naming an `api_version` the server does not serve is answered in the legacy envelope those versions have always used: `{"type": "response", "status": "error", "error": "invalid_API_version", "request": { ... }}`, with the request echoed and its credentials masked. That is the reply a version 3 WebSocket client receives from a server where `[beta_rpc_api]` is not enabled.
An entry of a top-level array is the exception to the third, because the array's own version is known: only a version 3 client sends an array at all. Such an entry is answered with a `-32606` error object in the array's envelope, described in the batch section below. An entry of a `"method": "batch"` request is answered the same way when the body is served at version 3, which it is when the body or any of its entries names it; a body served below version 3 keeps the shape earlier versions send.
One rejection is worth naming separately. On the WebSocket transport there are four ways for a request to name no one command to dispatch on: it names neither `command` nor `method`, one of those two is not a string, or the two disagree. From version 3 each is answered in the specification envelope, reporting `-32600` and a message naming which of the four it was. No such reply carries `data`: a rejection is not a failure a command reported, so it has no XRPL token to put there. Earlier versions answer all four with the single `missingCommand` token, and continue to.
The HTTP status still derives from the XRPL error code, now read from `error.data.error_code`. Four codes named no status in the error table and fell back to 200, which said the call succeeded on a reply that carries an error: `account_info` answered both a malformed account and a missing one with 200. They now name the status the table gives every comparable code: `actMalformed`, `alreadyMultisig` and `alreadySingleSig` report 400, and `actNotFound` reports 404.
Only version 3 reports those four. The legacy `ripplerpc: "3.0"` envelope derives the status from the same code and still answers 200 for them, since that is the status it has answered since it shipped and `account_info` on an account the ledger does not hold is a routine call rather than a failure. Every other code reports the status it always has, in both envelopes.
On the WebSocket transport the reply carries one extra member, `"type": "response"`. The specification has no place for it, but a WebSocket session also receives server-initiated messages on the same connection, and `type` is how a client tells the two apart. It is retained for that reason.
A WebSocket frame that does not parse as a JSON object, or exceeds the request size limit, is answered `{"type": "error", "error": "jsonInvalid", "size": <bytes>}` at every API version, including this one, unless the sender is already over the resource drop threshold, in which case the frame is charged and the connection is closed without a reply, as it is for a readable message from such a sender. There are no fields yet to shape into an envelope, and none to mask either, so the body is reported by its size rather than echoed: a frame with a stray comma would otherwise return whatever it carried, credentials included.
### Requests may take the specification's shape
Two request spellings are now accepted on the JSON-RPC transport, in addition to the ones XRPL clients already send: one the specification defines, `params` as an object, and one XRPL extension placed beside the members the specification defines, `api_version` at the top level. Both are additive, so every request that worked before still works; one shape is read differently, and it is named below. A WebSocket message is one flat object whose members are the parameters themselves: it has always carried `api_version` at its top level, and a `params` member there is not unpacked, so neither spelling applies to it.
- **`api_version` at the top level**, beside `method` and `id`, and not only inside `params`. For a lone JSON-RPC request a top-level value is honored only when it names version 3 or above: `"api_version": 2` there has been answered as version 1 for years, as has a version the server does not serve, and both continue to be. An entry of either batch form honors any version it names at its top level, including one the server does not serve, which is answered as an unsupported version: a `"method": "batch"` entry carries its parameters at its own top level, so that is where its version sits, and one that carries a by-name `params` object is read for `api_version` and credentials from that object instead; an array entry is read the same way so that the two forms agree, and an entry naming a served version other than the body's refuses the body.
A value inside `params` decides where a request carries both, which **reverses the earlier precedence**: a request that named a version inside `params` and a different one at its top level was previously answered at the top-level one whenever the value inside `params` resolved to version 1. Only a `"method": "batch"` entry could carry both, so that is the only shape the reversal reaches, and it reaches it at every API version. `API-CHANGELOG.md` records it.
- **`params` as the object itself**, the specification's by-name form, rather than an array holding that object. The array form is unchanged: it holds exactly one element, which is the object or `null`, as the Deviations section below records.
#### One API version per connection is the shape to write a client to
The server reads `api_version` from each request and answers that request at that version, so a connection may carry requests at several versions and each reply is shaped for the request that asked for it. Nothing refuses that. But there is no reason for a client to rely on it: a client that names one version for the life of a connection reads one reply shape throughout, and has one thing to change when it migrates. Write a client that way.
One case is not advice but a rule the server enforces: **every subscription a connection holds must name the same `api_version`**. A `subscribe` naming a version different from the one the connection's subscriptions are served at is refused with `apiVersionConflict` and registers nothing, because one event can match several of a connection's subscriptions and only one message goes out, so a second version would leave no shape that message could take. The version is fixed by the first `subscribe` for the connection's life, whether or not that call went on to register anything: a `subscribe` refused for a stream name the server does not have has still fixed it. A client that wants another version opens another connection.
A webhook subscriber is keyed on its `url` alone, so the same rule reaches every caller that names that url. To subscribe a url at a different version, send `unsubscribe` naming that `url` **and its streams**: naming the url alone does not release it, since the subscriber is not evicted while any stream map still holds it. Be aware that doing so removes the subscription of whoever subscribed that url first, whether or not that was you - the server keeps no record of which caller named it. Where the url may be shared, naming a different url is the safer answer. The refusal message names the version the url's subscriptions are served at and no remedy, for that reason. Ordinary requests are untouched by this: a connection subscribed at version 3 still calls `account_info` at version 1 and reads the version 1 shape.
```json
{
"jsonrpc": "2.0",
"id": 7,
"method": "ledger_closed",
"api_version": 3,
"params": { "ledger_index": "validated" }
}
```
### Batch requests
A top-level JSON array is accepted as a [batch](https://www.jsonrpc.org/specification#batch), and is answered with an array of replies, one per entry, each correlated by its own `id`:
```json
[
{
"jsonrpc": "2.0",
"id": 1,
"method": "ledger_closed",
"params": [{ "api_version": 3 }]
},
{
"jsonrpc": "2.0",
"id": 2,
"method": "account_info",
"params": [{ "api_version": 3 }]
}
]
```
In earlier versions a top-level array is rejected with HTTP 400, and that is unchanged; an array is treated as a batch only when an entry names an `api_version` of 3 or above that the server serves, inside its own `params` or at its top level, wherever that entry sits; an array holding at least one object in which no entry does is refused whole: as below version 3 where an entry names a served version below 3 or no entry names any, and for the version named where every version named is one the server does not serve. An array holding no object at all is answered per entry instead, as below. That entry also sets the version for the array: an entry naming none of its own inherits it, whether it comes before or after, so one batch is answered in one envelope even where an entry is rejected before its parameters can be read. An entry that names a served version of its own must name that one; a body whose entries name two different served versions is refused whole, as the table below shows. An entry naming a version the server does not serve is answered on its own, as below.
An entry's parameters are nested exactly as a lone request's are, so an entry reports the same error it would have reported on its own.
An entry that is not a JSON object is not a request. It is answered in place, among the replies, with `-32600` and `Request is not a JSON object`, and the entries that are requests are still dispatched. Earlier versions answer such an entry with `-32601` and `Method not found`, and echo it back under `request`; both are unchanged for them.
An entry naming an `api_version` the server does not serve is answered the same way: in place, with `-32606` and `invalid_API_version`, correlated by the entry's own `id`, or naming `"id": null` where the `id` itself was unusable, and echoing nothing. It takes the array's envelope rather than the one it asked for, since the version it asked for does not exist, and unlike a lone request in that position it is not answered as plain text: the array told the server which envelope this client reads. An entry naming a version the server does have must name the array's, or the whole array is refused.
A rejection of the whole array is answered with one error object, since only version 3 sends an array at all. The array names no `id`, its entries do, so `id` is null. The version is set by the first entry naming a served version of 3 or above. The version rows below are read in order: the first applies where every version named is one the server does not serve, the second where no entry names a served version of 3 or above, and the third where an entry names a served version other than the one set. An entry naming a version the server does not serve beside one naming a served version is answered on its own, wherever it sits, as above:
| Body | HTTP | `error.code` | `error.message` |
| --------------------------------------------------------------------------------------- | ---- | ------------ | --------------------------------------- |
| `[]` | 400 | `-32600` | `Request is empty` |
| More than 100 entries | 400 | `-32600` | `Batch has too many entries` |
| Every version named is one the server does not serve | 400 | `-32606` | `invalid_API_version` |
| Otherwise, no entry names a served version of 3 or above | 400 | `-32600` | `Batch requires API version 3 or above` |
| An entry names a served version of 3 or above, and another names a different served one | 400 | `-32600` | `Batch entries name different versions` |
A non-empty array of 100 entries or fewer holding nothing that could be a request, such as `[1,2,3]` from the specification's own example, is answered with one `-32600` object per entry, since no entry can name a version or an `id`. The table's first two rows are checked before any entry is read, so an empty or oversized array is answered once, whatever it holds.
A batch is limited to 100 entries, and the limit is applied before the entries are read, so an oversized array is answered once rather than once per entry. The body size limit alone is not a bound on the work a batch buys, since it dispatches one command per entry.
The `"method": "batch"` form, which nests its entries under `params`, is unrelated to the specification and continues to work on every API version. From version 3 up it takes the same 100-entry limit, read from the one version the body is served at, so no ordering of the entries evades it. Below version 3 it stays uncapped, which is what keeps every body clients send today acceptable.
Every entry is charged against the sender's resource allowance, whether it reaches a handler or is rejected first, except the one shed as overloaded, whose load the drop check has already accounted for. Once a connection is over the drop threshold the remaining entries are not answered, so a reply array can be shorter than the request array. The 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 error object, and the batch stops after it when that charge crossed the threshold; every other entry met over the threshold reports `-32604` and `Server is overloaded` in its own error object. Nothing follows in either case, so a client that correlates by `id` sees answers missing for the entries at the end, and should read any short reply array as an overloaded connection whatever its last element says. This applies to both batch forms.
A batch whose entries are answered reports HTTP 200, whatever those entries report, including the overloaded one above. An array holding nothing that could be a request is the exception: its entries are answered one by one, but the body is a rejection rather than a batch the server served, and it reports 400. One status cannot describe several outcomes, so an entry's own reply is where its outcome is stated: whether it carries `result` or `error`, and, for an error, the specification code in `error.code` for a rejection and the XRPL token and code under `error.data` for a handler failure, every one of which reports `-32000` in `error.code`. No entry has an HTTP status of its own. A rejection of the whole array is one answer rather than many and reports its own status, as the table above shows, and so does a request sent alone.
### Subscription messages are notifications
A message the server sends without being asked, such as a `subscribe` stream event, is shaped as a specification [notification](https://www.jsonrpc.org/specification#notification): a request-shaped object naming the protocol and the method, with the event's content under `params` and no `id`.
```json
{
"jsonrpc": "2.0",
"method": "ledgerClosed",
"params": { "ledger_index": 3, "...": "..." }
}
```
The `type` member that named the event in earlier versions becomes `method`.
A `path_find` update is a notification too, though the server directs it at the one client that asked rather than publishing it to a stream. The specification allows one response per request, and `path_find create` already consumed it, so no later update can be one. The `id` that correlates the update with the request travels inside `params`, which is where the update has always carried it:
```json
{
"jsonrpc": "2.0",
"method": "path_find",
"params": { "id": 7, "alternatives": ["..."], "full_reply": true }
}
```
An `account_history` subscription that fails reports the failure the same way, naming `account_history_tx_stream` as the method with the error under `params`. Earlier versions receive a bare error object with no `type`, which is what they have always received.
A subscriber named by a `url` is the exception, and receives the legacy `event` call at every version, including version 3. Such a subscriber is not sent the message directly: the server posts each message to the URL as the `params` of an `event` call, with a `seq` member counting the messages beside it. A notification sent that way would arrive nested inside a request and next to a member the specification does not define, so it would not be a notification. Which shape a subscriber receives therefore depends on how the message reaches it, not only on the version it asked for.
### Deviations from the specification
The reply follows the specification as closely as the XRPL API allows. These are the places it does not, all of them deliberate:
- **A request that names no `id` still receives a reply.** The specification calls such a request a notification and gives it no reply at all. XRPL clients routinely omit `id`, so a reply is always sent, with `"id": null`.
- **A batch of such requests is answered with an array**, for the same reason, where the specification would send no body.
- **An integer `id` must fit this server's JSON integer range**, -2147483648 to 4294967295. The specification allows any Number. One outside that range fails to parse, and the body is refused as unreadable before any envelope is chosen, so a client using a larger value, such as a millisecond timestamp, should send it as a string.
- **By-position `params` is an array of exactly one element, an object or `null`.** The specification allows an array of any length. This server's methods take one object, so an array of any other length, or one whose element is neither an object nor `null`, is refused with `-32602` and `params unparsable`. A `null` element is served as an empty parameter object, as it has been at every version.
- **`error.code` is `-32000`** for every failure a command reports, rather than a code per failure. The XRPL token and code carry that detail in `error.data`. A method the server does not have is the one exception, reporting `-32601`, because no command runs for it.
- **`-32700` (parse error) and `-32603` (internal error) are never reported.** A body that does not parse is answered as plain text on the JSON-RPC transport and as a `jsonInvalid` frame on WebSocket, and neither is an envelope, so there is no `error.code` to put a parse code in. An internal failure of a command is reported the way every other failure a command reports is, with `-32000` and the `internal` token under `error.data`, so that a client reads one code space for all of them.
- **`-32604`, `-32605` and `-32606`** lie in the band the specification reserves for the protocol. They are the codes earlier versions report for an overloaded server, a forbidden request and an unsupported API version, and moving one would change `error.code` for their clients.
- **A rejection the server cannot attribute to a version is plain text**, not an error object. The three classes are listed above.
- **The batch is accepted on the JSON-RPC transport only.** A WebSocket frame must be a single object, as it always has been.
- **`ripplerpc` is ignored** rather than rejected, as any other field the server does not honor is. When support for versions 1 and 2 ends, an ignored field stays ignored, where a rejection would silently turn into acceptance.
- **A WebSocket reply carries `"type": "response"`**, which the specification has no place for. A WebSocket session receives server-initiated messages on the same connection, and `type` is how a client tells the two apart.
- **A batch is served at one API version.** The specification says nothing about versions. An entry may name the version the body names, or name none and inherit it, and a body whose entries name two different versions the server serves is refused whole with `-32600` and `Batch entries name different versions`; one naming a version the server does not serve is answered on its own, as below. For a top-level array it is the one the first entry naming a served version of 3 or above does, wherever that entry sits. For a `"method": "batch"` body it is the one the first entry naming a served version does; such a body may also name it at its own top level, which then decides, and one naming a version the server does not serve there is refused. An entry names a version wherever dispatch would read one from it, inside its own `params` or at its top level. An entry naming a version the server does not serve is answered on its own, as it always has been, rather than taking the body down with it, except that a top-level array holding at least one object in which no entry names a served version of 3 or above is refused whole, with `-32606` where every version named is one the server does not serve and with `-32600` otherwise, as the table above shows, while one holding no object at all is answered per entry once it has passed the empty and size checks of the table's first two rows.
- **A reply array can be shorter than the request array.** The specification asks for one response per non-notification request; a batch stops at the entry the connection is too loaded to serve. `API-CHANGELOG.md` records this for the `"method": "batch"` form, which earlier versions serve; the array form is version 3 only, and this document is its record.
- **`warning`, `warnings` and `deprecated` sit beside `jsonrpc`, `result` and `id`** at the top level of the reply, where the specification defines no member of its own. The rule is positional: any of the three that a handler puts at the top level of its result is moved there, whatever it describes, and one nested deeper stays where the handler put it. A client therefore reads a top-level notice from one place whether the call succeeded or failed.
- **A subscriber named by a `url` receives the legacy `event` call**, not a notification, at every version. The transport that carries the message to the URL wraps it in a request of its own, so a notification could not survive the trip. See above.
- **A batch is limited to 100 entries.** The specification places no bound on an array's length. One command is dispatched per entry, so the request size limit bounds the bytes rather than the work, and an array of small entries buys far more of it than its size suggests. The same limit applies to the `"method": "batch"` form from version 3 up, for the reason given above.
- **A `subscribe` naming an `api_version` different from the one this connection's subscriptions are served at is refused.** The specification describes no such condition. Every subscription a connection holds is served at one version, for the reason given above, which is also why the remedy is a second connection rather than a second version. The refusal reports `apiVersionConflict`, registers nothing, and names the version already established. On the JSON-RPC transport it answers HTTP 400, as every version 3 error reporting a malformed request does. A WebSocket frame carries no status. `API-CHANGELOG.md` records it as breaking. This constrains `subscribe` alone: an ordinary request names its own `api_version` and is answered at it, whatever the connection has subscribed.
- **The request's own `jsonrpc` member is neither required nor read.** The specification asks a client to send `"jsonrpc": "2.0"`. A request is served whether it names that member, names some other value, or names none at all: `api_version` is what selects the shape of the reply, and refusing an otherwise well formed call for a missing member would reject requests every XRPL client sends today. The reply always names the member.
### Modifications to `amm_info`
The order of error checks has been changed to provide more specific error messages. ([#4924](https://github.com/XRPLF/rippled/pull/4924))
@@ -234,37 +25,3 @@ In API version 3, the following string values can be used with the `"index"` par
- `"index": "hashes"` - Returns the "short" `LedgerHashes` ledger entry (recent ledger hashes)
These shortcuts are only available in API version 3 and later. In API versions 1 and 2, these string values would result in an error.
#### `error_code` is the code that belongs to the reported token
`ledger_entry` validates its request fields through helpers that name the malformed field in the `error` token, such as `malformedOwner` or `malformedDirRoot`. Below API version 3 all of them report `error_code` 31 (`invalidParams`) regardless of the token, because changing the number would have broken clients matching on it. From version 3 each token reports the code it owns.
A client that matches on `error_code` 31 for these methods must match on the token instead, or on the code listed below. The `error` token itself is unchanged at every version, so a client that already matches on the token needs no change.
| Token | `error_code` below v3 | `error_code` from v3 |
| ------------------------------------------ | --------------------- | -------------------- |
| `malformedRequest` | 31 | 107 |
| `malformedAccount` | 31 | 110 |
| `malformedAddress` | 31 | 111 |
| `malformedAuthorized` | 31 | 112 |
| `malformedAuthorizedCredentials` | 31 | 113 |
| `malformedBridgeAccount` | 31 | 114 |
| `malformedBroker` | 31 | 115 |
| `malformedCurrency` | 31 | 116 |
| `malformedDirRoot` | 31 | 117 |
| `malformedDocumentID` | 31 | 118 |
| `malformedIssue` | 31 | 119 |
| `malformedIssuingChainDoor` | 31 | 120 |
| `malformedLockingChainDoor` | 31 | 121 |
| `malformedMPTIssuanceID` | 31 | 122 |
| `malformedMPTokenIssuance` | 31 | 123 |
| `malformedOwner` | 31 | 124 |
| `malformedSeq` | 31 | 125 |
| `malformedSponsee` | 31 | 126 |
| `malformedSponsor` | 31 | 127 |
| `malformedXChainOwnedClaimID` | 31 | 128 |
| `malformedXChainOwnedCreateAccountClaimID` | 31 | 129 |
`transaction_entry` reports `malformedRequest` too, and the two handlers agree on it from version 3 on. It set that token with no `error_code` at all before this release, and now reports 107 at every API version, where `ledger_entry` reports 31 below version 3 as the table above shows.
The HTTP status is unchanged: every code in the table above carries 400, as `invalidParams` does. `entryNotFound`, `lgrNotFound` and `unexpectedLedgerType` are unaffected by all of this, having always carried their own code. `unknownOption` is a separate change and is not a version 3 one: `ledger_entry` reports that token at API version 1 only, it carried no `error_code` at all there, and it now carries code 109.
@@ -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/nix/check-build-context-runtime.sh <graph.json>
# Usage: bin/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/nix/check-nix-store-refs.sh <path>
# Usage: bin/check-nix-store-refs.sh <path>
set -euo pipefail
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1 -5
View File
@@ -1461,17 +1461,13 @@
#
# [beta_rpc_api]
#
# 0 or 1. The section must hold exactly one line carrying that value: a bare
# [beta_rpc_api] header with nothing under it leaves the flag off, and the
# server logs one line saying so.
# 0 or 1.
#
# 0: Disable the beta API version for JSON-RPC and WebSocket [default]
# 1: Enable the beta API version for testing. The beta API version
# contains breaking changes that require a new API version number.
# They are not ready for public consumption.
#
# The beta API version is 3; see API-VERSION-3.md.
#
#-------------------------------------------------------------------------------
#
# 10. Example Settings
+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/nix/default-loader-path.sh.
The default loader is resolved by bin/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/nix/default-loader-path.sh")
set(_loader_path_script "${CMAKE_SOURCE_DIR}/bin/default-loader-path.sh")
if(
is_linux
+1 -2
View File
@@ -296,7 +296,7 @@ if(xrpld)
OUT_VAR rpcspec_instantiations
VALUE_TYPE "::json::Value"
VIEW_HEADER "xrpld/rpc/detail/JsonObjectView.hpp"
HANDLERS book_changes ledger transaction_entry
HANDLERS ledger
)
target_sources(xrpld PRIVATE ${rpcspec_instantiations})
@@ -330,7 +330,6 @@ if(xrpld)
# antithesis_instrumentation.h, which is not exported as INTERFACE
target_include_directories(
xrpld
SYSTEM
PRIVATE ${CMAKE_SOURCE_DIR}/external/antithesis-sdk
)
endif()
+1 -1
View File
@@ -3,7 +3,7 @@
"requires": [
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1782392402.420688",
"xrpl-rpc-spec/0.1.21#d536f87a2ae7d313452746cfa3ac4404%1790869005.122975",
"xrpl-rpc-spec/0.1.20#6daa13eeb4e6c92b82ea6d78866e1da8%1790720024.368048",
"sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1782392403.185447",
"soci/4.0.3#e726491a03468795453f7c83fc924a96%1782392402.679521",
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1782307151.633168",
+7 -13
View File
@@ -60,20 +60,8 @@ tools.build:exelinkflags+={{ static_runtime_flags }}
tools.info.package_id:confs+=["tools.build:exelinkflags"]
{% endif %}
{% if os == "Linux" and context == "build" %}
{# b2 links itself with its own script, which ignores exelinkflags #}
{# and only takes CXXFLAGS when use_cxx_env is set (see [buildenv] below). #}
[options]
b2/*:use_cxx_env=True
{% endif %}
[buildenv]
{# gRPC emits thousands of compiler warnings that we cannot act on. #}
{# CMake picks up CXXFLAGS, and unlike tools.build:cxxflags, #}
{# this is not part of the package ID, so binaries stay shareable. #}
grpc/*:CXXFLAGS=-w
{% if os == "Macos" %}
[buildenv]
{# 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. #}
@@ -83,5 +71,11 @@ 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 %}
+2 -2
View File
@@ -40,7 +40,7 @@ class Xrpl(ConanFile):
"nudb/2.0.9",
"openssl/3.6.3",
"soci/4.0.3",
"xrpl-rpc-spec/0.1.21",
"xrpl-rpc-spec/0.1.20",
"zlib/1.3.2",
]
@@ -154,7 +154,7 @@ class Xrpl(ConanFile):
self.requires("xxhash/0.8.3", transitive_headers=True)
exports_sources = (
"bin/nix/default-loader-path.sh",
"bin/default-loader-path.sh",
"CMakeLists.txt",
"cfg/*",
"cmake/*",
+6 -5
View File
@@ -80,12 +80,13 @@ function(add_xrpl_crate name)
# `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).
if(is_msvc)
corrosion_set_env_vars(${ARG_CRATE} "$<$<CONFIG:Debug>:CXXFLAGS=-MTd>")
corrosion_set_env_vars(
${ARG_CRATE}
"$<$<CONFIG:Debug>:CXXFLAGS=-MTd>"
)
endif()
corrosion_add_cxxbridge(
${name}_cxxbridge
CRATE ${ARG_CRATE}
FILES ${ARG_FILES}
corrosion_add_cxxbridge(${name}_cxxbridge CRATE ${ARG_CRATE} FILES
${ARG_FILES}
)
# Generated cxxbridge headers don't exist at configure time; CMake 3.28+
# validates INTERFACE_SOURCES on consuming targets. Clear it to skip the
+10 -10
View File
@@ -57,9 +57,9 @@ dependencies = [
[[package]]
name = "cxx"
version = "1.0.205"
version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8a02bfeba9074b2bbb39492c9b0908ec854f455a3cccdcde7a1de55e2315e40"
checksum = "13f6de320895f42e6e081abb5c7983bedcf0b6d0ff9323de0d33f620c8ac1199"
dependencies = [
"cc",
"cxx-build",
@@ -72,9 +72,9 @@ dependencies = [
[[package]]
name = "cxx-build"
version = "1.0.205"
version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbc2ac76997619d2d888b58ad79488f1c835de41ca4dd3dd7082acf4ecb0a50f"
checksum = "4fde53ca86b9704a943fef0f1e1d836239a6aedca5de3c65fa9f97ec0bd46d39"
dependencies = [
"cc",
"codespan-reporting",
@@ -87,9 +87,9 @@ dependencies = [
[[package]]
name = "cxxbridge-cmd"
version = "1.0.205"
version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54a486ed16a3f2a053fe7f5b98db4c1a59846a23e8cb9e49f9d1bd48830d51a2"
checksum = "07bae89236c811fd4d08ed3441759ac4ac98d752cbfd3de341315ba16ad20ec3"
dependencies = [
"clap",
"codespan-reporting",
@@ -101,15 +101,15 @@ dependencies = [
[[package]]
name = "cxxbridge-flags"
version = "1.0.205"
version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c72569be94e2283764d334cd285980b747dbe221e27e315484eb6bcd93fa808a"
checksum = "49045042e5fced01b80742aba5508de82aa4f13677ed3fa2b4cda709c40c5918"
[[package]]
name = "cxxbridge-macro"
version = "1.0.205"
version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "423e795284a7f7b3f843c956a5322c4bc497b60c2dd1a6339da10313cb18d575"
checksum = "b181252e2e3d3b5d183afbdc033a3958b445eb3e1a0ae65fc3d4f5259f5da6fd"
dependencies = [
"indexmap",
"proc-macro2",
+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/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.
[`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.
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/nix/check-nix-store-refs.sh build
bin/nix/check-nix-store-refs.sh ~/.conan2-nix
bin/check-nix-store-refs.sh build
bin/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/nix/check-build-context-runtime.sh graph.json
bin/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/nix/check-nix-store-refs.sh build/xrpld
bin/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/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`](../../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 ~/.conan2-nix
$ bin/check-nix-store-refs.sh ~/.conan2-nix
::error file=/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig::references the Nix store at run time
/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig
/nix/store/p4lp3xq4imd1qzqh08x8vcq2zfhi7rca-libresolv-93/lib/libresolv.9.dylib
+1 -1
View File
@@ -6,7 +6,7 @@ project(antithesis-sdk-cpp VERSION 0.4.4 LANGUAGES CXX)
add_library(antithesis-sdk-cpp INTERFACE antithesis_sdk.h)
# Note, both sections below created by xrpld project
target_include_directories(antithesis-sdk-cpp SYSTEM INTERFACE
target_include_directories(antithesis-sdk-cpp INTERFACE
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)
+1 -1
View File
@@ -34,7 +34,7 @@ lz4Compress(void const* in, std::size_t inSize, BufferFactory&& bf)
// data
auto compressed = bf(outCapacity);
auto const compressedSize = LZ4_compress_default(
auto compressedSize = LZ4_compress_default(
reinterpret_cast<char const*>(in),
reinterpret_cast<char*>(compressed),
inSize,
+30 -38
View File
@@ -20,14 +20,12 @@ SharedIntrusive<T>::SharedIntrusive(T* p, TAdoptTag) noexcept : ptr_{p}
template <class T>
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive const& rhs)
: ptr_{
[&] {
auto p = rhs.unsafeGetRawPtr();
if (p)
p->addStrongRef();
return p;
}(),
}
: ptr_{[&] {
auto p = rhs.unsafeGetRawPtr();
if (p)
p->addStrongRef();
return p;
}()}
{
}
@@ -35,14 +33,12 @@ template <class T>
template <class TT>
requires std::convertible_to<TT*, T*>
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive<TT> const& rhs)
: ptr_{
[&] {
auto p = rhs.unsafeGetRawPtr();
if (p)
p->addStrongRef();
return p;
}(),
}
: ptr_{[&] {
auto p = rhs.unsafeGetRawPtr();
if (p)
p->addStrongRef();
return p;
}()}
{
}
@@ -144,14 +140,12 @@ SharedIntrusive<T>::~SharedIntrusive()
template <class T>
template <class TT>
SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs)
: ptr_{
[&] {
auto p = static_cast<T*>(rhs.unsafeGetRawPtr());
if (p)
p->addStrongRef();
return p;
}(),
}
: ptr_{[&] {
auto p = static_cast<T*>(rhs.unsafeGetRawPtr());
if (p)
p->addStrongRef();
return p;
}()}
{
}
@@ -165,14 +159,12 @@ SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusiv
template <class T>
template <class TT>
SharedIntrusive<T>::SharedIntrusive(DynamicCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs)
: ptr_{
[&] {
auto p = dynamic_cast<T*>(rhs.unsafeGetRawPtr());
if (p)
p->addStrongRef();
return p;
}(),
}
: ptr_{[&] {
auto p = dynamic_cast<T*>(rhs.unsafeGetRawPtr());
if (p)
p->addStrongRef();
return p;
}()}
{
}
@@ -268,7 +260,7 @@ SharedIntrusive<T>::unsafeReleaseAndStore(T* next)
return;
using enum ReleaseStrongRefAction;
auto const action = prev->releaseStrongRef();
auto action = prev->releaseStrongRef();
switch (action)
{
case NoOp:
@@ -369,7 +361,7 @@ WeakIntrusive<T>::unsafeReleaseNoStore()
return;
using enum ReleaseWeakRefAction;
auto const action = ptr_->releaseWeakRef();
auto action = ptr_->releaseWeakRef();
switch (action)
{
case NoOp:
@@ -588,7 +580,7 @@ SharedWeakUnion<T>::convertToStrong()
auto p = unsafeGetRawPtr();
if (p && p->checkoutStrongRefFromWeak())
{
[[maybe_unused]] auto const action = p->releaseWeakRef();
[[maybe_unused]] auto action = p->releaseWeakRef();
XRPL_ASSERT(
(action == ReleaseWeakRefAction::NoOp),
"xrpl::SharedWeakUnion::convertToStrong : "
@@ -611,7 +603,7 @@ SharedWeakUnion<T>::convertToWeak()
return false;
using enum ReleaseStrongRefAction;
auto const action = p->addWeakReleaseStrongRef();
auto action = p->addWeakReleaseStrongRef();
switch (action)
{
case NoOp:
@@ -678,7 +670,7 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
if (isStrong())
{
using enum ReleaseStrongRefAction;
auto const strongAction = p->releaseStrongRef();
auto strongAction = p->releaseStrongRef();
switch (strongAction)
{
case NoOp:
@@ -696,7 +688,7 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
else
{
using enum ReleaseWeakRefAction;
auto const weakAction = p->releaseWeakRef();
auto weakAction = p->releaseWeakRef();
switch (weakAction)
{
case NoOp:
+2 -2
View File
@@ -406,10 +406,10 @@ IntrusiveRefCounts::useCount() const noexcept
inline IntrusiveRefCounts::~IntrusiveRefCounts() noexcept
{
#ifndef NDEBUG
auto const v = refCounts_.load(std::memory_order_acquire);
auto v = refCounts_.load(std::memory_order_acquire);
XRPL_ASSERT(
(!(v & kValueMask)), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero");
auto const t = v & kTagMask;
auto t = v & kTagMask;
XRPL_ASSERT((!t || t == kTagMask), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag");
#endif
}
-75
View File
@@ -3,84 +3,9 @@
#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
@@ -340,7 +340,7 @@ public:
for (auto const& c : cfg)
{
auto const& a = allocators_.emplace_back(c.extra_, c.alloc_, c.align_);
auto& a = allocators_.emplace_back(c.extra_, c.alloc_, c.align_);
if (a.size() > maxSize_)
maxSize_ = a.size();
+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)
+9 -9
View File
@@ -300,7 +300,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
// Remove from cache, if !valid, remove from map too. Returns true if removed from cache
std::scoped_lock const lock(mutex_);
auto const cit = cache_.find(key);
auto cit = cache_.find(key);
if (cit == cache_.end())
return false;
@@ -356,7 +356,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
std::scoped_lock const lock(mutex_);
auto const cit = cache_.find(key);
auto cit = cache_.find(key);
if (cit == cache_.end())
{
@@ -371,7 +371,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
Entry& entry = cit->second;
entry.touch(clock_.now());
auto const shouldReplaceCached = [&] {
auto shouldReplaceCached = [&] {
if constexpr (replaceCached)
{
return true;
@@ -400,7 +400,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
return true;
}
auto const cachedData = entry.lock();
auto cachedData = entry.lock();
if (cachedData)
{
@@ -563,7 +563,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
retrieve(key_type const& key, T& data)
{
// retrieve the value of the stored data
auto const entry = fetch(key);
auto entry = fetch(key);
if (!entry)
return false;
@@ -687,7 +687,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
return ret;
}
auto const sle = h();
auto sle = h();
if (!sle)
return {};
@@ -713,7 +713,7 @@ inline SharedPointerType
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
initialFetch(key_type const& key, std::scoped_lock<MutexType> const& l)
{
auto const cit = cache_.find(key);
auto cit = cache_.find(key);
if (cit == cache_.end())
return {};
@@ -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;
+2 -3
View File
@@ -195,8 +195,7 @@ private:
{
// Local lambda that converts a single hex char to four bits and
// ORs those bits into a uint32_t.
auto const hexCharToUInt =
[](char c, std::uint32_t shift, std::uint32_t& accum) -> ParseResult {
auto hexCharToUInt = [](char c, std::uint32_t shift, std::uint32_t& accum) -> ParseResult {
std::uint32_t nibble = 0xFFu;
if (c < '0' || c > 'f')
return ParseResult::BadChar;
@@ -454,7 +453,7 @@ public:
{
for (int i = kWidth - 1; i >= 0; --i)
{
auto const prev = data_[i];
auto prev = data_[i];
data_[i] = boost::endian::native_to_big(boost::endian::big_to_native(data_[i]) - 1);
if (prev != 0)
@@ -365,7 +365,7 @@ public:
size() const
{
std::size_t ret = 0;
for (auto const& p : map_)
for (auto& p : map_)
ret += p.size();
return ret;
}
@@ -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());
}
@@ -2536,7 +2536,7 @@ AgedUnorderedContainer<IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>
return false;
for (auto iter(cbegin()), last(cend()), otherLast(other.cend()); iter != last; ++iter)
{
auto const otherIter(other.find(extract(*iter)));
auto otherIter(other.find(extract(*iter)));
if (otherIter == otherLast)
return false;
}
+1 -1
View File
@@ -68,7 +68,7 @@ struct LexicalCast<Out, std::string_view>
if (first != last && *first == '+')
++first;
auto const ret = std::from_chars(first, last, out);
auto ret = std::from_chars(first, last, out);
return ret.ec == std::errc() && ret.ptr == last;
}
+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()>;
using HandlerType = std::function<void(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
@@ -83,7 +83,7 @@ trimRight(String const& s)
{
using std::begin;
using std::end;
auto const first(begin(s));
auto first(begin(s));
auto last(end(s));
last = trimRight(first, last);
return {first, last};
+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>)
{
+1 -1
View File
@@ -32,7 +32,7 @@ public:
Module,
// Match nothing (used internally)
None,
None
};
private:
+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()> b = [f = std::forward<F>(f),
... args = std::forward<Args>(args)] mutable {
std::function<void(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()> f)
run(std::function<void(void)> f)
{
try
{
+1 -1
View File
@@ -24,7 +24,7 @@ enum class Severity : std::uint8_t {
Fatal = 5,
Disabled = 6,
None = Disabled,
None = Disabled
};
/**
+1 -1
View File
@@ -18,7 +18,7 @@ enum class Type : std::uint8_t {
PrefixSha256 = 1,
ThresholdSha256 = 2,
RsaSha256 = 3,
Ed25519Sha256 = 4,
Ed25519Sha256 = 4
};
class Condition
@@ -49,7 +49,7 @@ public:
using namespace der;
auto const p = parsePreamble(s, ec);
auto p = parsePreamble(s, ec);
if (ec)
return nullptr;
+1 -1
View File
@@ -21,7 +21,7 @@ enum class Error {
UnexpectedTag,
LongTag,
LargeSize,
PreimageTooLong,
PreimageTooLong
};
std::error_code
+1 -1
View File
@@ -396,7 +396,7 @@ inline bool
getIfExists<bool>(Section const& section, std::string const& name, bool& v)
{
int intVal = 0;
auto const stat = getIfExists(section, name, intVal);
auto stat = getIfExists(section, name, intVal);
if (stat)
v = bool(intVal);
return stat;
+2 -2
View File
@@ -93,14 +93,14 @@ public:
void
check(std::vector<TxID> accepted, Predicate&& pred)
{
auto const acceptTxid = accepted.begin();
auto acceptTxid = accepted.begin();
auto const ae = accepted.end();
std::sort(acceptTxid, ae);
// We want to remove all tracking entries for transactions that were
// accepted as well as those which match the predicate.
auto const i = removeIfIntersectOrMatch(
auto i = removeIfIntersectOrMatch(
tracker_.begin(),
tracker_.end(),
accepted.begin(),
+9 -10
View File
@@ -779,7 +779,7 @@ Consensus<Adaptor>::peerProposalInternal(
{
// update current position
auto const peerPosIt = currPeerPositions_.find(peerID);
auto peerPosIt = currPeerPositions_.find(peerID);
if (peerPosIt != currPeerPositions_.end())
{
@@ -1110,7 +1110,7 @@ Consensus<Adaptor>::checkLedger(std::unique_ptr<std::stringstream> const& clog)
{
CLOG(clog) << "checkLedger. ";
auto const netLgr = adaptor_.getPrevLedger(prevLedgerID_, previousLedger_, mode_.get());
auto netLgr = adaptor_.getPrevLedger(prevLedgerID_, previousLedger_, mode_.get());
CLOG(clog) << "network ledgerid " << netLgr << ", "
<< "previous ledger " << prevLedgerID_ << ". ";
@@ -1159,8 +1159,8 @@ Consensus<Adaptor>::phaseOpen(std::unique_ptr<std::stringstream> const& clog)
// it is shortly before ledger close time
bool const anyTransactions = adaptor_.hasOpenTransactions();
auto const proposersClosed = currPeerPositions_.size();
auto const proposersValidated = adaptor_.proposersValidated(prevLedgerID_);
auto proposersClosed = currPeerPositions_.size();
auto proposersValidated = adaptor_.proposersValidated(prevLedgerID_);
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
int agree = 0, disagree = 0;
auto const ourPosition = result_->position.position();
auto ourPosition = result_->position.position();
// Count number of agreements/disagreements with our position
for (auto const& [nodeId, peerPos] : currPeerPositions_)
@@ -1686,7 +1686,7 @@ Consensus<Adaptor>::haveConsensus(std::unique_ptr<std::stringstream> const& clog
++disagree;
}
}
auto const currentFinished = adaptor_.proposersFinished(previousLedger_, prevLedgerID_);
auto currentFinished = adaptor_.proposersFinished(previousLedger_, prevLedgerID_);
JLOG(j_.debug()) << "Checking for TX consensus: agree=" << agree << ", disagree=" << disagree;
@@ -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();
auto const differences = result_->txns.compare(o);
auto differences = result_->txns.compare(o);
int dc = 0;
@@ -1826,7 +1826,7 @@ Consensus<Adaptor>::createDisputes(TxSetT const& o, std::unique_ptr<std::strings
"xrpl::Consensus::createDisputes : has disputed transactions");
TxT const tx = inThisSet ? result_->txns.find(txId) : o.find(txId);
auto const txID = tx.id();
auto txID = tx.id();
if (result_->disputes.find(txID) != result_->disputes.end())
continue;
@@ -1837,8 +1837,7 @@ Consensus<Adaptor>::createDisputes(TxSetT const& o, std::unique_ptr<std::strings
tx,
result_->txns.exists(txID),
std::max(prevProposers_, currPeerPositions_.size()),
j_,
};
j_};
// Update all of the available peer's votes on the disputed transaction
for (auto const& [nodeId, peerPos] : currPeerPositions_)
+8 -16
View File
@@ -145,26 +145,18 @@ struct ConsensusParms
std::map<AvalancheState, AvalancheCutoff> const avalancheCutoffs{
// {state, {time, percent, nextState}},
// 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
// 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
{
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
{
AvalancheState::Stuck,
{.consensusTime = 200, .consensusPct = 95, .next = AvalancheState::Stuck},
},
{AvalancheState::Stuck,
{.consensusTime = 200, .consensusPct = 95, .next = AvalancheState::Stuck}},
};
/**
+3 -3
View File
@@ -59,7 +59,7 @@ enum class ConsensusMode {
* if we entered the round observing, but is used to indicate we did
* have the wrongLedger at some point.
*/
SwitchedLedger,
SwitchedLedger
};
inline std::string
@@ -222,7 +222,7 @@ medianCloseOffset(ConsensusCloseTimes const& times)
// Accumulate weight in time order; the first bin to reach halfWeight is
// the (lower) weighted median. Returns true once that bin is found.
auto const step = [&](time_point t, std::int64_t w) {
auto step = [&](time_point t, std::int64_t w) {
XRPL_ASSERT(tally < halfWeight, "xrpl::medianCloseOffset::step : median not yet found");
tally += w;
if (tally >= halfWeight)
@@ -267,7 +267,7 @@ enum class ConsensusState {
No, ///< We do not have consensus
MovedOn, ///< The network has consensus without us
Expired, ///< Consensus time limit has hard-expired
Yes, ///< We have consensus along with the network
Yes ///< We have consensus along with the network
};
/**
+1 -1
View File
@@ -266,7 +266,7 @@ template <class Tx, class NodeId>
void
DisputedTx<Tx, NodeId>::unVote(NodeId const& peer)
{
auto const it = votes_.find(peer);
auto it = votes_.find(peer);
if (it != votes_.end())
{
+1 -1
View File
@@ -211,7 +211,7 @@ struct Node
void
erase(Node const* child)
{
auto const it = std::ranges::find_if(
auto it = std::ranges::find_if(
children, [child](std::unique_ptr<Node> const& curr) { return curr.get() == child; });
XRPL_ASSERT(it != children.end(), "xrpl::Node::erase : valid input");
std::swap(*it, children.back());
+9 -9
View File
@@ -184,7 +184,7 @@ enum class ValStatus {
/**
* Multiple validations by a validator for different ledgers
*/
Conflicting,
Conflicting
};
inline std::string
@@ -366,7 +366,7 @@ private:
removeTrie(std::scoped_lock<Mutex> const&, NodeID const& nodeID, Validation const& val)
{
{
auto const it = acquiring_.find(std::make_pair(val.seq(), val.ledgerID()));
auto it = acquiring_.find(std::make_pair(val.seq(), val.ledgerID()));
if (it != acquiring_.end())
{
it->second.erase(nodeID);
@@ -375,7 +375,7 @@ private:
}
}
{
auto const it = lastLedger_.find(nodeID);
auto it = lastLedger_.find(nodeID);
if (it != lastLedger_.end() && it->second.id() == val.ledgerID())
{
trie_.remove(it->second);
@@ -443,7 +443,7 @@ private:
// Clear any prior acquiring ledger for this node
if (prior)
{
auto const it = acquiring_.find(*prior);
auto it = acquiring_.find(*prior);
if (it != acquiring_.end())
{
it->second.erase(nodeID);
@@ -455,7 +455,7 @@ private:
checkAcquired(lock);
std::pair<Seq, ID> const valPair{val.seq(), val.ledgerID()};
auto const it = acquiring_.find(valPair);
auto it = acquiring_.find(valPair);
if (it != acquiring_.end())
{
it->second.insert(nodeID);
@@ -529,7 +529,7 @@ private:
}
else
{
auto const cit = typename decltype(current_)::const_iterator{it};
auto cit = typename decltype(current_)::const_iterator{it};
// contains a live record
f(cit->first, cit->second);
++it;
@@ -554,7 +554,7 @@ private:
void
byLedger(std::scoped_lock<Mutex> const&, ID const& ledgerID, Pre&& pre, F&& f)
{
auto const it = byLedger_.find(ledgerID);
auto it = byLedger_.find(ledgerID);
if (it != byLedger_.end())
{
// Update set time since it is being used
@@ -857,7 +857,7 @@ public:
if (!preferred)
{
// fall back to majority over acquiring ledgers
auto const it = std::ranges::max_element(acquiring_, [](auto const& a, auto const& b) {
auto it = std::ranges::max_element(acquiring_, [](auto const& a, auto const& b) {
std::pair<Seq, ID> const& aKey = a.first;
typename HashSet<NodeID>::size_type const& aSize = a.second.size();
std::pair<Seq, ID> const& bKey = b.first;
@@ -937,7 +937,7 @@ public:
return (preferred->first >= minSeq) ? preferred->second : lcl.id();
// Otherwise, rely on peer ledgers
auto const it = std::ranges::max_element(peerCounts, [](auto const& a, auto const& b) {
auto it = std::ranges::max_element(peerCounts, [](auto const& a, auto const& b) {
// Prefer larger counts, then larger ids on ties
// (max_element expects this to return true if a < b)
return std::tie(a.second, a.first) < std::tie(b.second, b.first);
+1 -1
View File
@@ -156,7 +156,7 @@ public:
{
if (!allClosuresDoneCond_.wait_for(lock, wait, [this] { return closureCount_ == 0; }))
{
if (auto const stream = j.error())
if (auto stream = j.error())
stream << name << " waiting for ClosureCounter::join().";
allClosuresDoneCond_.wait(lock, [this] { return closureCount_ == 0; });
}
+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
@@ -37,7 +37,7 @@ enum class HashRouterFlags : std::uint16_t {
PRIVATE6 = 0x2000,
// Used in apply.cpp
PRIVATE7 = 0x4000,
PRIVATE8 = 0x8000,
PRIVATE8 = 0x8000
};
constexpr HashRouterFlags
+6 -6
View File
@@ -30,12 +30,12 @@ private:
using namespace std::chrono_literals;
int const maxLimit = std::numeric_limits<int>::max();
auto const add = [this](
JobType jt,
std::string name,
int limit,
std::chrono::milliseconds avgLatency,
std::chrono::milliseconds peakLatency) {
auto add = [this](
JobType jt,
std::string name,
int limit,
std::chrono::milliseconds avgLatency,
std::chrono::milliseconds peakLatency) {
XRPL_ASSERT(!map.contains(jt), "xrpl::JobTypes::JobTypes::add : unique job type input");
[[maybe_unused]] auto const inserted =
+3 -4
View File
@@ -177,13 +177,12 @@ measureDurationAndLog(
std::chrono::duration<Rep, Period> maxDelay,
beast::Journal const& journal)
{
auto const startTime = std::chrono::high_resolution_clock::now();
auto startTime = std::chrono::high_resolution_clock::now();
auto result = func();
auto const endTime = std::chrono::high_resolution_clock::now();
auto const duration =
std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
auto endTime = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
if (duration > maxDelay)
{
JLOG(journal.warn()) << actionDescription << " took " << duration.count() << " ms";
+1 -1
View File
@@ -95,7 +95,7 @@ private:
ArraySeparator,
MemberSeparator,
Comment,
Error,
Error
};
class Token
+1 -38
View File
@@ -3,13 +3,11 @@
#include <xrpl/basics/Number.h>
#include <xrpl/json/json_forwards.h>
#include <concepts>
#include <cstring>
#include <iterator>
#include <limits>
#include <map>
#include <string>
#include <string_view>
#include <vector>
/**
@@ -28,7 +26,7 @@ enum class ValueType {
String, ///< UTF-8 string value
Boolean, ///< bool value
Array, ///< array value (ordered list)
Object, ///< object value (collection of name/value pairs).
Object ///< object value (collection of name/value pairs).
};
/**
@@ -200,15 +198,6 @@ public:
*/
Value(StaticString const& value);
Value(std::string const& value);
/**
* @brief Constructs a value from a string view.
*
* The characters are copied, so the view need not outlive the call and need
* not be NUL-terminated.
*
* @param value The characters to copy.
*/
Value(std::string_view value);
Value(bool value);
Value(Value const& other);
~Value();
@@ -483,32 +472,6 @@ toJson(xrpl::Number const& number)
bool
operator==(Value const&, Value const&);
/**
* Compares a value with a string view, reading the value's characters in place
* rather than building a Value from the view.
*
* Constrained to the exact type: a string literal converts equally well to a
* view and to a Value, so a plain overload makes `value == "literal"`
* ambiguous.
*
* @param x The value to compare.
* @param y The characters to compare it against.
* @return Whether `x` is a string whose characters up to its first NUL are
* exactly the characters of `y`.
*/
template <class T>
requires std::same_as<T, std::string_view>
bool
operator==(Value const& x, T y)
{
if (!x.isString())
return false;
// A string `Value` can hold a null pointer, which names no characters, so it equals no view.
char const* const s = x.asCString();
return s != nullptr && std::string_view{s} == y;
}
bool
operator<(Value const&, Value const&);
+1 -1
View File
@@ -165,7 +165,7 @@ public:
beast::Journal j)
{
// Ask implementation what to do
auto const actions = doVoting(
auto actions = doVoting(
lastClosedLedger->rules(),
lastClosedLedger->parentCloseTime(),
getEnabledAmendments(*lastClosedLedger),
+1 -1
View File
@@ -50,7 +50,7 @@ enum ApplyFlags : std::uint32_t {
// afterward, so signature-presence checks (e.g. Batch signer matching)
// are skipped at proposal-creation time (On-Chain Cosigner spec
// §5.3.1.2).
TapProposal = 0x2000,
TapProposal = 0x2000
};
constexpr ApplyFlags
+1 -2
View File
@@ -20,8 +20,7 @@ constexpr std::chrono::seconds kLedgerPossibleTimeResolutions[] = {
std::chrono::seconds{30},
std::chrono::seconds{60},
std::chrono::seconds{90},
std::chrono::seconds{120},
};
std::chrono::seconds{120}};
/**
* Initial resolution of ledger close time.
+2 -2
View File
@@ -35,7 +35,7 @@ public:
{
std::scoped_lock const lock(mutex_);
auto const it = map_.find(seq);
auto it = map_.find(seq);
if ((it == map_.end()) || it->second)
{
@@ -88,7 +88,7 @@ public:
std::unique_lock<std::mutex> lock(mutex_);
do
{
auto const it = map_.find(seq);
auto it = map_.find(seq);
if (it == map_.end())
{
+3 -3
View File
@@ -164,7 +164,7 @@ getCandidateLedger(LedgerIndex requested)
areCompatible(
ReadView const& validLedger,
ReadView const& testLedger,
beast::Journal::Stream const& s,
beast::Journal::Stream& s,
char const* reason);
[[nodiscard]] bool
@@ -172,7 +172,7 @@ areCompatible(
UInt256 const& validHash,
LedgerIndex validIndex,
ReadView const& testLedger,
beast::Journal::Stream const& s,
beast::Journal::Stream& s,
char const* reason);
//------------------------------------------------------------------------------
@@ -185,7 +185,7 @@ areCompatible(
dirLink(
ApplyView& view,
AccountID const& owner,
SLE::pointer const& object,
SLE::pointer& object,
SF_UINT64 const& node = sfOwnerNode);
/**
+4 -8
View File
@@ -30,17 +30,13 @@ public:
static constexpr size_t kInitialBufferSize = kilobytes(256);
RawStateTable()
: monotonicResource_{
std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
kInitialBufferSize),
}
: monotonicResource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
kInitialBufferSize)}
, items_{monotonicResource_.get()} {};
RawStateTable(RawStateTable const& rhs)
: monotonicResource_{
std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
kInitialBufferSize),
}
: monotonicResource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
kInitialBufferSize)}
, items_{rhs.items_, monotonicResource_.get()}
, dropsDestroyed_{rhs.dropsDestroyed_} {};
+17 -15
View File
@@ -224,7 +224,7 @@ getAMMOfferStartWithTakerGets(
if (nTakerGetsConstraint < *nTakerGets)
nTakerGets = nTakerGetsConstraint;
auto const getAmounts = [&pool, &tfee](Number const& nTakerGetsProposed) {
auto getAmounts = [&pool, &tfee](Number const& nTakerGetsProposed) {
// Round downward to minimize the offer and to maximize the quality.
// This has the most impact when takerGets is integral.
auto const takerGets =
@@ -292,7 +292,7 @@ getAMMOfferStartWithTakerPays(
if (nTakerPaysConstraint < *nTakerPays)
nTakerPays = nTakerPaysConstraint;
auto const getAmounts = [&pool, &tfee](Number const& nTakerPaysProposed) {
auto getAmounts = [&pool, &tfee](Number const& nTakerPaysProposed) {
// Round downward to minimize the offer and to maximize the quality.
// This has the most impact when takerPays is integral.
auto const takerPays =
@@ -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
auto amounts = TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
if (Quality{amounts} < quality &&
if (auto amounts = TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
Quality{amounts} < quality &&
!withinRelativeDistance(Quality{amounts}, quality, Number(1, -7)))
{
JLOG(j.error()) << "changeSpotPriceQuality failed: " << to_string(pool.in) << " "
@@ -382,19 +382,21 @@ changeSpotPriceQuality(
<< " " << to_string(amounts.out);
Throw<std::runtime_error>("changeSpotPriceQuality failed");
}
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;
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 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();
@@ -870,8 +872,8 @@ deleteAMMAccount(Sandbox& view, Asset const& asset, Asset const& asset2, beast::
*/
void
initializeFeeAuctionVote(
ApplyView const& view,
SLE::pointer const& ammSle,
ApplyView& view,
SLE::pointer& ammSle,
AccountID const& account,
Asset const& lptAsset,
std::uint16_t tfee);
@@ -893,7 +895,7 @@ std::expected<bool, TER>
verifyAndAdjustLPTokenBalance(
Sandbox& sb,
STAmount const& lpTokens,
SLE::pointer const& ammSle,
SLE::pointer& ammSle,
AccountID const& account);
} // namespace xrpl
+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
@@ -20,7 +20,7 @@ enum class NodeObjectType : std::uint32_t {
Ledger = 1,
AccountNode = 3,
TransactionNode = 4,
Dummy = 512, // an invalid or missing object
Dummy = 512 // an invalid or missing object
};
/**
+1 -1
View File
@@ -28,7 +28,7 @@ enum class Status {
Unknown = 3,
BackendError = 4,
CustomCode = 100,
CustomCode = 100
};
/**
+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)
+2 -2
View File
@@ -429,7 +429,7 @@ Livecache<Allocator>::insert(Endpoint const& ep)
XRPL_ASSERT(
ep.hops <= (tuning::kMaxHops + 1),
"xrpl::peer_finder::Livecache::insert : maximum input hops");
auto const result = cache_.emplace(ep.address, ep);
auto result = cache_.emplace(ep.address, ep);
Element& e(result.first->second);
if (result.second)
{
@@ -497,7 +497,7 @@ Livecache<Allocator>::HopsT::shuffle()
std::ranges::copy(list, std::back_inserter(v));
std::shuffle(v.begin(), v.end(), defaultPrng());
list.clear();
for (auto const& e : v)
for (auto& e : v)
list.push_back(e);
}
}
+4 -4
View File
@@ -194,7 +194,7 @@ public:
"Port not specified for address:" + remoteAddress.toString());
}
auto const result(fixed_.emplace(
auto result(fixed_.emplace(
std::piecewise_construct,
std::forward_as_tuple(remoteAddress),
std::make_tuple(std::ref(clock))));
@@ -439,7 +439,7 @@ public:
// Mark fixed slot success
if (slot->fixed() && !slot->inbound())
{
auto const iter(fixed_.find(slot->remoteEndpoint()));
auto iter(fixed_.find(slot->remoteEndpoint()));
if (iter == fixed_.end())
{
logicError(
@@ -485,7 +485,7 @@ public:
// Count how many more outbound attempts to make
//
auto const needed(counts_.attemptsNeeded());
auto needed(counts_.attemptsNeeded());
if (needed == 0)
return none;
@@ -903,7 +903,7 @@ public:
// Mark fixed slot failure
if (slot->fixed() && !slot->inbound() && slot->state() != Slot::State::Active)
{
auto const iter(fixed_.find(slot->remoteEndpoint()));
auto iter(fixed_.find(slot->remoteEndpoint()));
if (iter == fixed_.end())
{
logicError(
+17 -46
View File
@@ -6,25 +6,31 @@
#include <xrpl/protocol/jss.h>
#include <cstddef>
#include <string_view>
#include <type_traits>
#include <utility>
namespace xrpl {
/**
* The `api_version` numbers this server serves.
* API version numbers used in later API versions
*
* A request naming a version in [kApiMinimumSupportedVersion,
* kApiMaximumSupportedVersion] is served. With `[beta_rpc_api]` set to `1` in
* the config the range extends to kApiBetaVersion.
* Requests with a version number in the range
* [apiMinimumSupportedVersion, apiMaximumSupportedVersion]
* are supported.
*
* A request naming no version is served at kApiVersionIfUnspecified, which is 1
* because a request wanting any later version states it. A WebSocket message is
* one flat object and names it at its top level at every version. A JSON-RPC
* request names it in its parameters, or at its own top level: an entry of a
* `"method": "batch"` body at every version, a lone request from
* kApiMinimumSpecVersion up.
* If [beta_rpc_api] is enabled in config, the version numbers
* in the range [apiMinimumSupportedVersion, apiBetaVersion]
* are supported.
*
* Network Requests without explicit version numbers use
* apiVersionIfUnspecified. apiVersionIfUnspecified is 1,
* because all the RPC requests with a version >= 2 must
* explicitly specify the version in the requests.
* Note that apiVersionIfUnspecified will be lower than
* apiMinimumSupportedVersion when we stop supporting API
* version 1.
*
* Command line Requests use apiCommandLineVersion.
*/
namespace rpc {
@@ -40,31 +46,6 @@ static constexpr auto kApiCommandLineVersion = kApiVersion<1>; // TODO Bump to
static constexpr auto kApiBetaVersion = kApiVersion<3>;
static constexpr auto kApiMaximumValidVersion = kApiBetaVersion;
/**
* First API version that follows the JSON-RPC 2.0 specification.
*
* From this version up a lone JSON-RPC request may state its `api_version` at
* its own top level, beside the members the specification defines there, as a
* WebSocket message always has. The member is an XRPL extension: the
* specification defines no version member.
*
* Distinct from kApiBetaVersion, the same number today, which says instead that
* the version needs [beta_rpc_api] to be reachable.
*/
static constexpr auto kApiMinimumSpecVersion = kApiVersion<3>;
/**
* Whether @p apiVersion follows the JSON-RPC 2.0 specification.
*
* @param apiVersion The version a request asked for.
* @return Whether that version follows the specification.
*/
[[nodiscard]] constexpr bool
isSpecVersion(unsigned apiVersion)
{
return apiVersion >= kApiMinimumSpecVersion;
}
static_assert(kApiInvalidVersion < kApiMinimumSupportedVersion);
static_assert(
kApiVersionIfUnspecified >= kApiMinimumSupportedVersion &&
@@ -76,16 +57,6 @@ static_assert(kApiMaximumSupportedVersion >= kApiMinimumSupportedVersion);
static_assert(kApiBetaVersion >= kApiMaximumSupportedVersion);
static_assert(kApiMaximumValidVersion >= kApiMaximumSupportedVersion);
/**
* Values accepted in the `ripplerpc` request field, which selects the shape of
* the JSON-RPC reply envelope. Distinct from `kJsonRpcVersion` in JsonRpc.h,
* which names the JSON-RPC protocol itself, and from the `api_version`
* constants above, which select the content of the response.
*/
inline constexpr std::string_view kRippleRpcVersion1{"1.0"};
inline constexpr std::string_view kRippleRpcVersion2{"2.0"};
inline constexpr std::string_view kRippleRpcVersion3{"3.0"};
inline void
setVersion(json::Value& parent, unsigned int apiVersion, bool betaEnabled)
{
+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
+6 -65
View File
@@ -3,7 +3,6 @@
#include <xrpl/json/json_value.h>
#include <string>
#include <string_view>
namespace xrpl {
@@ -145,58 +144,7 @@ enum ErrorCodeI {
RpcEntryNotFound = 98,
RpcUnexpectedLedgerType = 99,
// submit + simulate
RpcInvalidTransaction = 100,
RpcInternalSubmit = 101,
RpcInternalJson = 102,
RpcInternalSimulate = 103,
// transaction_entry
RpcFieldNotFoundTransaction = 104,
RpcNotYetImplemented = 105,
RpcTransactionNotFound = 106,
// transaction_entry + ledger_entry
RpcMalformedRequest = 107,
// ledger_accept
RpcNotStandAlone = 108,
// ledger_entry, API version 1 only
RpcUnknownOption = 109,
// ledger_entry field validation, one code per malformed field. The ledger_entry helpers report
// invalidParams (31) for all of them, so each token needs a row of its own. Alphabetical by
// token here only: the enum is append-only once a code ships.
//
// `malformedIssue` duplicates `issueMalformed` (93): same message, same status, two tokens,
// both on the wire already. Do not add a third spelling.
RpcMalformedAccount = 110,
RpcMalformedAddress = 111,
RpcMalformedAuthorized = 112,
RpcMalformedAuthorizedCredentials = 113,
RpcMalformedBridgeAccount = 114,
RpcMalformedBroker = 115,
RpcMalformedCurrency = 116,
RpcMalformedDirRoot = 117,
RpcMalformedDocumentID = 118,
RpcMalformedIssue = 119,
RpcMalformedIssuingChainDoor = 120,
RpcMalformedLockingChainDoor = 121,
RpcMalformedMPTIssuanceID = 122,
RpcMalformedMPTokenIssuance = 123,
RpcMalformedOwner = 124,
RpcMalformedSeq = 125,
RpcMalformedSponsee = 126,
RpcMalformedSponsor = 127,
RpcMalformedXChainOwnedClaimID = 128,
RpcMalformedXChainOwnedCreateAccountClaimID = 129,
// subscribe
RpcApiVersionConflict = 130,
// RpcLast should always equal the last code.
RpcLast = RpcApiVersionConflict,
RpcLast = RpcUnexpectedLedgerType // rpcLAST should always equal the last code.
};
/**
@@ -232,6 +180,11 @@ struct ErrorInfo
{
}
constexpr ErrorInfo(ErrorCodeI code, char const* token, char const* message)
: code(code), token(token), message(message), httpStatus(200)
{
}
constexpr ErrorInfo(ErrorCodeI code, char const* token, char const* message, int httpStatus)
: code(code), token(token), message(message), httpStatus(httpStatus)
{
@@ -249,18 +202,6 @@ struct ErrorInfo
ErrorInfo const&
getErrorInfo(ErrorCodeI code);
/**
* Returns the error code that owns @p token.
*
* A linear scan over views measured at compile time, run once per error reply.
* A duplicate token is a build error, so the answer is never ambiguous.
*
* @param token The error token to resolve.
* @return The code the table gives @p token, or RpcUnknown if no row names it.
*/
ErrorCodeI
codeForToken(std::string_view token);
/**
* Add or update the json update to reflect the error code.
*/
-45
View File
@@ -1,45 +0,0 @@
#pragma once
#include <xrpl/json/json_forwards.h>
#include <string_view>
namespace xrpl::rpc {
/**
* Constants of the JSON-RPC 2.0 protocol itself.
*
* Kept apart from the `api_version` and `ripplerpc` constants in ApiVersion.h,
* which go when support for API versions 1 and 2 goes.
*/
/**
* Value of the `jsonrpc` member of a request and of its reply, fixed at "2.0"
* by the JSON-RPC specification.
*/
inline constexpr std::string_view kJsonRpcVersion{"2.0"};
/**
* Codes for the `code` member of a JSON-RPC error object.
*
* The specification reserves -32768 to -32000 for the protocol and leaves
* -32000 to -32099 of it to the implementation.
*
* kJsonRpcServerError is the code for an error an XRPL handler reports. The
* XRPL token and code travel in the error's `data` member, so renumbering an
* XRPL error cannot change a JSON-RPC code.
*
* The codes from kJsonRpcServerOverloaded on lie outside the
* implementation-defined sub-range, which the specification does not allow.
* They are the codes every shipped version reports, so moving one breaks the
* clients matching on it.
*/
inline constexpr json::Int kJsonRpcServerError{-32000};
inline constexpr json::Int kJsonRpcInvalidRequest{-32600};
inline constexpr json::Int kJsonRpcMethodNotFound{-32601};
inline constexpr json::Int kJsonRpcInvalidParams{-32602};
inline constexpr json::Int kJsonRpcServerOverloaded{-32604};
inline constexpr json::Int kJsonRpcForbidden{-32605};
inline constexpr json::Int kJsonRpcWrongVersion{-32606};
} // namespace xrpl::rpc
+1 -4
View File
@@ -208,10 +208,7 @@ enum LedgerEntryType : std::uint16_t {
\
LEDGER_OBJECT(Sponsorship, \
LSF_FLAG(lsfSponsorshipRequireSignForFee, 0x00010000) \
LSF_FLAG(lsfSponsorshipRequireSignForReserve, 0x00020000)) \
\
LEDGER_OBJECT(LoanBroker, \
LSF_FLAG(lsfLoanBrokerPrivate, 0x00010000))
LSF_FLAG(lsfSponsorshipRequireSignForReserve, 0x00020000))
// clang-format on
-2
View File
@@ -26,7 +26,6 @@ class STTx;
* greater than the maximum value of uint16.
*/
// Macro-generated, complex
// NOLINTBEGIN(readability-trailing-comma) the macro supplies the trailing comma
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum GranularPermissionType : std::uint32_t {
#pragma push_macro("GRANULAR_PERMISSION")
@@ -39,7 +38,6 @@ enum GranularPermissionType : std::uint32_t {
#undef GRANULAR_PERMISSION
#pragma pop_macro("GRANULAR_PERMISSION")
};
// NOLINTEND(readability-trailing-comma)
class Permission
{
+2 -4
View File
@@ -284,10 +284,8 @@ public:
auto const [minV, maxV] = std::minmax(q1.value_, q2.value_);
auto const mantissa = [](std::uint64_t rate) { return rate & ~(255ull << (64 - 8)); };
auto const exponent = [](std::uint64_t rate) {
return static_cast<int>(rate >> (64 - 8)) - 100;
};
auto mantissa = [](std::uint64_t rate) { return rate & ~(255ull << (64 - 8)); };
auto exponent = [](std::uint64_t rate) { return static_cast<int>(rate >> (64 - 8)) - 100; };
auto const minVMantissa = mantissa(minV);
auto const maxVMantissa = mantissa(maxV);
+1 -1
View File
@@ -29,7 +29,7 @@ struct JsonOptions
DisableApiPriorV2 = 0b0000'0010,
// IMPORTANT `All` must be union of all of the above; see also operator~
All = IncludeDate | DisableApiPriorV2, // 0b0000'0011
All = IncludeDate | DisableApiPriorV2 // 0b0000'0011
};
constexpr JsonOptions(UnderlyingT v) noexcept : value(v)
+4 -2
View File
@@ -440,7 +440,7 @@ private:
// These values are carefully chosen to do the right thing if passed
// to SField::shouldInclude (bool)
OmitSigningFields = false,
WithAllFields = true,
WithAllFields = true
};
void
@@ -457,7 +457,9 @@ 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_cvref_t<decltype(std::declval<T>().value())>>
template <
typename T,
typename V = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<T>().value())>>>
V
getFieldByValue(SField const& field) const;
Loaded 100 of 753 files, more files were not shown because too many files have changed in this diff. Show more