mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-19 21:30:56 +00:00
Merge branch 'develop' into ripple/wasmi
This commit is contained in:
@@ -75,6 +75,8 @@ Checks: "-*,
|
||||
# readability-static-accessed-through-instance, # this check is probably unnecessary. It makes the code less readable
|
||||
# ---
|
||||
|
||||
FormatStyle: file
|
||||
|
||||
CheckOptions:
|
||||
bugprone-unsafe-functions.ReportMoreUnsafeFunctions: true
|
||||
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
|
||||
@@ -83,6 +85,8 @@ CheckOptions:
|
||||
|
||||
readability-braces-around-statements.ShortStatementLines: 2
|
||||
readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
|
||||
readability-identifier-naming.NamespaceCase: lower_case
|
||||
readability-identifier-naming.InlineNamespaceCase: lower_case
|
||||
readability-identifier-naming.ClassCase: CamelCase
|
||||
readability-identifier-naming.StructCase: CamelCase
|
||||
readability-identifier-naming.UnionCase: CamelCase
|
||||
|
||||
@@ -30,7 +30,9 @@ ignoreRegExpList:
|
||||
- ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
- ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
overrides:
|
||||
- filename: "**/*_test.cpp" # all test files
|
||||
- filename:
|
||||
- "**/*_test.cpp" # legacy boost.test files
|
||||
- "src/tests/**/*.cpp" # gtest test files
|
||||
ignoreRegExpList:
|
||||
- /"[^"]*"/g # double-quoted strings
|
||||
- /'[^']*'/g # single-quoted strings
|
||||
@@ -172,7 +174,6 @@ words:
|
||||
- MPTAMM
|
||||
- MPTDEX
|
||||
- Merkle
|
||||
- Metafuncton
|
||||
- misprediction
|
||||
- missingok
|
||||
- mptbalance
|
||||
|
||||
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@@ -15,3 +15,7 @@ updates:
|
||||
commit-message:
|
||||
prefix: "ci: [DEPENDABOT] "
|
||||
target-branch: develop
|
||||
groups:
|
||||
github-actions:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
18
.github/scripts/levelization/README.md
vendored
18
.github/scripts/levelization/README.md
vendored
@@ -40,18 +40,18 @@ listed later.
|
||||
| 04 | xrpl/protocol |
|
||||
| 05 | xrpl/core xrpl/resource xrpl/server |
|
||||
| 06 | xrpl/ledger xrpl/nodestore xrpl/net |
|
||||
| 07 | xrpl/shamap |
|
||||
| 07 | xrpl/shamap xrpl/consensus |
|
||||
|
||||
## xrpld Modules (Application Implementation)
|
||||
|
||||
| Level / Tier | Module(s) |
|
||||
| ------------ | -------------------------------- |
|
||||
| 05 | xrpld/conditions xrpld/consensus |
|
||||
| 06 | xrpld/core xrpld/peerfinder |
|
||||
| 07 | xrpld/shamap xrpld/overlay |
|
||||
| 08 | xrpld/app |
|
||||
| 09 | xrpld/rpc |
|
||||
| 10 | xrpld/perflog |
|
||||
| Level / Tier | Module(s) |
|
||||
| ------------ | --------------------------- |
|
||||
| 05 | xrpld/conditions |
|
||||
| 06 | xrpld/core xrpld/peerfinder |
|
||||
| 07 | xrpld/shamap xrpld/overlay |
|
||||
| 08 | xrpld/app |
|
||||
| 09 | xrpld/rpc |
|
||||
| 10 | xrpld/perflog |
|
||||
|
||||
## Test Modules
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
Loop: xrpld.app xrpld.overlay
|
||||
xrpld.app > xrpld.overlay
|
||||
|
||||
Loop: xrpld.app xrpld.peerfinder
|
||||
xrpld.peerfinder ~= xrpld.app
|
||||
|
||||
Loop: xrpld.app xrpld.rpc
|
||||
xrpld.rpc > xrpld.app
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ libxrpl.conditions > xrpl.basics
|
||||
libxrpl.conditions > xrpl.conditions
|
||||
libxrpl.config > xrpl.basics
|
||||
libxrpl.config > xrpl.config
|
||||
libxrpl.consensus > xrpl.basics
|
||||
libxrpl.consensus > xrpl.consensus
|
||||
libxrpl.core > xrpl.basics
|
||||
libxrpl.core > xrpl.core
|
||||
libxrpl.core > xrpl.json
|
||||
@@ -25,6 +27,9 @@ libxrpl.nodestore > xrpl.config
|
||||
libxrpl.nodestore > xrpl.json
|
||||
libxrpl.nodestore > xrpl.nodestore
|
||||
libxrpl.nodestore > xrpl.protocol
|
||||
libxrpl.peerfinder > xrpl.basics
|
||||
libxrpl.peerfinder > xrpl.peerfinder
|
||||
libxrpl.peerfinder > xrpl.protocol
|
||||
libxrpl.protocol > xrpl.basics
|
||||
libxrpl.protocol > xrpl.json
|
||||
libxrpl.protocol > xrpl.protocol
|
||||
@@ -60,9 +65,9 @@ test.app > test.jtx
|
||||
test.app > test.unit_test
|
||||
test.app > xrpl.basics
|
||||
test.app > xrpl.config
|
||||
test.app > xrpl.consensus
|
||||
test.app > xrpl.core
|
||||
test.app > xrpld.app
|
||||
test.app > xrpld.consensus
|
||||
test.app > xrpld.core
|
||||
test.app > xrpld.overlay
|
||||
test.app > xrpld.rpc
|
||||
@@ -83,12 +88,9 @@ test.basics > xrpl.protocol
|
||||
test.beast > xrpl.basics
|
||||
test.conditions > xrpl.basics
|
||||
test.conditions > xrpl.conditions
|
||||
test.consensus > test.csf
|
||||
test.consensus > test.jtx
|
||||
test.consensus > test.unit_test
|
||||
test.consensus > xrpl.basics
|
||||
test.consensus > xrpld.app
|
||||
test.consensus > xrpld.consensus
|
||||
test.consensus > xrpl.ledger
|
||||
test.consensus > xrpl.protocol
|
||||
test.consensus > xrpl.shamap
|
||||
@@ -103,10 +105,6 @@ test.core > xrpl.json
|
||||
test.core > xrpl.protocol
|
||||
test.core > xrpl.rdb
|
||||
test.core > xrpl.server
|
||||
test.csf > xrpl.basics
|
||||
test.csf > xrpld.consensus
|
||||
test.csf > xrpl.json
|
||||
test.csf > xrpl.ledger
|
||||
test.json > test.jtx
|
||||
test.json > xrpl.json
|
||||
test.jtx > test.unit_test
|
||||
@@ -132,12 +130,9 @@ test.ledger > xrpl.json
|
||||
test.ledger > xrpl.ledger
|
||||
test.ledger > xrpl.protocol
|
||||
test.nodestore > test.jtx
|
||||
test.nodestore > test.unit_test
|
||||
test.nodestore > xrpl.basics
|
||||
test.nodestore > xrpl.config
|
||||
test.nodestore > xrpld.core
|
||||
test.nodestore > xrpl.nodestore
|
||||
test.nodestore > xrpl.protocol
|
||||
test.nodestore > xrpl.rdb
|
||||
test.overlay > test.jtx
|
||||
test.overlay > test.unit_test
|
||||
@@ -146,19 +141,13 @@ test.overlay > xrpl.config
|
||||
test.overlay > xrpld.app
|
||||
test.overlay > xrpld.core
|
||||
test.overlay > xrpld.overlay
|
||||
test.overlay > xrpld.peerfinder
|
||||
test.overlay > xrpl.json
|
||||
test.overlay > xrpl.nodestore
|
||||
test.overlay > xrpl.peerfinder
|
||||
test.overlay > xrpl.protocol
|
||||
test.overlay > xrpl.resource
|
||||
test.overlay > xrpl.server
|
||||
test.overlay > xrpl.shamap
|
||||
test.peerfinder > test.beast
|
||||
test.peerfinder > test.unit_test
|
||||
test.peerfinder > xrpl.basics
|
||||
test.peerfinder > xrpld.core
|
||||
test.peerfinder > xrpld.peerfinder
|
||||
test.peerfinder > xrpl.protocol
|
||||
test.protocol > test.jtx
|
||||
test.protocol > test.unit_test
|
||||
test.protocol > xrpl.basics
|
||||
@@ -192,11 +181,13 @@ test.unit_test > xrpl.basics
|
||||
test.unit_test > xrpl.protocol
|
||||
tests.libxrpl > xrpl.basics
|
||||
tests.libxrpl > xrpl.config
|
||||
tests.libxrpl > xrpl.consensus
|
||||
tests.libxrpl > xrpl.core
|
||||
tests.libxrpl > xrpl.json
|
||||
tests.libxrpl > xrpl.ledger
|
||||
tests.libxrpl > xrpl.net
|
||||
tests.libxrpl > xrpl.nodestore
|
||||
tests.libxrpl > xrpl.peerfinder
|
||||
tests.libxrpl > xrpl.protocol
|
||||
tests.libxrpl > xrpl.protocol_autogen
|
||||
tests.libxrpl > xrpl.resource
|
||||
@@ -206,6 +197,10 @@ tests.libxrpl > xrpl.tx
|
||||
xrpl.conditions > xrpl.basics
|
||||
xrpl.conditions > xrpl.protocol
|
||||
xrpl.config > xrpl.basics
|
||||
xrpl.consensus > xrpl.basics
|
||||
xrpl.consensus > xrpl.json
|
||||
xrpl.consensus > xrpl.ledger
|
||||
xrpl.consensus > xrpl.protocol
|
||||
xrpl.core > xrpl.basics
|
||||
xrpl.core > xrpl.json
|
||||
xrpl.core > xrpl.protocol
|
||||
@@ -220,6 +215,8 @@ xrpl.nodestore > xrpl.basics
|
||||
xrpl.nodestore > xrpl.config
|
||||
xrpl.nodestore > xrpl.json
|
||||
xrpl.nodestore > xrpl.protocol
|
||||
xrpl.peerfinder > xrpl.basics
|
||||
xrpl.peerfinder > xrpl.protocol
|
||||
xrpl.protocol > xrpl.basics
|
||||
xrpl.protocol > xrpl.json
|
||||
xrpl.protocol_autogen > xrpl.json
|
||||
@@ -246,23 +243,20 @@ xrpl.tx > xrpl.protocol
|
||||
xrpld.app > test.unit_test
|
||||
xrpld.app > xrpl.basics
|
||||
xrpld.app > xrpl.config
|
||||
xrpld.app > xrpl.consensus
|
||||
xrpld.app > xrpl.core
|
||||
xrpld.app > xrpld.consensus
|
||||
xrpld.app > xrpld.core
|
||||
xrpld.app > xrpl.json
|
||||
xrpld.app > xrpl.ledger
|
||||
xrpld.app > xrpl.net
|
||||
xrpld.app > xrpl.nodestore
|
||||
xrpld.app > xrpl.peerfinder
|
||||
xrpld.app > xrpl.protocol
|
||||
xrpld.app > xrpl.rdb
|
||||
xrpld.app > xrpl.resource
|
||||
xrpld.app > xrpl.server
|
||||
xrpld.app > xrpl.shamap
|
||||
xrpld.app > xrpl.tx
|
||||
xrpld.consensus > xrpl.basics
|
||||
xrpld.consensus > xrpl.json
|
||||
xrpld.consensus > xrpl.ledger
|
||||
xrpld.consensus > xrpl.protocol
|
||||
xrpld.core > xrpl.basics
|
||||
xrpld.core > xrpl.config
|
||||
xrpld.core > xrpl.core
|
||||
@@ -271,21 +265,22 @@ xrpld.core > xrpl.protocol
|
||||
xrpld.core > xrpl.rdb
|
||||
xrpld.overlay > xrpl.basics
|
||||
xrpld.overlay > xrpl.config
|
||||
xrpld.overlay > xrpl.consensus
|
||||
xrpld.overlay > xrpl.core
|
||||
xrpld.overlay > xrpld.consensus
|
||||
xrpld.overlay > xrpld.core
|
||||
xrpld.overlay > xrpld.peerfinder
|
||||
xrpld.overlay > xrpl.json
|
||||
xrpld.overlay > xrpl.ledger
|
||||
xrpld.overlay > xrpl.peerfinder
|
||||
xrpld.overlay > xrpl.protocol
|
||||
xrpld.overlay > xrpl.resource
|
||||
xrpld.overlay > xrpl.server
|
||||
xrpld.overlay > xrpl.shamap
|
||||
xrpld.overlay > xrpl.tx
|
||||
xrpld.peerfinder > xrpl.basics
|
||||
xrpld.peerfinder > xrpl.config
|
||||
xrpld.peerfinder > xrpld.app
|
||||
xrpld.peerfinder > xrpld.core
|
||||
xrpld.peerfinder > xrpl.protocol
|
||||
xrpld.peerfinder > xrpl.peerfinder
|
||||
xrpld.peerfinder > xrpl.rdb
|
||||
xrpld.perflog > xrpl.basics
|
||||
xrpld.perflog > xrpl.config
|
||||
|
||||
3
.github/scripts/rename/namespace.sh
vendored
3
.github/scripts/rename/namespace.sh
vendored
@@ -46,9 +46,6 @@ for DIRECTORY in "${DIRECTORIES[@]}"; do
|
||||
done
|
||||
done
|
||||
|
||||
# Special case for NuDBFactory that has ripple twice in the test suite name.
|
||||
${SED_COMMAND} -i -E 's/(BEAST_DEFINE_TESTSUITE.+)ripple(.+)/\1xrpl\2/g' src/test/nodestore/NuDBFactory_test.cpp
|
||||
|
||||
DIRECTORY=$1
|
||||
find "${DIRECTORY}" -type f -name "*.md" | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
|
||||
19
.github/scripts/strategy-matrix/linux.json
vendored
19
.github/scripts/strategy-matrix/linux.json
vendored
@@ -1,13 +1,22 @@
|
||||
{
|
||||
"image_tag": "sha-3122de8",
|
||||
"image_tag": "sha-fecfc0c",
|
||||
"configs": {
|
||||
"ubuntu": [
|
||||
{
|
||||
"compiler": ["gcc"],
|
||||
"build_type": ["Debug"],
|
||||
"arch": ["amd64"],
|
||||
"minimal": true,
|
||||
"suffix": "coverage",
|
||||
"extra_cmake_args": "-DUNIT_TEST_REFERENCE_FEE=500 -Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0"
|
||||
},
|
||||
{
|
||||
"compiler": ["clang"],
|
||||
"build_type": ["Release"],
|
||||
"arch": ["amd64"],
|
||||
"minimal": true
|
||||
},
|
||||
|
||||
{
|
||||
"compiler": ["gcc"],
|
||||
"build_type": ["Release"],
|
||||
@@ -29,14 +38,6 @@
|
||||
"sanitizers": ["address", "undefinedbehavior"]
|
||||
},
|
||||
|
||||
{
|
||||
"compiler": ["gcc"],
|
||||
"build_type": ["Debug"],
|
||||
"arch": ["amd64"],
|
||||
"minimal": true,
|
||||
"suffix": "coverage",
|
||||
"extra_cmake_args": "-DUNIT_TEST_REFERENCE_FEE=500 -Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0"
|
||||
},
|
||||
{
|
||||
"compiler": ["clang"],
|
||||
"build_type": ["Debug"],
|
||||
|
||||
2
.github/workflows/build-nix-images.yml
vendored
2
.github/workflows/build-nix-images.yml
vendored
@@ -13,6 +13,7 @@ on:
|
||||
- "!nix/docker/README.md"
|
||||
- "!nix/devshell.nix"
|
||||
- "bin/check-tools.sh"
|
||||
- "bin/default-loader-path.sh"
|
||||
- "bin/install-sanitizer-libs.sh"
|
||||
pull_request:
|
||||
paths:
|
||||
@@ -24,6 +25,7 @@ on:
|
||||
- "!nix/docker/README.md"
|
||||
- "!nix/devshell.nix"
|
||||
- "bin/check-tools.sh"
|
||||
- "bin/default-loader-path.sh"
|
||||
- "bin/install-sanitizer-libs.sh"
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
2
.github/workflows/check-pr-description.yml
vendored
2
.github/workflows/check-pr-description.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Write PR body to file
|
||||
env:
|
||||
|
||||
114
.github/workflows/check-tools.yml
vendored
Normal file
114
.github/workflows/check-tools.yml
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
# Verifies the committed snapshots of `bin/check-tools.sh` output for each Nix
|
||||
# environment (see nix/check-tools/). If the environment changes — a new image
|
||||
# tag, an updated flake.lock, a different tool list — without the matching
|
||||
# snapshot being regenerated and committed, this workflow fails so the drift is
|
||||
# caught in review.
|
||||
#
|
||||
# To regenerate the snapshots, see nix/check-tools/README.md.
|
||||
name: Check tools
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/check-tools.yml"
|
||||
- ".github/scripts/strategy-matrix/linux.json"
|
||||
- "bin/check-tools.sh"
|
||||
- "nix/**"
|
||||
- "flake.nix"
|
||||
- "flake.lock"
|
||||
- "rust-toolchain.toml"
|
||||
push:
|
||||
branches:
|
||||
- "develop"
|
||||
paths:
|
||||
- ".github/workflows/check-tools.yml"
|
||||
- ".github/scripts/strategy-matrix/linux.json"
|
||||
- "bin/check-tools.sh"
|
||||
- "nix/**"
|
||||
- "flake.nix"
|
||||
- "flake.lock"
|
||||
- "rust-toolchain.toml"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
# The nix-nixos image tag is pinned alongside the build matrix in linux.json,
|
||||
# so snapshots are checked against the exact image CI builds against.
|
||||
linux-image-tag:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
tag: ${{ steps.tag.outputs.tag }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Read nix image tag
|
||||
id: tag
|
||||
run: echo "tag=$(jq -r .image_tag .github/scripts/strategy-matrix/linux.json)" >>"${GITHUB_OUTPUT}"
|
||||
|
||||
# One job for all environments; they differ only in whether the tools come
|
||||
# from the nix-nixos container (Linux) or `nix develop` (macOS).
|
||||
check-tools:
|
||||
needs: linux-image-tag
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- runner: ubuntu-latest
|
||||
snapshot: nix/check-tools/nix-ubuntu-amd64.txt
|
||||
nix_develop: false
|
||||
- runner: ubuntu-24.04-arm
|
||||
snapshot: nix/check-tools/nix-ubuntu-arm64.txt
|
||||
nix_develop: false
|
||||
- runner: macos-26-apple-clang-21
|
||||
snapshot: nix/check-tools/macos.txt
|
||||
nix_develop: true
|
||||
runs-on: ${{ matrix.runner }}
|
||||
# Linux runs inside the pinned nix-nixos image; macOS runs natively and uses
|
||||
# the flake's dev shell instead (see the run step below).
|
||||
container: ${{ !matrix.nix_develop && format('ghcr.io/xrplf/xrpld/nix-ubuntu:{0}', needs.linux-image-tag.outputs.tag) || null }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
- name: Regenerate snapshot
|
||||
env:
|
||||
CHECK_TOOLS_SKIP_CLONE: "1"
|
||||
# check-tools.sh skips some macOS tools when CI is set; the snapshots
|
||||
# capture the full `nix develop` environment, so unset it here.
|
||||
CI: ""
|
||||
run: |
|
||||
if [ "${{ matrix.nix_develop }}" = "true" ]; then
|
||||
# `nix develop` prints the dev-shell greeting first; keep only the
|
||||
# check-tools.sh output (from the "Detected OS:" line onward).
|
||||
nix --extra-experimental-features "nix-command flakes" develop \
|
||||
-c bash bin/check-tools.sh | sed -n '/^Detected OS:/,$p' >"${{ matrix.snapshot }}"
|
||||
else
|
||||
bash bin/check-tools.sh >"${{ matrix.snapshot }}"
|
||||
fi
|
||||
|
||||
- name: Verify snapshot is up to date
|
||||
run: |
|
||||
if ! git diff --exit-code -- "${{ matrix.snapshot }}"; then
|
||||
echo "::error::${{ matrix.snapshot }} is out of date. Regenerate it (see nix/check-tools/README.md) and commit the result."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Upload regenerated snapshot
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: check-tools-${{ runner.os }}-${{ runner.arch }}
|
||||
path: ${{ matrix.snapshot }}
|
||||
3
.github/workflows/on-pr.yml
vendored
3
.github/workflows/on-pr.yml
vendored
@@ -52,7 +52,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Determine changed files
|
||||
# This step checks whether any files have changed that should
|
||||
# cause the next jobs to run. We do it this way rather than
|
||||
@@ -90,6 +90,7 @@ jobs:
|
||||
.clang-tidy
|
||||
.codecov.yml
|
||||
bin/check-tools.sh
|
||||
bin/default-loader-path.sh
|
||||
cfg/**
|
||||
cmake/**
|
||||
conan/**
|
||||
|
||||
1
.github/workflows/on-trigger.yml
vendored
1
.github/workflows/on-trigger.yml
vendored
@@ -28,6 +28,7 @@ on:
|
||||
- ".clang-tidy"
|
||||
- ".codecov.yml"
|
||||
- "bin/check-tools.sh"
|
||||
- "bin/default-loader-path.sh"
|
||||
- "cfg/**"
|
||||
- "cmake/**"
|
||||
- "conan/**"
|
||||
|
||||
6
.github/workflows/publish-docs.yml
vendored
6
.github/workflows/publish-docs.yml
vendored
@@ -41,13 +41,13 @@ env:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3122de8
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-fecfc0c
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@e4b6449d55a61c002d7c3fdfa6c20f721ede0606
|
||||
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -110,10 +110,10 @@ jobs:
|
||||
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@e4b6449d55a61c002d7c3fdfa6c20f721ede0606
|
||||
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
|
||||
with:
|
||||
enable_ccache: ${{ inputs.ccache_enabled }}
|
||||
|
||||
@@ -266,7 +266,7 @@ jobs:
|
||||
./xrpld --definitions | python3 -m json.tool >server_definitions.json
|
||||
|
||||
- name: Upload server definitions
|
||||
if: ${{ github.event.repository.visibility == 'public' && inputs.config_name == 'debian-gcc-release-amd64' }}
|
||||
if: ${{ github.event.repository.visibility == 'public' && inputs.config_name == 'ubuntu-gcc-debug-amd64-coverage' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: server-definitions
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Check levelization
|
||||
run: python .github/scripts/levelization/generate.py
|
||||
- name: Check for differences
|
||||
|
||||
2
.github/workflows/reusable-check-rename.yml
vendored
2
.github/workflows/reusable-check-rename.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Check definitions
|
||||
run: .github/scripts/rename/definitions.sh .
|
||||
- name: Check copyright notices
|
||||
|
||||
8
.github/workflows/reusable-clang-tidy.yml
vendored
8
.github/workflows/reusable-clang-tidy.yml
vendored
@@ -34,16 +34,16 @@ jobs:
|
||||
needs: [determine-files]
|
||||
if: ${{ needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.need_full_run == 'true' }}
|
||||
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
|
||||
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-3122de8"
|
||||
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-fecfc0c"
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@e4b6449d55a61c002d7c3fdfa6c20f721ede0606
|
||||
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
@@ -95,7 +95,7 @@ jobs:
|
||||
TARGETS: ${{ needs.determine-files.outputs.need_full_run != 'true' && needs.determine-files.outputs.cpp_changed_files || 'include src tests' }}
|
||||
run: |
|
||||
set -o pipefail
|
||||
run-clang-tidy -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" -quiet -fix -allow-no-checks ${TARGETS} 2>&1 | tee "${OUTPUT_FILE}"
|
||||
run-clang-tidy -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" -quiet -fix -format -allow-no-checks ${TARGETS} 2>&1 | tee "${OUTPUT_FILE}"
|
||||
|
||||
- name: Print filtered clang-tidy errors
|
||||
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
|
||||
|
||||
4
.github/workflows/reusable-package.yml
vendored
4
.github/workflows/reusable-package.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
matrix: ${{ steps.generate.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Download pre-built binary
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
matrix: ${{ steps.generate.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||
|
||||
4
.github/workflows/reusable-upload-recipe.yml
vendored
4
.github/workflows/reusable-upload-recipe.yml
vendored
@@ -40,14 +40,14 @@ defaults:
|
||||
jobs:
|
||||
upload:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3122de8
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-fecfc0c
|
||||
env:
|
||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||
CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.remote_username }}
|
||||
CONAN_PASSWORD_XRPLF: ${{ secrets.remote_password }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Generate build version number
|
||||
id: version
|
||||
|
||||
4
.github/workflows/upload-conan-deps.yml
vendored
4
.github/workflows/upload-conan-deps.yml
vendored
@@ -65,10 +65,10 @@ jobs:
|
||||
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@e4b6449d55a61c002d7c3fdfa6c20f721ede0606
|
||||
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -348,12 +348,14 @@ run-clang-tidy -p build -allow-no-checks src tests
|
||||
```
|
||||
|
||||
This will check all source files in the `src`, `include` and `tests` directories using the compile commands from your `build` directory.
|
||||
If you wish to automatically fix whatever clang-tidy finds _and_ is capable of fixing, add `-fix` to the above command:
|
||||
If you wish to automatically fix whatever clang-tidy finds _and_ is capable of fixing, add `-fix -format` to the above command:
|
||||
|
||||
```
|
||||
run-clang-tidy -p build -quiet -fix -allow-no-checks src tests
|
||||
run-clang-tidy -p build -quiet -fix -format -allow-no-checks src tests
|
||||
```
|
||||
|
||||
`-format` reformats the fixed code with [`.clang-format`](./.clang-format); without it the fixes are inserted in LLVM style and the `clang-format` hook rewrites them afterwards.
|
||||
|
||||
## Contracts and instrumentation
|
||||
|
||||
We are using [Antithesis](https://antithesis.com/) for continuous fuzzing,
|
||||
|
||||
@@ -30,8 +30,10 @@ missing=()
|
||||
checked=0
|
||||
|
||||
# check <name> [probe-command...]
|
||||
# Runs the probe (default: "<name> --version") quietly. Records <name> as
|
||||
# missing if the command is not found or exits non-zero.
|
||||
# Runs the probe (default: "<name> --version"), capturing both stdout and
|
||||
# stderr, and prints one aligned line: the status, the name, and the first
|
||||
# non-blank line of the probe output (its version). Records <name> as missing
|
||||
# if the command is not found or exits non-zero.
|
||||
check() {
|
||||
local name="$1"
|
||||
shift
|
||||
@@ -40,10 +42,11 @@ check() {
|
||||
probe=("${name}" --version)
|
||||
fi
|
||||
|
||||
echo "Checking ${name}..."
|
||||
checked=$((checked + 1))
|
||||
if "${probe[@]}" | head -n 1; then
|
||||
printf ' [ ok ] %s\n' "${name}"
|
||||
local output version
|
||||
if output="$("${probe[@]}" 2>&1)"; then
|
||||
version="$(printf '%s\n' "${output}" | grep -m1 '[^[:space:]]' || true)"
|
||||
printf ' [ ok ] %-20s %s\n' "${name}" "${version}"
|
||||
else
|
||||
printf ' [MISS] %s\n' "${name}"
|
||||
missing+=("${name}")
|
||||
@@ -85,12 +88,14 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
|
||||
check file
|
||||
check less
|
||||
check make
|
||||
check netstat which netstat
|
||||
# net-tools netstat reports "net-tools X.Y"; macOS ships BSD netstat with no
|
||||
# version flag, so fall back to a presence marker there.
|
||||
check netstat sh -c 'command -v netstat >/dev/null && { netstat --version 2>&1 | grep -m1 -oE "net-tools [0-9.]+" || echo present; }'
|
||||
check ninja
|
||||
check perl
|
||||
check perl perl -e 'print "$^V\n"'
|
||||
check pkg-config
|
||||
check vim
|
||||
check zip
|
||||
check zip bash -c 'zip --version 2>&1 | grep -m1 -oE "Zip [0-9.]+"'
|
||||
|
||||
# These tools are present in our Linux CI images and in local development
|
||||
# setups, but not in the macOS CI environment. So check them everywhere
|
||||
|
||||
@@ -144,7 +144,11 @@ def main():
|
||||
+ files
|
||||
)
|
||||
canonicalize_fix_paths(Path(fixes_dir))
|
||||
applied = subprocess.run([clang_apply_replacements, fixes_dir])
|
||||
# `FormatStyle` in .clang-tidy does not reach this path,
|
||||
# so ask for the repository style here.
|
||||
applied = subprocess.run(
|
||||
[clang_apply_replacements, "--format", "--style=file", fixes_dir]
|
||||
)
|
||||
|
||||
return result.returncode or applied.returncode
|
||||
|
||||
|
||||
@@ -29,6 +29,27 @@ if(CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
set(is_xcode TRUE)
|
||||
endif()
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Nix toolchain detection
|
||||
# --------------------------------------------------------------------
|
||||
# True when the C++ compiler resolves into the Nix store. CMAKE_CXX_COMPILER may
|
||||
# be referenced through a symlink outside the store (a Nix profile, a /usr/bin
|
||||
# alternative, ...), so resolve the real path before matching.
|
||||
set(is_nix_compiler FALSE)
|
||||
get_filename_component(_cxx_real "${CMAKE_CXX_COMPILER}" REALPATH)
|
||||
if(_cxx_real MATCHES "^/nix/store/")
|
||||
set(is_nix_compiler TRUE)
|
||||
endif()
|
||||
unset(_cxx_real)
|
||||
|
||||
# True inside the Nix CI Docker image, identified by the /nix/ci-env tree it
|
||||
# ships (see nix/docker/Dockerfile). The dev shell and bare systems don't have
|
||||
# it, so it distinguishes the CI image from other Nix-compiler environments.
|
||||
set(is_ci_image FALSE)
|
||||
if(EXISTS "/nix/ci-env/bin")
|
||||
set(is_ci_image TRUE)
|
||||
endif()
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Operating system detection
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
@@ -1,26 +1,37 @@
|
||||
#[===================================================================[
|
||||
Patch executables to run in non-Nix environments.
|
||||
|
||||
The Nix-based CI image links binaries against an ELF interpreter (loader)
|
||||
that lives in the Nix store, so the resulting binaries don't run elsewhere
|
||||
(including once installed from the .deb package). `patch_nix_binary` adds a
|
||||
POST_BUILD step that resets the interpreter to the system default loader and
|
||||
drops the rpath.
|
||||
The Nix toolchain links binaries against an ELF interpreter (loader)
|
||||
that lives in the Nix store, so the resulting binaries don't run elsewhere.
|
||||
`patch_nix_binary` adds a POST_BUILD step that resets the interpreter
|
||||
to the system default loader and drops the rpath.
|
||||
|
||||
This is only active inside the Nix-based image, detected by the presence of
|
||||
/tmp/loader-path.sh (shipped by that image, resolves the default loader). It
|
||||
is skipped for sanitizer builds, whose runtime libraries are resolved through
|
||||
the rpath. Everywhere else `patch_nix_binary` is a no-op.
|
||||
This runs by default for Nix-toolchain builds (determined by whether the compiler resolves under /nix/store/).
|
||||
Those builds are where binaries get a Nix-store loader.
|
||||
It is opted out of by setting the XRPLD_NO_PATCH_NIX_BINARY environment variable —
|
||||
the plain Nix dev shells set it, since their binaries link a newer glibc
|
||||
and must not be retargeted to the system loader.
|
||||
|
||||
Non-Nix builds (a system compiler, already using the system loader) and sanitizer builds
|
||||
(runtime libraries resolved through the rpath) are skipped too.
|
||||
Everywhere else `patch_nix_binary` is a no-op.
|
||||
|
||||
The default loader is resolved by bin/default-loader-path.sh.
|
||||
#]===================================================================]
|
||||
|
||||
include_guard(GLOBAL)
|
||||
|
||||
include(CompilationEnv)
|
||||
|
||||
# Provided by the Nix-based CI image; prints the system default ELF loader path.
|
||||
set(_loader_path_script "/tmp/loader-path.sh")
|
||||
# Resolves the system default ELF loader path for the current architecture.
|
||||
set(_loader_path_script "${CMAKE_SOURCE_DIR}/bin/default-loader-path.sh")
|
||||
|
||||
if(is_linux AND NOT SANITIZERS_ENABLED AND EXISTS "${_loader_path_script}")
|
||||
if(
|
||||
is_linux
|
||||
AND NOT SANITIZERS_ENABLED
|
||||
AND is_nix_compiler
|
||||
AND NOT DEFINED ENV{XRPLD_NO_PATCH_NIX_BINARY}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND "${_loader_path_script}"
|
||||
OUTPUT_VARIABLE DEFAULT_LOADER_PATH
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
include_guard()
|
||||
|
||||
include(isolate_headers)
|
||||
|
||||
# Define a benchmark executable for the module `name`.
|
||||
|
||||
@@ -171,9 +171,8 @@ else()
|
||||
# Clang wrapper supplies those paths itself (via -nostdinc++), so at compile time the
|
||||
# flag is unused -> Clang errors under our -Werror. At link time the flag IS consumed
|
||||
# (it selects the C++ runtime), so we move it there instead of dropping it entirely.
|
||||
get_filename_component(_cxx_real "${CMAKE_CXX_COMPILER}" REALPATH)
|
||||
if(
|
||||
_cxx_real MATCHES "^/nix/store/"
|
||||
is_nix_compiler
|
||||
AND is_linux
|
||||
AND is_clang
|
||||
AND CMAKE_CXX_FLAGS MATCHES "stdlib=libstdc"
|
||||
|
||||
@@ -134,6 +134,12 @@ target_link_libraries(
|
||||
add_module(xrpl resource)
|
||||
target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol)
|
||||
|
||||
add_module(xrpl peerfinder)
|
||||
target_link_libraries(
|
||||
xrpl.libxrpl.peerfinder
|
||||
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.protocol
|
||||
)
|
||||
|
||||
# Level 08
|
||||
add_module(xrpl net)
|
||||
target_link_libraries(
|
||||
@@ -202,6 +208,16 @@ target_link_libraries(
|
||||
add_module(xrpl tx)
|
||||
target_link_libraries(xrpl.libxrpl.tx PUBLIC xrpl.libxrpl.ledger)
|
||||
|
||||
add_module(xrpl consensus)
|
||||
target_link_libraries(
|
||||
xrpl.libxrpl.consensus
|
||||
PUBLIC
|
||||
xrpl.libxrpl.basics
|
||||
xrpl.libxrpl.json
|
||||
xrpl.libxrpl.protocol
|
||||
xrpl.libxrpl.ledger
|
||||
)
|
||||
|
||||
add_library(xrpl.libxrpl)
|
||||
set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl)
|
||||
|
||||
@@ -221,6 +237,7 @@ target_link_modules(
|
||||
beast
|
||||
conditions
|
||||
config
|
||||
consensus
|
||||
core
|
||||
crypto
|
||||
git
|
||||
@@ -228,6 +245,7 @@ target_link_modules(
|
||||
ledger
|
||||
net
|
||||
nodestore
|
||||
peerfinder
|
||||
protocol
|
||||
protocol_autogen
|
||||
rdb
|
||||
|
||||
@@ -36,6 +36,19 @@ elseif(is_gcc)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# A Nix compiler is only meant to be used from a managed environment: the xrpld
|
||||
# dev shell (which exports XRPL_DEVSHELL) or the CI image. Using one from a bare
|
||||
# shell usually means a leaked toolchain (picked up via PATH or a Conan profile)
|
||||
# and leads to confusing breakage, so fail early with guidance.
|
||||
if(is_nix_compiler AND NOT is_ci_image AND NOT DEFINED ENV{XRPL_DEVSHELL})
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"A Nix compiler (${CMAKE_CXX_COMPILER}) is being used outside the xrpld "
|
||||
"dev shell. Enter it with `nix develop` (see docs/build/nix.md) before "
|
||||
"configuring the build."
|
||||
)
|
||||
endif()
|
||||
|
||||
# check for in-source build and fail
|
||||
if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||
message(
|
||||
|
||||
38
docs/build/nix.md
vendored
38
docs/build/nix.md
vendored
@@ -38,8 +38,10 @@ The first time you run this command, it will take a few minutes to download and
|
||||
|
||||
### Platform notes
|
||||
|
||||
- **Linux**: `nix develop` gives you a shell with all the tooling necessary to
|
||||
develop xrpld and with GCC 15.2 (also provided by Nix). There are no caveats.
|
||||
- **Linux**: `nix develop` gives you a shell with all the tooling necessary to develop xrpld
|
||||
and with the same GCC/glibc toolchain that Nix builds for CI.
|
||||
See [Choosing a different compiler](#choosing-a-different-compiler)
|
||||
for the custom-vs-plain toolchain trade-off.
|
||||
- **macOS**: `nix develop` gives you a full environment too, with Clang (and
|
||||
every other tool, including Conan) provided by Nix. To use your system-wide
|
||||
Apple Clang instead, enter `nix develop .#apple-clang`. Conan has no binary in
|
||||
@@ -63,8 +65,16 @@ The first time you run this command, it will take a few minutes to download and
|
||||
### Choosing a different compiler
|
||||
|
||||
A compiler can be chosen by providing its name with the `.#` prefix, e.g. `nix develop .#clang`.
|
||||
The `.#gcc` and `.#clang` shells provide the same GCC and Clang versions used in CI
|
||||
(pinned in [`nix/packages.nix`](../../nix/packages.nix)).
|
||||
|
||||
On Linux, `.#gcc` and `.#clang` provide the exact toolchain CI uses:
|
||||
the compiler (pinned in [`nix/packages.nix`](../../nix/packages.nix))
|
||||
rebuilt against the pinned custom glibc (see [`nix/compilers.nix`](../../nix/compilers.nix)).
|
||||
Building that toolchain the first time is slow unless it is fetched from a Nix binary cache.
|
||||
If you don't need the custom glibc, the Linux-only `.#gcc-plain` and `.#clang-plain`
|
||||
give you the stock nixpkgs compilers of the same versions.
|
||||
On macOS there is no custom glibc, so `.#gcc` and `.#clang` are already the plain nixpkgs toolchain,
|
||||
and the `-plain` variants do not exist.
|
||||
|
||||
Use `nix flake show` to see all the available development shells.
|
||||
|
||||
Use `nix develop .#no-compiler` to use the compiler from your system.
|
||||
@@ -72,14 +82,18 @@ Use `nix develop .#no-compiler` to use the compiler from your system.
|
||||
### Example Usage
|
||||
|
||||
```bash
|
||||
# Use GCC (same version as CI)
|
||||
# Use GCC — same toolchain as CI (custom glibc on Linux)
|
||||
nix develop .#gcc
|
||||
|
||||
# Use Clang (same version as CI)
|
||||
# Use Clang — same toolchain as CI (custom glibc on Linux)
|
||||
nix develop .#clang
|
||||
|
||||
# Use default for your platform
|
||||
nix develop
|
||||
|
||||
# Stock nixpkgs GCC/Clang, Linux only — skips the custom-glibc build, but does not match CI
|
||||
nix develop .#gcc-plain
|
||||
nix develop .#clang-plain
|
||||
```
|
||||
|
||||
### Using a different shell
|
||||
@@ -110,6 +124,10 @@ nix develop -c "$SHELL"
|
||||
|
||||
Once inside the Nix development shell, follow the standard [build instructions](../../BUILD.md#steps). The Nix shell provides all necessary tools (CMake, Ninja, Conan, etc.).
|
||||
|
||||
Coverage builds (`-Dcoverage=ON`) work in the `gcc` shell (and `gcc-plain` on Linux):
|
||||
each ships a `gcov` matching its compiler, since Nix's cc-wrapper does not expose one.
|
||||
The `clang` shells do not include `llvm-cov`, so use a `gcc` shell for coverage.
|
||||
|
||||
## Automatic Activation with direnv
|
||||
|
||||
[direnv](https://direnv.net/) or [nix-direnv](https://github.com/nix-community/nix-direnv) can automatically activate the Nix development shell when you enter the repository directory.
|
||||
@@ -136,6 +154,14 @@ conan install .. --output-folder . --build '*' --settings build_type=Release
|
||||
|
||||
To update `flake.lock` to the latest revision use `nix flake update` command.
|
||||
|
||||
## Tooling snapshots
|
||||
|
||||
The tool versions in each Nix environment are recorded in
|
||||
[`nix/check-tools/`](../../nix/check-tools) and verified by CI. If you change the
|
||||
environment (bump the CI image tag, update `flake.lock`, or edit the tool list in
|
||||
`bin/check-tools.sh`), CI fails until you regenerate and commit the affected
|
||||
snapshot — see [`nix/check-tools/README.md`](../../nix/check-tools/README.md).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
See [Troubleshooting Nix problems](./nix_troubleshooting.md) for common issues,
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace xrpl {
|
||||
class Resolver
|
||||
{
|
||||
public:
|
||||
using HandlerType = std::function<void(std::string, std::vector<beast::IP::Endpoint>)>;
|
||||
using HandlerType = std::function<void(std::string, std::vector<beast::ip::Endpoint>)>;
|
||||
|
||||
virtual ~Resolver() = 0;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
@@ -251,4 +252,11 @@ makeSlice(std::basic_string<char, Traits, Alloc> const& s)
|
||||
return Slice(s.data(), s.size());
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
Slice
|
||||
makeSlice(std::basic_string_view<char, Traits> s)
|
||||
{
|
||||
return Slice(s.data(), s.size());
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/container/detail/aged_associative_container.h>
|
||||
#include <xrpl/beast/container/detail/aged_container_iterator.h>
|
||||
#include <xrpl/beast/container/detail/empty_base_optimization.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/intrusive/unordered_set.hpp>
|
||||
|
||||
@@ -58,7 +58,7 @@ struct LexicalCast<Out, std::string_view>
|
||||
"beast::LexicalCast can only be used with integral types");
|
||||
|
||||
template <class Integral = Out>
|
||||
bool
|
||||
constexpr bool
|
||||
operator()(Integral& out, std::string_view in) const
|
||||
requires(std::is_integral_v<Integral> && !std::is_same_v<Integral, bool>)
|
||||
{
|
||||
@@ -110,7 +110,7 @@ struct LexicalCast<Out, boost::core::basic_string_view<char>>
|
||||
{
|
||||
explicit LexicalCast() = default;
|
||||
|
||||
bool
|
||||
constexpr bool
|
||||
operator()(Out& out, boost::core::basic_string_view<char> in) const
|
||||
{
|
||||
return LexicalCast<Out, std::string_view>()(out, in);
|
||||
@@ -123,7 +123,7 @@ struct LexicalCast<Out, std::string>
|
||||
{
|
||||
explicit LexicalCast() = default;
|
||||
|
||||
bool
|
||||
constexpr bool
|
||||
operator()(Out& out, std::string in) const
|
||||
{
|
||||
return LexicalCast<Out, std::string_view>()(out, in);
|
||||
@@ -136,7 +136,7 @@ struct LexicalCast<Out, char const*>
|
||||
{
|
||||
explicit LexicalCast() = default;
|
||||
|
||||
bool
|
||||
constexpr bool
|
||||
operator()(Out& out, char const* in) const
|
||||
{
|
||||
XRPL_ASSERT(in, "beast::detail::LexicalCast(char const*) : non-null input");
|
||||
@@ -151,7 +151,7 @@ struct LexicalCast<Out, char*>
|
||||
{
|
||||
explicit LexicalCast() = default;
|
||||
|
||||
bool
|
||||
constexpr bool
|
||||
operator()(Out& out, char* in) const
|
||||
{
|
||||
XRPL_ASSERT(in, "beast::detail::LexicalCast(char*) : non-null input");
|
||||
@@ -177,7 +177,7 @@ struct BadLexicalCast : public std::bad_cast
|
||||
* @return `false` if there was a parsing or range error
|
||||
*/
|
||||
template <class Out, class In>
|
||||
bool
|
||||
constexpr bool
|
||||
lexicalCastChecked(Out& out, In in)
|
||||
{
|
||||
return detail::LexicalCast<Out, In>()(out, in);
|
||||
@@ -191,7 +191,7 @@ lexicalCastChecked(Out& out, In in)
|
||||
* @return The new type.
|
||||
*/
|
||||
template <class Out, class In>
|
||||
Out
|
||||
constexpr Out
|
||||
lexicalCastThrow(In in)
|
||||
{
|
||||
if (Out out; lexicalCastChecked(out, in))
|
||||
@@ -207,7 +207,7 @@ lexicalCastThrow(In in)
|
||||
* @return The new type.
|
||||
*/
|
||||
template <class Out, class In>
|
||||
Out
|
||||
constexpr Out
|
||||
lexicalCast(In in, Out defaultValue = Out())
|
||||
{
|
||||
if (Out out; lexicalCastChecked(out, in))
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace beast {
|
||||
class SemanticVersion
|
||||
{
|
||||
public:
|
||||
using identifier_list = std::vector<std::string>;
|
||||
using IdentifierList = std::vector<std::string>;
|
||||
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
int patchVersion;
|
||||
|
||||
identifier_list preReleaseIdentifiers;
|
||||
identifier_list metaData;
|
||||
IdentifierList preReleaseIdentifiers;
|
||||
IdentifierList metaData;
|
||||
|
||||
SemanticVersion();
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
* @param journal Destination for logging output.
|
||||
*/
|
||||
static std::shared_ptr<StatsDCollector>
|
||||
make(IP::Endpoint const& address, std::string const& prefix, Journal journal);
|
||||
make(ip::Endpoint const& address, std::string const& prefix, Journal journal);
|
||||
};
|
||||
|
||||
} // namespace beast::insight
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace beast {
|
||||
namespace IP {
|
||||
namespace ip {
|
||||
|
||||
using Address = boost::asio::ip::address;
|
||||
|
||||
@@ -73,13 +73,13 @@ isPublic(Address const& addr)
|
||||
return (addr.is_v4()) ? isPublic(addr.to_v4()) : isPublic(addr.to_v6());
|
||||
}
|
||||
|
||||
} // namespace IP
|
||||
} // namespace ip
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Hasher>
|
||||
void
|
||||
hash_append(Hasher& h, beast::IP::Address const& addr) noexcept
|
||||
hash_append(Hasher& h, beast::ip::Address const& addr) noexcept
|
||||
{
|
||||
using beast::hash_append;
|
||||
if (addr.is_v4())
|
||||
@@ -101,12 +101,12 @@ hash_append(Hasher& h, beast::IP::Address const& addr) noexcept
|
||||
|
||||
namespace boost {
|
||||
template <>
|
||||
struct hash<::beast::IP::Address>
|
||||
struct hash<::beast::ip::Address>
|
||||
{
|
||||
explicit hash() = default;
|
||||
|
||||
std::size_t
|
||||
operator()(::beast::IP::Address const& addr) const
|
||||
operator()(::beast::ip::Address const& addr) const
|
||||
{
|
||||
return ::beast::Uhash<>{}(addr);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace beast::IP {
|
||||
namespace beast::ip {
|
||||
|
||||
/**
|
||||
* Convert to Endpoint.
|
||||
@@ -32,7 +32,7 @@ toAsioAddress(Endpoint const& endpoint);
|
||||
boost::asio::ip::tcp::endpoint
|
||||
toAsioEndpoint(Endpoint const& endpoint);
|
||||
|
||||
} // namespace beast::IP
|
||||
} // namespace beast::ip
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -41,25 +41,25 @@ struct IPAddressConversion
|
||||
{
|
||||
explicit IPAddressConversion() = default;
|
||||
|
||||
static IP::Endpoint
|
||||
static ip::Endpoint
|
||||
fromAsio(boost::asio::ip::address const& address)
|
||||
{
|
||||
return IP::fromAsio(address);
|
||||
return ip::fromAsio(address);
|
||||
}
|
||||
static IP::Endpoint
|
||||
static ip::Endpoint
|
||||
fromAsio(boost::asio::ip::tcp::endpoint const& endpoint)
|
||||
{
|
||||
return IP::fromAsio(endpoint);
|
||||
return ip::fromAsio(endpoint);
|
||||
}
|
||||
static boost::asio::ip::address
|
||||
toAsioAddress(IP::Endpoint const& address)
|
||||
toAsioAddress(ip::Endpoint const& address)
|
||||
{
|
||||
return IP::toAsioAddress(address);
|
||||
return ip::toAsioAddress(address);
|
||||
}
|
||||
static boost::asio::ip::tcp::endpoint
|
||||
toAsioEndpoint(IP::Endpoint const& address)
|
||||
toAsioEndpoint(ip::Endpoint const& address)
|
||||
{
|
||||
return IP::toAsioEndpoint(address);
|
||||
return ip::toAsioEndpoint(address);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <boost/asio/ip/address_v4.hpp>
|
||||
|
||||
namespace beast::IP {
|
||||
namespace beast::ip {
|
||||
|
||||
using AddressV4 = boost::asio::ip::address_v4;
|
||||
|
||||
@@ -25,4 +25,4 @@ isPublic(AddressV4 const& addr);
|
||||
char
|
||||
getClass(AddressV4 const& address);
|
||||
|
||||
} // namespace beast::IP
|
||||
} // namespace beast::ip
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <boost/asio/ip/address_v6.hpp>
|
||||
|
||||
namespace beast::IP {
|
||||
namespace beast::ip {
|
||||
|
||||
using AddressV6 = boost::asio::ip::address_v6;
|
||||
|
||||
@@ -18,4 +18,4 @@ isPrivate(AddressV6 const& addr);
|
||||
bool
|
||||
isPublic(AddressV6 const& addr);
|
||||
|
||||
} // namespace beast::IP
|
||||
} // namespace beast::ip
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace beast::IP {
|
||||
namespace beast::ip {
|
||||
|
||||
using Port = std::uint16_t;
|
||||
|
||||
@@ -223,7 +223,7 @@ operator<<(OutputStream& os, Endpoint const& endpoint)
|
||||
std::istream&
|
||||
operator>>(std::istream& is, Endpoint& endpoint);
|
||||
|
||||
} // namespace beast::IP
|
||||
} // namespace beast::ip
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -232,12 +232,12 @@ namespace std {
|
||||
* std::hash support.
|
||||
*/
|
||||
template <>
|
||||
struct hash<::beast::IP::Endpoint>
|
||||
struct hash<::beast::ip::Endpoint>
|
||||
{
|
||||
hash() = default;
|
||||
|
||||
std::size_t
|
||||
operator()(::beast::IP::Endpoint const& endpoint) const
|
||||
operator()(::beast::ip::Endpoint const& endpoint) const
|
||||
{
|
||||
return ::beast::Uhash<>{}(endpoint);
|
||||
}
|
||||
@@ -249,12 +249,12 @@ namespace boost {
|
||||
* boost::hash support.
|
||||
*/
|
||||
template <>
|
||||
struct hash<::beast::IP::Endpoint>
|
||||
struct hash<::beast::ip::Endpoint>
|
||||
{
|
||||
hash() = default;
|
||||
|
||||
std::size_t
|
||||
operator()(::beast::IP::Endpoint const& endpoint) const
|
||||
operator()(::beast::ip::Endpoint const& endpoint) const
|
||||
{
|
||||
return ::beast::Uhash<>{}(endpoint);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace xrpl {
|
||||
|
||||
template <class TxID, class Sequence>
|
||||
class RCLCensorshipDetector
|
||||
class CensorshipDetector
|
||||
{
|
||||
public:
|
||||
struct TxIDSeq
|
||||
@@ -49,7 +49,7 @@ private:
|
||||
TxIDSeqVec tracker_;
|
||||
|
||||
public:
|
||||
RCLCensorshipDetector() = default;
|
||||
CensorshipDetector() = default;
|
||||
|
||||
/**
|
||||
* Add transactions being proposed for the current consensus round.
|
||||
@@ -1,15 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/consensus/ConsensusParms.h>
|
||||
#include <xrpld/consensus/ConsensusProposal.h>
|
||||
#include <xrpld/consensus/ConsensusTypes.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/clock/abstract_clock.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/consensus/ConsensusParms.h>
|
||||
#include <xrpl/consensus/ConsensusProposal.h>
|
||||
#include <xrpl/consensus/ConsensusTypes.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/json_writer.h>
|
||||
#include <xrpl/ledger/LedgerTiming.h>
|
||||
@@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/consensus/ConsensusProposal.h>
|
||||
#include <xrpld/consensus/DisputedTx.h>
|
||||
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/consensus/ConsensusProposal.h>
|
||||
#include <xrpl/consensus/DisputedTx.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/consensus/ConsensusParms.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/consensus/ConsensusParms.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/json_writer.h>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/consensus/LedgerTrie.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
@@ -11,6 +9,7 @@
|
||||
#include <xrpl/beast/hash/uhash.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/consensus/LedgerTrie.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -15,12 +15,12 @@
|
||||
namespace xrpl {
|
||||
|
||||
// Forward declarations
|
||||
namespace NodeStore {
|
||||
namespace node_store {
|
||||
class Database;
|
||||
} // namespace NodeStore
|
||||
namespace Resource {
|
||||
} // namespace node_store
|
||||
namespace resource {
|
||||
class Manager;
|
||||
} // namespace Resource
|
||||
} // namespace resource
|
||||
namespace perf {
|
||||
class PerfLog;
|
||||
} // namespace perf
|
||||
@@ -160,11 +160,11 @@ public:
|
||||
virtual PeerReservationTable&
|
||||
getPeerReservations() = 0;
|
||||
|
||||
virtual Resource::Manager&
|
||||
virtual resource::Manager&
|
||||
getResourceManager() = 0;
|
||||
|
||||
// Storage services
|
||||
virtual NodeStore::Database&
|
||||
virtual node_store::Database&
|
||||
getNodeStore() = 0;
|
||||
|
||||
virtual SHAMapStore&
|
||||
|
||||
@@ -623,6 +623,7 @@ class ValueConstIterator : public ValueIteratorBase
|
||||
public:
|
||||
using size_t = unsigned int;
|
||||
using difference_type = int;
|
||||
using value_type = Value const;
|
||||
using reference = Value const&;
|
||||
using pointer = Value const*;
|
||||
using SelfType = ValueConstIterator;
|
||||
@@ -687,6 +688,7 @@ class ValueIterator : public ValueIteratorBase
|
||||
public:
|
||||
using size_t = unsigned int;
|
||||
using difference_type = int;
|
||||
using value_type = Value;
|
||||
using reference = Value&;
|
||||
using pointer = Value*;
|
||||
using SelfType = ValueIterator;
|
||||
|
||||
@@ -286,6 +286,77 @@ computeFullPaymentInterest(
|
||||
std::uint32_t startDate,
|
||||
TenthBips32 closeInterestRate);
|
||||
|
||||
// Deltas applied to Vault.AssetsTotal and LoanBroker.DebtTotal at a single
|
||||
// accounting touch point (origination, payment, impair/unimpair/default).
|
||||
struct AccountingDeltas
|
||||
{
|
||||
Number assetsTotalDelta;
|
||||
Number debtTotalDelta;
|
||||
};
|
||||
|
||||
// Whole-life (pre-LendingProtocolV1_1) recognition model: interest is
|
||||
// recognized into AssetsTotal/DebtTotal up front, at origination.
|
||||
namespace accrual {
|
||||
|
||||
// LoanSet origination: what's added to Vault.AssetsTotal and LoanBroker.DebtTotal
|
||||
AccountingDeltas
|
||||
loanOriginationDeltas(Number const& principalRequested, Number const& interestDue);
|
||||
|
||||
// LoanSet origination: would recognizing this loan's interest push
|
||||
// Vault.AssetsTotal past Vault.AssetsMaximum?
|
||||
bool
|
||||
loanOriginationExceedsVaultMaximum(
|
||||
Number const& vaultMaximum,
|
||||
Number const& vaultTotal,
|
||||
Number const& interestDue);
|
||||
|
||||
// LoanManage impair/unimpair/default: the vault's exposure to this loan
|
||||
Number
|
||||
loanVaultExposure(SLE::const_ref loanSle);
|
||||
|
||||
// LoanPay: what's added to Vault.AssetsTotal and subtracted from LoanBroker.DebtTotal for a payment
|
||||
AccountingDeltas
|
||||
loanPaymentDeltas(LoanPaymentParts const& parts);
|
||||
|
||||
} // namespace accrual
|
||||
|
||||
// Cash-basis (LendingProtocolV1_1) recognition model: AssetsTotal/DebtTotal
|
||||
// are principal-only, interest is recognized only as it's actually paid.
|
||||
namespace cash_basis {
|
||||
|
||||
AccountingDeltas
|
||||
loanOriginationDeltas(Number const& principalRequested);
|
||||
|
||||
Number
|
||||
loanVaultExposure(SLE::const_ref loanSle);
|
||||
|
||||
AccountingDeltas
|
||||
loanPaymentDeltas(LoanPaymentParts const& parts);
|
||||
|
||||
} // namespace cash_basis
|
||||
|
||||
// Public dispatchers: pick cash_basis:: if featureLendingProtocolV1_1 is
|
||||
// enabled AND the Vault's LEVersion (VaultHelpers::getVaultVersion) is
|
||||
// VaultVersion::CashBasis, else accrual::. These are the only entry points
|
||||
// transactors call.
|
||||
AccountingDeltas
|
||||
loanOriginationDeltas(
|
||||
SLE::const_ref vaultSle,
|
||||
Number const& principalRequested,
|
||||
Number const& interestDue);
|
||||
|
||||
bool
|
||||
loanOriginationExceedsVaultMaximum(
|
||||
SLE::const_ref vaultSle,
|
||||
Number const& vaultTotal,
|
||||
Number const& interestDue);
|
||||
|
||||
Number
|
||||
loanVaultExposure(SLE::const_ref vaultSle, SLE::const_ref loanSle);
|
||||
|
||||
AccountingDeltas
|
||||
loanPaymentDeltas(SLE::const_ref vaultSle, LoanPaymentParts const& parts);
|
||||
|
||||
namespace detail {
|
||||
// These classes and functions should only be accessed by LendingHelper
|
||||
// functions and unit tests
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
|
||||
@@ -107,4 +108,19 @@ sharesToAssetsWithdraw(
|
||||
[[nodiscard]] bool
|
||||
isSoleShareholder(ReadView const& view, AccountID const& account, SLE::const_ref issuance);
|
||||
|
||||
/**
|
||||
* Resolves a Vault's LEVersion, the single point every accounting touch
|
||||
* point should call to determine which recognition model (accrual vs.
|
||||
* cash-basis) a Vault uses. Vaults created before featureLendingProtocolV1_1
|
||||
* activated never have sfLEVersion set, which resolves here to
|
||||
* VaultVersion::Legacy.
|
||||
*
|
||||
* @param vault The vault SLE.
|
||||
*
|
||||
* @return The Vault's LEVersion, or VaultVersion::Legacy if the field is
|
||||
* absent.
|
||||
*/
|
||||
[[nodiscard]] VaultVersion
|
||||
getVaultVersion(SLE::const_ref vault);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -67,16 +67,16 @@ public:
|
||||
return socket_->next_layer();
|
||||
}
|
||||
|
||||
beast::IP::Endpoint
|
||||
beast::ip::Endpoint
|
||||
localEndpoint()
|
||||
{
|
||||
return beast::IP::fromAsio(lowestLayer().local_endpoint());
|
||||
return beast::ip::fromAsio(lowestLayer().local_endpoint());
|
||||
}
|
||||
|
||||
beast::IP::Endpoint
|
||||
beast::ip::Endpoint
|
||||
remoteEndpoint()
|
||||
{
|
||||
return beast::IP::fromAsio(lowestLayer().remote_endpoint());
|
||||
return beast::ip::fromAsio(lowestLayer().remote_endpoint());
|
||||
}
|
||||
|
||||
lowest_layer_type&
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
/**
|
||||
* A backend used for the NodeStore.
|
||||
@@ -163,4 +163,4 @@ public:
|
||||
fdRequired() const = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace xrpl {
|
||||
class Section;
|
||||
} // namespace xrpl
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
/**
|
||||
* Persistency layer for NodeObject
|
||||
@@ -248,7 +248,7 @@ protected:
|
||||
void
|
||||
storeStats(std::uint64_t count, std::uint64_t sz)
|
||||
{
|
||||
XRPL_ASSERT(count <= sz, "xrpl::NodeStore::Database::storeStats : valid inputs");
|
||||
XRPL_ASSERT(count <= sz, "xrpl::node_store::Database::storeStats : valid inputs");
|
||||
storeCount_ += count;
|
||||
storeSz_ += sz;
|
||||
}
|
||||
@@ -308,4 +308,4 @@ private:
|
||||
threadEntry();
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
/* This class has two key-value store Backend objects for persisting SHAMap
|
||||
* records. This facilitates online deletion of data. New backends are
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
*/
|
||||
virtual void
|
||||
rotate(
|
||||
std::unique_ptr<NodeStore::Backend>&& newBackend,
|
||||
std::unique_ptr<node_store::Backend>&& newBackend,
|
||||
std::function<void(std::string const& writableName, std::string const& archiveName)> const&
|
||||
f) = 0;
|
||||
|
||||
@@ -56,4 +56,4 @@ public:
|
||||
setRotationInFlight(bool inFlight) = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <xrpl/nodestore/Scheduler.h>
|
||||
#include <xrpl/nodestore/Task.h>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
/**
|
||||
* Simple NodeStore Scheduler that just performs the tasks synchronously.
|
||||
@@ -21,4 +21,4 @@ public:
|
||||
onBatchWrite(BatchWriteReport const& report) override;
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace xrpl {
|
||||
class Section;
|
||||
} // namespace xrpl
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
/**
|
||||
* Base class for backend factories.
|
||||
@@ -70,4 +70,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
/**
|
||||
* Singleton for managing NodeStore factories and back ends.
|
||||
@@ -98,4 +98,4 @@ public:
|
||||
beast::Journal journal) = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
// VFALCO NOTE Intentionally not in the NodeStore namespace
|
||||
// VFALCO NOTE Intentionally not in the node_store namespace
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
enum class FetchType { Synchronous, Async };
|
||||
|
||||
@@ -71,4 +71,4 @@ public:
|
||||
onBatchWrite(BatchWriteReport const& report) = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
/**
|
||||
* Derived classes perform scheduled tasks.
|
||||
@@ -17,4 +17,4 @@ struct Task
|
||||
performScheduledTask() = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
// This is only used to pre-allocate the array for
|
||||
// batch objects and does not affect the amount written.
|
||||
@@ -36,4 +36,4 @@ enum class Status {
|
||||
*/
|
||||
using Batch = std::vector<std::shared_ptr<NodeObject>>;
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
/**
|
||||
* Batch-writing assist logic.
|
||||
@@ -86,4 +86,4 @@ private:
|
||||
Batch writeSet_;
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
class DatabaseNodeImp : public Database
|
||||
{
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
XRPL_ASSERT(
|
||||
backend_,
|
||||
"xrpl::NodeStore::DatabaseNodeImp::DatabaseNodeImp : non-null "
|
||||
"xrpl::node_store::DatabaseNodeImp::DatabaseNodeImp : non-null "
|
||||
"backend");
|
||||
}
|
||||
|
||||
@@ -138,4 +138,4 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
class DatabaseRotatingImp : public DatabaseRotating
|
||||
{
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
|
||||
void
|
||||
rotate(
|
||||
std::unique_ptr<NodeStore::Backend>&& newBackend,
|
||||
std::unique_ptr<node_store::Backend>&& newBackend,
|
||||
std::function<void(std::string const& writableName, std::string const& archiveName)> const&
|
||||
f) override;
|
||||
|
||||
@@ -94,4 +94,4 @@ private:
|
||||
forEach(std::function<void(std::shared_ptr<NodeObject>)> f) override;
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
/**
|
||||
* Parsed key/value blob into NodeObject components.
|
||||
@@ -49,4 +49,4 @@ private:
|
||||
int dataBytes_;
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
/**
|
||||
* Convert a NodeObject from in-memory to database format.
|
||||
@@ -68,7 +68,7 @@ class EncodedBlob
|
||||
public:
|
||||
explicit EncodedBlob(std::shared_ptr<NodeObject> const& obj)
|
||||
: size_([&obj]() {
|
||||
XRPL_ASSERT(obj, "xrpl::NodeStore::EncodedBlob::EncodedBlob : non-null input");
|
||||
XRPL_ASSERT(obj, "xrpl::node_store::EncodedBlob::EncodedBlob : non-null input");
|
||||
|
||||
if (!obj)
|
||||
throw std::runtime_error("EncodedBlob: unseated std::shared_ptr used.");
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
XRPL_ASSERT(
|
||||
((ptr_ == payload_.data()) && (size_ <= payload_.size())) ||
|
||||
((ptr_ != payload_.data()) && (size_ > payload_.size())),
|
||||
"xrpl::NodeStore::EncodedBlob::~EncodedBlob : valid payload "
|
||||
"xrpl::node_store::EncodedBlob::~EncodedBlob : valid payload "
|
||||
"pointer");
|
||||
|
||||
if (ptr_ != payload_.data())
|
||||
@@ -114,4 +114,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
class ManagerImp : public Manager
|
||||
{
|
||||
@@ -57,4 +57,4 @@ public:
|
||||
beast::Journal journal) override;
|
||||
};
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
@@ -6,25 +6,25 @@
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
// This is a variant of the base128 varint format from
|
||||
// google protocol buffers:
|
||||
// https://developers.google.com/protocol-buffers/docs/encoding#varints
|
||||
|
||||
// field tag
|
||||
struct varint;
|
||||
struct Varint;
|
||||
|
||||
// Metafuncton to return largest
|
||||
// Metafunction to return largest
|
||||
// possible size of T represented as varint.
|
||||
// T must be unsigned
|
||||
template <class T, bool = std::is_unsigned_v<T>>
|
||||
struct varint_traits;
|
||||
struct VarintTraits;
|
||||
|
||||
template <class T>
|
||||
struct varint_traits<T, true>
|
||||
struct VarintTraits<T, true>
|
||||
{
|
||||
explicit varint_traits() = default;
|
||||
explicit VarintTraits() = default;
|
||||
|
||||
static constexpr std::size_t kMax = ((8 * sizeof(T)) + 6) / 7;
|
||||
};
|
||||
@@ -104,7 +104,7 @@ writeVarint(void* p0, std::size_t v)
|
||||
template <class T>
|
||||
void
|
||||
read(nudb::detail::istream& is, std::size_t& u)
|
||||
requires(std::is_same_v<T, varint>)
|
||||
requires(std::is_same_v<T, Varint>)
|
||||
{
|
||||
auto p0 = is(1);
|
||||
auto p1 = p0;
|
||||
@@ -118,9 +118,9 @@ read(nudb::detail::istream& is, std::size_t& u)
|
||||
template <class T>
|
||||
void
|
||||
write(nudb::detail::ostream& os, std::size_t t)
|
||||
requires(std::is_same_v<T, varint>)
|
||||
requires(std::is_same_v<T, Varint>)
|
||||
{
|
||||
writeVarint(os.data(sizeVarint(t)), t);
|
||||
}
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
#include <xrpl/nodestore/NodeObject.h>
|
||||
#include <xrpl/nodestore/detail/varint.h>
|
||||
#include <xrpl/nodestore/detail/Varint.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
|
||||
#include <nudb/detail/field.hpp>
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl::NodeStore {
|
||||
namespace xrpl::node_store {
|
||||
|
||||
template <class BufferFactory>
|
||||
std::pair<void const*, std::size_t>
|
||||
@@ -59,7 +59,7 @@ lz4Compress(void const* in, std::size_t inSize, BufferFactory&& bf)
|
||||
using std::runtime_error;
|
||||
using namespace nudb::detail;
|
||||
std::pair<void const*, std::size_t> result;
|
||||
std::array<std::uint8_t, varint_traits<std::size_t>::kMax> vi{};
|
||||
std::array<std::uint8_t, VarintTraits<std::size_t>::kMax> vi{};
|
||||
auto const n = writeVarint(vi.data(), inSize);
|
||||
auto const outMax = LZ4_compressBound(inSize);
|
||||
auto* out = reinterpret_cast<std::uint8_t*>(bf(n + outMax));
|
||||
@@ -240,7 +240,7 @@ nodeobjectCompress(void const* in, std::size_t inSize, BufferFactory&& bf)
|
||||
auto* out = reinterpret_cast<std::uint8_t*>(bf(result.second));
|
||||
result.first = out;
|
||||
ostream os(out, result.second);
|
||||
write<varint>(os, type);
|
||||
write<Varint>(os, type);
|
||||
write<std::uint16_t>(os, mask);
|
||||
write(os, vh.data(), n * 32);
|
||||
return result;
|
||||
@@ -252,13 +252,13 @@ nodeobjectCompress(void const* in, std::size_t inSize, BufferFactory&& bf)
|
||||
auto* out = reinterpret_cast<std::uint8_t*>(bf(result.second));
|
||||
result.first = out;
|
||||
ostream os(out, result.second);
|
||||
write<varint>(os, type);
|
||||
write<Varint>(os, type);
|
||||
write(os, vh.data(), n * 32);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
std::array<std::uint8_t, varint_traits<std::size_t>::kMax> vi{};
|
||||
std::array<std::uint8_t, VarintTraits<std::size_t>::kMax> vi{};
|
||||
|
||||
static constexpr std::size_t kCodecType = 1;
|
||||
auto const vn = writeVarint(vi.data(), kCodecType);
|
||||
@@ -269,7 +269,7 @@ nodeobjectCompress(void const* in, std::size_t inSize, BufferFactory&& bf)
|
||||
case 1: // lz4
|
||||
{
|
||||
std::uint8_t* p = nullptr;
|
||||
auto const lzr = NodeStore::lz4Compress(in, inSize, [&p, &vn, &bf](std::size_t n) {
|
||||
auto const lzr = node_store::lz4Compress(in, inSize, [&p, &vn, &bf](std::size_t n) {
|
||||
p = reinterpret_cast<std::uint8_t*>(bf(vn + n));
|
||||
return p + vn;
|
||||
});
|
||||
@@ -316,4 +316,4 @@ filterInner(void* in, std::size_t inSize)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xrpl::NodeStore
|
||||
} // namespace xrpl::node_store
|
||||
|
||||
163
include/xrpl/peerfinder/Config.h
Normal file
163
include/xrpl/peerfinder/Config.h
Normal file
@@ -0,0 +1,163 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/PropertyStream.h>
|
||||
#include <xrpl/peerfinder/detail/Tuning.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
struct PeerLimitConfig
|
||||
{
|
||||
std::optional<std::size_t> maxPeers;
|
||||
std::optional<std::size_t> inPeers;
|
||||
std::optional<std::size_t> outPeers;
|
||||
};
|
||||
|
||||
/**
|
||||
* PeerFinder configuration settings.
|
||||
*/
|
||||
struct Config
|
||||
{
|
||||
/**
|
||||
* The largest number of public peer slots to allow.
|
||||
* This includes both inbound and outbound, but does not include
|
||||
* fixed peers.
|
||||
*/
|
||||
std::size_t maxPeers{tuning::kDefaultMaxPeers};
|
||||
|
||||
/**
|
||||
* The number of automatic outbound connections to maintain.
|
||||
* Outbound connections are only maintained if autoConnect
|
||||
* is `true`.
|
||||
*/
|
||||
std::size_t outPeers = calcOutPeers(); // Note: relies on `maxPeers` being initialized
|
||||
|
||||
/**
|
||||
* The number of automatic inbound connections to maintain.
|
||||
* Inbound connections are only maintained if wantIncoming
|
||||
* is `true`.
|
||||
*/
|
||||
std::size_t inPeers{0};
|
||||
|
||||
/**
|
||||
* `true` if we want our IP address kept private.
|
||||
*/
|
||||
bool peerPrivate = true;
|
||||
|
||||
/**
|
||||
* `true` if we want to accept incoming connections.
|
||||
*/
|
||||
bool wantIncoming{true};
|
||||
|
||||
/**
|
||||
* `true` if we want to establish connections automatically
|
||||
*/
|
||||
bool autoConnect{true};
|
||||
|
||||
/**
|
||||
* The listening port number.
|
||||
*/
|
||||
std::uint16_t listeningPort{0};
|
||||
|
||||
/**
|
||||
* The set of features we advertise.
|
||||
*/
|
||||
std::string features;
|
||||
|
||||
/**
|
||||
* Limit how many incoming connections we allow per IP
|
||||
*/
|
||||
int ipLimit{0};
|
||||
|
||||
/**
|
||||
* `true` if we want to verify endpoints in TMEndpoints messages
|
||||
*/
|
||||
bool verifyEndpoints = true;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns a suitable value for outPeers according to the rules.
|
||||
*/
|
||||
[[nodiscard]] std::size_t
|
||||
calcOutPeers() const;
|
||||
|
||||
/**
|
||||
* Adjusts the values so they follow the business rules.
|
||||
*/
|
||||
void
|
||||
applyTuning();
|
||||
|
||||
/**
|
||||
* Write the configuration into a property stream
|
||||
*/
|
||||
void
|
||||
onWrite(beast::PropertyStream::Map& map) const;
|
||||
|
||||
/**
|
||||
* Make peer_finder::Config from peer limit and server mode parameters.
|
||||
*/
|
||||
static Config
|
||||
makeConfig(
|
||||
bool peerPrivate,
|
||||
bool standalone,
|
||||
PeerLimitConfig const& limits,
|
||||
std::uint16_t port,
|
||||
bool validationPublicKey,
|
||||
int ipLimit,
|
||||
bool verifyEndpoints);
|
||||
|
||||
/**
|
||||
* Compares two configurations for equality field by field.
|
||||
*/
|
||||
friend bool
|
||||
operator==(Config const& lhs, Config const& rhs) = default;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Possible results from activating a slot.
|
||||
*/
|
||||
enum class Result { InboundDisabled, DuplicatePeer, IpLimitExceeded, Full, Success };
|
||||
|
||||
/**
|
||||
* @brief Converts a `Result` enum value to its string representation.
|
||||
*
|
||||
* This function provides a human-readable string for a given `Result` enum,
|
||||
* which is useful for logging, debugging, or displaying status messages.
|
||||
*
|
||||
* @param result The `Result` enum value to convert.
|
||||
* @return A `std::string_view` representing the enum value. Returns "unknown"
|
||||
* if the enum value is not explicitly handled.
|
||||
*
|
||||
* @note This function returns a `std::string_view` for performance.
|
||||
* A `std::string` would need to allocate memory on the heap and copy the
|
||||
* string literal into it every time the function is called.
|
||||
*/
|
||||
inline std::string_view
|
||||
to_string(Result result) noexcept
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case Result::InboundDisabled:
|
||||
return "inbound disabled";
|
||||
case Result::DuplicatePeer:
|
||||
return "peer already connected";
|
||||
case Result::IpLimitExceeded:
|
||||
return "ip limit exceeded";
|
||||
case Result::Full:
|
||||
return "slots full";
|
||||
case Result::Success:
|
||||
return "success";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
} // namespace xrpl::peer_finder
|
||||
179
include/xrpl/peerfinder/PeerfinderManager.h
Normal file
179
include/xrpl/peerfinder/PeerfinderManager.h
Normal file
@@ -0,0 +1,179 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/net/IPEndpoint.h>
|
||||
#include <xrpl/beast/utility/PropertyStream.h>
|
||||
#include <xrpl/peerfinder/Config.h>
|
||||
#include <xrpl/peerfinder/Slot.h>
|
||||
#include <xrpl/peerfinder/Types.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* Maintains a set of IP addresses used for getting into the network.
|
||||
*/
|
||||
class Manager : public beast::PropertyStream::Source
|
||||
{
|
||||
protected:
|
||||
Manager() noexcept;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Destroy the object.
|
||||
* Any pending source fetch operations are aborted.
|
||||
* There may be some listener calls made before the
|
||||
* destructor returns.
|
||||
*/
|
||||
~Manager() override = default;
|
||||
|
||||
/**
|
||||
* Set the configuration for the manager.
|
||||
* The new settings will be applied asynchronously.
|
||||
* Thread safety:
|
||||
* Can be called from any threads at any time.
|
||||
*/
|
||||
virtual void
|
||||
setConfig(Config const& config) = 0;
|
||||
|
||||
/**
|
||||
* Transition to the started state, synchronously.
|
||||
*/
|
||||
virtual void
|
||||
start() = 0;
|
||||
|
||||
/**
|
||||
* Transition to the stopped state, synchronously.
|
||||
*/
|
||||
virtual void
|
||||
stop() = 0;
|
||||
|
||||
/**
|
||||
* Returns the configuration for the manager.
|
||||
*/
|
||||
virtual Config
|
||||
config() = 0;
|
||||
|
||||
/**
|
||||
* Add a peer that should always be connected.
|
||||
* This is useful for maintaining a private cluster of peers.
|
||||
* The string is the name as specified in the configuration
|
||||
* file, along with the set of corresponding IP addresses.
|
||||
*/
|
||||
virtual void
|
||||
addFixedPeer(std::string_view name, std::vector<beast::ip::Endpoint> const& addresses) = 0;
|
||||
|
||||
/**
|
||||
* Add a set of strings as fallback ip::Endpoint sources.
|
||||
* @param name A label used for diagnostics.
|
||||
*/
|
||||
virtual void
|
||||
addFallbackStrings(std::string const& name, std::vector<std::string> const& strings) = 0;
|
||||
|
||||
/**
|
||||
* Add a URL as a fallback location to obtain ip::Endpoint sources.
|
||||
* @param name A label used for diagnostics.
|
||||
*/
|
||||
/* VFALCO NOTE Unimplemented
|
||||
virtual void addFallbackURL (std::string const& name,
|
||||
std::string const& url) = 0;
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a new inbound slot with the specified remote endpoint.
|
||||
* If nullptr is returned, then the slot could not be assigned.
|
||||
* Usually this is because of a detected self-connection.
|
||||
*/
|
||||
virtual std::pair<std::shared_ptr<Slot>, Result>
|
||||
newInboundSlot(
|
||||
beast::ip::Endpoint const& localEndpoint,
|
||||
beast::ip::Endpoint const& remoteEndpoint) = 0;
|
||||
|
||||
/**
|
||||
* Create a new outbound slot with the specified remote endpoint.
|
||||
* If nullptr is returned, then the slot could not be assigned.
|
||||
* Usually this is because of a duplicate connection.
|
||||
*/
|
||||
virtual std::pair<std::shared_ptr<Slot>, Result>
|
||||
newOutboundSlot(beast::ip::Endpoint const& remoteEndpoint) = 0;
|
||||
|
||||
/**
|
||||
* Called when mtENDPOINTS is received.
|
||||
*/
|
||||
virtual void
|
||||
onEndpoints(std::shared_ptr<Slot> const& slot, Endpoints const& endpoints) = 0;
|
||||
|
||||
/**
|
||||
* Called when the slot is closed.
|
||||
* This always happens when the socket is closed, unless the socket
|
||||
* was canceled.
|
||||
*/
|
||||
virtual void
|
||||
onClosed(std::shared_ptr<Slot> const& slot) = 0;
|
||||
|
||||
/**
|
||||
* Called when an outbound connection is deemed to have failed
|
||||
*/
|
||||
virtual void
|
||||
onFailure(std::shared_ptr<Slot> const& slot) = 0;
|
||||
|
||||
/**
|
||||
* Called when we received redirect IPs from a busy peer.
|
||||
*/
|
||||
virtual void
|
||||
onRedirects(
|
||||
boost::asio::ip::tcp::endpoint const& remoteAddress,
|
||||
std::vector<boost::asio::ip::tcp::endpoint> const& eps) = 0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Called when an outbound connection attempt succeeds.
|
||||
* The local endpoint must be valid. If the caller receives an error
|
||||
* when retrieving the local endpoint from the socket, it should
|
||||
* proceed as if the connection attempt failed by calling on_closed
|
||||
* instead of on_connected.
|
||||
* @return `true` if the connection should be kept
|
||||
*/
|
||||
virtual bool
|
||||
onConnected(std::shared_ptr<Slot> const& slot, beast::ip::Endpoint const& localEndpoint) = 0;
|
||||
|
||||
/**
|
||||
* Request an active slot type.
|
||||
*/
|
||||
virtual Result
|
||||
activate(std::shared_ptr<Slot> const& slot, PublicKey const& key, bool reserved) = 0;
|
||||
|
||||
/**
|
||||
* Returns a set of endpoints suitable for redirection.
|
||||
*/
|
||||
virtual std::vector<Endpoint>
|
||||
redirect(std::shared_ptr<Slot> const& slot) = 0;
|
||||
|
||||
/**
|
||||
* Return a set of addresses we should connect to.
|
||||
*/
|
||||
virtual std::vector<beast::ip::Endpoint>
|
||||
autoconnect() = 0;
|
||||
|
||||
virtual std::vector<std::pair<std::shared_ptr<Slot>, std::vector<Endpoint>>>
|
||||
buildEndpointsForPeers() = 0;
|
||||
|
||||
/**
|
||||
* Perform periodic activity.
|
||||
* This should be called once per second.
|
||||
*/
|
||||
virtual void
|
||||
oncePerSecond() = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* Properties and state associated with a peer to peer overlay connection.
|
||||
@@ -52,13 +52,13 @@ public:
|
||||
/**
|
||||
* The remote endpoint of socket.
|
||||
*/
|
||||
[[nodiscard]] virtual beast::IP::Endpoint const&
|
||||
[[nodiscard]] virtual beast::ip::Endpoint const&
|
||||
remoteEndpoint() const = 0;
|
||||
|
||||
/**
|
||||
* The local endpoint of the socket, when known.
|
||||
*/
|
||||
[[nodiscard]] virtual std::optional<beast::IP::Endpoint> const&
|
||||
[[nodiscard]] virtual std::optional<beast::ip::Endpoint> const&
|
||||
localEndpoint() const = 0;
|
||||
|
||||
[[nodiscard]] virtual std::optional<std::uint16_t>
|
||||
@@ -72,4 +72,4 @@ public:
|
||||
publicKey() const = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
46
include/xrpl/peerfinder/Types.h
Normal file
46
include/xrpl/peerfinder/Types.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/clock/abstract_clock.h>
|
||||
#include <xrpl/beast/net/IPEndpoint.h>
|
||||
#include <xrpl/peerfinder/detail/Tuning.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
using clock_type = beast::AbstractClock<std::chrono::steady_clock>;
|
||||
|
||||
/**
|
||||
* Represents a set of addresses.
|
||||
*/
|
||||
using IPAddresses = std::vector<beast::ip::Endpoint>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Describes a connectable peer address along with some metadata.
|
||||
*/
|
||||
struct Endpoint
|
||||
{
|
||||
Endpoint() = default;
|
||||
|
||||
Endpoint(beast::ip::Endpoint ep, std::uint32_t hops);
|
||||
|
||||
std::uint32_t hops = 0;
|
||||
beast::ip::Endpoint address;
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator<(Endpoint const& lhs, Endpoint const& rhs)
|
||||
{
|
||||
return lhs.address < rhs.address;
|
||||
}
|
||||
|
||||
/**
|
||||
* A set of Endpoint used for connecting.
|
||||
*/
|
||||
using Endpoints = std::vector<Endpoint>;
|
||||
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/peerfinder/PeerfinderManager.h>
|
||||
#include <xrpld/peerfinder/detail/Store.h>
|
||||
|
||||
#include <xrpl/beast/net/IPEndpoint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/PropertyStream.h>
|
||||
#include <xrpl/peerfinder/Types.h>
|
||||
#include <xrpl/peerfinder/detail/Store.h>
|
||||
#include <xrpl/peerfinder/detail/Tuning.h>
|
||||
|
||||
#include <boost/bimap.hpp>
|
||||
#include <boost/bimap/multiset_of.hpp>
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* Stores IP addresses useful for gaining initial connections.
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
};
|
||||
|
||||
using left_t = boost::bimaps::
|
||||
unordered_set_of<beast::IP::Endpoint, boost::hash<beast::IP::Endpoint>, std::equal_to<>>;
|
||||
unordered_set_of<beast::ip::Endpoint, boost::hash<beast::ip::Endpoint>, std::equal_to<>>;
|
||||
using right_t = boost::bimaps::multiset_of<Entry, std::less<>>;
|
||||
using map_type = boost::bimap<left_t, right_t>;
|
||||
using value_type = map_type::value_type;
|
||||
@@ -73,11 +73,11 @@ private:
|
||||
struct Transform
|
||||
{
|
||||
using first_argument_type = map_type::right_map::const_iterator::value_type const&;
|
||||
using result_type = beast::IP::Endpoint const&;
|
||||
using result_type = beast::ip::Endpoint const&;
|
||||
|
||||
explicit Transform() = default;
|
||||
|
||||
beast::IP::Endpoint const&
|
||||
beast::ip::Endpoint const&
|
||||
operator()(map_type::right_map::const_iterator::value_type const& v) const
|
||||
{
|
||||
return v.get_left();
|
||||
@@ -121,7 +121,7 @@ public:
|
||||
size() const;
|
||||
|
||||
/**
|
||||
* IP::Endpoint iterators that traverse in decreasing valence.
|
||||
* ip::Endpoint iterators that traverse in decreasing valence.
|
||||
*/
|
||||
/** @{ */
|
||||
[[nodiscard]] const_iterator
|
||||
@@ -146,25 +146,25 @@ public:
|
||||
* Add a newly-learned address to the cache.
|
||||
*/
|
||||
bool
|
||||
insert(beast::IP::Endpoint const& endpoint);
|
||||
insert(beast::ip::Endpoint const& endpoint);
|
||||
|
||||
/**
|
||||
* Add a staticallyconfigured address to the cache.
|
||||
*/
|
||||
bool
|
||||
insertStatic(beast::IP::Endpoint const& endpoint);
|
||||
insertStatic(beast::ip::Endpoint const& endpoint);
|
||||
|
||||
/**
|
||||
* Called when an outbound connection handshake completes.
|
||||
*/
|
||||
void
|
||||
onSuccess(beast::IP::Endpoint const& endpoint);
|
||||
onSuccess(beast::ip::Endpoint const& endpoint);
|
||||
|
||||
/**
|
||||
* Called when an outbound connection attempt fails to handshake.
|
||||
*/
|
||||
void
|
||||
onFailure(beast::IP::Endpoint const& endpoint);
|
||||
onFailure(beast::ip::Endpoint const& endpoint);
|
||||
|
||||
/**
|
||||
* Stores the cache in the persistent database on a timer.
|
||||
@@ -189,4 +189,4 @@ private:
|
||||
flagForUpdate();
|
||||
};
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* Tests remote listening sockets to make sure they are connectable.
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
*/
|
||||
template <class Handler>
|
||||
void
|
||||
asyncConnect(beast::IP::Endpoint const& endpoint, Handler&& handler);
|
||||
asyncConnect(beast::ip::Endpoint const& endpoint, Handler&& handler);
|
||||
|
||||
private:
|
||||
void
|
||||
@@ -179,7 +179,7 @@ Checker<Protocol>::wait()
|
||||
template <class Protocol>
|
||||
template <class Handler>
|
||||
void
|
||||
Checker<Protocol>::asyncConnect(beast::IP::Endpoint const& endpoint, Handler&& handler)
|
||||
Checker<Protocol>::asyncConnect(beast::ip::Endpoint const& endpoint, Handler&& handler)
|
||||
{
|
||||
auto const op =
|
||||
std::make_shared<AsyncOp<Handler>>(*this, ioContext_, std::forward<Handler>(handler));
|
||||
@@ -202,4 +202,4 @@ Checker<Protocol>::remove(BasicAsyncOp& op)
|
||||
cond_.notify_all();
|
||||
}
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -1,17 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/peerfinder/PeerfinderManager.h>
|
||||
#include <xrpld/peerfinder/Slot.h>
|
||||
#include <xrpld/peerfinder/detail/Tuning.h>
|
||||
|
||||
#include <xrpl/beast/utility/PropertyStream.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/peerfinder/Config.h>
|
||||
#include <xrpl/peerfinder/Slot.h>
|
||||
#include <xrpl/peerfinder/detail/Tuning.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* Direction of a slot count adjustment.
|
||||
@@ -51,7 +50,7 @@ public:
|
||||
// Must be handshaked and in the right state
|
||||
XRPL_ASSERT(
|
||||
s.state() == Slot::State::Connected || s.state() == Slot::State::Accept,
|
||||
"xrpl::PeerFinder::Counts::can_activate : valid input state");
|
||||
"xrpl::peer_finder::Counts::can_activate : valid input state");
|
||||
|
||||
if (s.fixed() || s.reserved())
|
||||
return true;
|
||||
@@ -68,9 +67,9 @@ public:
|
||||
[[nodiscard]] std::size_t
|
||||
attemptsNeeded() const
|
||||
{
|
||||
if (attempts_ >= Tuning::kMaxConnectAttempts)
|
||||
if (attempts_ >= tuning::kMaxConnectAttempts)
|
||||
return 0;
|
||||
return Tuning::kMaxConnectAttempts - attempts_;
|
||||
return tuning::kMaxConnectAttempts - attempts_;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,7 +295,7 @@ private:
|
||||
switch (s.state())
|
||||
{
|
||||
case Slot::State::Accept:
|
||||
XRPL_ASSERT(s.inbound(), "xrpl::PeerFinder::Counts::adjust : input is inbound");
|
||||
XRPL_ASSERT(s.inbound(), "xrpl::peer_finder::Counts::adjust : input is inbound");
|
||||
acceptCount_ += n;
|
||||
break;
|
||||
|
||||
@@ -304,7 +303,7 @@ private:
|
||||
case Slot::State::Connected:
|
||||
XRPL_ASSERT(
|
||||
!s.inbound(),
|
||||
"xrpl::PeerFinder::Counts::adjust : input is not "
|
||||
"xrpl::peer_finder::Counts::adjust : input is not "
|
||||
"inbound");
|
||||
attempts_ += n;
|
||||
break;
|
||||
@@ -332,7 +331,7 @@ private:
|
||||
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
UNREACHABLE("xrpl::PeerFinder::Counts::adjust : invalid input state");
|
||||
UNREACHABLE("xrpl::peer_finder::Counts::adjust : invalid input state");
|
||||
break;
|
||||
// LCOV_EXCL_STOP
|
||||
};
|
||||
@@ -392,4 +391,4 @@ private:
|
||||
int closingCount_{0};
|
||||
};
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/peerfinder/PeerfinderManager.h>
|
||||
#include <xrpld/peerfinder/detail/Tuning.h>
|
||||
#include <xrpl/peerfinder/Types.h>
|
||||
#include <xrpl/peerfinder/detail/Tuning.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* Metadata for a Fixed slot.
|
||||
@@ -36,8 +36,8 @@ public:
|
||||
void
|
||||
failure(clock_type::time_point const& now)
|
||||
{
|
||||
failures_ = std::min(failures_ + 1, Tuning::kConnectionBackoff.size() - 1);
|
||||
when_ = now + std::chrono::minutes(Tuning::kConnectionBackoff[failures_]);
|
||||
failures_ = std::min(failures_ + 1, tuning::kConnectionBackoff.size() - 1);
|
||||
when_ = now + std::chrono::minutes(tuning::kConnectionBackoff[failures_]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,4 +55,4 @@ private:
|
||||
std::size_t failures_{0};
|
||||
};
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -1,19 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/peerfinder/PeerfinderManager.h>
|
||||
#include <xrpld/peerfinder/detail/SlotImp.h>
|
||||
#include <xrpld/peerfinder/detail/Tuning.h>
|
||||
|
||||
#include <xrpl/beast/container/aged_set.h>
|
||||
#include <xrpl/beast/net/IPAddress.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/peerfinder/Types.h>
|
||||
#include <xrpl/peerfinder/detail/SlotImp.h>
|
||||
#include <xrpl/peerfinder/detail/Tuning.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -29,7 +28,7 @@ template <class Target, class HopContainer>
|
||||
std::size_t
|
||||
handoutOne(Target& t, HopContainer& h)
|
||||
{
|
||||
XRPL_ASSERT(!t.full(), "xrpl::PeerFinder::detail::handoutOne : target is not full");
|
||||
XRPL_ASSERT(!t.full(), "xrpl::peer_finder::detail::handoutOne : target is not full");
|
||||
for (auto it = h.begin(); it != h.end(); ++it)
|
||||
{
|
||||
auto const& e = *it;
|
||||
@@ -96,7 +95,7 @@ public:
|
||||
[[nodiscard]] bool
|
||||
full() const
|
||||
{
|
||||
return list_.size() >= Tuning::kRedirectEndpointCount;
|
||||
return list_.size() >= tuning::kRedirectEndpointCount;
|
||||
}
|
||||
|
||||
[[nodiscard]] SlotImp::ptr const&
|
||||
@@ -125,7 +124,7 @@ private:
|
||||
template <class>
|
||||
RedirectHandouts::RedirectHandouts(SlotImp::ptr slot) : slot_(std::move(slot))
|
||||
{
|
||||
list_.reserve(Tuning::kRedirectEndpointCount);
|
||||
list_.reserve(tuning::kRedirectEndpointCount);
|
||||
}
|
||||
|
||||
template <class>
|
||||
@@ -139,7 +138,7 @@ RedirectHandouts::tryInsert(Endpoint const& ep)
|
||||
// addresses in a peer HTTP handshake instead of
|
||||
// the tmENDPOINTS message.
|
||||
//
|
||||
if (ep.hops > Tuning::kMaxHops)
|
||||
if (ep.hops > tuning::kMaxHops)
|
||||
return false;
|
||||
|
||||
// Don't send them our address
|
||||
@@ -182,7 +181,7 @@ public:
|
||||
[[nodiscard]] bool
|
||||
full() const
|
||||
{
|
||||
return list_.size() >= Tuning::kNumberOfEndpoints;
|
||||
return list_.size() >= tuning::kNumberOfEndpoints;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -211,7 +210,7 @@ private:
|
||||
template <class>
|
||||
SlotHandouts::SlotHandouts(SlotImp::ptr slot) : slot_(std::move(slot))
|
||||
{
|
||||
list_.reserve(Tuning::kNumberOfEndpoints);
|
||||
list_.reserve(tuning::kNumberOfEndpoints);
|
||||
}
|
||||
|
||||
template <class>
|
||||
@@ -221,7 +220,7 @@ SlotHandouts::tryInsert(Endpoint const& ep)
|
||||
if (full())
|
||||
return false;
|
||||
|
||||
if (ep.hops > Tuning::kMaxHops)
|
||||
if (ep.hops > tuning::kMaxHops)
|
||||
return false;
|
||||
|
||||
if (slot_->recent.filter(ep.address, ep.hops))
|
||||
@@ -260,9 +259,9 @@ class ConnectHandouts
|
||||
public:
|
||||
// Keeps track of addresses we have made outgoing connections
|
||||
// to, for the purposes of not connecting to them too frequently.
|
||||
using Squelches = beast::aged_set<beast::IP::Address>;
|
||||
using Squelches = beast::aged_set<beast::ip::Address>;
|
||||
|
||||
using list_type = std::vector<beast::IP::Endpoint>;
|
||||
using list_type = std::vector<beast::ip::Endpoint>;
|
||||
|
||||
private:
|
||||
std::size_t needed_;
|
||||
@@ -275,7 +274,7 @@ public:
|
||||
|
||||
template <class = void>
|
||||
bool
|
||||
tryInsert(beast::IP::Endpoint const& endpoint);
|
||||
tryInsert(beast::ip::Endpoint const& endpoint);
|
||||
|
||||
[[nodiscard]] bool
|
||||
empty() const
|
||||
@@ -317,13 +316,13 @@ ConnectHandouts::ConnectHandouts(std::size_t needed, Squelches& squelches)
|
||||
|
||||
template <class>
|
||||
bool
|
||||
ConnectHandouts::tryInsert(beast::IP::Endpoint const& endpoint)
|
||||
ConnectHandouts::tryInsert(beast::ip::Endpoint const& endpoint)
|
||||
{
|
||||
if (full())
|
||||
return false;
|
||||
|
||||
// Make sure the address isn't already in our list
|
||||
if (std::ranges::any_of(list_, [&endpoint](beast::IP::Endpoint const& other) {
|
||||
if (std::ranges::any_of(list_, [&endpoint](beast::ip::Endpoint const& other) {
|
||||
// Ignore port for security reasons
|
||||
return other.address() == endpoint.address();
|
||||
}))
|
||||
@@ -342,4 +341,4 @@ ConnectHandouts::tryInsert(beast::IP::Endpoint const& endpoint)
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -1,9 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/peerfinder/PeerfinderManager.h>
|
||||
#include <xrpld/peerfinder/detail/Tuning.h>
|
||||
#include <xrpld/peerfinder/detail/iosformat.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/random.h>
|
||||
#include <xrpl/beast/container/aged_map.h>
|
||||
@@ -12,6 +8,8 @@
|
||||
#include <xrpl/beast/utility/PropertyStream.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/beast/utility/maybe_const.h>
|
||||
#include <xrpl/peerfinder/Types.h>
|
||||
#include <xrpl/peerfinder/detail/Tuning.h>
|
||||
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
@@ -22,6 +20,8 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
template <class>
|
||||
class Livecache;
|
||||
@@ -188,10 +188,10 @@ class Livecache : protected detail::LivecacheBase
|
||||
{
|
||||
private:
|
||||
using cache_type = beast::aged_map<
|
||||
beast::IP::Endpoint,
|
||||
beast::ip::Endpoint,
|
||||
Element,
|
||||
std::chrono::steady_clock,
|
||||
std::less<beast::IP::Endpoint>,
|
||||
std::less<beast::ip::Endpoint>,
|
||||
Allocator>;
|
||||
|
||||
beast::Journal journal_;
|
||||
@@ -220,8 +220,8 @@ public:
|
||||
// but not given out (since they would exceed maxHops). They
|
||||
// are used for automatic connection attempts.
|
||||
//
|
||||
using Histogram = std::array<int, 1 + Tuning::kMaxHops + 1>;
|
||||
using lists_type = std::array<list_type, 1 + Tuning::kMaxHops + 1>;
|
||||
using Histogram = std::array<int, 1 + tuning::kMaxHops + 1>;
|
||||
using lists_type = std::array<list_type, 1 + tuning::kMaxHops + 1>;
|
||||
|
||||
template <bool IsConst>
|
||||
struct Transform
|
||||
@@ -400,7 +400,7 @@ Livecache<Allocator>::expire()
|
||||
{
|
||||
std::size_t n(0);
|
||||
typename cache_type::time_point const expired(
|
||||
cache_.clock().now() - Tuning::kLiveCacheSecondsToLive);
|
||||
cache_.clock().now() - tuning::kLiveCacheSecondsToLive);
|
||||
for (auto iter(cache_.chronological.begin());
|
||||
iter != cache_.chronological.end() && iter.when() <= expired;)
|
||||
{
|
||||
@@ -411,7 +411,7 @@ Livecache<Allocator>::expire()
|
||||
}
|
||||
if (n > 0)
|
||||
{
|
||||
JLOG(journal_.debug()) << beast::Leftw(18) << "Livecache expired " << n
|
||||
JLOG(journal_.debug()) << std::left << std::setw(18) << "Livecache expired " << n
|
||||
<< ((n > 1) ? " entries" : " entry");
|
||||
}
|
||||
}
|
||||
@@ -427,14 +427,14 @@ Livecache<Allocator>::insert(Endpoint const& ep)
|
||||
// when redirecting.
|
||||
//
|
||||
XRPL_ASSERT(
|
||||
ep.hops <= (Tuning::kMaxHops + 1),
|
||||
"xrpl::PeerFinder::Livecache::insert : maximum input hops");
|
||||
ep.hops <= (tuning::kMaxHops + 1),
|
||||
"xrpl::peer_finder::Livecache::insert : maximum input hops");
|
||||
auto result = cache_.emplace(ep.address, ep);
|
||||
Element& e(result.first->second);
|
||||
if (result.second)
|
||||
{
|
||||
hops.insert(e);
|
||||
JLOG(journal_.debug()) << beast::Leftw(18) << "Livecache insert " << ep.address
|
||||
JLOG(journal_.debug()) << std::left << std::setw(18) << "Livecache insert " << ep.address
|
||||
<< " at hops " << ep.hops;
|
||||
return;
|
||||
}
|
||||
@@ -442,7 +442,7 @@ Livecache<Allocator>::insert(Endpoint const& ep)
|
||||
{
|
||||
// Drop duplicates at higher hops
|
||||
std::size_t const excess(ep.hops - e.endpoint.hops);
|
||||
JLOG(journal_.trace()) << beast::Leftw(18) << "Livecache drop " << ep.address
|
||||
JLOG(journal_.trace()) << std::left << std::setw(18) << "Livecache drop " << ep.address
|
||||
<< " at hops +" << excess;
|
||||
return;
|
||||
}
|
||||
@@ -453,12 +453,12 @@ Livecache<Allocator>::insert(Endpoint const& ep)
|
||||
if (ep.hops < e.endpoint.hops)
|
||||
{
|
||||
hops.reinsert(e, ep.hops);
|
||||
JLOG(journal_.debug()) << beast::Leftw(18) << "Livecache update " << ep.address
|
||||
JLOG(journal_.debug()) << std::left << std::setw(18) << "Livecache update " << ep.address
|
||||
<< " at hops " << ep.hops;
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(journal_.trace()) << beast::Leftw(18) << "Livecache refresh " << ep.address
|
||||
JLOG(journal_.trace()) << std::left << std::setw(18) << "Livecache refresh " << ep.address
|
||||
<< " at hops " << ep.hops;
|
||||
}
|
||||
}
|
||||
@@ -468,7 +468,7 @@ void
|
||||
Livecache<Allocator>::onWrite(beast::PropertyStream::Map& map)
|
||||
{
|
||||
typename cache_type::time_point const expired(
|
||||
cache_.clock().now() - Tuning::kLiveCacheSecondsToLive);
|
||||
cache_.clock().now() - tuning::kLiveCacheSecondsToLive);
|
||||
map["size"] = size();
|
||||
map["hist"] = hops.histogram();
|
||||
beast::PropertyStream::Set set("entries", map);
|
||||
@@ -527,8 +527,8 @@ void
|
||||
Livecache<Allocator>::HopsT::insert(Element& e)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
e.endpoint.hops <= Tuning::kMaxHops + 1,
|
||||
"xrpl::PeerFinder::Livecache::HopsT::insert : maximum input hops");
|
||||
e.endpoint.hops <= tuning::kMaxHops + 1,
|
||||
"xrpl::peer_finder::Livecache::HopsT::insert : maximum input hops");
|
||||
// This has security implications without a shuffle
|
||||
lists_[e.endpoint.hops].push_front(e);
|
||||
++hist_[e.endpoint.hops];
|
||||
@@ -539,8 +539,8 @@ void
|
||||
Livecache<Allocator>::HopsT::reinsert(Element& e, std::uint32_t numHops)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
numHops <= Tuning::kMaxHops + 1,
|
||||
"xrpl::PeerFinder::Livecache::HopsT::reinsert : maximum hops input");
|
||||
numHops <= tuning::kMaxHops + 1,
|
||||
"xrpl::peer_finder::Livecache::HopsT::reinsert : maximum hops input");
|
||||
|
||||
auto& list = lists_[e.endpoint.hops];
|
||||
list.erase(list.iterator_to(e));
|
||||
@@ -561,4 +561,4 @@ Livecache<Allocator>::HopsT::remove(Element& e)
|
||||
list.erase(list.iterator_to(e));
|
||||
}
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -1,17 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/peerfinder/PeerfinderManager.h>
|
||||
#include <xrpld/peerfinder/Slot.h>
|
||||
#include <xrpld/peerfinder/detail/Bootcache.h>
|
||||
#include <xrpld/peerfinder/detail/Counts.h>
|
||||
#include <xrpld/peerfinder/detail/Fixed.h>
|
||||
#include <xrpld/peerfinder/detail/Handouts.h>
|
||||
#include <xrpld/peerfinder/detail/Livecache.h>
|
||||
#include <xrpld/peerfinder/detail/SlotImp.h>
|
||||
#include <xrpld/peerfinder/detail/Source.h>
|
||||
#include <xrpld/peerfinder/detail/Store.h>
|
||||
#include <xrpld/peerfinder/detail/iosformat.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/basics/random.h>
|
||||
@@ -22,24 +10,40 @@
|
||||
#include <xrpl/beast/utility/PropertyStream.h>
|
||||
#include <xrpl/beast/utility/WrappedSink.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/peerfinder/Config.h>
|
||||
#include <xrpl/peerfinder/Slot.h>
|
||||
#include <xrpl/peerfinder/Types.h>
|
||||
#include <xrpl/peerfinder/detail/Bootcache.h>
|
||||
#include <xrpl/peerfinder/detail/Counts.h>
|
||||
#include <xrpl/peerfinder/detail/Fixed.h>
|
||||
#include <xrpl/peerfinder/detail/Handouts.h>
|
||||
#include <xrpl/peerfinder/detail/Livecache.h>
|
||||
#include <xrpl/peerfinder/detail/SlotImp.h>
|
||||
#include <xrpl/peerfinder/detail/Source.h>
|
||||
#include <xrpl/peerfinder/detail/Store.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
|
||||
#include <boost/asio/error.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* The Logic for maintaining the list of Slot addresses.
|
||||
@@ -53,7 +57,7 @@ public:
|
||||
// Maps remote endpoints to slots. Since a slot has a
|
||||
// remote endpoint upon construction, this holds all counts_.
|
||||
//
|
||||
using Slots = std::map<beast::IP::Endpoint, std::shared_ptr<SlotImp>>;
|
||||
using Slots = std::map<beast::ip::Endpoint, std::shared_ptr<SlotImp>>;
|
||||
|
||||
beast::Journal journal;
|
||||
clock_type& clock;
|
||||
@@ -77,7 +81,7 @@ private:
|
||||
Counts counts_;
|
||||
|
||||
// A list of slots that should always be connected
|
||||
std::map<beast::IP::Endpoint, Fixed> fixed_;
|
||||
std::map<beast::ip::Endpoint, Fixed> fixed_;
|
||||
|
||||
public:
|
||||
// Live livecache from mtENDPOINTS messages
|
||||
@@ -92,7 +96,7 @@ public:
|
||||
// The addresses (but not port) we are connected to. This includes
|
||||
// outgoing connection attempts. Note that this set can contain
|
||||
// duplicates (since the port is not set)
|
||||
std::multiset<beast::IP::Address> connectedAddresses;
|
||||
std::multiset<beast::ip::Address> connectedAddresses;
|
||||
|
||||
// Set of public keys belonging to active peers
|
||||
std::set<PublicKey> keys;
|
||||
@@ -166,13 +170,13 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
addFixedPeer(std::string_view name, beast::IP::Endpoint const& ep)
|
||||
addFixedPeer(std::string_view name, beast::ip::Endpoint const& ep)
|
||||
{
|
||||
addFixedPeer(name, std::vector<beast::IP::Endpoint>{ep});
|
||||
addFixedPeer(name, std::vector<beast::ip::Endpoint>{ep});
|
||||
}
|
||||
|
||||
void
|
||||
addFixedPeer(std::string_view name, std::vector<beast::IP::Endpoint> const& addresses)
|
||||
addFixedPeer(std::string_view name, std::vector<beast::ip::Endpoint> const& addresses)
|
||||
{
|
||||
std::scoped_lock const _(lock);
|
||||
|
||||
@@ -197,8 +201,8 @@ public:
|
||||
|
||||
if (result.second)
|
||||
{
|
||||
JLOG(journal.debug())
|
||||
<< beast::Leftw(18) << "Logic add fixed '" << name << "' at " << remoteAddress;
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic add fixed '" << name
|
||||
<< "' at " << remoteAddress;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -209,8 +213,8 @@ public:
|
||||
// Called when the Checker completes a connectivity test
|
||||
void
|
||||
checkComplete(
|
||||
beast::IP::Endpoint const& remoteAddress,
|
||||
beast::IP::Endpoint const& checkedAddress,
|
||||
beast::ip::Endpoint const& remoteAddress,
|
||||
beast::ip::Endpoint const& checkedAddress,
|
||||
boost::system::error_code ec)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
@@ -221,7 +225,7 @@ public:
|
||||
if (iter == slots.end())
|
||||
{
|
||||
// The slot disconnected before we finished the check
|
||||
JLOG(journal.debug()) << beast::Leftw(18) << "Logic tested " << checkedAddress
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic tested " << checkedAddress
|
||||
<< " but the connection was closed";
|
||||
return;
|
||||
}
|
||||
@@ -252,10 +256,10 @@ public:
|
||||
|
||||
std::pair<SlotImp::ptr, Result>
|
||||
newInboundSlot(
|
||||
beast::IP::Endpoint const& localEndpoint,
|
||||
beast::IP::Endpoint const& remoteEndpoint)
|
||||
beast::ip::Endpoint const& localEndpoint,
|
||||
beast::ip::Endpoint const& remoteEndpoint)
|
||||
{
|
||||
JLOG(journal.debug()) << beast::Leftw(18) << "Logic accept" << remoteEndpoint
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic accept" << remoteEndpoint
|
||||
<< " on local " << localEndpoint;
|
||||
|
||||
std::scoped_lock const _(lock);
|
||||
@@ -266,7 +270,7 @@ public:
|
||||
auto const count = connectedAddresses.count(remoteEndpoint.address());
|
||||
if (count + 1 > config_.ipLimit)
|
||||
{
|
||||
JLOG(journal.debug()) << beast::Leftw(18) << "Logic dropping inbound "
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic dropping inbound "
|
||||
<< remoteEndpoint << " because of ip limits.";
|
||||
return {SlotImp::ptr(), Result::IpLimitExceeded};
|
||||
}
|
||||
@@ -275,8 +279,8 @@ public:
|
||||
// Check for duplicate connection
|
||||
if (slots.contains(remoteEndpoint))
|
||||
{
|
||||
JLOG(journal.debug()) << beast::Leftw(18) << "Logic dropping " << remoteEndpoint
|
||||
<< " as duplicate incoming";
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic dropping "
|
||||
<< remoteEndpoint << " as duplicate incoming";
|
||||
return {SlotImp::ptr(), Result::DuplicatePeer};
|
||||
}
|
||||
|
||||
@@ -289,7 +293,7 @@ public:
|
||||
// Remote address must not already exist
|
||||
XRPL_ASSERT(
|
||||
result.second,
|
||||
"xrpl::PeerFinder::Logic::new_inbound_slot : remote endpoint "
|
||||
"xrpl::peer_finder::Logic::new_inbound_slot : remote endpoint "
|
||||
"inserted");
|
||||
// Add to the connected address list
|
||||
connectedAddresses.emplace(remoteEndpoint.address());
|
||||
@@ -302,17 +306,17 @@ public:
|
||||
|
||||
// Can't check for self-connect because we don't know the local endpoint
|
||||
std::pair<SlotImp::ptr, Result>
|
||||
newOutboundSlot(beast::IP::Endpoint const& remoteEndpoint)
|
||||
newOutboundSlot(beast::ip::Endpoint const& remoteEndpoint)
|
||||
{
|
||||
JLOG(journal.debug()) << beast::Leftw(18) << "Logic connect " << remoteEndpoint;
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic connect " << remoteEndpoint;
|
||||
|
||||
std::scoped_lock const _(lock);
|
||||
|
||||
// Check for duplicate connection
|
||||
if (slots.contains(remoteEndpoint))
|
||||
{
|
||||
JLOG(journal.debug()) << beast::Leftw(18) << "Logic dropping " << remoteEndpoint
|
||||
<< " as duplicate connect";
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic dropping "
|
||||
<< remoteEndpoint << " as duplicate connect";
|
||||
return {SlotImp::ptr(), Result::DuplicatePeer};
|
||||
}
|
||||
|
||||
@@ -325,7 +329,7 @@ public:
|
||||
// Remote address must not already exist
|
||||
XRPL_ASSERT(
|
||||
result.second,
|
||||
"xrpl::PeerFinder::Logic::new_outbound_slot : remote endpoint "
|
||||
"xrpl::peer_finder::Logic::new_outbound_slot : remote endpoint "
|
||||
"inserted");
|
||||
|
||||
// Add to the connected address list
|
||||
@@ -338,7 +342,7 @@ public:
|
||||
}
|
||||
|
||||
bool
|
||||
onConnected(SlotImp::ptr const& slot, beast::IP::Endpoint const& localEndpoint)
|
||||
onConnected(SlotImp::ptr const& slot, beast::ip::Endpoint const& localEndpoint)
|
||||
{
|
||||
beast::WrappedSink sink{journal.sink(), slot->prefix()};
|
||||
beast::Journal const journal{sink};
|
||||
@@ -350,7 +354,7 @@ public:
|
||||
// The object must exist in our table
|
||||
XRPL_ASSERT(
|
||||
slots.contains(slot->remoteEndpoint()),
|
||||
"xrpl::PeerFinder::Logic::onConnected : valid slot input");
|
||||
"xrpl::peer_finder::Logic::onConnected : valid slot input");
|
||||
// Assign the local endpoint now that it's known
|
||||
slot->localEndpoint(localEndpoint);
|
||||
|
||||
@@ -361,7 +365,7 @@ public:
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
iter->second->localEndpoint() == slot->remoteEndpoint(),
|
||||
"xrpl::PeerFinder::Logic::onConnected : local and remote "
|
||||
"xrpl::peer_finder::Logic::onConnected : local and remote "
|
||||
"endpoints do match");
|
||||
JLOG(journal.warn()) << "Logic dropping as self connect";
|
||||
return false;
|
||||
@@ -389,11 +393,11 @@ public:
|
||||
// The object must exist in our table
|
||||
XRPL_ASSERT(
|
||||
slots.contains(slot->remoteEndpoint()),
|
||||
"xrpl::PeerFinder::Logic::activate : valid slot input");
|
||||
"xrpl::peer_finder::Logic::activate : valid slot input");
|
||||
// Must be accepted or connected
|
||||
XRPL_ASSERT(
|
||||
slot->state() == Slot::State::Accept || slot->state() == Slot::State::Connected,
|
||||
"xrpl::PeerFinder::Logic::activate : valid slot state");
|
||||
"xrpl::peer_finder::Logic::activate : valid slot state");
|
||||
|
||||
// Check for duplicate connection by key
|
||||
if (keys.contains(key))
|
||||
@@ -421,7 +425,7 @@ public:
|
||||
{
|
||||
[[maybe_unused]] bool const inserted = keys.insert(key).second;
|
||||
// Public key must not already exist
|
||||
XRPL_ASSERT(inserted, "xrpl::PeerFinder::Logic::activate : public key inserted");
|
||||
XRPL_ASSERT(inserted, "xrpl::peer_finder::Logic::activate : public key inserted");
|
||||
}
|
||||
|
||||
// Change state and update counts
|
||||
@@ -439,7 +443,7 @@ public:
|
||||
if (iter == fixed_.end())
|
||||
{
|
||||
logicError(
|
||||
"PeerFinder::Logic::activate(): remote_endpoint "
|
||||
"peer_finder::Logic::activate(): remote_endpoint "
|
||||
"missing from fixed_");
|
||||
}
|
||||
|
||||
@@ -472,10 +476,10 @@ public:
|
||||
// VFALCO TODO This should add the returned addresses to the
|
||||
// squelch list in one go once the list is built,
|
||||
// rather than having each module add to the squelch list.
|
||||
std::vector<beast::IP::Endpoint>
|
||||
std::vector<beast::ip::Endpoint>
|
||||
autoconnect()
|
||||
{
|
||||
std::vector<beast::IP::Endpoint> none;
|
||||
std::vector<beast::ip::Endpoint> none;
|
||||
|
||||
std::scoped_lock const _(lock);
|
||||
|
||||
@@ -506,15 +510,15 @@ public:
|
||||
|
||||
if (!h.list().empty())
|
||||
{
|
||||
JLOG(journal.debug())
|
||||
<< beast::Leftw(18) << "Logic connect " << h.list().size() << " fixed";
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic connect "
|
||||
<< h.list().size() << " fixed";
|
||||
return h.list();
|
||||
}
|
||||
|
||||
if (counts_.attempts() > 0)
|
||||
{
|
||||
JLOG(journal.debug())
|
||||
<< beast::Leftw(18) << "Logic waiting on " << counts_.attempts() << " attempts";
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic waiting on "
|
||||
<< counts_.attempts() << " attempts";
|
||||
return none;
|
||||
}
|
||||
}
|
||||
@@ -535,14 +539,14 @@ public:
|
||||
if (!h.list().empty())
|
||||
{
|
||||
JLOG(journal.debug())
|
||||
<< beast::Leftw(18) << "Logic connect " << h.list().size() << " live "
|
||||
<< std::left << std::setw(18) << "Logic connect " << h.list().size() << " live "
|
||||
<< ((h.list().size() > 1) ? "endpoints" : "endpoint");
|
||||
return h.list();
|
||||
}
|
||||
if (counts_.attempts() > 0)
|
||||
{
|
||||
JLOG(journal.debug())
|
||||
<< beast::Leftw(18) << "Logic waiting on " << counts_.attempts() << " attempts";
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic waiting on "
|
||||
<< counts_.attempts() << " attempts";
|
||||
return none;
|
||||
}
|
||||
}
|
||||
@@ -568,8 +572,9 @@ public:
|
||||
|
||||
if (!h.list().empty())
|
||||
{
|
||||
JLOG(journal.debug()) << beast::Leftw(18) << "Logic connect " << h.list().size()
|
||||
<< " boot " << ((h.list().size() > 1) ? "addresses" : "address");
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Logic connect "
|
||||
<< h.list().size() << " boot "
|
||||
<< ((h.list().size() > 1) ? "addresses" : "address");
|
||||
return h.list();
|
||||
}
|
||||
|
||||
@@ -630,7 +635,7 @@ public:
|
||||
// either. ipv6 has a slightly more compact string
|
||||
// representation of 0, so use that for self entries.
|
||||
ep.address =
|
||||
beast::IP::Endpoint(beast::IP::AddressV6()).atPort(config_.listeningPort);
|
||||
beast::ip::Endpoint(beast::ip::AddressV6()).atPort(config_.listeningPort);
|
||||
for (auto& t : targets)
|
||||
t.insert(ep);
|
||||
}
|
||||
@@ -651,7 +656,7 @@ public:
|
||||
result.emplace_back(slot, list);
|
||||
}
|
||||
|
||||
whenBroadcast = now + Tuning::kSecondsPerMessage;
|
||||
whenBroadcast = now + tuning::kSecondsPerMessage;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -670,7 +675,7 @@ public:
|
||||
entry.second->expire();
|
||||
|
||||
// Expire the recent attempts table
|
||||
beast::expire(squelches, Tuning::kRecentAttemptDuration);
|
||||
beast::expire(squelches, tuning::kRecentAttemptDuration);
|
||||
|
||||
bootcache.periodicActivity();
|
||||
}
|
||||
@@ -687,10 +692,10 @@ public:
|
||||
Endpoint& ep(*iter);
|
||||
|
||||
// Enforce hop limit
|
||||
if (ep.hops > Tuning::kMaxHops)
|
||||
if (ep.hops > tuning::kMaxHops)
|
||||
{
|
||||
JLOG(journal.debug()) << beast::Leftw(18) << "Endpoints drop " << ep.address
|
||||
<< " for excess hops " << ep.hops;
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Endpoints drop "
|
||||
<< ep.address << " for excess hops " << ep.hops;
|
||||
iter = list.erase(iter);
|
||||
continue;
|
||||
}
|
||||
@@ -706,18 +711,18 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(journal.debug())
|
||||
<< beast::Leftw(18) << "Endpoints drop " << ep.address << " for extra self";
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Endpoints drop "
|
||||
<< ep.address << " for extra self";
|
||||
iter = list.erase(iter);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Discard invalid addresses
|
||||
if (config_.verifyEndpoints && !isValidAddress(ep.address))
|
||||
if (!isValidAddress(ep.address))
|
||||
{
|
||||
JLOG(journal.debug())
|
||||
<< beast::Leftw(18) << "Endpoints drop " << ep.address << " as invalid";
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Endpoints drop "
|
||||
<< ep.address << " as invalid";
|
||||
iter = list.erase(iter);
|
||||
continue;
|
||||
}
|
||||
@@ -727,8 +732,8 @@ public:
|
||||
return ep.address == other.address;
|
||||
}))
|
||||
{
|
||||
JLOG(journal.debug())
|
||||
<< beast::Leftw(18) << "Endpoints drop " << ep.address << " as duplicate";
|
||||
JLOG(journal.debug()) << std::left << std::setw(18) << "Endpoints drop "
|
||||
<< ep.address << " as duplicate";
|
||||
iter = list.erase(iter);
|
||||
continue;
|
||||
}
|
||||
@@ -749,10 +754,10 @@ public:
|
||||
beast::Journal const journal{sink};
|
||||
|
||||
// If we're sent too many endpoints, sample them at random:
|
||||
if (list.size() > Tuning::kNumberOfEndpointsMax)
|
||||
if (list.size() > tuning::kNumberOfEndpointsMax)
|
||||
{
|
||||
std::shuffle(list.begin(), list.end(), defaultPrng());
|
||||
list.resize(Tuning::kNumberOfEndpointsMax);
|
||||
list.resize(tuning::kNumberOfEndpointsMax);
|
||||
}
|
||||
|
||||
JLOG(journal.trace()) << "Endpoints contained " << list.size()
|
||||
@@ -763,12 +768,12 @@ public:
|
||||
// The object must exist in our table
|
||||
XRPL_ASSERT(
|
||||
slots.contains(slot->remoteEndpoint()),
|
||||
"xrpl::PeerFinder::Logic::onEndpoints : valid slot input");
|
||||
"xrpl::peer_finder::Logic::onEndpoints : valid slot input");
|
||||
|
||||
// Must be handshaked!
|
||||
XRPL_ASSERT(
|
||||
slot->state() == Slot::State::Active,
|
||||
"xrpl::PeerFinder::Logic::onEndpoints : valid slot state");
|
||||
"xrpl::peer_finder::Logic::onEndpoints : valid slot state");
|
||||
|
||||
clock_type::time_point const now(clock.now());
|
||||
|
||||
@@ -780,7 +785,7 @@ public:
|
||||
|
||||
for (auto const& ep : list)
|
||||
{
|
||||
XRPL_ASSERT(ep.hops, "xrpl::PeerFinder::Logic::onEndpoints : nonzero hops");
|
||||
XRPL_ASSERT(ep.hops, "xrpl::peer_finder::Logic::onEndpoints : nonzero hops");
|
||||
|
||||
slot->recent.insert(ep.address, ep.hops);
|
||||
|
||||
@@ -832,7 +837,7 @@ public:
|
||||
bootcache.insert(ep.address);
|
||||
}
|
||||
|
||||
slot->whenAcceptEndpoints = now + Tuning::kSecondsPerMessage;
|
||||
slot->whenAcceptEndpoints = now + tuning::kSecondsPerMessage;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -846,7 +851,7 @@ public:
|
||||
if (iter == slots.end())
|
||||
{
|
||||
logicError(
|
||||
"PeerFinder::Logic::remove(): remote_endpoint "
|
||||
"peer_finder::Logic::remove(): remote_endpoint "
|
||||
"missing from slots_");
|
||||
}
|
||||
|
||||
@@ -861,7 +866,7 @@ public:
|
||||
if (iter == keys.end())
|
||||
{
|
||||
logicError(
|
||||
"PeerFinder::Logic::remove(): public_key missing "
|
||||
"peer_finder::Logic::remove(): public_key missing "
|
||||
"from keys_");
|
||||
}
|
||||
|
||||
@@ -874,7 +879,7 @@ public:
|
||||
if (iter == connectedAddresses.end())
|
||||
{
|
||||
logicError(
|
||||
"PeerFinder::Logic::remove(): remote_endpoint "
|
||||
"peer_finder::Logic::remove(): remote_endpoint "
|
||||
"address missing from connectedAddresses_");
|
||||
}
|
||||
|
||||
@@ -902,7 +907,7 @@ public:
|
||||
if (iter == fixed_.end())
|
||||
{
|
||||
logicError(
|
||||
"PeerFinder::Logic::on_closed(): remote_endpoint "
|
||||
"peer_finder::Logic::on_closed(): remote_endpoint "
|
||||
"missing from fixed_");
|
||||
}
|
||||
|
||||
@@ -938,7 +943,7 @@ public:
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
UNREACHABLE(
|
||||
"xrpl::PeerFinder::Logic::on_closed : invalid slot "
|
||||
"xrpl::peer_finder::Logic::on_closed : invalid slot "
|
||||
"state");
|
||||
break;
|
||||
// LCOV_EXCL_STOP
|
||||
@@ -963,17 +968,17 @@ public:
|
||||
// Returns `true` if the address matches a fixed slot address
|
||||
// Must have the lock held
|
||||
bool
|
||||
fixed(beast::IP::Endpoint const& endpoint) const
|
||||
fixed(beast::ip::Endpoint const& endpoint) const
|
||||
{
|
||||
return std::ranges::any_of(
|
||||
fixed_, [&endpoint](auto const& entry) { return entry.first == endpoint; });
|
||||
}
|
||||
|
||||
// Returns `true` if the address matches a fixed slot address
|
||||
// Note that this does not use the port information in the IP::Endpoint
|
||||
// Note that this does not use the port information in the ip::Endpoint
|
||||
// Must have the lock held
|
||||
bool
|
||||
fixed(beast::IP::Address const& address) const
|
||||
fixed(beast::ip::Address const& address) const
|
||||
{
|
||||
return std::ranges::any_of(
|
||||
fixed_, [&address](auto const& entry) { return entry.first.address() == address; });
|
||||
@@ -1074,13 +1079,13 @@ public:
|
||||
if (!results.error)
|
||||
{
|
||||
int const count(addBootcacheAddresses(results.addresses));
|
||||
JLOG(journal.info()) << beast::Leftw(18) << "Logic added " << count << " new "
|
||||
JLOG(journal.info()) << std::left << std::setw(18) << "Logic added " << count << " new "
|
||||
<< ((count == 1) ? "address" : "addresses") << " from "
|
||||
<< source->name();
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(journal.error()) << beast::Leftw(18) << "Logic failed "
|
||||
JLOG(journal.error()) << std::left << std::setw(18) << "Logic failed "
|
||||
<< "'" << source->name() << "' fetch, "
|
||||
<< results.error.message();
|
||||
}
|
||||
@@ -1092,14 +1097,12 @@ public:
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Returns true if the IP::Endpoint contains no invalid data.
|
||||
// Returns true if the ip::Endpoint contains no invalid data.
|
||||
bool
|
||||
isValidAddress(beast::IP::Endpoint const& address)
|
||||
isValidAddress(beast::ip::Endpoint const& address)
|
||||
{
|
||||
if (isUnspecified(address))
|
||||
return false;
|
||||
if (isLoopback(address))
|
||||
return false;
|
||||
if (!isPublic(address))
|
||||
return false;
|
||||
if (address.port() == 0)
|
||||
@@ -1217,13 +1220,13 @@ Logic<Checker>::onRedirects(
|
||||
{
|
||||
std::scoped_lock const _(lock);
|
||||
std::size_t n = 0;
|
||||
for (; first != last && n < Tuning::kMaxRedirects; ++first, ++n)
|
||||
for (; first != last && n < tuning::kMaxRedirects; ++first, ++n)
|
||||
bootcache.insert(beast::IPAddressConversion::fromAsio(*first));
|
||||
if (n > 0)
|
||||
{
|
||||
JLOG(journal.trace()) << beast::Leftw(18) << "Logic add " << n << " redirect IPs from "
|
||||
<< remoteAddress;
|
||||
JLOG(journal.trace()) << std::left << std::setw(18) << "Logic add " << n
|
||||
<< " redirect IPs from " << remoteAddress;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/peerfinder/PeerfinderManager.h>
|
||||
#include <xrpld/peerfinder/Slot.h>
|
||||
|
||||
#include <xrpl/beast/container/aged_unordered_map.h>
|
||||
#include <xrpl/beast/net/IPEndpoint.h>
|
||||
#include <xrpl/peerfinder/Slot.h>
|
||||
#include <xrpl/peerfinder/Types.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
|
||||
#include <atomic>
|
||||
@@ -13,7 +12,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
class SlotImp : public Slot
|
||||
{
|
||||
@@ -22,13 +21,13 @@ public:
|
||||
|
||||
// inbound
|
||||
SlotImp(
|
||||
beast::IP::Endpoint const& localEndpoint,
|
||||
beast::IP::Endpoint remoteEndpoint,
|
||||
beast::ip::Endpoint const& localEndpoint,
|
||||
beast::ip::Endpoint remoteEndpoint,
|
||||
bool fixed,
|
||||
clock_type& clock);
|
||||
|
||||
// outbound
|
||||
SlotImp(beast::IP::Endpoint remoteEndpoint, bool fixed, clock_type& clock);
|
||||
SlotImp(beast::ip::Endpoint remoteEndpoint, bool fixed, clock_type& clock);
|
||||
|
||||
bool
|
||||
inbound() const override
|
||||
@@ -54,13 +53,13 @@ public:
|
||||
return state_;
|
||||
}
|
||||
|
||||
beast::IP::Endpoint const&
|
||||
beast::ip::Endpoint const&
|
||||
remoteEndpoint() const override
|
||||
{
|
||||
return remoteEndpoint_;
|
||||
}
|
||||
|
||||
std::optional<beast::IP::Endpoint> const&
|
||||
std::optional<beast::ip::Endpoint> const&
|
||||
localEndpoint() const override
|
||||
{
|
||||
return localEndpoint_;
|
||||
@@ -94,13 +93,13 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
localEndpoint(beast::IP::Endpoint const& endpoint)
|
||||
localEndpoint(beast::ip::Endpoint const& endpoint)
|
||||
{
|
||||
localEndpoint_ = endpoint;
|
||||
}
|
||||
|
||||
void
|
||||
remoteEndpoint(beast::IP::Endpoint const& endpoint)
|
||||
remoteEndpoint(beast::ip::Endpoint const& endpoint)
|
||||
{
|
||||
remoteEndpoint_ = endpoint;
|
||||
}
|
||||
@@ -141,20 +140,20 @@ public:
|
||||
* sending a slot the same address too frequently.
|
||||
*/
|
||||
void
|
||||
insert(beast::IP::Endpoint const& ep, std::uint32_t hops);
|
||||
insert(beast::ip::Endpoint const& ep, std::uint32_t hops);
|
||||
|
||||
/**
|
||||
* Returns `true` if we should not send endpoint to the slot.
|
||||
*/
|
||||
bool
|
||||
filter(beast::IP::Endpoint const& ep, std::uint32_t hops);
|
||||
filter(beast::ip::Endpoint const& ep, std::uint32_t hops);
|
||||
|
||||
private:
|
||||
void
|
||||
expire();
|
||||
|
||||
friend class SlotImp;
|
||||
beast::aged_unordered_map<beast::IP::Endpoint, std::uint32_t> cache_;
|
||||
beast::aged_unordered_map<beast::ip::Endpoint, std::uint32_t> cache_;
|
||||
} recent;
|
||||
|
||||
void
|
||||
@@ -168,11 +167,11 @@ private:
|
||||
bool const fixed_;
|
||||
bool reserved_;
|
||||
State state_;
|
||||
beast::IP::Endpoint remoteEndpoint_;
|
||||
std::optional<beast::IP::Endpoint> localEndpoint_;
|
||||
beast::ip::Endpoint remoteEndpoint_;
|
||||
std::optional<beast::ip::Endpoint> localEndpoint_;
|
||||
std::optional<PublicKey> publicKey_;
|
||||
|
||||
static constexpr std::int32_t kUnknownPort = -1;
|
||||
static std::int32_t constexpr kUnknownPort = -1;
|
||||
std::atomic<std::int32_t> listeningPort_;
|
||||
|
||||
public:
|
||||
@@ -197,4 +196,4 @@ public:
|
||||
clock_type::time_point whenAcceptEndpoints;
|
||||
};
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -1,14 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/peerfinder/PeerfinderManager.h>
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/peerfinder/Types.h>
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* A static or dynamic source of peer addresses.
|
||||
@@ -47,4 +46,4 @@ public:
|
||||
fetch(Results& results, beast::Journal journal) = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/peerfinder/detail/Source.h>
|
||||
#include <xrpl/peerfinder/detail/Source.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* Provides addresses from a static set of strings.
|
||||
@@ -22,4 +22,4 @@ public:
|
||||
make(std::string const& name, Strings const& strings);
|
||||
};
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl::PeerFinder {
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* Abstract persistence for PeerFinder data.
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
virtual ~Store() = default;
|
||||
|
||||
// load the bootstrap cache
|
||||
using load_callback = std::function<void(beast::IP::Endpoint, int)>;
|
||||
using load_callback = std::function<void(beast::ip::Endpoint, int)>;
|
||||
virtual std::size_t
|
||||
load(load_callback const& cb) = 0;
|
||||
|
||||
@@ -26,11 +26,11 @@ public:
|
||||
{
|
||||
explicit Entry() = default;
|
||||
|
||||
beast::IP::Endpoint endpoint;
|
||||
beast::ip::Endpoint endpoint;
|
||||
int valence{};
|
||||
};
|
||||
virtual void
|
||||
save(std::vector<Entry> const& v) = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl::PeerFinder
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -9,7 +9,7 @@
|
||||
* Heuristically tuned constants.
|
||||
*/
|
||||
/** @{ */
|
||||
namespace xrpl::PeerFinder::Tuning {
|
||||
namespace xrpl::peer_finder::tuning {
|
||||
|
||||
//---------------------------------------------------------
|
||||
//
|
||||
@@ -111,5 +111,5 @@ constexpr std::chrono::seconds kLiveCacheSecondsToLive(30);
|
||||
// Note that we ignore the port for purposes of comparison.
|
||||
constexpr std::chrono::seconds kRecentAttemptDuration(60);
|
||||
|
||||
} // namespace xrpl::PeerFinder::Tuning
|
||||
} // namespace xrpl::peer_finder::tuning
|
||||
/** @} */
|
||||
36
include/xrpl/peerfinder/make_Manager.h
Normal file
36
include/xrpl/peerfinder/make_Manager.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/insight/Collector.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/peerfinder/PeerfinderManager.h>
|
||||
#include <xrpl/peerfinder/Types.h>
|
||||
#include <xrpl/peerfinder/detail/Store.h>
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace xrpl::peer_finder {
|
||||
|
||||
/**
|
||||
* @brief Create a new Manager.
|
||||
*
|
||||
* @param ioContext The io_context used to schedule asynchronous work.
|
||||
* @param clock The clock used for timekeeping.
|
||||
* @param journal The journal used for logging.
|
||||
* @param store The persistence backend for the bootstrap cache. The caller
|
||||
* retains ownership and must keep it alive (and opened) for the lifetime of
|
||||
* the returned Manager. This lets consumers supply their own Store
|
||||
* implementation (e.g. the SQLite-backed StoreSqdb in xrpld).
|
||||
* @param collector The collector used to report metrics.
|
||||
* @return The newly created Manager.
|
||||
*/
|
||||
std::unique_ptr<Manager>
|
||||
makeManager(
|
||||
boost::asio::io_context& ioContext,
|
||||
clock_type& clock,
|
||||
beast::Journal journal,
|
||||
Store& store,
|
||||
beast::insight::Collector::ptr const& collector);
|
||||
|
||||
} // namespace xrpl::peer_finder
|
||||
@@ -246,7 +246,15 @@ message TMGetObjectByHash {
|
||||
|
||||
message TMLedgerNode {
|
||||
required bytes nodedata = 1;
|
||||
optional bytes nodeid = 2; // missing for ledger base data
|
||||
|
||||
// Used when protocol version <2.3. Not set for ledger base data.
|
||||
optional bytes nodeid = 2;
|
||||
|
||||
// Used when protocol version >=2.3. Neither value is set for ledger base data.
|
||||
oneof reference {
|
||||
bytes id = 3; // Set for inner nodes.
|
||||
uint32 depth = 4; // Set for leaf nodes.
|
||||
}
|
||||
}
|
||||
|
||||
enum TMLedgerInfoType {
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace xrpl {
|
||||
* Command line Requests use apiCommandLineVersion.
|
||||
*/
|
||||
|
||||
namespace RPC {
|
||||
namespace rpc {
|
||||
|
||||
template <unsigned int Version>
|
||||
static constexpr std::integral_constant<unsigned, Version> kApiVersion = {};
|
||||
@@ -60,7 +60,7 @@ static_assert(kApiMaximumValidVersion >= kApiMaximumSupportedVersion);
|
||||
inline void
|
||||
setVersion(json::Value& parent, unsigned int apiVersion, bool betaEnabled)
|
||||
{
|
||||
XRPL_ASSERT(apiVersion != kApiInvalidVersion, "xrpl::RPC::setVersion : input is valid");
|
||||
XRPL_ASSERT(apiVersion != kApiInvalidVersion, "xrpl::rpc::setVersion : input is valid");
|
||||
|
||||
auto& retObj = parent[jss::version] = json::ValueType::Object;
|
||||
|
||||
@@ -99,12 +99,12 @@ setVersion(json::Value& parent, unsigned int apiVersion, bool betaEnabled)
|
||||
inline unsigned int
|
||||
getAPIVersionNumber(json::Value const& jv, bool betaEnabled)
|
||||
{
|
||||
static json::Value const kMinVersion(RPC::kApiMinimumSupportedVersion);
|
||||
static json::Value const kMinVersion(rpc::kApiMinimumSupportedVersion);
|
||||
json::Value const maxVersion(
|
||||
betaEnabled ? RPC::kApiBetaVersion : RPC::kApiMaximumSupportedVersion);
|
||||
betaEnabled ? rpc::kApiBetaVersion : rpc::kApiMaximumSupportedVersion);
|
||||
|
||||
if (!jv.isObject() || !jv.isMember(jss::api_version))
|
||||
return RPC::kApiVersionIfUnspecified;
|
||||
return rpc::kApiVersionIfUnspecified;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -113,33 +113,33 @@ getAPIVersionNumber(json::Value const& jv, bool betaEnabled)
|
||||
{
|
||||
case json::ValueType::Int:
|
||||
if (rawVersion.asInt() < 0)
|
||||
return RPC::kApiInvalidVersion;
|
||||
return rpc::kApiInvalidVersion;
|
||||
[[fallthrough]];
|
||||
case json::ValueType::UInt: {
|
||||
auto const apiVersion = rawVersion.asUInt();
|
||||
if (apiVersion < kMinVersion || apiVersion > maxVersion)
|
||||
return RPC::kApiInvalidVersion;
|
||||
return rpc::kApiInvalidVersion;
|
||||
return apiVersion;
|
||||
}
|
||||
default:
|
||||
return RPC::kApiInvalidVersion;
|
||||
return rpc::kApiInvalidVersion;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return RPC::kApiInvalidVersion;
|
||||
return rpc::kApiInvalidVersion;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RPC
|
||||
} // namespace rpc
|
||||
|
||||
template <unsigned MinVer, unsigned MaxVer, typename Fn, typename... Args>
|
||||
void
|
||||
forApiVersions(Fn const& fn, Args&&... args)
|
||||
requires //
|
||||
(MaxVer >= MinVer) && //
|
||||
(MinVer >= RPC::kApiMinimumSupportedVersion) && //
|
||||
(RPC::kApiMaximumValidVersion >= MaxVer) && requires {
|
||||
(MinVer >= rpc::kApiMinimumSupportedVersion) && //
|
||||
(rpc::kApiMaximumValidVersion >= MaxVer) && requires {
|
||||
fn(std::integral_constant<unsigned int, MinVer>{}, std::forward<Args>(args)...);
|
||||
fn(std::integral_constant<unsigned int, MaxVer>{}, std::forward<Args>(args)...);
|
||||
}
|
||||
@@ -158,11 +158,11 @@ template <typename Fn, typename... Args>
|
||||
void
|
||||
forAllApiVersions(Fn const& fn, Args&&... args)
|
||||
requires requires {
|
||||
forApiVersions<RPC::kApiMinimumSupportedVersion, RPC::kApiMaximumValidVersion>(
|
||||
forApiVersions<rpc::kApiMinimumSupportedVersion, rpc::kApiMaximumValidVersion>(
|
||||
fn, std::forward<Args>(args)...);
|
||||
}
|
||||
{
|
||||
forApiVersions<RPC::kApiMinimumSupportedVersion, RPC::kApiMaximumValidVersion>(
|
||||
forApiVersions<rpc::kApiMinimumSupportedVersion, rpc::kApiMaximumValidVersion>(
|
||||
fn, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Versioning information for this build.
|
||||
*/
|
||||
// VFALCO The namespace is deprecated
|
||||
namespace xrpl::BuildInfo {
|
||||
namespace xrpl::build_info {
|
||||
|
||||
/**
|
||||
* Server version.
|
||||
@@ -84,4 +84,4 @@ isXrpldVersion(std::uint64_t version);
|
||||
bool
|
||||
isNewerVersion(std::uint64_t version);
|
||||
|
||||
} // namespace xrpl::BuildInfo
|
||||
} // namespace xrpl::build_info
|
||||
|
||||
@@ -167,7 +167,7 @@ enum WarningCodeI {
|
||||
|
||||
// VFALCO NOTE these should probably not be in the RPC namespace.
|
||||
|
||||
namespace RPC {
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* Maps an rpc error code to its token, default message, and HTTP status.
|
||||
@@ -337,7 +337,7 @@ containsError(json::Value const& json);
|
||||
int
|
||||
errorCodeHttpStatus(ErrorCodeI code);
|
||||
|
||||
} // namespace RPC
|
||||
} // namespace rpc
|
||||
|
||||
/**
|
||||
* Returns a single string with the contents of an RPC error.
|
||||
|
||||
@@ -188,6 +188,6 @@ struct MultiApiJson
|
||||
|
||||
// Wrapper for Json for all supported API versions.
|
||||
using MultiApiJson =
|
||||
detail::MultiApiJson<RPC::kApiMinimumSupportedVersion, RPC::kApiMaximumValidVersion>;
|
||||
detail::MultiApiJson<rpc::kApiMinimumSupportedVersion, rpc::kApiMaximumValidVersion>;
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace xrpl::RPC {
|
||||
namespace xrpl::rpc {
|
||||
|
||||
/**
|
||||
* Adds common synthetic fields to transaction-related JSON responses
|
||||
@@ -16,4 +16,4 @@ void
|
||||
insertNFTSyntheticInJson(json::Value&, std::shared_ptr<STTx const> const&, TxMeta const&);
|
||||
/** @} */
|
||||
|
||||
} // namespace xrpl::RPC
|
||||
} // namespace xrpl::rpc
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user