mirror of
https://github.com/XRPLF/clio.git
synced 2026-06-03 00:36:44 +00:00
chore: Merge develop into release/2.8.0 (#3071)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com> Co-authored-by: Alex Kremer <akremer@ripple.com>
This commit is contained in:
17
.clang-tidy
17
.clang-tidy
@@ -4,6 +4,7 @@ Checks: "-*,
|
||||
bugprone-assert-side-effect,
|
||||
bugprone-bad-signal-to-kill-thread,
|
||||
bugprone-bool-pointer-implicit-conversion,
|
||||
bugprone-capturing-this-in-member-variable,
|
||||
bugprone-casting-through-void,
|
||||
bugprone-chained-comparison,
|
||||
bugprone-compare-pointer-to-member-virtual-function,
|
||||
@@ -23,6 +24,7 @@ Checks: "-*,
|
||||
bugprone-lambda-function-name,
|
||||
bugprone-macro-parentheses,
|
||||
bugprone-macro-repeated-side-effects,
|
||||
bugprone-misleading-setter-of-reference,
|
||||
bugprone-misplaced-operator-in-strlen-in-alloc,
|
||||
bugprone-misplaced-pointer-arithmetic-in-alloc,
|
||||
bugprone-misplaced-widening-cast,
|
||||
@@ -64,6 +66,7 @@ Checks: "-*,
|
||||
bugprone-terminating-continue,
|
||||
bugprone-throw-keyword-missing,
|
||||
bugprone-too-small-loop-variable,
|
||||
bugprone-unchecked-optional-access,
|
||||
bugprone-undefined-memory-manipulation,
|
||||
bugprone-undelegated-constructor,
|
||||
bugprone-unhandled-exception-at-new,
|
||||
@@ -82,6 +85,7 @@ Checks: "-*,
|
||||
cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
cppcoreguidelines-rvalue-reference-param-not-moved,
|
||||
cppcoreguidelines-use-default-member-init,
|
||||
cppcoreguidelines-use-enum-class,
|
||||
cppcoreguidelines-virtual-class-destructor,
|
||||
hicpp-ignored-remove-result,
|
||||
llvm-namespace-comment,
|
||||
@@ -105,8 +109,10 @@ Checks: "-*,
|
||||
modernize-use-emplace,
|
||||
modernize-use-equals-default,
|
||||
modernize-use-equals-delete,
|
||||
modernize-use-nodiscard,
|
||||
modernize-use-override,
|
||||
modernize-use-ranges,
|
||||
modernize-use-scoped-lock,
|
||||
modernize-use-starts-ends-with,
|
||||
modernize-use-std-numbers,
|
||||
modernize-use-using,
|
||||
@@ -118,6 +124,7 @@ Checks: "-*,
|
||||
performance-move-constructor-init,
|
||||
performance-no-automatic-move,
|
||||
performance-trivially-destructible,
|
||||
readability-ambiguous-smartptr-reset-call,
|
||||
readability-avoid-nested-conditional-operator,
|
||||
readability-avoid-return-with-void-value,
|
||||
readability-braces-around-statements,
|
||||
@@ -128,9 +135,9 @@ Checks: "-*,
|
||||
readability-duplicate-include,
|
||||
readability-else-after-return,
|
||||
readability-enum-initial-value,
|
||||
readability-identifier-naming,
|
||||
readability-implicit-bool-conversion,
|
||||
readability-inconsistent-declaration-parameter-name,
|
||||
readability-identifier-naming,
|
||||
readability-make-member-function-const,
|
||||
readability-math-missing-parentheses,
|
||||
readability-misleading-indentation,
|
||||
@@ -149,6 +156,11 @@ Checks: "-*,
|
||||
"
|
||||
|
||||
CheckOptions:
|
||||
bugprone-unsafe-functions.ReportMoreUnsafeFunctions: true
|
||||
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
|
||||
|
||||
misc-include-cleaner.IgnoreHeaders: '.*/(detail|impl)/.*;.*(expected|unexpected).*;.*ranges_lower_bound\.h;time.h;stdlib.h;__chrono/.*;fmt/chrono.h;boost/uuid/uuid_hash.hpp'
|
||||
|
||||
readability-braces-around-statements.ShortStatementLines: 2
|
||||
readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
|
||||
readability-identifier-naming.ClassCase: CamelCase
|
||||
@@ -183,9 +195,6 @@ CheckOptions:
|
||||
readability-identifier-naming.ProtectedMemberSuffix: _
|
||||
readability-identifier-naming.PublicMemberSuffix: ""
|
||||
readability-identifier-naming.FunctionIgnoredRegexp: ".*tag_invoke.*"
|
||||
bugprone-unsafe-functions.ReportMoreUnsafeFunctions: true
|
||||
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
|
||||
misc-include-cleaner.IgnoreHeaders: '.*/(detail|impl)/.*;.*(expected|unexpected).*;.*ranges_lower_bound\.h;time.h;stdlib.h;__chrono/.*;fmt/chrono.h;boost/uuid/uuid_hash.hpp'
|
||||
|
||||
HeaderFilterRegex: '^.*/(src|tests)/.*\.(h|hpp)$'
|
||||
WarningsAsErrors: "*"
|
||||
|
||||
46
.github/actions/create-issue/action.yml
vendored
46
.github/actions/create-issue/action.yml
vendored
@@ -1,46 +0,0 @@
|
||||
name: Create an issue
|
||||
description: Create an issue
|
||||
|
||||
inputs:
|
||||
title:
|
||||
description: Issue title
|
||||
required: true
|
||||
body:
|
||||
description: Issue body
|
||||
required: true
|
||||
labels:
|
||||
description: Comma-separated list of labels
|
||||
required: true
|
||||
default: "bug"
|
||||
assignees:
|
||||
description: Comma-separated list of assignees
|
||||
required: true
|
||||
default: "godexsoft,kuznetsss,PeterChen13579,mathbunnyru"
|
||||
|
||||
outputs:
|
||||
created_issue_id:
|
||||
description: Created issue id
|
||||
value: ${{ steps.create_issue.outputs.created_issue }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Create an issue
|
||||
id: create_issue
|
||||
shell: bash
|
||||
env:
|
||||
ISSUE_BODY: ${{ inputs.body }}
|
||||
ISSUE_ASSIGNEES: ${{ inputs.assignees }}
|
||||
ISSUE_LABELS: ${{ inputs.labels }}
|
||||
ISSUE_TITLE: ${{ inputs.title }}
|
||||
run: |
|
||||
echo -e "${ISSUE_BODY}" > issue.md
|
||||
gh issue create \
|
||||
--assignee "${ISSUE_ASSIGNEES}" \
|
||||
--label "${ISSUE_LABELS}" \
|
||||
--title "${ISSUE_TITLE}" \
|
||||
--body-file ./issue.md \
|
||||
> create_issue.log
|
||||
created_issue="$(sed 's|.*/||' create_issue.log)"
|
||||
echo "created_issue=$created_issue" >> $GITHUB_OUTPUT
|
||||
rm create_issue.log issue.md
|
||||
13
.github/dependabot.yml
vendored
13
.github/dependabot.yml
vendored
@@ -78,19 +78,6 @@ updates:
|
||||
prefix: "ci: [DEPENDABOT] "
|
||||
target-branch: develop
|
||||
|
||||
- package-ecosystem: github-actions
|
||||
directory: .github/actions/create-issue/
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
time: "04:00"
|
||||
timezone: Etc/GMT
|
||||
reviewers:
|
||||
- XRPLF/clio-dev-team
|
||||
commit-message:
|
||||
prefix: "ci: [DEPENDABOT] "
|
||||
target-branch: develop
|
||||
|
||||
- package-ecosystem: github-actions
|
||||
directory: .github/actions/git-common-ancestor/
|
||||
schedule:
|
||||
|
||||
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
@@ -15,7 +15,6 @@ on:
|
||||
|
||||
- ".github/actions/**"
|
||||
- "!.github/actions/build-docker-image/**"
|
||||
- "!.github/actions/create-issue/**"
|
||||
|
||||
- CMakeLists.txt
|
||||
- conanfile.py
|
||||
|
||||
11
.github/workflows/check-libxrpl.yml
vendored
11
.github/workflows/check-libxrpl.yml
vendored
@@ -33,6 +33,9 @@ jobs:
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
- name: Print build environment
|
||||
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
|
||||
|
||||
- name: Update libXRPL version requirement
|
||||
run: |
|
||||
sed -i.bak -E "s|'xrpl/[a-zA-Z0-9\\.\\-]+'|'xrpl/${{ github.event.client_payload.conan_ref }}'|g" conanfile.py
|
||||
@@ -95,14 +98,12 @@ jobs:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Create an issue
|
||||
uses: ./.github/actions/create-issue
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
uses: XRPLF/actions/create-issue@fbcc16eb7f20dc3199eaf1aed0d3523a5ba9008c
|
||||
with:
|
||||
labels: "compatibility,bug"
|
||||
title: "Proposed libXRPL check failed"
|
||||
body: >
|
||||
Clio build or tests failed against `libXRPL ${{ github.event.client_payload.conan_ref }}`.
|
||||
|
||||
PR: ${{ github.event.client_payload.pr_url }}
|
||||
Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/
|
||||
labels: "compatibility,bug"
|
||||
assignees: "godexsoft,kuznetsss,mathbunnyru"
|
||||
|
||||
161
.github/workflows/clang-tidy.yml
vendored
161
.github/workflows/clang-tidy.yml
vendored
@@ -1,16 +1,22 @@
|
||||
name: Clang-tidy check
|
||||
name: Run clang-tidy on files
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
schedule:
|
||||
- cron: "0 9 * * 1-5"
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches: [develop]
|
||||
paths:
|
||||
- .github/workflows/clang-tidy.yml
|
||||
|
||||
- CMakeLists.txt
|
||||
- conanfile.py
|
||||
- conan.lock
|
||||
- "cmake/**"
|
||||
- "src/**"
|
||||
- "tests/**"
|
||||
- "benchmarks/**"
|
||||
|
||||
- .clang_tidy
|
||||
|
||||
concurrency:
|
||||
@@ -19,19 +25,34 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
BUILD_DIR: build
|
||||
BUILD_TYPE: Debug # Debug so that ASSERTS and such participate in clang-tidy check
|
||||
|
||||
OUTPUT_FILE: clang-tidy-output.txt
|
||||
DIFF_FILE: clang-tidy-git-diff.txt
|
||||
ISSUE_FILE: clang-tidy-issue.md
|
||||
|
||||
CONAN_PROFILE: clang
|
||||
LLVM_TOOLS_VERSION: 20
|
||||
LLVM_TOOLS_VERSION: 21
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
clang_tidy:
|
||||
if: github.event_name != 'push' || contains(github.event.head_commit.message, 'clang-tidy auto fixes')
|
||||
determine-files:
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
permissions:
|
||||
contents: read
|
||||
uses: XRPLF/actions/.github/workflows/determine-tidy-files.yml@12f5dbc98a2260259a66970e57fa4d26fb7f285c
|
||||
|
||||
run-clang-tidy:
|
||||
name: Run clang tidy
|
||||
needs: [determine-files]
|
||||
if: ${{ always() && !cancelled() && (github.event_name != 'pull_request' || needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.clang_tidy_config_changed == 'true') }}
|
||||
runs-on: heavy
|
||||
container:
|
||||
image: ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696
|
||||
image: ghcr.io/xrplf/clio-ci:f174b47f4909ae41b80406d836ab52adc39eacc6
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -40,37 +61,54 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
- name: Print build environment
|
||||
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
|
||||
|
||||
- name: Run conan
|
||||
uses: ./.github/actions/conan
|
||||
with:
|
||||
build_dir: ${{ env.BUILD_DIR }}
|
||||
conan_profile: ${{ env.CONAN_PROFILE }}
|
||||
build_type: ${{ env.BUILD_TYPE }}
|
||||
|
||||
- name: Run CMake
|
||||
uses: ./.github/actions/cmake
|
||||
with:
|
||||
build_dir: ${{ env.BUILD_DIR }}
|
||||
conan_profile: ${{ env.CONAN_PROFILE }}
|
||||
build_type: ${{ env.BUILD_TYPE }}
|
||||
|
||||
- name: Get number of processors
|
||||
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf
|
||||
id: nproc
|
||||
|
||||
- name: Run clang-tidy (several times)
|
||||
- name: Run clang tidy
|
||||
continue-on-error: true
|
||||
id: clang_tidy
|
||||
id: run_clang_tidy
|
||||
env:
|
||||
TARGETS: ${{ (needs.determine-files.outputs.clang_tidy_config_changed != 'true' && github.event_name == 'pull_request') && needs.determine-files.outputs.cpp_changed_files || 'benchmarks src tests' }}
|
||||
run: |
|
||||
# We run clang-tidy several times, because some fixes may enable new fixes in subsequent runs.
|
||||
CLANG_TIDY_COMMAND="run-clang-tidy-${{ env.LLVM_TOOLS_VERSION }} -p build -j ${{ steps.nproc.outputs.nproc }} -fix -quiet"
|
||||
${CLANG_TIDY_COMMAND} ||
|
||||
${CLANG_TIDY_COMMAND} ||
|
||||
${CLANG_TIDY_COMMAND}
|
||||
set -o pipefail
|
||||
run-clang-tidy-${{ env.LLVM_TOOLS_VERSION }} -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" -quiet -fix -allow-no-checks ${TARGETS} 2>&1 | tee "${OUTPUT_FILE}"
|
||||
|
||||
- name: Print errors
|
||||
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
|
||||
run: |
|
||||
sed '/error\||/!d' "${OUTPUT_FILE}"
|
||||
|
||||
- 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
|
||||
with:
|
||||
path: ${{ env.OUTPUT_FILE }}
|
||||
archive: false
|
||||
retention-days: 30
|
||||
|
||||
- name: Check for changes
|
||||
id: files_changed
|
||||
@@ -78,24 +116,76 @@ jobs:
|
||||
run: |
|
||||
git diff --exit-code
|
||||
|
||||
- name: Fix local includes and clang-format style
|
||||
- name: Fix style
|
||||
if: ${{ steps.files_changed.outcome != 'success' }}
|
||||
run: |
|
||||
pre-commit run --all-files fix-local-includes || true
|
||||
pre-commit run --all-files clang-format || true
|
||||
pre-commit run --all-files || true
|
||||
|
||||
- name: Create an issue
|
||||
if: ${{ (steps.clang_tidy.outcome != 'success' || steps.files_changed.outcome != 'success') && github.event_name != 'pull_request' }}
|
||||
id: create_issue
|
||||
uses: ./.github/actions/create-issue
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
- name: Generate git diff
|
||||
if: ${{ steps.files_changed.outcome != 'success' }}
|
||||
run: |
|
||||
git diff | tee "${DIFF_FILE}"
|
||||
|
||||
- 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
|
||||
with:
|
||||
title: "Clang-tidy found bugs in code 🐛"
|
||||
body: >
|
||||
Clang-tidy found issues in the code:
|
||||
path: ${{ env.DIFF_FILE }}
|
||||
archive: false
|
||||
retention-days: 30
|
||||
|
||||
List of the issues found: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/
|
||||
- name: Write issue header
|
||||
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
|
||||
run: |
|
||||
cat > "${ISSUE_FILE}" <<EOF
|
||||
## Clang-tidy Check Failed
|
||||
|
||||
### Clang-tidy Output:
|
||||
\`\`\`
|
||||
EOF
|
||||
|
||||
- name: Append clang-tidy output to issue body (filter for errors and warnings)
|
||||
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
|
||||
run: |
|
||||
if [ -f "${OUTPUT_FILE}" ]; then
|
||||
# Extract lines containing 'error:', 'warning:', or 'note:'
|
||||
grep -E '(error:|warning:|note:)' "${OUTPUT_FILE}" > filtered-output.txt || true
|
||||
|
||||
# If filtered output is empty, use original (might be a different error format)
|
||||
if [ ! -s filtered-output.txt ]; then
|
||||
cp "${OUTPUT_FILE}" filtered-output.txt
|
||||
fi
|
||||
|
||||
# Truncate if too large
|
||||
head -c 60000 filtered-output.txt >> "${ISSUE_FILE}"
|
||||
if [ "$(wc -c < filtered-output.txt)" -gt 60000 ]; then
|
||||
echo "" >> "${ISSUE_FILE}"
|
||||
echo "... (output truncated, see artifacts for full output)" >> "${ISSUE_FILE}"
|
||||
fi
|
||||
|
||||
rm filtered-output.txt
|
||||
else
|
||||
echo "No output file found" >> "${ISSUE_FILE}"
|
||||
fi
|
||||
|
||||
- name: Append issue footer
|
||||
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
|
||||
run: |
|
||||
cat >> "${ISSUE_FILE}" <<EOF
|
||||
\`\`\`
|
||||
|
||||
---
|
||||
*This issue was automatically created by the clang-tidy workflow.*
|
||||
EOF
|
||||
|
||||
- name: Create issue
|
||||
if: ${{ steps.run_clang_tidy.outcome != 'success' && github.event_name != 'pull_request' }}
|
||||
uses: XRPLF/actions/create-issue@fbcc16eb7f20dc3199eaf1aed0d3523a5ba9008c
|
||||
with:
|
||||
title: "Clang-tidy check failed"
|
||||
body_file: ${{ env.ISSUE_FILE }}
|
||||
labels: "bug"
|
||||
assignees: "godexsoft,mathbunnyru"
|
||||
|
||||
- uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7.0.0
|
||||
if: ${{ steps.files_changed.outcome != 'success' && github.event_name != 'pull_request' }}
|
||||
@@ -118,9 +208,14 @@ jobs:
|
||||
branch-suffix: timestamp
|
||||
delete-branch: true
|
||||
title: "style: clang-tidy auto fixes"
|
||||
body: "Fixes #${{ steps.create_issue.outputs.created_issue_id }}. Please review and commit clang-tidy fixes."
|
||||
reviewers: "godexsoft,kuznetsss,PeterChen13579,mathbunnyru"
|
||||
body: >
|
||||
Fixes #${{ steps.create_issue.outputs.issue_number }}.
|
||||
|
||||
Please review and commit clang-tidy fixes.
|
||||
reviewers: "godexsoft,kuznetsss,mathbunnyru"
|
||||
|
||||
- name: Fail the job
|
||||
if: ${{ steps.clang_tidy.outcome != 'success' || steps.files_changed.outcome != 'success' }}
|
||||
run: exit 1
|
||||
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
|
||||
run: |
|
||||
echo "Clang-tidy check failed!"
|
||||
exit 1
|
||||
|
||||
3
.github/workflows/docs.yml
vendored
3
.github/workflows/docs.yml
vendored
@@ -31,6 +31,9 @@ jobs:
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
- name: Print build environment
|
||||
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
|
||||
|
||||
- name: Create build directory
|
||||
run: mkdir build_docs
|
||||
|
||||
|
||||
11
.github/workflows/nightly.yml
vendored
11
.github/workflows/nightly.yml
vendored
@@ -172,12 +172,9 @@ jobs:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Create an issue
|
||||
uses: ./.github/actions/create-issue
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
uses: XRPLF/actions/create-issue@fbcc16eb7f20dc3199eaf1aed0d3523a5ba9008c
|
||||
with:
|
||||
title: "Nightly release failed 🌙"
|
||||
body: >
|
||||
Nightly release failed:
|
||||
|
||||
Workflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/
|
||||
body: ""
|
||||
labels: "bug"
|
||||
assignees: "godexsoft,kuznetsss,mathbunnyru"
|
||||
|
||||
4
.github/workflows/pre-commit-autoupdate.yml
vendored
4
.github/workflows/pre-commit-autoupdate.yml
vendored
@@ -12,11 +12,11 @@ on:
|
||||
|
||||
jobs:
|
||||
auto-update:
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit-autoupdate.yml@a249154199805d6809359fe99fa8ba09dd804e3d
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit-autoupdate.yml@5e942d61bf32f7557a7c159cfac4712a687b3e3a
|
||||
with:
|
||||
sign_commit: true
|
||||
committer: "Clio CI <skuznetsov@ripple.com>"
|
||||
reviewers: "godexsoft,kuznetsss,PeterChen13579,mathbunnyru"
|
||||
reviewers: "godexsoft,kuznetsss,mathbunnyru"
|
||||
secrets:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.ACTIONS_GPG_PRIVATE_KEY }}
|
||||
GPG_PASSPHRASE: ${{ secrets.ACTIONS_GPG_PASSPHRASE }}
|
||||
|
||||
2
.github/workflows/pre-commit.yml
vendored
2
.github/workflows/pre-commit.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
|
||||
jobs:
|
||||
run-hooks:
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@9307df762265e15c745ddcdb38a581c989f7f349
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@5e942d61bf32f7557a7c159cfac4712a687b3e3a
|
||||
with:
|
||||
runs_on: heavy
|
||||
container: '{ "image": "ghcr.io/xrplf/clio-pre-commit:14342e087ceb8b593027198bf9ef06a43833c696" }'
|
||||
|
||||
3
.github/workflows/reusable-build.yml
vendored
3
.github/workflows/reusable-build.yml
vendored
@@ -99,6 +99,9 @@ jobs:
|
||||
with:
|
||||
enable_ccache: ${{ inputs.download_ccache }}
|
||||
|
||||
- name: Print build environment
|
||||
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
|
||||
|
||||
- name: Setup conan on macOS
|
||||
if: ${{ runner.os == 'macOS' }}
|
||||
run: ./.github/scripts/conan/init.sh
|
||||
|
||||
12
.github/workflows/reusable-test.yml
vendored
12
.github/workflows/reusable-test.yml
vendored
@@ -68,16 +68,12 @@ jobs:
|
||||
|
||||
- name: Create an issue
|
||||
if: ${{ steps.run_clio_tests.outcome == 'failure' && endsWith(inputs.conan_profile, 'san') }}
|
||||
uses: ./.github/actions/create-issue
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
uses: XRPLF/actions/create-issue@fbcc16eb7f20dc3199eaf1aed0d3523a5ba9008c
|
||||
with:
|
||||
labels: "bug"
|
||||
title: "[${{ inputs.conan_profile }}] reported issues"
|
||||
body: >
|
||||
Clio tests failed one or more sanitizer checks when built with `${{ inputs.conan_profile }}`.
|
||||
|
||||
Workflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/
|
||||
body: "Clio tests failed one or more sanitizer checks when built with `${{ inputs.conan_profile }}`."
|
||||
labels: "bug"
|
||||
assignees: "godexsoft,kuznetsss,mathbunnyru"
|
||||
|
||||
- name: Fail the job if clio_tests failed
|
||||
if: ${{ steps.run_clio_tests.outcome == 'failure' }}
|
||||
|
||||
1
.github/workflows/sanitizers.yml
vendored
1
.github/workflows/sanitizers.yml
vendored
@@ -14,7 +14,6 @@ on:
|
||||
|
||||
- ".github/actions/**"
|
||||
- "!.github/actions/build-docker-image/**"
|
||||
- "!.github/actions/create-issue/**"
|
||||
|
||||
- CMakeLists.txt
|
||||
- conanfile.py
|
||||
|
||||
3
.github/workflows/upload-conan-deps.yml
vendored
3
.github/workflows/upload-conan-deps.yml
vendored
@@ -82,6 +82,9 @@ jobs:
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
- name: Print build environment
|
||||
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
|
||||
|
||||
- name: Setup conan on macOS
|
||||
if: ${{ runner.os == 'macOS' }}
|
||||
run: ./.github/scripts/conan/init.sh
|
||||
|
||||
@@ -29,7 +29,7 @@ repos:
|
||||
|
||||
# Autoformat: YAML, JSON, Markdown, etc.
|
||||
- repo: https://github.com/rbubley/mirrors-prettier
|
||||
rev: c2bc67fe8f8f549cc489e00ba8b45aa18ee713b1 # frozen: v3.8.1
|
||||
rev: 515f543f5718ebfd6ce22e16708bb32c68ff96e1 # frozen: v3.8.3
|
||||
hooks:
|
||||
- id: prettier
|
||||
|
||||
@@ -40,7 +40,7 @@ repos:
|
||||
exclude: LICENSE.md
|
||||
|
||||
- repo: https://github.com/hadolint/hadolint
|
||||
rev: 4e697ba704fd23b2409b947a319c19c3ee54d24f # frozen: v2.14.0
|
||||
rev: 57e1618d78fd469a92c1e584e8c9313024656623 # frozen: v2.14.0
|
||||
hooks:
|
||||
- id: hadolint-docker
|
||||
# hadolint-docker is a special hook that runs hadolint in a Docker container
|
||||
@@ -64,7 +64,7 @@ repos:
|
||||
- id: black
|
||||
|
||||
- repo: https://github.com/scop/pre-commit-shfmt
|
||||
rev: e26a818fd47b4f33cefa99035d1265b0849f4b47 # frozen: v3.13.0-1
|
||||
rev: 05c1426671b9237fb5e1444dd63aa5731bec0dfb # frozen: v3.13.1-1
|
||||
hooks:
|
||||
- id: shfmt
|
||||
args: ["-i", "4", "--write"]
|
||||
@@ -94,14 +94,14 @@ repos:
|
||||
language: script
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: 07a0f7667439f60724899f6ae288e4a4f572e0e1 # frozen: v22.1.2
|
||||
rev: 39233709be54124a7371a50cbfc5325bd4fb9d90 # frozen: v22.1.4
|
||||
hooks:
|
||||
- id: clang-format
|
||||
args: [--style=file]
|
||||
types: [c++]
|
||||
|
||||
- repo: https://github.com/BlankSpruce/gersemi
|
||||
rev: 79ddf2c9f3a84d766fce4e39fb2f83eac62b34f7 # frozen: 0.26.1
|
||||
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
|
||||
rev: fc2d0aefdd73b719180177a2d4a7a56cef4d3ab6 # frozen: 0.27.2
|
||||
hooks:
|
||||
- id: gersemi
|
||||
|
||||
|
||||
22
conan.lock
22
conan.lock
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"version": "0.5",
|
||||
"requires": [
|
||||
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075",
|
||||
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809",
|
||||
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
|
||||
"xrpl/3.1.0#3d408ab8c8020014fa7dd52bc7cc7ea8%1769706825.165",
|
||||
"xrpl/3.1.3#eabc6838b4553671bdde4b3aa1f8e3e6%1778495466.414",
|
||||
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1765850149.926",
|
||||
"spdlog/1.17.0#bcbaaf7147bda6ad24ffbd1ac3d7142c%1768312128.781",
|
||||
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1765850149.46",
|
||||
"soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231",
|
||||
"re2/20230301#ca3b241baec15bd31ea9187150e0b333%1765850148.103",
|
||||
"rapidjson/cci.20220822#1b9d8c2256876a154172dc5cfbe447c6%1754325007.656",
|
||||
"protobuf/3.21.12#44ee56c0a6eea0c19aeeaca680370b88%1764175361.456",
|
||||
"openssl/1.1.1w#a8f0792d7c5121b954578a7149d23e03%1756223730.729",
|
||||
"nudb/2.0.9#0432758a24204da08fee953ec9ea03cb%1769436073.32",
|
||||
"nudb/2.0.9#11149c73f8f2baff9a0198fe25971fc7%1775040983.408",
|
||||
"minizip/1.2.13#9e87d57804bd372d6d1e32b1871517a3%1754325004.374",
|
||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914",
|
||||
"libuv/1.46.0#dc28c1f653fa197f00db5b577a6f6011%1754325003.592",
|
||||
@@ -25,18 +25,18 @@
|
||||
"doctest/2.4.11#a4211dfc329a16ba9f280f9574025659%1756234220.819",
|
||||
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772",
|
||||
"cassandra-cpp-driver/2.17.0#bd3934138689482102c265d01288a316%1764175359.611",
|
||||
"c-ares/1.34.5#5581c2b62a608b40bb85d965ab3ec7c8%1765850144.336",
|
||||
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1774439234.681",
|
||||
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1765850143.837",
|
||||
"boost/1.83.0#91d8b1572534d2c334d6790e3c34d0c1%1764175359.61",
|
||||
"benchmark/1.9.4#ce4403f7a24d3e1f907cd9da4b678be4%1754578869.672",
|
||||
"abseil/20230802.1#90ba607d4ee8fb5fb157c3db540671fc%1764175359.429"
|
||||
],
|
||||
"build_requires": [
|
||||
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075",
|
||||
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809",
|
||||
"protobuf/3.21.12#44ee56c0a6eea0c19aeeaca680370b88%1764175361.456",
|
||||
"cmake/4.2.0#ae0a44f44a1ef9ab68fd4b3e9a1f8671%1765850153.937",
|
||||
"cmake/3.31.10#313d16a1aa16bbdb2ca0792467214b76%1765850153.479",
|
||||
"b2/5.3.3#107c15377719889654eb9a162a673975%1765850144.355"
|
||||
"cmake/4.3.0#b939a42e98f593fb34d3a8c5cc860359%1774439249.183",
|
||||
"cmake/3.31.11#f325c933f618a1fcebc1e1c0babfd1ba%1774439246.719",
|
||||
"b2/5.4.2#ffd6084a119587e70f11cd45d1a386e2%1774439233.447"
|
||||
],
|
||||
"python_requires": [],
|
||||
"overrides": {
|
||||
@@ -51,10 +51,10 @@
|
||||
"lz4/1.9.4": [
|
||||
"lz4/1.10.0"
|
||||
],
|
||||
"boost/1.90.0": [
|
||||
"boost/[>=1.83.0 <1.91.0]": [
|
||||
"boost/1.83.0"
|
||||
],
|
||||
"sqlite3/3.44.2": [
|
||||
"sqlite3/[>=3.44 <4]": [
|
||||
"sqlite3/3.49.1"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@ class ClioConan(ConanFile):
|
||||
"openssl/1.1.1w",
|
||||
"protobuf/3.21.12",
|
||||
"spdlog/1.17.0",
|
||||
"xrpl/3.1.0",
|
||||
"xrpl/3.1.3",
|
||||
"zlib/1.3.1",
|
||||
]
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ RUN pip install -q --no-cache-dir \
|
||||
pre-commit
|
||||
|
||||
# Install LLVM tools
|
||||
ARG LLVM_TOOLS_VERSION=20
|
||||
ARG LLVM_TOOLS_VERSION=21
|
||||
|
||||
RUN echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${LLVM_TOOLS_VERSION} main" >> /etc/apt/sources.list \
|
||||
&& wget --progress=dot:giga -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
|
||||
@@ -14,6 +14,7 @@ The image is based on Ubuntu 20.04 and contains:
|
||||
- GDB 17.1
|
||||
- gh 2.83.2
|
||||
- git-cliff 2.11.0
|
||||
- LLVM Tools 21
|
||||
- mold 2.40.4
|
||||
- Ninja 1.13.2
|
||||
- Python 3.8
|
||||
|
||||
@@ -28,7 +28,7 @@ parseConfig(std::string_view configPath)
|
||||
}
|
||||
auto const errors = getClioConfig().parse(json.value());
|
||||
if (errors.has_value()) {
|
||||
for (auto const& err : errors.value()) {
|
||||
for (auto const& err : *errors) {
|
||||
std::cerr << "Issues found in provided config '" << configPath << "':\n";
|
||||
std::cerr << err.error << std::endl;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ MetricsHandler::operator()(
|
||||
ASSERT(onTaskComplete.has_value(), "Coroutine group can't be full");
|
||||
|
||||
bool const postSuccessful = workQueue_.get().postCoro(
|
||||
[this, &request, &response, &onTaskComplete = onTaskComplete.value(), &connectionMetadata](
|
||||
[this, &request, &response, &onTaskComplete = *onTaskComplete, &connectionMetadata]( // NOLINT(bugprone-unchecked-optional-access)
|
||||
boost::asio::yield_context
|
||||
) mutable {
|
||||
auto const maybeHttpRequest = request.asHttpRequest();
|
||||
@@ -94,7 +94,7 @@ MetricsHandler::operator()(
|
||||
httpRequest, adminVerifier_->isAdmin(httpRequest, connectionMetadata.ip())
|
||||
);
|
||||
ASSERT(maybeResponse.has_value(), "Got unexpected request for Prometheus");
|
||||
response = web::ng::Response{std::move(maybeResponse).value(), request};
|
||||
response = web::ng::Response{*std::move(maybeResponse), request};
|
||||
// notify the coroutine group that the foreign task is done
|
||||
onTaskComplete();
|
||||
},
|
||||
@@ -114,7 +114,7 @@ MetricsHandler::operator()(
|
||||
coroutineGroup.asyncWait(yield);
|
||||
ASSERT(response.has_value(), "Woke up coroutine without setting response");
|
||||
|
||||
return std::move(response).value();
|
||||
return *std::move(response); // NOLINT(bugprone-unchecked-optional-access)
|
||||
}
|
||||
|
||||
web::ng::Response
|
||||
|
||||
@@ -108,7 +108,7 @@ tag_invoke(boost::json::value_to_tag<ClioNode>, boost::json::value const& jv)
|
||||
// Json data doesn't contain uuid so leaving it empty here. It will be filled outside of
|
||||
// this parsing
|
||||
.uuid = std::make_shared<boost::uuids::uuid>(),
|
||||
.updateTime = updateTime.value(),
|
||||
.updateTime = *updateTime,
|
||||
.dbRole = dbRole,
|
||||
.etlStarted = etlStarted,
|
||||
.cacheIsFull = cacheIsFull,
|
||||
|
||||
@@ -159,6 +159,7 @@ struct Amendments {
|
||||
REGISTER(fix1523);
|
||||
REGISTER(fix1528);
|
||||
REGISTER(fixBatchInnerSigs);
|
||||
REGISTER(fixCleanup3_1_3);
|
||||
// NOLINTEND(readability-identifier-naming)
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
*
|
||||
* @return The report
|
||||
*/
|
||||
boost::json::object
|
||||
[[nodiscard]] boost::json::object
|
||||
report() const;
|
||||
|
||||
private:
|
||||
@@ -152,7 +152,7 @@ private:
|
||||
void
|
||||
registerError(std::uint64_t count);
|
||||
|
||||
boost::json::object
|
||||
[[nodiscard]] boost::json::object
|
||||
report() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -188,7 +188,7 @@ BackendInterface::fetchBookOffers(
|
||||
auto mid2 = std::chrono::system_clock::now();
|
||||
numSucc++;
|
||||
succMillis += getMillis(mid2 - mid1);
|
||||
if (!offerDir || offerDir->key >= bookEnd) {
|
||||
if (not offerDir.has_value() || offerDir->key >= bookEnd) {
|
||||
LOG(log_.trace()) << "offerDir.has_value() " << offerDir.has_value() << " breaking";
|
||||
break;
|
||||
}
|
||||
@@ -208,8 +208,10 @@ BackendInterface::fetchBookOffers(
|
||||
auto nextKey = ripple::keylet::page(uTipIndex, next);
|
||||
auto nextDir = fetchLedgerObject(nextKey.key, ledgerSequence, yield);
|
||||
ASSERT(nextDir.has_value(), "Next dir must exist");
|
||||
// NOLINTBEGIN(bugprone-unchecked-optional-access)
|
||||
offerDir->blob = *nextDir;
|
||||
offerDir->key = nextKey.key;
|
||||
// NOLINTEND(bugprone-unchecked-optional-access)
|
||||
}
|
||||
auto mid3 = std::chrono::system_clock::now();
|
||||
pageMillis += getMillis(mid3 - mid2);
|
||||
@@ -312,6 +314,7 @@ BackendInterface::fetchLedgerPage(
|
||||
return (cursor ? *cursor : kFIRST_KEY);
|
||||
}();
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
std::uint32_t const seq = outOfOrder ? range_->maxSequence : ledgerSequence;
|
||||
auto succ = fetchSuccessorKey(curCursor, seq, yield);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
/**
|
||||
* @return The error message as a C string
|
||||
*/
|
||||
char const*
|
||||
[[nodiscard]] char const*
|
||||
what() const throw() override
|
||||
{
|
||||
return "Database read timed out. Please retry the request";
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
NFTsAndCursor
|
||||
[[nodiscard]] NFTsAndCursor
|
||||
fetchNFTsByIssuer(
|
||||
ripple::AccountID const& issuer,
|
||||
std::optional<std::uint32_t> const& taxon,
|
||||
@@ -190,7 +190,7 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<ripple::uint256>
|
||||
[[nodiscard]] std::vector<ripple::uint256>
|
||||
fetchAccountRoots(
|
||||
std::uint32_t number,
|
||||
std::uint32_t pageSize,
|
||||
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
NFTsAndCursor
|
||||
[[nodiscard]] NFTsAndCursor
|
||||
fetchNFTsByIssuer(
|
||||
ripple::AccountID const& issuer,
|
||||
std::optional<std::uint32_t> const& taxon,
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
* @param yield The coroutine context.
|
||||
* @return A vector of ripple::uint256 representing the account root hashes.
|
||||
*/
|
||||
std::vector<ripple::uint256>
|
||||
[[nodiscard]] std::vector<ripple::uint256>
|
||||
fetchAccountRoots(
|
||||
[[maybe_unused]] std::uint32_t number,
|
||||
[[maybe_unused]] std::uint32_t pageSize,
|
||||
@@ -175,7 +175,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ripple::uint256>
|
||||
[[nodiscard]] std::vector<ripple::uint256>
|
||||
fetchNFTIDsByTaxon(
|
||||
ripple::AccountID const& issuer,
|
||||
std::uint32_t const taxon,
|
||||
@@ -198,7 +198,7 @@ private:
|
||||
return nftIDs;
|
||||
}
|
||||
|
||||
std::vector<ripple::uint256>
|
||||
[[nodiscard]] std::vector<ripple::uint256>
|
||||
fetchNFTIDsWithoutTaxon(
|
||||
ripple::AccountID const& issuer,
|
||||
std::uint32_t const limit,
|
||||
@@ -242,7 +242,7 @@ private:
|
||||
* @brief Takes a list of NFT IDs, fetches their full data, and assembles the final result with
|
||||
* a cursor.
|
||||
*/
|
||||
NFTsAndCursor
|
||||
[[nodiscard]] NFTsAndCursor
|
||||
populateNFTsAndCreateCursor(
|
||||
std::vector<ripple::uint256> const& nftIDs,
|
||||
std::uint32_t const ledgerSequence,
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
* @param seq The sequence to fetch for
|
||||
* @return If found in cache, will return the cached Blob; otherwise nullopt is returned
|
||||
*/
|
||||
virtual std::optional<Blob>
|
||||
[[nodiscard]] virtual std::optional<Blob>
|
||||
get(ripple::uint256 const& key, uint32_t seq) const = 0;
|
||||
|
||||
/**
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
* @param seq The sequence to fetch for
|
||||
* @return If found in deleted cache, will return the cached Blob; otherwise nullopt is returned
|
||||
*/
|
||||
virtual std::optional<Blob>
|
||||
[[nodiscard]] virtual std::optional<Blob>
|
||||
getDeleted(ripple::uint256 const& key, uint32_t seq) const = 0;
|
||||
|
||||
/**
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
* @param seq The sequence to fetch for
|
||||
* @return If found in cache, will return the cached successor; otherwise nullopt is returned
|
||||
*/
|
||||
virtual std::optional<LedgerObject>
|
||||
[[nodiscard]] virtual std::optional<LedgerObject>
|
||||
getSuccessor(ripple::uint256 const& key, uint32_t seq) const = 0;
|
||||
|
||||
/**
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
* @param seq The sequence to fetch for
|
||||
* @return If found in cache, will return the cached predcessor; otherwise nullopt is returned
|
||||
*/
|
||||
virtual std::optional<LedgerObject>
|
||||
[[nodiscard]] virtual std::optional<LedgerObject>
|
||||
getPredecessor(ripple::uint256 const& key, uint32_t seq) const = 0;
|
||||
|
||||
/**
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
/**
|
||||
* @return true if the cache is disabled; false otherwise
|
||||
*/
|
||||
virtual bool
|
||||
[[nodiscard]] virtual bool
|
||||
isDisabled() const = 0;
|
||||
|
||||
/**
|
||||
@@ -117,33 +117,33 @@ public:
|
||||
/**
|
||||
* @return The latest ledger sequence for which cache is available.
|
||||
*/
|
||||
virtual uint32_t
|
||||
[[nodiscard]] virtual uint32_t
|
||||
latestLedgerSequence() const = 0;
|
||||
|
||||
/**
|
||||
* @return true if the cache has all data for the most recent ledger; false otherwise
|
||||
*/
|
||||
virtual bool
|
||||
[[nodiscard]] virtual bool
|
||||
isFull() const = 0;
|
||||
|
||||
/**
|
||||
* @return The total size of the cache.
|
||||
*/
|
||||
virtual size_t
|
||||
[[nodiscard]] virtual size_t
|
||||
size() const = 0;
|
||||
|
||||
/**
|
||||
* @return A number representing the success rate of hitting an object in the cache versus
|
||||
* missing it.
|
||||
*/
|
||||
virtual float
|
||||
[[nodiscard]] virtual float
|
||||
getObjectHitRate() const = 0;
|
||||
|
||||
/**
|
||||
* @return A number representing the success rate of hitting a successor in the cache versus
|
||||
* missing it.
|
||||
*/
|
||||
virtual float
|
||||
[[nodiscard]] virtual float
|
||||
getSuccessorHitRate() const = 0;
|
||||
|
||||
/**
|
||||
|
||||
@@ -564,7 +564,7 @@ public:
|
||||
<< ", key = " << ripple::to_string(key);
|
||||
if (auto const res = executor_.read(yield, schema_->selectObject, key, sequence); res) {
|
||||
if (auto const result = res->template get<Blob, std::uint32_t>(); result) {
|
||||
auto [_, seq] = result.value();
|
||||
auto [_, seq] = *result;
|
||||
return seq;
|
||||
}
|
||||
LOG(log_.debug()) << "Could not fetch ledger object sequence - no rows";
|
||||
@@ -923,14 +923,15 @@ public:
|
||||
record.tokenID
|
||||
));
|
||||
statements.push_back(schema_->insertNFTURI.bind(
|
||||
record.tokenID, record.ledgerSequence, record.uri.value()
|
||||
record.tokenID, record.ledgerSequence, *record.uri
|
||||
));
|
||||
}
|
||||
} else {
|
||||
// only uri changed, we update the uri table only
|
||||
statements.push_back(schema_->insertNFTURI.bind(
|
||||
record.tokenID, record.ledgerSequence, record.uri.value()
|
||||
));
|
||||
statements.push_back(
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
schema_->insertNFTURI.bind(record.tokenID, record.ledgerSequence, *record.uri)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1002,7 +1003,7 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not maybeSuccess.value()) {
|
||||
if (not *maybeSuccess) {
|
||||
LOG(log_.warn()) << "Update failed. Checking if DB state is what we expect";
|
||||
|
||||
// error may indicate that another writer wrote something.
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
/**
|
||||
* @return The final error message as a std::string
|
||||
*/
|
||||
std::string
|
||||
[[nodiscard]] std::string
|
||||
message() const
|
||||
{
|
||||
return message_;
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
/**
|
||||
* @return The error code
|
||||
*/
|
||||
uint32_t
|
||||
[[nodiscard]] uint32_t
|
||||
code() const
|
||||
{
|
||||
return code_;
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
/**
|
||||
* @return true if the wrapped error is considered a timeout; false otherwise
|
||||
*/
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isTimeout() const
|
||||
{
|
||||
return code_ == CASS_ERROR_LIB_NO_HOSTS_AVAILABLE or
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
/**
|
||||
* @return true if the wrapped error is an invalid query; false otherwise
|
||||
*/
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isInvalidQuery() const
|
||||
{
|
||||
return code_ == CASS_ERROR_SERVER_INVALID_QUERY;
|
||||
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
*
|
||||
* @return Possibly an error
|
||||
*/
|
||||
[[maybe_unused]] MaybeErrorType
|
||||
[[nodiscard]] [[maybe_unused]] MaybeErrorType
|
||||
disconnect() const;
|
||||
|
||||
/**
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
* @return The result or an error
|
||||
*/
|
||||
template <typename... Args>
|
||||
[[maybe_unused]] ResultOrErrorType
|
||||
[[nodiscard]] [[maybe_unused]] ResultOrErrorType
|
||||
execute(std::string_view query, Args&&... args) const
|
||||
{
|
||||
return asyncExecute<Args...>(query, std::forward<Args>(args)...).get();
|
||||
@@ -189,7 +189,7 @@ public:
|
||||
* @param statements The statements to execute
|
||||
* @return Possibly an error
|
||||
*/
|
||||
[[maybe_unused]] MaybeErrorType
|
||||
[[nodiscard]] [[maybe_unused]] MaybeErrorType
|
||||
executeEach(std::vector<StatementType> const& statements) const;
|
||||
|
||||
/**
|
||||
@@ -250,7 +250,7 @@ public:
|
||||
* @param statement The statement to execute
|
||||
* @return The result or an error
|
||||
*/
|
||||
[[maybe_unused]] ResultOrErrorType
|
||||
[[nodiscard]] [[maybe_unused]] ResultOrErrorType
|
||||
execute(StatementType const& statement) const;
|
||||
|
||||
/**
|
||||
@@ -270,7 +270,7 @@ public:
|
||||
* @param statements The statements to execute
|
||||
* @return Possibly an error
|
||||
*/
|
||||
[[maybe_unused]] MaybeErrorType
|
||||
[[nodiscard]] [[maybe_unused]] MaybeErrorType
|
||||
execute(std::vector<StatementType> const& statements) const;
|
||||
|
||||
/**
|
||||
|
||||
@@ -123,8 +123,8 @@ Cluster::setupContactPoints(Settings::ContactPoints const& points)
|
||||
}
|
||||
|
||||
if (points.port) {
|
||||
auto const rc = cass_cluster_set_port(*this, points.port.value());
|
||||
throwErrorIfNeeded(rc, "port", to_string(points.port.value()));
|
||||
auto const rc = cass_cluster_set_port(*this, *points.port);
|
||||
throwErrorIfNeeded(rc, "port", to_string(*points.port));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,10 +158,8 @@ Cluster::setupCredentials(Settings const& settings)
|
||||
if (not settings.username || not settings.password)
|
||||
return;
|
||||
|
||||
LOG(log_.debug()) << "Set credentials; username: " << settings.username.value();
|
||||
cass_cluster_set_credentials(
|
||||
*this, settings.username.value().c_str(), settings.password.value().c_str()
|
||||
);
|
||||
LOG(log_.debug()) << "Set credentials; username: " << *settings.username;
|
||||
cass_cluster_set_credentials(*this, settings.username->c_str(), settings.password->c_str());
|
||||
}
|
||||
|
||||
} // namespace data::cassandra::impl
|
||||
|
||||
@@ -525,13 +525,13 @@ private:
|
||||
{
|
||||
// mutex lock required to prevent race condition around spurious
|
||||
// wakeup
|
||||
std::lock_guard const lck(throttleMutex_);
|
||||
std::scoped_lock const lck(throttleMutex_);
|
||||
throttleCv_.notify_one();
|
||||
}
|
||||
if (cur == 0) {
|
||||
// mutex lock required to prevent race condition around spurious
|
||||
// wakeup
|
||||
std::lock_guard const lck(syncMutex_);
|
||||
std::scoped_lock const lck(syncMutex_);
|
||||
syncCv_.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ namespace data::cassandra::impl {
|
||||
struct Future : public ManagedObject<CassFuture> {
|
||||
/* implicit */ Future(CassFuture* ptr);
|
||||
|
||||
MaybeError
|
||||
[[nodiscard]] MaybeError
|
||||
await() const;
|
||||
|
||||
ResultOrError
|
||||
[[nodiscard]] ResultOrError
|
||||
get() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ struct Result : public ManagedObject<CassResult const> {
|
||||
hasRows() const;
|
||||
|
||||
template <typename... RowTypes>
|
||||
std::optional<std::tuple<RowTypes...>>
|
||||
[[nodiscard]] std::optional<std::tuple<RowTypes...>>
|
||||
get() const
|
||||
requires(std::tuple_size<std::tuple<RowTypes...>>{} > 1)
|
||||
{
|
||||
@@ -126,7 +126,7 @@ struct Result : public ManagedObject<CassResult const> {
|
||||
}
|
||||
|
||||
template <typename RowType>
|
||||
std::optional<RowType>
|
||||
[[nodiscard]] std::optional<RowType>
|
||||
get() const
|
||||
{
|
||||
// row managed internally by cassandra driver, hence no ManagedObject.
|
||||
@@ -153,7 +153,7 @@ public:
|
||||
hasMore() const;
|
||||
|
||||
template <typename... RowTypes>
|
||||
std::tuple<RowTypes...>
|
||||
[[nodiscard]] std::tuple<RowTypes...>
|
||||
extractCurrentRow() const
|
||||
{
|
||||
// note: row is invalidated on each iteration.
|
||||
|
||||
@@ -171,7 +171,7 @@ public:
|
||||
* @return A bound and ready to execute Statement object
|
||||
*/
|
||||
template <typename... Args>
|
||||
Statement
|
||||
[[nodiscard]] Statement
|
||||
bind(Args&&... args) const
|
||||
{
|
||||
Statement statement = cass_prepared_bind(*this);
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
|
||||
private:
|
||||
template <typename Type>
|
||||
Type
|
||||
[[nodiscard]] Type
|
||||
extractNext() const
|
||||
{
|
||||
using std::to_string;
|
||||
|
||||
@@ -47,8 +47,7 @@ makeCacheLoaderSettings(util::config::ClioConfigDefinition const& config)
|
||||
|
||||
if (auto filePath = cache.maybeValue<std::string>("file.path"); filePath.has_value()) {
|
||||
settings.cacheFileSettings = CacheLoaderSettings::CacheFileSettings{
|
||||
.path = std::move(filePath).value(),
|
||||
.maxAge = cache.get<uint32_t>("file.max_sequence_age")
|
||||
.path = *std::move(filePath), .maxAge = cache.get<uint32_t>("file.max_sequence_age")
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -417,6 +417,7 @@ ETLService::attemptTakeoverWriter()
|
||||
auto rng = backend_->hardFetchLedgerRangeNoThrow();
|
||||
ASSERT(rng.has_value(), "Ledger range can't be null");
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
if (backend_->cache().latestLedgerSequence() != rng->maxSequence) {
|
||||
LOG(log_.info()) << "Wanted to take over the ETL writer seat but LedgerCache is outdated";
|
||||
// Give ETL time to update LedgerCache. This method will be called because
|
||||
@@ -426,7 +427,7 @@ ETLService::attemptTakeoverWriter()
|
||||
|
||||
state_->isWriting = true; // switch to writer
|
||||
LOG(log_.info()) << "Taking over the ETL writer seat";
|
||||
startLoading(rng->maxSequence + 1);
|
||||
startLoading(rng->maxSequence + 1); // NOLINT(bugprone-unchecked-optional-access)
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -32,7 +32,7 @@ struct LedgerPublisherInterface {
|
||||
*
|
||||
* @return A std::chrono::time_point representing the time of the last publish
|
||||
*/
|
||||
virtual std::chrono::time_point<std::chrono::system_clock>
|
||||
[[nodiscard]] virtual std::chrono::time_point<std::chrono::system_clock>
|
||||
getLastPublish() const = 0;
|
||||
|
||||
/**
|
||||
@@ -40,7 +40,7 @@ struct LedgerPublisherInterface {
|
||||
*
|
||||
* @return The number of seconds since the last ledger close as std::uint32_t
|
||||
*/
|
||||
virtual std::uint32_t
|
||||
[[nodiscard]] virtual std::uint32_t
|
||||
lastCloseAgeSeconds() const = 0;
|
||||
|
||||
/**
|
||||
@@ -48,7 +48,7 @@ struct LedgerPublisherInterface {
|
||||
*
|
||||
* @return The number of seconds since the last publish as std::uint32_t
|
||||
*/
|
||||
virtual std::uint32_t
|
||||
[[nodiscard]] virtual std::uint32_t
|
||||
lastPublishAgeSeconds() const = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -275,10 +275,11 @@ LoadBalancer::forwardToRippled(
|
||||
return std::unexpected{rpc::ClioError::RpcCommandIsMissing};
|
||||
|
||||
auto const cmd = boost::json::value_to<std::string>(request.at("command"));
|
||||
if (forwardingCache_) {
|
||||
if (shouldUseCache(isAdmin)) {
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
if (auto cachedResponse = forwardingCache_->get(cmd); cachedResponse) {
|
||||
forwardingCounters_.cacheHit.get() += 1;
|
||||
return std::move(cachedResponse).value();
|
||||
return *std::move(cachedResponse);
|
||||
}
|
||||
}
|
||||
forwardingCounters_.cacheMiss.get() += 1;
|
||||
@@ -310,9 +311,9 @@ LoadBalancer::forwardToRippled(
|
||||
}
|
||||
|
||||
if (response) {
|
||||
if (forwardingCache_ and not response->contains("error"))
|
||||
forwardingCache_->put(cmd, *response);
|
||||
return std::move(response).value();
|
||||
if (shouldUseCache(isAdmin) and not response->contains("error"))
|
||||
forwardingCache_->put(cmd, *response); // NOLINT(bugprone-unchecked-optional-access)
|
||||
return *std::move(response);
|
||||
}
|
||||
|
||||
return std::unexpected{error};
|
||||
@@ -415,4 +416,10 @@ LoadBalancer::chooseForwardingSource()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LoadBalancer::shouldUseCache(bool isAdmin) const
|
||||
{
|
||||
return forwardingCache_.has_value() and not isAdmin;
|
||||
}
|
||||
|
||||
} // namespace etl
|
||||
|
||||
@@ -254,6 +254,9 @@ private:
|
||||
*/
|
||||
void
|
||||
chooseForwardingSource();
|
||||
|
||||
bool
|
||||
shouldUseCache(bool isAdmin) const;
|
||||
};
|
||||
|
||||
} // namespace etl
|
||||
|
||||
@@ -18,7 +18,7 @@ NetworkValidatedLedgers::makeValidatedLedgers()
|
||||
void
|
||||
NetworkValidatedLedgers::push(uint32_t idx)
|
||||
{
|
||||
std::lock_guard const lck(mtx_);
|
||||
std::scoped_lock const lck(mtx_);
|
||||
if (!latest_ || idx > *latest_)
|
||||
latest_ = idx;
|
||||
|
||||
|
||||
@@ -171,14 +171,14 @@ public:
|
||||
*/
|
||||
WriterState(std::shared_ptr<SystemState> state, data::LedgerCacheInterface const& cache);
|
||||
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isReadOnly() const override;
|
||||
|
||||
/**
|
||||
* @brief Check if the ETL process is currently writing to the database.
|
||||
* @return true if the process is writing, false otherwise
|
||||
*/
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isWriting() const override;
|
||||
|
||||
/**
|
||||
@@ -213,11 +213,11 @@ public:
|
||||
*
|
||||
* @return true if the cluster has switched to fallback mode, false otherwise
|
||||
*/
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isFallback() const override;
|
||||
|
||||
/** @copydoc WriterStateInterface::isFallbackRecovery */
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isFallbackRecovery() const override;
|
||||
|
||||
/** @copydoc WriterStateInterface::setFallbackRecovery */
|
||||
@@ -225,11 +225,11 @@ public:
|
||||
setFallbackRecovery(bool newValue) override;
|
||||
|
||||
/** @copydoc WriterStateInterface::isEtlStarted */
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isEtlStarted() const override;
|
||||
|
||||
/** @copydoc WriterStateInterface::isCacheFull */
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isCacheFull() const override;
|
||||
|
||||
/**
|
||||
@@ -239,7 +239,7 @@ public:
|
||||
*
|
||||
* @return A unique pointer to the cloned writer state.
|
||||
*/
|
||||
std::unique_ptr<WriterStateInterface>
|
||||
[[nodiscard]] std::unique_ptr<WriterStateInterface>
|
||||
clone() const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ private:
|
||||
return; // queue is empty
|
||||
}
|
||||
|
||||
auto [start, end] = cursor.value();
|
||||
auto [start, end] = *cursor;
|
||||
LOG(log_.debug()) << "Starting a cursor: " << ripple::strHex(start);
|
||||
|
||||
while (not token.isStopRequested() and not cache_.get().isDisabled()) {
|
||||
@@ -136,7 +136,7 @@ private:
|
||||
break; // pick up the next cursor if available
|
||||
}
|
||||
|
||||
start = std::move(res.cursor).value();
|
||||
start = *std::move(res.cursor);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
std::set<ripple::uint256> liveCursors;
|
||||
std::set<ripple::uint256> deletedCursors;
|
||||
auto i = 0;
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
while (liveCursors.size() < numCursors_ and seq - i >= range->minSequence) {
|
||||
auto diffs = fetchDiff(i++);
|
||||
rg::copy(
|
||||
|
||||
@@ -94,6 +94,8 @@ extractObj(PBObjType obj)
|
||||
{
|
||||
auto const key = ripple::uint256::fromVoidChecked(obj.key());
|
||||
ASSERT(key.has_value(), "Failed to deserialize key from void");
|
||||
if (!key)
|
||||
return {};
|
||||
|
||||
auto const valueOr = [](std::string const& maybe, std::string fallback) -> std::string {
|
||||
if (maybe.empty())
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
* @param yield The coroutine context
|
||||
* @return Response on success or error on failure
|
||||
*/
|
||||
std::expected<boost::json::object, rpc::ClioError>
|
||||
[[nodiscard]] std::expected<boost::json::object, rpc::ClioError>
|
||||
forwardToRippled(
|
||||
boost::json::object const& request,
|
||||
std::optional<std::string> const& forwardToRippledClientIp,
|
||||
|
||||
@@ -139,6 +139,8 @@ public:
|
||||
"Ledger must exist in database. Ledger sequence = {}",
|
||||
ledgerSequence
|
||||
);
|
||||
if (!lgr)
|
||||
return false;
|
||||
publish(*lgr);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -51,6 +51,8 @@ Monitor::notifySequenceLoaded(uint32_t seq)
|
||||
lck->lastSeenMaxSeqInDb = std::max(seq, lck->lastSeenMaxSeqInDb);
|
||||
lck->lastDbCheckTime = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
repeatedTask_->invoke(); // force-invoke doWork immediately
|
||||
};
|
||||
|
||||
@@ -110,6 +112,8 @@ Monitor::onNextSequence(uint32_t seq)
|
||||
{
|
||||
ASSERT(repeatedTask_.has_value(), "Ledger subscription without repeated task is a logic error");
|
||||
LOG(log_.debug()) << "Notified about new sequence on the network: " << seq;
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
repeatedTask_->invoke(); // force-invoke immediately
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
*
|
||||
* @return true if source is connected; false otherwise
|
||||
*/
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isConnected() const final
|
||||
{
|
||||
return subscriptionSource_->isConnected();
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
*
|
||||
* @return JSON representation of the source
|
||||
*/
|
||||
boost::json::object
|
||||
[[nodiscard]] boost::json::object
|
||||
toJson() const final
|
||||
{
|
||||
boost::json::object res;
|
||||
@@ -144,7 +144,7 @@ public:
|
||||
}
|
||||
|
||||
/** @return String representation of the source (for debug) */
|
||||
std::string
|
||||
[[nodiscard]] std::string
|
||||
toString() const final
|
||||
{
|
||||
return "{validated range: " + subscriptionSource_->validatedRange() + ", ip: " + ip_ +
|
||||
@@ -157,7 +157,7 @@ public:
|
||||
* @param sequence The ledger sequence to check
|
||||
* @return true if ledger is in the range of this source; false otherwise
|
||||
*/
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
hasLedger(uint32_t sequence) const final
|
||||
{
|
||||
return subscriptionSource_->hasLedger(sequence);
|
||||
@@ -208,7 +208,7 @@ public:
|
||||
* @param yield The coroutine context
|
||||
* @return Response or ClioError
|
||||
*/
|
||||
std::expected<boost::json::object, rpc::ClioError>
|
||||
[[nodiscard]] std::expected<boost::json::object, rpc::ClioError>
|
||||
forwardToRippled(
|
||||
boost::json::object const& request,
|
||||
std::optional<std::string> const& forwardToRippledClientIp,
|
||||
|
||||
@@ -155,7 +155,7 @@ SubscriptionSource::subscribe()
|
||||
if (auto const writeErrorOpt =
|
||||
wsConnection_->write(subscribeCommand, yield, wsTimeout_);
|
||||
writeErrorOpt) {
|
||||
handleError(writeErrorOpt.value(), yield);
|
||||
handleError(*writeErrorOpt, yield);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -172,8 +172,8 @@ SubscriptionSource::subscribe()
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto const handleErrorOpt = handleMessage(message.value()); handleErrorOpt) {
|
||||
handleError(handleErrorOpt.value(), yield);
|
||||
if (auto const handleErrorOpt = handleMessage(*message); handleErrorOpt) {
|
||||
handleError(*handleErrorOpt, yield);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -296,8 +296,8 @@ SubscriptionSource::logError(util::requests::RequestError const& error) const
|
||||
auto const& errorCodeOpt = error.errorCode();
|
||||
|
||||
if (not errorCodeOpt or
|
||||
(errorCodeOpt.value() != boost::asio::error::operation_aborted &&
|
||||
errorCodeOpt.value() != boost::asio::error::connection_refused)) {
|
||||
(*errorCodeOpt != boost::asio::error::operation_aborted &&
|
||||
*errorCodeOpt != boost::asio::error::connection_refused)) {
|
||||
LOG(log_.error()) << error.message();
|
||||
} else {
|
||||
LOG(log_.warn()) << error.message();
|
||||
|
||||
@@ -37,7 +37,7 @@ SuccessorExt::onInitialData(model::LedgerData const& data) const
|
||||
ASSERT(data.edgeKeys.has_value(), "Expecting to have edge keys on initial data load");
|
||||
ASSERT(data.objects.empty(), "Should not have objects from initial data");
|
||||
writeSuccessors(data.seq);
|
||||
writeEdgeKeys(data.seq, data.edgeKeys.value());
|
||||
writeEdgeKeys(data.seq, *data.edgeKeys); // NOLINT(bugprone-unchecked-optional-access)
|
||||
}
|
||||
|
||||
void
|
||||
@@ -67,7 +67,7 @@ SuccessorExt::onLedgerData(model::LedgerData const& data) const
|
||||
| vs::filter([](auto const& obj) { return obj.type != model::Object::ModType::Modified; });
|
||||
|
||||
if (data.successors.has_value()) {
|
||||
for (auto const& successor : data.successors.value())
|
||||
for (auto const& successor : *data.successors)
|
||||
writeIncludedSuccessor(data.seq, successor);
|
||||
|
||||
for (auto const& obj : filteredObjects)
|
||||
@@ -135,7 +135,7 @@ SuccessorExt::updateSuccessorFromCache(uint32_t seq, model::Object const& obj) c
|
||||
auto const old = cache_.get().getDeleted(obj.key, seq - 1);
|
||||
ASSERT(old.has_value(), "Deleted object {} must be in cache", ripple::strHex(obj.key));
|
||||
|
||||
checkBookBase = isBookDir(obj.key, *old);
|
||||
checkBookBase = isBookDir(obj.key, *old); // NOLINT(bugprone-unchecked-optional-access)
|
||||
} else {
|
||||
checkBookBase = isBookDir(obj.key, obj.data);
|
||||
}
|
||||
@@ -191,7 +191,7 @@ SuccessorExt::writeSuccessors(uint32_t seq) const
|
||||
succ.has_value(), "Book base {} must have a successor", ripple::strHex(base)
|
||||
);
|
||||
|
||||
if (succ->key == cur->key)
|
||||
if (succ->key == cur->key) // NOLINT(bugprone-unchecked-optional-access)
|
||||
backend_->writeSuccessor(uint256ToString(base), seq, uint256ToString(cur->key));
|
||||
}
|
||||
}
|
||||
@@ -206,6 +206,7 @@ void
|
||||
SuccessorExt::writeEdgeKeys(std::uint32_t seq, auto const& edgeKeys) const
|
||||
{
|
||||
for (auto const& key : edgeKeys) {
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
auto succ = cache_.get().getSuccessor(*ripple::uint256::fromVoidChecked(key), seq);
|
||||
if (succ)
|
||||
backend_->writeSuccessor(auto{key}, seq, uint256ToString(succ->key));
|
||||
|
||||
@@ -236,7 +236,7 @@ public:
|
||||
*
|
||||
* @return The report of the number of subscribers.
|
||||
*/
|
||||
virtual boost::json::object
|
||||
[[nodiscard]] virtual boost::json::object
|
||||
report() const = 0;
|
||||
|
||||
/**
|
||||
@@ -251,7 +251,7 @@ public:
|
||||
*
|
||||
* @return The network id.
|
||||
*/
|
||||
virtual uint32_t
|
||||
[[nodiscard]] virtual uint32_t
|
||||
getNetworkID() const = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -57,16 +57,21 @@ LedgerFeed::sub(
|
||||
auto const ledgerRange = backend->fetchLedgerRange();
|
||||
ASSERT(ledgerRange.has_value(), "Ledger range must be valid");
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
auto const lgrInfo = backend->fetchLedgerBySequence(ledgerRange->maxSequence, yield);
|
||||
ASSERT(lgrInfo.has_value(), "Ledger must be valid");
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
auto const fees = backend->fetchFees(lgrInfo->seq, yield);
|
||||
ASSERT(fees.has_value(), "Fees must be valid");
|
||||
|
||||
// NOLINTBEGIN(bugprone-unchecked-optional-access)
|
||||
auto const range =
|
||||
std::to_string(ledgerRange->minSequence) + "-" + std::to_string(ledgerRange->maxSequence);
|
||||
|
||||
auto pubMsg = makeLedgerPubMessage(*lgrInfo, *fees, range, 0, networkID);
|
||||
// NOLINTEND(bugprone-unchecked-optional-access)
|
||||
|
||||
pubMsg.erase("txn_count");
|
||||
pubMsg.erase("type");
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ public:
|
||||
/**
|
||||
* @brief Get the number of connections.
|
||||
*/
|
||||
std::size_t
|
||||
[[nodiscard]] std::size_t
|
||||
count() const
|
||||
{
|
||||
return connections_.template lock<std::scoped_lock>()->size();
|
||||
|
||||
@@ -234,7 +234,7 @@ TransactionFeed::pub(
|
||||
networkID
|
||||
);
|
||||
ctid)
|
||||
pubObj[JS(ctid)] = ctid.value();
|
||||
pubObj[JS(ctid)] = *ctid;
|
||||
}
|
||||
|
||||
pubObj[JS(type)] = "transaction";
|
||||
|
||||
@@ -72,13 +72,13 @@ int
|
||||
MigratorApplication::migrate(std::string const& migratorName)
|
||||
{
|
||||
auto const status = migrationManager_->getMigratorStatusByName(migratorName);
|
||||
if (status == migration::MigratorStatus::Migrated) {
|
||||
if (status == migration::MigratorStatus::Status::Migrated) {
|
||||
std::cout << "Migrator " << migratorName << " has already migrated" << std::endl;
|
||||
printStatus();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (status == migration::MigratorStatus::NotKnown) {
|
||||
if (status == migration::MigratorStatus::Status::NotKnown) {
|
||||
std::cout << "Migrator " << migratorName << " not found" << std::endl;
|
||||
printStatus();
|
||||
return EXIT_FAILURE;
|
||||
|
||||
@@ -36,7 +36,7 @@ makeMigrationInspector(
|
||||
|
||||
// Database is empty, we need to initialize the migration table if it is a writeable backend
|
||||
if (not config.get<bool>("read_only") and not backend->hardFetchLedgerRangeNoThrow()) {
|
||||
migration::MigratorStatus const migrated(migration::MigratorStatus::Migrated);
|
||||
migration::MigratorStatus const migrated(migration::MigratorStatus::Status::Migrated);
|
||||
for (auto const& name : inspector->allMigratorsNames()) {
|
||||
backend->writeMigratorStatus(name, migrated.toString());
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ struct MigrationInspectorInterface {
|
||||
* @return A vector of tuple, the first element is the migrator's name, the second element is
|
||||
* the status of the
|
||||
*/
|
||||
virtual std::vector<std::tuple<std::string, MigratorStatus>>
|
||||
[[nodiscard]] virtual std::vector<std::tuple<std::string, MigratorStatus>>
|
||||
allMigratorsStatusPairs() const = 0;
|
||||
|
||||
/**
|
||||
@@ -28,7 +28,7 @@ struct MigrationInspectorInterface {
|
||||
*
|
||||
* @return A vector of migrators' names
|
||||
*/
|
||||
virtual std::vector<std::string>
|
||||
[[nodiscard]] virtual std::vector<std::string>
|
||||
allMigratorsNames() const = 0;
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ struct MigrationInspectorInterface {
|
||||
* @param name The migrator's name
|
||||
* @return The status of the migrator
|
||||
*/
|
||||
virtual MigratorStatus
|
||||
[[nodiscard]] virtual MigratorStatus
|
||||
getMigratorStatusByName(std::string const& name) const = 0;
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ struct MigrationInspectorInterface {
|
||||
* @param name The migrator's name
|
||||
* @return The description of the migrator
|
||||
*/
|
||||
virtual std::string
|
||||
[[nodiscard]] virtual std::string
|
||||
getMigratorDescriptionByName(std::string const& name) const = 0;
|
||||
|
||||
/**
|
||||
@@ -54,7 +54,7 @@ struct MigrationInspectorInterface {
|
||||
*
|
||||
* @return True if Clio server is blocked by migration, false otherwise
|
||||
*/
|
||||
virtual bool
|
||||
[[nodiscard]] virtual bool
|
||||
isBlockingClio() const = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
/**
|
||||
* @brief The status of a migrator
|
||||
*/
|
||||
enum Status { Migrated, NotMigrated, NotKnown, NumStatuses };
|
||||
enum class Status { Migrated, NotMigrated, NotKnown, NumStatuses };
|
||||
|
||||
/**
|
||||
* @brief Construct a new Migrator Status object with the given status
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
*
|
||||
* @return The string representation of the status
|
||||
*/
|
||||
std::string
|
||||
[[nodiscard]] std::string
|
||||
toString() const;
|
||||
|
||||
/**
|
||||
@@ -61,11 +61,8 @@ public:
|
||||
fromString(std::string const& statusStr);
|
||||
|
||||
private:
|
||||
static constexpr std::array<char const*, static_cast<size_t>(NumStatuses)> kSTATUS_STR_MAP = {
|
||||
"Migrated",
|
||||
"NotMigrated",
|
||||
"NotKnown"
|
||||
};
|
||||
static constexpr std::array<char const*, static_cast<size_t>(Status::NumStatuses)>
|
||||
kSTATUS_STR_MAP = {"Migrated", "NotMigrated", "NotKnown"};
|
||||
|
||||
Status status_;
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ concept TableSpec = requires {
|
||||
// Check that 'row' exists and is a tuple
|
||||
// keys types are at the beginning and the other fields types sort in alphabetical order
|
||||
typename T::Row;
|
||||
requires std::tuple_size<typename T::Row>::value >= 0; // Ensures 'row' is a tuple
|
||||
requires std::tuple_size_v<typename T::Row> >= 0; // Ensures 'row' is a tuple
|
||||
|
||||
// Check that static constexpr members 'partitionKey' and 'tableName' exist
|
||||
{ T::kPARTITION_KEY } -> std::convertible_to<char const*>;
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
* @return A vector of tuple, the first element is the migrator's name, the second element is
|
||||
* the status of the migrator
|
||||
*/
|
||||
std::vector<std::tuple<std::string, MigratorStatus>>
|
||||
[[nodiscard]] std::vector<std::tuple<std::string, MigratorStatus>>
|
||||
allMigratorsStatusPairs() const override
|
||||
{
|
||||
return migrators_.getMigratorsStatus();
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
* @param name The name of the migrator
|
||||
* @return The status of the migrator
|
||||
*/
|
||||
MigratorStatus
|
||||
[[nodiscard]] MigratorStatus
|
||||
getMigratorStatusByName(std::string const& name) const override
|
||||
{
|
||||
return migrators_.getMigratorStatus(name);
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
*
|
||||
* @return A vector of string, the names of all the migrators
|
||||
*/
|
||||
std::vector<std::string>
|
||||
[[nodiscard]] std::vector<std::string>
|
||||
allMigratorsNames() const override
|
||||
{
|
||||
auto const names = migrators_.getMigratorNames();
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
* @param name The name of the migrator
|
||||
* @return The description of the migrator
|
||||
*/
|
||||
std::string
|
||||
[[nodiscard]] std::string
|
||||
getMigratorDescriptionByName(std::string const& name) const override
|
||||
{
|
||||
return migrators_.getMigratorDescription(name);
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
*
|
||||
* @return True if server is blocked, false otherwise
|
||||
*/
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isBlockingClio() const override
|
||||
{
|
||||
return std::ranges::any_of(migrators_.getMigratorNames(), [&](auto const& migrator) {
|
||||
|
||||
@@ -61,7 +61,7 @@ class MigratorsRegister {
|
||||
LOG(log_.info()) << "Running migration: " << name;
|
||||
Migrator::runMigration(backend_, config);
|
||||
backend_->writeMigratorStatus(
|
||||
name, MigratorStatus(MigratorStatus::Migrated).toString()
|
||||
name, MigratorStatus(MigratorStatus::Status::Migrated).toString()
|
||||
);
|
||||
LOG(log_.info()) << "Finished migration: " << name;
|
||||
}
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
* @return A vector of tuple, the first element is the migrator's name, the second element is
|
||||
* the status of the migrator
|
||||
*/
|
||||
std::vector<std::tuple<std::string, MigratorStatus>>
|
||||
[[nodiscard]] std::vector<std::tuple<std::string, MigratorStatus>>
|
||||
getMigratorsStatus() const
|
||||
{
|
||||
auto const fullList = getMigratorNames();
|
||||
@@ -145,19 +145,19 @@ public:
|
||||
* @param name The migrator's name to get the status
|
||||
* @return The status of the migrator
|
||||
*/
|
||||
MigratorStatus
|
||||
[[nodiscard]] MigratorStatus
|
||||
getMigratorStatus(std::string const& name) const
|
||||
{
|
||||
auto const fullList = getMigratorNames();
|
||||
if (std::ranges::find(fullList, name) == fullList.end()) {
|
||||
return MigratorStatus::NotKnown;
|
||||
return MigratorStatus::Status::NotKnown;
|
||||
}
|
||||
auto const statusStringOpt = data::synchronous([&](auto yield) {
|
||||
return backend_->fetchMigratorStatus(name, yield);
|
||||
});
|
||||
|
||||
return statusStringOpt ? MigratorStatus::fromString(statusStringOpt.value())
|
||||
: MigratorStatus::NotMigrated;
|
||||
: MigratorStatus::Status::NotMigrated;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,7 +165,7 @@ public:
|
||||
*
|
||||
* @return A array of migrator's names
|
||||
*/
|
||||
constexpr auto
|
||||
[[nodiscard]] constexpr auto
|
||||
getMigratorNames() const
|
||||
{
|
||||
return std::array<std::string_view, sizeof...(MigratorType)>{MigratorType::kNAME...};
|
||||
@@ -177,7 +177,7 @@ public:
|
||||
* @param name The migrator's name
|
||||
* @return The description of the migrator
|
||||
*/
|
||||
std::string
|
||||
[[nodiscard]] std::string
|
||||
getMigratorDescription(std::string const& name) const
|
||||
{
|
||||
if constexpr (sizeof...(MigratorType) == 0) {
|
||||
@@ -199,7 +199,7 @@ public:
|
||||
* @return std::nullopt if the migrator name is not found, or a boolean value indicating whether
|
||||
* the migrator is blocking Clio server.
|
||||
*/
|
||||
std::optional<bool>
|
||||
[[nodiscard]] std::optional<bool>
|
||||
canMigratorBlockClio(std::string_view name) const
|
||||
{
|
||||
if constexpr (sizeof...(MigratorType) == 0) {
|
||||
|
||||
@@ -85,8 +85,12 @@ parseAuthorizeCredentials(boost::json::array const& jv)
|
||||
);
|
||||
|
||||
auto credential = ripple::STObject::makeInnerObject(ripple::sfCredential);
|
||||
|
||||
// NOLINTBEGIN(bugprone-unchecked-optional-access)
|
||||
credential.setAccountID(ripple::sfIssuer, *issuer);
|
||||
credential.setFieldVL(ripple::sfCredentialType, *credentialType);
|
||||
// NOLINTEND(bugprone-unchecked-optional-access)
|
||||
|
||||
arr.push_back(std::move(credential));
|
||||
}
|
||||
|
||||
@@ -104,7 +108,7 @@ fetchCredentialArray(
|
||||
{
|
||||
ripple::STArray authCreds;
|
||||
std::unordered_set<std::string_view> elems;
|
||||
for (auto const& elem : credID.value()) {
|
||||
for (auto const& elem : *credID) { // NOLINT(bugprone-unchecked-optional-access)
|
||||
ASSERT(
|
||||
elem.is_string(), "should already be checked in validators.hpp that elem is a string."
|
||||
);
|
||||
|
||||
@@ -61,14 +61,14 @@ WarningInfo const&
|
||||
getWarningInfo(WarningCode code)
|
||||
{
|
||||
static constexpr WarningInfo kINFOS[]{
|
||||
{WarnUnknown, "Unknown warning"},
|
||||
{WarnRpcClio,
|
||||
{WarningCode::WarnUnknown, "Unknown warning"},
|
||||
{WarningCode::WarnRpcClio,
|
||||
"This is a clio server. clio only serves validated data. If you want to talk to rippled, "
|
||||
"include "
|
||||
"'ledger_index':'current' in your request"},
|
||||
{WarnRpcOutdated, "This server may be out of date"},
|
||||
{WarnRpcRateLimit, "You are about to be rate limited"},
|
||||
{WarnRpcDeprecated,
|
||||
{WarningCode::WarnRpcOutdated, "This server may be out of date"},
|
||||
{WarningCode::WarnRpcRateLimit, "You are about to be rate limited"},
|
||||
{WarningCode::WarnRpcDeprecated,
|
||||
"Some fields from your request are deprecated. Please check the documentation at "
|
||||
"https://xrpl.org/docs/references/http-websocket-apis/ and update your request."}
|
||||
};
|
||||
@@ -85,7 +85,7 @@ makeWarning(WarningCode code)
|
||||
{
|
||||
auto json = boost::json::object{};
|
||||
auto const& info = getWarningInfo(code);
|
||||
json["id"] = code;
|
||||
json["id"] = static_cast<int>(code);
|
||||
json["message"] = info.message;
|
||||
return json;
|
||||
}
|
||||
@@ -220,7 +220,7 @@ makeError(Status const& status)
|
||||
);
|
||||
|
||||
if (status.extraInfo) {
|
||||
for (auto& [key, value] : status.extraInfo.value())
|
||||
for (auto& [key, value] : *status.extraInfo)
|
||||
res[key] = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@ struct Status {
|
||||
};
|
||||
|
||||
/** @brief Warning codes that can be returned by clio. */
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
|
||||
enum WarningCode {
|
||||
WarnUnknown = -1,
|
||||
WarnRpcClio = 2001,
|
||||
@@ -200,7 +201,7 @@ struct WarningInfo {
|
||||
{
|
||||
}
|
||||
|
||||
WarningCode code = WarnUnknown;
|
||||
WarningCode code = WarningCode::WarnUnknown;
|
||||
std::string_view const message = "unknown warning";
|
||||
};
|
||||
|
||||
@@ -223,7 +224,7 @@ public:
|
||||
*
|
||||
* @return The error message
|
||||
*/
|
||||
char const*
|
||||
[[nodiscard]] char const*
|
||||
what() const throw() override
|
||||
{
|
||||
return msg_.c_str();
|
||||
@@ -249,7 +250,7 @@ public:
|
||||
*
|
||||
* @return The error message
|
||||
*/
|
||||
char const*
|
||||
[[nodiscard]] char const*
|
||||
what() const throw() override
|
||||
{
|
||||
return account_.c_str();
|
||||
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
|
||||
if (not ctx.isAdmin and responseCache_) {
|
||||
if (auto res = responseCache_->get(ctx.method); res.has_value())
|
||||
return Result{std::move(res).value()};
|
||||
return Result{*std::move(res)};
|
||||
}
|
||||
|
||||
if (backend_->isTooBusy()) {
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
.clientIp = ctx.clientIp,
|
||||
.apiVersion = ctx.apiVersion
|
||||
};
|
||||
auto v = (*method).process(ctx.params, context);
|
||||
auto v = method->process(ctx.params, context);
|
||||
|
||||
LOG(perfLog_.debug()) << ctx.tag() << " finish executing rpc `" << ctx.method << '`';
|
||||
|
||||
@@ -321,7 +321,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
validHandler(std::string const& method) const
|
||||
{
|
||||
return handlerProvider_->contains(method) || forwardingProxy_.isProxied(method);
|
||||
@@ -352,7 +352,7 @@ private:
|
||||
.clientIp = ctx.clientIp,
|
||||
.apiVersion = ctx.apiVersion
|
||||
};
|
||||
auto v = (*method).process(ctx.params, context);
|
||||
auto v = method->process(ctx.params, context);
|
||||
|
||||
LOG(perfLog_.debug()) << ctx.tag() << " finish executing rpc `" << ctx.method << '`';
|
||||
|
||||
|
||||
@@ -359,6 +359,8 @@ insertMPTIssuanceID(
|
||||
|
||||
auto const id = getMPTIssuanceID(meta);
|
||||
ASSERT(id.has_value(), "MPTIssuanceID must have value");
|
||||
if (!id)
|
||||
return false;
|
||||
|
||||
// For mpttokenissuance create, add mpt_issuance_id to metajson
|
||||
// Otherwise, add it to txn json
|
||||
@@ -630,6 +632,8 @@ traverseNFTObjects(
|
||||
return AccountCursor{.index = nftPreviousPage, .hint = count};
|
||||
|
||||
page = backend.fetchLedgerObject(nftPreviousPage, sequence, yield);
|
||||
if (!page)
|
||||
break;
|
||||
pageSLE = ripple::SLE{ripple::SerialIter{page->data(), page->size()}, nftPreviousPage};
|
||||
}
|
||||
|
||||
|
||||
@@ -187,14 +187,16 @@ WorkQueue::executeTask(boost::asio::yield_context yield)
|
||||
);
|
||||
auto const takenAt = std::chrono::system_clock::now();
|
||||
auto const waited =
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(takenAt - taskWithTimestamp->queuedAt)
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
takenAt - taskWithTimestamp->queuedAt // NOLINT(bugprone-unchecked-optional-access)
|
||||
)
|
||||
.count();
|
||||
|
||||
++queued_.get();
|
||||
durationUs_.get() += waited;
|
||||
LOG(log_.info()) << "WorkQueue wait time: " << waited << ", queue size: " << size();
|
||||
|
||||
taskWithTimestamp->task(yield);
|
||||
taskWithTimestamp->task(yield); // NOLINT(bugprone-unchecked-optional-access)
|
||||
--curSize_.get();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
* @param request A JSON object representing the request
|
||||
* @return The specified API version if contained in the JSON object; error string otherwise
|
||||
*/
|
||||
std::expected<uint32_t, std::string> virtual parse(
|
||||
[[nodiscard]] std::expected<uint32_t, std::string> virtual parse(
|
||||
boost::json::object const& request
|
||||
) const = 0;
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
* @param command The method to check for
|
||||
* @return true if the provider contains a handler for the method, false otherwise
|
||||
*/
|
||||
virtual bool
|
||||
[[nodiscard]] virtual bool
|
||||
contains(std::string const& command) const = 0;
|
||||
|
||||
/**
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
* @param command The method to get the handler for
|
||||
* @return The handler for the method, or std::nullopt if the method is not found
|
||||
*/
|
||||
virtual std::optional<AnyHandler>
|
||||
[[nodiscard]] virtual std::optional<AnyHandler>
|
||||
getHandler(std::string const& command) const = 0;
|
||||
|
||||
/**
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
* @param command The method to check
|
||||
* @return true if the method is Clio-only, false otherwise
|
||||
*/
|
||||
virtual bool
|
||||
[[nodiscard]] virtual bool
|
||||
isClioOnly(std::string const& command) const = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
...);
|
||||
|
||||
if (firstFailure)
|
||||
return Error{firstFailure.value()};
|
||||
return Error{*firstFailure};
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ struct AccountCursor {
|
||||
*
|
||||
* @return The string representation of the cursor
|
||||
*/
|
||||
std::string
|
||||
[[nodiscard]] std::string
|
||||
toString() const
|
||||
{
|
||||
return ripple::strHex(index) + "," + std::to_string(hint);
|
||||
@@ -168,7 +168,7 @@ struct AccountCursor {
|
||||
*
|
||||
* @return true if the cursor is non-zero, false otherwise
|
||||
*/
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isNonZero() const
|
||||
{
|
||||
return index.isNonZero() || hint != 0;
|
||||
|
||||
@@ -28,22 +28,22 @@ public:
|
||||
|
||||
ProductionAPIVersionParser(util::config::ObjectView const& config);
|
||||
|
||||
std::expected<uint32_t, std::string>
|
||||
[[nodiscard]] std::expected<uint32_t, std::string>
|
||||
parse(boost::json::object const& request) const override;
|
||||
|
||||
uint32_t
|
||||
[[nodiscard]] uint32_t
|
||||
getDefaultVersion() const
|
||||
{
|
||||
return defaultVersion_;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
[[nodiscard]] uint32_t
|
||||
getMinVersion() const
|
||||
{
|
||||
return minVersion_;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
[[nodiscard]] uint32_t
|
||||
getMaxVersion() const
|
||||
{
|
||||
return maxVersion_;
|
||||
|
||||
@@ -76,7 +76,7 @@ makeFieldChecker(std::string const& key, Checks&&... checks)
|
||||
(
|
||||
[&j, &key, &warnings, req = &checks]() {
|
||||
if (auto res = req->check(j, key); res)
|
||||
warnings.push_back(std::move(res).value());
|
||||
warnings.push_back(*std::move(res));
|
||||
}(),
|
||||
...);
|
||||
return warnings;
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
shouldForward(web::Context const& ctx) const
|
||||
{
|
||||
auto const& request = ctx.params;
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
return Result{std::move(res).value()};
|
||||
}
|
||||
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isProxied(std::string const& method) const
|
||||
{
|
||||
return RPCCenter::isForwarded(method);
|
||||
@@ -106,13 +106,13 @@ private:
|
||||
counters_.get().rpcFailedToForward(method);
|
||||
}
|
||||
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
validHandler(std::string const& method) const
|
||||
{
|
||||
return handlerProvider_->contains(method) || isProxied(method);
|
||||
}
|
||||
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isForcedForward(web::Context const& ctx) const
|
||||
{
|
||||
static constexpr auto kFORCE_FORWARD = "force_forward";
|
||||
|
||||
@@ -41,16 +41,16 @@ public:
|
||||
Counters const& counters
|
||||
);
|
||||
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
contains(std::string const& command) const override;
|
||||
|
||||
std::optional<AnyHandler>
|
||||
[[nodiscard]] std::optional<AnyHandler>
|
||||
getHandler(std::string const& command) const override;
|
||||
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
isClioOnly(std::string const& command) const override;
|
||||
|
||||
std::unordered_set<std::string>
|
||||
[[nodiscard]] std::unordered_set<std::string>
|
||||
handlerNames() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -81,13 +81,17 @@ AMMInfoHandler::process(AMMInfoHandler::Input const& input, Context const& ctx)
|
||||
ASSERT(range.has_value(), "AMMInfo's ledger range must be available");
|
||||
|
||||
auto const expectedLgrInfo = getLedgerHeaderFromHashOrSeq(
|
||||
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
|
||||
*sharedPtrBackend_,
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
auto const& lgrInfo = expectedLgrInfo.value();
|
||||
auto const& lgrInfo = *expectedLgrInfo;
|
||||
|
||||
if (input.accountID) {
|
||||
auto keylet = keylet::account(*input.accountID);
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
[[nodiscard]] Result
|
||||
process(Input const& input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -75,23 +75,30 @@ AccountChannelsHandler::process(
|
||||
auto const range = sharedPtrBackend_->fetchLedgerRange();
|
||||
ASSERT(range.has_value(), "AccountChannel's ledger range must be available");
|
||||
auto const expectedLgrInfo = getLedgerHeaderFromHashOrSeq(
|
||||
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
|
||||
*sharedPtrBackend_,
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
auto const& lgrInfo = expectedLgrInfo.value();
|
||||
auto const& lgrInfo = *expectedLgrInfo;
|
||||
auto const accountID = accountFromStringStrict(input.account);
|
||||
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
|
||||
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
ripple::keylet::account(*accountID).key,
|
||||
lgrInfo.seq,
|
||||
ctx.yield
|
||||
);
|
||||
|
||||
if (!accountLedgerObject)
|
||||
return Error{Status{RippledError::rpcACT_NOT_FOUND}};
|
||||
|
||||
auto const destAccountID = input.destinationAccount
|
||||
? accountFromStringStrict(input.destinationAccount.value())
|
||||
? accountFromStringStrict(*input.destinationAccount)
|
||||
: std::optional<ripple::AccountID>{};
|
||||
|
||||
Output response;
|
||||
@@ -107,7 +114,7 @@ AccountChannelsHandler::process(
|
||||
|
||||
auto const expectedNext = traverseOwnedNodes(
|
||||
*sharedPtrBackend_,
|
||||
*accountID,
|
||||
*accountID, // NOLINT(bugprone-unchecked-optional-access)
|
||||
lgrInfo.seq,
|
||||
input.limit,
|
||||
input.marker,
|
||||
@@ -123,7 +130,7 @@ AccountChannelsHandler::process(
|
||||
response.ledgerHash = ripple::strHex(lgrInfo.hash);
|
||||
response.ledgerIndex = lgrInfo.seq;
|
||||
|
||||
auto const nextMarker = expectedNext.value();
|
||||
auto const nextMarker = *expectedNext;
|
||||
if (nextMarker.isNonZero())
|
||||
response.marker = nextMarker.toString();
|
||||
|
||||
@@ -180,7 +187,7 @@ tag_invoke(
|
||||
};
|
||||
|
||||
if (output.marker)
|
||||
obj[JS(marker)] = output.marker.value();
|
||||
obj[JS(marker)] = *output.marker;
|
||||
|
||||
jv = std::move(obj);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
[[nodiscard]] Result
|
||||
process(Input const& input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -33,17 +33,24 @@ AccountCurrenciesHandler::process(
|
||||
auto const range = sharedPtrBackend_->fetchLedgerRange();
|
||||
ASSERT(range.has_value(), "AccountCurrencies' ledger range must be available");
|
||||
auto const expectedLgrInfo = getLedgerHeaderFromHashOrSeq(
|
||||
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
|
||||
*sharedPtrBackend_,
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
auto const& lgrInfo = expectedLgrInfo.value();
|
||||
auto const& lgrInfo = *expectedLgrInfo;
|
||||
auto const accountID = accountFromStringStrict(input.account);
|
||||
|
||||
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
|
||||
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
ripple::keylet::account(*accountID).key,
|
||||
lgrInfo.seq,
|
||||
ctx.yield
|
||||
);
|
||||
if (!accountLedgerObject)
|
||||
return Error{Status{RippledError::rpcACT_NOT_FOUND}};
|
||||
@@ -74,7 +81,7 @@ AccountCurrenciesHandler::process(
|
||||
// traverse all owned nodes, limit->max, marker->empty
|
||||
traverseOwnedNodes(
|
||||
*sharedPtrBackend_,
|
||||
*accountID,
|
||||
*accountID, // NOLINT(bugprone-unchecked-optional-access)
|
||||
lgrInfo.seq,
|
||||
std::numeric_limits<std::uint32_t>::max(),
|
||||
{},
|
||||
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
[[nodiscard]] Result
|
||||
process(Input const& input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -47,16 +47,21 @@ AccountInfoHandler::process(AccountInfoHandler::Input const& input, Context cons
|
||||
auto const range = sharedPtrBackend_->fetchLedgerRange();
|
||||
ASSERT(range.has_value(), "AccountInfo's ledger range must be available");
|
||||
auto const expectedLgrInfo = getLedgerHeaderFromHashOrSeq(
|
||||
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
|
||||
*sharedPtrBackend_,
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
auto const& lgrInfo = expectedLgrInfo.value();
|
||||
auto const& lgrInfo = *expectedLgrInfo;
|
||||
auto const accountStr = input.account.value_or(input.ident.value_or(""));
|
||||
auto const accountID = accountFromStringStrict(accountStr);
|
||||
auto const accountKeylet = ripple::keylet::account(*accountID);
|
||||
auto const accountKeylet =
|
||||
ripple::keylet::account(*accountID); // NOLINT(bugprone-unchecked-optional-access)
|
||||
auto const accountLedgerObject =
|
||||
sharedPtrBackend_->fetchLedgerObject(accountKeylet.key, lgrInfo.seq, ctx.yield);
|
||||
|
||||
@@ -94,7 +99,8 @@ AccountInfoHandler::process(AccountInfoHandler::Input const& input, Context cons
|
||||
if (input.signerLists) {
|
||||
// We put the SignerList in an array because of an anticipated
|
||||
// future when we support multiple signer lists on one account.
|
||||
auto const signersKey = ripple::keylet::signers(*accountID);
|
||||
auto const signersKey =
|
||||
ripple::keylet::signers(*accountID); // NOLINT(bugprone-unchecked-optional-access)
|
||||
|
||||
// This code will need to be revisited if in the future we
|
||||
// support multiple SignerLists on one account.
|
||||
@@ -184,8 +190,8 @@ tag_invoke(
|
||||
if (output.signerLists) {
|
||||
auto signers = boost::json::array();
|
||||
std::transform(
|
||||
std::cbegin(output.signerLists.value()),
|
||||
std::cend(output.signerLists.value()),
|
||||
std::cbegin(*output.signerLists),
|
||||
std::cend(*output.signerLists),
|
||||
std::back_inserter(signers),
|
||||
[](auto const& signerList) { return toJson(signerList); }
|
||||
);
|
||||
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
[[nodiscard]] Result
|
||||
process(Input const& input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -124,16 +124,23 @@ AccountLinesHandler::process(AccountLinesHandler::Input const& input, Context co
|
||||
auto const range = sharedPtrBackend_->fetchLedgerRange();
|
||||
ASSERT(range.has_value(), "AccountLines' ledger range must be available");
|
||||
auto const expectedLgrInfo = getLedgerHeaderFromHashOrSeq(
|
||||
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
|
||||
*sharedPtrBackend_,
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
auto const& lgrInfo = expectedLgrInfo.value();
|
||||
auto const& lgrInfo = *expectedLgrInfo;
|
||||
auto const accountID = accountFromStringStrict(input.account);
|
||||
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
|
||||
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
ripple::keylet::account(*accountID).key,
|
||||
lgrInfo.seq,
|
||||
ctx.yield
|
||||
);
|
||||
|
||||
if (not accountLedgerObject)
|
||||
@@ -163,7 +170,7 @@ AccountLinesHandler::process(AccountLinesHandler::Input const& input, Context co
|
||||
|
||||
auto const expectedNext = traverseOwnedNodes(
|
||||
*sharedPtrBackend_,
|
||||
*accountID,
|
||||
*accountID, // NOLINT(bugprone-unchecked-optional-access)
|
||||
lgrInfo.seq,
|
||||
input.limit,
|
||||
input.marker,
|
||||
@@ -174,7 +181,7 @@ AccountLinesHandler::process(AccountLinesHandler::Input const& input, Context co
|
||||
if (not expectedNext.has_value())
|
||||
return Error{expectedNext.error()};
|
||||
|
||||
auto const nextMarker = expectedNext.value();
|
||||
auto const nextMarker = *expectedNext;
|
||||
|
||||
response.account = input.account;
|
||||
response.limit = input.limit; // not documented,
|
||||
@@ -238,7 +245,7 @@ tag_invoke(
|
||||
};
|
||||
|
||||
if (output.marker)
|
||||
obj[JS(marker)] = output.marker.value();
|
||||
obj[JS(marker)] = *output.marker;
|
||||
|
||||
jv = std::move(obj);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public:
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
[[nodiscard]] Result
|
||||
process(Input const& input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -106,16 +106,23 @@ AccountMPTokenIssuancesHandler::process(
|
||||
auto const range = sharedPtrBackend_->fetchLedgerRange();
|
||||
ASSERT(range.has_value(), "AccountMPTokenIssuances' ledger range must be available");
|
||||
auto const expectedLgrInfo = getLedgerHeaderFromHashOrSeq(
|
||||
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
|
||||
*sharedPtrBackend_,
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
auto const& lgrInfo = expectedLgrInfo.value();
|
||||
auto const& lgrInfo = *expectedLgrInfo;
|
||||
auto const accountID = accountFromStringStrict(input.account);
|
||||
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
|
||||
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
ripple::keylet::account(*accountID).key,
|
||||
lgrInfo.seq,
|
||||
ctx.yield
|
||||
);
|
||||
|
||||
if (not accountLedgerObject.has_value())
|
||||
@@ -132,7 +139,7 @@ AccountMPTokenIssuancesHandler::process(
|
||||
|
||||
auto const expectedNext = traverseOwnedNodes(
|
||||
*sharedPtrBackend_,
|
||||
*accountID,
|
||||
*accountID, // NOLINT(bugprone-unchecked-optional-access)
|
||||
lgrInfo.seq,
|
||||
input.limit,
|
||||
input.marker,
|
||||
@@ -143,7 +150,7 @@ AccountMPTokenIssuancesHandler::process(
|
||||
if (not expectedNext.has_value())
|
||||
return Error{expectedNext.error()};
|
||||
|
||||
auto const nextMarker = expectedNext.value();
|
||||
auto const nextMarker = *expectedNext;
|
||||
|
||||
response.account = input.account;
|
||||
response.limit = input.limit;
|
||||
|
||||
@@ -145,7 +145,7 @@ public:
|
||||
* @param ctx The context of the request.
|
||||
* @return The result of the operation.
|
||||
*/
|
||||
Result
|
||||
[[nodiscard]] Result
|
||||
process(Input const& input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -63,16 +63,23 @@ AccountMPTokensHandler::process(
|
||||
auto const range = sharedPtrBackend_->fetchLedgerRange();
|
||||
ASSERT(range.has_value(), "AccountMPTokens' ledger range must be available");
|
||||
auto const expectedLgrInfo = getLedgerHeaderFromHashOrSeq(
|
||||
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
|
||||
*sharedPtrBackend_,
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
auto const& lgrInfo = expectedLgrInfo.value();
|
||||
auto const& lgrInfo = *expectedLgrInfo;
|
||||
auto const accountID = accountFromStringStrict(input.account);
|
||||
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
|
||||
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
ripple::keylet::account(*accountID).key,
|
||||
lgrInfo.seq,
|
||||
ctx.yield
|
||||
);
|
||||
|
||||
if (not accountLedgerObject.has_value())
|
||||
@@ -89,7 +96,7 @@ AccountMPTokensHandler::process(
|
||||
|
||||
auto const expectedNext = traverseOwnedNodes(
|
||||
*sharedPtrBackend_,
|
||||
*accountID,
|
||||
*accountID, // NOLINT(bugprone-unchecked-optional-access)
|
||||
lgrInfo.seq,
|
||||
input.limit,
|
||||
input.marker,
|
||||
@@ -100,7 +107,7 @@ AccountMPTokensHandler::process(
|
||||
if (not expectedNext.has_value())
|
||||
return Error{expectedNext.error()};
|
||||
|
||||
auto const& nextMarker = expectedNext.value();
|
||||
auto const& nextMarker = *expectedNext;
|
||||
|
||||
response.account = input.account;
|
||||
response.limit = input.limit;
|
||||
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
* @param ctx The context of the request.
|
||||
* @return The result of the operation.
|
||||
*/
|
||||
Result
|
||||
[[nodiscard]] Result
|
||||
process(Input const& input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -36,16 +36,23 @@ AccountNFTsHandler::process(AccountNFTsHandler::Input const& input, Context cons
|
||||
auto const range = sharedPtrBackend_->fetchLedgerRange();
|
||||
ASSERT(range.has_value(), "AccountNFT's ledger range must be available");
|
||||
auto const expectedLgrInfo = getLedgerHeaderFromHashOrSeq(
|
||||
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
|
||||
*sharedPtrBackend_,
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
auto const& lgrInfo = expectedLgrInfo.value();
|
||||
auto const& lgrInfo = *expectedLgrInfo;
|
||||
auto const accountID = accountFromStringStrict(input.account);
|
||||
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
|
||||
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
ripple::keylet::account(*accountID).key,
|
||||
lgrInfo.seq,
|
||||
ctx.yield
|
||||
);
|
||||
|
||||
if (!accountLedgerObject)
|
||||
@@ -59,6 +66,7 @@ AccountNFTsHandler::process(AccountNFTsHandler::Input const& input, Context cons
|
||||
|
||||
// if a marker was passed, start at the page specified in marker. Else, start at the max page
|
||||
auto const pageKey = input.marker ? ripple::uint256{input.marker->c_str()}
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
: ripple::keylet::nftpage_max(*accountID).key;
|
||||
auto const blob = sharedPtrBackend_->fetchLedgerObject(pageKey, lgrInfo.seq, ctx.yield);
|
||||
|
||||
@@ -113,6 +121,7 @@ AccountNFTsHandler::process(AccountNFTsHandler::Input const& input, Context cons
|
||||
auto const nextBlob =
|
||||
sharedPtrBackend_->fetchLedgerObject(nextKey.key, lgrInfo.seq, ctx.yield);
|
||||
page.emplace(
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
ripple::SLE{ripple::SerialIter{nextBlob->data(), nextBlob->size()}, nextKey.key}
|
||||
);
|
||||
} else {
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
[[nodiscard]] Result
|
||||
process(Input const& input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -37,16 +37,23 @@ AccountObjectsHandler::process(AccountObjectsHandler::Input const& input, Contex
|
||||
auto const range = sharedPtrBackend_->fetchLedgerRange();
|
||||
ASSERT(range.has_value(), "AccountObject's ledger range must be available");
|
||||
auto const expectedLgrInfo = getLedgerHeaderFromHashOrSeq(
|
||||
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
|
||||
*sharedPtrBackend_,
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
auto const& lgrInfo = expectedLgrInfo.value();
|
||||
auto const& lgrInfo = *expectedLgrInfo;
|
||||
auto const accountID = accountFromStringStrict(input.account);
|
||||
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
|
||||
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
ripple::keylet::account(*accountID).key,
|
||||
lgrInfo.seq,
|
||||
ctx.yield
|
||||
);
|
||||
|
||||
if (!accountLedgerObject)
|
||||
@@ -73,9 +80,8 @@ AccountObjectsHandler::process(AccountObjectsHandler::Input const& input, Contex
|
||||
Output response;
|
||||
auto const addToResponse = [&](ripple::SLE&& sle) {
|
||||
if (not typeFilter or
|
||||
std::find(
|
||||
std::begin(typeFilter.value()), std::end(typeFilter.value()), sle.getType()
|
||||
) != std::end(typeFilter.value())) {
|
||||
std::find(std::begin(*typeFilter), std::end(*typeFilter), sle.getType()) !=
|
||||
std::end(*typeFilter)) {
|
||||
response.accountObjects.push_back(std::move(sle));
|
||||
}
|
||||
return true;
|
||||
@@ -83,7 +89,7 @@ AccountObjectsHandler::process(AccountObjectsHandler::Input const& input, Contex
|
||||
|
||||
auto const expectedNext = traverseOwnedNodes(
|
||||
*sharedPtrBackend_,
|
||||
*accountID,
|
||||
*accountID, // NOLINT(bugprone-unchecked-optional-access)
|
||||
lgrInfo.seq,
|
||||
input.limit,
|
||||
input.marker,
|
||||
@@ -100,7 +106,7 @@ AccountObjectsHandler::process(AccountObjectsHandler::Input const& input, Contex
|
||||
response.limit = input.limit;
|
||||
response.account = input.account;
|
||||
|
||||
auto const& nextMarker = expectedNext.value();
|
||||
auto const& nextMarker = *expectedNext;
|
||||
|
||||
if (nextMarker.isNonZero())
|
||||
response.marker = nextMarker.toString();
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
[[nodiscard]] Result
|
||||
process(Input const& input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -53,23 +53,30 @@ AccountOffersHandler::process(AccountOffersHandler::Input const& input, Context
|
||||
auto const range = sharedPtrBackend_->fetchLedgerRange();
|
||||
ASSERT(range.has_value(), "AccountOffer's ledger range must be available");
|
||||
auto const expectedLgrInfo = getLedgerHeaderFromHashOrSeq(
|
||||
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
|
||||
*sharedPtrBackend_,
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
auto const& lgrInfo = expectedLgrInfo.value();
|
||||
auto const& lgrInfo = *expectedLgrInfo;
|
||||
auto const accountID = accountFromStringStrict(input.account);
|
||||
auto const accountLedgerObject = sharedPtrBackend_->fetchLedgerObject(
|
||||
ripple::keylet::account(*accountID).key, lgrInfo.seq, ctx.yield
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
ripple::keylet::account(*accountID).key,
|
||||
lgrInfo.seq,
|
||||
ctx.yield
|
||||
);
|
||||
|
||||
if (!accountLedgerObject)
|
||||
return Error{Status{RippledError::rpcACT_NOT_FOUND}};
|
||||
|
||||
Output response;
|
||||
response.account = ripple::to_string(*accountID);
|
||||
response.account = ripple::to_string(*accountID); // NOLINT(bugprone-unchecked-optional-access)
|
||||
response.ledgerHash = ripple::strHex(lgrInfo.hash);
|
||||
response.ledgerIndex = lgrInfo.seq;
|
||||
|
||||
@@ -82,7 +89,7 @@ AccountOffersHandler::process(AccountOffersHandler::Input const& input, Context
|
||||
|
||||
auto const expectedNext = traverseOwnedNodes(
|
||||
*sharedPtrBackend_,
|
||||
*accountID,
|
||||
*accountID, // NOLINT(bugprone-unchecked-optional-access)
|
||||
lgrInfo.seq,
|
||||
input.limit,
|
||||
input.marker,
|
||||
@@ -93,7 +100,7 @@ AccountOffersHandler::process(AccountOffersHandler::Input const& input, Context
|
||||
if (not expectedNext.has_value())
|
||||
return Error{expectedNext.error()};
|
||||
|
||||
auto const nextMarker = expectedNext.value();
|
||||
auto const nextMarker = *expectedNext;
|
||||
|
||||
if (nextMarker.isNonZero())
|
||||
response.marker = nextMarker.toString();
|
||||
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
[[nodiscard]] Result
|
||||
process(Input const& input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -38,12 +38,14 @@ AccountTxHandler::process(AccountTxHandler::Input const& input, Context const& c
|
||||
auto const range = sharedPtrBackend_->fetchLedgerRange();
|
||||
ASSERT(range.has_value(), "AccountTX's ledger range must be available");
|
||||
|
||||
auto [minIndex, maxIndex] = *range;
|
||||
auto [minIndex, maxIndex] = *range; // NOLINT(bugprone-unchecked-optional-access)
|
||||
|
||||
if (input.ledgerIndexMin) {
|
||||
if (ctx.apiVersion > 1u &&
|
||||
(input.ledgerIndexMin > range->maxSequence ||
|
||||
input.ledgerIndexMin < range->minSequence)) {
|
||||
(input.ledgerIndexMin >
|
||||
range->maxSequence || // NOLINT(bugprone-unchecked-optional-access)
|
||||
input.ledgerIndexMin <
|
||||
range->minSequence)) { // NOLINT(bugprone-unchecked-optional-access)
|
||||
return Error{Status{RippledError::rpcLGR_IDX_MALFORMED, "ledgerSeqMinOutOfRange"}};
|
||||
}
|
||||
|
||||
@@ -53,8 +55,10 @@ AccountTxHandler::process(AccountTxHandler::Input const& input, Context const& c
|
||||
|
||||
if (input.ledgerIndexMax) {
|
||||
if (ctx.apiVersion > 1u &&
|
||||
(input.ledgerIndexMax > range->maxSequence ||
|
||||
input.ledgerIndexMax < range->minSequence)) {
|
||||
(input.ledgerIndexMax >
|
||||
range->maxSequence || // NOLINT(bugprone-unchecked-optional-access)
|
||||
input.ledgerIndexMax <
|
||||
range->minSequence)) { // NOLINT(bugprone-unchecked-optional-access)
|
||||
return Error{Status{RippledError::rpcLGR_IDX_MALFORMED, "ledgerSeqMaxOutOfRange"}};
|
||||
}
|
||||
|
||||
@@ -84,13 +88,13 @@ AccountTxHandler::process(AccountTxHandler::Input const& input, Context const& c
|
||||
ctx.yield,
|
||||
input.ledgerHash,
|
||||
input.ledgerIndex,
|
||||
range->maxSequence
|
||||
range->maxSequence // NOLINT(bugprone-unchecked-optional-access)
|
||||
);
|
||||
|
||||
if (not expectedLgrInfo.has_value())
|
||||
return Error{expectedLgrInfo.error()};
|
||||
|
||||
maxIndex = minIndex = expectedLgrInfo.value().seq;
|
||||
maxIndex = minIndex = expectedLgrInfo->seq;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +150,7 @@ AccountTxHandler::process(AccountTxHandler::Input const& input, Context const& c
|
||||
|
||||
if (txn.contains(JS(TransactionType)) && input.transactionTypeInLowercase.has_value() &&
|
||||
util::toLower(boost::json::value_to<std::string>(txn[JS(TransactionType)])) !=
|
||||
input.transactionTypeInLowercase.value())
|
||||
*input.transactionTypeInLowercase)
|
||||
continue;
|
||||
|
||||
if (!input.binary) {
|
||||
@@ -166,7 +170,7 @@ AccountTxHandler::process(AccountTxHandler::Input const& input, Context const& c
|
||||
if (auto const& ctid =
|
||||
rpc::encodeCTID(txnPlusMeta.ledgerSequence, txnIdx, networkID);
|
||||
ctid)
|
||||
obj[txKey].as_object()[JS(ctid)] = ctid.value();
|
||||
obj[txKey].as_object()[JS(ctid)] = *ctid;
|
||||
}
|
||||
|
||||
obj[txKey].as_object()[JS(date)] = txnPlusMeta.date;
|
||||
@@ -201,7 +205,7 @@ AccountTxHandler::process(AccountTxHandler::Input const& input, Context const& c
|
||||
}
|
||||
|
||||
response.limit = input.limit;
|
||||
response.account = ripple::to_string(*accountID);
|
||||
response.account = ripple::to_string(*accountID); // NOLINT(bugprone-unchecked-optional-access)
|
||||
response.ledgerIndexMin = minIndex;
|
||||
response.ledgerIndexMax = maxIndex;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user