mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-22 03:27:08 +00:00
Compare commits
30
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a0c8ba982 | ||
|
|
4d30ee7ec3 | ||
|
|
d25df82c14 | ||
|
|
0fe9167bed | ||
|
|
2c5cee2925 | ||
|
|
450d00ad65 | ||
|
|
b515af4d4e | ||
|
|
cf495fde86 | ||
|
|
00bf88afad | ||
|
|
f45dab46d1 | ||
|
|
b87ad0f08e | ||
|
|
50c9e6335e | ||
|
|
78709c1d09 | ||
|
|
b67266aad4 | ||
|
|
79a8b4849e | ||
|
|
49410ad867 | ||
|
|
3689dca688 | ||
|
|
671a00b1ac | ||
|
|
9096ec03a7 | ||
|
|
5fec493960 | ||
|
|
a6a4fff2aa | ||
|
|
c2478f509c | ||
|
|
c908ed7839 | ||
|
|
fc57311c81 | ||
|
|
818de49264 | ||
|
|
1318b1e58b | ||
|
|
617c816ec8 | ||
|
|
34fc86f585 | ||
|
|
e071f0a28d | ||
|
|
8faa624ade |
No files matched your search
@@ -76,7 +76,6 @@ Checks: "-*,
|
||||
-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 +92,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
|
||||
|
||||
@@ -174,8 +174,10 @@ test.server > xrpl.basics
|
||||
test.server > xrpl.config
|
||||
test.server > xrpld.app
|
||||
test.server > xrpld.core
|
||||
test.server > xrpld.rpc
|
||||
test.server > xrpl.json
|
||||
test.server > xrpl.protocol
|
||||
test.server > xrpl.resource
|
||||
test.server > xrpl.server
|
||||
test.unit_test > xrpl.basics
|
||||
test.unit_test > xrpl.protocol
|
||||
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
|
||||
- name: Create issue
|
||||
if: ${{ steps.audit.outcome != 'success' && github.event_name == 'schedule' }}
|
||||
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
|
||||
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
|
||||
with:
|
||||
title: "cargo audit found vulnerabilities"
|
||||
body_file: /tmp/cargo-audit-issue.md
|
||||
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
|
||||
- name: Create issue
|
||||
if: ${{ failure() && github.event_name == 'schedule' && github.repository == 'XRPLF/rippled' }}
|
||||
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
|
||||
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
|
||||
with:
|
||||
title: "Releases not merged back into develop"
|
||||
body_file: ${{ env.ISSUE_FILE }}
|
||||
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
|
||||
- name: Upload regenerated snapshot
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: check-tools-${{ runner.os }}-${{ runner.arch }}
|
||||
path: ${{ matrix.snapshot }}
|
||||
@@ -14,7 +14,7 @@ on:
|
||||
jobs:
|
||||
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
|
||||
run-hooks:
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@279ec358f4a1be4088be3e024b07916fa97c75b6
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@d7f2acb47d9662e1e2f8b1f5feffa6d21cc3290a
|
||||
with:
|
||||
runs_on: ubuntu-latest
|
||||
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-70b8fd3" }'
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
with:
|
||||
enable_ccache: ${{ inputs.ccache_enabled }}
|
||||
|
||||
@@ -280,7 +280,7 @@ jobs:
|
||||
|
||||
- name: Upload the binary (Linux)
|
||||
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && runner.os == 'Linux' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: xrpld-${{ inputs.config_name }}
|
||||
path: ${{ env.BUILD_DIR }}/xrpld
|
||||
@@ -294,7 +294,7 @@ jobs:
|
||||
|
||||
- name: Upload the validator-keys binary
|
||||
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && env.VALIDATOR_KEYS_ENABLED == 'true' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: validator-keys-${{ inputs.config_name }}
|
||||
path: |
|
||||
@@ -305,7 +305,7 @@ jobs:
|
||||
|
||||
- name: Upload the test binary (Linux)
|
||||
if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: xrpl_tests-${{ inputs.config_name }}
|
||||
path: ${{ env.BUILD_DIR }}/xrpl_tests
|
||||
@@ -321,7 +321,7 @@ jobs:
|
||||
|
||||
- name: Upload server definitions
|
||||
if: ${{ github.event.repository.visibility == 'public' && inputs.config_name == 'ubuntu-gcc-debug-amd64-coverage' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: server-definitions
|
||||
path: ${{ env.BUILD_DIR }}/server_definitions.json
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
@@ -109,7 +109,7 @@ jobs:
|
||||
|
||||
- name: Upload clang-tidy output
|
||||
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
path: ${{ env.OUTPUT_FILE }}
|
||||
archive: false
|
||||
@@ -133,7 +133,7 @@ jobs:
|
||||
|
||||
- name: Upload clang-tidy diff output
|
||||
if: ${{ github.event.repository.visibility == 'public' && steps.files_changed.outcome != 'success' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
path: ${{ env.DIFF_FILE }}
|
||||
archive: false
|
||||
@@ -185,7 +185,7 @@ jobs:
|
||||
|
||||
- name: Create issue
|
||||
if: ${{ steps.run_clang_tidy.outcome != 'success' && inputs.create_issue_on_failure }}
|
||||
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
|
||||
uses: XRPLF/actions/create-issue@b489c21d53928f7dab4874912fec40e4f6c9e85e
|
||||
with:
|
||||
title: "Clang-tidy check failed"
|
||||
body_file: ${{ env.ISSUE_FILE }}
|
||||
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
# Every package lands in one directory; the step below picks its own,
|
||||
# which keeps this independent of the artifact names.
|
||||
- name: Download package artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||
with:
|
||||
pattern: "*-pkg"
|
||||
merge-multiple: true
|
||||
|
||||
@@ -100,18 +100,18 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
- name: Download pre-built xrpld binary
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||
with:
|
||||
name: ${{ matrix.xrpld_artifact_name }}
|
||||
path: ${{ env.BUILD_DIR }}
|
||||
|
||||
- name: Download pre-built validator-keys binary
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||
with:
|
||||
name: ${{ matrix.validator_keys_artifact_name }}
|
||||
path: ${{ env.BUILD_DIR }}
|
||||
@@ -151,7 +151,7 @@ jobs:
|
||||
# version starts with a digit and a longer name does not, so that one digit
|
||||
# is what tells 'xrpld-3.4.1-...' from 'xrpld-assert-3.4.1-...'.
|
||||
- name: Upload package artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: ${{ matrix.xrpld_artifact_name }}-pkg
|
||||
path: |
|
||||
@@ -160,7 +160,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload debug symbol artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: ${{ matrix.xrpld_artifact_name }}-pkg-debug
|
||||
path: |
|
||||
@@ -225,13 +225,13 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
# Both artifacts, so the debug symbols are published alongside the package.
|
||||
- name: Download package artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||
with:
|
||||
pattern: ${{ matrix.xrpld_artifact_name }}-pkg*
|
||||
merge-multiple: true
|
||||
@@ -287,7 +287,7 @@ jobs:
|
||||
run: echo "PUSH=${PUSH}" | tee -a "${GITHUB_ENV}"
|
||||
|
||||
- name: Download package artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||
with:
|
||||
pattern: "*-pkg"
|
||||
merge-multiple: true
|
||||
@@ -295,7 +295,7 @@ jobs:
|
||||
|
||||
- name: Download voidstar binary
|
||||
if: ${{ matrix.target == 'voidstar' }}
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||
with:
|
||||
name: xrpld-ubuntu-clang-debug-amd64-voidstar
|
||||
path: ${{ env.CONTEXT }}
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -22,6 +22,37 @@ API version 2 is available in `xrpld` version 2.0.0 and later. See [API-VERSION-
|
||||
|
||||
This version is supported by all `xrpld` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- The `ripplerpc` request field, which selects the shape of the JSON-RPC reply envelope, is now validated, and a value that is not exactly `"1.0"`, `"2.0"` or `"3.0"` is rejected. Two things it does not reach: a WebSocket session, which reads the field only to echo it back, and API version 3, where the field selects nothing and so is neither read nor checked, `ripplerpc: "banana"` and no `ripplerpc` at all being served alike. A request sending `"2"`, `" 2.0"`, `"2.00"`, `"02.0"`, `"2.0.0"`, `"10.0"` or any other text, such as `"abc"` or `"x2"`, gets a working reply today. After this ships, such a request sent alone gets HTTP 400 with `ripplerpc is not a supported version`, charged as a malformed request, and such an entry of a `"method": "batch"` body gets that error in its own reply while the batch answers 200. A client that spells the version loosely must therefore be corrected to one of the three exact values, or omit the field. Previously the value was compared as a string, which both accepted values that name no version and ordered multi-digit versions incorrectly: `"abc"` and `"x2"` sorted above `"3.0"` and so selected version 3, and `"10.0"` sorted below `"2.0"` and so selected version 1. Requests that send one of the three supported values, or omit the field, are unaffected.
|
||||
- `subscribe`: every subscription a connection holds must name the same `api_version`. The first `subscribe` establishes it, and a later one naming a different version is refused with `apiVersionConflict`, registering nothing; the message names the version the connection's subscriptions are served at. The HTTP status is 400 where the envelope derives it from the error, with `ripplerpc: "3.0"` or at API version 3, and 200 with `ripplerpc` `"1.0"` or `"2.0"`, as for every error; a WebSocket frame carries no status. A `subscribe` refused for another reason, a stream name the server does not have for one, still fixes that version, since the registrations it makes are spread through the handler. A connection that subscribed one stream at `api_version` 2 and another at 1, in two calls, was previously served both at version 1, the later call's, so the first stream's shape changed under it. The version is fixed for the connection's life: a client that wants another version opens another connection. On the webhook path the subscriber is keyed on its `url` alone, so the refusal reaches a second admin because of a first admin's version, and the message names the version the url's subscriptions are served at, and no remedy: releasing a url means unsubscribing its streams, which would remove that first admin's subscription, and the server cannot tell the two callers apart. Naming the url alone does not release it, a subscriber a stream map still holds not being evicted. This reaches every API version, since version 1 and version 2 content is not interchangeable either: version 2 renames `transaction` to `tx_json` and hoists `hash`, so a version 1 client handed version 2 content finds no `transaction` member.
|
||||
- `batch`: An entry of a `"method": "batch"` request that names `api_version` both inside `params` and at its own top level is now served at the version inside `params`. It was previously served at the top-level version whenever the one inside `params` resolved to version 1, so an entry asking for version 1 explicitly and something else at the top level changes which version answers it. A lone request can name both values too, and for it the version inside `params` has always won; reversing that precedence was confined to a batch entry.
|
||||
- `batch`: every entry of one batch request is now served at the same API version. An entry may name the version the body names, or name none and inherit it, and a body whose entries name two different versions is refused whole with `Batch entries name different versions` at HTTP 400, charged as a malformed request. **This is visible to a version 1 or 2 client:** a `"method": "batch"` body could mix versions across its entries, each entry being dispatched at its own, and the difference is observable because the reply shape changes with the version. Three bodies change. One whose entries name two different versions is now refused instead of answered. One where some entries name a version and others name none now serves all of them at the named version, where an entry naming none was served at version 1; the same applies to a version named on the request's own top level, which the entries now inherit. One whose top level names a version and whose entries name a different one is now refused, where the top-level value was ignored and each entry was served at the version it named. A body whose top level names no version or the same version as its entries, and whose entries agree with one another or name none at all, is unaffected. A `"method": "batch"` body naming at its own top level a version the server does not serve is refused with `invalid_API_version` at HTTP 400, where it was previously served at version 1 as if it had named none. No test pinned the mixing behavior and the line that produced it was a fallback about where the field sits rather than a decision that entries may differ, so this is a correction rather than a removal of a feature: a per-entry version made the entry cap above unanswerable, since a cap can only ask about a body that has one version.
|
||||
|
||||
### Additions
|
||||
|
||||
- A JSON-RPC (HTTP) request may send its parameters as an object, `"params": {"account": "r..."}`, as well as the array of one object that was already accepted. This reaches every API version: such a request was previously rejected with HTTP 400 and `params unparsable`, and is now served. A request that already sends the array form is unaffected. An entry of a `"method": "batch"` request that carries a by-name `params` object is read for `api_version` and credentials from that object. Previously such an entry had its `api_version` read from its top level and its credentials ignored, since credentials were read only from an array-form `params`.
|
||||
- A JSON-RPC (HTTP) request may name its `api_version` at its own top level, beside `method` and `id`, as well as inside `params`. The member is an XRPL extension, which the JSON-RPC 2.0 specification does not define; placing it beside the specification's own members is what lets a version 3 client send a specification-shaped request. This is honored from API version 3 up, so it needs `[beta_rpc_api]`; a version below that named at the top level is ignored, exactly as it always has been. Previously only an entry of a `"method": "batch"` request had its own top level read; a WebSocket request, which is one flat object, has always been read there.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- A request echoed back in an error reply now has every credential-bearing field masked: `admin_password`, `admin_user`, `passphrase`, `password`, `secret`, `seed`, `seed_hex`, `url_password`, `url_username` and `username`. Nesting no longer matters, so a credential inside `params` is masked too. The same masking is applied to every request and reply written to the log, and it covers six further names that only a reply carries: `master_key`, `master_seed`, `master_seed_hex`, `validation_key`, `validation_private_key` and `validation_seed`, which is how `wallet_propose` and `validation_create` used to write a live private key to the log. A request or reply written to the log is truncated at 10,000 characters. An `[rpc_startup]` line that does not parse is reported by its position in the section and the parser's message, never by its text, and no command runs for it.
|
||||
- The command line client no longer prints a credential the operator did not type. A failing command echoes the request it built under `request_sent`, which carries the `admin_password` the client copies out of `[port_rpc]` in the config, so `./xrpld account_info rBogus` printed that password to stdout and into any captured output. `request_sent` is now masked. The `rpc` member beside it, which echoes the arguments as they were typed, is unchanged. The command line client also no longer writes an unparsed `json` or `ripple_path_find` argument to its trace log before parsing it, where a `secret` inside that argument could not be masked; it logs the parsed request instead, masked. The reply it receives is logged the same way, parsed and masked, where the raw body was written before, a `validation_create` answer included.
|
||||
- A WebSocket frame that does not parse, or exceeds the request size limit, is answered `{"type": "error", "error": "jsonInvalid", "size": <bytes>}`. The frame's body is reported by size rather than echoed back in a `value` member, since a body that does not parse has no fields to mask. A client that read `value` gets `size` instead.
|
||||
- Four error codes that named no HTTP status of their own, and so answered 200 on a reply reporting an error, now name one: `actMalformed`, `alreadyMultisig` and `alreadySingleSig` answer 400, and `actNotFound` answers 404. **Only API version 3 reports these four.** A request sending `ripplerpc: "3.0"` at API version 1 or 2 still receives 200 for all four, as it always has, so `account_info` on a malformed account or one the ledger does not hold answers 200 for those clients exactly as before.
|
||||
- `submit`, `simulate`, `transaction_entry`, `ledger_entry` and `ledger_accept`: Errors from these methods now include `error_code` and `error_message` alongside the `error` token, as every other method already did. Each error now answers the status its code names: 400 for a malformed request, 404 for `transactionNotFound`, 500 for an internal failure, and 501 for `notYetImplemented` and `notStandAlone`. That status change reaches only a request sending `ripplerpc: "3.0"`, or API version 3, which are the envelopes that derive the status from the error. With `ripplerpc` `"1.0"` the status stays 200 and the two new members appear beside `error`; with `"2.0"` the status stays 200, `error_code` appears, and the `code` and `message` members carry the code and the message rather than null, since that envelope copies them from `error_code` and `error_message` and drops `error_message`. From API version 3 the twenty-one `malformed*` tokens `ledger_entry` names each report the code they own instead of 31.
|
||||
- A reply reporting HTTP 402 or 502 now carries a status line. Those two statuses named no case in the switch that writes one, so such a reply began with a header instead and did not parse as an HTTP response at all. Both are reachable at any API version with `ripplerpc: "3.0"`, which derives the status from the error code: 402 through `highFee` from `sign`, `sign_for` or `submit` with a low `fee_mult_max`, and 502 through `dbDeserialization` from `tx`. The eleven statuses that already named a case report the same phrase they always have.
|
||||
- An error reply to a request sending `ripplerpc: "2.0"` or `"3.0"` no longer carries a stray `"error_message": null` beside the error it reports. The member appeared only when the `Server` log partition was set to debug or lower, because the log statement read `error_message` after the reply had renamed it to `message`, and reading it put it back as null. So the reply a client received depended on the server's log level, and the log line itself printed an empty message. Both are fixed.
|
||||
- A body the server rejects before it reads a request out of it now says what was wrong. A body over the size limit answers `Request is too large`, and a body that parses to `{}` or `null` answers `Request is empty`; both previously answered `Unable to parse request: ` with nothing after the colon, the parser having recorded no error for them. Any other body that is not an array does not parse, which includes one that is only whitespace and one whose top-level value is a string, number or boolean; it answers `Unable to parse request: ` followed by the parser's own reason, as it did before. The status is 400 for all three, as before, and this reaches every API version. A top-level array, the one other body nothing can read a request from, is answered with a JSON error object instead, which the entry on top-level arrays below describes.
|
||||
- `batch`: An entry that is not identified through a secure gateway no longer clears the connection's `X-User` and forwarded-for values for the entries after it, so every entry of one body reports the role and username it would have reported on its own.
|
||||
- `batch`: Every entry of a `"method": "batch"` request is now charged against the sender's resource allowance, including one rejected before it reaches a handler, and the request stops at the first entry the connection is too loaded to serve. A reply array can therefore be shorter than the request array, and its last element depends on where the batch stopped. An entry that is not a JSON object, or names an API version the server does not serve, is charged before its role is known and answered with its own rejection; if that charge took the connection over the drop threshold, the batch stops there and that rejection is the last answer. Every other entry met over the threshold is answered `Server is overloaded` and nothing follows. A client should read any reply array shorter than its request as a connection over the drop threshold, whatever the last element says. A well-behaved client is unaffected; one that sends thousands of entries in a single body no longer gets every one of them answered.
|
||||
- A body the server rejects before it reads a request out of it is now charged against the sender's resource allowance, as a malformed request already was. Ten conditions were free: a body over the size limit, one that does not parse, one carrying no document, one that is neither a JSON object nor an array, a `"method": "batch"` naming no entry array, and six ways a top-level array is not a batch this server can serve. The answer to the first five is unchanged; an array's answer changes as the entry on top-level arrays below describes, the one generic rejection it received having become six. A well-behaved client is unaffected; one that repeats such a body exhausts its allowance and is refused the next request a handler would have served. A WebSocket frame that does not parse, or exceeds the request size limit, is charged the same way, and a connection that sends only such frames is closed once it crosses the drop threshold.
|
||||
- `subscribe`, `path_find`: A subscription is now served at the API version its own `subscribe` call named, rather than at the version of the most recent `subscribe` or `path_find` on the same connection. A `path_find` no longer changes the version anything that connection has subscribed is served at. An ordinary request is unaffected: it names its own version and is answered at it, so a connection subscribed at `api_version` 3 still calls `account_info` at version 1 and reads the version 1 shape.
|
||||
- `batch`: A batch request served at API version 3 or above is now refused when it holds more than 100 entries, before any entry is dispatched. The cap reads the one version the body is served at, so no ordering of the entries evades it. A body served below version 3 is unaffected and stays bounded only by the request size limit.
|
||||
- A top-level JSON array, which is the JSON-RPC 2.0 batch form accepted from API version 3, is now rejected with a JSON-RPC error object rather than a plain text body when it cannot be served: when it is empty, holds more than 100 entries, holds nothing that could be a request, names no API version of 3 or above that the server serves, or names two different versions the server serves. An array naming no served version of 3 or above is refused for requiring version 3, or, where every version it names is one the server does not serve, with `invalid_API_version`. One entry naming a version the server does not serve does not reject an array in which another entry names a served version: it is answered on its own, inside the reply array, with the same `-32606` code. This reaches every API version, since no earlier version accepts an array at all: a client that sent one received HTTP 400 with `Unable to parse request: ` and now receives the same status with a JSON body. The message also names the version rather than the shape where the version is what is wrong, which is what a client with `[beta_rpc_api]` disabled receives.
|
||||
|
||||
## XRP Ledger server version 3.5.0
|
||||
|
||||
Version 3.5.0 is not yet released.
|
||||
|
||||
Generated
+10
-10
@@ -57,9 +57,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.202"
|
||||
version = "1.0.205"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13f6de320895f42e6e081abb5c7983bedcf0b6d0ff9323de0d33f620c8ac1199"
|
||||
checksum = "c8a02bfeba9074b2bbb39492c9b0908ec854f455a3cccdcde7a1de55e2315e40"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxx-build",
|
||||
@@ -72,9 +72,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxx-build"
|
||||
version = "1.0.202"
|
||||
version = "1.0.205"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fde53ca86b9704a943fef0f1e1d836239a6aedca5de3c65fa9f97ec0bd46d39"
|
||||
checksum = "bbc2ac76997619d2d888b58ad79488f1c835de41ca4dd3dd7082acf4ecb0a50f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"codespan-reporting",
|
||||
@@ -87,9 +87,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-cmd"
|
||||
version = "1.0.202"
|
||||
version = "1.0.205"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bae89236c811fd4d08ed3441759ac4ac98d752cbfd3de341315ba16ad20ec3"
|
||||
checksum = "54a486ed16a3f2a053fe7f5b98db4c1a59846a23e8cb9e49f9d1bd48830d51a2"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"codespan-reporting",
|
||||
@@ -101,15 +101,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.202"
|
||||
version = "1.0.205"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49045042e5fced01b80742aba5508de82aa4f13677ed3fa2b4cda709c40c5918"
|
||||
checksum = "c72569be94e2283764d334cd285980b747dbe221e27e315484eb6bcd93fa808a"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.202"
|
||||
version = "1.0.205"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b181252e2e3d3b5d183afbdc033a3958b445eb3e1a0ae65fc3d4f5259f5da6fd"
|
||||
checksum = "423e795284a7f7b3f843c956a5322c4bc497b60c2dd1a6339da10313cb18d575"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"proc-macro2",
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
/**
|
||||
* RAII class to check if an Item is already being processed on another thread,
|
||||
* as indicated by it's presence in a Collection.
|
||||
*
|
||||
* If the Item is not in the Collection, it will be added under lock in the
|
||||
* ctor, and removed under lock in the dtor. The object will be considered
|
||||
* "usable" and evaluate to `true`.
|
||||
*
|
||||
* If the Item is in the Collection, no changes will be made to the collection,
|
||||
* and the CanProcess object will be considered "unusable".
|
||||
*
|
||||
* It's up to the caller to decide what "usable" and "unusable" mean. (e.g.
|
||||
* Process or skip a block of code, or set a flag.)
|
||||
*
|
||||
* The current use is to avoid lock contention that would be involved in
|
||||
* processing something associated with the Item.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* void IncomingLedgers::acquireAsync(LedgerHash const& hash, ...)
|
||||
* {
|
||||
* if (CanProcess check{acquiresMutex_, pendingAcquires_, hash})
|
||||
* {
|
||||
* acquire(hash, ...);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* bool
|
||||
* NetworkOPsImp::recvValidation(
|
||||
* std::shared_ptr<STValidation> const& val,
|
||||
* std::string const& source)
|
||||
* {
|
||||
* CanProcess check(
|
||||
* validationsMutex_, pendingValidations_, val->getLedgerHash());
|
||||
* BypassAccept bypassAccept =
|
||||
* check ? BypassAccept::no : BypassAccept::yes;
|
||||
* handleNewValidation(app_, val, source, bypassAccept, m_journal);
|
||||
* }
|
||||
*
|
||||
*/
|
||||
class CanProcess
|
||||
{
|
||||
public:
|
||||
template <class Mutex, class Collection, class Item>
|
||||
CanProcess(Mutex& mtx, Collection& collection, Item const& item)
|
||||
: cleanup_(insert(mtx, collection, item))
|
||||
{
|
||||
}
|
||||
|
||||
~CanProcess()
|
||||
{
|
||||
if (cleanup_)
|
||||
cleanup_();
|
||||
}
|
||||
|
||||
CanProcess(CanProcess const&) = delete;
|
||||
|
||||
CanProcess&
|
||||
operator=(CanProcess const&) = delete;
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return static_cast<bool>(cleanup_);
|
||||
}
|
||||
|
||||
private:
|
||||
template <bool useIterator, class Mutex, class Collection, class Item>
|
||||
std::function<void()>
|
||||
doInsert(Mutex& mtx, Collection& collection, Item const& item)
|
||||
{
|
||||
std::unique_lock<Mutex> lock(mtx);
|
||||
// TODO: Use structured binding once LLVM 16 is the minimum supported
|
||||
// version. See also: https://github.com/llvm/llvm-project/issues/48582
|
||||
// https://github.com/llvm/llvm-project/commit/127bf44385424891eb04cff8e52d3f157fc2cb7c
|
||||
auto const insertResult = collection.insert(item);
|
||||
auto const it = insertResult.first;
|
||||
if (!insertResult.second)
|
||||
return {};
|
||||
if constexpr (useIterator)
|
||||
return [&, it]() {
|
||||
std::unique_lock<Mutex> lock(mtx);
|
||||
collection.erase(it);
|
||||
};
|
||||
else
|
||||
return [&]() {
|
||||
std::unique_lock<Mutex> lock(mtx);
|
||||
collection.erase(item);
|
||||
};
|
||||
}
|
||||
|
||||
// Generic insert() function doesn't use iterators because they may get
|
||||
// invalidated
|
||||
template <class Mutex, class Collection, class Item>
|
||||
std::function<void()>
|
||||
insert(Mutex& mtx, Collection& collection, Item const& item)
|
||||
{
|
||||
return doInsert<false>(mtx, collection, item);
|
||||
}
|
||||
|
||||
// Specialize insert() for std::set, which does not invalidate iterators for
|
||||
// insert and erase
|
||||
template <class Mutex, class Item>
|
||||
std::function<void()>
|
||||
insert(Mutex& mtx, std::set<Item>& collection, Item const& item)
|
||||
{
|
||||
return doInsert<true>(mtx, collection, item);
|
||||
}
|
||||
|
||||
// If set, then the item is "usable"
|
||||
std::function<void()> cleanup_;
|
||||
};
|
||||
@@ -34,7 +34,7 @@ lz4Compress(void const* in, std::size_t inSize, BufferFactory&& bf)
|
||||
// data
|
||||
auto compressed = bf(outCapacity);
|
||||
|
||||
auto compressedSize = LZ4_compress_default(
|
||||
auto const compressedSize = LZ4_compress_default(
|
||||
reinterpret_cast<char const*>(in),
|
||||
reinterpret_cast<char*>(compressed),
|
||||
inSize,
|
||||
|
||||
@@ -20,12 +20,14 @@ SharedIntrusive<T>::SharedIntrusive(T* p, TAdoptTag) noexcept : ptr_{p}
|
||||
|
||||
template <class T>
|
||||
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive const& rhs)
|
||||
: ptr_{[&] {
|
||||
auto p = rhs.unsafeGetRawPtr();
|
||||
if (p)
|
||||
p->addStrongRef();
|
||||
return p;
|
||||
}()}
|
||||
: ptr_{
|
||||
[&] {
|
||||
auto p = rhs.unsafeGetRawPtr();
|
||||
if (p)
|
||||
p->addStrongRef();
|
||||
return p;
|
||||
}(),
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -33,12 +35,14 @@ template <class T>
|
||||
template <class TT>
|
||||
requires std::convertible_to<TT*, T*>
|
||||
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive<TT> const& rhs)
|
||||
: ptr_{[&] {
|
||||
auto p = rhs.unsafeGetRawPtr();
|
||||
if (p)
|
||||
p->addStrongRef();
|
||||
return p;
|
||||
}()}
|
||||
: ptr_{
|
||||
[&] {
|
||||
auto p = rhs.unsafeGetRawPtr();
|
||||
if (p)
|
||||
p->addStrongRef();
|
||||
return p;
|
||||
}(),
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -140,12 +144,14 @@ SharedIntrusive<T>::~SharedIntrusive()
|
||||
template <class T>
|
||||
template <class TT>
|
||||
SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs)
|
||||
: ptr_{[&] {
|
||||
auto p = static_cast<T*>(rhs.unsafeGetRawPtr());
|
||||
if (p)
|
||||
p->addStrongRef();
|
||||
return p;
|
||||
}()}
|
||||
: ptr_{
|
||||
[&] {
|
||||
auto p = static_cast<T*>(rhs.unsafeGetRawPtr());
|
||||
if (p)
|
||||
p->addStrongRef();
|
||||
return p;
|
||||
}(),
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -159,12 +165,14 @@ SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusiv
|
||||
template <class T>
|
||||
template <class TT>
|
||||
SharedIntrusive<T>::SharedIntrusive(DynamicCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs)
|
||||
: ptr_{[&] {
|
||||
auto p = dynamic_cast<T*>(rhs.unsafeGetRawPtr());
|
||||
if (p)
|
||||
p->addStrongRef();
|
||||
return p;
|
||||
}()}
|
||||
: ptr_{
|
||||
[&] {
|
||||
auto p = dynamic_cast<T*>(rhs.unsafeGetRawPtr());
|
||||
if (p)
|
||||
p->addStrongRef();
|
||||
return p;
|
||||
}(),
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -260,7 +268,7 @@ SharedIntrusive<T>::unsafeReleaseAndStore(T* next)
|
||||
return;
|
||||
|
||||
using enum ReleaseStrongRefAction;
|
||||
auto action = prev->releaseStrongRef();
|
||||
auto const action = prev->releaseStrongRef();
|
||||
switch (action)
|
||||
{
|
||||
case NoOp:
|
||||
@@ -361,7 +369,7 @@ WeakIntrusive<T>::unsafeReleaseNoStore()
|
||||
return;
|
||||
|
||||
using enum ReleaseWeakRefAction;
|
||||
auto action = ptr_->releaseWeakRef();
|
||||
auto const action = ptr_->releaseWeakRef();
|
||||
switch (action)
|
||||
{
|
||||
case NoOp:
|
||||
@@ -580,7 +588,7 @@ SharedWeakUnion<T>::convertToStrong()
|
||||
auto p = unsafeGetRawPtr();
|
||||
if (p && p->checkoutStrongRefFromWeak())
|
||||
{
|
||||
[[maybe_unused]] auto action = p->releaseWeakRef();
|
||||
[[maybe_unused]] auto const action = p->releaseWeakRef();
|
||||
XRPL_ASSERT(
|
||||
(action == ReleaseWeakRefAction::NoOp),
|
||||
"xrpl::SharedWeakUnion::convertToStrong : "
|
||||
@@ -603,7 +611,7 @@ SharedWeakUnion<T>::convertToWeak()
|
||||
return false;
|
||||
|
||||
using enum ReleaseStrongRefAction;
|
||||
auto action = p->addWeakReleaseStrongRef();
|
||||
auto const action = p->addWeakReleaseStrongRef();
|
||||
switch (action)
|
||||
{
|
||||
case NoOp:
|
||||
@@ -670,7 +678,7 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
|
||||
if (isStrong())
|
||||
{
|
||||
using enum ReleaseStrongRefAction;
|
||||
auto strongAction = p->releaseStrongRef();
|
||||
auto const strongAction = p->releaseStrongRef();
|
||||
switch (strongAction)
|
||||
{
|
||||
case NoOp:
|
||||
@@ -688,7 +696,7 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
|
||||
else
|
||||
{
|
||||
using enum ReleaseWeakRefAction;
|
||||
auto weakAction = p->releaseWeakRef();
|
||||
auto const weakAction = p->releaseWeakRef();
|
||||
switch (weakAction)
|
||||
{
|
||||
case NoOp:
|
||||
|
||||
@@ -406,10 +406,10 @@ IntrusiveRefCounts::useCount() const noexcept
|
||||
inline IntrusiveRefCounts::~IntrusiveRefCounts() noexcept
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
auto v = refCounts_.load(std::memory_order_acquire);
|
||||
auto const v = refCounts_.load(std::memory_order_acquire);
|
||||
XRPL_ASSERT(
|
||||
(!(v & kValueMask)), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero");
|
||||
auto t = v & kTagMask;
|
||||
auto const t = v & kTagMask;
|
||||
XRPL_ASSERT((!t || t == kTagMask), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -340,7 +340,7 @@ public:
|
||||
|
||||
for (auto const& c : cfg)
|
||||
{
|
||||
auto& a = allocators_.emplace_back(c.extra_, c.alloc_, c.align_);
|
||||
auto const& a = allocators_.emplace_back(c.extra_, c.alloc_, c.align_);
|
||||
|
||||
if (a.size() > maxSize_)
|
||||
maxSize_ = a.size();
|
||||
|
||||
@@ -300,7 +300,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
// Remove from cache, if !valid, remove from map too. Returns true if removed from cache
|
||||
std::scoped_lock const lock(mutex_);
|
||||
|
||||
auto cit = cache_.find(key);
|
||||
auto const cit = cache_.find(key);
|
||||
|
||||
if (cit == cache_.end())
|
||||
return false;
|
||||
@@ -356,7 +356,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
|
||||
std::scoped_lock const lock(mutex_);
|
||||
|
||||
auto cit = cache_.find(key);
|
||||
auto const cit = cache_.find(key);
|
||||
|
||||
if (cit == cache_.end())
|
||||
{
|
||||
@@ -371,7 +371,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
Entry& entry = cit->second;
|
||||
entry.touch(clock_.now());
|
||||
|
||||
auto shouldReplaceCached = [&] {
|
||||
auto const shouldReplaceCached = [&] {
|
||||
if constexpr (replaceCached)
|
||||
{
|
||||
return true;
|
||||
@@ -400,7 +400,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
return true;
|
||||
}
|
||||
|
||||
auto cachedData = entry.lock();
|
||||
auto const cachedData = entry.lock();
|
||||
|
||||
if (cachedData)
|
||||
{
|
||||
@@ -563,7 +563,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
retrieve(key_type const& key, T& data)
|
||||
{
|
||||
// retrieve the value of the stored data
|
||||
auto entry = fetch(key);
|
||||
auto const entry = fetch(key);
|
||||
|
||||
if (!entry)
|
||||
return false;
|
||||
@@ -687,7 +687,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto sle = h();
|
||||
auto const sle = h();
|
||||
if (!sle)
|
||||
return {};
|
||||
|
||||
@@ -713,7 +713,7 @@ inline SharedPointerType
|
||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||
initialFetch(key_type const& key, std::scoped_lock<MutexType> const& l)
|
||||
{
|
||||
auto cit = cache_.find(key);
|
||||
auto const cit = cache_.find(key);
|
||||
if (cit == cache_.end())
|
||||
return {};
|
||||
|
||||
|
||||
@@ -195,7 +195,8 @@ private:
|
||||
{
|
||||
// Local lambda that converts a single hex char to four bits and
|
||||
// ORs those bits into a uint32_t.
|
||||
auto hexCharToUInt = [](char c, std::uint32_t shift, std::uint32_t& accum) -> ParseResult {
|
||||
auto const hexCharToUInt =
|
||||
[](char c, std::uint32_t shift, std::uint32_t& accum) -> ParseResult {
|
||||
std::uint32_t nibble = 0xFFu;
|
||||
if (c < '0' || c > 'f')
|
||||
return ParseResult::BadChar;
|
||||
@@ -453,7 +454,7 @@ public:
|
||||
{
|
||||
for (int i = kWidth - 1; i >= 0; --i)
|
||||
{
|
||||
auto prev = data_[i];
|
||||
auto const prev = data_[i];
|
||||
data_[i] = boost::endian::native_to_big(boost::endian::big_to_native(data_[i]) - 1);
|
||||
|
||||
if (prev != 0)
|
||||
|
||||
@@ -365,7 +365,7 @@ public:
|
||||
size() const
|
||||
{
|
||||
std::size_t ret = 0;
|
||||
for (auto& p : map_)
|
||||
for (auto const& p : map_)
|
||||
ret += p.size();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2536,7 +2536,7 @@ AgedUnorderedContainer<IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>
|
||||
return false;
|
||||
for (auto iter(cbegin()), last(cend()), otherLast(other.cend()); iter != last; ++iter)
|
||||
{
|
||||
auto otherIter(other.find(extract(*iter)));
|
||||
auto const otherIter(other.find(extract(*iter)));
|
||||
if (otherIter == otherLast)
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ struct LexicalCast<Out, std::string_view>
|
||||
if (first != last && *first == '+')
|
||||
++first;
|
||||
|
||||
auto ret = std::from_chars(first, last, out);
|
||||
auto const ret = std::from_chars(first, last, out);
|
||||
|
||||
return ret.ec == std::errc() && ret.ptr == last;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ trimRight(String const& s)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
auto first(begin(s));
|
||||
auto const first(begin(s));
|
||||
auto last(end(s));
|
||||
last = trimRight(first, last);
|
||||
return {first, last};
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
Module,
|
||||
|
||||
// Match nothing (used internally)
|
||||
None
|
||||
None,
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
@@ -24,7 +24,7 @@ enum class Severity : std::uint8_t {
|
||||
Fatal = 5,
|
||||
|
||||
Disabled = 6,
|
||||
None = Disabled
|
||||
None = Disabled,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ enum class Type : std::uint8_t {
|
||||
PrefixSha256 = 1,
|
||||
ThresholdSha256 = 2,
|
||||
RsaSha256 = 3,
|
||||
Ed25519Sha256 = 4
|
||||
Ed25519Sha256 = 4,
|
||||
};
|
||||
|
||||
class Condition
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
|
||||
using namespace der;
|
||||
|
||||
auto p = parsePreamble(s, ec);
|
||||
auto const p = parsePreamble(s, ec);
|
||||
if (ec)
|
||||
return nullptr;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ enum class Error {
|
||||
UnexpectedTag,
|
||||
LongTag,
|
||||
LargeSize,
|
||||
PreimageTooLong
|
||||
PreimageTooLong,
|
||||
};
|
||||
|
||||
std::error_code
|
||||
|
||||
@@ -396,7 +396,7 @@ inline bool
|
||||
getIfExists<bool>(Section const& section, std::string const& name, bool& v)
|
||||
{
|
||||
int intVal = 0;
|
||||
auto stat = getIfExists(section, name, intVal);
|
||||
auto const stat = getIfExists(section, name, intVal);
|
||||
if (stat)
|
||||
v = bool(intVal);
|
||||
return stat;
|
||||
|
||||
@@ -93,14 +93,14 @@ public:
|
||||
void
|
||||
check(std::vector<TxID> accepted, Predicate&& pred)
|
||||
{
|
||||
auto acceptTxid = accepted.begin();
|
||||
auto const acceptTxid = accepted.begin();
|
||||
auto const ae = accepted.end();
|
||||
std::sort(acceptTxid, ae);
|
||||
|
||||
// We want to remove all tracking entries for transactions that were
|
||||
// accepted as well as those which match the predicate.
|
||||
|
||||
auto i = removeIfIntersectOrMatch(
|
||||
auto const i = removeIfIntersectOrMatch(
|
||||
tracker_.begin(),
|
||||
tracker_.end(),
|
||||
accepted.begin(),
|
||||
|
||||
@@ -779,7 +779,7 @@ Consensus<Adaptor>::peerProposalInternal(
|
||||
|
||||
{
|
||||
// update current position
|
||||
auto peerPosIt = currPeerPositions_.find(peerID);
|
||||
auto const peerPosIt = currPeerPositions_.find(peerID);
|
||||
|
||||
if (peerPosIt != currPeerPositions_.end())
|
||||
{
|
||||
@@ -1110,7 +1110,7 @@ Consensus<Adaptor>::checkLedger(std::unique_ptr<std::stringstream> const& clog)
|
||||
{
|
||||
CLOG(clog) << "checkLedger. ";
|
||||
|
||||
auto netLgr = adaptor_.getPrevLedger(prevLedgerID_, previousLedger_, mode_.get());
|
||||
auto const netLgr = adaptor_.getPrevLedger(prevLedgerID_, previousLedger_, mode_.get());
|
||||
CLOG(clog) << "network ledgerid " << netLgr << ", "
|
||||
<< "previous ledger " << prevLedgerID_ << ". ";
|
||||
|
||||
@@ -1159,8 +1159,8 @@ Consensus<Adaptor>::phaseOpen(std::unique_ptr<std::stringstream> const& clog)
|
||||
|
||||
// it is shortly before ledger close time
|
||||
bool const anyTransactions = adaptor_.hasOpenTransactions();
|
||||
auto proposersClosed = currPeerPositions_.size();
|
||||
auto proposersValidated = adaptor_.proposersValidated(prevLedgerID_);
|
||||
auto const proposersClosed = currPeerPositions_.size();
|
||||
auto const proposersValidated = adaptor_.proposersValidated(prevLedgerID_);
|
||||
|
||||
openTime_.tick(clock_.now());
|
||||
|
||||
@@ -1669,7 +1669,7 @@ Consensus<Adaptor>::haveConsensus(std::unique_ptr<std::stringstream> const& clog
|
||||
// CHECKME: should possibly count unacquired TX sets as disagreeing
|
||||
int agree = 0, disagree = 0;
|
||||
|
||||
auto ourPosition = result_->position.position();
|
||||
auto const ourPosition = result_->position.position();
|
||||
|
||||
// Count number of agreements/disagreements with our position
|
||||
for (auto const& [nodeId, peerPos] : currPeerPositions_)
|
||||
@@ -1686,7 +1686,7 @@ Consensus<Adaptor>::haveConsensus(std::unique_ptr<std::stringstream> const& clog
|
||||
++disagree;
|
||||
}
|
||||
}
|
||||
auto currentFinished = adaptor_.proposersFinished(previousLedger_, prevLedgerID_);
|
||||
auto const currentFinished = adaptor_.proposersFinished(previousLedger_, prevLedgerID_);
|
||||
|
||||
JLOG(j_.debug()) << "Checking for TX consensus: agree=" << agree << ", disagree=" << disagree;
|
||||
|
||||
@@ -1812,7 +1812,7 @@ Consensus<Adaptor>::createDisputes(TxSetT const& o, std::unique_ptr<std::strings
|
||||
<< ". ";
|
||||
JLOG(j_.debug()) << "createDisputes " << result_->txns.id() << " to " << o.id();
|
||||
|
||||
auto differences = result_->txns.compare(o);
|
||||
auto const differences = result_->txns.compare(o);
|
||||
|
||||
int dc = 0;
|
||||
|
||||
@@ -1826,7 +1826,7 @@ Consensus<Adaptor>::createDisputes(TxSetT const& o, std::unique_ptr<std::strings
|
||||
"xrpl::Consensus::createDisputes : has disputed transactions");
|
||||
|
||||
TxT const tx = inThisSet ? result_->txns.find(txId) : o.find(txId);
|
||||
auto txID = tx.id();
|
||||
auto const txID = tx.id();
|
||||
|
||||
if (result_->disputes.find(txID) != result_->disputes.end())
|
||||
continue;
|
||||
@@ -1837,7 +1837,8 @@ Consensus<Adaptor>::createDisputes(TxSetT const& o, std::unique_ptr<std::strings
|
||||
tx,
|
||||
result_->txns.exists(txID),
|
||||
std::max(prevProposers_, currPeerPositions_.size()),
|
||||
j_};
|
||||
j_,
|
||||
};
|
||||
|
||||
// Update all of the available peer's votes on the disputed transaction
|
||||
for (auto const& [nodeId, peerPos] : currPeerPositions_)
|
||||
|
||||
@@ -145,18 +145,26 @@ struct ConsensusParms
|
||||
std::map<AvalancheState, AvalancheCutoff> const avalancheCutoffs{
|
||||
// {state, {time, percent, nextState}},
|
||||
// Initial state: 50% of nodes must vote yes
|
||||
{AvalancheState::Init,
|
||||
{.consensusTime = 0, .consensusPct = 50, .next = AvalancheState::Mid}},
|
||||
{
|
||||
AvalancheState::Init,
|
||||
{.consensusTime = 0, .consensusPct = 50, .next = AvalancheState::Mid},
|
||||
},
|
||||
// mid-consensus starts after 50% of the previous round time, and
|
||||
// requires 65% yes
|
||||
{AvalancheState::Mid,
|
||||
{.consensusTime = 50, .consensusPct = 65, .next = AvalancheState::Late}},
|
||||
{
|
||||
AvalancheState::Mid,
|
||||
{.consensusTime = 50, .consensusPct = 65, .next = AvalancheState::Late},
|
||||
},
|
||||
// late consensus starts after 85% time, and requires 70% yes
|
||||
{AvalancheState::Late,
|
||||
{.consensusTime = 85, .consensusPct = 70, .next = AvalancheState::Stuck}},
|
||||
{
|
||||
AvalancheState::Late,
|
||||
{.consensusTime = 85, .consensusPct = 70, .next = AvalancheState::Stuck},
|
||||
},
|
||||
// we're stuck after 2x time, requires 95% yes votes
|
||||
{AvalancheState::Stuck,
|
||||
{.consensusTime = 200, .consensusPct = 95, .next = AvalancheState::Stuck}},
|
||||
{
|
||||
AvalancheState::Stuck,
|
||||
{.consensusTime = 200, .consensusPct = 95, .next = AvalancheState::Stuck},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -59,7 +59,7 @@ enum class ConsensusMode {
|
||||
* if we entered the round observing, but is used to indicate we did
|
||||
* have the wrongLedger at some point.
|
||||
*/
|
||||
SwitchedLedger
|
||||
SwitchedLedger,
|
||||
};
|
||||
|
||||
inline std::string
|
||||
@@ -222,7 +222,7 @@ medianCloseOffset(ConsensusCloseTimes const& times)
|
||||
|
||||
// Accumulate weight in time order; the first bin to reach halfWeight is
|
||||
// the (lower) weighted median. Returns true once that bin is found.
|
||||
auto step = [&](time_point t, std::int64_t w) {
|
||||
auto const step = [&](time_point t, std::int64_t w) {
|
||||
XRPL_ASSERT(tally < halfWeight, "xrpl::medianCloseOffset::step : median not yet found");
|
||||
tally += w;
|
||||
if (tally >= halfWeight)
|
||||
@@ -267,7 +267,7 @@ enum class ConsensusState {
|
||||
No, ///< We do not have consensus
|
||||
MovedOn, ///< The network has consensus without us
|
||||
Expired, ///< Consensus time limit has hard-expired
|
||||
Yes ///< We have consensus along with the network
|
||||
Yes, ///< We have consensus along with the network
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -266,7 +266,7 @@ template <class Tx, class NodeId>
|
||||
void
|
||||
DisputedTx<Tx, NodeId>::unVote(NodeId const& peer)
|
||||
{
|
||||
auto it = votes_.find(peer);
|
||||
auto const it = votes_.find(peer);
|
||||
|
||||
if (it != votes_.end())
|
||||
{
|
||||
|
||||
@@ -211,7 +211,7 @@ struct Node
|
||||
void
|
||||
erase(Node const* child)
|
||||
{
|
||||
auto it = std::ranges::find_if(
|
||||
auto const it = std::ranges::find_if(
|
||||
children, [child](std::unique_ptr<Node> const& curr) { return curr.get() == child; });
|
||||
XRPL_ASSERT(it != children.end(), "xrpl::Node::erase : valid input");
|
||||
std::swap(*it, children.back());
|
||||
|
||||
@@ -184,7 +184,7 @@ enum class ValStatus {
|
||||
/**
|
||||
* Multiple validations by a validator for different ledgers
|
||||
*/
|
||||
Conflicting
|
||||
Conflicting,
|
||||
};
|
||||
|
||||
inline std::string
|
||||
@@ -366,7 +366,7 @@ private:
|
||||
removeTrie(std::scoped_lock<Mutex> const&, NodeID const& nodeID, Validation const& val)
|
||||
{
|
||||
{
|
||||
auto it = acquiring_.find(std::make_pair(val.seq(), val.ledgerID()));
|
||||
auto const it = acquiring_.find(std::make_pair(val.seq(), val.ledgerID()));
|
||||
if (it != acquiring_.end())
|
||||
{
|
||||
it->second.erase(nodeID);
|
||||
@@ -375,7 +375,7 @@ private:
|
||||
}
|
||||
}
|
||||
{
|
||||
auto it = lastLedger_.find(nodeID);
|
||||
auto const it = lastLedger_.find(nodeID);
|
||||
if (it != lastLedger_.end() && it->second.id() == val.ledgerID())
|
||||
{
|
||||
trie_.remove(it->second);
|
||||
@@ -443,7 +443,7 @@ private:
|
||||
// Clear any prior acquiring ledger for this node
|
||||
if (prior)
|
||||
{
|
||||
auto it = acquiring_.find(*prior);
|
||||
auto const it = acquiring_.find(*prior);
|
||||
if (it != acquiring_.end())
|
||||
{
|
||||
it->second.erase(nodeID);
|
||||
@@ -455,7 +455,7 @@ private:
|
||||
checkAcquired(lock);
|
||||
|
||||
std::pair<Seq, ID> const valPair{val.seq(), val.ledgerID()};
|
||||
auto it = acquiring_.find(valPair);
|
||||
auto const it = acquiring_.find(valPair);
|
||||
if (it != acquiring_.end())
|
||||
{
|
||||
it->second.insert(nodeID);
|
||||
@@ -529,7 +529,7 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
auto cit = typename decltype(current_)::const_iterator{it};
|
||||
auto const cit = typename decltype(current_)::const_iterator{it};
|
||||
// contains a live record
|
||||
f(cit->first, cit->second);
|
||||
++it;
|
||||
@@ -554,7 +554,7 @@ private:
|
||||
void
|
||||
byLedger(std::scoped_lock<Mutex> const&, ID const& ledgerID, Pre&& pre, F&& f)
|
||||
{
|
||||
auto it = byLedger_.find(ledgerID);
|
||||
auto const it = byLedger_.find(ledgerID);
|
||||
if (it != byLedger_.end())
|
||||
{
|
||||
// Update set time since it is being used
|
||||
@@ -857,7 +857,7 @@ public:
|
||||
if (!preferred)
|
||||
{
|
||||
// fall back to majority over acquiring ledgers
|
||||
auto it = std::ranges::max_element(acquiring_, [](auto const& a, auto const& b) {
|
||||
auto const it = std::ranges::max_element(acquiring_, [](auto const& a, auto const& b) {
|
||||
std::pair<Seq, ID> const& aKey = a.first;
|
||||
typename HashSet<NodeID>::size_type const& aSize = a.second.size();
|
||||
std::pair<Seq, ID> const& bKey = b.first;
|
||||
@@ -937,7 +937,7 @@ public:
|
||||
return (preferred->first >= minSeq) ? preferred->second : lcl.id();
|
||||
|
||||
// Otherwise, rely on peer ledgers
|
||||
auto it = std::ranges::max_element(peerCounts, [](auto const& a, auto const& b) {
|
||||
auto const it = std::ranges::max_element(peerCounts, [](auto const& a, auto const& b) {
|
||||
// Prefer larger counts, then larger ids on ties
|
||||
// (max_element expects this to return true if a < b)
|
||||
return std::tie(a.second, a.first) < std::tie(b.second, b.first);
|
||||
|
||||
@@ -156,7 +156,7 @@ public:
|
||||
{
|
||||
if (!allClosuresDoneCond_.wait_for(lock, wait, [this] { return closureCount_ == 0; }))
|
||||
{
|
||||
if (auto stream = j.error())
|
||||
if (auto const stream = j.error())
|
||||
stream << name << " waiting for ClosureCounter::join().";
|
||||
allClosuresDoneCond_.wait(lock, [this] { return closureCount_ == 0; });
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ enum class HashRouterFlags : std::uint16_t {
|
||||
PRIVATE6 = 0x2000,
|
||||
// Used in apply.cpp
|
||||
PRIVATE7 = 0x4000,
|
||||
PRIVATE8 = 0x8000
|
||||
PRIVATE8 = 0x8000,
|
||||
};
|
||||
|
||||
constexpr HashRouterFlags
|
||||
@@ -221,7 +221,7 @@ public:
|
||||
/**
|
||||
* Add a suppression peer and get message's relay status.
|
||||
* Return pair:
|
||||
* element 1: true if the key is added.
|
||||
* element 1: true if the peer is added.
|
||||
* element 2: optional is seated to the relay time point or
|
||||
* is unseated if has not relayed yet.
|
||||
*/
|
||||
|
||||
@@ -30,12 +30,12 @@ private:
|
||||
using namespace std::chrono_literals;
|
||||
int const maxLimit = std::numeric_limits<int>::max();
|
||||
|
||||
auto add = [this](
|
||||
JobType jt,
|
||||
std::string name,
|
||||
int limit,
|
||||
std::chrono::milliseconds avgLatency,
|
||||
std::chrono::milliseconds peakLatency) {
|
||||
auto const add = [this](
|
||||
JobType jt,
|
||||
std::string name,
|
||||
int limit,
|
||||
std::chrono::milliseconds avgLatency,
|
||||
std::chrono::milliseconds peakLatency) {
|
||||
XRPL_ASSERT(!map.contains(jt), "xrpl::JobTypes::JobTypes::add : unique job type input");
|
||||
|
||||
[[maybe_unused]] auto const inserted =
|
||||
|
||||
@@ -177,12 +177,13 @@ measureDurationAndLog(
|
||||
std::chrono::duration<Rep, Period> maxDelay,
|
||||
beast::Journal const& journal)
|
||||
{
|
||||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
auto const startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
auto result = func();
|
||||
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
|
||||
auto const endTime = std::chrono::high_resolution_clock::now();
|
||||
auto const duration =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
|
||||
if (duration > maxDelay)
|
||||
{
|
||||
JLOG(journal.warn()) << actionDescription << " took " << duration.count() << " ms";
|
||||
|
||||
@@ -95,7 +95,7 @@ private:
|
||||
ArraySeparator,
|
||||
MemberSeparator,
|
||||
Comment,
|
||||
Error
|
||||
Error,
|
||||
};
|
||||
|
||||
class Token
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
#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>
|
||||
|
||||
/**
|
||||
@@ -26,7 +28,7 @@ enum class ValueType {
|
||||
String, ///< UTF-8 string value
|
||||
Boolean, ///< bool value
|
||||
Array, ///< array value (ordered list)
|
||||
Object ///< object value (collection of name/value pairs).
|
||||
Object, ///< object value (collection of name/value pairs).
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -198,6 +200,15 @@ 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();
|
||||
@@ -472,6 +483,32 @@ 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&);
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ public:
|
||||
beast::Journal j)
|
||||
{
|
||||
// Ask implementation what to do
|
||||
auto actions = doVoting(
|
||||
auto const actions = doVoting(
|
||||
lastClosedLedger->rules(),
|
||||
lastClosedLedger->parentCloseTime(),
|
||||
getEnabledAmendments(*lastClosedLedger),
|
||||
|
||||
@@ -50,7 +50,7 @@ enum ApplyFlags : std::uint32_t {
|
||||
// afterward, so signature-presence checks (e.g. Batch signer matching)
|
||||
// are skipped at proposal-creation time (On-Chain Cosigner spec
|
||||
// §5.3.1.2).
|
||||
TapProposal = 0x2000
|
||||
TapProposal = 0x2000,
|
||||
};
|
||||
|
||||
constexpr ApplyFlags
|
||||
|
||||
@@ -20,7 +20,8 @@ constexpr std::chrono::seconds kLedgerPossibleTimeResolutions[] = {
|
||||
std::chrono::seconds{30},
|
||||
std::chrono::seconds{60},
|
||||
std::chrono::seconds{90},
|
||||
std::chrono::seconds{120}};
|
||||
std::chrono::seconds{120},
|
||||
};
|
||||
|
||||
/**
|
||||
* Initial resolution of ledger close time.
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
{
|
||||
std::scoped_lock const lock(mutex_);
|
||||
|
||||
auto it = map_.find(seq);
|
||||
auto const it = map_.find(seq);
|
||||
|
||||
if ((it == map_.end()) || it->second)
|
||||
{
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
do
|
||||
{
|
||||
auto it = map_.find(seq);
|
||||
auto const it = map_.find(seq);
|
||||
|
||||
if (it == map_.end())
|
||||
{
|
||||
|
||||
@@ -164,7 +164,7 @@ getCandidateLedger(LedgerIndex requested)
|
||||
areCompatible(
|
||||
ReadView const& validLedger,
|
||||
ReadView const& testLedger,
|
||||
beast::Journal::Stream& s,
|
||||
beast::Journal::Stream const& s,
|
||||
char const* reason);
|
||||
|
||||
[[nodiscard]] bool
|
||||
@@ -172,7 +172,7 @@ areCompatible(
|
||||
UInt256 const& validHash,
|
||||
LedgerIndex validIndex,
|
||||
ReadView const& testLedger,
|
||||
beast::Journal::Stream& s,
|
||||
beast::Journal::Stream const& s,
|
||||
char const* reason);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -185,7 +185,7 @@ areCompatible(
|
||||
dirLink(
|
||||
ApplyView& view,
|
||||
AccountID const& owner,
|
||||
SLE::pointer& object,
|
||||
SLE::pointer const& object,
|
||||
SF_UINT64 const& node = sfOwnerNode);
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,13 +30,17 @@ public:
|
||||
static constexpr size_t kInitialBufferSize = kilobytes(256);
|
||||
|
||||
RawStateTable()
|
||||
: monotonicResource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
|
||||
kInitialBufferSize)}
|
||||
: monotonicResource_{
|
||||
std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
|
||||
kInitialBufferSize),
|
||||
}
|
||||
, items_{monotonicResource_.get()} {};
|
||||
|
||||
RawStateTable(RawStateTable const& rhs)
|
||||
: monotonicResource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
|
||||
kInitialBufferSize)}
|
||||
: monotonicResource_{
|
||||
std::make_unique<boost::container::pmr::monotonic_buffer_resource>(
|
||||
kInitialBufferSize),
|
||||
}
|
||||
, items_{rhs.items_, monotonicResource_.get()}
|
||||
, dropsDestroyed_{rhs.dropsDestroyed_} {};
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ getAMMOfferStartWithTakerGets(
|
||||
if (nTakerGetsConstraint < *nTakerGets)
|
||||
nTakerGets = nTakerGetsConstraint;
|
||||
|
||||
auto getAmounts = [&pool, &tfee](Number const& nTakerGetsProposed) {
|
||||
auto const getAmounts = [&pool, &tfee](Number const& nTakerGetsProposed) {
|
||||
// Round downward to minimize the offer and to maximize the quality.
|
||||
// This has the most impact when takerGets is integral.
|
||||
auto const takerGets =
|
||||
@@ -292,7 +292,7 @@ getAMMOfferStartWithTakerPays(
|
||||
if (nTakerPaysConstraint < *nTakerPays)
|
||||
nTakerPays = nTakerPaysConstraint;
|
||||
|
||||
auto getAmounts = [&pool, &tfee](Number const& nTakerPaysProposed) {
|
||||
auto const getAmounts = [&pool, &tfee](Number const& nTakerPaysProposed) {
|
||||
// Round downward to minimize the offer and to maximize the quality.
|
||||
// This has the most impact when takerPays is integral.
|
||||
auto const takerPays =
|
||||
@@ -870,8 +870,8 @@ deleteAMMAccount(Sandbox& view, Asset const& asset, Asset const& asset2, beast::
|
||||
*/
|
||||
void
|
||||
initializeFeeAuctionVote(
|
||||
ApplyView& view,
|
||||
SLE::pointer& ammSle,
|
||||
ApplyView const& view,
|
||||
SLE::pointer const& ammSle,
|
||||
AccountID const& account,
|
||||
Asset const& lptAsset,
|
||||
std::uint16_t tfee);
|
||||
@@ -893,7 +893,7 @@ std::expected<bool, TER>
|
||||
verifyAndAdjustLPTokenBalance(
|
||||
Sandbox& sb,
|
||||
STAmount const& lpTokens,
|
||||
SLE::pointer& ammSle,
|
||||
SLE::pointer const& ammSle,
|
||||
AccountID const& account);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -20,7 +20,7 @@ enum class NodeObjectType : std::uint32_t {
|
||||
Ledger = 1,
|
||||
AccountNode = 3,
|
||||
TransactionNode = 4,
|
||||
Dummy = 512 // an invalid or missing object
|
||||
Dummy = 512, // an invalid or missing object
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,7 @@ enum class Status {
|
||||
Unknown = 3,
|
||||
BackendError = 4,
|
||||
|
||||
CustomCode = 100
|
||||
CustomCode = 100,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -429,7 +429,7 @@ Livecache<Allocator>::insert(Endpoint const& ep)
|
||||
XRPL_ASSERT(
|
||||
ep.hops <= (tuning::kMaxHops + 1),
|
||||
"xrpl::peer_finder::Livecache::insert : maximum input hops");
|
||||
auto result = cache_.emplace(ep.address, ep);
|
||||
auto const result = cache_.emplace(ep.address, ep);
|
||||
Element& e(result.first->second);
|
||||
if (result.second)
|
||||
{
|
||||
@@ -497,7 +497,7 @@ Livecache<Allocator>::HopsT::shuffle()
|
||||
std::ranges::copy(list, std::back_inserter(v));
|
||||
std::shuffle(v.begin(), v.end(), defaultPrng());
|
||||
list.clear();
|
||||
for (auto& e : v)
|
||||
for (auto const& e : v)
|
||||
list.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ public:
|
||||
"Port not specified for address:" + remoteAddress.toString());
|
||||
}
|
||||
|
||||
auto result(fixed_.emplace(
|
||||
auto const result(fixed_.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(remoteAddress),
|
||||
std::make_tuple(std::ref(clock))));
|
||||
@@ -439,7 +439,7 @@ public:
|
||||
// Mark fixed slot success
|
||||
if (slot->fixed() && !slot->inbound())
|
||||
{
|
||||
auto iter(fixed_.find(slot->remoteEndpoint()));
|
||||
auto const iter(fixed_.find(slot->remoteEndpoint()));
|
||||
if (iter == fixed_.end())
|
||||
{
|
||||
logicError(
|
||||
@@ -485,7 +485,7 @@ public:
|
||||
|
||||
// Count how many more outbound attempts to make
|
||||
//
|
||||
auto needed(counts_.attemptsNeeded());
|
||||
auto const needed(counts_.attemptsNeeded());
|
||||
if (needed == 0)
|
||||
return none;
|
||||
|
||||
@@ -903,7 +903,7 @@ public:
|
||||
// Mark fixed slot failure
|
||||
if (slot->fixed() && !slot->inbound() && slot->state() != Slot::State::Active)
|
||||
{
|
||||
auto iter(fixed_.find(slot->remoteEndpoint()));
|
||||
auto const iter(fixed_.find(slot->remoteEndpoint()));
|
||||
if (iter == fixed_.end())
|
||||
{
|
||||
logicError(
|
||||
|
||||
@@ -6,31 +6,25 @@
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* API version numbers used in later API versions
|
||||
* The `api_version` numbers this server serves.
|
||||
*
|
||||
* Requests with a version number in the range
|
||||
* [apiMinimumSupportedVersion, apiMaximumSupportedVersion]
|
||||
* are supported.
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
* A request naming no version is served at kApiVersionIfUnspecified, which is 1
|
||||
* because a request wanting any later version states it. A WebSocket message is
|
||||
* one flat object and names it at its top level at every version. A JSON-RPC
|
||||
* request names it in its parameters, or at its own top level: an entry of a
|
||||
* `"method": "batch"` body at every version, a lone request from
|
||||
* kApiMinimumSpecVersion up.
|
||||
*/
|
||||
|
||||
namespace rpc {
|
||||
@@ -46,6 +40,31 @@ static constexpr auto kApiCommandLineVersion = kApiVersion<1>; // TODO Bump to
|
||||
static constexpr auto kApiBetaVersion = kApiVersion<3>;
|
||||
static constexpr auto kApiMaximumValidVersion = kApiBetaVersion;
|
||||
|
||||
/**
|
||||
* First API version that follows the JSON-RPC 2.0 specification.
|
||||
*
|
||||
* From this version up a lone JSON-RPC request may state its `api_version` at
|
||||
* its own top level, beside the members the specification defines there, as a
|
||||
* WebSocket message always has. The member is an XRPL extension: the
|
||||
* specification defines no version member.
|
||||
*
|
||||
* Distinct from kApiBetaVersion, the same number today, which says instead that
|
||||
* the version needs [beta_rpc_api] to be reachable.
|
||||
*/
|
||||
static constexpr auto kApiMinimumSpecVersion = kApiVersion<3>;
|
||||
|
||||
/**
|
||||
* Whether @p apiVersion follows the JSON-RPC 2.0 specification.
|
||||
*
|
||||
* @param apiVersion The version a request asked for.
|
||||
* @return Whether that version follows the specification.
|
||||
*/
|
||||
[[nodiscard]] constexpr bool
|
||||
isSpecVersion(unsigned apiVersion)
|
||||
{
|
||||
return apiVersion >= kApiMinimumSpecVersion;
|
||||
}
|
||||
|
||||
static_assert(kApiInvalidVersion < kApiMinimumSupportedVersion);
|
||||
static_assert(
|
||||
kApiVersionIfUnspecified >= kApiMinimumSupportedVersion &&
|
||||
@@ -57,6 +76,16 @@ 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)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -144,7 +145,58 @@ enum ErrorCodeI {
|
||||
RpcEntryNotFound = 98,
|
||||
RpcUnexpectedLedgerType = 99,
|
||||
|
||||
RpcLast = RpcUnexpectedLedgerType // rpcLAST should always equal the last code.
|
||||
// submit + simulate
|
||||
RpcInvalidTransaction = 100,
|
||||
RpcInternalSubmit = 101,
|
||||
RpcInternalJson = 102,
|
||||
RpcInternalSimulate = 103,
|
||||
|
||||
// transaction_entry
|
||||
RpcFieldNotFoundTransaction = 104,
|
||||
RpcNotYetImplemented = 105,
|
||||
RpcTransactionNotFound = 106,
|
||||
|
||||
// transaction_entry + ledger_entry
|
||||
RpcMalformedRequest = 107,
|
||||
|
||||
// ledger_accept
|
||||
RpcNotStandAlone = 108,
|
||||
|
||||
// ledger_entry, API version 1 only
|
||||
RpcUnknownOption = 109,
|
||||
|
||||
// ledger_entry field validation, one code per malformed field. The ledger_entry helpers report
|
||||
// invalidParams (31) for all of them, so each token needs a row of its own. Alphabetical by
|
||||
// token here only: the enum is append-only once a code ships.
|
||||
//
|
||||
// `malformedIssue` duplicates `issueMalformed` (93): same message, same status, two tokens,
|
||||
// both on the wire already. Do not add a third spelling.
|
||||
RpcMalformedAccount = 110,
|
||||
RpcMalformedAddress = 111,
|
||||
RpcMalformedAuthorized = 112,
|
||||
RpcMalformedAuthorizedCredentials = 113,
|
||||
RpcMalformedBridgeAccount = 114,
|
||||
RpcMalformedBroker = 115,
|
||||
RpcMalformedCurrency = 116,
|
||||
RpcMalformedDirRoot = 117,
|
||||
RpcMalformedDocumentID = 118,
|
||||
RpcMalformedIssue = 119,
|
||||
RpcMalformedIssuingChainDoor = 120,
|
||||
RpcMalformedLockingChainDoor = 121,
|
||||
RpcMalformedMPTIssuanceID = 122,
|
||||
RpcMalformedMPTokenIssuance = 123,
|
||||
RpcMalformedOwner = 124,
|
||||
RpcMalformedSeq = 125,
|
||||
RpcMalformedSponsee = 126,
|
||||
RpcMalformedSponsor = 127,
|
||||
RpcMalformedXChainOwnedClaimID = 128,
|
||||
RpcMalformedXChainOwnedCreateAccountClaimID = 129,
|
||||
|
||||
// subscribe
|
||||
RpcApiVersionConflict = 130,
|
||||
|
||||
// RpcLast should always equal the last code.
|
||||
RpcLast = RpcApiVersionConflict,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -180,11 +232,6 @@ 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)
|
||||
{
|
||||
@@ -202,6 +249,18 @@ struct ErrorInfo
|
||||
ErrorInfo const&
|
||||
getErrorInfo(ErrorCodeI code);
|
||||
|
||||
/**
|
||||
* Returns the error code that owns @p token.
|
||||
*
|
||||
* A linear scan over views measured at compile time, run once per error reply.
|
||||
* A duplicate token is a build error, so the answer is never ambiguous.
|
||||
*
|
||||
* @param token The error token to resolve.
|
||||
* @return The code the table gives @p token, or RpcUnknown if no row names it.
|
||||
*/
|
||||
ErrorCodeI
|
||||
codeForToken(std::string_view token);
|
||||
|
||||
/**
|
||||
* Add or update the json update to reflect the error code.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/json/json_forwards.h>
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace xrpl::rpc {
|
||||
|
||||
/**
|
||||
* Constants of the JSON-RPC 2.0 protocol itself.
|
||||
*
|
||||
* Kept apart from the `api_version` and `ripplerpc` constants in ApiVersion.h,
|
||||
* which go when support for API versions 1 and 2 goes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Value of the `jsonrpc` member of a request and of its reply, fixed at "2.0"
|
||||
* by the JSON-RPC specification.
|
||||
*/
|
||||
inline constexpr std::string_view kJsonRpcVersion{"2.0"};
|
||||
|
||||
/**
|
||||
* Codes for the `code` member of a JSON-RPC error object.
|
||||
*
|
||||
* The specification reserves -32768 to -32000 for the protocol and leaves
|
||||
* -32000 to -32099 of it to the implementation.
|
||||
*
|
||||
* kJsonRpcServerError is the code for an error an XRPL handler reports. The
|
||||
* XRPL token and code travel in the error's `data` member, so renumbering an
|
||||
* XRPL error cannot change a JSON-RPC code.
|
||||
*
|
||||
* The codes from kJsonRpcServerOverloaded on lie outside the
|
||||
* implementation-defined sub-range, which the specification does not allow.
|
||||
* They are the codes every shipped version reports, so moving one breaks the
|
||||
* clients matching on it.
|
||||
*/
|
||||
inline constexpr json::Int kJsonRpcServerError{-32000};
|
||||
inline constexpr json::Int kJsonRpcInvalidRequest{-32600};
|
||||
inline constexpr json::Int kJsonRpcMethodNotFound{-32601};
|
||||
inline constexpr json::Int kJsonRpcInvalidParams{-32602};
|
||||
inline constexpr json::Int kJsonRpcServerOverloaded{-32604};
|
||||
inline constexpr json::Int kJsonRpcForbidden{-32605};
|
||||
inline constexpr json::Int kJsonRpcWrongVersion{-32606};
|
||||
|
||||
} // namespace xrpl::rpc
|
||||
@@ -40,8 +40,6 @@ struct LedgerHeader
|
||||
|
||||
// If validated is false, it means "not yet validated."
|
||||
// Once validated is true, it will never be set false at a later time.
|
||||
// NOTE: If you are accessing this directly, you are probably doing it
|
||||
// wrong. Use LedgerMaster::isValidated().
|
||||
// VFALCO TODO Make this not mutable
|
||||
bool mutable validated = false;
|
||||
bool accepted = false;
|
||||
|
||||
@@ -26,6 +26,7 @@ class STTx;
|
||||
* greater than the maximum value of uint16.
|
||||
*/
|
||||
// Macro-generated, complex
|
||||
// NOLINTBEGIN(readability-trailing-comma) the macro supplies the trailing comma
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
|
||||
enum GranularPermissionType : std::uint32_t {
|
||||
#pragma push_macro("GRANULAR_PERMISSION")
|
||||
@@ -38,6 +39,7 @@ enum GranularPermissionType : std::uint32_t {
|
||||
#undef GRANULAR_PERMISSION
|
||||
#pragma pop_macro("GRANULAR_PERMISSION")
|
||||
};
|
||||
// NOLINTEND(readability-trailing-comma)
|
||||
|
||||
class Permission
|
||||
{
|
||||
|
||||
@@ -284,8 +284,10 @@ public:
|
||||
|
||||
auto const [minV, maxV] = std::minmax(q1.value_, q2.value_);
|
||||
|
||||
auto mantissa = [](std::uint64_t rate) { return rate & ~(255ull << (64 - 8)); };
|
||||
auto exponent = [](std::uint64_t rate) { return static_cast<int>(rate >> (64 - 8)) - 100; };
|
||||
auto const mantissa = [](std::uint64_t rate) { return rate & ~(255ull << (64 - 8)); };
|
||||
auto const exponent = [](std::uint64_t rate) {
|
||||
return static_cast<int>(rate >> (64 - 8)) - 100;
|
||||
};
|
||||
|
||||
auto const minVMantissa = mantissa(minV);
|
||||
auto const maxVMantissa = mantissa(maxV);
|
||||
|
||||
@@ -29,7 +29,7 @@ struct JsonOptions
|
||||
DisableApiPriorV2 = 0b0000'0010,
|
||||
|
||||
// IMPORTANT `All` must be union of all of the above; see also operator~
|
||||
All = IncludeDate | DisableApiPriorV2 // 0b0000'0011
|
||||
All = IncludeDate | DisableApiPriorV2, // 0b0000'0011
|
||||
};
|
||||
|
||||
constexpr JsonOptions(UnderlyingT v) noexcept : value(v)
|
||||
|
||||
@@ -440,7 +440,7 @@ private:
|
||||
// These values are carefully chosen to do the right thing if passed
|
||||
// to SField::shouldInclude (bool)
|
||||
OmitSigningFields = false,
|
||||
WithAllFields = true
|
||||
WithAllFields = true,
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
@@ -36,7 +36,7 @@ enum class TxnSql : char {
|
||||
Held = 'H',
|
||||
Validated = 'V',
|
||||
Included = 'I',
|
||||
Unknown = 'U'
|
||||
Unknown = 'U',
|
||||
};
|
||||
|
||||
class STTx final : public STObject, public CountedObject<STTx>
|
||||
|
||||
@@ -250,7 +250,7 @@ public:
|
||||
bool
|
||||
getBitString(BaseUInt<Bits, Tag>& data, int offset) const
|
||||
{
|
||||
auto success = (offset + (Bits / 8)) <= data_.size();
|
||||
auto const success = (offset + (Bits / 8)) <= data_.size();
|
||||
if (success)
|
||||
memcpy(data.begin(), &data_.front() + offset, (Bits / 8));
|
||||
return success;
|
||||
|
||||
@@ -32,7 +32,7 @@ enum class SignatureRole {
|
||||
/**
|
||||
* The sponsor's signature, in sfSponsorSignature.
|
||||
*/
|
||||
Sponsor
|
||||
Sponsor,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,7 +51,7 @@ enum TELcodes : TERUnderlyingType {
|
||||
telWRONG_NETWORK,
|
||||
telREQUIRES_NETWORK_ID,
|
||||
telNETWORK_ID_MAKES_TX_NON_CANONICAL,
|
||||
telENV_RPC_FAILED
|
||||
telENV_RPC_FAILED,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -247,7 +247,7 @@ enum TEScodes : TERUnderlyingType {
|
||||
// Implications:
|
||||
// - Applied
|
||||
// - Forwarded
|
||||
tesSUCCESS = 0
|
||||
tesSUCCESS = 0,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -319,7 +319,9 @@ inline FlagMap const&
|
||||
getUniversalFlags()
|
||||
{
|
||||
static FlagMap const flags = {
|
||||
{"tfFullyCanonicalSig", tfFullyCanonicalSig}, {"tfInnerBatchTxn", tfInnerBatchTxn}};
|
||||
{"tfFullyCanonicalSig", tfFullyCanonicalSig},
|
||||
{"tfInnerBatchTxn", tfInnerBatchTxn},
|
||||
};
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
@@ -427,7 +427,7 @@ mulDivU(Source1 value, Dest mul, Source2 div)
|
||||
static_cast<std::uint64_t>(value.value()),
|
||||
static_cast<std::uint64_t>(mul.value()));
|
||||
|
||||
auto quotient = product / div.value();
|
||||
auto const quotient = product / div.value();
|
||||
|
||||
if (quotient > kMax)
|
||||
return std::nullopt;
|
||||
|
||||
@@ -236,7 +236,7 @@ enum class AttestationMatch {
|
||||
// all of the fields match, except the dst field
|
||||
MatchExceptDst,
|
||||
// all of the fields match
|
||||
Match
|
||||
Match,
|
||||
};
|
||||
|
||||
struct XChainClaimAttestation
|
||||
|
||||
@@ -119,13 +119,13 @@ inplaceBigintDivRem(std::span<uint64_t> numerator, std::uint64_t divisor)
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto toU128 = [](std::uint64_t high, std::uint64_t low) -> unsigned __int128 {
|
||||
auto const toU128 = [](std::uint64_t high, std::uint64_t low) -> unsigned __int128 {
|
||||
unsigned __int128 const high128 = high;
|
||||
unsigned __int128 const low128 = low;
|
||||
return ((high128 << 64) | low128);
|
||||
};
|
||||
auto divRe64 = [](unsigned __int128 num,
|
||||
std::uint64_t denom) -> std::tuple<std::uint64_t, std::uint64_t> {
|
||||
auto const divRe64 = [](unsigned __int128 num,
|
||||
std::uint64_t denom) -> std::tuple<std::uint64_t, std::uint64_t> {
|
||||
unsigned __int128 const denom128 = denom;
|
||||
unsigned __int128 const d = num / denom128;
|
||||
unsigned __int128 const r = num - (denom128 * d);
|
||||
|
||||
@@ -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
|
||||
JSS(error_exception); // out: Submit, Simulate
|
||||
JSS(error_message); // out: error
|
||||
JSS(expand); // in: handler/Ledger
|
||||
JSS(expected_date); // out: any (warnings)
|
||||
@@ -559,7 +559,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
|
||||
JSS(size); // out: get_aggregate_price, ServerHandler
|
||||
JSS(snapshot); // in: Subscribe
|
||||
JSS(source_account); // in: PathRequest, RipplePathFind
|
||||
JSS(source_amount); // in: PathRequest, RipplePathFind
|
||||
|
||||
@@ -24,7 +24,7 @@ enum class TokenType : std::uint8_t {
|
||||
AccountPublic = 35,
|
||||
AccountSecret = 34,
|
||||
FamilyGenerator = 41, // unused
|
||||
FamilySeed = 33
|
||||
FamilySeed = 33,
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
||||
+37
-28
@@ -46,9 +46,10 @@ inline constexpr std::uint32_t kSqliteTuningCutoff = 10'000'000;
|
||||
inline constexpr auto kLgrDbName{"ledger.db"};
|
||||
|
||||
inline constexpr std::array<char const*, 5> kLgrDbInit{
|
||||
{"BEGIN TRANSACTION;",
|
||||
{
|
||||
"BEGIN TRANSACTION;",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS Ledgers ( \
|
||||
"CREATE TABLE IF NOT EXISTS Ledgers ( \
|
||||
LedgerHash CHARACTER(64) PRIMARY KEY, \
|
||||
LedgerSeq BIGINT UNSIGNED, \
|
||||
PrevHash CHARACTER(64), \
|
||||
@@ -60,12 +61,14 @@ inline constexpr std::array<char const*, 5> kLgrDbInit{
|
||||
AccountSetHash CHARACTER(64), \
|
||||
TransSetHash CHARACTER(64) \
|
||||
);",
|
||||
"CREATE INDEX IF NOT EXISTS SeqLedger ON Ledgers(LedgerSeq);",
|
||||
"CREATE INDEX IF NOT EXISTS SeqLedger ON Ledgers(LedgerSeq);",
|
||||
|
||||
// Old table and indexes no longer needed
|
||||
"DROP TABLE IF EXISTS Validations;",
|
||||
// Old table and indexes no longer needed
|
||||
"DROP TABLE IF EXISTS Validations;",
|
||||
|
||||
"END TRANSACTION;"}};
|
||||
"END TRANSACTION;",
|
||||
},
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -73,9 +76,10 @@ inline constexpr std::array<char const*, 5> kLgrDbInit{
|
||||
inline constexpr auto kTxDbName{"transaction.db"};
|
||||
|
||||
inline constexpr std::array<char const*, 8> kTxDbInit{
|
||||
{"BEGIN TRANSACTION;",
|
||||
{
|
||||
"BEGIN TRANSACTION;",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS Transactions ( \
|
||||
"CREATE TABLE IF NOT EXISTS Transactions ( \
|
||||
TransID CHARACTER(64) PRIMARY KEY, \
|
||||
TransType CHARACTER(24), \
|
||||
FromAcct CHARACTER(35), \
|
||||
@@ -85,57 +89,62 @@ inline constexpr std::array<char const*, 8> kTxDbInit{
|
||||
RawTxn BLOB, \
|
||||
TxnMeta BLOB \
|
||||
);",
|
||||
"CREATE INDEX IF NOT EXISTS TxLgrIndex ON \
|
||||
"CREATE INDEX IF NOT EXISTS TxLgrIndex ON \
|
||||
Transactions(LedgerSeq);",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS AccountTransactions ( \
|
||||
"CREATE TABLE IF NOT EXISTS AccountTransactions ( \
|
||||
TransID CHARACTER(64), \
|
||||
Account CHARACTER(64), \
|
||||
LedgerSeq BIGINT UNSIGNED, \
|
||||
TxnSeq INTEGER \
|
||||
);",
|
||||
"CREATE INDEX IF NOT EXISTS AcctTxIDIndex ON \
|
||||
"CREATE INDEX IF NOT EXISTS AcctTxIDIndex ON \
|
||||
AccountTransactions(TransID);",
|
||||
"CREATE INDEX IF NOT EXISTS AcctTxIndex ON \
|
||||
"CREATE INDEX IF NOT EXISTS AcctTxIndex ON \
|
||||
AccountTransactions(Account, LedgerSeq, TxnSeq, TransID);",
|
||||
"CREATE INDEX IF NOT EXISTS AcctLgrIndex ON \
|
||||
"CREATE INDEX IF NOT EXISTS AcctLgrIndex ON \
|
||||
AccountTransactions(LedgerSeq, Account, TransID);",
|
||||
|
||||
"END TRANSACTION;"}};
|
||||
"END TRANSACTION;",
|
||||
},
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline constexpr auto kWalletDbName{"wallet.db"};
|
||||
|
||||
inline constexpr std::array<char const*, 6> kWalletDbInit{
|
||||
{"BEGIN TRANSACTION;",
|
||||
{
|
||||
"BEGIN TRANSACTION;",
|
||||
|
||||
// A node's identity must be persisted, including
|
||||
// for clustering purposes. This table holds one
|
||||
// entry: the server's unique identity, but the
|
||||
// value can be overriden by specifying a node
|
||||
// identity in the config file using a [node_seed]
|
||||
// entry.
|
||||
"CREATE TABLE IF NOT EXISTS NodeIdentity ( \
|
||||
// A node's identity must be persisted, including
|
||||
// for clustering purposes. This table holds one
|
||||
// entry: the server's unique identity, but the
|
||||
// value can be overriden by specifying a node
|
||||
// identity in the config file using a [node_seed]
|
||||
// entry.
|
||||
"CREATE TABLE IF NOT EXISTS NodeIdentity ( \
|
||||
PublicKey CHARACTER(53), \
|
||||
PrivateKey CHARACTER(52) \
|
||||
);",
|
||||
|
||||
// Peer reservations
|
||||
"CREATE TABLE IF NOT EXISTS PeerReservations ( \
|
||||
// Peer reservations
|
||||
"CREATE TABLE IF NOT EXISTS PeerReservations ( \
|
||||
PublicKey CHARACTER(53) UNIQUE NOT NULL, \
|
||||
Description CHARACTER(64) NOT NULL \
|
||||
);",
|
||||
|
||||
// Validator Manifests
|
||||
"CREATE TABLE IF NOT EXISTS ValidatorManifests ( \
|
||||
// Validator Manifests
|
||||
"CREATE TABLE IF NOT EXISTS ValidatorManifests ( \
|
||||
RawData BLOB NOT NULL \
|
||||
);",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS PublisherManifests ( \
|
||||
"CREATE TABLE IF NOT EXISTS PublisherManifests ( \
|
||||
RawData BLOB NOT NULL \
|
||||
);",
|
||||
|
||||
"END TRANSACTION;"}};
|
||||
"END TRANSACTION;",
|
||||
},
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -50,8 +50,8 @@ struct LedgerRange
|
||||
enum class DelegateType {
|
||||
Actor, ///< Another account signed and submitted transactions on behalf of this account (this
|
||||
///< account is the owner/delegator).
|
||||
Authorizer ///< This account signed and submitted transactions on behalf of another account
|
||||
///< (this account is the signer/delegatee).
|
||||
Authorizer, ///< This account signed and submitted transactions on behalf of another account
|
||||
///< (this account is the signer/delegatee).
|
||||
};
|
||||
|
||||
struct DelegateFilter
|
||||
|
||||
@@ -21,7 +21,7 @@ enum class Disposition {
|
||||
* Consumer should be disconnected for excess consumption.
|
||||
*/
|
||||
,
|
||||
Drop
|
||||
Drop,
|
||||
};
|
||||
|
||||
} // namespace xrpl::resource
|
||||
@@ -334,7 +334,7 @@ public:
|
||||
if (iter->whenExpires <= elapsed)
|
||||
{
|
||||
JLOG(journal_.debug()) << "Expired " << *iter;
|
||||
auto tableIter = table_.find(*iter->key);
|
||||
auto const tableIter = table_.find(*iter->key);
|
||||
++iter;
|
||||
erase(tableIter);
|
||||
}
|
||||
@@ -437,7 +437,8 @@ public:
|
||||
static_assert(
|
||||
kFeeLogAsWarn > kFeeLogAsInfo && kFeeLogAsInfo > kFeeLogAsDebug && kFeeLogAsDebug > 10);
|
||||
|
||||
static auto kGetStream = [](resource::Charge::value_type cost, beast::Journal& journal) {
|
||||
static auto const kGetStream = [](resource::Charge::value_type cost,
|
||||
beast::Journal& journal) {
|
||||
if (cost >= kFeeLogAsWarn)
|
||||
return journal.warn();
|
||||
if (cost >= kFeeLogAsInfo)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -113,7 +114,11 @@ public:
|
||||
// you get transactions as they occur or once their
|
||||
// results are confirmed
|
||||
virtual void
|
||||
subAccount(Ref ispListener, HashSet<AccountID> const& vnaAccountIDs, bool realTime) = 0;
|
||||
subAccount(
|
||||
Ref ispListener,
|
||||
HashSet<AccountID> const& vnaAccountIDs,
|
||||
bool realTime,
|
||||
unsigned int apiVersion) = 0;
|
||||
|
||||
// for normal use, removes from InfoSub and server
|
||||
virtual void
|
||||
@@ -130,10 +135,12 @@ public:
|
||||
/**
|
||||
* subscribe an account's new transactions and retrieve the account's
|
||||
* historical transactions
|
||||
* @param apiVersion The version the subscription is registered at,
|
||||
* which is the version its messages are shaped for.
|
||||
* @return rpcSUCCESS if successful, otherwise an error code
|
||||
*/
|
||||
virtual ErrorCodeI
|
||||
subAccountHistory(Ref ispListener, AccountID const& account) = 0;
|
||||
subAccountHistory(Ref ispListener, AccountID const& account, unsigned int apiVersion) = 0;
|
||||
|
||||
/**
|
||||
* unsubscribe an account's transactions
|
||||
@@ -196,30 +203,34 @@ public:
|
||||
HashSet<AccountID> historyAccounts) = 0;
|
||||
|
||||
// VFALCO TODO Document the bool return value
|
||||
//
|
||||
// Every sub* below takes the version the subscription is registered at, which is the
|
||||
// version its messages are shaped for. Registering the same subscription again replaces
|
||||
// the entry, so the newest registration decides that subscription's version.
|
||||
virtual bool
|
||||
subLedger(Ref ispListener, json::Value& jvResult) = 0;
|
||||
subLedger(Ref ispListener, json::Value& jvResult, unsigned int apiVersion) = 0;
|
||||
virtual bool
|
||||
unsubLedger(std::uint64_t uListener) = 0;
|
||||
|
||||
virtual bool
|
||||
subBookChanges(Ref ispListener) = 0;
|
||||
subBookChanges(Ref ispListener, unsigned int apiVersion) = 0;
|
||||
virtual bool
|
||||
unsubBookChanges(std::uint64_t uListener) = 0;
|
||||
|
||||
virtual bool
|
||||
subManifests(Ref ispListener) = 0;
|
||||
subManifests(Ref ispListener, unsigned int apiVersion) = 0;
|
||||
virtual bool
|
||||
unsubManifests(std::uint64_t uListener) = 0;
|
||||
virtual void
|
||||
pubManifest(Manifest const&) = 0;
|
||||
|
||||
virtual bool
|
||||
subServer(Ref ispListener, json::Value& jvResult, bool admin) = 0;
|
||||
subServer(Ref ispListener, json::Value& jvResult, bool admin, unsigned int apiVersion) = 0;
|
||||
virtual bool
|
||||
unsubServer(std::uint64_t uListener) = 0;
|
||||
|
||||
virtual bool
|
||||
subBook(Ref ispListener, Book const&) = 0;
|
||||
subBook(Ref ispListener, Book const&, unsigned int apiVersion) = 0;
|
||||
|
||||
/**
|
||||
* Remove a book subscription for a live subscriber.
|
||||
@@ -248,7 +259,8 @@ public:
|
||||
* InfoSub::bookSubscriptions_ because the InfoSub is being destroyed.
|
||||
* Called by ~InfoSub() for each book in bookSubscriptions_.
|
||||
*
|
||||
* @param uListener The sequence number of the subscriber being torn down.
|
||||
* @param uListener The sequence number of the subscriber being torn
|
||||
* down.
|
||||
* @param book The order book entry to remove.
|
||||
* @return true if the entry was present and removed, false otherwise
|
||||
* (e.g., already removed by a concurrent RPC unsubscribe).
|
||||
@@ -259,22 +271,22 @@ public:
|
||||
unsubBookInternal(std::uint64_t uListener, Book const&) = 0;
|
||||
|
||||
virtual bool
|
||||
subTransactions(Ref ispListener) = 0;
|
||||
subTransactions(Ref ispListener, unsigned int apiVersion) = 0;
|
||||
virtual bool
|
||||
unsubTransactions(std::uint64_t uListener) = 0;
|
||||
|
||||
virtual bool
|
||||
subRTTransactions(Ref ispListener) = 0;
|
||||
subRTTransactions(Ref ispListener, unsigned int apiVersion) = 0;
|
||||
virtual bool
|
||||
unsubRTTransactions(std::uint64_t uListener) = 0;
|
||||
|
||||
virtual bool
|
||||
subValidations(Ref ispListener) = 0;
|
||||
subValidations(Ref ispListener, unsigned int apiVersion) = 0;
|
||||
virtual bool
|
||||
unsubValidations(std::uint64_t uListener) = 0;
|
||||
|
||||
virtual bool
|
||||
subPeerStatus(Ref ispListener) = 0;
|
||||
subPeerStatus(Ref ispListener, unsigned int apiVersion) = 0;
|
||||
|
||||
virtual bool
|
||||
unsubPeerStatus(std::uint64_t uListener) = 0;
|
||||
@@ -282,12 +294,12 @@ public:
|
||||
pubPeerStatus(std::function<json::Value()> const&) = 0;
|
||||
|
||||
virtual bool
|
||||
subConsensus(Ref ispListener) = 0;
|
||||
subConsensus(Ref ispListener, unsigned int apiVersion) = 0;
|
||||
virtual bool
|
||||
unsubConsensus(std::uint64_t uListener) = 0;
|
||||
|
||||
virtual void
|
||||
subMPT(InfoSub::Ref ispListener, HashSet<MPTID> const& mptIDs) = 0;
|
||||
subMPT(InfoSub::Ref ispListener, HashSet<MPTID> const& mptIDs, unsigned int apiVersion) = 0;
|
||||
virtual void
|
||||
unsubMPT(InfoSub::Ref ispListener, HashSet<MPTID> const& mptIDs) = 0;
|
||||
|
||||
@@ -385,8 +397,9 @@ public:
|
||||
/**
|
||||
* Whether this connection already tracks an account-history for @p account.
|
||||
*
|
||||
* `doSubscribe` reads this to charge the cap for an account_history_tx_stream
|
||||
* only when it is net-new, matching the account branches.
|
||||
* `doSubscribe` reads this to charge the cap for an
|
||||
* account_history_tx_stream only when it is net-new, matching the account
|
||||
* branches.
|
||||
*
|
||||
* @param account The account an account_history_tx_stream would add.
|
||||
* @return true if @p account is already in the account-history set.
|
||||
@@ -447,11 +460,26 @@ public:
|
||||
std::shared_ptr<InfoSubRequest> const&
|
||||
getRequest();
|
||||
|
||||
void
|
||||
setApiVersion(unsigned int apiVersion);
|
||||
|
||||
[[nodiscard]] unsigned int
|
||||
getApiVersion() const noexcept;
|
||||
/**
|
||||
* Establishes @p apiVersion as the version every subscription on this
|
||||
* connection is served at.
|
||||
*
|
||||
* A connection serves one version: one message has one shape, and several
|
||||
* of its subscriptions may match it. The first `subscribe` decides it and
|
||||
* it is never cleared. A `subscribe` refused for another reason still
|
||||
* establishes it, the registrations it makes being spread through the
|
||||
* handler.
|
||||
*
|
||||
* For the subscribe path alone. Nothing reads this value back: a publisher
|
||||
* reads the version recorded on the subscription it took the sink from.
|
||||
*
|
||||
* @param apiVersion The version the `subscribe` named.
|
||||
* @return nullopt when @p apiVersion is this connection's version;
|
||||
* otherwise the version already established.
|
||||
* @note Thread-safe: takes `lock_`.
|
||||
*/
|
||||
[[nodiscard]] std::optional<unsigned int>
|
||||
establishSubscriptionVersion(unsigned int apiVersion);
|
||||
|
||||
void
|
||||
insertSubMPTInfo(MPTID const& mptID);
|
||||
@@ -485,9 +513,20 @@ private:
|
||||
HashSet<AccountID> accountHistorySubscriptions_;
|
||||
HashSet<Book> bookSubscriptions_;
|
||||
HashSet<MPTID> mptSubscriptions_;
|
||||
unsigned int apiVersion_ = 0;
|
||||
// The API version every subscription on this connection was registered at, set by the first
|
||||
// `subscribe` and never cleared. Guarded by lock_. Read only by establishSubscriptionVersion,
|
||||
// so no publisher can reach it.
|
||||
std::optional<unsigned int> subscriptionApiVersion_;
|
||||
|
||||
static int
|
||||
/**
|
||||
* The next sequence number, which is what identifies a connection.
|
||||
*
|
||||
* 64 bits wide, as the counter and `seq_` are, so no two live connections
|
||||
* share an identity.
|
||||
*
|
||||
* @return A sequence number no live connection holds.
|
||||
*/
|
||||
static std::uint64_t
|
||||
assignId()
|
||||
{
|
||||
static std::atomic<std::uint64_t> kID(0);
|
||||
|
||||
@@ -328,7 +328,7 @@ enum class ManifestDisposition {
|
||||
|
||||
Invalid, ///< Timely, but invalid signature
|
||||
|
||||
UntrustedCapacity ///< Unlisted and limit reached
|
||||
UntrustedCapacity, ///< Unlisted and limit reached
|
||||
};
|
||||
|
||||
inline std::string
|
||||
@@ -361,8 +361,8 @@ to_string(ManifestDisposition m)
|
||||
* configured keys should use `Uncapped`.
|
||||
*/
|
||||
enum class ManifestRateLimitCapPolicy : std::uint8_t {
|
||||
Capped, ///< Subject to the untrusted cap (unlisted peer gossip)
|
||||
Uncapped ///< Bypasses the cap (listed/trusted or config manifests)
|
||||
Capped, ///< Subject to the untrusted cap (unlisted peer gossip)
|
||||
Uncapped, ///< Bypasses the cap (listed/trusted or config manifests)
|
||||
};
|
||||
|
||||
class DatabaseCon;
|
||||
|
||||
@@ -62,7 +62,7 @@ enum class OperatingMode {
|
||||
CONNECTED = 1, ///< convinced we are talking to the network
|
||||
SYNCING = 2, ///< fallen slightly behind
|
||||
TRACKING = 3, ///< convinced we agree with the network
|
||||
FULL = 4 ///< we have the ledger and can even validate
|
||||
FULL = 4, ///< we have the ledger and can even validate
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -196,7 +196,7 @@ public:
|
||||
virtual bool
|
||||
isFull() = 0;
|
||||
virtual void
|
||||
setMode(OperatingMode om, char const* reason) = 0;
|
||||
setMode(OperatingMode om) = 0;
|
||||
virtual bool
|
||||
isBlocked() = 0;
|
||||
virtual bool
|
||||
|
||||
@@ -267,7 +267,7 @@ template <class Handler, class Impl>
|
||||
void
|
||||
BaseHTTPPeer<Handler, Impl>::onTimer()
|
||||
{
|
||||
auto ec = boost::system::errc::make_error_code(boost::system::errc::timed_out);
|
||||
auto const ec = boost::system::errc::make_error_code(boost::system::errc::timed_out);
|
||||
fail(ec, "timer");
|
||||
}
|
||||
|
||||
|
||||
@@ -96,10 +96,12 @@ private:
|
||||
boost::asio::strand<boost::asio::io_context::executor_type> strand_;
|
||||
bool ssl_{
|
||||
port_.protocol.contains("https") || port_.protocol.contains("wss") ||
|
||||
port_.protocol.contains("wss2") || port_.protocol.contains("peer")};
|
||||
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};
|
||||
@@ -207,12 +209,12 @@ Door<Handler>::Detector::doDetect(boost::asio::yield_context doYield)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
if (auto sp = ios().template emplace<SSLHTTPPeer<Handler>>(
|
||||
if (auto const sp = ios().template emplace<SSLHTTPPeer<Handler>>(
|
||||
port_, handler_, ioc_, j_, remoteAddress_, buf.data(), std::move(stream_)))
|
||||
sp->run();
|
||||
return;
|
||||
}
|
||||
if (auto sp = ios().template emplace<PlainHTTPPeer<Handler>>(
|
||||
if (auto const sp = ios().template emplace<PlainHTTPPeer<Handler>>(
|
||||
port_, handler_, ioc_, j_, remoteAddress_, buf.data(), std::move(stream_)))
|
||||
sp->run();
|
||||
return;
|
||||
@@ -328,12 +330,12 @@ Door<Handler>::create(
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
if (auto sp = ios().template emplace<SSLHTTPPeer<Handler>>(
|
||||
if (auto const sp = ios().template emplace<SSLHTTPPeer<Handler>>(
|
||||
port_, handler_, ioc_, j_, remoteAddress, buffers, std::move(stream)))
|
||||
sp->run();
|
||||
return;
|
||||
}
|
||||
if (auto sp = ios().template emplace<PlainHTTPPeer<Handler>>(
|
||||
if (auto const sp = ios().template emplace<PlainHTTPPeer<Handler>>(
|
||||
port_, handler_, ioc_, j_, remoteAddress, buffers, std::move(stream)))
|
||||
sp->run();
|
||||
}
|
||||
@@ -390,7 +392,7 @@ Door<Handler>::doAccept(boost::asio::yield_context doYield)
|
||||
|
||||
if (ssl_ && plain_)
|
||||
{
|
||||
if (auto sp = ios().template emplace<Detector>(
|
||||
if (auto const sp = ios().template emplace<Detector>(
|
||||
port_, handler_, ioc_, std::move(stream), remoteAddress, j_))
|
||||
sp->run();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,20 @@
|
||||
|
||||
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.
|
||||
* The status line carries the phrase Beast's registry gives @p nStatus, except
|
||||
* for 401 and 503, which carry a phrase of this server's own.
|
||||
*
|
||||
* @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);
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ ServerImpl<Handler>::ports(std::vector<Port> const& ports)
|
||||
{
|
||||
ports_.push_back(port);
|
||||
auto& internalPort = ports_.back();
|
||||
if (auto sp = ios_.emplace<Door<Handler>>(handler_, ioContext_, internalPort, j_))
|
||||
if (auto const sp = ios_.emplace<Door<Handler>>(handler_, ioContext_, internalPort, j_))
|
||||
{
|
||||
list_.push_back(sp);
|
||||
|
||||
|
||||
@@ -225,14 +225,14 @@ IOList::close(Finisher&& f)
|
||||
if (closed_)
|
||||
return;
|
||||
closed_ = true;
|
||||
auto map = std::move(map_);
|
||||
auto const map = std::move(map_);
|
||||
if (!map.empty())
|
||||
{
|
||||
f_ = std::forward<Finisher>(f);
|
||||
lock.unlock();
|
||||
for (auto const& p : map)
|
||||
{
|
||||
if (auto sp = p.second.lock())
|
||||
if (auto const sp = p.second.lock())
|
||||
sp->close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,7 +486,7 @@ private:
|
||||
XRPL_ASSERT(node, "xrpl::SHAMap::NodePathStack::pushChild : non-null node input");
|
||||
XRPL_ASSERT(
|
||||
!stack_.empty(), "xrpl::SHAMap::NodePathStack::pushChild : non-empty stack");
|
||||
auto childID = stack_.top().second.getChildNodeID(branch);
|
||||
auto const childID = stack_.top().second.getChildNodeID(branch);
|
||||
XRPL_ASSERT_IF(
|
||||
node->isInner(),
|
||||
childID.getDepth() < kLeafDepth,
|
||||
@@ -495,7 +495,7 @@ private:
|
||||
node->isLeaf(),
|
||||
childID.isPrefixOf(leafKey(*node)),
|
||||
"xrpl::SHAMap::NodePathStack::pushChild : leaf key below branch");
|
||||
stack_.emplace(std::move(node), std::move(childID));
|
||||
stack_.emplace(std::move(node), childID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -878,7 +878,7 @@ SHAMap::ConstIterator::operator++()
|
||||
inline SHAMap::ConstIterator
|
||||
SHAMap::ConstIterator::operator++(int)
|
||||
{
|
||||
auto tmp = *this;
|
||||
auto const tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -14,35 +14,112 @@ private:
|
||||
|
||||
public:
|
||||
SHAMapAddNode();
|
||||
|
||||
/**
|
||||
* Record one node that was rejected.
|
||||
*/
|
||||
void
|
||||
incInvalid();
|
||||
|
||||
/**
|
||||
* Record one node that produced a good result.
|
||||
*/
|
||||
void
|
||||
incUseful();
|
||||
|
||||
/**
|
||||
* Record one node that was not needed: the map already held it, or the map
|
||||
* or its acquisition was no longer taking nodes. isGood() counts it on the
|
||||
* accepted side.
|
||||
*/
|
||||
void
|
||||
incDuplicate();
|
||||
void
|
||||
reset();
|
||||
|
||||
/**
|
||||
* @return How many nodes produced a good result.
|
||||
*/
|
||||
[[nodiscard]] int
|
||||
getGood() const;
|
||||
|
||||
/**
|
||||
* @return How many nodes this code rejected, which is not how many the
|
||||
* batch was given: a batch that stops at its first bad node counts
|
||||
* one, and a batch that carries on counts each.
|
||||
*/
|
||||
[[nodiscard]] int
|
||||
getBad() const;
|
||||
|
||||
/**
|
||||
* @return How many nodes were not needed, whether already held or offered
|
||||
* to a map no longer taking nodes, tallied apart from the good and
|
||||
* bad counts.
|
||||
*/
|
||||
[[nodiscard]] int
|
||||
getDuplicate() const;
|
||||
|
||||
/**
|
||||
* Whether nodes that produced a good result or were not needed outnumber
|
||||
* the ones rejected.
|
||||
*
|
||||
* @return Whether the batch was good.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isGood() const;
|
||||
|
||||
/**
|
||||
* @return Whether at least one node in the batch was rejected.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isInvalid() const;
|
||||
|
||||
/**
|
||||
* @return Whether at least one node in the batch produced a good result.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isUseful() const;
|
||||
|
||||
/**
|
||||
* @return A verdict recording one node that was not needed.
|
||||
*/
|
||||
static SHAMapAddNode
|
||||
duplicate();
|
||||
|
||||
/**
|
||||
* @return A verdict recording one useful node.
|
||||
*/
|
||||
static SHAMapAddNode
|
||||
useful();
|
||||
|
||||
/**
|
||||
* @return A verdict recording one invalid node.
|
||||
*/
|
||||
static SHAMapAddNode
|
||||
invalid();
|
||||
|
||||
/**
|
||||
* Clear every count back to zero.
|
||||
*/
|
||||
void
|
||||
reset();
|
||||
|
||||
/**
|
||||
* Render the tally as a log line.
|
||||
*
|
||||
* @return The tally, e.g. "good:2 bad:1 dupe:1", or "no nodes processed" if
|
||||
* every count is zero.
|
||||
*/
|
||||
[[nodiscard]] std::string
|
||||
get() const;
|
||||
|
||||
/**
|
||||
* Add another verdict's counts into this one.
|
||||
*
|
||||
* @param n The verdict to add.
|
||||
* @return This verdict, updated.
|
||||
*/
|
||||
SHAMapAddNode&
|
||||
operator+=(SHAMapAddNode const& n);
|
||||
|
||||
static SHAMapAddNode
|
||||
duplicate();
|
||||
static SHAMapAddNode
|
||||
useful();
|
||||
static SHAMapAddNode
|
||||
invalid();
|
||||
|
||||
private:
|
||||
SHAMapAddNode(int good, int bad, int duplicate);
|
||||
};
|
||||
@@ -74,18 +151,30 @@ SHAMapAddNode::incDuplicate()
|
||||
++duplicate_;
|
||||
}
|
||||
|
||||
inline void
|
||||
SHAMapAddNode::reset()
|
||||
{
|
||||
good_ = bad_ = duplicate_ = 0;
|
||||
}
|
||||
|
||||
inline int
|
||||
SHAMapAddNode::getGood() const
|
||||
{
|
||||
return good_;
|
||||
}
|
||||
|
||||
inline int
|
||||
SHAMapAddNode::getBad() const
|
||||
{
|
||||
return bad_;
|
||||
}
|
||||
|
||||
inline int
|
||||
SHAMapAddNode::getDuplicate() const
|
||||
{
|
||||
return duplicate_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
SHAMapAddNode::isGood() const
|
||||
{
|
||||
return (good_ + duplicate_) > bad_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
SHAMapAddNode::isInvalid() const
|
||||
{
|
||||
@@ -98,22 +187,6 @@ SHAMapAddNode::isUseful() const
|
||||
return good_ > 0;
|
||||
}
|
||||
|
||||
inline SHAMapAddNode&
|
||||
SHAMapAddNode::operator+=(SHAMapAddNode const& n)
|
||||
{
|
||||
good_ += n.good_;
|
||||
bad_ += n.bad_;
|
||||
duplicate_ += n.duplicate_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool
|
||||
SHAMapAddNode::isGood() const
|
||||
{
|
||||
return (good_ + duplicate_) > bad_;
|
||||
}
|
||||
|
||||
inline SHAMapAddNode
|
||||
SHAMapAddNode::duplicate()
|
||||
{
|
||||
@@ -132,6 +205,12 @@ SHAMapAddNode::invalid()
|
||||
return SHAMapAddNode(0, 1, 0);
|
||||
}
|
||||
|
||||
inline void
|
||||
SHAMapAddNode::reset()
|
||||
{
|
||||
good_ = bad_ = duplicate_ = 0;
|
||||
}
|
||||
|
||||
inline std::string
|
||||
SHAMapAddNode::get() const
|
||||
{
|
||||
@@ -160,4 +239,14 @@ SHAMapAddNode::get() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline SHAMapAddNode&
|
||||
SHAMapAddNode::operator+=(SHAMapAddNode const& n)
|
||||
{
|
||||
good_ += n.good_;
|
||||
bad_ += n.bad_;
|
||||
duplicate_ += n.duplicate_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -31,7 +31,7 @@ enum class SHAMapNodeType {
|
||||
TnInner = 1,
|
||||
TnTransactionNm = 2, // transaction, no metadata
|
||||
TnTransactionMd = 3, // transaction, with metadata
|
||||
TnAccountState = 4
|
||||
TnAccountState = 4,
|
||||
};
|
||||
|
||||
class SHAMapTreeNode : public IntrusiveRefCounts
|
||||
|
||||
@@ -33,7 +33,7 @@ enum class Validity {
|
||||
/**
|
||||
* Signature and local checks are good / passed.
|
||||
*/
|
||||
Valid
|
||||
Valid,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -133,7 +133,7 @@ enum class ApplyTransactionResult {
|
||||
/**
|
||||
* Should be retried in this ledger
|
||||
*/
|
||||
Retry
|
||||
Retry,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
* Affects the ability of subsequent transactions
|
||||
* to claim a fee. Eg. `SetRegularKey`
|
||||
*/
|
||||
Blocker
|
||||
Blocker,
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
@@ -19,6 +19,7 @@ setUnion(boost::container::flat_set<T>& dst, boost::container::flat_set<T> const
|
||||
return;
|
||||
|
||||
dst.reserve(dst.size() + src.size());
|
||||
// NOLINTNEXTLINE(readability-trailing-comma) fix-it drops comma after `{}`
|
||||
dst.insert(boost::container::ordered_unique_range_t{}, src.begin(), src.end());
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ struct FlowDebugInfo
|
||||
[[nodiscard]] auto
|
||||
duration(std::string const& tag) const
|
||||
{
|
||||
auto i = timePoints.find(tag);
|
||||
auto const i = timePoints.find(tag);
|
||||
if (i == timePoints.end())
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
@@ -119,7 +119,7 @@ struct FlowDebugInfo
|
||||
[[nodiscard]] std::size_t
|
||||
count(std::string const& tag) const
|
||||
{
|
||||
auto i = counts.find(tag);
|
||||
auto const i = counts.find(tag);
|
||||
if (i == counts.end())
|
||||
return 0;
|
||||
return i->second;
|
||||
@@ -151,7 +151,7 @@ struct FlowDebugInfo
|
||||
void
|
||||
inc(std::string const& tag)
|
||||
{
|
||||
auto i = counts.find(tag);
|
||||
auto const i = counts.find(tag);
|
||||
if (i == counts.end())
|
||||
{
|
||||
counts[tag] = 1;
|
||||
@@ -212,24 +212,25 @@ struct FlowDebugInfo
|
||||
};
|
||||
auto writeXrpAmtList = [&writeList](
|
||||
std::vector<EitherAmount> const& amts, char delim = ';') {
|
||||
auto getVal = [](EitherAmount const& a) -> std::string {
|
||||
auto const getVal = [](EitherAmount const& a) -> std::string {
|
||||
return xrpl::to_string(a.get<XRPAmount>());
|
||||
};
|
||||
writeList(amts, getVal, delim);
|
||||
};
|
||||
auto writeIouAmtList = [&writeList](
|
||||
std::vector<EitherAmount> const& amts, char delim = ';') {
|
||||
auto getVal = [](EitherAmount const& a) -> std::string {
|
||||
auto const getVal = [](EitherAmount const& a) -> std::string {
|
||||
return xrpl::to_string(a.get<IOUAmount>());
|
||||
};
|
||||
writeList(amts, getVal, delim);
|
||||
};
|
||||
auto writeIntList = [&writeList](std::vector<size_t> const& vals, char delim = ';') {
|
||||
auto const writeIntList = [&writeList](
|
||||
std::vector<size_t> const& vals, char delim = ';') {
|
||||
// NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)
|
||||
auto getVal = [](size_t const& v) -> size_t const& { return v; };
|
||||
auto const getVal = [](size_t const& v) -> size_t const& { return v; };
|
||||
writeList(vals, getVal);
|
||||
};
|
||||
auto writeNestedIouAmtList =
|
||||
auto const writeNestedIouAmtList =
|
||||
[&ostr, &writeIouAmtList](std::vector<std::vector<EitherAmount>> const& amts) {
|
||||
ostr << '[';
|
||||
if (!amts.empty())
|
||||
@@ -243,7 +244,7 @@ struct FlowDebugInfo
|
||||
}
|
||||
ostr << ']';
|
||||
};
|
||||
auto writeNestedXrpAmtList =
|
||||
auto const writeNestedXrpAmtList =
|
||||
[&ostr, &writeXrpAmtList](std::vector<std::vector<EitherAmount>> const& amts) {
|
||||
ostr << '[';
|
||||
if (!amts.empty())
|
||||
|
||||
@@ -25,7 +25,7 @@ checkFreeze(
|
||||
XRPL_ASSERT(src != dst, "xrpl::checkFreeze : unequal input accounts");
|
||||
|
||||
// check freeze
|
||||
if (auto sle = view.read(keylet::account(dst)))
|
||||
if (auto const sle = view.read(keylet::account(dst)))
|
||||
{
|
||||
if (sle->isFlag(lsfGlobalFreeze))
|
||||
{
|
||||
@@ -33,7 +33,7 @@ checkFreeze(
|
||||
}
|
||||
}
|
||||
|
||||
if (auto sle = view.read(keylet::trustLine(src, dst, currency)))
|
||||
if (auto const sle = view.read(keylet::trustLine(src, dst, currency)))
|
||||
{
|
||||
if (sle->isFlag((dst > src) ? lsfHighFreeze : lsfLowFreeze))
|
||||
{
|
||||
@@ -77,8 +77,8 @@ checkNoRipple(
|
||||
beast::Journal j)
|
||||
{
|
||||
// fetch the ripple lines into and out of this node
|
||||
auto sleIn = view.read(keylet::trustLine(prev, cur, currency));
|
||||
auto sleOut = view.read(keylet::trustLine(cur, next, currency));
|
||||
auto const sleIn = view.read(keylet::trustLine(prev, cur, currency));
|
||||
auto const sleOut = view.read(keylet::trustLine(cur, next, currency));
|
||||
|
||||
if (!sleIn || !sleOut)
|
||||
return terNO_LINE;
|
||||
|
||||
@@ -647,7 +647,7 @@ flow(
|
||||
|
||||
// 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 const sum = [](auto const& col) -> std::optional<std::decay_t<decltype(*col.begin())>> {
|
||||
using TResult = std::decay_t<decltype(*col.begin())>;
|
||||
if (col.empty())
|
||||
return TResult{beast::kZero};
|
||||
@@ -794,7 +794,7 @@ flow(
|
||||
setUnion(ofrsToRmOnFail, ofrsToRm);
|
||||
for (auto const& o : ofrsToRm)
|
||||
{
|
||||
if (auto ok = sb.peek(keylet::offer(o)))
|
||||
if (auto const ok = sb.peek(keylet::offer(o)))
|
||||
offerDelete(sb, ok, j);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,25 +36,44 @@ public:
|
||||
};
|
||||
|
||||
static constexpr std::array<FlagMapping, 7> flagMapping = {
|
||||
{{.setFlag = tfMPTSetCanLock, .immutableFlag = lsifMPTCanLock, .ledgerFlag = lsfMPTCanLock},
|
||||
{.setFlag = tfMPTSetRequireAuth,
|
||||
.immutableFlag = lsifMPTRequireAuth,
|
||||
.ledgerFlag = lsfMPTRequireAuth},
|
||||
{.setFlag = tfMPTSetCanEscrow,
|
||||
.immutableFlag = lsifMPTCanEscrow,
|
||||
.ledgerFlag = lsfMPTCanEscrow},
|
||||
{.setFlag = tfMPTSetCanTrade,
|
||||
.immutableFlag = lsifMPTCanTrade,
|
||||
.ledgerFlag = lsfMPTCanTrade},
|
||||
{.setFlag = tfMPTSetCanTransfer,
|
||||
.immutableFlag = lsifMPTCanTransfer,
|
||||
.ledgerFlag = lsfMPTCanTransfer},
|
||||
{.setFlag = tfMPTSetCanClawback,
|
||||
.immutableFlag = lsifMPTCanClawback,
|
||||
.ledgerFlag = lsfMPTCanClawback},
|
||||
{.setFlag = tfMPTSetCanHoldConfidentialBalance,
|
||||
.immutableFlag = lsifMPTCanHoldConfidentialBalance,
|
||||
.ledgerFlag = lsfMPTCanHoldConfidentialBalance}}};
|
||||
{
|
||||
{
|
||||
.setFlag = tfMPTSetCanLock,
|
||||
.immutableFlag = lsifMPTCanLock,
|
||||
.ledgerFlag = lsfMPTCanLock,
|
||||
},
|
||||
{
|
||||
.setFlag = tfMPTSetRequireAuth,
|
||||
.immutableFlag = lsifMPTRequireAuth,
|
||||
.ledgerFlag = lsfMPTRequireAuth,
|
||||
},
|
||||
{
|
||||
.setFlag = tfMPTSetCanEscrow,
|
||||
.immutableFlag = lsifMPTCanEscrow,
|
||||
.ledgerFlag = lsfMPTCanEscrow,
|
||||
},
|
||||
{
|
||||
.setFlag = tfMPTSetCanTrade,
|
||||
.immutableFlag = lsifMPTCanTrade,
|
||||
.ledgerFlag = lsfMPTCanTrade,
|
||||
},
|
||||
{
|
||||
.setFlag = tfMPTSetCanTransfer,
|
||||
.immutableFlag = lsifMPTCanTransfer,
|
||||
.ledgerFlag = lsfMPTCanTransfer,
|
||||
},
|
||||
{
|
||||
.setFlag = tfMPTSetCanClawback,
|
||||
.immutableFlag = lsifMPTCanClawback,
|
||||
.ledgerFlag = lsfMPTCanClawback,
|
||||
},
|
||||
{
|
||||
.setFlag = tfMPTSetCanHoldConfidentialBalance,
|
||||
.immutableFlag = lsifMPTCanHoldConfidentialBalance,
|
||||
.ledgerFlag = lsfMPTCanHoldConfidentialBalance,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static bool
|
||||
checkExtraFeatures(PreflightContext const& ctx);
|
||||
|
||||
@@ -203,14 +203,15 @@ makeRunner(Workload w, std::string cfg, std::shared_ptr<RunState> rs)
|
||||
}
|
||||
|
||||
std::size_t index = state.thread_index();
|
||||
for (auto _ : state)
|
||||
for (auto const _ : state)
|
||||
{
|
||||
w.iterate(
|
||||
IterateContext{
|
||||
.rs = *rs,
|
||||
.backend = *rs->harness->backend,
|
||||
.index = index,
|
||||
.poolSize = poolSize});
|
||||
.poolSize = poolSize,
|
||||
});
|
||||
index += state.threads();
|
||||
}
|
||||
|
||||
@@ -239,7 +240,7 @@ registerWorkload(BackendConfig const& bc, Workload const& w)
|
||||
|
||||
if (!w.pinToPool)
|
||||
{
|
||||
auto rs = std::make_shared<RunState>();
|
||||
auto const rs = std::make_shared<RunState>();
|
||||
benchmark::RegisterBenchmark(name, makeRunner(w, cfg, rs))
|
||||
->RangeMultiplier(10)
|
||||
->Range(kPoolSizes.front(), kPoolSizes.back())
|
||||
@@ -258,7 +259,7 @@ registerWorkload(BackendConfig const& bc, Workload const& w)
|
||||
if (poolSize % threads != 0)
|
||||
continue;
|
||||
|
||||
auto rs = std::make_shared<RunState>();
|
||||
auto const rs = std::make_shared<RunState>();
|
||||
benchmark::RegisterBenchmark(name, makeRunner(w, cfg, rs))
|
||||
->Arg(poolSize)
|
||||
->Iterations(poolSize / threads)
|
||||
@@ -287,7 +288,7 @@ registerStoreBatch(BackendConfig const& bc)
|
||||
if (numBatches == 0)
|
||||
continue;
|
||||
|
||||
auto rs = std::make_shared<RunState>();
|
||||
auto const rs = std::make_shared<RunState>();
|
||||
benchmark::RegisterBenchmark(
|
||||
name,
|
||||
[rs, cfg](benchmark::State& state) {
|
||||
@@ -303,7 +304,7 @@ registerStoreBatch(BackendConfig const& bc)
|
||||
}
|
||||
|
||||
std::size_t index = 0;
|
||||
for (auto _ : state)
|
||||
for (auto const _ : state)
|
||||
{
|
||||
rs->harness->backend->storeBatch(batches[index % batches.size()]);
|
||||
++index;
|
||||
|
||||
@@ -192,7 +192,7 @@ Workload const kWork{
|
||||
void
|
||||
registerWorkload(BackendConfig const& bc, Workload const& w)
|
||||
{
|
||||
auto rs = std::make_shared<RunState>();
|
||||
auto const rs = std::make_shared<RunState>();
|
||||
std::string const cfg = bc.config;
|
||||
std::string name{kNamePrefix};
|
||||
name += w.name;
|
||||
@@ -206,11 +206,16 @@ registerWorkload(BackendConfig const& bc, Workload const& w)
|
||||
auto const seq = db.earliestLedgerSeq();
|
||||
|
||||
std::size_t index = 0;
|
||||
for (auto _ : state)
|
||||
for (auto const _ : state)
|
||||
{
|
||||
w.iterate(
|
||||
IterateContext{
|
||||
.rs = *rs, .db = db, .seq = seq, .index = index, .poolSize = poolSize});
|
||||
.rs = *rs,
|
||||
.db = db,
|
||||
.seq = seq,
|
||||
.index = index,
|
||||
.poolSize = poolSize,
|
||||
});
|
||||
++index;
|
||||
}
|
||||
benchmark::ClobberMemory();
|
||||
|
||||
@@ -25,7 +25,7 @@ CountedObjects::getCounts(int minimumThreshold) const
|
||||
// might be temporarily less than the actual count.
|
||||
counts.reserve(count_.load());
|
||||
|
||||
for (auto* ctr = head_.load(); ctr != nullptr; ctr = ctr->getNext())
|
||||
for (auto const* ctr = head_.load(); ctr != nullptr; ctr = ctr->getNext())
|
||||
{
|
||||
if (ctr->getCount() >= minimumThreshold)
|
||||
counts.emplace_back(ctr->getName(), ctr->getCount());
|
||||
|
||||
@@ -302,7 +302,7 @@ Logs::format(
|
||||
|
||||
// Attempt to prevent sensitive information from appearing in log files by
|
||||
// redacting it with asterisks.
|
||||
auto scrubber = [&output](char const* token) {
|
||||
auto const scrubber = [&output](char const* token) {
|
||||
auto first = output.find(token);
|
||||
|
||||
// If we have found the specified token, then attempt to isolate the
|
||||
|
||||
Loaded 100 of 646 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user