mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-11 22:28:02 +00:00
Compare commits
12 Commits
bthomee/rp
...
dangell7/b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6cb72aa5e0 | ||
|
|
70764e9362 | ||
|
|
1f6679938e | ||
|
|
b3abd3243c | ||
|
|
a99ee034b9 | ||
|
|
2b069f863a | ||
|
|
d0dbd1527a | ||
|
|
fa5baf2cc4 | ||
|
|
775759eddf | ||
|
|
17777928c7 | ||
|
|
26da18be9f | ||
|
|
b1a9539a6c |
16
.clang-tidy
16
.clang-tidy
@@ -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,11 +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-trailing-comma,
|
||||
-readability-trivial-switch,
|
||||
-readability-uppercase-literal-suffix
|
||||
"
|
||||
# ---
|
||||
@@ -93,10 +81,6 @@ CheckOptions:
|
||||
bugprone-unsafe-functions.ReportMoreUnsafeFunctions: true
|
||||
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
|
||||
|
||||
# New in clang-tidy 23; disabled until the code is updated
|
||||
misc-const-correctness.AnalyzeAutoVariables: false
|
||||
misc-const-correctness.AnalyzeLambdas: false
|
||||
misc-const-correctness.AnalyzeParameters: false
|
||||
misc-include-cleaner.IgnoreHeaders: ".*/(detail|impl)/.*;.*fwd\\.h(pp)?;time.h;stdlib.h;sqlite3.h;netinet/in\\.h;sys/resource\\.h;sys/sysinfo\\.h;linux/sysinfo\\.h;__chrono/.*;bits/.*;_abort\\.h;boost/.*;openssl/obj_mac\\.h"
|
||||
|
||||
readability-braces-around-statements.ShortStatementLines: 2
|
||||
|
||||
19
.github/actions/build-deps/action.yml
vendored
19
.github/actions/build-deps/action.yml
vendored
@@ -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"
|
||||
|
||||
@@ -75,6 +75,7 @@ test.app > xrpl.json
|
||||
test.app > xrpl.ledger
|
||||
test.app > xrpl.nodestore
|
||||
test.app > xrpl.protocol
|
||||
test.app > xrpl.rdb
|
||||
test.app > xrpl.resource
|
||||
test.app > xrpl.server
|
||||
test.app > xrpl.shamap
|
||||
@@ -174,7 +175,6 @@ 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.server
|
||||
|
||||
6
.github/workflows/build-nix-images.yml
vendored
6
.github/workflows/build-nix-images.yml
vendored
@@ -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:
|
||||
|
||||
4
.github/workflows/build-packaging-images.yml
vendored
4
.github/workflows/build-packaging-images.yml
vendored
@@ -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:
|
||||
|
||||
|
||||
3
.github/workflows/on-pr.yml
vendored
3
.github/workflows/on-pr.yml
vendored
@@ -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/**
|
||||
|
||||
3
.github/workflows/on-trigger.yml
vendored
3
.github/workflows/on-trigger.yml
vendored
@@ -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/**"
|
||||
|
||||
13
.github/workflows/reusable-build-test-config.yml
vendored
13
.github/workflows/reusable-build-test-config.yml
vendored
@@ -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 }}
|
||||
|
||||
3
.github/workflows/reusable-clang-tidy.yml
vendored
3
.github/workflows/reusable-clang-tidy.yml
vendored
@@ -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
|
||||
@@ -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 }}
|
||||
|
||||
5
.github/workflows/upload-conan-deps.yml
vendored
5
.github/workflows/upload-conan-deps.yml
vendored
@@ -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') }}
|
||||
|
||||
@@ -22,23 +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
|
||||
|
||||
### 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.
|
||||
- The command line client no longer prints a credential the operator did not type. A failing command echoes the request it built under `request_sent`, which carries the `admin_password` the client copies out of `[port_rpc]` in the config, so `./xrpld account_info rBogus` printed that password to stdout and into any captured output. `request_sent` is now masked. The `rpc` member beside it, which echoes the arguments as they were typed, is unchanged. The command line client also no longer writes an unparsed `json` or `ripple_path_find` argument to its trace log before parsing it, where a `secret` inside that argument could not be masked; it logs the parsed request instead, masked. The reply it receives is logged the same way, parsed and masked, where the raw body was written before, a `validation_create` answer included.
|
||||
- A WebSocket frame that does not parse, or exceeds the request size limit, is answered `{"type": "error", "error": "jsonInvalid", "size": <bytes>}`. The frame's body is reported by size rather than echoed back in a `value` member, since a body that does not parse has no fields to mask. A client that read `value` gets `size` instead.
|
||||
- Four error codes that named no HTTP status of their own, and so answered 200 on a reply reporting an error, now name one: `actMalformed`, `alreadyMultisig` and `alreadySingleSig` answer 400, and `actNotFound` answers 404. **No shipped envelope reports these four.** A request sending `ripplerpc: "3.0"` still receives 200 for all four, as it always has, so `account_info` on a malformed account or one the ledger does not hold answers 200 exactly as before.
|
||||
- `submit`, `simulate`, `transaction_entry`, `ledger_entry` and `ledger_accept`: Errors from these methods now include `error_code` and `error_message` alongside the `error` token, as every other method already did. Each error now answers the status its code names: 400 for a malformed request, 404 for `transactionNotFound`, 500 for an internal failure, and 501 for `notYetImplemented` and `notStandAlone`. That status change reaches only a request sending `ripplerpc: "3.0"`, which is the envelope that derives the status from the error. With `ripplerpc` `"1.0"` the status stays 200 and the two new members appear beside `error`; with `"2.0"` the status stays 200, `error_code` appears, and the `code` and `message` members carry the code and the message rather than null, since that envelope copies them from `error_code` and `error_message` and drops `error_message`.
|
||||
|
||||
## 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
|
||||
@@ -92,6 +82,7 @@ This release contains bug fixes only and no API changes.
|
||||
|
||||
### Additions in 3.2.0
|
||||
|
||||
- `tx`: A validated `Batch` transaction now includes `inner_results`, an array in `RawTransactions` order with one entry per inner transaction that was evaluated, whether or not it was applied: `hash`, `result` (the transaction result code) and `applied` (whether its changes ended up in the ledger; `false` for an inner transaction that failed with a `ter`/`tem`/`tef` code, and for every inner transaction of a `tfAllOrNothing` batch that rolled back). `tfOnlyOne` stops evaluating after the first inner that returns `tesSUCCESS`, not merely applies (an applied `tec` does not stop it), and `tfUntilFailure` stops after the first inner that fails, so later `RawTransactions` entries have no corresponding `inner_results` entry. Inner transactions that fail are not in the ledger, so this is the only record of them. The field is present only when this node built the validated ledger itself and has `[ledger_tx_tables]` enabled; a node that acquired the ledger from the network omits it.
|
||||
- `ledger_entry`, `account_objects`: The `Delegate` ledger entry now includes an optional `DestinationNode` field, which stores the index into the authorized account's owner directory. This field is present on entries created after bidirectional directory tracking was introduced and may appear in RPC responses for those entries. ([#6681](https://github.com/XRPLF/rippled/pull/6681))
|
||||
- `server_definitions`: Added the following new sections to the response ([#6321](https://github.com/XRPLF/rippled/pull/6321)):
|
||||
- `TRANSACTION_FORMATS`: Describes the fields and their optionality for each transaction type, including common fields shared across all transactions.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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/*",
|
||||
|
||||
12
docs/build/nix.md
vendored
12
docs/build/nix.md
vendored
@@ -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
|
||||
|
||||
6
docs/build/nix_troubleshooting.md
vendored
6
docs/build/nix_troubleshooting.md
vendored
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -783,7 +783,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
std::atomic<int>& allRemovals,
|
||||
std::scoped_lock<std::recursive_mutex> const&)
|
||||
{
|
||||
return std::thread([&, this] {
|
||||
return std::thread([&, this]() {
|
||||
int cacheRemovals = 0;
|
||||
int mapRemovals = 0;
|
||||
|
||||
@@ -863,7 +863,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
std::atomic<int>& allRemovals,
|
||||
std::scoped_lock<std::recursive_mutex> const&)
|
||||
{
|
||||
return std::thread([&, this] {
|
||||
return std::thread([&, this]() {
|
||||
// NOLINTBEGIN https://github.com/XRPLF/rippled/issues/7056
|
||||
int cacheRemovals = 0;
|
||||
int mapRemovals = 0;
|
||||
|
||||
@@ -1604,7 +1604,7 @@ AgedOrderedContainer<IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::erase(
|
||||
beast::detail::AgedContainerIterator<IsConst, Iterator> pos)
|
||||
requires(!IsBoostReverseIterator<Iterator>::value)
|
||||
{
|
||||
unlinkAndDeleteElement(&*(pos++).iterator());
|
||||
unlinkAndDeleteElement(&*((pos++).iterator()));
|
||||
return beast::detail::AgedContainerIterator<false, Iterator>(pos.iterator());
|
||||
}
|
||||
|
||||
@@ -1617,7 +1617,7 @@ AgedOrderedContainer<IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::erase(
|
||||
requires(!IsBoostReverseIterator<Iterator>::value)
|
||||
{
|
||||
for (; first != last;)
|
||||
unlinkAndDeleteElement(&*(first++).iterator());
|
||||
unlinkAndDeleteElement(&*((first++).iterator()));
|
||||
|
||||
return beast::detail::AgedContainerIterator<false, Iterator>(first.iterator());
|
||||
}
|
||||
|
||||
@@ -2404,7 +2404,7 @@ beast::detail::AgedContainerIterator<false, Iterator>
|
||||
AgedUnorderedContainer<IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>::erase(
|
||||
beast::detail::AgedContainerIterator<IsConst, Iterator> pos)
|
||||
{
|
||||
unlinkAndDeleteElement(&*(pos++).iterator());
|
||||
unlinkAndDeleteElement(&*((pos++).iterator()));
|
||||
return beast::detail::AgedContainerIterator<false, Iterator>(pos.iterator());
|
||||
}
|
||||
|
||||
@@ -2424,7 +2424,7 @@ AgedUnorderedContainer<IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>
|
||||
beast::detail::AgedContainerIterator<IsConst, Iterator> last)
|
||||
{
|
||||
for (; first != last;)
|
||||
unlinkAndDeleteElement(&*(first++).iterator());
|
||||
unlinkAndDeleteElement(&*((first++).iterator()));
|
||||
|
||||
return beast::detail::AgedContainerIterator<false, Iterator>(first.iterator());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -34,7 +34,7 @@ typeName()
|
||||
name += " volatile";
|
||||
if (std::is_lvalue_reference_v<T>)
|
||||
{
|
||||
name += '&';
|
||||
name += "&";
|
||||
}
|
||||
else if (std::is_rvalue_reference_v<T>)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
/**
|
||||
@@ -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&);
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/CachedView.h>
|
||||
#include <xrpl/ledger/RawView.h>
|
||||
#include <xrpl/protocol/BatchInnerResult.h>
|
||||
#include <xrpl/protocol/Fees.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/LedgerHeader.h>
|
||||
@@ -325,6 +326,24 @@ public:
|
||||
bool
|
||||
addSLE(SLE const& sle);
|
||||
|
||||
/**
|
||||
* @brief Inner Batch outcomes observed while this node built the ledger.
|
||||
*
|
||||
* Empty for a ledger acquired from the network or loaded from the database. Not part of
|
||||
* the ledger hash; persisted to the transaction tables when the ledger is saved.
|
||||
*/
|
||||
void
|
||||
setBatchInnerResults(std::vector<BatchInnerResult> results)
|
||||
{
|
||||
batchInnerResults_ = std::move(results);
|
||||
}
|
||||
|
||||
std::vector<BatchInnerResult> const&
|
||||
batchInnerResults() const
|
||||
{
|
||||
return batchInnerResults_;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
@@ -433,6 +452,7 @@ private:
|
||||
Rules rules_;
|
||||
LedgerHeader header_;
|
||||
beast::Journal j_;
|
||||
std::vector<BatchInnerResult> batchInnerResults_;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -6,21 +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.
|
||||
* 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 {
|
||||
@@ -47,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)
|
||||
{
|
||||
|
||||
37
include/xrpl/protocol/BatchInnerResult.h
Normal file
37
include/xrpl/protocol/BatchInnerResult.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* @brief Outcome of one inner transaction of a Batch, recorded while the outer Batch was
|
||||
* applied.
|
||||
*
|
||||
* Inner transactions that fail with a ter/tem/tef result are never applied and leave no
|
||||
* metadata in the ledger, and a tfAllOrNothing rollback discards the ones that did apply.
|
||||
* This record is the only place those outcomes survive. It is node-local and not part of
|
||||
* the ledger hash.
|
||||
*/
|
||||
struct BatchInnerResult
|
||||
{
|
||||
uint256 parentBatchId;
|
||||
uint256 innerTxId;
|
||||
|
||||
/**
|
||||
* @brief Position in the outer transaction's RawTransactions.
|
||||
*/
|
||||
std::uint32_t index = 0;
|
||||
|
||||
TER ter = tesSUCCESS;
|
||||
|
||||
/**
|
||||
* @brief True if the inner transaction's changes ended up in the ledger.
|
||||
*/
|
||||
bool applied = false;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -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
|
||||
|
||||
@@ -144,27 +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,
|
||||
|
||||
RpcLast = RpcUnknownOption // rpcLAST should always equal the last code.
|
||||
RpcLast = RpcUnexpectedLedgerType // rpcLAST should always equal the last code.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -200,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)
|
||||
{
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#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"};
|
||||
|
||||
} // namespace xrpl::rpc
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ private:
|
||||
template <class LookupNodeID>
|
||||
STValidation::STValidation(SerialIter& sit, LookupNodeID&& lookupNodeID, DeserializeOptions options)
|
||||
: STObject(validationFormat(), sit, sfValidation, options.requireCanonicalOrder)
|
||||
, signingPubKey_([this] {
|
||||
, signingPubKey_([this]() {
|
||||
auto const spk = getFieldVL(sfSigningPubKey);
|
||||
|
||||
if (publicKeyType(makeSlice(spk)) != KeyType::Secp256k1)
|
||||
|
||||
@@ -252,7 +252,7 @@ public:
|
||||
{
|
||||
auto success = (offset + (Bits / 8)) <= data_.size();
|
||||
if (success)
|
||||
memcpy(data.begin(), &data_.front() + offset, (Bits / 8));
|
||||
memcpy(data.begin(), &(data_.front()) + offset, (Bits / 8));
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@@ -449,7 +449,7 @@ public:
|
||||
// Trait tells the requires-clause which types are allowed for construction.
|
||||
template <typename T>
|
||||
constexpr TERSubset(T rhs)
|
||||
requires(Trait<std::remove_cvref_t<T>>::value)
|
||||
requires(Trait<std::remove_cv_t<std::remove_reference_t<T>>>::value)
|
||||
: code_(TERtoInt(rhs))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -226,10 +226,6 @@ inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
|
||||
TF_FLAG(tfLoanUnimpair, 0x00040000), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(LoanBrokerSet, \
|
||||
TF_FLAG(tfLoanBrokerPrivate, 0x00010000), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(SponsorshipSet, \
|
||||
TF_FLAG(tfSponsorshipSetRequireSignForFee, 0x00010000) \
|
||||
TF_FLAG(tfSponsorshipClearRequireSignForFee, 0x00020000) \
|
||||
|
||||
@@ -20,7 +20,6 @@ XRPL_FEATURE(SmartEscrow, Supported::No, VoteBehavior::DefaultN
|
||||
XRPL_FEATURE(LendingProtocolV1_2, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Cleanup3_5_0, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(ConfidentialMPTKeyRotation, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (BatchV1_2, Supported::Yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (Cleanup3_4_0, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(Sponsor, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(BatchV1_1, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -549,7 +549,6 @@ LEDGER_ENTRY(ltLOAN_BROKER, 0x0088, LoanBroker, loan_broker, ({
|
||||
{sfCoverAvailable, SoeDefault},
|
||||
{sfCoverRateMinimum, SoeDefault},
|
||||
{sfCoverRateLiquidation, SoeDefault},
|
||||
{sfDomainID, SoeOptional},
|
||||
}))
|
||||
|
||||
/** A ledger object representing a loan between a Borrower and a Loan Broker
|
||||
|
||||
@@ -900,7 +900,6 @@ TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet,
|
||||
{sfDebtMaximum, SoeOptional},
|
||||
{sfCoverRateMinimum, SoeOptional},
|
||||
{sfCoverRateLiquidation, SoeOptional},
|
||||
{sfDomainID, SoeOptional},
|
||||
}))
|
||||
|
||||
/** This transaction deletes a Loan Broker */
|
||||
|
||||
@@ -245,7 +245,7 @@ JSS(ephemeral_key); // out: ValidatorInfo
|
||||
JSS(error); // out: error
|
||||
JSS(errored); //
|
||||
JSS(error_code); // out: error
|
||||
JSS(error_exception); // out: Submit, Simulate
|
||||
JSS(error_exception); // out: Submit
|
||||
JSS(error_message); // out: error
|
||||
JSS(expand); // in: handler/Ledger
|
||||
JSS(expected_date); // out: any (warnings)
|
||||
@@ -300,6 +300,7 @@ JSS(in); // out: OverlayImpl
|
||||
JSS(inLedger); // out: tx/Transaction
|
||||
JSS(inbound); // out: PeerImp
|
||||
JSS(index); // in: LedgerEntry
|
||||
JSS(inner_results); // out: Tx
|
||||
// out: STLedgerEntry, LedgerEntry, TxHistory, LedgerData
|
||||
JSS(info); // out: ServerInfo, ConsensusInfo, FetchInfo
|
||||
JSS(initial_sync_duration_us); //
|
||||
@@ -559,7 +560,7 @@ JSS(signing_key); // out: NetworkOPs
|
||||
JSS(signing_keys); // out: ValidatorList
|
||||
JSS(signing_time); // out: NetworkOPs
|
||||
JSS(signer_lists); // in/out: AccountInfo
|
||||
JSS(size); // out: get_aggregate_price, ServerHandler
|
||||
JSS(size); // out: get_aggregate_price
|
||||
JSS(snapshot); // in: Subscribe
|
||||
JSS(source_account); // in: PathRequest, RipplePathFind
|
||||
JSS(source_amount); // in: PathRequest, RipplePathFind
|
||||
|
||||
@@ -335,30 +335,6 @@ public:
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfCoverRateLiquidation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfDomainID (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT256::type::value_type>
|
||||
getDomainID() const
|
||||
{
|
||||
if (hasDomainID())
|
||||
return this->sle_->at(sfDomainID);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfDomainID is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasDomainID() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfDomainID);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -602,17 +578,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfDomainID (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
LoanBrokerBuilder&
|
||||
setDomainID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfDomainID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed LoanBroker wrapper.
|
||||
* @param index The ledger entry index.
|
||||
|
||||
@@ -213,32 +213,6 @@ public:
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfCoverRateLiquidation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfDomainID (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT256::type::value_type>
|
||||
getDomainID() const
|
||||
{
|
||||
if (hasDomainID())
|
||||
{
|
||||
return this->tx_->at(sfDomainID);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfDomainID is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasDomainID() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfDomainID);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -362,17 +336,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfDomainID (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
LoanBrokerSetBuilder&
|
||||
setDomainID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfDomainID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the LoanBrokerSet wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
|
||||
@@ -72,7 +72,7 @@ inline constexpr std::array<char const*, 5> kLgrDbInit{
|
||||
// Transaction database holds transactions and public keys
|
||||
inline constexpr auto kTxDbName{"transaction.db"};
|
||||
|
||||
inline constexpr std::array<char const*, 8> kTxDbInit{
|
||||
inline constexpr std::array<char const*, 10> kTxDbInit{
|
||||
{"BEGIN TRANSACTION;",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS Transactions ( \
|
||||
@@ -101,6 +101,21 @@ inline constexpr std::array<char const*, 8> kTxDbInit{
|
||||
"CREATE INDEX IF NOT EXISTS AcctLgrIndex ON \
|
||||
AccountTransactions(LedgerSeq, Account, TransID);",
|
||||
|
||||
// Outcome of each inner transaction of a Batch this node applied while building a
|
||||
// validated ledger. Inner transactions that failed are not in the ledger, so this is
|
||||
// the only record of them. See BatchInnerResult.
|
||||
"CREATE TABLE IF NOT EXISTS BatchInnerResults ( \
|
||||
ParentBatchID CHARACTER(64) NOT NULL, \
|
||||
InnerTxnID CHARACTER(64) NOT NULL, \
|
||||
TxnIndex INTEGER NOT NULL, \
|
||||
LedgerSeq BIGINT UNSIGNED NOT NULL, \
|
||||
TERResult INTEGER NOT NULL, \
|
||||
Applied INTEGER NOT NULL, \
|
||||
PRIMARY KEY (ParentBatchID, InnerTxnID) \
|
||||
);",
|
||||
"CREATE INDEX IF NOT EXISTS BatchInnerLgrIndex ON \
|
||||
BatchInnerResults(LedgerSeq);",
|
||||
|
||||
"END TRANSACTION;"}};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -178,7 +178,7 @@ public:
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
LockedSociSession session = perf::measureDurationAndLog(
|
||||
[&] { return LockedSociSession(session_, lock_); }, "checkoutDb", 10ms, j_);
|
||||
[&]() { return LockedSociSession(session_, lock_); }, "checkoutDb", 10ms, j_);
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/BatchInnerResult.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/LedgerHeader.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
@@ -212,6 +213,18 @@ public:
|
||||
virtual std::optional<LedgerIndex>
|
||||
getAccountTransactionsMinLedgerSeq() = 0;
|
||||
|
||||
/**
|
||||
* @brief getBatchInnerResults Returns the recorded inner-transaction outcomes of a
|
||||
* Batch this node applied while building a validated ledger.
|
||||
* @param parentBatchId Hash of the outer Batch transaction.
|
||||
* @param ledgerSeq Ledger sequence the outer Batch transaction is validated in; rows
|
||||
* recorded for any other sequence are not this ledger's and are excluded.
|
||||
* @return Outcomes in RawTransactions order; empty if the tx tables are disabled or
|
||||
* nothing was recorded (a ledger acquired from the network records nothing).
|
||||
*/
|
||||
virtual std::vector<BatchInnerResult>
|
||||
getBatchInnerResults(uint256 const& parentBatchId, LedgerIndex ledgerSeq) = 0;
|
||||
|
||||
/**
|
||||
* @brief deleteTransactionByLedgerSeq Deletes transactions from the ledger
|
||||
* with the given sequence.
|
||||
|
||||
@@ -279,7 +279,7 @@ public:
|
||||
virtual bool
|
||||
unsubPeerStatus(std::uint64_t uListener) = 0;
|
||||
virtual void
|
||||
pubPeerStatus(std::function<json::Value()> const&) = 0;
|
||||
pubPeerStatus(std::function<json::Value(void)> const&) = 0;
|
||||
|
||||
virtual bool
|
||||
subConsensus(Ref ispListener) = 0;
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
}
|
||||
|
||||
bool
|
||||
prepare(std::size_t bytes, std::function<void()>) override
|
||||
prepare(std::size_t bytes, std::function<void(void)>) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
* empty vector.
|
||||
*/
|
||||
virtual std::pair<boost::tribool, std::vector<boost::asio::const_buffer>>
|
||||
prepare(std::size_t bytes, std::function<void()> resume) = 0;
|
||||
prepare(std::size_t bytes, std::function<void(void)> resume) = 0;
|
||||
};
|
||||
|
||||
template <class Streambuf>
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
}
|
||||
|
||||
std::pair<boost::tribool, std::vector<boost::asio::const_buffer>>
|
||||
prepare(std::size_t bytes, std::function<void()>) override
|
||||
prepare(std::size_t bytes, std::function<void(void)>) override
|
||||
{
|
||||
if (sb_.size() == 0)
|
||||
return {true, {}};
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
* @return `true` if the writer is ready to provide more data.
|
||||
*/
|
||||
virtual bool
|
||||
prepare(std::size_t bytes, std::function<void()> resume) = 0;
|
||||
prepare(std::size_t bytes, std::function<void(void)> resume) = 0;
|
||||
|
||||
/**
|
||||
* Returns a ConstBufferSequence representing the input sequence.
|
||||
|
||||
@@ -342,10 +342,10 @@ BaseHTTPPeer<Handler, Impl>::doWriter(
|
||||
bool keepAlive,
|
||||
YieldContext doYield)
|
||||
{
|
||||
std::function<void()> resume;
|
||||
std::function<void(void)> resume;
|
||||
{
|
||||
auto const p = impl().shared_from_this();
|
||||
resume = std::function<void()>([this, p, writer, keepAlive] {
|
||||
resume = std::function<void(void)>([this, p, writer, keepAlive]() {
|
||||
util::spawn(strand_, [p, writer, keepAlive](YieldContext doYield) {
|
||||
p->doWriter(writer, keepAlive, doYield);
|
||||
});
|
||||
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
port_.protocol.contains("wss2") || port_.protocol.contains("peer")};
|
||||
bool plain_{
|
||||
port_.protocol.contains("http") || port_.protocol.contains("ws") ||
|
||||
port_.protocol.contains("ws2")};
|
||||
(port_.protocol.contains("ws2"))};
|
||||
static constexpr std::chrono::milliseconds kInitialAcceptDelay{50};
|
||||
static constexpr std::chrono::milliseconds kMaxAcceptDelay{2000};
|
||||
std::chrono::milliseconds acceptDelay_{kInitialAcceptDelay};
|
||||
|
||||
@@ -7,18 +7,6 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* Writes an HTTP reply carrying @p strMsg with status @p nStatus to @p output,
|
||||
* and logs the status at trace. The body is not logged here: it may carry a
|
||||
* credential this library cannot mask, so the caller logs it masked.
|
||||
*
|
||||
* A 401 with an empty body is answered with the fixed authentication page.
|
||||
*
|
||||
* @param nStatus The HTTP status code.
|
||||
* @param strMsg The body.
|
||||
* @param output Where the reply bytes are written.
|
||||
* @param j The journal the status is logged to.
|
||||
*/
|
||||
void
|
||||
httpReply(int nStatus, std::string const& strMsg, json::Output const&, beast::Journal j);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ private:
|
||||
bool closed_ = false;
|
||||
std::condition_variable cv_;
|
||||
boost::container::flat_map<Work*, std::weak_ptr<Work>> map_;
|
||||
std::function<void()> f_;
|
||||
std::function<void(void)> f_;
|
||||
|
||||
public:
|
||||
IOList() = default;
|
||||
@@ -171,7 +171,7 @@ IOList::Work::destroy()
|
||||
{
|
||||
if (!ios_)
|
||||
return;
|
||||
std::function<void()> f;
|
||||
std::function<void(void)> f;
|
||||
{
|
||||
std::scoped_lock const lock(ios_->m_);
|
||||
ios_->map_.erase(this);
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/protocol/BatchInnerResult.h>
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -142,6 +144,7 @@ enum class ApplyTransactionResult {
|
||||
* Provides more detailed logging and decodes the
|
||||
* correct behavior based on the `TER` type
|
||||
*
|
||||
* @param innerResults If set, receives one entry per inner transaction the outer Batch ran.
|
||||
* @see ApplyTransactionResult
|
||||
*/
|
||||
ApplyTransactionResult
|
||||
@@ -151,6 +154,7 @@ applyTransaction(
|
||||
STTx const& tx,
|
||||
bool retryAssured,
|
||||
ApplyFlags flags,
|
||||
beast::Journal journal);
|
||||
beast::Journal journal,
|
||||
std::vector<BatchInnerResult>* innerResults = nullptr);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#include <xrpl/tx/invariants/SponsorshipInvariant.h>
|
||||
#include <xrpl/tx/invariants/VaultInvariant.h>
|
||||
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <set>
|
||||
#include <string>
|
||||
@@ -141,7 +139,7 @@ public:
|
||||
*/
|
||||
class XRPNotCreated
|
||||
{
|
||||
boost::multiprecision::int128_t drops_ = 0;
|
||||
std::int64_t drops_ = 0;
|
||||
|
||||
public:
|
||||
void
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/MathUtilities.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -25,7 +23,6 @@
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -505,46 +502,6 @@ public:
|
||||
};
|
||||
/** @endcond */
|
||||
|
||||
/** @cond INTERNAL */
|
||||
template <class T>
|
||||
[[nodiscard]] std::optional<T>
|
||||
checkedStepAddOpt(T const& lhs, T const& rhs)
|
||||
{
|
||||
if constexpr (std::is_same_v<T, XRPAmount>)
|
||||
{
|
||||
if (auto const r = checkedAdd(lhs.drops(), rhs.drops()))
|
||||
return XRPAmount{*r};
|
||||
return std::nullopt;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, MPTAmount>)
|
||||
{
|
||||
if (auto const r = checkedAdd(lhs.value(), rhs.value()))
|
||||
return MPTAmount{*r};
|
||||
return std::nullopt;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, IOUAmount>)
|
||||
{
|
||||
// IOUAmount is Number-backed and throws on overflow.
|
||||
return lhs + rhs;
|
||||
}
|
||||
else
|
||||
{
|
||||
// A new amount type must decide explicitly how to add; do not fall back
|
||||
// to an unchecked add.
|
||||
static_assert(sizeof(T) == 0, "checkedStepAddOpt: unsupported amount type");
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
[[nodiscard]] T
|
||||
checkedStepAdd(T const& lhs, T const& rhs)
|
||||
{
|
||||
if (auto const r = checkedStepAddOpt(lhs, rhs))
|
||||
return *r;
|
||||
Throw<FlowException>(tecPATH_DRY);
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
/** @cond INTERNAL */
|
||||
// Check equal with tolerance
|
||||
bool
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
@@ -407,7 +408,7 @@ limitOut(
|
||||
if (!qf || qf->isConst())
|
||||
return remainingOut;
|
||||
|
||||
auto const out = [&] {
|
||||
auto const out = [&]() {
|
||||
auto const out = qf->outFromAvgQ(limitQuality);
|
||||
if (!out)
|
||||
return remainingOut;
|
||||
@@ -645,21 +646,11 @@ flow(
|
||||
boost::container::flat_multiset<TOutAmt> savedOuts;
|
||||
savedOuts.reserve(maxTries);
|
||||
|
||||
// Returns std::nullopt if the aggregate overflows; callers treat that as a
|
||||
// dry path.
|
||||
auto sum = [](auto const& col) -> std::optional<std::decay_t<decltype(*col.begin())>> {
|
||||
auto sum = [](auto const& col) {
|
||||
using TResult = std::decay_t<decltype(*col.begin())>;
|
||||
if (col.empty())
|
||||
return TResult{beast::kZero};
|
||||
TResult total = *col.begin();
|
||||
for (auto it = col.begin() + 1; it != col.end(); ++it)
|
||||
{
|
||||
auto const next = checkedStepAddOpt(total, *it);
|
||||
if (!next)
|
||||
return std::nullopt;
|
||||
total = *next;
|
||||
}
|
||||
return total;
|
||||
return std::accumulate(col.begin() + 1, col.end(), *col.begin());
|
||||
};
|
||||
|
||||
// These offers only need to be removed if the payment is not
|
||||
@@ -679,7 +670,7 @@ flow(
|
||||
ammContext.setMultiPath(activeStrands.size() > 1);
|
||||
|
||||
// Limit only if one strand and limitQuality
|
||||
auto const limitRemainingOut = [&] {
|
||||
auto const limitRemainingOut = [&]() {
|
||||
if (activeStrands.size() == 1 && limitQuality)
|
||||
{
|
||||
if (auto const strand = activeStrands.get(0))
|
||||
@@ -758,17 +749,9 @@ flow(
|
||||
{
|
||||
savedIns.insert(best->in);
|
||||
savedOuts.insert(best->out);
|
||||
auto const sumOut = sum(savedOuts);
|
||||
if (!sumOut)
|
||||
return {tecPATH_DRY, std::move(ofrsToRmOnFail)};
|
||||
remainingOut = outReq - *sumOut;
|
||||
remainingOut = outReq - sum(savedOuts);
|
||||
if (sendMax)
|
||||
{
|
||||
auto const sumIn = sum(savedIns);
|
||||
if (!sumIn)
|
||||
return {tecPATH_DRY, std::move(ofrsToRmOnFail)};
|
||||
remainingIn = *sendMax - *sumIn;
|
||||
}
|
||||
remainingIn = *sendMax - sum(savedIns);
|
||||
|
||||
if (flowDebugInfo)
|
||||
{
|
||||
@@ -803,12 +786,8 @@ flow(
|
||||
break;
|
||||
}
|
||||
|
||||
auto const actualOutOpt = sum(savedOuts);
|
||||
auto const actualInOpt = sum(savedIns);
|
||||
if (!actualOutOpt || !actualInOpt)
|
||||
return {tecPATH_DRY, std::move(ofrsToRmOnFail)};
|
||||
auto const actualOut = *actualOutOpt;
|
||||
auto const actualIn = *actualInOpt;
|
||||
auto const actualOut = sum(savedOuts);
|
||||
auto const actualIn = sum(savedIns);
|
||||
|
||||
JLOG(j.trace()) << "Total flow: in: " << to_string(actualIn)
|
||||
<< " out: " << to_string(actualOut);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -33,9 +32,6 @@ public:
|
||||
static std::vector<OptionaledField<STNumber>> const&
|
||||
getValueFields();
|
||||
|
||||
static std::uint32_t
|
||||
getFlagsMask(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
|
||||
@@ -60,10 +60,10 @@ ENV GIT_SSL_CAINFO="/nix/ci-env/etc/ssl/certs/ca-bundle.crt"
|
||||
# Externally-built dynamically-linked ELF binaries hard-code the loader path
|
||||
# (e.g. /lib64/ld-linux-x86-64.so.2) in their PT_INTERP header. Install it
|
||||
# from the Nix store when the base image doesn't already provide one.
|
||||
COPY bin/nix/default-loader-path.sh /usr/local/bin/default-loader-path.sh
|
||||
COPY bin/default-loader-path.sh /tmp/loader-path.sh
|
||||
|
||||
RUN <<EOF
|
||||
target="$(/usr/local/bin/default-loader-path.sh)"
|
||||
target="$(/tmp/loader-path.sh)"
|
||||
|
||||
if [ ! -e "${target}" ]; then
|
||||
# Use the loader from the same glibc that gcc links libc against, so
|
||||
@@ -101,7 +101,7 @@ RUN if echo "${BASE_IMAGE}" | grep -qiE 'nixos'; then \
|
||||
SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]
|
||||
|
||||
# Sanity-check that the built binaries run correctly in the vanilla base image, with the necessary sanitizer runtime libraries installed.
|
||||
COPY bin/install/sanitizer-libs.sh /tmp/install-sanitizer-libs.sh
|
||||
COPY bin/install-sanitizer-libs.sh /tmp/install-sanitizer-libs.sh
|
||||
COPY nix/docker/test_files/cpp/run-binaries.sh /tmp/test_files/cpp/run-binaries.sh
|
||||
COPY nix/docker/test_files/rust/run-binaries.sh /tmp/test_files/rust/run-binaries.sh
|
||||
COPY --from=final /tmp/cpp-bins /tmp/cpp-bins
|
||||
|
||||
@@ -52,10 +52,10 @@ work without `ca-certificates` being installed in the base image.
|
||||
workspace with `cargo` to exercise proc-macro dylib loading.
|
||||
3. **`tester`** — Start again from a clean `BASE_IMAGE` (no Nix toolchain),
|
||||
install only the sanitizer runtime libraries
|
||||
([`bin/install/sanitizer-libs.sh`](../../bin/install/sanitizer-libs.sh)),
|
||||
and run the binaries compiled in `final`. This proves the binaries built with
|
||||
the Nix toolchain actually run on a vanilla base image. On `nixos/nix` this
|
||||
step is skipped (the binaries are patched for a conventional FHS loader).
|
||||
([`install-sanitizer-libs.sh`](./install-sanitizer-libs.sh)), and run the
|
||||
binaries compiled in `final`. This proves the binaries built with the Nix
|
||||
toolchain actually run on a vanilla base image. On `nixos/nix` this step is
|
||||
skipped (the binaries are patched for a conventional FHS loader).
|
||||
4. **Output** — The final image is gated on the tester succeeding: it copies a
|
||||
sentinel file out of `tester`, so a failed test run fails the whole build.
|
||||
|
||||
@@ -75,10 +75,9 @@ toolchain being present at runtime. Two pieces make that work:
|
||||
|
||||
- **An expected dynamic linker in the image.**
|
||||
Binaries built in Nix environments reference a dynamic linker from Nix store paths, which won't be present in the base image. However,
|
||||
[`bin/nix/default-loader-path.sh`](../../bin/nix/default-loader-path.sh) reports the
|
||||
[`bin/default-loader-path.sh`](../../bin/default-loader-path.sh) reports the
|
||||
expected loader path for the current architecture, so we can patch the binaries
|
||||
to use the correct loader. The image ships it as
|
||||
`/usr/local/bin/default-loader-path.sh`.
|
||||
to use the correct loader.
|
||||
|
||||
The build then verifies all of this end to end, and the C++ and Rust programs
|
||||
go through the same pipeline: each is compiled in `final`, has its `PT_INTERP`
|
||||
@@ -92,11 +91,11 @@ whose resulting binary is patched and run like the others.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||
| [`./Dockerfile`](./Dockerfile) | Multi-stage build described above. |
|
||||
| [`./test_files/cpp/`](./test_files/cpp) | C++ sanitizer smoke test: sources + compile/run scripts. |
|
||||
| [`./test_files/rust/`](./test_files/rust) | Rust smoke test: rustc sources + a cargo proc-macro workspace + compile/run scripts. |
|
||||
| [`/bin/check-tools.sh`](../../bin/check-tools.sh) | Verify every expected tools are present and runnable. |
|
||||
| [`/bin/nix/default-loader-path.sh`](../../bin/nix/default-loader-path.sh) | Print the dynamic-linker (`PT_INTERP`) path for the current architecture. |
|
||||
| [`/bin/install/sanitizer-libs.sh`](../../bin/install/sanitizer-libs.sh) | Install `libasan`/`libtsan`/`libubsan` runtimes on the supported base images. |
|
||||
| File | Purpose |
|
||||
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||
| [`./Dockerfile`](./Dockerfile) | Multi-stage build described above. |
|
||||
| [`./test_files/cpp/`](./test_files/cpp) | C++ sanitizer smoke test: sources + compile/run scripts. |
|
||||
| [`./test_files/rust/`](./test_files/rust) | Rust smoke test: rustc sources + a cargo proc-macro workspace + compile/run scripts. |
|
||||
| [`/bin/check-tools.sh`](../../bin/check-tools.sh) | Verify every expected tools are present and runnable. |
|
||||
| [`/bin/default-loader-path.sh`](../../bin/default-loader-path.sh) | Print the dynamic-linker (`PT_INTERP`) path for the current architecture. |
|
||||
| [`/bin/install-sanitizer-libs.sh`](../../bin/install-sanitizer-libs.sh) | Install `libasan`/`libtsan`/`libubsan` runtimes on the supported base images. |
|
||||
|
||||
@@ -8,7 +8,7 @@ set -eo pipefail
|
||||
src_dir="${1:?usage: $0 <src_dir> <dst_dir>}"
|
||||
dst_dir="${2:?usage: $0 <src_dir> <dst_dir>}"
|
||||
|
||||
loader="$(/usr/local/bin/default-loader-path.sh)"
|
||||
loader="$(/tmp/loader-path.sh)"
|
||||
|
||||
mkdir -p "${dst_dir}"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ set -eo pipefail
|
||||
src_dir="${1:?usage: $0 <src_dir> <dst_dir>}"
|
||||
dst_dir="${2:?usage: $0 <src_dir> <dst_dir>}"
|
||||
|
||||
loader="$(/usr/local/bin/default-loader-path.sh)"
|
||||
loader="$(/tmp/loader-path.sh)"
|
||||
|
||||
mkdir -p "${dst_dir}"
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ package/
|
||||
sign_rpm.py Signs the built RPMs (called by CI when publishing)
|
||||
images/
|
||||
packaging/
|
||||
Dockerfile Packaging image, built by `build-packaging-images.yml`; installs its tooling with `bin/install/packaging-tools.sh`
|
||||
Dockerfile Packaging image, built by `build-packaging-images.yml`; installs its tooling with `bin/install-packaging-tools.sh`
|
||||
publish_pkg.py Uploads built packages to the XRPLF Nexus repositories (called by CI, and shipped in that image)
|
||||
xrpld/
|
||||
Dockerfile The xrpld Docker images, installing the built DEB on Ubuntu (see "Docker images")
|
||||
|
||||
@@ -2,7 +2,7 @@ ARG BASE_IMAGE=debian:trixie
|
||||
|
||||
FROM ${BASE_IMAGE}
|
||||
|
||||
RUN --mount=type=bind,source=bin/install/packaging-tools.sh,target=/install-packaging-tools.sh \
|
||||
RUN --mount=type=bind,source=bin/install-packaging-tools.sh,target=/install-packaging-tools.sh \
|
||||
/install-packaging-tools.sh
|
||||
|
||||
# See package/README.md, "Publishing from other repositories".
|
||||
|
||||
@@ -130,13 +130,6 @@ unsigned-integer-overflow:__chrono/duration.h
|
||||
# distinct header from the bits/ directory so it needs its own entry.
|
||||
unsigned-integer-overflow:include/c++/*/bit
|
||||
|
||||
# libstdc++ <format> takes the magnitude of a negative integer with
|
||||
# -static_cast<make_unsigned_t<T>>(v), which wraps by design for the most
|
||||
# negative value (std::format("{}", INT_MIN)). std::to_string avoids the report
|
||||
# only because it spells the same thing (unsigned)~v + 1u. Like <bit>, <format>
|
||||
# is a top-level header rather than one under bits/.
|
||||
unsigned-integer-overflow:include/c++/*/format
|
||||
|
||||
# =============================================================================
|
||||
# Rippled code suppressions
|
||||
# =============================================================================
|
||||
|
||||
@@ -259,7 +259,7 @@ Logs::format(
|
||||
|
||||
output = xrpl::to_string(std::chrono::system_clock::now());
|
||||
|
||||
output += ' ';
|
||||
output += " ";
|
||||
if (!partition.empty())
|
||||
output += partition + ":";
|
||||
|
||||
|
||||
@@ -1557,7 +1557,7 @@ root(Number f, unsigned d)
|
||||
// Scale f into the range (0, 1) such that f's exponent is a multiple of d
|
||||
auto e = f.exponent_ + Number::mantissaLog() + 1;
|
||||
auto const di = static_cast<int>(d);
|
||||
auto ex = [e = e, di = di] // Euclidean remainder of e/d
|
||||
auto ex = [e = e, di = di]() // Euclidean remainder of e/d
|
||||
{
|
||||
int const k = (e >= 0 ? e : e - (di - 1)) / di;
|
||||
int const k2 = e - (k * di);
|
||||
|
||||
@@ -94,7 +94,7 @@ initAnonymous(boost::asio::ssl::context& context)
|
||||
{
|
||||
using namespace openssl;
|
||||
|
||||
static auto kDefaultRsa = [] {
|
||||
static auto kDefaultRsa = []() {
|
||||
BIGNUM* bn = BN_new();
|
||||
BN_set_word(bn, RSA_F4);
|
||||
|
||||
@@ -111,7 +111,7 @@ initAnonymous(boost::asio::ssl::context& context)
|
||||
return rsa;
|
||||
}();
|
||||
|
||||
static auto kDefaultEphemeralPrivateKey = [] {
|
||||
static auto kDefaultEphemeralPrivateKey = []() {
|
||||
auto pkey = EVP_PKEY_new();
|
||||
|
||||
if (!pkey)
|
||||
@@ -128,7 +128,7 @@ initAnonymous(boost::asio::ssl::context& context)
|
||||
return pkey;
|
||||
}();
|
||||
|
||||
static auto kDefaultCert = [] {
|
||||
static auto kDefaultCert = []() {
|
||||
auto x509 = X509_new();
|
||||
|
||||
if (x509 == nullptr)
|
||||
|
||||
@@ -22,7 +22,7 @@ printIdentifiers(SemanticVersion::IdentifierList const& list)
|
||||
for (auto const& x : list)
|
||||
{
|
||||
if (!ret.empty())
|
||||
ret += '.';
|
||||
ret += ".";
|
||||
ret += x;
|
||||
}
|
||||
|
||||
@@ -219,13 +219,13 @@ SemanticVersion::print() const
|
||||
|
||||
if (!preReleaseIdentifiers.empty())
|
||||
{
|
||||
s += '-';
|
||||
s += "-";
|
||||
s += printIdentifiers(preReleaseIdentifiers);
|
||||
}
|
||||
|
||||
if (!metaData.empty())
|
||||
{
|
||||
s += '+';
|
||||
s += "+";
|
||||
s += printIdentifiers(metaData);
|
||||
}
|
||||
|
||||
|
||||
@@ -844,7 +844,7 @@ Reader::addErrorAndRecover(std::string const& message, Token& token, TokenType s
|
||||
Value&
|
||||
Reader::currentValue()
|
||||
{
|
||||
return *nodes_.top();
|
||||
return *(nodes_.top());
|
||||
}
|
||||
|
||||
Reader::Char
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
namespace json {
|
||||
@@ -112,7 +111,7 @@ Value::CZString::CZString(CZString const& other)
|
||||
other.cstr_ != nullptr
|
||||
? valueAllocator()->makeMemberName(other.cstr_)
|
||||
: other.cstr_)
|
||||
, index_([&] -> int {
|
||||
, index_([&]() -> int {
|
||||
if (!other.cstr_)
|
||||
return other.index_;
|
||||
return other.index_ == static_cast<int>(DuplicationPolicy::NoDuplication)
|
||||
@@ -242,14 +241,10 @@ Value::Value(xrpl::Number const& value) : type_(ValueType::String), allocated_(t
|
||||
value_.stringVal = valueAllocator()->duplicateStringValue(tmp.c_str(), tmp.length());
|
||||
}
|
||||
|
||||
Value::Value(std::string const& value) : Value(std::string_view{value})
|
||||
Value::Value(std::string const& value) : type_(ValueType::String), allocated_(true)
|
||||
{
|
||||
}
|
||||
|
||||
Value::Value(std::string_view value) : type_(ValueType::String), allocated_(true)
|
||||
{
|
||||
value_.stringVal = valueAllocator()->duplicateStringValue(
|
||||
value.data(), static_cast<unsigned int>(value.length()));
|
||||
value_.stringVal =
|
||||
valueAllocator()->duplicateStringValue(value.c_str(), (unsigned int)value.length());
|
||||
}
|
||||
|
||||
Value::Value(StaticString const& value) : type_(ValueType::String)
|
||||
@@ -945,7 +940,7 @@ Value::resolveReference(char const* key, bool isStatic)
|
||||
Value
|
||||
Value::get(UInt index, Value const& defaultValue) const
|
||||
{
|
||||
Value const* value = &(*this)[index];
|
||||
Value const* value = &((*this)[index]);
|
||||
return value == &kNull ? defaultValue : *value;
|
||||
}
|
||||
|
||||
@@ -1013,7 +1008,7 @@ Value::append(Value&& value)
|
||||
Value
|
||||
Value::get(char const* key, Value const& defaultValue) const
|
||||
{
|
||||
Value const* value = &(*this)[key];
|
||||
Value const* value = &((*this)[key]);
|
||||
return value == &kNull ? defaultValue : *value;
|
||||
}
|
||||
|
||||
@@ -1056,7 +1051,7 @@ Value::isMember(char const* key) const
|
||||
if (type_ != ValueType::Object)
|
||||
return false;
|
||||
|
||||
Value const* value = &(*this)[key];
|
||||
Value const* value = &((*this)[key]);
|
||||
return value != &kNull;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ valueToQuotedString(char const* value)
|
||||
unsigned const maxsize = (strlen(value) * 2) + 3; // all-escaped+quotes+NULL
|
||||
std::string result;
|
||||
result.reserve(maxsize); // to avoid lots of mallocs
|
||||
result += '"';
|
||||
result += "\"";
|
||||
|
||||
for (char const* c = value; *c != 0; ++c)
|
||||
{
|
||||
@@ -168,7 +168,7 @@ valueToQuotedString(char const* value)
|
||||
}
|
||||
}
|
||||
|
||||
result += '"';
|
||||
result += "\"";
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -213,38 +213,38 @@ FastWriter::writeValue(Value const& value)
|
||||
break;
|
||||
|
||||
case ValueType::Array: {
|
||||
document_ += '[';
|
||||
document_ += "[";
|
||||
int const size = value.size();
|
||||
|
||||
for (int index = 0; index < size; ++index)
|
||||
{
|
||||
if (index > 0)
|
||||
document_ += ',';
|
||||
document_ += ",";
|
||||
|
||||
writeValue(value[index]);
|
||||
}
|
||||
|
||||
document_ += ']';
|
||||
document_ += "]";
|
||||
}
|
||||
break;
|
||||
|
||||
case ValueType::Object: {
|
||||
Value::Members members(value.getMemberNames());
|
||||
document_ += '{';
|
||||
document_ += "{";
|
||||
|
||||
for (auto it = members.begin(); it != members.end(); ++it)
|
||||
{
|
||||
std::string const& name = *it;
|
||||
|
||||
if (it != members.begin())
|
||||
document_ += ',';
|
||||
document_ += ",";
|
||||
|
||||
document_ += valueToQuotedString(name.c_str());
|
||||
document_ += ':';
|
||||
document_ += ":";
|
||||
writeValue(value[name]);
|
||||
}
|
||||
|
||||
document_ += '}';
|
||||
document_ += "}";
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -262,7 +262,7 @@ StyledWriter::write(Value const& root)
|
||||
addChildValues_ = false;
|
||||
indentString_ = "";
|
||||
writeValue(root);
|
||||
document_ += '\n';
|
||||
document_ += "\n";
|
||||
return document_;
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ StyledWriter::writeValue(Value const& value)
|
||||
if (++it; it == members.end())
|
||||
break;
|
||||
|
||||
document_ += ',';
|
||||
document_ += ",";
|
||||
}
|
||||
|
||||
unindent();
|
||||
@@ -371,7 +371,7 @@ StyledWriter::writeArrayValue(Value const& value)
|
||||
if (++index == size)
|
||||
break;
|
||||
|
||||
document_ += ',';
|
||||
document_ += ",";
|
||||
}
|
||||
|
||||
unindent();
|
||||
|
||||
@@ -27,7 +27,7 @@ CachedViewImpl::read(Keylet const& k) const
|
||||
bool cacheHit = false;
|
||||
bool baseRead = false;
|
||||
|
||||
auto const digest = [&] -> std::optional<UInt256> {
|
||||
auto const digest = [&]() -> std::optional<UInt256> {
|
||||
{
|
||||
std::scoped_lock const lock(mutex_);
|
||||
auto const iter = map_.find(k.key);
|
||||
@@ -41,7 +41,7 @@ CachedViewImpl::read(Keylet const& k) const
|
||||
}();
|
||||
if (!digest)
|
||||
return nullptr;
|
||||
auto sle = cache_.fetch(*digest, [&] {
|
||||
auto sle = cache_.fetch(*digest, [&]() {
|
||||
baseRead = true;
|
||||
return base_.read(k);
|
||||
});
|
||||
|
||||
@@ -213,7 +213,7 @@ adjustAmountsByLPTokens(
|
||||
|
||||
if (lpTokensActual < lpTokens)
|
||||
{
|
||||
bool const ammRoundingEnabled = [&] {
|
||||
bool const ammRoundingEnabled = [&]() {
|
||||
if (auto const& rules = getCurrentTransactionRules();
|
||||
rules && rules->enabled(fixAMMv1_1))
|
||||
return true;
|
||||
@@ -238,7 +238,7 @@ adjustAmountsByLPTokens(
|
||||
}
|
||||
|
||||
// Single trade
|
||||
auto const amountActual = [&] {
|
||||
auto const amountActual = [&]() {
|
||||
if (isDeposit == IsDeposit::Yes)
|
||||
{
|
||||
return ammAssetIn(amountBalance, lptAMMBalance, lpTokensActual, tfee);
|
||||
@@ -481,7 +481,7 @@ ammHolds(
|
||||
AuthHandling authHandling,
|
||||
beast::Journal const j)
|
||||
{
|
||||
auto const assets = [&] -> std::optional<std::pair<Asset, Asset>> {
|
||||
auto const assets = [&]() -> std::optional<std::pair<Asset, Asset>> {
|
||||
auto const asset1 = ammSle[sfAsset];
|
||||
auto const asset2 = ammSle[sfAsset2];
|
||||
if (optAsset1 && optAsset2)
|
||||
|
||||
@@ -522,7 +522,7 @@ pseudoAccountAddress(ReadView const& view, UInt256 const& pseudoOwnerKey)
|
||||
[[nodiscard]] std::vector<SField const*> const&
|
||||
getPseudoAccountFields()
|
||||
{
|
||||
static std::vector<SField const*> const kPseudoFields = [] {
|
||||
static std::vector<SField const*> const kPseudoFields = []() {
|
||||
auto const ar = LedgerFormats::getInstance().findByType(ltACCOUNT_ROOT);
|
||||
if (!ar)
|
||||
{
|
||||
|
||||
@@ -744,7 +744,7 @@ tryOverpayment(
|
||||
// Calculate what the new loan state should be with the new periodic payment,
|
||||
// including the preserved rounding errors.
|
||||
|
||||
auto const newTheoreticalState = [&] {
|
||||
auto const newTheoreticalState = [&]() {
|
||||
auto const state = computeTheoreticalLoanState(
|
||||
rules,
|
||||
newLoanProperties.periodicPayment,
|
||||
@@ -2179,7 +2179,7 @@ computeLoanProperties(
|
||||
auto const periodicPayment =
|
||||
detail::loanPeriodicPayment(rules, principalOutstanding, periodicRate, paymentsRemaining);
|
||||
|
||||
auto const [totalValueOutstanding, loanScale] = [&] {
|
||||
auto const [totalValueOutstanding, loanScale] = [&]() {
|
||||
// only round up if there should be interest
|
||||
NumberRoundModeGuard const mg(
|
||||
periodicRate == 0 ? Number::RoundingMode::ToNearest : Number::RoundingMode::Upward);
|
||||
@@ -2221,7 +2221,7 @@ computeLoanProperties(
|
||||
// Compute the principal part of the first payment. This is needed
|
||||
// because the principal part may be rounded down to zero, which
|
||||
// would prevent the principal from ever being paid down.
|
||||
auto const firstPaymentPrincipal = [&] {
|
||||
auto const firstPaymentPrincipal = [&]() {
|
||||
// Compute the parts for the first payment. Ensure that the
|
||||
// principal payment will actually change the principal.
|
||||
auto const startingState = computeTheoreticalLoanState(
|
||||
|
||||
@@ -500,7 +500,7 @@ enforceMPTokenAuthorization(
|
||||
auto const sleToken = ctx.view.read(keylet); // NOTE: might be null
|
||||
auto const maybeDomainID = sleIssuance->at(~sfDomainID);
|
||||
bool expired = false;
|
||||
bool const authorizedByDomain = [&] -> bool {
|
||||
bool const authorizedByDomain = [&]() -> bool {
|
||||
// NOTE: defensive here, should be checked in preclaim
|
||||
if (!maybeDomainID.has_value())
|
||||
return false; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/MathUtilities.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
@@ -1158,10 +1157,6 @@ accountSendMultiIOU(
|
||||
|
||||
if (receiver)
|
||||
{
|
||||
// Confirm the running debit will not overflow before crediting.
|
||||
if (!checkedAdd(takeFromSender.xrp().drops(), amount.xrp().drops()))
|
||||
return tecINTERNAL;
|
||||
|
||||
// Increment XRP balance.
|
||||
auto const rcvBal = receiver->getFieldAmount(sfBalance);
|
||||
receiver->setFieldAmount(sfBalance, rcvBal + amount);
|
||||
@@ -1169,7 +1164,7 @@ accountSendMultiIOU(
|
||||
|
||||
view.update(receiver);
|
||||
|
||||
// Take what is actually sent.
|
||||
// Take what is actually sent
|
||||
takeFromSender += amount;
|
||||
}
|
||||
|
||||
@@ -1462,8 +1457,6 @@ directSendNoLimitMultiMPT(
|
||||
}
|
||||
|
||||
// Direct send: redeeming MPTs and/or sending own MPTs.
|
||||
if (!checkedAdd(actual.mpt().value(), amount.mpt().value()))
|
||||
return tecINTERNAL;
|
||||
if (auto const ter = directSendNoFeeMPT(view, senderID, receiverID, amount, j);
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
@@ -1491,10 +1484,6 @@ directSendNoLimitMultiMPT(
|
||||
actualSend = multiply(amount, rate);
|
||||
}
|
||||
}
|
||||
// actual is a superset of takeFromSender, so checking it before both add
|
||||
// sites also protects the debit accumulator.
|
||||
if (!checkedAdd(actual.mpt().value(), actualSend.mpt().value()))
|
||||
return tecINTERNAL;
|
||||
actual += actualSend;
|
||||
takeFromSender += actualSend;
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ Database::importInternal(Backend& dstBackend, Database& srcDB)
|
||||
{
|
||||
Batch batch;
|
||||
batch.reserve(kBatchWritePreallocationSize);
|
||||
auto storeBatch = [&, fname = __func__] {
|
||||
auto storeBatch = [&, fname = __func__]() {
|
||||
try
|
||||
{
|
||||
dstBackend.storeBatch(batch);
|
||||
|
||||
@@ -20,102 +20,88 @@ namespace detail {
|
||||
// will remain in the object file. But the string literals will remain.
|
||||
//
|
||||
// There's a certain amount of tension in determining the correct HTTP
|
||||
// status to associate with a given RPC error. Every row below names its
|
||||
// HTTP status, and a row that omits it does not compile, since ErrorInfo has
|
||||
// no constructor that leaves the status out.
|
||||
// status to associate with a given RPC error. Initially all RPC errors
|
||||
// returned 200 (OK). And that's the default behavior if no HTTP status code
|
||||
// is specified below.
|
||||
//
|
||||
// The codes currently selected target the load balancer fail-over use case.
|
||||
// If a query fails on one node but is likely to have a positive outcome
|
||||
// on a different node, then the failure should return a 4xx/5xx range
|
||||
// status code.
|
||||
|
||||
// The rows below are aligned by hand into four columns, so that a wrong status or a mistyped token
|
||||
// is visible by scanning one column. That cannot be had inside the 100-column limit once the
|
||||
// longest enumerator and the longest message sit in one row. So this region is exempt from the
|
||||
// limit by design rather than by oversight.
|
||||
// clang-format off
|
||||
static constexpr ErrorInfo kUnorderedErrorInfos[]{
|
||||
{RpcActMalformed, "actMalformed", "Account malformed.", 400},
|
||||
{RpcActNotFound, "actNotFound", "Account not found.", 404},
|
||||
{RpcAlreadyMultisig, "alreadyMultisig", "Already multisigned.", 400},
|
||||
{RpcAlreadySingleSig, "alreadySingleSig", "Already single-signed.", 400},
|
||||
{RpcAmendmentBlocked, "amendmentBlocked", "Amendment blocked, need upgrade.", 503},
|
||||
{RpcExpiredValidatorList, "unlBlocked", "Validator list expired.", 503},
|
||||
{RpcAtxDeprecated, "deprecated", "Use the new API or specify a ledger range.", 400},
|
||||
{RpcBadKeyType, "badKeyType", "Bad key type.", 400},
|
||||
{RpcBadFeature, "badFeature", "Feature unknown or invalid.", 500},
|
||||
{RpcBadIssuer, "badIssuer", "Issuer account malformed.", 400},
|
||||
{RpcBadMarket, "badMarket", "No such market.", 404},
|
||||
{RpcBadSecret, "badSecret", "Secret does not match account.", 403},
|
||||
{RpcBadSeed, "badSeed", "Disallowed seed.", 403},
|
||||
{RpcBadSyntax, "badSyntax", "Syntax error.", 400},
|
||||
{RpcChannelMalformed, "channelMalformed", "Payment channel is malformed.", 400},
|
||||
{RpcChannelAmtMalformed, "channelAmtMalformed", "Payment channel amount is malformed.", 400},
|
||||
{RpcCommandMissing, "commandMissing", "Missing command entry.", 400},
|
||||
{RpcDbDeserialization, "dbDeserialization", "Database deserialization error.", 502},
|
||||
{RpcDstActMalformed, "dstActMalformed", "Destination account is malformed.", 400},
|
||||
{RpcDstActMissing, "dstActMissing", "Destination account not provided.", 400},
|
||||
{RpcDstActNotFound, "dstActNotFound", "Destination account not found.", 404},
|
||||
{RpcDstAmtMalformed, "dstAmtMalformed", "Destination amount/currency/issuer is malformed.", 400},
|
||||
{RpcDstAmtMissing, "dstAmtMissing", "Destination amount/currency/issuer is missing.", 400},
|
||||
{RpcDstIsrMalformed, "dstIsrMalformed", "Destination issuer is malformed.", 400},
|
||||
{RpcExcessiveLgrRange, "excessiveLgrRange", "Ledger range exceeds 1000.", 400},
|
||||
{RpcForbidden, "forbidden", "Bad credentials.", 403},
|
||||
{RpcHighFee, "highFee", "Current transaction fee exceeds your limit.", 402},
|
||||
{RpcInternal, "internal", "Internal error.", 500},
|
||||
{RpcInvalidLgrRange, "invalidLgrRange", "Ledger range is invalid.", 400},
|
||||
{RpcInvalidParams, "invalidParams", "Invalid parameters.", 400},
|
||||
{RpcInvalidHotwallet, "invalidHotWallet", "Invalid hotwallet.", 400},
|
||||
{RpcIssueMalformed, "issueMalformed", "Issue is malformed.", 400},
|
||||
{RpcJsonRpc, "json_rpc", "JSON-RPC transport error.", 500},
|
||||
{RpcLgrIdxsInvalid, "lgrIdxsInvalid", "Ledger indexes invalid.", 400},
|
||||
{RpcLgrIdxMalformed, "lgrIdxMalformed", "Ledger index malformed.", 400},
|
||||
{RpcLgrNotFound, "lgrNotFound", "Ledger not found.", 404},
|
||||
{RpcLgrNotValidated, "lgrNotValidated", "Ledger not validated.", 202},
|
||||
{RpcMasterDisabled, "masterDisabled", "Master key is disabled.", 403},
|
||||
{RpcNotEnabled, "notEnabled", "Not enabled in configuration.", 501},
|
||||
{RpcNotImpl, "notImpl", "Not implemented.", 501},
|
||||
{RpcNotReady, "notReady", "Not ready to handle this request.", 503},
|
||||
{RpcNotSupported, "notSupported", "Operation not supported.", 501},
|
||||
{RpcNoClosed, "noClosed", "Closed ledger is unavailable.", 503},
|
||||
{RpcNoCurrent, "noCurrent", "Current ledger is unavailable.", 503},
|
||||
{RpcNotSynced, "notSynced", "Not synced to the network.", 503},
|
||||
{RpcNoEvents, "noEvents", "Current transport does not support events.", 405},
|
||||
{RpcNoNetwork, "noNetwork", "Not synced to the network.", 503},
|
||||
{RpcWrongNetwork, "wrongNetwork", "Wrong network.", 503},
|
||||
{RpcNoPermission, "noPermission", "You don't have permission for this command.", 401},
|
||||
{RpcNoPfRequest, "noPathRequest", "No pathfinding request in progress.", 404},
|
||||
{RpcObjectNotFound, "objectNotFound", "The requested object was not found.", 404},
|
||||
{RpcPublicMalformed, "publicMalformed", "Public key is malformed.", 400},
|
||||
{RpcSendmaxMalformed, "sendMaxMalformed", "SendMax amount malformed.", 400},
|
||||
{RpcSigningMalformed, "signingMalformed", "Signing of transaction is malformed.", 400},
|
||||
{RpcSlowDown, "slowDown", "You are placing too much load on the server.", 429},
|
||||
{RpcSrcActMalformed, "srcActMalformed", "Source account is malformed.", 400},
|
||||
{RpcSrcActMissing, "srcActMissing", "Source account not provided.", 400},
|
||||
{RpcSrcActNotFound, "srcActNotFound", "Source account not found.", 404},
|
||||
{RpcDelegateActNotFound, "delegateActNotFound", "Delegate account not found.", 404},
|
||||
{RpcSrcCurMalformed, "srcCurMalformed", "Source currency is malformed.", 400},
|
||||
{RpcSrcIsrMalformed, "srcIsrMalformed", "Source issuer is malformed.", 400},
|
||||
{RpcStreamMalformed, "malformedStream", "Stream malformed.", 400},
|
||||
{RpcTooBusy, "tooBusy", "The server is too busy to help you now.", 503},
|
||||
{RpcTxnNotFound, "txnNotFound", "Transaction not found.", 404},
|
||||
{RpcUnknownCommand, "unknownCmd", "Unknown method.", 405},
|
||||
{RpcOracleMalformed, "oracleMalformed", "Oracle request is malformed.", 400},
|
||||
{RpcBadCredentials, "badCredentials", "Credentials do not exist, are not accepted, or have expired.", 400},
|
||||
{RpcTxSigned, "transactionSigned", "Transaction should not be signed.", 400},
|
||||
{RpcDomainMalformed, "domainMalformed", "Domain is malformed.", 400},
|
||||
{RpcEntryNotFound, "entryNotFound", "Entry not found.", 400},
|
||||
{RpcUnexpectedLedgerType, "unexpectedLedgerType", "Unexpected ledger type.", 400},
|
||||
{RpcInvalidTransaction, "invalidTransaction", "Transaction is invalid.", 400},
|
||||
{RpcInternalSubmit, "internalSubmit", "Internal error during submit.", 500},
|
||||
{RpcInternalJson, "internalJson", "Internal error during JSON handling.", 500},
|
||||
{RpcInternalSimulate, "internalSimulate", "Internal error during simulate.", 500},
|
||||
{RpcFieldNotFoundTransaction, "fieldNotFoundTransaction", "Missing required field.", 400},
|
||||
{RpcNotYetImplemented, "notYetImplemented", "Not yet implemented.", 501},
|
||||
{RpcTransactionNotFound, "transactionNotFound", "Transaction not found.", 404},
|
||||
{RpcMalformedRequest, "malformedRequest", "Request is malformed.", 400},
|
||||
{RpcNotStandAlone, "notStandAlone", "Server is not running stand-alone.", 501},
|
||||
{RpcUnknownOption, "unknownOption", "Unknown option.", 400},
|
||||
{RpcActMalformed, "actMalformed", "Account malformed."},
|
||||
{RpcActNotFound, "actNotFound", "Account not found."},
|
||||
{RpcAlreadyMultisig, "alreadyMultisig", "Already multisigned."},
|
||||
{RpcAlreadySingleSig, "alreadySingleSig", "Already single-signed."},
|
||||
{RpcAmendmentBlocked, "amendmentBlocked", "Amendment blocked, need upgrade.", 503},
|
||||
{RpcExpiredValidatorList, "unlBlocked", "Validator list expired.", 503},
|
||||
{RpcAtxDeprecated, "deprecated", "Use the new API or specify a ledger range.", 400},
|
||||
{RpcBadKeyType, "badKeyType", "Bad key type.", 400},
|
||||
{RpcBadFeature, "badFeature", "Feature unknown or invalid.", 500},
|
||||
{RpcBadIssuer, "badIssuer", "Issuer account malformed.", 400},
|
||||
{RpcBadMarket, "badMarket", "No such market.", 404},
|
||||
{RpcBadSecret, "badSecret", "Secret does not match account.", 403},
|
||||
{RpcBadSeed, "badSeed", "Disallowed seed.", 403},
|
||||
{RpcBadSyntax, "badSyntax", "Syntax error.", 400},
|
||||
{RpcChannelMalformed, "channelMalformed", "Payment channel is malformed.", 400},
|
||||
{RpcChannelAmtMalformed, "channelAmtMalformed", "Payment channel amount is malformed.", 400},
|
||||
{RpcCommandMissing, "commandMissing", "Missing command entry.", 400},
|
||||
{RpcDbDeserialization, "dbDeserialization", "Database deserialization error.", 502},
|
||||
{RpcDstActMalformed, "dstActMalformed", "Destination account is malformed.", 400},
|
||||
{RpcDstActMissing, "dstActMissing", "Destination account not provided.", 400},
|
||||
{RpcDstActNotFound, "dstActNotFound", "Destination account not found.", 404},
|
||||
{RpcDstAmtMalformed, "dstAmtMalformed", "Destination amount/currency/issuer is malformed.", 400},
|
||||
{RpcDstAmtMissing, "dstAmtMissing", "Destination amount/currency/issuer is missing.", 400},
|
||||
{RpcDstIsrMalformed, "dstIsrMalformed", "Destination issuer is malformed.", 400},
|
||||
{RpcExcessiveLgrRange, "excessiveLgrRange", "Ledger range exceeds 1000.", 400},
|
||||
{RpcForbidden, "forbidden", "Bad credentials.", 403},
|
||||
{RpcHighFee, "highFee", "Current transaction fee exceeds your limit.", 402},
|
||||
{RpcInternal, "internal", "Internal error.", 500},
|
||||
{RpcInvalidLgrRange, "invalidLgrRange", "Ledger range is invalid.", 400},
|
||||
{RpcInvalidParams, "invalidParams", "Invalid parameters.", 400},
|
||||
{RpcInvalidHotwallet, "invalidHotWallet", "Invalid hotwallet.", 400},
|
||||
{RpcIssueMalformed, "issueMalformed", "Issue is malformed.", 400},
|
||||
{RpcJsonRpc, "json_rpc", "JSON-RPC transport error.", 500},
|
||||
{RpcLgrIdxsInvalid, "lgrIdxsInvalid", "Ledger indexes invalid.", 400},
|
||||
{RpcLgrIdxMalformed, "lgrIdxMalformed", "Ledger index malformed.", 400},
|
||||
{RpcLgrNotFound, "lgrNotFound", "Ledger not found.", 404},
|
||||
{RpcLgrNotValidated, "lgrNotValidated", "Ledger not validated.", 202},
|
||||
{RpcMasterDisabled, "masterDisabled", "Master key is disabled.", 403},
|
||||
{RpcNotEnabled, "notEnabled", "Not enabled in configuration.", 501},
|
||||
{RpcNotImpl, "notImpl", "Not implemented.", 501},
|
||||
{RpcNotReady, "notReady", "Not ready to handle this request.", 503},
|
||||
{RpcNotSupported, "notSupported", "Operation not supported.", 501},
|
||||
{RpcNoClosed, "noClosed", "Closed ledger is unavailable.", 503},
|
||||
{RpcNoCurrent, "noCurrent", "Current ledger is unavailable.", 503},
|
||||
{RpcNotSynced, "notSynced", "Not synced to the network.", 503},
|
||||
{RpcNoEvents, "noEvents", "Current transport does not support events.", 405},
|
||||
{RpcNoNetwork, "noNetwork", "Not synced to the network.", 503},
|
||||
{RpcWrongNetwork, "wrongNetwork", "Wrong network.", 503},
|
||||
{RpcNoPermission, "noPermission", "You don't have permission for this command.", 401},
|
||||
{RpcNoPfRequest, "noPathRequest", "No pathfinding request in progress.", 404},
|
||||
{RpcObjectNotFound, "objectNotFound", "The requested object was not found.", 404},
|
||||
{RpcPublicMalformed, "publicMalformed", "Public key is malformed.", 400},
|
||||
{RpcSendmaxMalformed, "sendMaxMalformed", "SendMax amount malformed.", 400},
|
||||
{RpcSigningMalformed, "signingMalformed", "Signing of transaction is malformed.", 400},
|
||||
{RpcSlowDown, "slowDown", "You are placing too much load on the server.", 429},
|
||||
{RpcSrcActMalformed, "srcActMalformed", "Source account is malformed.", 400},
|
||||
{RpcSrcActMissing, "srcActMissing", "Source account not provided.", 400},
|
||||
{RpcSrcActNotFound, "srcActNotFound", "Source account not found.", 404},
|
||||
{RpcDelegateActNotFound, "delegateActNotFound", "Delegate account not found.", 404},
|
||||
{RpcSrcCurMalformed, "srcCurMalformed", "Source currency is malformed.", 400},
|
||||
{RpcSrcIsrMalformed, "srcIsrMalformed", "Source issuer is malformed.", 400},
|
||||
{RpcStreamMalformed, "malformedStream", "Stream malformed.", 400},
|
||||
{RpcTooBusy, "tooBusy", "The server is too busy to help you now.", 503},
|
||||
{RpcTxnNotFound, "txnNotFound", "Transaction not found.", 404},
|
||||
{RpcUnknownCommand, "unknownCmd", "Unknown method.", 405},
|
||||
{RpcOracleMalformed, "oracleMalformed", "Oracle request is malformed.", 400},
|
||||
{RpcBadCredentials, "badCredentials", "Credentials do not exist, are not accepted, or have expired.", 400},
|
||||
{RpcTxSigned, "transactionSigned", "Transaction should not be signed.", 400},
|
||||
{RpcDomainMalformed, "domainMalformed", "Domain is malformed.", 400},
|
||||
{RpcEntryNotFound, "entryNotFound", "Entry not found.", 400},
|
||||
{RpcUnexpectedLedgerType, "unexpectedLedgerType", "Unexpected ledger type.", 400},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ FeatureCollections::registerFeature(std::string const& name, Supported support,
|
||||
|
||||
features_.emplace_back(name, f);
|
||||
|
||||
auto const getAmendmentSupport = [=] {
|
||||
auto const getAmendmentSupport = [=]() {
|
||||
if (vote == VoteBehavior::Obsolete)
|
||||
return AmendmentSupport::Retired;
|
||||
return support == Supported::Yes ? AmendmentSupport::Supported
|
||||
|
||||
@@ -240,7 +240,8 @@ skip(LedgerIndex ledger) noexcept
|
||||
{
|
||||
return {
|
||||
ltLEDGER_HASHES,
|
||||
indexHash(LedgerNameSpace::SkipList, static_cast<std::uint32_t>(ledger) >> 16)};
|
||||
indexHash(
|
||||
LedgerNameSpace::SkipList, std::uint32_t(static_cast<std::uint32_t>(ledger) >> 16))};
|
||||
}
|
||||
|
||||
Keylet const&
|
||||
|
||||
@@ -182,7 +182,7 @@ InnerObjectFormats::findSOTemplateBySField(SField const& sField) const
|
||||
{
|
||||
auto itemPtr = findByType(sField.getCode());
|
||||
if (itemPtr != nullptr)
|
||||
return &itemPtr->getSOTemplate();
|
||||
return &(itemPtr->getSOTemplate());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -23,15 +23,15 @@ Issue::getText() const
|
||||
|
||||
if (!isXRP(currency))
|
||||
{
|
||||
ret += '/';
|
||||
ret += "/";
|
||||
|
||||
if (isXRP(account))
|
||||
{
|
||||
ret += '0';
|
||||
ret += "0";
|
||||
}
|
||||
else if (account == noAccount())
|
||||
{
|
||||
ret += '1';
|
||||
ret += "1";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ setCurrentTransactionRules(std::optional<Rules> r)
|
||||
// the value is needed. That could get expensive fast.
|
||||
|
||||
// Declare the range this way to keep clang-tidy from complaining
|
||||
auto const range = [&r] {
|
||||
auto const range = [&r]() {
|
||||
// If any new conditions with new amendments are added to "enableLargeNumbers", those
|
||||
// amendments must also be added to useRulesGuards.
|
||||
bool const enableLargeNumbers = !r ||
|
||||
|
||||
@@ -111,7 +111,7 @@ SField::getField(int code)
|
||||
|
||||
if (it != knownCodeToField.end())
|
||||
{
|
||||
return *it->second;
|
||||
return *(it->second);
|
||||
}
|
||||
return sfInvalid;
|
||||
}
|
||||
@@ -139,7 +139,7 @@ SField::getField(std::string const& fieldName)
|
||||
|
||||
if (it != knownNameToField.end())
|
||||
{
|
||||
return *it->second;
|
||||
return *(it->second);
|
||||
}
|
||||
return sfInvalid;
|
||||
}
|
||||
|
||||
@@ -864,7 +864,7 @@ STAmount::canonicalize()
|
||||
{
|
||||
Throw<std::runtime_error>("Native currency amount out of range");
|
||||
}
|
||||
if (!native() && value_ > kMaxMpTokenAmount)
|
||||
else if (!native() && value_ > kMaxMpTokenAmount)
|
||||
{
|
||||
Throw<std::runtime_error>("MPT amount out of range");
|
||||
}
|
||||
@@ -927,7 +927,7 @@ amountFromJson(SField const& name, json::Value const& v)
|
||||
{
|
||||
Throw<std::runtime_error>("XRP may not be specified with a null Json value");
|
||||
}
|
||||
if (v.isObject())
|
||||
else if (v.isObject())
|
||||
{
|
||||
if (!validJSONAsset(v))
|
||||
Throw<std::runtime_error>("Invalid Asset's Json specification");
|
||||
@@ -1590,7 +1590,7 @@ mulRoundImpl(STAmount const& v1, STAmount const& v2, Asset const& asset, bool ro
|
||||
{
|
||||
CanonicalizeFunc(asset.integral(), amount, offset, roundUp);
|
||||
}
|
||||
STAmount result = [&] {
|
||||
STAmount result = [&]() {
|
||||
// If appropriate, tell Number to round down. This gives the desired
|
||||
// result from STAmount::canonicalize.
|
||||
MightSaveRound const savedRound(Number::RoundingMode::TowardsZero);
|
||||
@@ -1695,7 +1695,7 @@ divRoundImpl(STAmount const& num, STAmount const& den, Asset const& asset, bool
|
||||
if (resultNegative != roundUp)
|
||||
canonicalizeRound(asset.integral(), amount, offset, roundUp);
|
||||
|
||||
STAmount result = [&] {
|
||||
STAmount result = [&]() {
|
||||
// If appropriate, tell Number the rounding mode we are using.
|
||||
// Note that "roundUp == true" actually means "round away from zero".
|
||||
// Otherwise, round toward zero.
|
||||
|
||||
@@ -98,13 +98,13 @@ STArray::getFullText() const
|
||||
for (auto const& obj : v_)
|
||||
{
|
||||
if (!first)
|
||||
r += ',';
|
||||
r += ",";
|
||||
|
||||
r += obj.getFullText();
|
||||
first = false;
|
||||
}
|
||||
|
||||
r += ']';
|
||||
r += "]";
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -117,13 +117,13 @@ STArray::getText() const
|
||||
for (STObject const& o : v_)
|
||||
{
|
||||
if (!first)
|
||||
r += ',';
|
||||
r += ",";
|
||||
|
||||
r += o.getText();
|
||||
first = false;
|
||||
}
|
||||
|
||||
r += ']';
|
||||
r += "]";
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user