Compare commits

..

25 Commits

Author SHA1 Message Date
Mayukha Vadari
646b3aa269 do an audit of fields 2026-05-29 10:50:44 -04:00
Mayukha Vadari
4dc61deeb4 fix build 2026-05-29 10:23:21 -04:00
Mayukha Vadari
e2103b1bef remove inner object mutabilities 2026-05-29 09:46:19 -04:00
Mayukha Vadari
9dfb0cf981 NoModifiedUnmodifiableFields -> NoModifiedImmutableFields 2026-05-29 09:44:43 -04:00
Mayukha Vadari
84908d56c1 rename constant -> mutability 2026-05-29 09:43:45 -04:00
Mayukha Vadari
076d923cc1 fix tests 2026-05-28 13:31:26 -04:00
Mayukha Vadari
fd86ca9205 Merge branch 'develop' of https://github.com/XRPLF/rippled into mvadari/constant-field-invariant 2026-05-28 12:32:57 -04:00
Mayukha Vadari
effec43851 ignore clang-tidy 2026-05-21 14:52:21 -04:00
Mayukha Vadari
08d5e1f6db Merge branch 'develop' into mvadari/constant-field-invariant 2026-05-20 17:16:01 -04:00
Mayukha Vadari
ceba7c6e34 fix typo 2026-05-20 17:12:28 -04:00
Mayukha Vadari
18994a31b1 Merge branch 'develop' of https://github.com/XRPLF/rippled into mvadari/constant-field-invariant 2026-05-20 16:47:06 -04:00
Mayukha Vadari
0a671b7d0b fix more issues 2026-05-20 16:37:55 -04:00
Mayukha Vadari
9cf2c0c3ae more fixes 2026-05-20 15:23:09 -04:00
Mayukha Vadari
bf68edb541 Merge branch 'develop' of https://github.com/XRPLF/rippled into mvadari/constant-field-invariant 2026-05-19 16:22:16 -04:00
Mayukha Vadari
67a199fcb5 fix build issue 2026-05-06 17:18:19 -04:00
Mayukha Vadari
02fba4c998 remove bad assert 2026-05-06 15:42:42 -04:00
Mayukha Vadari
1e51b61747 fix straggling issues 2026-05-06 11:39:05 -04:00
Mayukha Vadari
7b9a98692d fix clang-tidy issues 2026-05-06 11:36:45 -04:00
Mayukha Vadari
98ed477ca7 rename enum values 2026-05-06 11:35:38 -04:00
Mayukha Vadari
654734dcf9 fix clang-tidy issues 2026-05-06 11:17:21 -04:00
Mayukha Vadari
d5ca8ef77d Merge branch 'develop' into mvadari/constant-field-invariant 2026-05-06 11:16:19 -04:00
Mayukha Vadari
7de9560048 Update src/libxrpl/protocol/InnerObjectFormats.cpp
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-27 09:33:25 -04:00
Mayukha Vadari
568623f699 fix clang-tidy issues 2026-04-27 09:30:42 -04:00
Mayukha Vadari
cf33298abd add tests, fix issues 2026-04-27 08:52:52 -04:00
Mayukha Vadari
b46ca16f7d feature: Add invariant checks to ensure only fields that are expected to be modified are modified 2026-04-25 19:59:47 -04:00
414 changed files with 4083 additions and 5291 deletions

View File

@@ -154,7 +154,7 @@ Checks: "-*,
"
# ---
# readability-inconsistent-declaration-parameter-name, # in this codebase this check will break a lot of arg names
# readability-static-accessed-through-instance, # this check is probably unnecessary. It makes the code less readable
# readability-static-accessed-through-instance, # this check is probably unnecessary. it makes the code less readable
# ---
CheckOptions:

View File

@@ -11,6 +11,9 @@ endfunction()
function(create_symbolic_link target link)
endfunction()
function(xrpl_add_test name)
endfunction()
macro(exclude_from_default target_)
endmacro()

View File

@@ -35,8 +35,9 @@ runs:
LOG_VERBOSITY: ${{ inputs.log_verbosity }}
SANITIZERS: ${{ inputs.sanitizers }}
run: |
echo 'Installing dependencies.'
conan install \
--profile:all ci \
--profile ci \
--build="${BUILD_OPTION}" \
--options:host='&:tests=True' \
--options:host='&:xrpld=True' \

View File

@@ -1,34 +0,0 @@
name: Set compiler environment
description: "Set CC and CXX environment variables for the given compiler."
inputs:
compiler:
description: 'The compiler to use ("gcc" or "clang").'
required: true
runs:
using: composite
steps:
- name: Set CC and CXX for gcc
if: ${{ inputs.compiler == 'gcc' }}
shell: bash
run: |
echo "CC=gcc" >>"${GITHUB_ENV}"
echo "CXX=g++" >>"${GITHUB_ENV}"
- name: Set CC and CXX for clang
if: ${{ inputs.compiler == 'clang' }}
shell: bash
run: |
echo "CC=clang" >>"${GITHUB_ENV}"
echo "CXX=clang++" >>"${GITHUB_ENV}"
- name: Fail on unknown compiler
if: ${{ inputs.compiler != 'gcc' && inputs.compiler != 'clang' }}
shell: bash
env:
COMPILER: ${{ inputs.compiler }}
run: |
echo "Unknown compiler: $COMPILER" >&2
exit 1

View File

@@ -15,35 +15,32 @@ runs:
using: composite
steps:
- name: Apply custom configuration to global.conf
- name: Set up Conan configuration
shell: bash
run: |
echo 'Installing configuration.'
cat conan/global.conf ${{ runner.os == 'Linux' && '>>' || '>' }} $(conan config home)/global.conf
- name: Show global configuration
shell: bash
run: |
echo 'Conan configuration:'
conan config show '*'
- name: Install profiles
- name: Set up Conan profile
shell: bash
run: |
echo 'Installing profile.'
conan config install conan/profiles/ -tf $(conan config home)/profiles/
- name: Show CI profile
shell: bash
run: |
echo 'Conan profile:'
conan profile show --profile ci
- name: Add a remote
- name: Set up Conan remote
shell: bash
env:
REMOTE_NAME: ${{ inputs.remote_name }}
REMOTE_URL: ${{ inputs.remote_url }}
run: |
echo "Adding Conan remote '${REMOTE_NAME}' at '${REMOTE_URL}'."
conan remote add --index 0 --force "${REMOTE_NAME}" "${REMOTE_URL}"
- name: List remotes
shell: bash
run: |
echo 'Listing Conan remotes.'
conan remote list

View File

@@ -1,12 +1,40 @@
version: 2
updates:
- package-ecosystem: github-actions
directories:
- /
- .github/actions/build-deps/
- .github/actions/generate-version/
- .github/actions/set-compiler-env/
- .github/actions/setup-conan/
directory: /
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/build-deps/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/generate-version/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/setup-conan/
schedule:
interval: weekly
day: monday

View File

@@ -43,6 +43,9 @@ pushd "${DIRECTORY}"
# Rename the files.
find cmake -type f -name 'Rippled*.cmake' -exec bash -c 'mv "${1}" "${1/Rippled/Xrpl}"' - {} \;
find cmake -type f -name 'Ripple*.cmake' -exec bash -c 'mv "${1}" "${1/Ripple/Xrpl}"' - {} \;
if [ -e cmake/xrpl_add_test.cmake ]; then
mv cmake/xrpl_add_test.cmake cmake/XrplAddTest.cmake
fi
if [ -e include/xrpl/proto/ripple.proto ]; then
mv include/xrpl/proto/ripple.proto include/xrpl/proto/xrpl.proto
fi
@@ -57,6 +60,7 @@ find cmake -type f -name '*.cmake' | while read -r FILE; do
done
${SED_COMMAND} -i -E 's/Rippled?/Xrpl/g' CMakeLists.txt
${SED_COMMAND} -i 's/ripple/xrpl/g' CMakeLists.txt
${SED_COMMAND} -i 's/include(xrpl_add_test)/include(XrplAddTest)/' src/tests/libxrpl/CMakeLists.txt
${SED_COMMAND} -i 's/ripple.pb.h/xrpl.pb.h/' include/xrpl/protocol/messages.h
${SED_COMMAND} -i 's/ripple.pb.h/xrpl.pb.h/' BUILD.md
${SED_COMMAND} -i 's/ripple.pb.h/xrpl.pb.h/' BUILD.md

View File

