mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-24 19:17:03 +00:00
Compare commits
5 Commits
develop
...
ximinez/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d62ad9a8e7 | ||
|
|
d7e7baa675 | ||
|
|
054284701e | ||
|
|
eb4681da51 | ||
|
|
9b3dd7002d |
@@ -96,6 +96,3 @@ function(verbose_find_path variable name)
|
|||||||
${ARGN}
|
${ARGN}
|
||||||
)
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(patch_nix_binary target)
|
|
||||||
endfunction()
|
|
||||||
|
|||||||
2
.github/scripts/strategy-matrix/linux.json
vendored
2
.github/scripts/strategy-matrix/linux.json
vendored
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"image_tag": "sha-e29b523",
|
"image_tag": "sha-fe4c8ae",
|
||||||
"configs": {
|
"configs": {
|
||||||
"ubuntu": [
|
"ubuntu": [
|
||||||
{
|
{
|
||||||
|
|||||||
2
.github/scripts/strategy-matrix/windows.json
vendored
2
.github/scripts/strategy-matrix/windows.json
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"platform": "windows/amd64",
|
"platform": "windows/amd64",
|
||||||
"runner": ["self-hosted", "Windows", "dev-box-windows-2026"],
|
"runner": ["self-hosted", "Windows", "devbox"],
|
||||||
"configs": [
|
"configs": [
|
||||||
{ "build_type": "Release" },
|
{ "build_type": "Release" },
|
||||||
{
|
{
|
||||||
|
|||||||
1
.github/workflows/on-pr.yml
vendored
1
.github/workflows/on-pr.yml
vendored
@@ -70,7 +70,6 @@ jobs:
|
|||||||
.github/workflows/reusable-upload-recipe.yml
|
.github/workflows/reusable-upload-recipe.yml
|
||||||
.clang-tidy
|
.clang-tidy
|
||||||
.codecov.yml
|
.codecov.yml
|
||||||
bin/check-tools.sh
|
|
||||||
cfg/**
|
cfg/**
|
||||||
cmake/**
|
cmake/**
|
||||||
conan/**
|
conan/**
|
||||||
|
|||||||
1
.github/workflows/on-trigger.yml
vendored
1
.github/workflows/on-trigger.yml
vendored
@@ -27,7 +27,6 @@ on:
|
|||||||
- ".github/workflows/reusable-upload-recipe.yml"
|
- ".github/workflows/reusable-upload-recipe.yml"
|
||||||
- ".clang-tidy"
|
- ".clang-tidy"
|
||||||
- ".codecov.yml"
|
- ".codecov.yml"
|
||||||
- "bin/check-tools.sh"
|
|
||||||
- "cfg/**"
|
- "cfg/**"
|
||||||
- "cmake/**"
|
- "cmake/**"
|
||||||
- "conan/**"
|
- "conan/**"
|
||||||
|
|||||||
2
.github/workflows/publish-docs.yml
vendored
2
.github/workflows/publish-docs.yml
vendored
@@ -41,7 +41,7 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-e29b523
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-fe4c8ae
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
|
|||||||
19
.github/workflows/reusable-build-test-config.yml
vendored
19
.github/workflows/reusable-build-test-config.yml
vendored
@@ -82,7 +82,7 @@ jobs:
|
|||||||
name: ${{ inputs.config_name }}
|
name: ${{ inputs.config_name }}
|
||||||
runs-on: ${{ fromJSON(inputs.runs_on) }}
|
runs-on: ${{ fromJSON(inputs.runs_on) }}
|
||||||
container: ${{ inputs.image != '' && inputs.image || null }}
|
container: ${{ inputs.image != '' && inputs.image || null }}
|
||||||
timeout-minutes: ${{ inputs.sanitizers != '' && 360 || 180 }}
|
timeout-minutes: ${{ inputs.sanitizers != '' && 360 || 90 }}
|
||||||
env:
|
env:
|
||||||
# Use a namespace to keep the objects separate for each configuration.
|
# Use a namespace to keep the objects separate for each configuration.
|
||||||
CCACHE_NAMESPACE: ${{ inputs.config_name }}
|
CCACHE_NAMESPACE: ${{ inputs.config_name }}
|
||||||
@@ -163,7 +163,7 @@ jobs:
|
|||||||
CMAKE_ARGS: ${{ inputs.cmake_args }}
|
CMAKE_ARGS: ${{ inputs.cmake_args }}
|
||||||
run: |
|
run: |
|
||||||
cmake \
|
cmake \
|
||||||
-G '${{ runner.os == 'Windows' && 'Visual Studio 18 2026' || 'Ninja' }}' \
|
-G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
|
||||||
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
|
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
|
||||||
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
||||||
${CMAKE_ARGS} \
|
${CMAKE_ARGS} \
|
||||||
@@ -229,6 +229,21 @@ jobs:
|
|||||||
--parallel "${BUILD_NPROC}" \
|
--parallel "${BUILD_NPROC}" \
|
||||||
--target "${CMAKE_TARGET}"
|
--target "${CMAKE_TARGET}"
|
||||||
|
|
||||||
|
# This step is needed to allow running in non-Nix environments
|
||||||
|
- name: Patch binary to use default loader and remove rpath (Linux)
|
||||||
|
if: ${{ runner.os == 'Linux' && env.SANITIZERS_ENABLED == 'false' }}
|
||||||
|
run: |
|
||||||
|
loader="$(/tmp/loader-path.sh)"
|
||||||
|
patchelf --set-interpreter "${loader}" --remove-rpath "${{ env.BUILD_DIR }}/xrpld"
|
||||||
|
|
||||||
|
# We're only running aarch64 Linux builds in Ubuntu-based images, so this is kept simple
|
||||||
|
- name: Install libatomic (Linux aarch64)
|
||||||
|
if: ${{ runner.os == 'Linux' && runner.arch == 'ARM64' }}
|
||||||
|
run: |
|
||||||
|
apt update --yes
|
||||||
|
apt install -y --no-install-recommends \
|
||||||
|
libatomic1
|
||||||
|
|
||||||
- name: Show ccache statistics
|
- name: Show ccache statistics
|
||||||
if: ${{ inputs.ccache_enabled }}
|
if: ${{ inputs.ccache_enabled }}
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
2
.github/workflows/reusable-clang-tidy.yml
vendored
2
.github/workflows/reusable-clang-tidy.yml
vendored
@@ -39,7 +39,7 @@ jobs:
|
|||||||
needs: [determine-files]
|
needs: [determine-files]
|
||||||
if: ${{ always() && !cancelled() && (!inputs.check_only_changed || needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.clang_tidy_config_changed == 'true') }}
|
if: ${{ always() && !cancelled() && (!inputs.check_only_changed || needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.clang_tidy_config_changed == 'true') }}
|
||||||
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
|
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
|
||||||
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-e29b523"
|
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-fe4c8ae"
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
issues: write
|
issues: write
|
||||||
|
|||||||
2
.github/workflows/reusable-upload-recipe.yml
vendored
2
.github/workflows/reusable-upload-recipe.yml
vendored
@@ -40,7 +40,7 @@ defaults:
|
|||||||
jobs:
|
jobs:
|
||||||
upload:
|
upload:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-e29b523
|
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-fe4c8ae
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ repos:
|
|||||||
hooks:
|
hooks:
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
args: [--maxkb=400, --enforce-all]
|
args: [--maxkb=400, --enforce-all]
|
||||||
- id: check-executables-have-shebangs
|
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
- id: check-merge-conflict
|
- id: check-merge-conflict
|
||||||
@@ -36,18 +35,13 @@ repos:
|
|||||||
language: python
|
language: python
|
||||||
types_or: [c++, c]
|
types_or: [c++, c]
|
||||||
exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/
|
exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/
|
||||||
- id: fix-pragma-once
|
|
||||||
name: fix missing '#pragma once' declarations in header files
|
|
||||||
language: python
|
|
||||||
entry: ./bin/pre-commit/fix_pragma_once.py
|
|
||||||
files: \.(h|hpp)$
|
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
rev: dd18dad857d6133e90bbe478f4f2f22ec0030269 # frozen: v22.1.5
|
rev: dd18dad857d6133e90bbe478f4f2f22ec0030269 # frozen: v22.1.5
|
||||||
hooks:
|
hooks:
|
||||||
- id: clang-format
|
- id: clang-format
|
||||||
args: [--style=file]
|
args: [--style=file]
|
||||||
types_or: [c++, c, proto]
|
"types_or": [c++, c, proto]
|
||||||
exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/
|
exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/
|
||||||
|
|
||||||
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
|
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
|
||||||
|
|||||||
@@ -57,8 +57,6 @@ if(target)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(PatchNixBinary)
|
|
||||||
|
|
||||||
include(XrplSanity)
|
include(XrplSanity)
|
||||||
include(XrplVersion)
|
include(XrplVersion)
|
||||||
include(XrplSettings)
|
include(XrplSettings)
|
||||||
|
|||||||
@@ -90,19 +90,16 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
|
|||||||
check perl
|
check perl
|
||||||
check pkg-config
|
check pkg-config
|
||||||
check vim
|
check vim
|
||||||
check zip
|
|
||||||
|
|
||||||
# These tools are present in our Linux CI images and in local development
|
# 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
|
# setups, but not in the macOS CI environment. So check them everywhere
|
||||||
# except when running in CI on macOS.
|
# except when running in CI on macOS.
|
||||||
if [ "${os}" = "linux" ] || [ -z "${CI:-}" ]; then
|
if [ "${os}" = "linux" ] || [ -z "${CI:-}" ]; then
|
||||||
check clang-format
|
check clang-format
|
||||||
check dot
|
|
||||||
check doxygen
|
check doxygen
|
||||||
check gcovr
|
check gcovr
|
||||||
check gh
|
check gh
|
||||||
check git-cliff
|
check git-cliff
|
||||||
check git-lfs
|
|
||||||
check gpg
|
check gpg
|
||||||
# pre-commit, or its alternative implementation prek
|
# pre-commit, or its alternative implementation prek
|
||||||
check pre-commit sh -c 'pre-commit --version || prek --version'
|
check pre-commit sh -c 'pre-commit --version || prek --version'
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
"""
|
|
||||||
Adds "#pragma once" to the top of header files that don't already have it.
|
|
||||||
|
|
||||||
Usage: ./bin/pre-commit/fix_pragma_once.py <file1> <file2> ...
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
PRAGMA_ONCE = "#pragma once\n\n"
|
|
||||||
|
|
||||||
|
|
||||||
def fix_pragma_once(path: Path) -> bool:
|
|
||||||
original = path.read_text(encoding="utf-8")
|
|
||||||
if PRAGMA_ONCE not in original:
|
|
||||||
path.write_text(PRAGMA_ONCE + original, encoding="utf-8")
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
|
||||||
files = [Path(f) for f in sys.argv[1:]]
|
|
||||||
success = True
|
|
||||||
|
|
||||||
for path in files:
|
|
||||||
success &= fix_pragma_once(path)
|
|
||||||
|
|
||||||
return 0 if success else 1
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
sys.exit(main())
|
|
||||||
@@ -56,16 +56,3 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64")
|
|||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Unknown architecture: ${CMAKE_SYSTEM_PROCESSOR}")
|
message(FATAL_ERROR "Unknown architecture: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
# Sanitizers
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
# SANITIZERS is injected by the Conan toolchain when a sanitizer build is
|
|
||||||
# requested (see conan/profiles/sanitizers). The flags are applied to the
|
|
||||||
# 'common' target in XrplSanitizers; this flag lets other modules know a
|
|
||||||
# sanitizer build is active without depending on that module.
|
|
||||||
if(DEFINED SANITIZERS)
|
|
||||||
set(SANITIZERS_ENABLED TRUE)
|
|
||||||
else()
|
|
||||||
set(SANITIZERS_ENABLED FALSE)
|
|
||||||
endif()
|
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
#[===================================================================[
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
#]===================================================================]
|
|
||||||
|
|
||||||
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")
|
|
||||||
|
|
||||||
if(is_linux AND NOT SANITIZERS_ENABLED AND EXISTS "${_loader_path_script}")
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${_loader_path_script}"
|
|
||||||
OUTPUT_VARIABLE DEFAULT_LOADER_PATH
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
COMMAND_ERROR_IS_FATAL ANY
|
|
||||||
)
|
|
||||||
find_program(PATCHELF_COMMAND patchelf REQUIRED)
|
|
||||||
set(PATCH_NIX_BINARIES TRUE)
|
|
||||||
message(
|
|
||||||
STATUS
|
|
||||||
"Binaries will be patched to use loader '${DEFAULT_LOADER_PATH}'"
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
set(PATCH_NIX_BINARIES FALSE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
function(patch_nix_binary target)
|
|
||||||
if(NOT PATCH_NIX_BINARIES)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
add_custom_command(
|
|
||||||
TARGET ${target}
|
|
||||||
POST_BUILD
|
|
||||||
COMMAND
|
|
||||||
"${PATCHELF_COMMAND}" --set-interpreter "${DEFAULT_LOADER_PATH}"
|
|
||||||
--remove-rpath "$<TARGET_FILE:${target}>"
|
|
||||||
COMMENT "Patching ${target}: set default loader, remove rpath"
|
|
||||||
VERBATIM
|
|
||||||
)
|
|
||||||
endfunction()
|
|
||||||
@@ -154,15 +154,6 @@ else()
|
|||||||
>
|
>
|
||||||
)
|
)
|
||||||
|
|
||||||
# On aarch64, libatomic is required for atomic operations. It is not needed on x86_64.
|
|
||||||
# Linking it statically on Linux
|
|
||||||
if(is_arm64 AND is_linux)
|
|
||||||
target_link_options(
|
|
||||||
common
|
|
||||||
INTERFACE -Wl,--push-state -Wl,-Bstatic -latomic -Wl,--pop-state
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Keep -stdlib=libstdc++ off the compile commands, but preserve it for linking.
|
# Keep -stdlib=libstdc++ off the compile commands, but preserve it for linking.
|
||||||
#
|
#
|
||||||
# Conan turns `compiler.libcxx=libstdc++` into `-stdlib=libstdc++` and puts it in
|
# Conan turns `compiler.libcxx=libstdc++` into `-stdlib=libstdc++` and puts it in
|
||||||
|
|||||||
@@ -247,7 +247,6 @@ target_link_modules(
|
|||||||
|
|
||||||
if(xrpld)
|
if(xrpld)
|
||||||
add_executable(xrpld)
|
add_executable(xrpld)
|
||||||
patch_nix_binary(xrpld)
|
|
||||||
if(tests)
|
if(tests)
|
||||||
target_compile_definitions(xrpld PUBLIC ENABLE_TESTS)
|
target_compile_definitions(xrpld PUBLIC ENABLE_TESTS)
|
||||||
target_compile_definitions(
|
target_compile_definitions(
|
||||||
|
|||||||
@@ -14,9 +14,11 @@
|
|||||||
include_guard(GLOBAL)
|
include_guard(GLOBAL)
|
||||||
include(CompilationEnv)
|
include(CompilationEnv)
|
||||||
|
|
||||||
if(NOT SANITIZERS_ENABLED)
|
if(NOT DEFINED SANITIZERS)
|
||||||
|
set(SANITIZERS_ENABLED FALSE)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
set(SANITIZERS_ENABLED TRUE)
|
||||||
|
|
||||||
message(STATUS "=== Configuring Sanitizers ===")
|
message(STATUS "=== Configuring Sanitizers ===")
|
||||||
message(STATUS " SANITIZERS: ${SANITIZERS}")
|
message(STATUS " SANITIZERS: ${SANITIZERS}")
|
||||||
|
|||||||
12
conan.lock
12
conan.lock
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"version": "0.5",
|
"version": "0.5",
|
||||||
"requires": [
|
"requires": [
|
||||||
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1778091116.056",
|
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1777558780.503",
|
||||||
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
|
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
|
||||||
"sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1778091117.311",
|
"sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1776096494.149",
|
||||||
"soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231",
|
"soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231",
|
||||||
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",
|
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",
|
||||||
"secp256k1/0.7.1#481881709eb0bdd0185a12b912bbe8ad%1770910500.329",
|
"secp256k1/0.7.1#481881709eb0bdd0185a12b912bbe8ad%1770910500.329",
|
||||||
@@ -15,19 +15,19 @@
|
|||||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914",
|
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914",
|
||||||
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492",
|
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492",
|
||||||
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1765842973.03",
|
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1765842973.03",
|
||||||
"libarchive/3.8.7#c446109bd1f1d8ba7936c94189bc50e6%1778091117.848",
|
"libarchive/3.8.7#c446109bd1f1d8ba7936c94189bc50e6%1776147552.838",
|
||||||
"jemalloc/5.3.1#1fc58d55316041f10fbc1e8a2eae632a%1776700028.228",
|
"jemalloc/5.3.1#1fc58d55316041f10fbc1e8a2eae632a%1776700028.228",
|
||||||
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152",
|
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152",
|
||||||
"grpc/1.81.0#2fb144aeb47e7f35c6ebb0e5f35bed31%1781620605.685",
|
"grpc/1.78.1#b1a9e74b145cc471bed4dc64dc6eb2c1%1774467387.342",
|
||||||
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1765850143.772",
|
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1765850143.772",
|
||||||
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772",
|
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772",
|
||||||
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1774439234.681",
|
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1774439234.681",
|
||||||
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1765850143.837",
|
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1765850143.837",
|
||||||
"boost/1.91.0#ea540ca2133d831b560036aa24dece3c%1778091165.282",
|
"boost/1.91.0#ea540ca2133d831b560036aa24dece3c%1778050991.9",
|
||||||
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196"
|
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196"
|
||||||
],
|
],
|
||||||
"build_requires": [
|
"build_requires": [
|
||||||
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1778091116.056",
|
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1777558780.503",
|
||||||
"strawberryperl/5.32.1.1#8d114504d172cfea8ea1662d09b6333e%1774447376.964",
|
"strawberryperl/5.32.1.1#8d114504d172cfea8ea1662d09b6333e%1774447376.964",
|
||||||
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1774467363.12",
|
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1774467363.12",
|
||||||
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1765850144.707",
|
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1765850144.707",
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class Xrpl(ConanFile):
|
|||||||
|
|
||||||
requires = [
|
requires = [
|
||||||
"ed25519/2015.03",
|
"ed25519/2015.03",
|
||||||
"grpc/1.81.0",
|
"grpc/1.78.1",
|
||||||
"libarchive/3.8.7",
|
"libarchive/3.8.7",
|
||||||
"nudb/2.0.9",
|
"nudb/2.0.9",
|
||||||
"openssl/3.6.2",
|
"openssl/3.6.2",
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#include <xrpl/beast/insight/Insight.h>
|
#include <xrpl/beast/insight/Insight.h>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cstddef>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@@ -18,22 +17,6 @@
|
|||||||
|
|
||||||
namespace xrpl {
|
namespace xrpl {
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
// Replace-policy tags selecting how TaggedCache::canonicalizeImpl resolves a
|
|
||||||
// collision when the key already exists (defined in TaggedCache.ipp):
|
|
||||||
// - ReplaceCached: always replace the cached value with `data`. `data` is
|
|
||||||
// never written back and may be const.
|
|
||||||
// - ReplaceClient: keep the cached value and write it back into `data` (the
|
|
||||||
// client's pointer), which must therefore be writable.
|
|
||||||
// - ReplaceDynamically: call the supplied callback to decide per call; `data`
|
|
||||||
// is written back when the cached value is kept, so it must be writable.
|
|
||||||
struct ReplaceCached;
|
|
||||||
struct ReplaceClient;
|
|
||||||
struct ReplaceDynamically;
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/** Map/cache combination.
|
/** Map/cache combination.
|
||||||
This class implements a cache and a map. The cache keeps objects alive
|
This class implements a cache and a map. The cache keeps objects alive
|
||||||
in the map. The map allows multiple code paths that reference objects
|
in the map. The map allows multiple code paths that reference objects
|
||||||
@@ -113,32 +96,6 @@ public:
|
|||||||
bool
|
bool
|
||||||
del(key_type const& key, bool valid);
|
del(key_type const& key, bool valid);
|
||||||
|
|
||||||
private:
|
|
||||||
// Selects the `data` parameter type of canonicalizeImpl from the replace
|
|
||||||
// policy: const for detail::ReplaceCached (never written back), otherwise
|
|
||||||
// writable.
|
|
||||||
template <typename Policy>
|
|
||||||
using CanonicalizeClientPointerType = std::conditional_t<
|
|
||||||
std::is_same_v<detail::ReplaceCached, Policy>,
|
|
||||||
SharedPointerType const&,
|
|
||||||
SharedPointerType&>;
|
|
||||||
|
|
||||||
/** Shared implementation of the canonicalize family.
|
|
||||||
|
|
||||||
`policy` selects how a collision is resolved when `key` already exists:
|
|
||||||
detail::ReplaceCached, detail::ReplaceClient or
|
|
||||||
detail::ReplaceDynamically. For ReplaceDynamically `replaceCallback` is
|
|
||||||
invoked with the existing strong pointer and returns whether to replace
|
|
||||||
the cached value with `data`; for the tag policies it is unused.
|
|
||||||
*/
|
|
||||||
template <class Policy, class Callback = std::nullptr_t>
|
|
||||||
bool
|
|
||||||
canonicalizeImpl(
|
|
||||||
key_type const& key,
|
|
||||||
CanonicalizeClientPointerType<Policy> data,
|
|
||||||
Policy policy,
|
|
||||||
Callback&& replaceCallback = nullptr);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Replace aliased objects with originals.
|
/** Replace aliased objects with originals.
|
||||||
|
|
||||||
@@ -147,52 +104,19 @@ public:
|
|||||||
This routine eliminates the duplicate and performs a replacement
|
This routine eliminates the duplicate and performs a replacement
|
||||||
on the callers shared pointer if needed.
|
on the callers shared pointer if needed.
|
||||||
|
|
||||||
`replaceCallback` is a callable taking the existing strong pointer and
|
|
||||||
returning whether to replace the cached value with `data` (true) or to
|
|
||||||
keep the cached value and write it back into `data` (false). Because the
|
|
||||||
write-back case mutates `data`, `data` must be writable.
|
|
||||||
|
|
||||||
@param key The key corresponding to the object
|
@param key The key corresponding to the object
|
||||||
@param data A shared pointer to the data corresponding to the object.
|
@param data A shared pointer to the data corresponding to the object.
|
||||||
@param replaceCallback A callable (existing strong pointer -> bool).
|
@param replace Function that decides if cache should be replaced
|
||||||
|
|
||||||
@return `true` if an existing live entry was found and used; `false` if a new entry was
|
@return `true` If the key already existed.
|
||||||
inserted or an expired tracked entry was re-cached.
|
*/
|
||||||
**/
|
template <class R>
|
||||||
template <class Callback>
|
|
||||||
bool
|
bool
|
||||||
canonicalize(key_type const& key, SharedPointerType& data, Callback&& replaceCallback);
|
canonicalize(key_type const& key, SharedPointerType& data, R&& replaceCallback);
|
||||||
|
|
||||||
/** Insert/update the canonical entry for `key`, always replacing the
|
|
||||||
cached value with `data`.
|
|
||||||
|
|
||||||
If an entry already exists for `key`, the cached value is unconditionally
|
|
||||||
replaced with `data`; otherwise `data` is inserted. `data` is never
|
|
||||||
written back, so it may be const.
|
|
||||||
|
|
||||||
@param key The key corresponding to the object.
|
|
||||||
@param data A shared pointer to the data corresponding to the object.
|
|
||||||
|
|
||||||
@return `true` if an existing live entry was found and used; `false` if a new entry was
|
|
||||||
inserted or an expired tracked entry was re-cached.
|
|
||||||
**/
|
|
||||||
bool
|
bool
|
||||||
canonicalizeReplaceCache(key_type const& key, SharedPointerType const& data);
|
canonicalizeReplaceCache(key_type const& key, SharedPointerType const& data);
|
||||||
|
|
||||||
/** Insert the canonical entry for `key`, keeping any existing cached value.
|
|
||||||
|
|
||||||
If an entry already exists for `key`, the cached value is kept and
|
|
||||||
written back into `data` so the caller ends up with the canonical
|
|
||||||
object; otherwise `data` is inserted. Because `data` may be overwritten
|
|
||||||
it must be writable.
|
|
||||||
|
|
||||||
@param key The key corresponding to the object.
|
|
||||||
@param data A shared pointer to the data corresponding to the object;
|
|
||||||
updated to the canonical value when one already exists.
|
|
||||||
|
|
||||||
@return `true` if an existing live entry was found and used; `false` if a new entry was
|
|
||||||
inserted or an expired tracked entry was re-cached.
|
|
||||||
**/
|
|
||||||
bool
|
bool
|
||||||
canonicalizeReplaceClient(key_type const& key, SharedPointerType& data);
|
canonicalizeReplaceClient(key_type const& key, SharedPointerType& data);
|
||||||
|
|
||||||
|
|||||||
@@ -2,33 +2,10 @@
|
|||||||
|
|
||||||
#include <xrpl/basics/IntrusivePointer.ipp>
|
#include <xrpl/basics/IntrusivePointer.ipp>
|
||||||
#include <xrpl/basics/TaggedCache.h>
|
#include <xrpl/basics/TaggedCache.h>
|
||||||
|
#include <xrpl/basics/scope.h>
|
||||||
|
|
||||||
namespace xrpl {
|
namespace xrpl {
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
// Replace-policy tags selecting how TaggedCache::canonicalizeImpl resolves a
|
|
||||||
// collision when the key already exists:
|
|
||||||
// - ReplaceCached: always replace the cached value with `data`. `data` is
|
|
||||||
// never written back and may be const.
|
|
||||||
// - ReplaceClient: keep the cached value and write it back into `data` (the
|
|
||||||
// client's pointer), which must therefore be writable.
|
|
||||||
// - ReplaceDynamically: call the supplied callback to decide per call; `data`
|
|
||||||
// is written back when the cached value is kept, so it must be writable.
|
|
||||||
struct ReplaceCached
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ReplaceClient
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ReplaceDynamically
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class Key,
|
class Key,
|
||||||
class T,
|
class T,
|
||||||
@@ -324,29 +301,13 @@ template <
|
|||||||
class Hash,
|
class Hash,
|
||||||
class KeyEqual,
|
class KeyEqual,
|
||||||
class Mutex>
|
class Mutex>
|
||||||
template <class Policy, class Callback>
|
template <class R>
|
||||||
inline bool
|
inline bool
|
||||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||||
canonicalizeImpl(
|
canonicalize(key_type const& key, SharedPointerType& data, R&& replaceCallback)
|
||||||
key_type const& key,
|
|
||||||
CanonicalizeClientPointerType<Policy> data,
|
|
||||||
[[maybe_unused]] Policy policy,
|
|
||||||
[[maybe_unused]] Callback&& replaceCallback)
|
|
||||||
{
|
{
|
||||||
// Return canonical value, store if needed, refresh in cache
|
// Return canonical value, store if needed, refresh in cache
|
||||||
// Return values: true=we had the data already
|
// Return values: true=we had the data already
|
||||||
|
|
||||||
// `Policy` is one of:
|
|
||||||
// - detail::ReplaceCached: always replace the cached value with `data`;
|
|
||||||
// `data` is never written back and may be const.
|
|
||||||
// - detail::ReplaceClient: keep the cached value and write it back into
|
|
||||||
// `data` (the client's pointer), which must therefore be writable.
|
|
||||||
// - detail::ReplaceDynamically: call `replaceCallback` to decide at run
|
|
||||||
// time; `data` must be writable.
|
|
||||||
// For the latter two the write-back below requires a mutable `data`, so
|
|
||||||
// passing a const argument is a compile error.
|
|
||||||
constexpr bool replaceCached = std::is_same_v<Policy, detail::ReplaceCached>;
|
|
||||||
|
|
||||||
std::scoped_lock const lock(mutex_);
|
std::scoped_lock const lock(mutex_);
|
||||||
|
|
||||||
auto cit = cache_.find(key);
|
auto cit = cache_.find(key);
|
||||||
@@ -364,14 +325,13 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
Entry& entry = cit->second;
|
Entry& entry = cit->second;
|
||||||
entry.touch(clock_.now());
|
entry.touch(clock_.now());
|
||||||
|
|
||||||
auto shouldReplaceCached = [&] {
|
auto shouldReplace = [&] {
|
||||||
if constexpr (replaceCached)
|
if constexpr (std::is_invocable_r_v<bool, R>)
|
||||||
{
|
{
|
||||||
return true;
|
// The reason for this extra complexity is for intrusive
|
||||||
}
|
// strong/weak combo getting a strong is relatively expensive
|
||||||
else if constexpr (std::is_same_v<Policy, detail::ReplaceClient>)
|
// and not needed for many cases.
|
||||||
{
|
return replaceCallback();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -381,11 +341,11 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
|
|
||||||
if (entry.isCached())
|
if (entry.isCached())
|
||||||
{
|
{
|
||||||
if (shouldReplaceCached())
|
if (shouldReplace())
|
||||||
{
|
{
|
||||||
entry.ptr = data;
|
entry.ptr = data;
|
||||||
}
|
}
|
||||||
else if constexpr (!replaceCached)
|
else
|
||||||
{
|
{
|
||||||
data = entry.ptr.getStrong();
|
data = entry.ptr.getStrong();
|
||||||
}
|
}
|
||||||
@@ -397,11 +357,11 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
|
|
||||||
if (cachedData)
|
if (cachedData)
|
||||||
{
|
{
|
||||||
if (shouldReplaceCached())
|
if (shouldReplace())
|
||||||
{
|
{
|
||||||
entry.ptr = data;
|
entry.ptr = data;
|
||||||
}
|
}
|
||||||
else if constexpr (!replaceCached)
|
else
|
||||||
{
|
{
|
||||||
entry.ptr.convertToStrong();
|
entry.ptr.convertToStrong();
|
||||||
data = cachedData;
|
data = cachedData;
|
||||||
@@ -417,24 +377,6 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
|
||||||
class Key,
|
|
||||||
class T,
|
|
||||||
bool IsKeyCache,
|
|
||||||
class SharedWeakUnionPointer,
|
|
||||||
class SharedPointerType,
|
|
||||||
class Hash,
|
|
||||||
class KeyEqual,
|
|
||||||
class Mutex>
|
|
||||||
template <class Callback>
|
|
||||||
inline bool
|
|
||||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
|
||||||
canonicalize(key_type const& key, SharedPointerType& data, Callback&& replaceCallback)
|
|
||||||
{
|
|
||||||
return canonicalizeImpl(
|
|
||||||
key, data, detail::ReplaceDynamically{}, std::forward<Callback>(replaceCallback));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class Key,
|
class Key,
|
||||||
class T,
|
class T,
|
||||||
@@ -448,7 +390,7 @@ inline bool
|
|||||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||||
canonicalizeReplaceCache(key_type const& key, SharedPointerType const& data)
|
canonicalizeReplaceCache(key_type const& key, SharedPointerType const& data)
|
||||||
{
|
{
|
||||||
return canonicalizeImpl(key, data, detail::ReplaceCached{});
|
return canonicalize(key, const_cast<SharedPointerType&>(data), []() { return true; });
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
@@ -464,7 +406,7 @@ inline bool
|
|||||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||||
canonicalizeReplaceClient(key_type const& key, SharedPointerType& data)
|
canonicalizeReplaceClient(key_type const& key, SharedPointerType& data)
|
||||||
{
|
{
|
||||||
return canonicalizeImpl(key, data, detail::ReplaceClient{});
|
return canonicalize(key, data, []() { return false; });
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
@@ -595,8 +537,15 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
|||||||
std::vector<key_type> v;
|
std::vector<key_type> v;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock const lock(mutex_);
|
std::unique_lock lock(mutex_);
|
||||||
v.reserve(cache_.size());
|
for (auto size = cache_.size(); v.capacity() < size; size = cache_.size())
|
||||||
|
{
|
||||||
|
ScopeUnlock const unlock(lock);
|
||||||
|
v.reserve(size);
|
||||||
|
}
|
||||||
|
XRPL_ASSERT(lock.owns_lock(), "xrpl::TaggedCache::getKeys(): owns lock");
|
||||||
|
XRPL_ASSERT(
|
||||||
|
v.capacity() >= cache_.size(), "xrpl::TaggedCache::getKeys(): sufficient capacity");
|
||||||
for (auto const& _ : cache_)
|
for (auto const& _ : cache_)
|
||||||
v.push_back(_.first);
|
v.push_back(_.first);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <xrpl/ledger/View.h>
|
#include <xrpl/ledger/View.h>
|
||||||
|
|
||||||
namespace xrpl::permissioned_dex {
|
namespace xrpl::permissioned_dex {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <xrpl/protocol/HashPrefix.h>
|
#include <xrpl/protocol/HashPrefix.h>
|
||||||
#include <xrpl/protocol/STVector256.h>
|
#include <xrpl/protocol/STVector256.h>
|
||||||
#include <xrpl/protocol/Serializer.h>
|
#include <xrpl/protocol/Serializer.h>
|
||||||
|
|||||||
0
include/xrpl/tx/paths/detail/AmountSpec.h
Normal file
0
include/xrpl/tx/paths/detail/AmountSpec.h
Normal file
@@ -3,6 +3,7 @@
|
|||||||
#include <xrpl/ledger/PaymentSandbox.h>
|
#include <xrpl/ledger/PaymentSandbox.h>
|
||||||
#include <xrpl/protocol/IOUAmount.h>
|
#include <xrpl/protocol/IOUAmount.h>
|
||||||
#include <xrpl/protocol/XRPAmount.h>
|
#include <xrpl/protocol/XRPAmount.h>
|
||||||
|
#include <xrpl/tx/paths/detail/AmountSpec.h>
|
||||||
|
|
||||||
#include <boost/container/flat_map.hpp>
|
#include <boost/container/flat_map.hpp>
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <xrpl/protocol/IOUAmount.h>
|
#include <xrpl/protocol/IOUAmount.h>
|
||||||
#include <xrpl/protocol/XRPAmount.h>
|
#include <xrpl/protocol/XRPAmount.h>
|
||||||
#include <xrpl/tx/paths/Flow.h>
|
#include <xrpl/tx/paths/Flow.h>
|
||||||
|
#include <xrpl/tx/paths/detail/AmountSpec.h>
|
||||||
#include <xrpl/tx/paths/detail/FlatSets.h>
|
#include <xrpl/tx/paths/detail/FlatSets.h>
|
||||||
#include <xrpl/tx/paths/detail/FlowDebugInfo.h>
|
#include <xrpl/tx/paths/detail/FlowDebugInfo.h>
|
||||||
#include <xrpl/tx/paths/detail/Steps.h>
|
#include <xrpl/tx/paths/detail/Steps.h>
|
||||||
|
|||||||
@@ -905,11 +905,6 @@ BookStep<TIn, TOut, TDerived>::getAMMOffer(
|
|||||||
ReadView const& view,
|
ReadView const& view,
|
||||||
std::optional<Quality> const& clobQuality) const
|
std::optional<Quality> const& clobQuality) const
|
||||||
{
|
{
|
||||||
// AMM doesn't support domain books. When fixCleanup3_3_0 is enabled, exclude
|
|
||||||
// AMM liquidity so quality estimation matches actual crossing (tryAMM skips
|
|
||||||
// AMM for domain books).
|
|
||||||
if (book_.domain && view.rules().enabled(fixCleanup3_3_0))
|
|
||||||
return std::nullopt;
|
|
||||||
if (ammLiquidity_)
|
if (ammLiquidity_)
|
||||||
return ammLiquidity_->getOffer(view, clobQuality);
|
return ammLiquidity_->getOffer(view, clobQuality);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <xrpl/protocol/STAmount.h>
|
#include <xrpl/protocol/STAmount.h>
|
||||||
#include <xrpl/protocol/STPathSet.h>
|
#include <xrpl/protocol/STPathSet.h>
|
||||||
#include <xrpl/tx/paths/RippleCalc.h>
|
#include <xrpl/tx/paths/RippleCalc.h>
|
||||||
|
#include <xrpl/tx/paths/detail/AmountSpec.h>
|
||||||
#include <xrpl/tx/paths/detail/Steps.h>
|
#include <xrpl/tx/paths/detail/Steps.h>
|
||||||
#include <xrpl/tx/paths/detail/StrandFlow.h>
|
#include <xrpl/tx/paths/detail/StrandFlow.h>
|
||||||
#include <xrpl/tx/transactors/dex/AMMContext.h>
|
#include <xrpl/tx/transactors/dex/AMMContext.h>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <xrpl/protocol/TER.h>
|
#include <xrpl/protocol/TER.h>
|
||||||
#include <xrpl/protocol/UintTypes.h>
|
#include <xrpl/protocol/UintTypes.h>
|
||||||
#include <xrpl/protocol/XRPAmount.h>
|
#include <xrpl/protocol/XRPAmount.h>
|
||||||
|
#include <xrpl/tx/paths/detail/AmountSpec.h>
|
||||||
#include <xrpl/tx/paths/detail/EitherAmount.h>
|
#include <xrpl/tx/paths/detail/EitherAmount.h>
|
||||||
#include <xrpl/tx/paths/detail/StepChecks.h>
|
#include <xrpl/tx/paths/detail/StepChecks.h>
|
||||||
#include <xrpl/tx/paths/detail/Steps.h>
|
#include <xrpl/tx/paths/detail/Steps.h>
|
||||||
|
|||||||
@@ -52,13 +52,9 @@ DelegateSet::preclaim(PreclaimContext const& ctx)
|
|||||||
if (!ctx.view.exists(keylet::account(ctx.tx[sfAccount])))
|
if (!ctx.view.exists(keylet::account(ctx.tx[sfAccount])))
|
||||||
return terNO_ACCOUNT; // LCOV_EXCL_LINE
|
return terNO_ACCOUNT; // LCOV_EXCL_LINE
|
||||||
|
|
||||||
auto const sleAuthorize = ctx.view.read(keylet::account(ctx.tx[sfAuthorize]));
|
if (!ctx.view.exists(keylet::account(ctx.tx[sfAuthorize])))
|
||||||
if (!sleAuthorize)
|
|
||||||
return tecNO_TARGET;
|
return tecNO_TARGET;
|
||||||
|
|
||||||
if (isPseudoAccount(sleAuthorize))
|
|
||||||
return tecNO_PERMISSION;
|
|
||||||
|
|
||||||
// Deleting the delegate object is invalid if it doesn’t exist.
|
// Deleting the delegate object is invalid if it doesn’t exist.
|
||||||
if (ctx.tx.getFieldArray(sfPermissions).empty() &&
|
if (ctx.tx.getFieldArray(sfPermissions).empty() &&
|
||||||
!ctx.view.exists(keylet::delegate(ctx.tx[sfAccount], ctx.tx[sfAuthorize])))
|
!ctx.view.exists(keylet::delegate(ctx.tx[sfAccount], ctx.tx[sfAuthorize])))
|
||||||
|
|||||||
0
src/libxrpl/tx/transactors/escrow/Escrow.cpp
Normal file
0
src/libxrpl/tx/transactors/escrow/Escrow.cpp
Normal file
@@ -235,19 +235,6 @@ class Delegate_test : public beast::unit_test::Suite
|
|||||||
env(delegate::set(gw, Account("unknown"), {"Payment"}), Ter(tecNO_TARGET));
|
env(delegate::set(gw, Account("unknown"), {"Payment"}), Ter(tecNO_TARGET));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delegating to a pseudo-account is not allowed, should return tecNO_PERMISSION
|
|
||||||
{
|
|
||||||
Vault const vault{env};
|
|
||||||
auto [tx, keylet] = vault.create({.owner = gw, .asset = xrpIssue()});
|
|
||||||
env(tx);
|
|
||||||
env.close();
|
|
||||||
|
|
||||||
auto const sleVault = env.le(keylet);
|
|
||||||
BEAST_EXPECT(sleVault);
|
|
||||||
Account const vaultPseudo{"vault", sleVault->at(sfAccount)};
|
|
||||||
env(delegate::set(gw, vaultPseudo, {"Payment"}), Ter(tecNO_PERMISSION));
|
|
||||||
}
|
|
||||||
|
|
||||||
// non-delegable transaction
|
// non-delegable transaction
|
||||||
{
|
{
|
||||||
env(delegate::set(gw, alice, {"SetRegularKey"}), Ter(temMALFORMED));
|
env(delegate::set(gw, alice, {"SetRegularKey"}), Ter(temMALFORMED));
|
||||||
|
|||||||
@@ -993,83 +993,6 @@ class PermissionedDEX_test : public beast::unit_test::Suite
|
|||||||
BEAST_EXPECT(usd == USD(45));
|
BEAST_EXPECT(usd == USD(45));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
testAmmQualityNotLeaked(FeatureBitset features)
|
|
||||||
{
|
|
||||||
bool const excludesAmmFromDomainQuality = features[fixCleanup3_3_0];
|
|
||||||
|
|
||||||
testcase << "AMM quality not leaked into domain BookStep"
|
|
||||||
<< (excludesAmmFromDomainQuality ? " (Cleanup3_3_0 enabled)"
|
|
||||||
: " (Cleanup3_3_0 disabled)");
|
|
||||||
|
|
||||||
Env env(*this, features);
|
|
||||||
auto const& [gw, domainOwner, alice, bob, carol, USD, domainID, credType] =
|
|
||||||
PermissionedDEX(env);
|
|
||||||
auto const eur = gw["EUR"];
|
|
||||||
|
|
||||||
env.trust(eur(1000), bob, domainOwner);
|
|
||||||
env.close();
|
|
||||||
env(pay(gw, bob, eur(100)));
|
|
||||||
env.close();
|
|
||||||
|
|
||||||
env(pay(gw, alice, USD(500)));
|
|
||||||
env.close();
|
|
||||||
|
|
||||||
// The AMM makes the direct XRP->USD book look much better than it
|
|
||||||
// really is for domain payments. The domain LOB direct path is 1:1,
|
|
||||||
// while the competing XRP->EUR->USD path is 2:1.
|
|
||||||
AMM const amm(env, alice, XRP(10), USD(500));
|
|
||||||
|
|
||||||
auto const directOfferSeq{env.seq(bob)};
|
|
||||||
env(offer(bob, XRP(10), USD(10)), Domain(domainID));
|
|
||||||
env.close();
|
|
||||||
|
|
||||||
auto const xrpEurOfferSeq{env.seq(bob)};
|
|
||||||
env(offer(bob, XRP(10), eur(20)), Domain(domainID));
|
|
||||||
env.close();
|
|
||||||
|
|
||||||
auto const eurUsdOfferSeq{env.seq(domainOwner)};
|
|
||||||
env(offer(domainOwner, eur(20), USD(20)), Domain(domainID));
|
|
||||||
env.close();
|
|
||||||
|
|
||||||
auto const carolBalBefore = env.balance(carol, USD);
|
|
||||||
|
|
||||||
// Both paths compete for the same XRP(10) sendmax. If AMM quality leaks
|
|
||||||
// into the direct domain book, the engine ranks direct XRP->USD first
|
|
||||||
// but crossing can only consume the 1:1 LOB offer. With the fix, the
|
|
||||||
// direct book is ranked by its domain LOB quality, so the 2:1
|
|
||||||
// XRP->EUR->USD path executes first.
|
|
||||||
env(pay(alice, carol, USD(100)),
|
|
||||||
Path(~USD),
|
|
||||||
Path(~eur, ~USD),
|
|
||||||
Sendmax(XRP(10)),
|
|
||||||
Txflags(tfPartialPayment | tfNoRippleDirect),
|
|
||||||
Domain(domainID));
|
|
||||||
env.close();
|
|
||||||
|
|
||||||
auto const delivered = env.balance(carol, USD) - carolBalBefore;
|
|
||||||
if (excludesAmmFromDomainQuality)
|
|
||||||
{
|
|
||||||
BEAST_EXPECT(delivered == USD(20));
|
|
||||||
|
|
||||||
BEAST_EXPECT(checkOffer(env, bob, directOfferSeq, XRP(10), USD(10), 0, true));
|
|
||||||
BEAST_EXPECT(!offerExists(env, bob, xrpEurOfferSeq));
|
|
||||||
BEAST_EXPECT(!offerExists(env, domainOwner, eurUsdOfferSeq));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BEAST_EXPECT(delivered == USD(10));
|
|
||||||
|
|
||||||
BEAST_EXPECT(!offerExists(env, bob, directOfferSeq));
|
|
||||||
BEAST_EXPECT(checkOffer(env, bob, xrpEurOfferSeq, XRP(10), eur(20), 0, true));
|
|
||||||
BEAST_EXPECT(checkOffer(env, domainOwner, eurUsdOfferSeq, eur(20), USD(20), 0, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto [xrp, usd, lpt] = amm.balances(XRP, USD);
|
|
||||||
BEAST_EXPECT(xrp == XRP(10));
|
|
||||||
BEAST_EXPECT(usd == USD(500));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
testHybridOfferCreate(FeatureBitset features)
|
testHybridOfferCreate(FeatureBitset features)
|
||||||
{
|
{
|
||||||
@@ -2020,8 +1943,6 @@ public:
|
|||||||
testOfferTokenIssuerInDomain(all);
|
testOfferTokenIssuerInDomain(all);
|
||||||
testRemoveUnfundedOffer(all);
|
testRemoveUnfundedOffer(all);
|
||||||
testAmmNotUsed(all);
|
testAmmNotUsed(all);
|
||||||
testAmmQualityNotLeaked(all);
|
|
||||||
testAmmQualityNotLeaked(all - fixCleanup3_3_0);
|
|
||||||
testAutoBridge(all);
|
testAutoBridge(all);
|
||||||
|
|
||||||
// Test hybrid offers
|
// Test hybrid offers
|
||||||
|
|||||||
@@ -8,21 +8,18 @@
|
|||||||
#include <test/jtx/pay.h>
|
#include <test/jtx/pay.h>
|
||||||
#include <test/jtx/permissioned_domains.h>
|
#include <test/jtx/permissioned_domains.h>
|
||||||
#include <test/jtx/ter.h>
|
#include <test/jtx/ter.h>
|
||||||
#include <test/jtx/ticket.h>
|
|
||||||
#include <test/jtx/txflags.h>
|
#include <test/jtx/txflags.h>
|
||||||
|
|
||||||
#include <xrpl/basics/base_uint.h>
|
#include <xrpl/basics/base_uint.h>
|
||||||
#include <xrpl/beast/unit_test/suite.h>
|
#include <xrpl/beast/unit_test/suite.h>
|
||||||
#include <xrpl/json/json_value.h>
|
#include <xrpl/json/json_value.h>
|
||||||
#include <xrpl/protocol/Feature.h>
|
#include <xrpl/protocol/Feature.h>
|
||||||
#include <xrpl/protocol/Indexes.h>
|
|
||||||
#include <xrpl/protocol/Protocol.h>
|
#include <xrpl/protocol/Protocol.h>
|
||||||
#include <xrpl/protocol/TER.h>
|
#include <xrpl/protocol/TER.h>
|
||||||
#include <xrpl/protocol/TxFlags.h>
|
#include <xrpl/protocol/TxFlags.h>
|
||||||
#include <xrpl/protocol/jss.h>
|
#include <xrpl/protocol/jss.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@@ -529,47 +526,6 @@ class PermissionedDomains_test : public beast::unit_test::Suite
|
|||||||
BEAST_EXPECT(env.ownerCount(alice) == 1);
|
BEAST_EXPECT(env.ownerCount(alice) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
testTicket(FeatureBitset features)
|
|
||||||
{
|
|
||||||
testcase("Tickets");
|
|
||||||
|
|
||||||
using namespace test::jtx;
|
|
||||||
|
|
||||||
Env env(*this, features);
|
|
||||||
Account const alice("alice");
|
|
||||||
env.fund(XRP(1000), alice);
|
|
||||||
|
|
||||||
pdomain::Credentials const credentials{
|
|
||||||
{.issuer = alice, .credType = "credential1"},
|
|
||||||
};
|
|
||||||
|
|
||||||
std::uint32_t seq{env.seq(alice)};
|
|
||||||
env(ticket::create(alice, 2));
|
|
||||||
|
|
||||||
{
|
|
||||||
env(pdomain::setTx(alice, credentials), ticket::Use(++seq));
|
|
||||||
auto domain = pdomain::getNewDomain(env.meta());
|
|
||||||
if (features[fixCleanup3_1_3])
|
|
||||||
{
|
|
||||||
BEAST_EXPECT(domain == keylet::permissionedDomain(alice.id(), seq).key);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BEAST_EXPECT(domain == keylet::permissionedDomain(alice.id(), 0).key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (features[fixCleanup3_1_3])
|
|
||||||
{
|
|
||||||
env(pdomain::setTx(alice, credentials), ticket::Use(++seq));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
env(pdomain::setTx(alice, credentials), ticket::Use(++seq), Ter(tefEXCEPTION));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void
|
void
|
||||||
run() override
|
run() override
|
||||||
@@ -584,8 +540,6 @@ public:
|
|||||||
testDelete(withFix_);
|
testDelete(withFix_);
|
||||||
testAccountReserve(withFeature_);
|
testAccountReserve(withFeature_);
|
||||||
testAccountReserve(withFix_);
|
testAccountReserve(withFix_);
|
||||||
testTicket(withFeature_);
|
|
||||||
testTicket(withFix_);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#include <test/unit_test/SuiteJournal.h>
|
#include <test/unit_test/SuiteJournal.h>
|
||||||
|
|
||||||
#include <xrpl/basics/IntrusivePointer.h>
|
|
||||||
#include <xrpl/basics/IntrusiveRefCounts.h>
|
|
||||||
#include <xrpl/basics/TaggedCache.h>
|
#include <xrpl/basics/TaggedCache.h>
|
||||||
#include <xrpl/basics/TaggedCache.ipp> // IWYU pragma: keep
|
#include <xrpl/basics/TaggedCache.ipp> // IWYU pragma: keep
|
||||||
#include <xrpl/basics/chrono.h>
|
#include <xrpl/basics/chrono.h>
|
||||||
@@ -10,7 +8,6 @@
|
|||||||
#include <xrpl/protocol/Protocol.h>
|
#include <xrpl/protocol/Protocol.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace xrpl {
|
namespace xrpl {
|
||||||
|
|
||||||
@@ -136,113 +133,6 @@ public:
|
|||||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||||
BEAST_EXPECT(c.getTrackSize() == 0);
|
BEAST_EXPECT(c.getTrackSize() == 0);
|
||||||
}
|
}
|
||||||
{
|
|
||||||
BEAST_EXPECT(!c.insert(5, "five"));
|
|
||||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
|
||||||
BEAST_EXPECT(c.size() == 1);
|
|
||||||
|
|
||||||
{
|
|
||||||
auto const p1 = c.fetch(5);
|
|
||||||
BEAST_EXPECT(p1 != nullptr);
|
|
||||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
|
||||||
BEAST_EXPECT(c.size() == 1);
|
|
||||||
|
|
||||||
// Advance the clock a lot
|
|
||||||
++clock;
|
|
||||||
c.sweep();
|
|
||||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
|
||||||
BEAST_EXPECT(c.size() == 1);
|
|
||||||
|
|
||||||
auto p2 = std::make_shared<std::string>("five_2");
|
|
||||||
BEAST_EXPECT(c.canonicalizeReplaceCache(5, p2));
|
|
||||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
|
||||||
BEAST_EXPECT(c.size() == 1);
|
|
||||||
// Make sure the caller's original pointer is unchanged
|
|
||||||
BEAST_EXPECT(p1.get() != p2.get());
|
|
||||||
BEAST_EXPECT(*p2 == "five_2");
|
|
||||||
|
|
||||||
auto const p3 = c.fetch(5);
|
|
||||||
BEAST_EXPECT(p3 != nullptr);
|
|
||||||
BEAST_EXPECT(p3.get() == p2.get());
|
|
||||||
BEAST_EXPECT(p3.get() != p1.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
++clock;
|
|
||||||
c.sweep();
|
|
||||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
|
||||||
BEAST_EXPECT(c.size() == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
testcase("intrptr");
|
|
||||||
|
|
||||||
struct MyRefCountObject : IntrusiveRefCounts
|
|
||||||
{
|
|
||||||
std::string data;
|
|
||||||
|
|
||||||
// Needed to support weak intrusive pointers
|
|
||||||
virtual void
|
|
||||||
partialDestructor() {};
|
|
||||||
|
|
||||||
MyRefCountObject() = default;
|
|
||||||
explicit MyRefCountObject(std::string data) : data(std::move(data))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator==(std::string const& other) const
|
|
||||||
{
|
|
||||||
return data == other;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
using IntrPtrCache = TaggedCache<
|
|
||||||
Key,
|
|
||||||
MyRefCountObject,
|
|
||||||
/*IsKeyCache*/ false,
|
|
||||||
intr_ptr::SharedWeakUnionPtr<MyRefCountObject>,
|
|
||||||
intr_ptr::SharedPtr<MyRefCountObject>>;
|
|
||||||
|
|
||||||
IntrPtrCache intrPtrCache("IntrPtrTest", 1, 1s, clock, journal);
|
|
||||||
|
|
||||||
intrPtrCache.canonicalizeReplaceCache(1, intr_ptr::makeShared<MyRefCountObject>("one"));
|
|
||||||
BEAST_EXPECT(intrPtrCache.getCacheSize() == 1);
|
|
||||||
BEAST_EXPECT(intrPtrCache.size() == 1);
|
|
||||||
|
|
||||||
{
|
|
||||||
{
|
|
||||||
intrPtrCache.canonicalizeReplaceCache(
|
|
||||||
1, intr_ptr::makeShared<MyRefCountObject>("one_replaced"));
|
|
||||||
|
|
||||||
auto p = intrPtrCache.fetch(1);
|
|
||||||
BEAST_EXPECT(*p == "one_replaced");
|
|
||||||
|
|
||||||
// Advance the clock a lot
|
|
||||||
++clock;
|
|
||||||
intrPtrCache.sweep();
|
|
||||||
BEAST_EXPECT(intrPtrCache.getCacheSize() == 0);
|
|
||||||
BEAST_EXPECT(intrPtrCache.size() == 1);
|
|
||||||
|
|
||||||
intrPtrCache.canonicalizeReplaceCache(
|
|
||||||
1, intr_ptr::makeShared<MyRefCountObject>("one_replaced_2"));
|
|
||||||
|
|
||||||
auto p2 = intrPtrCache.fetch(1);
|
|
||||||
BEAST_EXPECT(*p2 == "one_replaced_2");
|
|
||||||
|
|
||||||
intrPtrCache.del(1, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
intrPtrCache.canonicalizeReplaceCache(
|
|
||||||
1, intr_ptr::makeShared<MyRefCountObject>("one_replaced_3"));
|
|
||||||
auto p3 = intrPtrCache.fetch(1);
|
|
||||||
BEAST_EXPECT(*p3 == "one_replaced_3");
|
|
||||||
}
|
|
||||||
|
|
||||||
++clock;
|
|
||||||
intrPtrCache.sweep();
|
|
||||||
BEAST_EXPECT(intrPtrCache.getCacheSize() == 0);
|
|
||||||
BEAST_EXPECT(intrPtrCache.size() == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <xrpl/basics/random.h>
|
#include <xrpl/basics/random.h>
|
||||||
#include <xrpl/beast/net/IPEndpoint.h>
|
#include <xrpl/beast/net/IPEndpoint.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <test/csf/BasicNetwork.h>
|
#include <test/csf/BasicNetwork.h>
|
||||||
#include <test/csf/Digraph.h>
|
#include <test/csf/Digraph.h>
|
||||||
#include <test/csf/Histogram.h>
|
#include <test/csf/Histogram.h>
|
||||||
|
|||||||
@@ -174,22 +174,12 @@ public:
|
|||||||
ammRpcInfo(
|
ammRpcInfo(
|
||||||
std::optional<AccountID> const& account = std::nullopt,
|
std::optional<AccountID> const& account = std::nullopt,
|
||||||
std::optional<std::string> const& ledgerIndex = std::nullopt,
|
std::optional<std::string> const& ledgerIndex = std::nullopt,
|
||||||
std::optional<Asset> const& asset1 = std::nullopt,
|
std::optional<Asset> asset1 = std::nullopt,
|
||||||
std::optional<Asset> const& asset2 = std::nullopt,
|
std::optional<Asset> asset2 = std::nullopt,
|
||||||
std::optional<AccountID> const& ammAccount = std::nullopt,
|
std::optional<AccountID> const& ammAccount = std::nullopt,
|
||||||
bool ignoreParams = false,
|
bool ignoreParams = false,
|
||||||
unsigned apiVersion = RPC::kApiInvalidVersion) const;
|
unsigned apiVersion = RPC::kApiInvalidVersion) const;
|
||||||
|
|
||||||
[[nodiscard]] json::Value
|
|
||||||
ammRpcInfo(
|
|
||||||
std::optional<json::Value> const& account,
|
|
||||||
std::optional<std::string> const& ledgerIndex,
|
|
||||||
std::optional<Asset> const& asset1,
|
|
||||||
std::optional<Asset> const& asset2,
|
|
||||||
std::optional<json::Value> const& ammAccount,
|
|
||||||
bool ignoreParams,
|
|
||||||
unsigned apiVersion) const;
|
|
||||||
|
|
||||||
/** Verify the AMM balances.
|
/** Verify the AMM balances.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool
|
[[nodiscard]] bool
|
||||||
|
|||||||
@@ -183,37 +183,15 @@ json::Value
|
|||||||
AMM::ammRpcInfo(
|
AMM::ammRpcInfo(
|
||||||
std::optional<AccountID> const& account,
|
std::optional<AccountID> const& account,
|
||||||
std::optional<std::string> const& ledgerIndex,
|
std::optional<std::string> const& ledgerIndex,
|
||||||
std::optional<Asset> const& asset1,
|
std::optional<Asset> asset1,
|
||||||
std::optional<Asset> const& asset2,
|
std::optional<Asset> asset2,
|
||||||
std::optional<AccountID> const& ammAccount,
|
std::optional<AccountID> const& ammAccount,
|
||||||
bool ignoreParams,
|
bool ignoreParams,
|
||||||
unsigned apiVersion) const
|
unsigned apiVersion) const
|
||||||
{
|
|
||||||
auto const toJson = [](AccountID const& a) { return json::Value{to_string(a)}; };
|
|
||||||
|
|
||||||
return ammRpcInfo(
|
|
||||||
account.transform(toJson),
|
|
||||||
ledgerIndex,
|
|
||||||
asset1,
|
|
||||||
asset2,
|
|
||||||
ammAccount.transform(toJson),
|
|
||||||
ignoreParams,
|
|
||||||
apiVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
json::Value
|
|
||||||
AMM::ammRpcInfo(
|
|
||||||
std::optional<json::Value> const& account,
|
|
||||||
std::optional<std::string> const& ledgerIndex,
|
|
||||||
std::optional<Asset> const& asset1,
|
|
||||||
std::optional<Asset> const& asset2,
|
|
||||||
std::optional<json::Value> const& ammAccount,
|
|
||||||
bool ignoreParams,
|
|
||||||
unsigned apiVersion) const
|
|
||||||
{
|
{
|
||||||
json::Value jv;
|
json::Value jv;
|
||||||
if (account)
|
if (account)
|
||||||
jv[jss::account] = *account;
|
jv[jss::account] = to_string(*account);
|
||||||
if (ledgerIndex)
|
if (ledgerIndex)
|
||||||
jv[jss::ledger_index] = *ledgerIndex;
|
jv[jss::ledger_index] = *ledgerIndex;
|
||||||
if (!ignoreParams)
|
if (!ignoreParams)
|
||||||
@@ -231,7 +209,7 @@ AMM::ammRpcInfo(
|
|||||||
jv[jss::asset2] = STIssue(sfAsset2, asset2_.asset()).getJson(JsonOptions::Values::None);
|
jv[jss::asset2] = STIssue(sfAsset2, asset2_.asset()).getJson(JsonOptions::Values::None);
|
||||||
}
|
}
|
||||||
if (ammAccount)
|
if (ammAccount)
|
||||||
jv[jss::amm_account] = *ammAccount;
|
jv[jss::amm_account] = to_string(*ammAccount);
|
||||||
}
|
}
|
||||||
auto jr =
|
auto jr =
|
||||||
(apiVersion == RPC::kApiInvalidVersion
|
(apiVersion == RPC::kApiInvalidVersion
|
||||||
|
|||||||
@@ -65,26 +65,6 @@ public:
|
|||||||
BEAST_EXPECT(jv[jss::error_message] == "Account malformed.");
|
BEAST_EXPECT(jv[jss::error_message] == "Account malformed.");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Account is not a string
|
|
||||||
testAMM([&](AMM& ammAlice, Env&) {
|
|
||||||
auto const jv =
|
|
||||||
ammAlice.ammRpcInfo(json::Value{42}, std::nullopt, XRP, USD, std::nullopt, true, 3);
|
|
||||||
BEAST_EXPECT(jv[jss::error_message] == "Account malformed.");
|
|
||||||
});
|
|
||||||
|
|
||||||
// AMM Account is not a string
|
|
||||||
testAMM([&](AMM& ammAlice, Env&) {
|
|
||||||
auto const jv = ammAlice.ammRpcInfo(
|
|
||||||
json::Value{to_string(ammAlice.ammAccount())},
|
|
||||||
std::nullopt,
|
|
||||||
XRP,
|
|
||||||
USD,
|
|
||||||
json::Value{42},
|
|
||||||
false,
|
|
||||||
3);
|
|
||||||
BEAST_EXPECT(jv[jss::error_message] == "Account malformed.");
|
|
||||||
});
|
|
||||||
|
|
||||||
std::vector<std::tuple<std::optional<Issue>, std::optional<Issue>, TestAccount, bool>> const
|
std::vector<std::tuple<std::optional<Issue>, std::optional<Issue>, TestAccount, bool>> const
|
||||||
invalidParams = {
|
invalidParams = {
|
||||||
{xrpIssue(), std::nullopt, TestAccount::None, false},
|
{xrpIssue(), std::nullopt, TestAccount::None, false},
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <xrpl/protocol/SecretKey.h>
|
#include <xrpl/protocol/SecretKey.h>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ add_executable(
|
|||||||
helpers/TestSink.cpp
|
helpers/TestSink.cpp
|
||||||
helpers/TxTest.cpp
|
helpers/TxTest.cpp
|
||||||
)
|
)
|
||||||
patch_nix_binary(xrpl_tests)
|
|
||||||
set_target_properties(
|
set_target_properties(
|
||||||
xrpl_tests
|
xrpl_tests
|
||||||
PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||||
|
|||||||
0
src/xrpld/app/ledger/OrderBookDB.h
Normal file
0
src/xrpld/app/ledger/OrderBookDB.h
Normal file
@@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <xrpl/shamap/SHAMapInnerNode.h>
|
#include <xrpl/shamap/SHAMapInnerNode.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <xrpld/app/main/Application.h>
|
#include <xrpld/app/main/Application.h>
|
||||||
#include <xrpld/rpc/detail/AssetCache.h>
|
#include <xrpld/rpc/detail/AssetCache.h>
|
||||||
#include <xrpld/rpc/detail/PathRequest.h>
|
#include <xrpld/rpc/detail/PathRequest.h>
|
||||||
|
#include <xrpld/rpc/detail/RippleLineCache.h>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <xrpld/app/main/Application.h>
|
#include <xrpld/app/main/Application.h>
|
||||||
#include <xrpld/rpc/detail/AssetCache.h>
|
#include <xrpld/rpc/detail/AssetCache.h>
|
||||||
#include <xrpld/rpc/detail/PathfinderUtils.h>
|
#include <xrpld/rpc/detail/PathfinderUtils.h>
|
||||||
|
#include <xrpld/rpc/detail/RippleLineCache.h>
|
||||||
#include <xrpld/rpc/detail/TrustLine.h>
|
#include <xrpld/rpc/detail/TrustLine.h>
|
||||||
|
|
||||||
#include <xrpl/basics/Log.h>
|
#include <xrpl/basics/Log.h>
|
||||||
|
|||||||
0
src/xrpld/rpc/detail/RippleLineCache.cpp
Normal file
0
src/xrpld/rpc/detail/RippleLineCache.cpp
Normal file
0
src/xrpld/rpc/detail/RippleLineCache.h
Normal file
0
src/xrpld/rpc/detail/RippleLineCache.h
Normal file
@@ -1,5 +1,3 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <xrpld/rpc/detail/RPCHelpers.h>
|
#include <xrpld/rpc/detail/RPCHelpers.h>
|
||||||
|
|
||||||
#include <xrpl/basics/StringUtilities.h>
|
#include <xrpl/basics/StringUtilities.h>
|
||||||
|
|||||||
@@ -120,10 +120,7 @@ doAMMInfo(RPC::JsonContext& context)
|
|||||||
|
|
||||||
if (params.isMember(jss::amm_account))
|
if (params.isMember(jss::amm_account))
|
||||||
{
|
{
|
||||||
auto const& ammAccount = params[jss::amm_account];
|
auto const id = parseBase58<AccountID>((params[jss::amm_account].asString()));
|
||||||
if (!ammAccount.isString())
|
|
||||||
return std::unexpected(RpcActMalformed);
|
|
||||||
auto const id = parseBase58<AccountID>(ammAccount.asString());
|
|
||||||
if (!id)
|
if (!id)
|
||||||
return std::unexpected(RpcActMalformed);
|
return std::unexpected(RpcActMalformed);
|
||||||
auto const sle = ledger->read(keylet::account(*id));
|
auto const sle = ledger->read(keylet::account(*id));
|
||||||
@@ -136,10 +133,7 @@ doAMMInfo(RPC::JsonContext& context)
|
|||||||
|
|
||||||
if (params.isMember(jss::account))
|
if (params.isMember(jss::account))
|
||||||
{
|
{
|
||||||
auto const& localAccount = params[jss::account];
|
accountID = parseBase58<AccountID>(params[jss::account].asString());
|
||||||
if (!localAccount.isString())
|
|
||||||
return std::unexpected(RpcActMalformed);
|
|
||||||
accountID = parseBase58<AccountID>(localAccount.asString());
|
|
||||||
if (!accountID || !ledger->read(keylet::account(*accountID)))
|
if (!accountID || !ledger->read(keylet::account(*accountID)))
|
||||||
return std::unexpected(RpcActMalformed);
|
return std::unexpected(RpcActMalformed);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user