@@ -1,281 +1,384 @@
#!/usr/bin/env python3
import argparse
import dataclasses
import itertools
import json
from dataclasses import dataclass
from pathlib import Path
THIS_DIR = Path(__file__).parent.resolve()
_BASE_CMAKE_ARGS = ["-Dtests=ON", "-Dwerr=ON", "-Dxrpld=ON", "-Dwextra=ON"]
# Maps sanitizer names (as used in cmake) to short config-name suffixes.
_SANITIZER_SUFFIX: dict[str, str] = {
"address": "asan",
"undefinedbehavior": "ubsan",
"thread": "tsan",
}
def get_cmake_args(build_type: str, extra_args: str) -> str:
"""Get the full list of CMake arguments for a config."""
args = _BASE_CMAKE_ARGS.copy()
if build_type == "Release":
args.append("-Dassert=ON")
if extra_args:
args.extend(extra_args.split())
return " ".join(args)
# ---------------------------------------------------------------------------
# Input types — shapes of the JSON config files
# ---------------------------------------------------------------------------
@dataclasses.dataclass
class LinuxConfig:
"""One entry in linux.json's 'configs' or 'package_configs' arrays."""
compiler: list[str]
@dataclass
class Config:
architecture: list[dict]
os: list[dict]
build_type: list[str]
arch: list[str]
sanitizers: list[str] = dataclasses.field(default_factory=list)
suffix: str = ""
extra_cmake_args: str = ""
image: str = "" # only used by package_configs entries
cmake_args: list[str]
@dataclasses.dataclass
class LinuxFile:
"""Shape of linux.json."""
"""
Generate a strategy matrix for GitHub Actions CI.
image_tag: str
configs: dict[str, list[LinuxConfig]] # distro → configs
package_configs: dict[str, list[LinuxConfig]] # distro → packaging configs
On each PR commit we will build a selection of Debian, RHEL, Ubuntu, MacOS, and
Windows configurations, while upon merge into the develop or release branches,
we will build all configurations, and test most of them.
@classmethod
def load(cls, path: Path) -> "LinuxFile":
data = json.loads(path.read_text())
def parse(section: dict) -> dict[str, list[LinuxConfig]]:
return {
distro: [LinuxConfig(**c) for c in cfgs]
for distro, cfgs in section.items()
}
return cls(
image_tag=data["image_tag"],
configs=parse(data["configs"]),
package_configs=parse(data.get("package_configs", {})),
)
We will further set additional CMake arguments as follows:
- All builds will have the `tests`, `werr`, and `xrpld` options.
- All builds will have the `wextra` option except for GCC 12 and Clang 16.
- All release builds will have the `assert` option.
- Certain Debian Bookworm configurations will change the reference fee, enable
codecov, and enable voidstar in PRs.
"""
@dataclasses.dataclass
class PlatformConfig:
"""One entry in macos.json's or windows.json's 'configs' array."""
build_type: list[str]
build_only: bool = False # if true, skip tests (e.g. macos/Windows Debug)
extra_cmake_args: str = ""
def __post_init__(self) -> None:
if isinstance(self.build_type, str):
self.build_type = [self.build_type]
def build_config_name(os_entry: dict[str, str], platform: str, build_type: str) -> str:
parts = [os_entry["distro_name"]]
for key in ("distro_version", "compiler_name", "compiler_version"):
if value := os_entry[key]:
parts.append(value)
parts.append("arm64" if "arm64" in platform else "amd64")
parts.append(build_type.lower())
return "-".join(parts)
@dataclasses.dataclass
class PlatformFile:
"""Shape of macos.json and windows.json."""
platform: str # e.g. "macos/arm64" or "windows/amd64"
runner: list[str] # GitHub Actions runner labels
configs: list[PlatformConfig]
@classmethod
def load(cls, path: Path) -> "PlatformFile":
data = json.loads(path.read_text())
return cls(
platform=data["platform"],
runner=data["runner"],
configs=[PlatformConfig(**c) for c in data["configs"]],
)
# ---------------------------------------------------------------------------
# Output types — shapes of the generated GitHub Actions matrix entries
# ---------------------------------------------------------------------------
@dataclasses.dataclass
class Architecture:
platform: str
runner: list[str]
@dataclasses.dataclass
class MatrixEntry:
"""One entry in the generated build/test strategy matrix."""
config_name: str
cmake_args: str
cmake_target: str
build_only: bool
build_type: str
architecture: Architecture
sanitizers: str
image: str = "" # container image; empty for macOS/Windows (runs natively)
compiler: str = "" # compiler name ("gcc" or "clang"); empty for macOS/Windows
@dataclasses.dataclass
class PackagingEntry:
"""One entry in the generated packaging strategy matrix."""
artifact_name: str
image: str
distro: str # e.g. "debian" or "rhel"; drives package-format-specific steps
# ---------------------------------------------------------------------------
# Matrix expansion
# ---------------------------------------------------------------------------
_ARCHS: dict[str, Architecture] = {
"amd64": Architecture(
platform="linux/amd64", runner=["self-hosted", "Linux", "X64", "heavy"]
),
"arm64": Architecture(
platform="linux/arm64",
runner=["self-hosted", "Linux", "ARM64", "heavy-arm64"],
),
}
def expand_linux_matrix(linux: LinuxFile) -> list[MatrixEntry]:
"""Expand a LinuxFile into a flat list of matrix entries.
Each config entry is expanded over the cross-product of its
compiler, build_type, sanitizers, and architecture lists.
def generate_packaging_matrix(config: Config) -> list[dict]:
"""Emit one entry per os entry with `package: true`. Architecture is
hardcoded to linux/amd64 here (and the runner is hardcoded at the
workflow level) until arm64 packaging is ready.
"""
entries: list[MatrixEntry] = []
return [
{
"artifact_name": f"xrpld-{build_config_name(os, 'linux/amd64', 'Release')}",
"os": os,
}
for os in config.os
if os.get("package", False)
]
for distro, configs in linux.configs.items():
for cfg in configs:
# An empty sanitizers list means "one entry with no sanitizer".
effective_sanitizers = cfg.sanitizers or [""]
effective_archs = {arch: _ARCHS[arch] for arch in cfg.arch}
for compiler, build_type, sanitizer, (arch, arch_info) in itertools.product(
cfg.compiler,
cfg.build_type,
effective_sanitizers,
effective_archs.items(),
def generate_strategy_matrix(all: bool, config: Config) -> list[dict]:
configurations = []
for architecture, os, build_type, cmake_args in itertools.product(
config.architecture, config.os, config.build_type, config.cmake_args
):
# The default CMake target is 'all' for Linux and MacOS and 'install'
# for Windows, but it can get overridden for certain configurations.
cmake_target = "install" if os["distro_name"] == "windows" else "all"
# We build and test all configurations by default, except for Windows in
# Debug, because it is too slow, as well as when code coverage is
# enabled as that mode already runs the tests.
build_only = False
if os["distro_name"] == "windows" and build_type == "Debug":
build_only = True
# Only generate a subset of configurations in PRs.
if not all:
# Debian:
# - Bookworm using GCC 13: Debug on linux/amd64, set the reference
# fee to 500 and enable code coverage (which will be done below).
# - Bookworm using GCC 15: Debug on linux/amd64, enable Address and
# UB sanitizers (which will be done below).
# - Bookworm using Clang 16: Debug on linux/amd64, enable voidstar.
# - Bookworm using Clang 17: Release on linux/amd64, set the
# reference fee to 1000.
# - Bookworm using Clang 20: Debug on linux/amd64, enable Address
# and UB sanitizers (which will be done below).
if os["distro_name"] == "debian":
skip = True
if os["distro_version"] == "bookworm":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}"
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
and build_type == "Release"
and architecture["platform"] == "linux/amd64"
):
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-16"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"-Dvoidstar=ON {cmake_args}"
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-17"
and build_type == "Release"
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=1000 {cmake_args}"
skip = False
elif os["distro_version"] == "trixie":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-22"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
skip = False
if skip:
continue
# RHEL:
# - 9 using GCC 12: Debug and Release on linux/amd64
# (Release is required for RPM packaging).
# - 10 using Clang: Release on linux/amd64.
if os["distro_name"] == "rhel":
skip = True
if os["distro_version"] == "9":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type in ["Debug", "Release"]
and architecture["platform"] == "linux/amd64"
):
skip = False
elif os["distro_version"] == "10":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-any"
and build_type == "Release"
and architecture["platform"] == "linux/amd64"
):
skip = False
if skip:
continue
# Ubuntu:
# - Jammy using GCC 12: Debug on linux/arm64, Release on
# linux/amd64 (Release is required for DEB packaging).
# - Noble using GCC 14: Release on linux/amd64.
# - Noble using Clang 18: Debug on linux/amd64.
# - Noble using Clang 19: Release on linux/arm64.
if os["distro_name"] == "ubuntu":
skip = True
if os["distro_version"] == "jammy":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type == "Debug"
and architecture["platform"] == "linux/arm64"
):
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type == "Release"
and architecture["platform"] == "linux/amd64"
):
skip = False
elif os["distro_version"] == "noble":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-14"
and build_type == "Release"
and architecture["platform"] == "linux/amd64"
):
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-18"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-19"
and build_type == "Release"
and architecture["platform"] == "linux/arm64"
):
skip = False
if skip:
continue
# MacOS:
# - Debug on macos/arm64.
if os["distro_name"] == "macos" and not (
build_type == "Debug" and architecture["platform"] == "macos/arm64"
):
name = f"{distro}-{compiler}-{build_type.lower()}-{arch}"
suffix_parts = [
s for s in [cfg.suffix, _SANITIZER_SUFFIX.get(sanitizer, "")] if s
]
if suffix_parts:
name += "-" + "-".join(suffix_parts)
continue
entries.append(
MatrixEntry(
config_name=name,
image=f"ghcr.io/xrplf/xrpld/nix-{distro}:{linux.image_tag}",
cmake_args=get_cmake_args(build_type, cfg.extra_cmake_args),
cmake_target="all",
build_only=False,
build_type=build_type,
architecture=arch_info,
sanitizers=sanitizer,
compiler=compiler,
)
)
# Windows:
# - Release on windows/amd64.
if os["distro_name"] == "windows" and not (
build_type == "Release" and architecture["platform"] == "windows/amd64"
):
continue
return entries
# Additional CMake arguments.
cmake_args = f"{cmake_args} -Dtests=ON -Dwerr=ON -Dxrpld=ON"
if not f"{os['compiler_name']}-{os['compiler_version']}" in [
"gcc-12",
"clang-16",
]:
cmake_args = f"{cmake_args} -Dwextra=ON"
if build_type == "Release":
cmake_args = f"{cmake_args} -Dassert=ON"
# We skip all RHEL on arm64 due to a build failure that needs further
# investigation.
if os["distro_name"] == "rhel" and architecture["platform"] == "linux/arm64":
continue
def expand_linux_packaging(linux: LinuxFile) -> list[PackagingEntry]:
"""Generate the packaging matrix from a LinuxFile's package_configs section.
# We skip all clang 20+ on arm64 due to Boost build error.
if (
os["compiler_name"] == "clang"
and os["compiler_version"].isdigit()
and int(os["compiler_version"]) >= 20
and architecture["platform"] == "linux/arm64"
):
continue
Packaging uses vanilla distro images (debian:bookworm, ubi9, …) instead of
the nix-based build images, because deb/rpm tooling (debhelper, rpm-build)
is taken from the distro's archive rather than from nixpkgs. Each config
entry carries its own 'image'.
"""
entries = []
for distro, configs in linux.package_configs.items():
for cfg in configs:
for compiler, build_type in itertools.product(cfg.compiler, cfg.build_type):
entries.append(
PackagingEntry(
artifact_name=f"xrpld-{distro}-{compiler}-{build_type.lower()}-amd64",
image=cfg.image,
distro=distro,
)
)
# Enable code coverage for Debian Bookworm using GCC 13 in Debug on
# linux/amd64.
if (
f"{os['distro_name']}-{os['distro_version']}" == "debian-bookworm"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"{cmake_args} -Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0"
return entries
# Enable unity build for Ubuntu Jammy using GCC 12 in Debug on
# linux/amd64.
if (
f"{os['distro_name']}-{os['distro_version']}" == "ubuntu-jammy"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"{cmake_args} -Dunity=ON"
# Generate a unique name for the configuration, e.g. macos-arm64-debug
# or debian-bookworm-gcc-12-amd64-release.
config_name = build_config_name(os, architecture["platform"], build_type)
if "-Dcoverage=ON" in cmake_args:
config_name += "-coverage"
if "-Dunity=ON" in cmake_args:
config_name += "-unity"
def expand_platform_matrix(pf: PlatformFile) -> list[MatrixEntry]:
"""Expand a PlatformFile (macOS or Windows) into matrix entries."""
platform_name, arch = pf.platform.split("/")
is_windows = platform_name == "windows"
entries: list[MatrixEntry] = []
for cfg in pf.configs:
for build_type in cfg.build_type:
entries.append(
MatrixEntry(
config_name=f"{platform_name}-{arch}-{build_type.lower()}",
cmake_args=get_cmake_args(build_type, cfg.extra_cmake_args),
cmake_target="install" if is_windows else "all",
build_only=cfg.build_only,
build_type=build_type,
architecture=Architecture(platform=pf.platform, runner=pf.runner),
sanitizers="",
)
# Add the configuration to the list, with the most unique fields first,
# so that they are easier to identify in the GitHub Actions UI, as long
# names get truncated.
# Add Address and UB sanitizers as separate configurations for specific
# bookworm distros. Thread sanitizer is currently disabled (see below).
# GCC-Asan xrpld-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
if (
os["distro_version"] == "bookworm"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
) or (
os["distro_version"] == "trixie"
and f"{os['compiler_name']}-{os['compiler_version']}" == "clang-22"
):
# Add ASAN and UBSAN configurations for both gcc-15 and clang-22
configurations.append(
{
"config_name": config_name + "-asan",
"cmake_args": cmake_args,
"cmake_target": cmake_target,
"build_only": build_only,
"build_type": build_type,
"os": os,
"architecture": architecture,
"sanitizers": "address",
}
)
return entries
configurations.append(
{
"config_name": config_name + "-ubsan",
"cmake_args": cmake_args,
"cmake_target": cmake_target,
"build_only": build_only,
"build_type": build_type,
"os": os,
"architecture": architecture,
"sanitizers": "undefinedbehavior",
}
)
# TSAN is deactivated due to seg faults with latest compilers.
activate_tsan = False
if activate_tsan:
configurations.append(
{
"config_name": config_name + "-tsan-ubsan",
"cmake_args": cmake_args,
"cmake_target": cmake_target,
"build_only": build_only,
"build_type": build_type,
"os": os,
"architecture": architecture,
"sanitizers": "thread,undefinedbehavior",
}
)
else:
configurations.append(
{
"config_name": config_name,
"cmake_args": cmake_args,
"cmake_target": cmake_target,
"build_only": build_only,
"build_type": build_type,
"os": os,
"architecture": architecture,
"sanitizers": "",
}
)
return configurations
# ---------------------------------------------------------------------------
# Entry point
# ---------------------------------------------------------------------------
def read_config(file: Path) -> Config:
config = json.loads(file.read_text())
if (
config["architecture"] is None
or config["os"] is None
or config["build_type"] is None
or config["cmake_args"] is None
):
raise Exception("Invalid configuration file.")
return Config(**config)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Generate a CI strategy matrix for all platforms or a specific one."
parser = argparse.ArgumentParser()
parser.add_argument(
"-a",
"--all",
help="Set to generate all configurations (generally used when merging a PR) or leave unset to generate a subset of configurations (generally used when committing to a PR).",
action="store_true",
)
parser.add_argument(
"-c",
"--config",
help="Platform to generate for ('linux', 'macos', or 'windows'). Defaults to all platforms.",
choices=["linux", "macos", "windows"],
default=None,
help="Path to the JSON file containing the strategy matrix configurations.",
required=False,
type=Path,
)
parser.add_argument(
"-p",
"--packaging",
help="Emit the Linux packaging matrix instead of the build/test matrix.",
help="Emit the packaging matrix (derived from the 'package' field on os entries) instead of the build/test matrix.",
action="store_true",
)
args = parser.parse_args()
matrix: list[MatrixEntry] | list[PackagingEntry] = []
matrix = []
if args.packaging:
matrix = expand_linux_packaging(LinuxFile.load(THIS_DIR / "linux.json"))
config_path = args.config if args.config else THIS_DIR / "linux.json"
matrix += generate_packaging_matrix(read_config(config_path))
elif args.config is None or args.config == "":
matrix += generate_strategy_matrix(
args.all, read_config(THIS_DIR / "linux.json")
)
matrix += generate_strategy_matrix(
args.all, read_config(THIS_DIR / "macos.json")
)
matrix += generate_strategy_matrix(
args.all, read_config(THIS_DIR / "windows.json")
)
else:
if args.config in ("linux", None):
matrix += expand_linux_matrix(LinuxFile.load(THIS_DIR / "linux.json"))
if args.config in ("macos", None):
matrix += expand_platform_matrix(PlatformFile.load(THIS_DIR / "macos.json"))
if args.config in ("windows", None):
matrix += expand_platform_matrix(
PlatformFile.load(THIS_DIR / "windows.json")
)
matrix += generate_strategy_matrix(args.all, read_config(args.config))
print(f"matrix={json.dumps({'include': [dataclasses.asdict(e) for e in matrix]})}")
# Generate the strategy matrix.
print(f"matrix={json.dumps({'include': matrix})}")

View File

@@ -1,83 +1,221 @@
{
"image_tag": "sha-8abe82e",
"configs": {
"ubuntu": [
{
"compiler": ["gcc", "clang"],
"build_type": ["Debug", "Release"],
"arch": ["amd64", "arm64"]
},
{
"compiler": ["gcc", "clang"],
"build_type": ["Debug"],
"arch": ["amd64"],
"sanitizers": ["address", "undefinedbehavior"]
},
{
"compiler": ["gcc"],
"build_type": ["Debug"],
"arch": ["amd64"],
"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"],
"arch": ["amd64"],
"suffix": "voidstar",
"extra_cmake_args": "-Dvoidstar=ON"
},
{
"compiler": ["clang"],
"build_type": ["Release"],
"arch": ["amd64"],
"suffix": "reffee",
"extra_cmake_args": "-DUNIT_TEST_REFERENCE_FEE=1000"
},
{
"compiler": ["gcc"],
"build_type": ["Debug"],
"arch": ["amd64"],
"suffix": "unity",
"extra_cmake_args": "-Dunity=ON"
}
],
"debian": [
{
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["amd64"]
}
],
"rhel": [
{
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["amd64"]
}
]
},
"package_configs": {
"debian": [
{
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["amd64"],
"image": "debian:bookworm"
}
],
"rhel": [
{
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["amd64"],
"image": "registry.access.redhat.com/ubi9/ubi:latest"
}
]
}
"architecture": [
{
"platform": "linux/amd64",
"runner": ["self-hosted", "Linux", "X64", "heavy"]
},
{
"platform": "linux/arm64",
"runner": ["self-hosted", "Linux", "ARM64", "heavy-arm64"]
}
],
"os": [
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "15",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "16",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "17",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "18",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "19",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "20",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "gcc",
"compiler_version": "15",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "20",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "21",
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "22",
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "8",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "8",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "4c086b9",
"package": true
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "jammy",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "4c086b9",
"package": true
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "16",
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "17",
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "18",
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "19",
"image_sha": "4c086b9"
}
],
"build_type": ["Debug", "Release"],
"cmake_args": [""]
}

View File

@@ -1,15 +1,19 @@
{
"platform": "macos/arm64",
"runner": ["self-hosted", "macOS", "ARM64", "mac-runner-m1"],
"configs": [
"architecture": [
{
"build_type": "Release",
"extra_cmake_args": "-DCMAKE_POLICY_VERSION_MINIMUM=3.5"
},
{
"build_type": "Debug",
"extra_cmake_args": "-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
"build_only": true
"platform": "macos/arm64",
"runner": ["self-hosted", "macOS", "ARM64", "mac-runner-m1"]
}
]
],
"os": [
{
"distro_name": "macos",
"distro_version": "",
"compiler_name": "",
"compiler_version": "",
"image_sha": ""
}
],
"build_type": ["Debug", "Release"],
"cmake_args": ["-DCMAKE_POLICY_VERSION_MINIMUM=3.5"]
}

View File

@@ -1,8 +1,19 @@
{
"platform": "windows/amd64",
"runner": ["self-hosted", "Windows", "devbox"],
"configs": [
{ "build_type": "Release" },
{ "build_type": "Debug", "build_only": true }
]
"architecture": [
{
"platform": "windows/amd64",
"runner": ["self-hosted", "Windows", "devbox"]
}
],
"os": [
{
"distro_name": "windows",
"distro_version": "",
"compiler_name": "",
"compiler_version": "",
"image_sha": ""
}
],
"build_type": ["Debug", "Release"],
"cmake_args": [""]
}

109
.github/workflows/build-nix-image.yml vendored Normal file
View File

@@ -0,0 +1,109 @@
name: Build Nix Docker image
on:
push:
branches:
- develop
paths:
- ".github/workflows/build-nix-image.yml"
- ".github/workflows/reusable-build-docker-image.yml"
- "docker/**"
- "flake.nix"
- "flake.lock"
- "nix/**"
pull_request:
paths:
- ".github/workflows/build-nix-image.yml"
- ".github/workflows/reusable-build-docker-image.yml"
- "docker/**"
- "flake.nix"
- "flake.lock"
- "nix/**"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
build:
name: Build ${{ matrix.distro.name }} (${{ matrix.target.platform }})
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
# The base images are the oldest supported version of each distro
# that we want to build images for.
distro:
- name: nixos
base_image: nixos/nix:latest
- name: ubuntu
base_image: ubuntu:20.04
- name: rhel
base_image: registry.access.redhat.com/ubi9/ubi:latest
- name: debian
base_image: debian:bookworm
target:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
uses: ./.github/workflows/reusable-build-docker-image.yml
with:
image_name: ghcr.io/xrplf/xrpld/nix-${{ matrix.distro.name }}
dockerfile: docker/nix.Dockerfile
base_image: ${{ matrix.distro.base_image }}
platform: ${{ matrix.target.platform }}
runner: ${{ matrix.target.runner }}
push: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' }}
merge:
name: Merge ${{ matrix.distro }} manifest
needs: build
if: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
distro: [nixos, ubuntu, rhel, debian]
env:
IMAGE_NAME: ghcr.io/xrplf/xrpld/nix-${{ matrix.distro }}
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Docker metadata
id: meta
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
with:
images: ${{ env.IMAGE_NAME }}
tags: |
type=sha,prefix=sha-,format=short
type=raw,value=latest
- name: Login to GitHub Container Registry
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create multi-arch manifests
run: |
for tag in $(jq -cr '.tags[]' <<<"$DOCKER_METADATA_OUTPUT_JSON"); do
docker buildx imagetools create -t "$tag" "${tag}-amd64" "${tag}-arm64"
done
- name: Inspect image
run: |
docker buildx imagetools inspect "${IMAGE_NAME}:${{ steps.meta.outputs.version }}"

View File

@@ -1,56 +0,0 @@
name: Build Nix Docker images
on:
push:
branches:
- develop
paths:
- ".github/workflows/build-nix-images.yml"
- ".github/workflows/reusable-build-docker-image.yml"
- ".github/workflows/reusable-build-merge-docker-images.yml"
- "flake.nix"
- "flake.lock"
- "nix/**"
pull_request:
paths:
- ".github/workflows/build-nix-images.yml"
- ".github/workflows/reusable-build-docker-image.yml"
- ".github/workflows/reusable-build-merge-docker-images.yml"
- "flake.nix"
- "flake.lock"
- "nix/**"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
build-merge:
name: Build and push nix-${{ matrix.distro.name }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
# The base images are the oldest supported version of each distro
# that we want to build images for.
distro:
- name: nixos
base_image: nixos/nix:latest
- name: ubuntu
base_image: ubuntu:20.04
- name: debian
base_image: debian:bookworm
- name: rhel
base_image: registry.access.redhat.com/ubi9/ubi:latest
uses: ./.github/workflows/reusable-build-merge-docker-images.yml
with:
image_name: ghcr.io/xrplf/xrpld/nix-${{ matrix.distro.name }}
dockerfile: nix/docker/Dockerfile
base_image: ${{ matrix.distro.base_image }}

View File

@@ -1,48 +0,0 @@
name: Build packaging Docker images
on:
push:
branches:
- develop
paths:
- ".github/workflows/build-packaging-images.yml"
- ".github/workflows/reusable-build-docker-image.yml"
- ".github/workflows/reusable-build-merge-docker-images.yml"
- "package/Dockerfile"
- "package/install-packaging-tools.sh"
pull_request:
paths:
- ".github/workflows/build-packaging-images.yml"
- ".github/workflows/reusable-build-docker-image.yml"
- ".github/workflows/reusable-build-merge-docker-images.yml"
- "package/Dockerfile"
- "package/install-packaging-tools.sh"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
build-merge:
name: Build and push packaging-${{ matrix.distro.name }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
distro:
- name: debian
base_image: debian:bookworm
- name: rhel
base_image: registry.access.redhat.com/ubi9/ubi:latest
uses: ./.github/workflows/reusable-build-merge-docker-images.yml
with:
image_name: ghcr.io/xrplf/xrpld/packaging-${{ matrix.distro.name }}
dockerfile: package/Dockerfile
base_image: ${{ matrix.distro.base_image }}

View File

@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Write PR body to file
env:

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check if PRs are dirty
uses: eps1lon/actions-label-merge-conflict@0273be72a0bbd58fcd71d0d6c02c209b50d1e5e1 # v3.1.0
uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3
with:
dirtyLabel: "PR: has conflicts"
repoToken: "${{ secrets.GITHUB_TOKEN }}"

View File

@@ -33,7 +33,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- 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

View File

@@ -33,6 +33,7 @@ jobs:
with:
ccache_enabled: false
os: ${{ matrix.os }}
strategy_matrix: minimal
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -88,6 +88,7 @@ jobs:
# not identical to a regular compilation.
ccache_enabled: ${{ github.repository_owner == 'XRPLF' && !startsWith(github.ref, 'refs/heads/release') }}
os: ${{ matrix.os }}
strategy_matrix: ${{ github.event_name == 'schedule' && 'all' || 'minimal' }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -41,10 +41,10 @@ env:
jobs:
build:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-8abe82e
container: ghcr.io/xrplf/ci/tools-rippled-documentation:sha-a8c7be1
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
@@ -57,11 +57,19 @@ jobs:
with:
subtract: ${{ env.NPROC_SUBTRACT }}
- name: Print build environment
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
- name: Check configuration
run: |
echo 'Checking path.'
echo ${PATH} | tr ':' '\n'
- name: Check Doxygen version
run: doxygen --version
echo 'Checking environment variables.'
env | sort
echo 'Checking CMake version.'
cmake --version
echo 'Checking Doxygen version.'
doxygen --version
- name: Build documentation
env:

View File

@@ -38,7 +38,7 @@ defaults:
jobs:
build:
name: Build ${{ inputs.platform }}
name: Build (${{ inputs.platform }})
runs-on: ${{ inputs.runner }}
permissions:
contents: read
@@ -46,7 +46,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Determine arch
id: vars

View File

@@ -1,89 +0,0 @@
name: Reusable build and merge Docker image (multi-arch)
on:
workflow_call:
inputs:
image_name:
description: "Full image name without tag (e.g. 'ghcr.io/xrplf/xrpld/nix-ubuntu')"
required: true
type: string
dockerfile:
description: "Path to the Dockerfile, relative to the repository root"
required: true
type: string
base_image:
description: "Value passed to the Dockerfile as the BASE_IMAGE build arg"
required: true
type: string
defaults:
run:
shell: bash
jobs:
build:
name: Build ${{ inputs.image_name }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
target:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
uses: ./.github/workflows/reusable-build-docker-image.yml
with:
image_name: ${{ inputs.image_name }}
dockerfile: ${{ inputs.dockerfile }}
base_image: ${{ inputs.base_image }}
platform: ${{ matrix.target.platform }}
runner: ${{ matrix.target.runner }}
push: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' }}
merge:
name: Merge ${{ inputs.image_name }}
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Docker metadata
id: meta
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
with:
images: ${{ inputs.image_name }}
tags: |
type=sha,prefix=sha-,format=short
type=raw,value=latest
- name: Login to GitHub Container Registry
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create multi-arch manifests
if: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' }}
run: |
for tag in $(jq -cr '.tags[]' <<<"$DOCKER_METADATA_OUTPUT_JSON"); do
docker buildx imagetools create -t "$tag" "${tag}-amd64" "${tag}-arm64"
done
- name: Inspect image
if: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' }}
env:
IMAGE_NAME: ${{ inputs.image_name }}
IMAGE_VERSION: ${{ steps.meta.outputs.version }}
run: |
docker buildx imagetools inspect "${IMAGE_NAME}:${IMAGE_VERSION}"

View File

@@ -57,12 +57,6 @@ on:
type: string
default: ""
compiler:
description: 'The compiler to use ("gcc" or "clang"). Leave empty for macOS/Windows (uses system default).'
required: false
type: string
default: ""
secrets:
CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports."
@@ -110,7 +104,7 @@ jobs:
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
@@ -130,12 +124,6 @@ jobs:
with:
subtract: ${{ inputs.nproc_subtract }}
- name: Set compiler environment (Linux)
if: ${{ runner.os == 'Linux' }}
uses: ./.github/actions/set-compiler-env
with:
compiler: ${{ inputs.compiler }}
- name: Setup Conan
env:
SANITIZERS: ${{ inputs.sanitizers }}
@@ -203,21 +191,6 @@ jobs:
--parallel "${BUILD_NPROC}" \
--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
if: ${{ inputs.ccache_enabled }}
run: |
@@ -236,15 +209,6 @@ jobs:
retention-days: 3
if-no-files-found: error
- name: Upload the test binary (Linux)
if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: xrpl_tests-${{ inputs.config_name }}
path: ${{ env.BUILD_DIR }}/xrpl_tests
retention-days: 3
if-no-files-found: error
- name: Export server definitions
if: ${{ runner.os != 'Windows' && !inputs.build_only && env.VOIDSTAR_ENABLED != 'true' }}
working-directory: ${{ env.BUILD_DIR }}
@@ -253,7 +217,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 == 'debian-bookworm-gcc-13-amd64-release' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: server-definitions
@@ -295,8 +259,16 @@ jobs:
- name: Run the separate tests
if: ${{ !inputs.build_only }}
working-directory: ${{ runner.os == 'Windows' && format('{0}/{1}', env.BUILD_DIR, inputs.build_type) || env.BUILD_DIR }}
run: ./xrpl_tests
working-directory: ${{ env.BUILD_DIR }}
# Windows locks some of the build files while running tests, and parallel jobs can collide
env:
BUILD_TYPE: ${{ inputs.build_type }}
PARALLELISM: ${{ runner.os == 'Windows' && '1' || steps.nproc.outputs.nproc }}
run: |
ctest \
--output-on-failure \
-C "${BUILD_TYPE}" \
-j "${PARALLELISM}"
- name: Run the embedded tests
if: ${{ !inputs.build_only }}
@@ -307,25 +279,7 @@ jobs:
set -o pipefail
# Coverage builds are slower due to instrumentation; use fewer parallel jobs to avoid flakiness
[ "$COVERAGE_ENABLED" = "true" ] && BUILD_NPROC=$((BUILD_NPROC - 2))
# The resolver/preload workaround is only correct for the ASan build:
# a regular build doesn't hit the __dn_expand interceptor bug, and must
# NOT have libasan injected. So only preload when xrpld is ASan-built.
#
# libresolv hosts getaddrinfo's resolver helpers (dn_expand, res_*). Under ASan
# these are intercepted via dlsym(RTLD_NEXT, ...), which yields a NULL pointer
# and crashes DNS resolution if libresolv isn't loaded. Linking it guarantees
# the symbols are present; it's a harmless no-op on glibc >= 2.34 (merged into
# libc) and is what the compiler driver already does for sanitizer builds.
# https://github.com/llvm/llvm-project/issues/59007
# https://github.com/google/sanitizers/issues/1592
if ldd ./xrpld | grep -q libasan; then
PRELOAD="$(gcc -print-file-name=libasan.so):/usr/lib/x86_64-linux-gnu/libresolv.so.2"
else
PRELOAD=""
fi
LD_PRELOAD="$PRELOAD" ./xrpld --unittest --unittest-jobs "${BUILD_NPROC}" 2>&1 | tee unittest.log
./xrpld --unittest --unittest-jobs "${BUILD_NPROC}" 2>&1 | tee unittest.log
- name: Show test failure summary
if: ${{ failure() && !inputs.build_only }}

View File

@@ -19,6 +19,13 @@ on:
required: true
type: string
strategy_matrix:
# TODO: Support additional strategies, e.g. "ubuntu" for generating all Ubuntu configurations.
description: 'The strategy matrix to use for generating the configurations ("minimal", "all").'
required: false
type: string
default: "minimal"
secrets:
CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports."
@@ -30,6 +37,7 @@ jobs:
uses: ./.github/workflows/reusable-strategy-matrix.yml
with:
os: ${{ inputs.os }}
strategy_matrix: ${{ inputs.strategy_matrix }}
# Build and test the binary for each configuration.
build-test-config:
@@ -39,6 +47,7 @@ jobs:
strategy:
fail-fast: ${{ github.event_name == 'merge_group' }}
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
max-parallel: 10
with:
build_only: ${{ matrix.build_only }}
build_type: ${{ matrix.build_type }}
@@ -46,9 +55,8 @@ jobs:
cmake_args: ${{ matrix.cmake_args }}
cmake_target: ${{ matrix.cmake_target }}
runs_on: ${{ toJSON(matrix.architecture.runner) }}
image: ${{ matrix.image || '' }}
image: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-{4}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version, matrix.os.image_sha) || '' }}
config_name: ${{ matrix.config_name }}
sanitizers: ${{ matrix.sanitizers }}
compiler: ${{ matrix.compiler || '' }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check levelization
run: python .github/scripts/levelization/generate.py
- name: Check for differences

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check definitions
run: .github/scripts/rename/definitions.sh .
- name: Check copyright notices

View File

@@ -36,13 +36,13 @@ jobs:
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') }}
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-8abe82e"
container: "ghcr.io/xrplf/ci/debian-trixie:clang-21-sha-53033a2"
permissions:
contents: read
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
@@ -56,11 +56,6 @@ jobs:
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf
id: nproc
- name: Set compiler environment
uses: ./.github/actions/set-compiler-env
with:
compiler: clang
- name: Setup Conan
uses: ./.github/actions/setup-conan

View File

@@ -1,7 +1,8 @@
# Build Linux packages (DEB and RPM) from pre-built binary artifacts.
# Discovers which configurations to package from linux.json (configs in
# "package_configs") and fans out one job per distro. Only linux/amd64 is
# supported; the runner is hardcoded in the job below.
# Discovers which configurations to package from linux.json (os entries
# with "package": true) and fans out one job per entry. Today only
# linux/amd64 is emitted; the architecture is hardcoded both here
# (runner) and in generate.py.
name: Package
on:
@@ -27,17 +28,18 @@ jobs:
matrix: ${{ steps.generate.outputs.matrix }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.13"
python-version: 3.13
- name: Generate packaging matrix
id: generate
working-directory: .github/scripts/strategy-matrix
run: ./generate.py --packaging >>"${GITHUB_OUTPUT}"
run: |
./generate.py --packaging --config=linux.json >>"${GITHUB_OUTPUT}"
generate-version:
runs-on: ubuntu-latest
@@ -45,7 +47,7 @@ jobs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout: |
.github/actions/generate-version
@@ -64,37 +66,12 @@ jobs:
permissions:
contents: read
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: ${{ matrix.image }}
container: ${{ format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-{4}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version, matrix.os.image_sha) }}
timeout-minutes: 30
steps:
# Packaging runs in a vanilla distro image, so the tooling has to come
# from the distro's archive: debhelper for deb, rpm-build (and the
# systemd / find-debuginfo macros it depends on) for rpm. Run this
# before actions/checkout so the latter can use git (real history) for
# build_pkg.sh's SOURCE_DATE_EPOCH; otherwise it falls back to a tarball
# download and the timestamp comes from wall-clock time.
- name: Install packaging tooling (deb)
if: ${{ matrix.distro == 'debian' }}
run: |
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends \
ca-certificates \
debhelper \
git
- name: Install packaging tooling (rpm)
if: ${{ matrix.distro == 'rhel' }}
run: |
dnf install -y --setopt=install_weak_deps=False \
git \
rpm-build \
redhat-rpm-config \
systemd-rpm-macros
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Download pre-built binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1

View File

@@ -4,9 +4,15 @@ on:
workflow_call:
inputs:
os:
description: 'The operating system to use for the build ("linux", "macos", "windows", or empty for all).'
description: 'The operating system to use for the build ("linux", "macos", "windows").'
required: false
type: string
strategy_matrix:
# TODO: Support additional strategies, e.g. "ubuntu" for generating all Ubuntu configurations.
description: 'The strategy matrix to use for generating the configurations ("minimal", "all").'
required: false
type: string
default: "minimal"
outputs:
matrix:
description: "The generated strategy matrix."
@@ -23,16 +29,17 @@ jobs:
matrix: ${{ steps.generate.outputs.matrix }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.13"
python-version: 3.13
- name: Generate strategy matrix
working-directory: .github/scripts/strategy-matrix
id: generate
env:
GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}', inputs.os) || '' }}
run: ./generate.py ${GENERATE_CONFIG} >>"${GITHUB_OUTPUT}"
GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }}
GENERATE_OPTION: ${{ inputs.strategy_matrix == 'all' && '--all' || '' }}
run: ./generate.py ${GENERATE_OPTION} ${GENERATE_CONFIG} >>"${GITHUB_OUTPUT}"

View File

@@ -40,10 +40,10 @@ defaults:
jobs:
upload:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-8abe82e
container: ghcr.io/xrplf/ci/ubuntu-noble:gcc-13-sha-5dd7158
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Generate build version number
id: version

View File

@@ -48,6 +48,8 @@ jobs:
# Generate the strategy matrix to be used by the following job.
generate-matrix:
uses: ./.github/workflows/reusable-strategy-matrix.yml
with:
strategy_matrix: ${{ github.event_name == 'pull_request' && 'minimal' || 'all' }}
# Build and upload the dependencies for each configuration.
run-upload-conan-deps:
@@ -56,15 +58,16 @@ jobs:
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
max-parallel: 10
runs-on: ${{ matrix.architecture.runner }}
container: ${{ matrix.image || null }}
container: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-{4}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version, matrix.os.image_sha) || null }}
steps:
- name: Cleanup workspace (macOS and Windows)
if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }}
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
@@ -80,12 +83,6 @@ jobs:
with:
subtract: ${{ env.NPROC_SUBTRACT }}
- name: Set compiler environment (Linux)
if: ${{ runner.os == 'Linux' }}
uses: ./.github/actions/set-compiler-env
with:
compiler: ${{ matrix.compiler }}
- name: Setup Conan
env:
SANITIZERS: ${{ matrix.sanitizers }}

View File

@@ -953,21 +953,6 @@
#
# Optional keys for NuDB and RocksDB:
#
# cache_size Size of cache for database records. Default is 16384.
# Setting this value to 0 will use the default value.
#
# cache_age Length of time in minutes to keep database records
# cached. Default is 5 minutes. Setting this value to
# 0 will use the default value.
#
# Note: if cache_size or cache_age is not specified,
# default values will be used for the unspecified
# parameter.
#
# Note: the cache will not be created if online_delete
# is specified, because the rotating NodeStore does
# not use this cache).
#
# fast_load Boolean. If set, load the last persisted ledger
# from disk upon process start before syncing to
# the network. This is likely to improve performance

22
cmake/XrplAddTest.cmake Normal file
View File

@@ -0,0 +1,22 @@
include(isolate_headers)
function(xrpl_add_test name)
set(target ${PROJECT_NAME}.test.${name})
file(
GLOB_RECURSE sources
CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp"
)
add_executable(${target} ${ARGN} ${sources})
isolate_headers(
${target}
"${CMAKE_SOURCE_DIR}"
"${CMAKE_SOURCE_DIR}/tests/${name}"
PRIVATE
)
add_test(NAME ${target} COMMAND ${target})
endfunction()

View File

@@ -145,39 +145,13 @@ else()
INTERFACE
-rdynamic
$<$<BOOL:${is_linux}>:-Wl,-z,relro,-z,now,--build-id>
# link to static libc/c++ if:
# * static option set and
# * NOT APPLE (AppleClang does not support static libc/c++)
$<$<AND:$<BOOL:${static}>,$<NOT:$<BOOL:${APPLE}>>>:
# link to static libc/c++ iff: * static option set and * NOT APPLE (AppleClang does not support static
# libc/c++) and * NOT SANITIZERS (sanitizers typically don't work with static libc/c++)
$<$<AND:$<BOOL:${static}>,$<NOT:$<BOOL:${APPLE}>>,$<NOT:$<BOOL:${SANITIZERS_ENABLED}>>>:
-static-libstdc++
-static-libgcc
>
)
# Keep -stdlib=libstdc++ off the compile commands, but preserve it for linking.
#
# Conan turns `compiler.libcxx=libstdc++` into `-stdlib=libstdc++` and puts it in
# CMAKE_CXX_FLAGS, which CMake passes to BOTH compile and link steps. On a normal Clang
# the compile step consumes it while choosing the C++ stdlib include paths. The Nixpkgs
# 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/"
AND is_linux
AND is_clang
AND CMAKE_CXX_FLAGS MATCHES "stdlib=libstdc"
)
string(
REPLACE "-stdlib=libstdc++"
""
CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS}"
)
string(STRIP "${CMAKE_CXX_FLAGS}" CMAKE_CXX_FLAGS)
add_link_options($<$<LINK_LANGUAGE:CXX>:-stdlib=libstdc++>)
endif()
endif()
# Antithesis instrumentation will only be built and deployed using machines running Linux.

View File

@@ -47,7 +47,7 @@ setup_target_for_coverage_gcovr(
"include/xrpl/beast/test"
"include/xrpl/beast/unit_test"
"${CMAKE_BINARY_DIR}/pb-xrpl.libpb"
DEPENDENCIES xrpld xrpl_tests
DEPENDENCIES xrpld xrpl.tests
)
add_code_coverage_to_target(opts INTERFACE)

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a ${name} ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit ${name}(SLE::const_pointer sle)
explicit ${name}(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -168,7 +168,7 @@ ${field['typeData']['setter_type']} ${field['paramName']}${',' if i < len(requir
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
${name}Builder(SLE::const_pointer sle)
${name}Builder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ${tag})
{

View File

@@ -1,8 +1 @@
{% set os = detect_api.detect_os() %}
include(sanitizers)
[conf]
{% if os == "Linux" %}
user.package:libc_version=2.31
tools.info.package_id:confs+=["user.package:libc_version"]
{% endif %}

View File

@@ -50,7 +50,6 @@ words:
- AMMXRP
- amt
- amts
- archs
- asnode
- asynchrony
- attestation
@@ -135,7 +134,6 @@ words:
- iou
- ious
- isrdc
- isystem
- itype
- jemalloc
- jlog

48
docker/check-sanitizers.sh Executable file
View File

@@ -0,0 +1,48 @@
#!/bin/bash
# Sanity-check that the sanitizer runtimes shipped with g++/clang++ work
# end-to-end against the system loader: compile each example with both
# compilers, run it, and confirm the expected diagnostic is emitted.
set -eo pipefail
cpp_files_dir="${1:?usage: $0 <cpp_files_dir>}"
case "$(uname -m)" in
x86_64) loader=/lib64/ld-linux-x86-64.so.2 ;;
aarch64) loader=/lib/ld-linux-aarch64.so.1 ;;
*)
echo "Unsupported arch: $(uname -m)" >&2
exit 1
;;
esac
declare -A sanitize=(
[asan]="-fsanitize=address"
[tsan]="-fsanitize=thread"
[ubsan]="-fsanitize=undefined"
)
declare -A expect=(
[asan]="heap-use-after-free"
[tsan]="data race"
[ubsan]="signed integer overflow"
)
for compiler in g++ clang++; do
for name in asan tsan ubsan; do
bin="/tmp/${name}-${compiler}"
echo "=== Build ${name} with ${compiler} ==="
"$compiler" -std=c++20 -O1 -g ${sanitize[$name]} \
-Wl,--dynamic-linker=$loader \
"${cpp_files_dir}/${name}.cpp" -o "$bin"
echo "=== Run ${name}-${compiler} ==="
output=$("$bin" 2>&1) || true
echo "$output"
echo "$output" | grep -q "${expect[$name]}" ||
{
echo "expected '${expect[$name]}' from $bin"
exit 1
}
rm -f "$bin"
done
done

View File

@@ -2,13 +2,6 @@
#include <cstddef>
#include <iostream>
// Regression test: the compiler-rt sanitizer interface headers must be on the
// include path. A bare on-PATH clang in the Nix CI env doesn't get them
// propagated automatically, so this include would fail to compile with clang++
// if the env isn't wired up correctly. abseil hits the same include during
// sanitizer builds. LeakSanitizer ships with AddressSanitizer.
#include <sanitizer/lsan_interface.h>
#if defined(__clang__) || defined(__GNUC__)
__attribute__((noinline))
#elif defined(_MSC_VER)

95
docker/nix.Dockerfile Normal file
View File

@@ -0,0 +1,95 @@
ARG BASE_IMAGE=nixos/nix:latest
# Nix builder
FROM nixos/nix:latest AS builder-source
RUN mkdir -p ~/.config/nix && \
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
# Copy our source and setup our working dir.
COPY nix/ci-env.nix /tmp/build/nix/ci-env.nix
COPY nix/packages.nix /tmp/build/nix/packages.nix
COPY nix/utils.nix /tmp/build/nix/utils.nix
COPY flake.nix /tmp/build/
COPY flake.lock /tmp/build/
WORKDIR /tmp/build
FROM builder-source AS builder
# Build our Nix CI environment (all build tools in a single store path)
RUN nix \
--option filter-syscalls false \
build
# Copy the Nix store closure into a directory. The Nix store closure is the
# entire set of Nix store values that we need for our build.
RUN mkdir /tmp/nix-store-closure && \
cp -R $(nix-store -qR result/) /tmp/nix-store-closure
# Final image
FROM ${BASE_IMAGE}
# bash is not located at /bin/bash in nixos/nix, so we need to create a symlink to it.
RUN if [ -d /nix ]; then \
ln -s /root/.nix-profile/bin/bash /bin/bash; \
fi
# Use Bash as the default shell for RUN commands, using the options
# `set -o errexit -o pipefail`, and as the entrypoint.
SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]
ENTRYPOINT ["/bin/bash"]
# Copy /nix/store and the env symlink tree
COPY --from=builder /tmp/nix-store-closure /nix/store
COPY --from=builder /tmp/build/result /nix/ci-env
ENV PATH="/nix/ci-env/bin:$PATH"
# Externally-built dynamically-linked ELF binaries hard-code the loader path
# (e.g. /lib64/ld-linux-x86-64.so.2) in their PT_INTERP header. Copy the
# loader from the Nix store to that path when the base image doesn't already
# provide one (i.e. on nixos/nix).
RUN <<EOF
case "$(uname -m)" in
x86_64) target=/lib64/ld-linux-x86-64.so.2 ;;
aarch64) target=/lib/ld-linux-aarch64.so.1 ;;
*) echo "Unsupported arch: $(uname -m)" >&2; exit 1 ;;
esac
if [ ! -e "$target" ]; then
# Use the loader from the same glibc that gcc links libc against, so
# ld-linux and libc/libpthread share GLIBC_PRIVATE symbols at runtime.
src="$(dirname "$(gcc -print-file-name=libc.so.6)")/$(basename "$target")"
[ -e "$src" ] || { echo "ld-linux not found at $src" >&2; exit 1; }
mkdir -p "$(dirname "$target")"
cp "$src" "$target"
fi
EOF
RUN <<EOF
ccache --version
clang --version
clang++ --version
clang-format --version
cmake --version
conan --version
g++ --version
gcc --version
gcovr --version
git --version
make --version
mold --version
ninja --version
perl --version
pkg-config --version
pre-commit --version
python3 --version
run-clang-tidy --help
vim --version
EOF
# Sanity-check that the sanitizer runtimes shipped with g++/clang++ work
# end-to-end against the system loader.
COPY docker/cpp_files/ /tmp/cpp_files/
COPY docker/check-sanitizers.sh /tmp/check-sanitizers.sh
RUN grep -qi ubuntu /etc/os-release 2>/dev/null && /tmp/check-sanitizers.sh /tmp/cpp_files || true

6
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1780243769,
"narHash": "sha256-x5UQuRsH3MqI0U9afaXSNqzTPSeZlRLvFAav2Ux1pNw=",
"lastModified": 1777954456,
"narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "331800de5053fcebacf6813adb5db9c9dca22a0c",
"rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1",
"type": "github"
},
"original": {

View File

@@ -2,14 +2,12 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <array>
#include <cstdint>
#include <functional>
#include <limits>
#include <optional>
#include <ostream>
#include <set>
#include <stdexcept>
#include <string>
#include <unordered_map>
@@ -42,47 +40,6 @@ isPowerOfTen(T value)
return logTen(value).has_value();
}
namespace detail {
/** Builds a table of the powers of 10
*
* This function is marked consteval, so it can only be run in
* a constexpr context. This assures that it is and can only be run at
* compile time. Doing it at runtime would be pretty wasteful and
* inefficient.
*/
constexpr std::size_t kInt64Digits = 20;
consteval std::array<std::uint64_t, kInt64Digits>
buildPowersOfTen()
{
std::array<std::uint64_t, kInt64Digits> result{};
std::uint64_t power = 1;
std::size_t exponent = 0;
// end the loop early so it doesn't overflow;
for (; exponent < result.size() - 1; ++exponent, power *= 10)
{
result[exponent] = power;
if (power > std::numeric_limits<std::uint64_t>::max() / 10)
throw std::logic_error("Power of 10 table is too big");
}
result[exponent] = power;
if (power < std::numeric_limits<std::uint64_t>::max() / 10)
throw std::logic_error("Power of 10 table is not big enough for the uint64_t type");
return result;
}
} // namespace detail
constexpr std::array<std::uint64_t, detail::kInt64Digits> kPowerOfTen = detail::buildPowersOfTen();
static_assert(kPowerOfTen[0] == 1);
static_assert(kPowerOfTen[1] == 10);
static_assert(kPowerOfTen[10] == 10'000'000'000);
static_assert(
isPowerOfTen(kPowerOfTen.back()) && *logTen(kPowerOfTen.back()) == detail::kInt64Digits - 1);
/** MantissaRange defines a range for the mantissa of a normalized Number.
*
* The mantissa is in the range [min, max], where
@@ -119,7 +76,6 @@ static_assert(
struct MantissaRange final
{
using rep = std::uint64_t;
enum class MantissaScale {
Small,
// LargeLegacy can be removed when fixCleanup3_2_0 is retired
@@ -133,15 +89,19 @@ struct MantissaRange final
Enabled = true,
};
explicit constexpr MantissaRange(MantissaScale sc) : scale(sc)
explicit constexpr MantissaRange(MantissaScale scale)
: min(getMin(scale))
, cuspRoundingFixEnabled(isCuspFixEnabled(scale))
, log(logTen(min).value_or(-1))
, scale(scale)
{
}
MantissaScale const scale;
int const log{getExponent(scale)};
rep const min{getMin(scale, log)};
rep const max{(min * 10) - 1};
CuspRoundingFix const cuspRoundingFixEnabled{isCuspFixEnabled(scale)};
rep min;
rep max{(min * 10) - 1};
CuspRoundingFix cuspRoundingFixEnabled;
int log;
MantissaScale scale;
static MantissaRange const&
getMantissaRange(MantissaScale scale);
@@ -150,35 +110,23 @@ struct MantissaRange final
getAllScales();
private:
static constexpr int
getExponent(MantissaScale scale)
static constexpr rep
getMin(MantissaScale scale)
{
switch (scale)
{
case MantissaScale::Small:
return 15;
return 1'000'000'000'000'000ULL;
case MantissaScale::LargeLegacy:
case MantissaScale::Large:
return 18;
// LCOV_EXCL_START
return 1'000'000'000'000'000'000ULL;
default:
// If called in a constexpr context, this throw assures that the build fails if an
// invalid scale is used.
throw std::runtime_error("Unknown mantissa scale");
// LCOV_EXCL_STOP
throw std::runtime_error("Unknown mantissa scale"); // LCOV_EXCL_LINE
}
}
// Keep this function for future use with different ways to compute
// the ranges.
static constexpr rep
getMin(MantissaScale scale, int exponent)
{
if (exponent < 0 || exponent >= kPowerOfTen.size())
throw std::runtime_error("Invalid exponent"); // LCOV_EXCL_LINE
return kPowerOfTen[exponent];
}
static constexpr CuspRoundingFix
isCuspFixEnabled(MantissaScale scale)
{
@@ -529,7 +477,8 @@ public:
template <
auto MinMantissa,
auto MaxMantissa,
Integral64 T = std::decay_t<decltype(MinMantissa)>>
Integral64 T = std::decay_t<decltype(MinMantissa)>,
Integral64 TMax = std::decay_t<decltype(MaxMantissa)>>
[[nodiscard]]
std::pair<T, int>
normalizeToRange() const;
@@ -570,8 +519,7 @@ private:
int& exponent,
MantissaRange::rep const& minMantissa,
MantissaRange::rep const& maxMantissa,
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled,
bool dropped);
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled);
[[nodiscard]] bool
isnormal() const noexcept;
@@ -777,18 +725,16 @@ Number::isnormal() const noexcept
kMinExponent <= exponent_ && exponent_ <= kMaxExponent);
}
template <auto MinMantissa, auto MaxMantissa, Integral64 T>
template <auto MinMantissa, auto MaxMantissa, Integral64 T, Integral64 TMax>
std::pair<T, int>
Number::normalizeToRange() const
{
static_assert(std::is_same_v<T, std::uint64_t> || std::is_same_v<T, std::int64_t>);
static_assert(std::is_same_v<T, std::decay_t<decltype(MinMantissa)>>);
static_assert(std::is_same_v<T, std::decay_t<decltype(MaxMantissa)>>);
static_assert(std::is_same_v<T, TMax>);
auto constexpr kMIN = static_cast<T>(MinMantissa);
auto constexpr kMAX = static_cast<T>(MaxMantissa);
static_assert(kMIN > 0);
static_assert(kMIN % 10 == 0);
static_assert(isPowerOfTen(kMIN));
static_assert(kMAX % 10 == 9);
static_assert((kMAX + 1) / 10 == kMIN);

View File

@@ -157,7 +157,7 @@ public:
/** Fetch an item from the cache.
If the digest was not found, Handler
will be called with this signature:
SLE::const_pointer(void)
std::shared_ptr<SLE const>(void)
*/
template <class Handler>
SharedPointerType

View File

@@ -123,7 +123,7 @@ private:
bool preserveOrder,
Keylet const& directory,
uint256 const& key,
std::function<void(SLE::ref)> const& describe);
std::function<void(std::shared_ptr<SLE> const&)> const& describe);
public:
ApplyView() = default;
@@ -153,7 +153,7 @@ public:
@return `nullptr` if the key is not present
*/
virtual SLE::pointer
virtual std::shared_ptr<SLE>
peek(Keylet const& k) = 0;
/** Remove a peeked SLE.
@@ -168,7 +168,7 @@ public:
The key is no longer associated with the SLE.
*/
virtual void
erase(SLE::ref sle) = 0;
erase(std::shared_ptr<SLE> const& sle) = 0;
/** Insert a new state SLE
@@ -189,7 +189,7 @@ public:
@note The key is taken from the SLE
*/
virtual void
insert(SLE::ref sle) = 0;
insert(std::shared_ptr<SLE> const& sle) = 0;
/** Indicate changes to a peeked SLE
@@ -208,7 +208,7 @@ public:
*/
/** @{ */
virtual void
update(SLE::ref sle) = 0;
update(std::shared_ptr<SLE> const& sle) = 0;
//--------------------------------------------------------------------------
@@ -301,7 +301,7 @@ public:
dirAppend(
Keylet const& directory,
Keylet const& key,
std::function<void(SLE::ref)> const& describe)
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
{
if (key.type != ltOFFER)
{
@@ -340,7 +340,7 @@ public:
dirInsert(
Keylet const& directory,
uint256 const& key,
std::function<void(SLE::ref)> const& describe)
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
{
return dirAdd(false, directory, key, describe);
}
@@ -349,7 +349,7 @@ public:
dirInsert(
Keylet const& directory,
Keylet const& key,
std::function<void(SLE::ref)> const& describe)
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
{
return dirAdd(false, directory, key.key, describe);
}
@@ -411,7 +411,7 @@ createRoot(
ApplyView& view,
Keylet const& directory,
uint256 const& key,
std::function<void(SLE::ref)> const& describe);
std::function<void(std::shared_ptr<SLE> const&)> const& describe);
auto
findPreviousPage(ApplyView& view, Keylet const& directory, SLE::ref start);
@@ -434,7 +434,7 @@ insertPage(
SLE::ref next,
uint256 const& key,
Keylet const& directory,
std::function<void(SLE::ref)> const& describe);
std::function<void(std::shared_ptr<SLE> const&)> const& describe);
} // namespace directory
} // namespace xrpl

View File

@@ -67,8 +67,8 @@ public:
std::function<void(
uint256 const& key,
bool isDelete,
SLE::const_ref before,
SLE::const_ref after)> const& func);
std::shared_ptr<SLE const> const& before,
std::shared_ptr<SLE const> const& after)> const& func);
private:
std::optional<STAmount> deliver_;

View File

@@ -11,13 +11,13 @@ private:
uint256 const root_;
uint256 const nextQuality_;
uint256 const key_;
SLE::const_pointer sle_ = nullptr;
std::shared_ptr<SLE const> sle_ = nullptr;
unsigned int entry_ = 0;
uint256 index_;
public:
class const_iterator; // NOLINT(readability-identifier-naming)
using value_type = SLE::const_pointer;
using value_type = std::shared_ptr<SLE const>;
BookDirs(ReadView const&, Book const&);
@@ -76,7 +76,7 @@ private:
uint256 nextQuality_;
uint256 key_;
uint256 curKey_;
SLE::const_pointer sle_;
std::shared_ptr<SLE const> sle_;
unsigned int entry_ = 0;
uint256 index_;
std::optional<value_type> mutable cache_;

View File

@@ -36,7 +36,7 @@ public:
bool
exists(Keylet const& k) const override;
SLE::const_pointer
std::shared_ptr<SLE const>
read(Keylet const& k) const override;
bool

View File

@@ -22,12 +22,12 @@ class Dir
private:
ReadView const* view_ = nullptr;
Keylet root_;
SLE::const_pointer sle_;
std::shared_ptr<SLE const> sle_;
STVector256 const* indexes_ = nullptr;
public:
class ConstIterator;
using value_type = SLE::const_pointer;
using value_type = std::shared_ptr<SLE const>;
Dir(ReadView const&, Keylet const&);
@@ -102,7 +102,7 @@ private:
Keylet page_;
uint256 index_;
std::optional<value_type> mutable cache_;
SLE::const_pointer sle_;
std::shared_ptr<SLE const> sle_;
STVector256 const* indexes_ = nullptr;
std::vector<uint256>::const_iterator it_;
};

View File

@@ -166,7 +166,7 @@ public:
std::optional<uint256>
succ(uint256 const& key, std::optional<uint256> const& last = std::nullopt) const override;
SLE::const_pointer
std::shared_ptr<SLE const>
read(Keylet const& k) const override;
std::unique_ptr<SlesType::iter_base>
@@ -202,16 +202,16 @@ public:
//
void
rawErase(SLE::ref sle) override;
rawErase(std::shared_ptr<SLE> const& sle) override;
void
rawInsert(SLE::ref sle) override;
rawInsert(std::shared_ptr<SLE> const& sle) override;
void
rawErase(uint256 const& key);
void
rawReplace(SLE::ref sle) override;
rawReplace(std::shared_ptr<SLE> const& sle) override;
void
rawDestroyXRP(XRPAmount const& fee) override
@@ -361,7 +361,7 @@ public:
bool
isVotingLedger() const;
SLE::pointer
std::shared_ptr<SLE>
peek(Keylet const& k) const;
private:

View File

@@ -197,7 +197,7 @@ public:
std::optional<key_type>
succ(key_type const& key, std::optional<key_type> const& last = std::nullopt) const override;
SLE::const_pointer
std::shared_ptr<SLE const>
read(Keylet const& k) const override;
std::unique_ptr<SlesType::iter_base>
@@ -224,13 +224,13 @@ public:
// RawView
void
rawErase(SLE::ref sle) override;
rawErase(std::shared_ptr<SLE> const& sle) override;
void
rawInsert(SLE::ref sle) override;
rawInsert(std::shared_ptr<SLE> const& sle) override;
void
rawReplace(SLE::ref sle) override;
rawReplace(std::shared_ptr<SLE> const& sle) override;
void
rawDestroyXRP(XRPAmount const& fee) override;

View File

@@ -25,7 +25,7 @@ public:
can calculate metadata.
*/
virtual void
rawErase(SLE::ref sle) = 0;
rawErase(std::shared_ptr<SLE> const& sle) = 0;
/** Unconditionally insert a state item.
@@ -39,7 +39,7 @@ public:
@note The key is taken from the SLE
*/
virtual void
rawInsert(SLE::ref sle) = 0;
rawInsert(std::shared_ptr<SLE> const& sle) = 0;
/** Unconditionally replace a state item.
@@ -54,7 +54,7 @@ public:
@note The key is taken from the SLE
*/
virtual void
rawReplace(SLE::ref sle) = 0;
rawReplace(std::shared_ptr<SLE> const& sle) = 0;
/** Destroy XRP.

View File

@@ -34,9 +34,9 @@ public:
using key_type = uint256;
using mapped_type = SLE::const_pointer;
using mapped_type = std::shared_ptr<SLE const>;
struct SlesType : detail::ReadViewFwdRange<SLE::const_pointer>
struct SlesType : detail::ReadViewFwdRange<std::shared_ptr<SLE const>>
{
explicit SlesType(ReadView const& view);
[[nodiscard]] Iterator
@@ -143,7 +143,7 @@ public:
@return `nullptr` if the key is not present or
if the type does not match.
*/
[[nodiscard]] virtual SLE::const_pointer
[[nodiscard]] virtual std::shared_ptr<SLE const>
read(Keylet const& k) const = 0;
// Accounts in a payment are not allowed to use assets acquired during that

View File

@@ -12,6 +12,7 @@
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <utility>
@@ -134,7 +135,7 @@ areCompatible(
dirLink(
ApplyView& view,
AccountID const& owner,
SLE::pointer& object,
std::shared_ptr<SLE>& object,
SF_UINT64 const& node = sfOwnerNode);
/** Checks that can withdraw funds from an object to itself or a destination.
@@ -214,8 +215,8 @@ doWithdraw(
* (if should not be skipped) and if the entry should be skipped. The status
* is always tesSUCCESS if the entry should be skipped.
*/
using EntryDeleter =
std::function<std::pair<TER, SkipEntry>(LedgerEntryType, uint256 const&, SLE::pointer&)>;
using EntryDeleter = std::function<
std::pair<TER, SkipEntry>(LedgerEntryType, uint256 const&, std::shared_ptr<SLE>&)>;
/** Cleanup owner directory entries on account delete.
* Used for a regular and AMM accounts deletion. The caller
* has to provide the deleter function, which handles details of

View File

@@ -8,6 +8,8 @@
#include <xrpl/protocol/TxMeta.h>
#include <xrpl/protocol/XRPAmount.h>
#include <memory>
namespace xrpl::detail {
// Helper class that buffers modifications
@@ -24,7 +26,7 @@ private:
Modify,
};
using items_t = std::map<key_type, std::pair<Action, SLE::pointer>>;
using items_t = std::map<key_type, std::pair<Action, std::shared_ptr<SLE>>>;
items_t items_;
XRPAmount dropsDestroyed_{0};
@@ -58,10 +60,10 @@ public:
[[nodiscard]] std::optional<key_type>
succ(ReadView const& base, key_type const& key, std::optional<key_type> const& last) const;
[[nodiscard]] SLE::const_pointer
[[nodiscard]] std::shared_ptr<SLE const>
read(ReadView const& base, Keylet const& k) const;
SLE::pointer
std::shared_ptr<SLE>
peek(ReadView const& base, Keylet const& k);
[[nodiscard]] std::size_t
@@ -73,23 +75,23 @@ public:
std::function<void(
uint256 const& key,
bool isDelete,
SLE::const_ref before,
SLE::const_ref after)> const& func) const;
std::shared_ptr<SLE const> const& before,
std::shared_ptr<SLE const> const& after)> const& func) const;
void
erase(ReadView const& base, SLE::ref sle);
erase(ReadView const& base, std::shared_ptr<SLE> const& sle);
void
rawErase(ReadView const& base, SLE::ref sle);
rawErase(ReadView const& base, std::shared_ptr<SLE> const& sle);
void
insert(ReadView const& base, SLE::ref sle);
insert(ReadView const& base, std::shared_ptr<SLE> const& sle);
void
update(ReadView const& base, SLE::ref sle);
update(ReadView const& base, std::shared_ptr<SLE> const& sle);
void
replace(ReadView const& base, SLE::ref sle);
replace(ReadView const& base, std::shared_ptr<SLE> const& sle);
void
destroyXRP(XRPAmount const& fee);
@@ -102,12 +104,12 @@ public:
}
private:
using Mods = hash_map<key_type, SLE::pointer>;
using Mods = hash_map<key_type, std::shared_ptr<SLE>>;
static void
threadItem(TxMeta& meta, SLE::ref to);
threadItem(TxMeta& meta, std::shared_ptr<SLE> const& to);
SLE::pointer
std::shared_ptr<SLE>
getForMod(ReadView const& base, key_type const& key, Mods& mods, beast::Journal j);
void
@@ -117,7 +119,7 @@ private:
threadOwners(
ReadView const& base,
TxMeta& meta,
SLE::const_ref sle,
std::shared_ptr<SLE const> const& sle,
Mods& mods,
beast::Journal j);
};

View File

@@ -40,7 +40,7 @@ public:
[[nodiscard]] std::optional<key_type>
succ(key_type const& key, std::optional<key_type> const& last = std::nullopt) const override;
[[nodiscard]] SLE::const_pointer
[[nodiscard]] std::shared_ptr<SLE const>
read(Keylet const& k) const override;
[[nodiscard]] std::unique_ptr<SlesType::iter_base>
@@ -69,28 +69,28 @@ public:
[[nodiscard]] ApplyFlags
flags() const override;
SLE::pointer
std::shared_ptr<SLE>
peek(Keylet const& k) override;
void
erase(SLE::ref sle) override;
erase(std::shared_ptr<SLE> const& sle) override;
void
insert(SLE::ref sle) override;
insert(std::shared_ptr<SLE> const& sle) override;
void
update(SLE::ref sle) override;
update(std::shared_ptr<SLE> const& sle) override;
// RawView
void
rawErase(SLE::ref sle) override;
rawErase(std::shared_ptr<SLE> const& sle) override;
void
rawInsert(SLE::ref sle) override;
rawInsert(std::shared_ptr<SLE> const& sle) override;
void
rawReplace(SLE::ref sle) override;
rawReplace(std::shared_ptr<SLE> const& sle) override;
void
rawDestroyXRP(XRPAmount const& feeDrops) override;

View File

@@ -49,15 +49,15 @@ public:
succ(ReadView const& base, key_type const& key, std::optional<key_type> const& last) const;
void
erase(SLE::ref sle);
erase(std::shared_ptr<SLE> const& sle);
void
insert(SLE::ref sle);
insert(std::shared_ptr<SLE> const& sle);
void
replace(SLE::ref sle);
replace(std::shared_ptr<SLE> const& sle);
[[nodiscard]] SLE::const_pointer
[[nodiscard]] std::shared_ptr<SLE const>
read(ReadView const& base, Keylet const& k) const;
void
@@ -84,10 +84,10 @@ private:
struct SleAction
{
Action action;
SLE::pointer sle;
std::shared_ptr<SLE> sle;
// Constructor needed for emplacement in std::map
SleAction(Action action, SLE::pointer sle) : action(action), sle(std::move(sle))
SleAction(Action action, std::shared_ptr<SLE> const& sle) : action(action), sle(sle)
{
}
};

View File

@@ -792,7 +792,7 @@ deleteAMMAccount(Sandbox& view, Asset const& asset, Asset const& asset2, beast::
void
initializeFeeAuctionVote(
ApplyView& view,
SLE::pointer& ammSle,
std::shared_ptr<SLE>& ammSle,
AccountID const& account,
Asset const& lptAsset,
std::uint16_t tfee);
@@ -812,7 +812,7 @@ Expected<bool, TER>
verifyAndAdjustLPTokenBalance(
Sandbox& sb,
STAmount const& lpTokens,
SLE::pointer& ammSle,
std::shared_ptr<SLE>& ammSle,
AccountID const& account);
} // namespace xrpl

View File

@@ -9,6 +9,7 @@
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/TER.h>
#include <memory>
#include <set>
#include <vector>
@@ -35,7 +36,11 @@ xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj,
/** Adjust the owner count up or down. */
void
adjustOwnerCount(ApplyView& view, SLE::ref sle, std::int32_t amount, beast::Journal j);
adjustOwnerCount(
ApplyView& view,
std::shared_ptr<SLE> const& sle,
std::int32_t amount,
beast::Journal j);
/** Returns IOU issuer transfer fee as Rate. Rate specifies
* the fee as fractions of 1 billion. For example, 1% transfer rate
@@ -71,7 +76,9 @@ getPseudoAccountFields();
- null pointer
*/
[[nodiscard]] bool
isPseudoAccount(SLE::const_pointer sleAcct, std::set<SField const*> const& pseudoFieldFilter = {});
isPseudoAccount(
std::shared_ptr<SLE const> sleAcct,
std::set<SField const*> const& pseudoFieldFilter = {});
/** Convenience overload that reads the account from the view. */
[[nodiscard]] inline bool
@@ -91,7 +98,7 @@ isPseudoAccount(
* before using a field. The amendment check is **not** performed in
* createPseudoAccount.
*/
[[nodiscard]] Expected<SLE::pointer, TER>
[[nodiscard]] Expected<std::shared_ptr<SLE>, TER>
createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const& ownerField);
/** Checks the destination and tag.

View File

@@ -23,7 +23,7 @@ checkExpired(SLE const& sleCredential, NetClock::time_point const& closed);
// Actually remove a credentials object from the ledger
[[nodiscard]] TER
deleteSLE(ApplyView& view, SLE::ref sleCredential, beast::Journal j);
deleteSLE(ApplyView& view, std::shared_ptr<SLE> const& sleCredential, beast::Journal j);
// Amendment and parameters checks for sfCredentialIDs field
NotTEC
@@ -70,7 +70,7 @@ verifyDepositPreauth(
ApplyView& view,
AccountID const& src,
AccountID const& dst,
SLE::const_ref sleDst,
std::shared_ptr<SLE const> const& sleDst,
beast::Journal j);
} // namespace xrpl

View File

@@ -15,7 +15,7 @@ namespace xrpl {
* if not.
*/
NotTEC
checkTxPermission(SLE::const_ref delegate, STTx const& tx);
checkTxPermission(std::shared_ptr<SLE const> const& delegate, STTx const& tx);
/**
* Load the granular permissions granted to the delegate account for the
@@ -28,7 +28,7 @@ checkTxPermission(SLE::const_ref delegate, STTx const& tx);
*/
void
loadGranularPermission(
SLE::const_ref delegate,
std::shared_ptr<SLE const> const& delegate,
TxType const& type,
std::unordered_set<GranularPermissionType>& granularPermissions);

View File

@@ -115,7 +115,7 @@ bool
cdirFirst(
ReadView const& view,
uint256 const& root,
SLE::const_pointer& page,
std::shared_ptr<SLE const>& page,
unsigned int& index,
uint256& entry);
@@ -123,7 +123,7 @@ bool
dirFirst(
ApplyView& view,
uint256 const& root,
SLE::pointer& page,
std::shared_ptr<SLE>& page,
unsigned int& index,
uint256& entry);
/** @} */
@@ -147,7 +147,7 @@ bool
cdirNext(
ReadView const& view,
uint256 const& root,
SLE::const_pointer& page,
std::shared_ptr<SLE const>& page,
unsigned int& index,
uint256& entry);
@@ -155,14 +155,17 @@ bool
dirNext(
ApplyView& view,
uint256 const& root,
SLE::pointer& page,
std::shared_ptr<SLE>& page,
unsigned int& index,
uint256& entry);
/** @} */
/** Iterate all items in the given directory. */
void
forEachItem(ReadView const& view, Keylet const& root, std::function<void(SLE::const_ref)> const& f);
forEachItem(
ReadView const& view,
Keylet const& root,
std::function<void(std::shared_ptr<SLE const> const&)> const& f);
/** Iterate all items after an item in the given directory.
@param after The key of the item to start after
@@ -177,11 +180,14 @@ forEachItemAfter(
uint256 const& after,
std::uint64_t const hint,
unsigned int limit,
std::function<bool(SLE::const_ref)> const& f);
std::function<bool(std::shared_ptr<SLE const> const&)> const& f);
/** Iterate all items in an account's owner directory. */
inline void
forEachItem(ReadView const& view, AccountID const& id, std::function<void(SLE::const_ref)> const& f)
forEachItem(
ReadView const& view,
AccountID const& id,
std::function<void(std::shared_ptr<SLE const> const&)> const& f)
{
forEachItem(view, keylet::ownerDir(id), f);
}
@@ -199,7 +205,7 @@ forEachItemAfter(
uint256 const& after,
std::uint64_t const hint,
unsigned int limit,
std::function<bool(SLE::const_ref)> const& f)
std::function<bool(std::shared_ptr<SLE const> const&)> const& f)
{
return forEachItemAfter(view, keylet::ownerDir(id), after, hint, limit, f);
}

View File

@@ -18,7 +18,7 @@ TER
escrowUnlockApplyHelper(
ApplyView& view,
Rate lockedRate,
SLE::ref sleDest,
std::shared_ptr<SLE> const& sleDest,
STAmount const& xrpBalance,
STAmount const& amount,
AccountID const& issuer,
@@ -32,7 +32,7 @@ inline TER
escrowUnlockApplyHelper<Issue>(
ApplyView& view,
Rate lockedRate,
SLE::ref sleDest,
std::shared_ptr<SLE> const& sleDest,
STAmount const& xrpBalance,
STAmount const& amount,
AccountID const& issuer,
@@ -162,7 +162,7 @@ inline TER
escrowUnlockApplyHelper<MPTIssue>(
ApplyView& view,
Rate lockedRate,
SLE::ref sleDest,
std::shared_ptr<SLE> const& sleDest,
STAmount const& xrpBalance,
STAmount const& amount,
AccountID const& issuer,

View File

@@ -461,7 +461,6 @@ loanAccruedInterest(
ExtendedPaymentComponents
computeOverpaymentComponents(
Rules const& rules,
Asset const& asset,
int32_t const loanScale,
Number const& overpayment,

View File

@@ -28,9 +28,10 @@ findToken(ReadView const& view, AccountID const& owner, uint256 const& nftokenID
struct TokenAndPage
{
STObject token;
SLE::pointer page;
std::shared_ptr<SLE> page;
TokenAndPage(STObject token, SLE::pointer page) : token(std::move(token)), page(std::move(page))
TokenAndPage(STObject token, std::shared_ptr<SLE> page)
: token(std::move(token)), page(std::move(page))
{
}
};
@@ -46,7 +47,11 @@ TER
removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID);
TER
removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID, SLE::ref page);
removeToken(
ApplyView& view,
AccountID const& owner,
uint256 const& nftokenID,
std::shared_ptr<SLE> const& page);
/** Deletes the given token offer.
@@ -58,7 +63,7 @@ removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID, S
The offer also consumes one incremental reserve.
*/
bool
deleteTokenOffer(ApplyView& view, SLE::ref offer);
deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer);
/** Repairs the links in an NFTokenPage directory.

View File

@@ -5,6 +5,8 @@
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/TER.h>
#include <memory>
namespace xrpl {
/** Delete an offer.
@@ -21,6 +23,6 @@ namespace xrpl {
*/
// [[nodiscard]] // nodiscard commented out so Flow, BookTip and others compile.
TER
offerDelete(ApplyView& view, SLE::ref sle, beast::Journal j);
offerDelete(ApplyView& view, std::shared_ptr<SLE> const& sle, beast::Journal j);
} // namespace xrpl

View File

@@ -8,6 +8,10 @@
namespace xrpl {
TER
closeChannel(SLE::ref slep, ApplyView& view, uint256 const& key, beast::Journal j);
closeChannel(
std::shared_ptr<SLE> const& slep,
ApplyView& view,
uint256 const& key,
beast::Journal j);
} // namespace xrpl

View File

@@ -154,7 +154,7 @@ trustCreate(
[[nodiscard]] TER
trustDelete(
ApplyView& view,
SLE::ref sleRippleState,
std::shared_ptr<SLE> const& sleRippleState,
AccountID const& uLowAccountID,
AccountID const& uHighAccountID,
beast::Journal j);
@@ -248,7 +248,7 @@ removeEmptyHolding(
[[nodiscard]] TER
deleteAMMTrustLine(
ApplyView& view,
SLE::pointer sleState,
std::shared_ptr<SLE> sleState,
std::optional<AccountID> const& ammAccountID,
beast::Journal j);
@@ -258,7 +258,7 @@ deleteAMMTrustLine(
[[nodiscard]] TER
deleteAMMMPToken(
ApplyView& view,
SLE::pointer sleMPT,
std::shared_ptr<SLE> sleMPT,
AccountID const& ammAccountID,
beast::Journal j);

View File

@@ -5,6 +5,7 @@
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <memory>
#include <optional>
namespace xrpl {
@@ -20,7 +21,10 @@ namespace xrpl {
@return The number of shares, or nullopt on error.
*/
[[nodiscard]] std::optional<STAmount>
assetsToSharesDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const& assets);
assetsToSharesDeposit(
std::shared_ptr<SLE const> const& vault,
std::shared_ptr<SLE const> const& issuance,
STAmount const& assets);
/** From the perspective of a vault, return the number of assets to take from
depositor when they receive a fixed amount of shares. Note, since shares are
@@ -33,7 +37,10 @@ assetsToSharesDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount co
@return The number of assets, or nullopt on error.
*/
[[nodiscard]] std::optional<STAmount>
sharesToAssetsDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const& shares);
sharesToAssetsDeposit(
std::shared_ptr<SLE const> const& vault,
std::shared_ptr<SLE const> const& issuance,
STAmount const& shares);
/** Controls whether to truncate shares instead of rounding. */
enum class TruncateShares : bool { No = false, Yes = true };
@@ -62,8 +69,8 @@ enum class WaiveUnrealizedLoss : bool { No = false, Yes = true };
*/
[[nodiscard]] std::optional<STAmount>
assetsToSharesWithdraw(
SLE::const_ref vault,
SLE::const_ref issuance,
std::shared_ptr<SLE const> const& vault,
std::shared_ptr<SLE const> const& issuance,
STAmount const& assets,
TruncateShares truncate = TruncateShares::No,
WaiveUnrealizedLoss waive = WaiveUnrealizedLoss::No);
@@ -82,8 +89,8 @@ assetsToSharesWithdraw(
*/
[[nodiscard]] std::optional<STAmount>
sharesToAssetsWithdraw(
SLE::const_ref vault,
SLE::const_ref issuance,
std::shared_ptr<SLE const> const& vault,
std::shared_ptr<SLE const> const& issuance,
STAmount const& shares,
WaiveUnrealizedLoss waive = WaiveUnrealizedLoss::No);
@@ -97,6 +104,9 @@ sharesToAssetsWithdraw(
both the share MPTID and the outstanding-amount total.
*/
[[nodiscard]] bool
isSoleShareholder(ReadView const& view, AccountID const& account, SLE::const_ref issuance);
isSoleShareholder(
ReadView const& view,
AccountID const& account,
std::shared_ptr<SLE const> const& issuance);
} // namespace xrpl

View File

@@ -131,10 +131,6 @@ public:
std::uint32_t ledgerSeq,
std::function<void(std::shared_ptr<NodeObject> const&)>&& callback);
/** Remove expired entries from the positive and negative caches. */
virtual void
sweep() = 0;
/** Gather statistics pertaining to read and write activities.
*
* @param obj Json object reference into which to place counters.

View File

@@ -22,32 +22,6 @@ public:
beast::Journal j)
: Database(scheduler, readThreads, config, j), backend_(std::move(backend))
{
std::optional<int> cacheSize, cacheAge;
if (config.exists("cache_size"))
{
cacheSize = get<int>(config, "cache_size");
if (cacheSize.value() < 0)
Throw<std::runtime_error>("Specified negative value for cache_size");
}
if (config.exists("cache_age"))
{
cacheAge = get<int>(config, "cache_age");
if (cacheAge.value() < 0)
Throw<std::runtime_error>("Specified negative value for cache_age");
}
if (cacheSize.has_value() || cacheAge.has_value())
{
cache_ = std::make_shared<TaggedCache<uint256, NodeObject>>(
"DatabaseNodeImp",
cacheSize.value_or(0),
std::chrono::minutes(cacheAge.value_or(0)),
stopwatch(),
j);
}
XRPL_ASSERT(
backend_,
"xrpl::NodeStore::DatabaseNodeImp::DatabaseNodeImp : non-null "
@@ -99,13 +73,7 @@ public:
std::uint32_t ledgerSeq,
std::function<void(std::shared_ptr<NodeObject> const&)>&& callback) override;
void
sweep() override;
private:
// Cache for database objects. This cache is not always initialized. Check
// for null before using.
std::shared_ptr<TaggedCache<uint256, NodeObject>> cache_;
// Persistent key/value storage
std::shared_ptr<Backend> backend_;

View File

@@ -55,9 +55,6 @@ public:
void
sync() override;
void
sweep() override;
private:
std::shared_ptr<Backend> writableBackend_;
std::shared_ptr<Backend> archiveBackend_;

View File

@@ -25,7 +25,7 @@ struct varint_traits<T, true>
{
explicit varint_traits() = default;
static constexpr std::size_t kMax = ((8 * sizeof(T)) + 6) / 7;
static constexpr std::size_t kMax = (8 * sizeof(T) + 6) / 7;
};
// Returns: Number of bytes consumed or 0 on error,

View File

@@ -27,6 +27,13 @@ enum SOEStyle {
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum SOETxMPTIssue { SoeMptNone, SoeMptSupported, SoeMptNotSupported };
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum SOEMutability {
SoeImmutable,
SoeMutable,
SoeImmutableSetOnce,
};
//------------------------------------------------------------------------------
/** An element in a SOTemplate. */
@@ -35,6 +42,7 @@ class SOElement
// Use std::reference_wrapper so SOElement can be stored in a std::vector.
std::reference_wrapper<SField const> sField_;
SOEStyle style_;
SOEMutability mutability_ = SoeImmutable;
SOETxMPTIssue supportMpt_ = SoeMptNone;
private:
@@ -48,6 +56,14 @@ private:
nm += ": '" + fieldName.getName() + "'";
Throw<std::runtime_error>("SField (" + nm + ") in SOElement must be useful.");
}
XRPL_ASSERT(
mutability_ != SoeImmutableSetOnce || style_ == SoeOptional,
"xrpl::SOElement::init : set-once fields must be optional");
XRPL_ASSERT(
mutability_ != SoeMutable || style_ == SoeRequired || style_ == SoeOptional ||
style_ == SoeDefault,
"xrpl::SOElement::init : mutable fields must have a valid style");
}
public:
@@ -56,6 +72,12 @@ public:
init(fieldName);
}
SOElement(SField const& fieldName, SOEStyle style, SOEMutability mutability)
: sField_(fieldName), style_(style), mutability_(mutability)
{
init(fieldName);
}
template <typename T>
requires(std::is_same_v<T, STAmount> || std::is_same_v<T, STIssue>)
SOElement(
@@ -67,6 +89,18 @@ public:
init(fieldName);
}
template <typename T>
requires(std::is_same_v<T, STAmount> || std::is_same_v<T, STIssue>)
SOElement(
TypedField<T> const& fieldName,
SOEStyle style,
SOEMutability mutability,
SOETxMPTIssue supportMpt = SoeMptNotSupported)
: sField_(fieldName), style_(style), mutability_(mutability), supportMpt_(supportMpt)
{
init(fieldName);
}
[[nodiscard]] SField const&
sField() const
{
@@ -79,6 +113,12 @@ public:
return style_;
}
[[nodiscard]] SOEMutability
mutability() const
{
return mutability_;
}
[[nodiscard]] SOETxMPTIssue
supportMPT() const
{

View File

@@ -587,7 +587,7 @@ public:
/** Returns `true` if the field is set.
Fields with soeDEFAULT and set to the
Fields with SoeDefault and set to the
default value will return `true`
*/
explicit

View File

@@ -15,6 +15,7 @@
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FIX (ImmutableInvariant, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_2_0, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(MPTokensV2, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_1_3, Supported::Yes, VoteBehavior::DefaultYes)

View File

@@ -24,15 +24,15 @@
\sa keylet::nftoffer
*/
LEDGER_ENTRY(ltNFTOKEN_OFFER, 0x0037, NFTokenOffer, nft_offer, ({
{sfOwner, SoeRequired},
{sfNFTokenID, SoeRequired},
{sfAmount, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfNFTokenOfferNode, SoeRequired},
{sfDestination, SoeOptional},
{sfExpiration, SoeOptional},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfOwner, SoeRequired, SoeImmutable},
{sfNFTokenID, SoeRequired, SoeImmutable},
{sfAmount, SoeRequired, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfNFTokenOfferNode, SoeRequired, SoeImmutable},
{sfDestination, SoeOptional, SoeImmutable},
{sfExpiration, SoeOptional, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object which describes a check.
@@ -40,18 +40,18 @@ LEDGER_ENTRY(ltNFTOKEN_OFFER, 0x0037, NFTokenOffer, nft_offer, ({
\sa keylet::check
*/
LEDGER_ENTRY(ltCHECK, 0x0043, Check, check, ({
{sfAccount, SoeRequired},
{sfDestination, SoeRequired},
{sfSendMax, SoeRequired},
{sfSequence, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfDestinationNode, SoeRequired},
{sfExpiration, SoeOptional},
{sfInvoiceID, SoeOptional},
{sfSourceTag, SoeOptional},
{sfDestinationTag, SoeOptional},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAccount, SoeRequired, SoeImmutable},
{sfDestination, SoeRequired, SoeImmutable},
{sfSendMax, SoeRequired, SoeImmutable},
{sfSequence, SoeRequired, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfDestinationNode, SoeRequired, SoeImmutable},
{sfExpiration, SoeOptional, SoeImmutable},
{sfInvoiceID, SoeOptional, SoeImmutable},
{sfSourceTag, SoeOptional, SoeImmutable},
{sfDestinationTag, SoeOptional, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** The ledger object which tracks the DID.
@@ -59,13 +59,13 @@ LEDGER_ENTRY(ltCHECK, 0x0043, Check, check, ({
\sa keylet::did
*/
LEDGER_ENTRY(ltDID, 0x0049, DID, did, ({
{sfAccount, SoeRequired},
{sfDIDDocument, SoeOptional},
{sfURI, SoeOptional},
{sfData, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAccount, SoeRequired, SoeImmutable},
{sfDIDDocument, SoeOptional, SoeMutable},
{sfURI, SoeOptional, SoeMutable},
{sfData, SoeOptional, SoeMutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** The ledger object which tracks the current negative UNL state.
@@ -75,11 +75,11 @@ LEDGER_ENTRY(ltDID, 0x0049, DID, did, ({
\sa keylet::negativeUNL
*/
LEDGER_ENTRY(ltNEGATIVE_UNL, 0x004e, NegativeUNL, nunl, ({
{sfDisabledValidators, SoeOptional},
{sfValidatorToDisable, SoeOptional},
{sfValidatorToReEnable, SoeOptional},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
{sfDisabledValidators, SoeOptional, SoeMutable},
{sfValidatorToDisable, SoeOptional, SoeMutable},
{sfValidatorToReEnable, SoeOptional, SoeMutable},
{sfPreviousTxnID, SoeOptional, SoeMutable},
{sfPreviousTxnLgrSeq, SoeOptional, SoeMutable},
}))
/** A ledger object which contains a list of NFTs
@@ -87,11 +87,11 @@ LEDGER_ENTRY(ltNEGATIVE_UNL, 0x004e, NegativeUNL, nunl, ({
\sa keylet::nftpageMin, keylet::nftpageMax, keylet::nftpage
*/
LEDGER_ENTRY(ltNFTOKEN_PAGE, 0x0050, NFTokenPage, nft_page, ({
{sfPreviousPageMin, SoeOptional},
{sfNextPageMin, SoeOptional},
{sfNFTokens, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfPreviousPageMin, SoeOptional, SoeMutable},
{sfNextPageMin, SoeOptional, SoeMutable},
{sfNFTokens, SoeRequired, SoeMutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object which contains a signer list for an account.
@@ -101,13 +101,13 @@ LEDGER_ENTRY(ltNFTOKEN_PAGE, 0x0050, NFTokenPage, nft_page, ({
// All fields are SoeRequired because there is always a SignerEntries.
// If there are no SignerEntries the node is deleted.
LEDGER_ENTRY(ltSIGNER_LIST, 0x0053, SignerList, signer_list, ({
{sfOwner, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfSignerQuorum, SoeRequired},
{sfSignerEntries, SoeRequired},
{sfSignerListID, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfOwner, SoeOptional, SoeImmutableSetOnce},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfSignerQuorum, SoeRequired, SoeMutable},
{sfSignerEntries, SoeRequired, SoeMutable},
{sfSignerListID, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object which describes a ticket.
@@ -115,11 +115,11 @@ LEDGER_ENTRY(ltSIGNER_LIST, 0x0053, SignerList, signer_list, ({
\sa keylet::kTicket
*/
LEDGER_ENTRY(ltTICKET, 0x0054, Ticket, ticket, ({
{sfAccount, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfTicketSequence, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAccount, SoeRequired, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfTicketSequence, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object which describes an account.
@@ -127,29 +127,29 @@ LEDGER_ENTRY(ltTICKET, 0x0054, Ticket, ticket, ({
\sa keylet::account
*/
LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
{sfAccount, SoeRequired},
{sfSequence, SoeRequired},
{sfBalance, SoeRequired},
{sfOwnerCount, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAccountTxnID, SoeOptional},
{sfRegularKey, SoeOptional},
{sfEmailHash, SoeOptional},
{sfWalletLocator, SoeOptional},
{sfWalletSize, SoeOptional},
{sfMessageKey, SoeOptional},
{sfTransferRate, SoeOptional},
{sfDomain, SoeOptional},
{sfTickSize, SoeOptional},
{sfTicketCount, SoeOptional},
{sfNFTokenMinter, SoeOptional},
{sfMintedNFTokens, SoeDefault},
{sfBurnedNFTokens, SoeDefault},
{sfFirstNFTokenSequence, SoeOptional},
{sfAMMID, SoeOptional}, // pseudo-account designator
{sfVaultID, SoeOptional}, // pseudo-account designator
{sfLoanBrokerID, SoeOptional}, // pseudo-account designator
{sfAccount, SoeRequired, SoeImmutable},
{sfSequence, SoeRequired, SoeMutable},
{sfBalance, SoeRequired, SoeMutable},
{sfOwnerCount, SoeRequired, SoeMutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
{sfAccountTxnID, SoeOptional, SoeMutable},
{sfRegularKey, SoeOptional, SoeMutable},
{sfEmailHash, SoeOptional, SoeMutable},
{sfWalletLocator, SoeOptional, SoeMutable},
{sfWalletSize, SoeOptional, SoeMutable},
{sfMessageKey, SoeOptional, SoeMutable},
{sfTransferRate, SoeOptional, SoeMutable},
{sfDomain, SoeOptional, SoeMutable},
{sfTickSize, SoeOptional, SoeMutable},
{sfTicketCount, SoeOptional, SoeMutable},
{sfNFTokenMinter, SoeOptional, SoeMutable},
{sfMintedNFTokens, SoeDefault, SoeMutable},
{sfBurnedNFTokens, SoeDefault, SoeMutable},
{sfFirstNFTokenSequence, SoeOptional, SoeImmutableSetOnce},
{sfAMMID, SoeOptional, SoeImmutable}, // pseudo-account designator
{sfVaultID, SoeOptional, SoeImmutable}, // pseudo-account designator
{sfLoanBrokerID, SoeOptional, SoeImmutable}, // pseudo-account designator
}))
/** A ledger object which contains a list of object identifiers.
@@ -158,22 +158,22 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
keylet::ownerDir
*/
LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, directory, ({
{sfOwner, SoeOptional}, // for owner directories
{sfTakerPaysCurrency, SoeOptional}, // order book directories
{sfTakerPaysIssuer, SoeOptional}, // order book directories
{sfTakerPaysMPT, SoeOptional}, // order book directories
{sfTakerGetsCurrency, SoeOptional}, // order book directories
{sfTakerGetsIssuer, SoeOptional}, // order book directories
{sfTakerGetsMPT, SoeOptional}, // order book directories
{sfExchangeRate, SoeOptional}, // order book directories
{sfIndexes, SoeRequired},
{sfRootIndex, SoeRequired},
{sfIndexNext, SoeOptional},
{sfIndexPrevious, SoeOptional},
{sfNFTokenID, SoeOptional},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
{sfDomainID, SoeOptional} // order book directories
{sfOwner, SoeOptional, SoeImmutable}, // for owner directories
{sfTakerPaysCurrency, SoeOptional, SoeImmutable}, // order book directories
{sfTakerPaysIssuer, SoeOptional, SoeImmutable}, // order book directories
{sfTakerPaysMPT, SoeOptional, SoeImmutable}, // order book directories
{sfTakerGetsCurrency, SoeOptional, SoeImmutable}, // order book directories
{sfTakerGetsIssuer, SoeOptional, SoeImmutable}, // order book directories
{sfTakerGetsMPT, SoeOptional, SoeImmutable}, // order book directories
{sfExchangeRate, SoeOptional, SoeImmutable}, // order book directories
{sfIndexes, SoeRequired, SoeMutable},
{sfRootIndex, SoeRequired, SoeImmutable},
{sfIndexNext, SoeOptional, SoeMutable},
{sfIndexPrevious, SoeOptional, SoeMutable},
{sfNFTokenID, SoeOptional, SoeImmutable},
{sfPreviousTxnID, SoeOptional, SoeMutable},
{sfPreviousTxnLgrSeq, SoeOptional, SoeMutable},
{sfDomainID, SoeOptional, SoeImmutable}, // order book directories
}))
/** The ledger object which lists details about amendments on the network.
@@ -183,10 +183,10 @@ LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, directory, ({
\sa keylet::amendments
*/
LEDGER_ENTRY(ltAMENDMENTS, 0x0066, Amendments, amendments, ({
{sfAmendments, SoeOptional}, // Enabled
{sfMajorities, SoeOptional},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
{sfAmendments, SoeOptional, SoeMutable}, // Enabled
{sfMajorities, SoeOptional, SoeMutable},
{sfPreviousTxnID, SoeOptional, SoeMutable},
{sfPreviousTxnLgrSeq, SoeOptional, SoeMutable},
}))
/** A ledger object that contains a list of ledger hashes.
@@ -198,9 +198,9 @@ LEDGER_ENTRY(ltAMENDMENTS, 0x0066, Amendments, amendments, ({
\sa keylet::skip
*/
LEDGER_ENTRY(ltLEDGER_HASHES, 0x0068, LedgerHashes, hashes, ({
{sfFirstLedgerSequence, SoeOptional},
{sfLastLedgerSequence, SoeOptional},
{sfHashes, SoeRequired},
{sfFirstLedgerSequence, SoeOptional, SoeImmutable},
{sfLastLedgerSequence, SoeOptional, SoeMutable},
{sfHashes, SoeRequired, SoeMutable},
}))
/** The ledger object which lists details about sidechains.
@@ -208,16 +208,16 @@ LEDGER_ENTRY(ltLEDGER_HASHES, 0x0068, LedgerHashes, hashes, ({
\sa keylet::bridge
*/
LEDGER_ENTRY(ltBRIDGE, 0x0069, Bridge, bridge, ({
{sfAccount, SoeRequired},
{sfSignatureReward, SoeRequired},
{sfMinAccountCreateAmount, SoeOptional},
{sfXChainBridge, SoeRequired},
{sfXChainClaimID, SoeRequired},
{sfXChainAccountCreateCount, SoeRequired},
{sfXChainAccountClaimCount, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAccount, SoeRequired, SoeImmutable},
{sfSignatureReward, SoeRequired, SoeMutable},
{sfMinAccountCreateAmount, SoeOptional, SoeMutable},
{sfXChainBridge, SoeRequired, SoeImmutable},
{sfXChainClaimID, SoeRequired, SoeMutable},
{sfXChainAccountCreateCount, SoeRequired, SoeMutable},
{sfXChainAccountClaimCount, SoeRequired, SoeMutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object which describes an offer on the DEX.
@@ -225,18 +225,18 @@ LEDGER_ENTRY(ltBRIDGE, 0x0069, Bridge, bridge, ({
\sa keylet::offer
*/
LEDGER_ENTRY(ltOFFER, 0x006f, Offer, offer, ({
{sfAccount, SoeRequired},
{sfSequence, SoeRequired},
{sfTakerPays, SoeRequired},
{sfTakerGets, SoeRequired},
{sfBookDirectory, SoeRequired},
{sfBookNode, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfExpiration, SoeOptional},
{sfDomainID, SoeOptional},
{sfAdditionalBooks, SoeOptional},
{sfAccount, SoeRequired, SoeImmutable},
{sfSequence, SoeRequired, SoeImmutable},
{sfTakerPays, SoeRequired, SoeMutable},
{sfTakerGets, SoeRequired, SoeMutable},
{sfBookDirectory, SoeRequired, SoeImmutable},
{sfBookNode, SoeRequired, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
{sfExpiration, SoeOptional, SoeImmutable},
{sfDomainID, SoeOptional, SoeImmutable},
{sfAdditionalBooks, SoeOptional, SoeImmutable},
}))
/** A ledger object which describes a deposit pre-authorization.
@@ -244,12 +244,12 @@ LEDGER_ENTRY(ltOFFER, 0x006f, Offer, offer, ({
\sa keylet::depositPreauth
*/
LEDGER_ENTRY_DUPLICATE(ltDEPOSIT_PREAUTH, 0x0070, DepositPreauth, deposit_preauth, ({
{sfAccount, SoeRequired},
{sfAuthorize, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAuthorizeCredentials, SoeOptional},
{sfAccount, SoeRequired, SoeImmutable},
{sfAuthorize, SoeOptional, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
{sfAuthorizeCredentials, SoeOptional, SoeImmutable},
}))
/** A claim id for a cross chain transaction.
@@ -257,15 +257,15 @@ LEDGER_ENTRY_DUPLICATE(ltDEPOSIT_PREAUTH, 0x0070, DepositPreauth, deposit_preaut
\sa keylet::xChainClaimID
*/
LEDGER_ENTRY(ltXCHAIN_OWNED_CLAIM_ID, 0x0071, XChainOwnedClaimID, xchain_owned_claim_id, ({
{sfAccount, SoeRequired},
{sfXChainBridge, SoeRequired},
{sfXChainClaimID, SoeRequired},
{sfOtherChainSource, SoeRequired},
{sfXChainClaimAttestations, SoeRequired},
{sfSignatureReward, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAccount, SoeRequired, SoeImmutable},
{sfXChainBridge, SoeRequired, SoeImmutable},
{sfXChainClaimID, SoeRequired, SoeImmutable},
{sfOtherChainSource, SoeRequired, SoeImmutable},
{sfXChainClaimAttestations, SoeRequired, SoeMutable},
{sfSignatureReward, SoeRequired, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object which describes a bidirectional trust line.
@@ -275,17 +275,17 @@ LEDGER_ENTRY(ltXCHAIN_OWNED_CLAIM_ID, 0x0071, XChainOwnedClaimID, xchain_owned_c
\sa keylet::line
*/
LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, state, ({
{sfBalance, SoeRequired},
{sfLowLimit, SoeRequired},
{sfHighLimit, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfLowNode, SoeOptional},
{sfLowQualityIn, SoeOptional},
{sfLowQualityOut, SoeOptional},
{sfHighNode, SoeOptional},
{sfHighQualityIn, SoeOptional},
{sfHighQualityOut, SoeOptional},
{sfBalance, SoeRequired, SoeMutable},
{sfLowLimit, SoeRequired, SoeMutable},
{sfHighLimit, SoeRequired, SoeMutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
{sfLowNode, SoeOptional, SoeImmutable},
{sfLowQualityIn, SoeOptional, SoeMutable},
{sfLowQualityOut, SoeOptional, SoeMutable},
{sfHighNode, SoeOptional, SoeImmutable},
{sfHighQualityIn, SoeOptional, SoeMutable},
{sfHighQualityOut, SoeOptional, SoeMutable},
}))
/** The ledger object which lists the network's fee settings.
@@ -296,16 +296,16 @@ LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, state, ({
*/
LEDGER_ENTRY(ltFEE_SETTINGS, 0x0073, FeeSettings, fee, ({
// Old version uses raw numbers
{sfBaseFee, SoeOptional},
{sfReferenceFeeUnits, SoeOptional},
{sfReserveBase, SoeOptional},
{sfReserveIncrement, SoeOptional},
{sfBaseFee, SoeOptional, SoeMutable},
{sfReferenceFeeUnits, SoeOptional, SoeMutable},
{sfReserveBase, SoeOptional, SoeMutable},
{sfReserveIncrement, SoeOptional, SoeMutable},
// New version uses Amounts
{sfBaseFeeDrops, SoeOptional},
{sfReserveBaseDrops, SoeOptional},
{sfReserveIncrementDrops, SoeOptional},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
{sfBaseFeeDrops, SoeOptional, SoeMutable},
{sfReserveBaseDrops, SoeOptional, SoeMutable},
{sfReserveIncrementDrops, SoeOptional, SoeMutable},
{sfPreviousTxnID, SoeOptional, SoeMutable},
{sfPreviousTxnLgrSeq, SoeOptional, SoeMutable},
}))
/** A claim id for a cross chain create account transaction.
@@ -313,13 +313,13 @@ LEDGER_ENTRY(ltFEE_SETTINGS, 0x0073, FeeSettings, fee, ({
\sa keylet::xChainCreateAccountClaimID
*/
LEDGER_ENTRY(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID, 0x0074, XChainOwnedCreateAccountClaimID, xchain_owned_create_account_claim_id, ({
{sfAccount, SoeRequired},
{sfXChainBridge, SoeRequired},
{sfXChainAccountCreateCount, SoeRequired},
{sfXChainCreateAccountAttestations, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAccount, SoeRequired, SoeImmutable},
{sfXChainBridge, SoeRequired, SoeImmutable},
{sfXChainAccountCreateCount, SoeRequired, SoeImmutable},
{sfXChainCreateAccountAttestations, SoeRequired, SoeMutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object describing a single escrow.
@@ -327,21 +327,21 @@ LEDGER_ENTRY(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID, 0x0074, XChainOwnedCreateAc
\sa keylet::escrow
*/
LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
{sfAccount, SoeRequired},
{sfSequence, SoeOptional},
{sfDestination, SoeRequired},
{sfAmount, SoeRequired},
{sfCondition, SoeOptional},
{sfCancelAfter, SoeOptional},
{sfFinishAfter, SoeOptional},
{sfSourceTag, SoeOptional},
{sfDestinationTag, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfDestinationNode, SoeOptional},
{sfTransferRate, SoeOptional},
{sfIssuerNode, SoeOptional},
{sfAccount, SoeRequired, SoeImmutable},
{sfSequence, SoeOptional, SoeImmutable},
{sfDestination, SoeRequired, SoeImmutable},
{sfAmount, SoeRequired, SoeImmutable},
{sfCondition, SoeOptional, SoeImmutable},
{sfCancelAfter, SoeOptional, SoeImmutable},
{sfFinishAfter, SoeOptional, SoeImmutable},
{sfSourceTag, SoeOptional, SoeImmutable},
{sfDestinationTag, SoeOptional, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
{sfDestinationNode, SoeOptional, SoeImmutable},
{sfTransferRate, SoeOptional, SoeImmutable},
{sfIssuerNode, SoeOptional, SoeImmutable},
}))
/** A ledger object describing a single unidirectional XRP payment channel.
@@ -349,21 +349,21 @@ LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
\sa keylet::payChan
*/
LEDGER_ENTRY(ltPAYCHAN, 0x0078, PayChannel, payment_channel, ({
{sfAccount, SoeRequired},
{sfDestination, SoeRequired},
{sfSequence, SoeOptional},
{sfAmount, SoeRequired},
{sfBalance, SoeRequired},
{sfPublicKey, SoeRequired},
{sfSettleDelay, SoeRequired},
{sfExpiration, SoeOptional},
{sfCancelAfter, SoeOptional},
{sfSourceTag, SoeOptional},
{sfDestinationTag, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfDestinationNode, SoeOptional},
{sfAccount, SoeRequired, SoeImmutable},
{sfDestination, SoeRequired, SoeImmutable},
{sfSequence, SoeOptional, SoeImmutable},
{sfAmount, SoeRequired, SoeMutable},
{sfBalance, SoeRequired, SoeMutable},
{sfPublicKey, SoeRequired, SoeImmutable},
{sfSettleDelay, SoeRequired, SoeImmutable},
{sfExpiration, SoeOptional, SoeMutable},
{sfCancelAfter, SoeOptional, SoeImmutable},
{sfSourceTag, SoeOptional, SoeImmutable},
{sfDestinationTag, SoeOptional, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
{sfDestinationNode, SoeOptional, SoeImmutable},
}))
/** The ledger object which tracks the AMM.
@@ -371,126 +371,126 @@ LEDGER_ENTRY(ltPAYCHAN, 0x0078, PayChannel, payment_channel, ({
\sa keylet::amm
*/
LEDGER_ENTRY(ltAMM, 0x0079, AMM, amm, ({
{sfAccount, SoeRequired},
{sfTradingFee, SoeDefault},
{sfVoteSlots, SoeOptional},
{sfAuctionSlot, SoeOptional},
{sfLPTokenBalance, SoeRequired},
{sfAsset, SoeRequired},
{sfAsset2, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
{sfAccount, SoeRequired, SoeImmutable},
{sfTradingFee, SoeDefault, SoeMutable},
{sfVoteSlots, SoeOptional, SoeMutable},
{sfAuctionSlot, SoeOptional, SoeMutable},
{sfLPTokenBalance, SoeRequired, SoeMutable},
{sfAsset, SoeRequired, SoeImmutable},
{sfAsset2, SoeRequired, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeOptional, SoeMutable},
{sfPreviousTxnLgrSeq, SoeOptional, SoeMutable},
}))
/** A ledger object which tracks MPTokenIssuance
\sa keylet::mptIssuance
*/
LEDGER_ENTRY(ltMPTOKEN_ISSUANCE, 0x007e, MPTokenIssuance, mpt_issuance, ({
{sfIssuer, SoeRequired},
{sfSequence, SoeRequired},
{sfTransferFee, SoeDefault},
{sfOwnerNode, SoeRequired},
{sfAssetScale, SoeDefault},
{sfMaximumAmount, SoeOptional},
{sfOutstandingAmount, SoeRequired},
{sfLockedAmount, SoeOptional},
{sfMPTokenMetadata, SoeOptional},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfDomainID, SoeOptional},
{sfMutableFlags, SoeDefault},
{sfReferenceHolding, SoeOptional},
{sfIssuer, SoeRequired, SoeImmutable},
{sfSequence, SoeRequired, SoeImmutable},
{sfTransferFee, SoeDefault, SoeMutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfAssetScale, SoeDefault, SoeImmutable},
{sfMaximumAmount, SoeOptional, SoeImmutable},
{sfOutstandingAmount, SoeRequired, SoeMutable},
{sfLockedAmount, SoeOptional, SoeMutable},
{sfMPTokenMetadata, SoeOptional, SoeMutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
{sfDomainID, SoeOptional, SoeMutable},
{sfMutableFlags, SoeDefault, SoeMutable},
{sfReferenceHolding, SoeOptional, SoeImmutable},
}))
/** A ledger object which tracks MPToken
\sa keylet::mptoken
*/
LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, mptoken, ({
{sfAccount, SoeRequired},
{sfMPTokenIssuanceID, SoeRequired},
{sfMPTAmount, SoeDefault},
{sfLockedAmount, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAccount, SoeRequired, SoeImmutable},
{sfMPTokenIssuanceID, SoeRequired, SoeImmutable},
{sfMPTAmount, SoeDefault, SoeMutable},
{sfLockedAmount, SoeOptional, SoeMutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object which tracks Oracle
\sa keylet::oracle
*/
LEDGER_ENTRY(ltORACLE, 0x0080, Oracle, oracle, ({
{sfOwner, SoeRequired},
{sfOracleDocumentID, SoeOptional},
{sfProvider, SoeRequired},
{sfPriceDataSeries, SoeRequired},
{sfAssetClass, SoeRequired},
{sfLastUpdateTime, SoeRequired},
{sfURI, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfOwner, SoeRequired, SoeImmutable},
{sfOracleDocumentID, SoeOptional, SoeImmutableSetOnce},
{sfProvider, SoeRequired, SoeImmutable},
{sfPriceDataSeries, SoeRequired, SoeMutable},
{sfAssetClass, SoeRequired, SoeImmutable},
{sfLastUpdateTime, SoeRequired, SoeMutable},
{sfURI, SoeOptional, SoeMutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object which tracks Credential
\sa keylet::credential
*/
LEDGER_ENTRY(ltCREDENTIAL, 0x0081, Credential, credential, ({
{sfSubject, SoeRequired},
{sfIssuer, SoeRequired},
{sfCredentialType, SoeRequired},
{sfExpiration, SoeOptional},
{sfURI, SoeOptional},
{sfIssuerNode, SoeRequired},
{sfSubjectNode, SoeOptional},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfSubject, SoeRequired, SoeImmutable},
{sfIssuer, SoeRequired, SoeImmutable},
{sfCredentialType, SoeRequired, SoeImmutable},
{sfExpiration, SoeOptional, SoeImmutable},
{sfURI, SoeOptional, SoeImmutable},
{sfIssuerNode, SoeRequired, SoeImmutable},
{sfSubjectNode, SoeOptional, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object which tracks PermissionedDomain
\sa keylet::permissionedDomain
*/
LEDGER_ENTRY(ltPERMISSIONED_DOMAIN, 0x0082, PermissionedDomain, permissioned_domain, ({
{sfOwner, SoeRequired},
{sfSequence, SoeRequired},
{sfAcceptedCredentials, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfOwner, SoeRequired, SoeImmutable},
{sfSequence, SoeRequired, SoeImmutable},
{sfAcceptedCredentials, SoeRequired, SoeMutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object representing permissions an account has delegated to another account.
\sa keylet::delegate
*/
LEDGER_ENTRY(ltDELEGATE, 0x0083, Delegate, delegate, ({
{sfAccount, SoeRequired},
{sfAuthorize, SoeRequired},
{sfPermissions, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfDestinationNode, SoeOptional},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAccount, SoeRequired, SoeImmutable},
{sfAuthorize, SoeRequired, SoeImmutable},
{sfPermissions, SoeRequired, SoeMutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfDestinationNode, SoeOptional, SoeImmutable},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
}))
/** A ledger object representing a single asset vault.
\sa keylet::vault
*/
LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfSequence, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfOwner, SoeRequired},
{sfAccount, SoeRequired},
{sfData, SoeOptional},
{sfAsset, SoeRequired},
{sfAssetsTotal, SoeDefault},
{sfAssetsAvailable, SoeDefault},
{sfAssetsMaximum, SoeDefault},
{sfLossUnrealized, SoeDefault},
{sfShareMPTID, SoeRequired},
{sfWithdrawalPolicy, SoeRequired},
{sfScale, SoeDefault},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
{sfSequence, SoeRequired, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfOwner, SoeRequired, SoeImmutable},
{sfAccount, SoeRequired, SoeImmutable},
{sfData, SoeOptional, SoeMutable},
{sfAsset, SoeRequired, SoeImmutable},
{sfAssetsTotal, SoeDefault, SoeMutable},
{sfAssetsAvailable, SoeDefault, SoeMutable},
{sfAssetsMaximum, SoeDefault, SoeMutable},
{sfLossUnrealized, SoeDefault, SoeMutable},
{sfShareMPTID, SoeRequired, SoeImmutable},
{sfWithdrawalPolicy, SoeRequired, SoeImmutable},
{sfScale, SoeDefault, SoeImmutable},
// no SharesTotal ever (use MPTIssuance.sfOutstandingAmount)
// no PermissionedDomainID ever (use MPTIssuance.sfDomainID)
}))
@@ -502,23 +502,23 @@ LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
\sa keylet::loanbroker
*/
LEDGER_ENTRY(ltLOAN_BROKER, 0x0088, LoanBroker, loan_broker, ({
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfSequence, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfVaultNode, SoeRequired},
{sfVaultID, SoeRequired},
{sfAccount, SoeRequired},
{sfOwner, SoeRequired},
{sfLoanSequence, SoeRequired},
{sfData, SoeDefault},
{sfManagementFeeRate, SoeDefault},
{sfOwnerCount, SoeDefault},
{sfDebtTotal, SoeDefault},
{sfDebtMaximum, SoeDefault},
{sfCoverAvailable, SoeDefault},
{sfCoverRateMinimum, SoeDefault},
{sfCoverRateLiquidation, SoeDefault},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
{sfSequence, SoeRequired, SoeImmutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfVaultNode, SoeRequired, SoeImmutable},
{sfVaultID, SoeRequired, SoeImmutable},
{sfAccount, SoeRequired, SoeImmutable},
{sfOwner, SoeRequired, SoeImmutable},
{sfLoanSequence, SoeRequired, SoeMutable},
{sfData, SoeDefault, SoeMutable},
{sfManagementFeeRate, SoeDefault, SoeImmutable},
{sfOwnerCount, SoeDefault, SoeMutable},
{sfDebtTotal, SoeDefault, SoeMutable},
{sfDebtMaximum, SoeDefault, SoeMutable},
{sfCoverAvailable, SoeDefault, SoeMutable},
{sfCoverRateMinimum, SoeDefault, SoeImmutable},
{sfCoverRateLiquidation, SoeDefault, SoeImmutable},
}))
/** A ledger object representing a loan between a Borrower and a Loan Broker
@@ -526,27 +526,27 @@ LEDGER_ENTRY(ltLOAN_BROKER, 0x0088, LoanBroker, loan_broker, ({
\sa keylet::loan
*/
LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfLoanBrokerNode, SoeRequired},
{sfLoanBrokerID, SoeRequired},
{sfLoanSequence, SoeRequired},
{sfBorrower, SoeRequired},
{sfLoanOriginationFee, SoeDefault},
{sfLoanServiceFee, SoeDefault},
{sfLatePaymentFee, SoeDefault},
{sfClosePaymentFee, SoeDefault},
{sfOverpaymentFee, SoeDefault},
{sfInterestRate, SoeDefault},
{sfLateInterestRate, SoeDefault},
{sfCloseInterestRate, SoeDefault},
{sfOverpaymentInterestRate, SoeDefault},
{sfStartDate, SoeRequired},
{sfPaymentInterval, SoeRequired},
{sfGracePeriod, SoeDefault},
{sfPreviousPaymentDueDate, SoeDefault},
{sfNextPaymentDueDate, SoeDefault},
{sfPreviousTxnID, SoeRequired, SoeMutable},
{sfPreviousTxnLgrSeq, SoeRequired, SoeMutable},
{sfOwnerNode, SoeRequired, SoeImmutable},
{sfLoanBrokerNode, SoeRequired, SoeImmutable},
{sfLoanBrokerID, SoeRequired, SoeImmutable},
{sfLoanSequence, SoeRequired, SoeImmutable},
{sfBorrower, SoeRequired, SoeImmutable},
{sfLoanOriginationFee, SoeDefault, SoeImmutable},
{sfLoanServiceFee, SoeDefault, SoeImmutable},
{sfLatePaymentFee, SoeDefault, SoeImmutable},
{sfClosePaymentFee, SoeDefault, SoeImmutable},
{sfOverpaymentFee, SoeDefault, SoeImmutable},
{sfInterestRate, SoeDefault, SoeImmutable},
{sfLateInterestRate, SoeDefault, SoeImmutable},
{sfCloseInterestRate, SoeDefault, SoeImmutable},
{sfOverpaymentInterestRate, SoeDefault, SoeImmutable},
{sfStartDate, SoeRequired, SoeImmutable},
{sfPaymentInterval, SoeRequired, SoeImmutable},
{sfGracePeriod, SoeDefault, SoeImmutable},
{sfPreviousPaymentDueDate, SoeDefault, SoeMutable},
{sfNextPaymentDueDate, SoeDefault, SoeMutable},
// The loan object tracks these values:
//
// - PaymentRemaining: The number of payments left in the loan. When it
@@ -594,17 +594,17 @@ LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
//
// Note the "True" values may differ significantly from the tracked
// rounded values.
{sfPaymentRemaining, SoeDefault},
{sfPeriodicPayment, SoeRequired},
{sfPrincipalOutstanding, SoeDefault},
{sfTotalValueOutstanding, SoeDefault},
{sfManagementFeeOutstanding, SoeDefault},
{sfPaymentRemaining, SoeDefault, SoeMutable},
{sfPeriodicPayment, SoeRequired, SoeMutable},
{sfPrincipalOutstanding, SoeDefault, SoeMutable},
{sfTotalValueOutstanding, SoeDefault, SoeMutable},
{sfManagementFeeOutstanding, SoeDefault, SoeMutable},
// Based on the computed total value at creation, used for
// rounding calculated values so they are all on a
// consistent scale - that is, they all have the same
// number of digits after the decimal point (excluding
// trailing zeros).
{sfLoanScale, SoeDefault},
{sfLoanScale, SoeDefault, SoeImmutable},
}))
#undef EXPAND

View File

@@ -27,7 +27,7 @@ public:
* @brief Construct a ledger entry wrapper from an existing SLE object.
* @param sle The underlying serialized ledger entry to wrap
*/
explicit LedgerEntryBase(SLE::const_pointer sle) : sle_(std::move(sle))
explicit LedgerEntryBase(std::shared_ptr<SLE const> sle) : sle_(std::move(sle))
{
}
@@ -151,7 +151,7 @@ public:
* @return A constant reference to the underlying SLE object
*/
[[nodiscard]]
SLE::const_pointer
std::shared_ptr<SLE const>
getSle() const
{
return sle_;
@@ -159,7 +159,7 @@ public:
protected:
/** @brief The underlying serialized ledger entry being wrapped. */
SLE::const_pointer sle_;
std::shared_ptr<SLE const> sle_;
};
} // namespace xrpl::ledger_entries

View File

@@ -27,7 +27,7 @@ public:
SF_UINT32::type::value_type flags = 0)
{
// Don't call object_.set(soTemplate) - keep object_ as a free object.
// This avoids creating STBase placeholders for soeDEFAULT fields,
// This avoids creating STBase placeholders for SoeDefault fields,
// which would cause applyTemplate() to throw "may not be explicitly
// set to default" when building the SLE.
// The SLE constructor will call applyTemplate() which properly

View File

@@ -35,7 +35,7 @@ public:
std::optional<SF_AMOUNT::type::value_type> fee)
{
// Don't call object_.set(soTemplate) - keep object_ as a free object.
// This avoids creating STBase placeholders for soeDEFAULT fields,
// This avoids creating STBase placeholders for SoeDefault fields,
// which would cause applyTemplate() to throw "may not be explicitly
// set to default" when building the STTx.
// The STTx constructor will call applyTemplate() which properly

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a AMM ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit AMM(SLE::const_pointer sle)
explicit AMM(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -256,7 +256,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
AMMBuilder(SLE::const_pointer sle)
AMMBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltAMM)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a AccountRoot ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit AccountRoot(SLE::const_pointer sle)
explicit AccountRoot(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -555,7 +555,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
AccountRootBuilder(SLE::const_pointer sle)
AccountRootBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltACCOUNT_ROOT)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a Amendments ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit Amendments(SLE::const_pointer sle)
explicit Amendments(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -166,7 +166,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
AmendmentsBuilder(SLE::const_pointer sle)
AmendmentsBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltAMENDMENTS)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a Bridge ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit Bridge(SLE::const_pointer sle)
explicit Bridge(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -210,7 +210,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
BridgeBuilder(SLE::const_pointer sle)
BridgeBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltBRIDGE)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a Check ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit Check(SLE::const_pointer sle)
explicit Check(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -269,7 +269,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
CheckBuilder(SLE::const_pointer sle)
CheckBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltCHECK)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a Credential ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit Credential(SLE::const_pointer sle)
explicit Credential(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -219,7 +219,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
CredentialBuilder(SLE::const_pointer sle)
CredentialBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltCREDENTIAL)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a DID ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit DID(SLE::const_pointer sle)
explicit DID(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -193,7 +193,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
DIDBuilder(SLE::const_pointer sle)
DIDBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltDID)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a Delegate ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit Delegate(SLE::const_pointer sle)
explicit Delegate(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -172,7 +172,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
DelegateBuilder(SLE::const_pointer sle)
DelegateBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltDELEGATE)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a DepositPreauth ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit DepositPreauth(SLE::const_pointer sle)
explicit DepositPreauth(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -170,7 +170,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
DepositPreauthBuilder(SLE::const_pointer sle)
DepositPreauthBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltDEPOSIT_PREAUTH)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a DirectoryNode ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit DirectoryNode(SLE::const_pointer sle)
explicit DirectoryNode(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -431,7 +431,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
DirectoryNodeBuilder(SLE::const_pointer sle)
DirectoryNodeBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltDIR_NODE)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a Escrow ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit Escrow(SLE::const_pointer sle)
explicit Escrow(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -363,7 +363,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
EscrowBuilder(SLE::const_pointer sle)
EscrowBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltESCROW)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a FeeSettings ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit FeeSettings(SLE::const_pointer sle)
explicit FeeSettings(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -285,7 +285,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
FeeSettingsBuilder(SLE::const_pointer sle)
FeeSettingsBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltFEE_SETTINGS)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a LedgerHashes ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit LedgerHashes(SLE::const_pointer sle)
explicit LedgerHashes(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -130,7 +130,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
LedgerHashesBuilder(SLE::const_pointer sle)
LedgerHashesBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltLEDGER_HASHES)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a Loan ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit Loan(SLE::const_pointer sle)
explicit Loan(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -607,7 +607,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
LoanBuilder(SLE::const_pointer sle)
LoanBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltLOAN)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a LoanBroker ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit LoanBroker(SLE::const_pointer sle)
explicit LoanBroker(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -378,7 +378,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
LoanBrokerBuilder(SLE::const_pointer sle)
LoanBrokerBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltLOAN_BROKER)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a MPToken ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit MPToken(SLE::const_pointer sle)
explicit MPToken(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -182,7 +182,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
MPTokenBuilder(SLE::const_pointer sle)
MPTokenBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltMPTOKEN)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a MPTokenIssuance ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit MPTokenIssuance(SLE::const_pointer sle)
explicit MPTokenIssuance(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -339,7 +339,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
MPTokenIssuanceBuilder(SLE::const_pointer sle)
MPTokenIssuanceBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltMPTOKEN_ISSUANCE)
{

View File

@@ -33,7 +33,7 @@ public:
* @brief Construct a NFTokenOffer ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit NFTokenOffer(SLE::const_pointer sle)
explicit NFTokenOffer(std::shared_ptr<SLE const> sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
@@ -208,7 +208,7 @@ public:
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
NFTokenOfferBuilder(SLE::const_pointer sle)
NFTokenOfferBuilder(std::shared_ptr<SLE const> sle)
{
if (sle->at(sfLedgerEntryType) != ltNFTOKEN_OFFER)
{

Some files were not shown because too many files have changed in this diff Show More