Compare commits

..

16 Commits

Author SHA1 Message Date
Bart
4a4fded2eb chore: Bump version to 3.4.0 2026-09-16 18:23:54 +02:00
yinyiqian1
c8e767afa4 fix: Reject PaymentBurn payments that cross zero balance 2026-09-16 18:23:28 +02:00
Pratik Mankawde
00eeb0a005 fix: Reject variable-length prefixes the encoder cannot write 2026-09-16 18:23:28 +02:00
Vito Tumas
a18839d92d fix: Relax MPT authorize cap for LoanSet and VaultWithdraw 2026-09-16 18:23:28 +02:00
Gregory Tsipenyuk
8c594c7ed9 fix: Skip CheckCash limit waiver for the issuer 2026-09-16 18:22:39 +02:00
Ayaz Salikhov
ebd810b184 build: Add missing script to conan package 2026-09-16 18:22:26 +02:00
Jingchen
3e4e56d6bb fix: Make calculateBaseFee exception-safe 2026-09-16 18:22:26 +02:00
Ayaz Salikhov
76da5d4475 build: Fix test installation on debian:11 due to EOL 2026-09-16 18:22:26 +02:00
Ayaz Salikhov
c0d0fd0d97 build: Add assert-enabled builds and packages 2026-09-16 18:22:26 +02:00
Timothy Banks
9aebb5ebea fix: Cap TMTransactions list size and charge fee for undeserializable transactions 2026-09-16 18:22:26 +02:00
Vito Tumas
796f2f8f1e fix: Relax Loan Invariants to allow zero-principal LoanPay transaction 2026-09-16 18:22:26 +02:00
Timothy Banks
b190f2b14f test: Add ProtocolMessage harness for testing TMPing 2026-09-16 18:22:25 +02:00
Timothy Banks
6099940c2c fix: Unbounded Database Seek via TMGetLedger 2026-09-04 15:32:36 +01:00
Ed Hennis
0db7b766e6 fix: Trim unknown fields when parsing incoming peer protobuf messages 2026-09-04 10:32:08 +00:00
Mayukha Vadari
ea6226b8b9 fix: Prevent simulate from updating the orderbook db 2026-09-04 06:17:43 -04:00
Timothy Banks
eae0a35415 fix: Use a hardened hash on the STPathElement 2026-09-03 17:06:27 -04:00
362 changed files with 3257 additions and 56464 deletions

View File

@@ -7,8 +7,6 @@ ignorePaths:
- cmake/**
- LICENSE.md
- .clang-tidy
- src/test/app/wasm_fixtures/**/*.wat
- src/test/app/wasm_fixtures/*.c
- nix/check-tools/*.txt # generated, and full of Nix store hashes
language: en
allowCompoundWords: true # TODO (#6334)
@@ -70,7 +68,6 @@ words:
- Btrfs
- Buildx
- canonicality
- cdylib
- canonicalised
- cctools
- changespq
@@ -117,7 +114,7 @@ words:
- dsymutil
- dxrpl
- elgamal
- emittance
- enabled
- enablerepo
- endmacro
- envrc
@@ -144,6 +141,7 @@ words:
- hwrap
- ifndef
- inequation
- Injectivity
- insuf
- insuff
- invasively
@@ -309,9 +307,7 @@ words:
- statsd
- STATSDCOLLECTOR
- stissue
- stjson
- stnum
- stnumber
- stobj
- stobject
- stpath
@@ -380,7 +376,6 @@ words:
- xbridge
- xchain
- xcrun
- xfloat
- ximinez
- XMACRO
- xored

2
.github/CODEOWNERS vendored
View File

@@ -1,2 +0,0 @@
# Allow anyone to review any change by default.
*

View File

@@ -19,7 +19,6 @@ libxrpl.ledger > xrpl.json
libxrpl.ledger > xrpl.ledger
libxrpl.ledger > xrpl.nodestore
libxrpl.ledger > xrpl.protocol
libxrpl.ledger > xrpl.server
libxrpl.ledger > xrpl.shamap
libxrpl.net > xrpl.basics
libxrpl.net > xrpl.net
@@ -207,7 +206,6 @@ xrpl.core > xrpl.json
xrpl.core > xrpl.protocol
xrpl.json > xrpl.basics
xrpl.ledger > xrpl.basics
xrpl.ledger > xrpl.core
xrpl.ledger > xrpl.json
xrpl.ledger > xrpl.nodestore
xrpl.ledger > xrpl.protocol

View File

@@ -15,6 +15,14 @@ _BASE_CMAKE_ARGS = [
"-Drust=ON",
]
# The package formats a config can be packaged as, each with its own
# install-test job in reusable-package.yml.
PACKAGE_TYPES = ("deb", "rpm")
# The package name a variant suffixes, as build_pkg.py's BASE_NAME spells it:
# the two have to agree, or the artifact globs miss what was built.
BASE_NAME = "xrpld"
# Maps sanitizer names (as used in cmake) to short config-name suffixes.
_SANITIZER_SUFFIX: dict[str, str] = {
"address": "asan",
@@ -62,10 +70,20 @@ def get_cmake_args(build_type: str, extra_args: str) -> str:
class PackageConfig:
"""The 'package' map of a config whose binaries are also packaged."""
type: str # "deb" or "rpm"; has to match what the image provides
type: str # has to match what the image provides
# The packaging container image: a vanilla distro image, not the nix image
# the config itself builds in.
image: str
# A flavour of the package, named xrpld-<variant>, for a config whose
# binaries are not the plain release build. A variant needs no counterpart
# in the other format.
variant: str = ""
def __post_init__(self) -> None:
assert self.type in PACKAGE_TYPES, (
f"unsupported package type {self.type!r}: "
f"use one of {', '.join(PACKAGE_TYPES)}."
)
@dataclasses.dataclass
@@ -178,6 +196,8 @@ class PackagingEntry:
validator_keys_artifact_name: str
image: str
package_type: str # "deb" or "rpm"; drives the format-specific steps
package_variant: str # passed to build_pkg.py --variant; empty for xrpld
package_name: str # the name it builds under, which the artifact globs use
# ---------------------------------------------------------------------------
@@ -267,12 +287,32 @@ def expand_linux_packaging(linux: LinuxFile) -> list[PackagingEntry]:
validator_keys_artifact_name=f"validator-keys-{name}",
image=cfg.package.image,
package_type=cfg.package.type,
package_variant=cfg.package.variant,
package_name=(
f"{BASE_NAME}-{cfg.package.variant}"
if cfg.package.variant
else BASE_NAME
),
)
)
return entries
def package_names_by_type(entries: list[PackagingEntry]) -> dict[str, list[str]]:
"""The names of the packages in 'entries', keyed by format.
Derived from the packaging matrix rather than listed again, so the packages
the install-test jobs look for are the packages that were built.
"""
return {
package_type: sorted(
{e.package_name for e in entries if e.package_type == package_type}
)
for package_type in PACKAGE_TYPES
}
def expand_platform_matrix(pf: PlatformFile, minimal: bool) -> list[MatrixEntry]:
"""Expand a PlatformFile (macOS or Windows) into matrix entries.
@@ -341,6 +381,10 @@ if __name__ == "__main__":
if args.packaging:
matrix = expand_linux_packaging(LinuxFile.load(THIS_DIR / "linux.json"))
# One list per format, so each install-test job installs the packages its
# own format produced.
for package_type, names in package_names_by_type(matrix).items():
print(f"{package_type}_package_names={json.dumps(names)}")
else:
if args.config in ("linux", None):
matrix += expand_linux_matrix(

View File

@@ -1,5 +1,5 @@
{
"image_tag": "sha-060957e",
"image_tag": "sha-473fe44",
"configs": {
"ubuntu": [
{
@@ -76,6 +76,19 @@
"type": "deb",
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-49cdc10"
}
},
{
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["amd64"],
"minimal": false,
"suffix": "assert",
"extra_cmake_args": "-Dvalidator_keys=ON -Dassert=ON",
"package": {
"type": "deb",
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-49cdc10",
"variant": "assert"
}
}
],

View File

@@ -5,13 +5,15 @@ on:
branches:
- develop
paths:
- ".github/workflows/build-nix-images.yml"
- "flake.nix"
- "flake.lock"
- "rust-toolchain.toml"
- "nix/**"
- "!nix/docker/README.md"
- "!nix/devshell.nix"
- "!nix/check-tools/**"
- "!nix/check-tools/*.txt"
- "bin/check-tools.sh"
- "bin/default-loader-path.sh"
- "bin/install-sanitizer-libs.sh"
pull_request:
@@ -23,7 +25,7 @@ on:
- "nix/**"
- "!nix/docker/README.md"
- "!nix/devshell.nix"
- "!nix/check-tools/**"
- "!nix/check-tools/*.txt"
- "bin/check-tools.sh"
- "bin/default-loader-path.sh"
- "bin/install-sanitizer-libs.sh"

View File

@@ -34,7 +34,7 @@ permissions:
jobs:
audit:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-473fe44
permissions:
contents: read
# Needed to open an issue on scheduled failures.

View File

@@ -85,6 +85,7 @@ jobs:
.github/workflows/reusable-build-test.yml
.github/workflows/reusable-check-autogen.yml
.github/workflows/reusable-clang-tidy.yml
.github/workflows/reusable-package-test-install.yml
.github/workflows/reusable-package.yml
.github/workflows/reusable-rust.yml
.github/workflows/reusable-strategy-matrix.yml

View File

@@ -23,6 +23,7 @@ on:
- ".github/workflows/reusable-build-test.yml"
- ".github/workflows/reusable-check-autogen.yml"
- ".github/workflows/reusable-clang-tidy.yml"
- ".github/workflows/reusable-package-test-install.yml"
- ".github/workflows/reusable-package.yml"
- ".github/workflows/reusable-rust.yml"
- ".github/workflows/reusable-strategy-matrix.yml"

View File

@@ -41,7 +41,7 @@ env:
jobs:
build:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-473fe44
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -91,4 +91,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deploy
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0

View File

@@ -34,7 +34,7 @@ jobs:
needs: [determine-files]
if: ${{ needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.need_full_run == 'true' }}
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-060957e"
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-473fe44"
permissions:
contents: read
issues: write

View File

@@ -0,0 +1,120 @@
# Install one package format on every distro family it targets, one job per
# package name and image, and run the binaries there. Called once per format by
# reusable-package.yml, which owns the names and the image lists.
name: Install packages
on:
workflow_call:
inputs:
package_type:
description: 'The package format to install ("deb" or "rpm").'
required: true
type: string
package_names:
description: "JSON array of package names built for this format."
required: true
type: string
images:
description: "JSON array of container images to install in."
required: true
type: string
defaults:
run:
shell: bash
env:
PACKAGE_DIR: packages
jobs:
install:
strategy:
fail-fast: false
matrix:
package_name: ${{ fromJson(inputs.package_names) }}
image: ${{ fromJson(inputs.images) }}
name: "${{ matrix.package_name }} on ${{ matrix.image }}"
permissions:
contents: read
runs-on: ubuntu-latest
container: ${{ matrix.image }}
timeout-minutes: 5
steps:
# Every package lands in one directory; the step below picks its own,
# which keeps this independent of the artifact names.
- name: Download package artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: "*-pkg"
merge-multiple: true
path: ${{ env.PACKAGE_DIR }}
- name: Find the package
id: find
env:
PACKAGE_NAME: ${{ matrix.package_name }}
PACKAGE_TYPE: ${{ inputs.package_type }}
run: |
# The version follows the name, separated by '_' in a DEB and '-' in an
# RPM. Requiring a digit after it is what keeps 'xrpld' from picking up
# another package, such as 'xrpld-assert'.
pattern="${PACKAGE_NAME}[_-][0-9]*.${PACKAGE_TYPE}"
package="$(find "${PACKAGE_DIR}" -type f -name "${pattern}" -print -quit)"
test -n "${package}" || {
echo "no ${pattern} found in ${PACKAGE_DIR}" >&2
exit 1
}
echo "package=${package}" >>"${GITHUB_OUTPUT}"
# Debian 11 went end-of-life on 2026-08-31
# (https://www.debian.org/News/2026/20260831) and its packages are
# already partly gone from deb.debian.org, so switch to the
# snapshot.debian.org entries the image ships commented out in its
# sources.list: they are pinned to the snapshot the image was built
# from, so they serve every version it needs and never go away.
# Snapshots keep their original, long-passed Valid-Until, hence the
# disabled check; the retries absorb snapshot.debian.org's throttling.
- name: Switch Debian 11 to snapshot.debian.org
if: ${{ matrix.image == 'debian:11' }}
run: |
sed -i 's|^deb |# deb |; s|^# deb http://snapshot|deb http://snapshot|' /etc/apt/sources.list
printf '%s\n' \
'Acquire::Check-Valid-Until "false";' \
'Acquire::Retries "3";' \
>/etc/apt/apt.conf.d/99snapshot
- name: Install the DEB
if: ${{ inputs.package_type == 'deb' }}
env:
DEBIAN_FRONTEND: noninteractive
PACKAGE: ${{ steps.find.outputs.package }}
run: |
# Stock Debian and Ubuntu images carry no package lists, so apt has
# nothing to resolve the systemd dependency from until it fetches them.
apt-get update -qq
apt-get install -y "./${PACKAGE}"
- name: Install the RPM
if: ${{ inputs.package_type == 'rpm' }}
env:
PACKAGE: ${{ steps.find.outputs.package }}
run: dnf install -y "./${PACKAGE}"
- name: Run xrpld
run: xrpld --version
- name: Run validator-keys
run: validator-keys --version
- name: Run rippled, the legacy compatibility symlink
run: rippled --version
- name: Check the service account
run: id xrpld
- name: Check the state directory
run: test -d /var/lib/xrpld
- name: Check the log directory
run: test -d /var/log/xrpld

View File

@@ -3,8 +3,10 @@
#
# - 'package' builds and signs one format per config that carries a "package"
# map in linux.json; that map names the container image and the format
# - 'test-install' installs what was built on a range of distros and runs the
# binaries there, so a package that cannot be installed never reaches Nexus
# - 'test-install-deb' and 'test-install-rpm' call
# reusable-package-test-install.yml to install what was built on a range of
# distros and run the binaries there, so a package that cannot be installed
# never reaches Nexus
# - 'publish' uploads with the image's publish_pkg.py, doing a --dry-run
# unless 'publish: true'
#
@@ -49,6 +51,8 @@ jobs:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate.outputs.matrix }}
deb_package_names: ${{ steps.generate.outputs.deb_package_names }}
rpm_package_names: ${{ steps.generate.outputs.rpm_package_names }}
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -107,6 +111,7 @@ jobs:
- name: Build package
env:
PACKAGE_TYPE: ${{ matrix.package_type }}
PACKAGE_VARIANT: ${{ matrix.package_variant }}
PKG_RELEASE: ${{ steps.release_info.outputs.pkg_release }}
CHANNEL: ${{ steps.release_info.outputs.channel }}
run: |
@@ -114,6 +119,7 @@ jobs:
--package-type "${PACKAGE_TYPE}" \
--build-dir "${BUILD_DIR}" \
--pkg-release "${PKG_RELEASE}" \
--variant "${PACKAGE_VARIANT}" \
--channel "${CHANNEL}"
# Before the upload, so the artifact, the tested package and the published
@@ -125,14 +131,17 @@ jobs:
run: ./package/sign_rpm.py --package-dir "${BUILD_DIR}"
# Split from the debug symbols, which are an order of magnitude larger, so
# that test-install downloads only what it installs.
# that test-install downloads only what it installs. In the globs below the
# version follows the name, separated by '_' in a DEB and '-' in an RPM. A
# version starts with a digit and a longer name does not, so that one digit
# is what tells 'xrpld-3.4.1-...' from 'xrpld-assert-3.4.1-...'.
- name: Upload package artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ matrix.xrpld_artifact_name }}-pkg
path: |
${{ env.BUILD_DIR }}/debbuild/xrpld_*.deb
${{ env.BUILD_DIR }}/rpmbuild/RPMS/**/xrpld-[0-9]*.rpm
${{ env.BUILD_DIR }}/debbuild/${{ matrix.package_name }}_[0-9]*.deb
${{ env.BUILD_DIR }}/rpmbuild/RPMS/**/${{ matrix.package_name }}-[0-9]*.rpm
if-no-files-found: error
- name: Upload debug symbol artifact
@@ -140,129 +149,52 @@ jobs:
with:
name: ${{ matrix.xrpld_artifact_name }}-pkg-debug
path: |
${{ env.BUILD_DIR }}/debbuild/xrpld-dbgsym_*.deb
${{ env.BUILD_DIR }}/debbuild/xrpld-dbgsym_*.ddeb
${{ env.BUILD_DIR }}/rpmbuild/RPMS/**/xrpld-debuginfo-*.rpm
${{ env.BUILD_DIR }}/debbuild/${{ matrix.package_name }}-dbgsym_[0-9]*.deb
${{ env.BUILD_DIR }}/debbuild/${{ matrix.package_name }}-dbgsym_[0-9]*.ddeb
${{ env.BUILD_DIR }}/rpmbuild/RPMS/**/${{ matrix.package_name }}-debuginfo-[0-9]*.rpm
if-no-files-found: error
# Every distro family the packages target, oldest release first, so both ends
# of the dependency range they declare are exercised.
test-install:
needs: [package]
strategy:
fail-fast: false
matrix:
include:
- package_type: deb
image: debian:11
- package_type: deb
image: debian:12
- package_type: deb
image: debian:13
- package_type: deb
image: ubuntu:20.04
- package_type: deb
image: ubuntu:22.04
- package_type: deb
image: ubuntu:24.04
- package_type: deb
image: ubuntu:26.04
# One call per format, so a variant packaged for one format is installed for
# that format alone. The images are every distro family that format targets,
# oldest release first, so both ends of the dependency range the packages
# declare are exercised.
test-install-deb:
needs: [generate-matrix, package]
name: install deb
uses: ./.github/workflows/reusable-package-test-install.yml
with:
package_type: deb
package_names: ${{ needs.generate-matrix.outputs.deb_package_names }}
images: |
[
"debian:11",
"debian:12",
"debian:13",
"ubuntu:20.04",
"ubuntu:22.04",
"ubuntu:24.04",
"ubuntu:26.04"
]
- package_type: rpm
image: almalinux:9
- package_type: rpm
image: almalinux:10
- package_type: rpm
image: rockylinux/rockylinux:9
- package_type: rpm
image: rockylinux/rockylinux:10
- package_type: rpm
image: registry.access.redhat.com/ubi9/ubi
- package_type: rpm
image: registry.access.redhat.com/ubi10/ubi
name: "install ${{ matrix.package_type }} on ${{ matrix.image }}"
permissions:
contents: read
runs-on: ubuntu-latest
container: ${{ matrix.image }}
timeout-minutes: 5
steps:
# Both formats land in one directory; the step below picks its own by
# extension, so this stays independent of the artifact names.
- name: Download package artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: "*-pkg"
merge-multiple: true
path: ${{ env.PACKAGE_DIR }}
- name: Find the package
id: find
env:
PACKAGE_TYPE: ${{ matrix.package_type }}
run: |
package="$(find "${PACKAGE_DIR}" -type f -name "*.${PACKAGE_TYPE}" -print -quit)"
test -n "${package}" || {
echo "no .${PACKAGE_TYPE} found in ${PACKAGE_DIR}" >&2
exit 1
}
echo "package=${package}" >>"${GITHUB_OUTPUT}"
# Debian 11 went end-of-life on 2026-08-31
# (https://www.debian.org/News/2026/20260831) and its packages are
# already partly gone from deb.debian.org, so switch to the
# snapshot.debian.org entries the image ships commented out in its
# sources.list: they are pinned to the snapshot the image was built
# from, so they serve every version it needs and never go away.
# Snapshots keep their original, long-passed Valid-Until, hence the
# disabled check; the retries absorb snapshot.debian.org's throttling.
- name: Switch Debian 11 to snapshot.debian.org
if: ${{ matrix.image == 'debian:11' }}
run: |
sed -i 's|^deb |# deb |; s|^# deb http://snapshot|deb http://snapshot|' /etc/apt/sources.list
printf '%s\n' \
'Acquire::Check-Valid-Until "false";' \
'Acquire::Retries "3";' \
>/etc/apt/apt.conf.d/99snapshot
- name: Install the DEB
if: ${{ matrix.package_type == 'deb' }}
env:
DEBIAN_FRONTEND: noninteractive
PACKAGE: ${{ steps.find.outputs.package }}
run: |
# Stock Debian and Ubuntu images carry no package lists, so apt has
# nothing to resolve the systemd dependency from until it fetches them.
apt-get update -qq
apt-get install -y "./${PACKAGE}"
- name: Install the RPM
if: ${{ matrix.package_type == 'rpm' }}
env:
PACKAGE: ${{ steps.find.outputs.package }}
run: dnf install -y "./${PACKAGE}"
- name: Run xrpld
run: xrpld --version
- name: Run validator-keys
run: validator-keys --version
- name: Run rippled, the legacy compatibility symlink
run: rippled --version
- name: Check the service account
run: id xrpld
- name: Check the state directory
run: test -d /var/lib/xrpld
- name: Check the log directory
run: test -d /var/log/xrpld
test-install-rpm:
needs: [generate-matrix, package]
name: install rpm
uses: ./.github/workflows/reusable-package-test-install.yml
with:
package_type: rpm
package_names: ${{ needs.generate-matrix.outputs.rpm_package_names }}
images: |
[
"almalinux:9",
"almalinux:10",
"rockylinux/rockylinux:9",
"rockylinux/rockylinux:10",
"registry.access.redhat.com/ubi9/ubi",
"registry.access.redhat.com/ubi10/ubi"
]
publish:
needs: [generate-matrix, package, test-install]
needs: [generate-matrix, package, test-install-deb, test-install-rpm]
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}

View File

@@ -1,9 +1,8 @@
# Clippy, coverage and documentation for the Rust crates in crates/. Each runs
# as an independent job on a GitHub-hosted runner, but inside the same container
# image used to build the crates in the C++/Corrosion path, so the toolchain
# (and therefore the lints and the cargo cache) matches what production builds
# use. Coverage is the exception: it needs the nightly rustc that honours
# #[coverage(off)], which the image carries alongside the pinned stable.
# (and therefore the lints, coverage instrumentation and the cargo cache) matches
# what production builds use.
#
# Rust unit tests are deliberately NOT run here. They run as part of the C++
# build (reusable-build-test-config.yml), which already compiles the crates on a
@@ -28,7 +27,7 @@ permissions:
jobs:
clippy:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-473fe44
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -41,14 +40,11 @@ jobs:
coverage:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-473fe44
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Use the nightly Rust toolchain
run: rust-nightly path >>"${GITHUB_PATH}"
- name: Use cargo artifacts cache
uses: ./.github/actions/cargo-cache
@@ -70,7 +66,7 @@ jobs:
doc:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-473fe44
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

View File

@@ -40,7 +40,7 @@ defaults:
jobs:
upload:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-473fe44
env:
REMOTE_NAME: ${{ inputs.remote_name }}
CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.remote_username }}

View File

@@ -70,11 +70,6 @@ repos:
language: system
types: [rust]
pass_filenames: false # rustfmt formats the whole workspace
- id: check-coverage-attrs
name: check Rust coverage attributes
entry: ./bin/pre-commit/check_rust_coverage_attrs.py
language: python
files: ^crates/.*\.rs$
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
rev: e98930bdc210d3387007f9252d8c1694ea7e410f # frozen: 0.27.7

View File

@@ -114,7 +114,6 @@ find_package(OpenSSL REQUIRED)
find_package(secp256k1 REQUIRED)
find_package(SOCI REQUIRED)
find_package(SQLite3 REQUIRED)
find_package(wasmi REQUIRED)
find_package(xxHash REQUIRED)
target_link_libraries(

View File

@@ -158,7 +158,6 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
check cargo-nextest cargo nextest --version
check clippy-driver
check rust-analyzer
check rust-nightly rust-nightly run rustc --version
check rustc
check rustfmt
fi

View File

@@ -1,149 +0,0 @@
#!/usr/bin/env python3
"""
Check that Rust unit tests stay out of the coverage report.
cargo-llvm-cov instruments the test code along with everything else, so a test
module that is not excluded counts its own body as covered and inflates the
reported number. Excluding it takes two attributes:
* every `#[cfg(test)]` module carries
`#[cfg_attr(coverage_nightly, coverage(off))]`;
* every crate root (lib.rs, main.rs) carries
`#![cfg_attr(coverage_nightly, feature(coverage_attribute))]`, which the
attribute above needs in order to compile.
Both are inert outside the coverage job: cargo-llvm-cov defines
`coverage_nightly` only when it runs on a nightly toolchain.
The crate-root gate is checked even in a crate that has no tests yet, because
that is what lets the first test module added later carry the attribute without
a build failure. Missing it is a hard error, so it cannot go unnoticed; a
missing `coverage(off)` fails open, which is why this check exists.
Matching is on exact attribute text, which works because `cargo fmt` runs over
the whole workspace in the hook ahead of this one: rustfmt puts every attribute
on its own line and normalizes what is inside it, turning `#[cfg( test )]`
and `#[cfg(test,)]` alike into `#[cfg(test)]`. So there is nothing here that
parses Rust. The price is that a cfg this file does not spell out literally --
`all(test, ...)`, `any(test, ...)`, `not(test)` -- is reported rather than
classified, on the grounds that guessing at coverage semantics is how a check
like this ends up quietly wrong.
Usage: ./bin/pre-commit/check_rust_coverage_attrs.py <file1> <file2> ...
Exit status is non-zero if any violation is found.
"""
import re
import sys
from dataclasses import dataclass
from pathlib import Path
CRATE_ROOTS = {"lib.rs", "main.rs"}
FEATURE_ATTR = "#![cfg_attr(coverage_nightly, feature(coverage_attribute))]"
COVERAGE_OFF_ATTR = "#[cfg_attr(coverage_nightly, coverage(off))]"
CFG_TEST_ATTR = "#[cfg(test)]"
# Any other cfg that mentions `test`. String literals are blanked before this
# runs, so `feature = "test"` does not read as the `test` cfg.
RE_CFG_MENTIONS_TEST = re.compile(r"^#\[cfg\(.*\btest\b.*\)\]$")
RE_STRING = re.compile(r'"(?:[^"\\]|\\.)*"')
RE_MOD = re.compile(r"^(?:pub(?:\([^)]*\))?\s+)?mod\s+([A-Za-z_]\w*)")
@dataclass(frozen=True)
class Finding:
line: int
label: str
message: str
def _check_module(attrs: list[str], line: int, name: str) -> list[Finding]:
"""Findings for one module, given the attributes attached to it."""
if COVERAGE_OFF_ATTR in attrs:
return [] # excluded from coverage; which cfg gates it does not matter
if CFG_TEST_ATTR in attrs:
return [
Finding(
line,
"missing-coverage-off",
f"`mod {name}` is #[cfg(test)] but not excluded from coverage; "
f"add {COVERAGE_OFF_ATTR}",
)
]
unclassified = [
attr for attr in attrs if RE_CFG_MENTIONS_TEST.match(RE_STRING.sub('""', attr))
]
if unclassified:
return [
Finding(
line,
"unclassified-cfg",
f"`mod {name}` is gated on {unclassified[0]}, which this check "
f"cannot tell apart from a module that ships in the library; "
f"add {COVERAGE_OFF_ATTR} if it is test-only, or teach this "
f"check the cfg if it is not",
)
]
return []
def _check_test_modules(lines: list[str]) -> list[Finding]:
"""Findings for every test module that is not excluded from coverage."""
findings: list[Finding] = []
attrs: list[str] = []
attrs_line = 0
for number, raw in enumerate(lines, start=1):
stripped = raw.strip()
# Blank lines and comments are allowed between an attribute and its item.
if not stripped or stripped.startswith("//"):
continue
if stripped.startswith("#["):
if not attrs:
attrs_line = number
attrs.append(stripped)
continue
module = RE_MOD.match(stripped)
if module is not None and attrs:
findings += _check_module(attrs, attrs_line, module.group(1))
attrs = []
return findings
def _check_crate_root(name: str, lines: list[str]) -> list[Finding]:
"""A finding if a crate root is missing the coverage_attribute feature gate."""
if name not in CRATE_ROOTS:
return []
if any(line.strip() == FEATURE_ATTR for line in lines):
return []
return [
Finding(
1,
"missing-feature-gate",
f"crate root is missing {FEATURE_ATTR}",
)
]
def check_source(name: str, text: str) -> list[Finding]:
"""Findings for one file's contents; `name` is its base name (lib.rs, ...)."""
lines = text.splitlines()
return _check_crate_root(name, lines) + _check_test_modules(lines)
def check_file(path: Path) -> list[Finding]:
return check_source(path.name, path.read_text(encoding="utf-8"))
def main() -> int:
total = 0
for path in (Path(name) for name in sys.argv[1:]):
for finding in check_file(path):
total += 1
print(f"{path}:{finding.line}: {finding.label}: {finding.message}")
return 1 if total else 0
if __name__ == "__main__":
sys.exit(main())

View File

@@ -1360,39 +1360,6 @@
# Example:
# owner_reserve = 200000 # 0.2 XRP
#
# gas_limit = <gas>
#
# The gas limit is the maximum amount of gas that can be
# consumed by a single transaction. The gas limit is used to prevent
# transactions from consuming too many resources.
#
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# gas_limit = 1000000 # 1 million gas
#
# bytecode_size_limit = <bytes>
#
# The bytecode size limit is the maximum size of a WASM extension in
# bytes. The size limit is used to prevent extensions from consuming
# too many resources.
#
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# bytecode_size_limit = 100000 # 100 kb
#
# gas_price = <micro-drops>
#
# The gas price is the conversion between WASM gas and its price in drops.
#
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# gas_price = 1000000 # 1 drop per gas
#-------------------------------------------------------------------------------
#
# 9. Misc Settings

View File

@@ -69,7 +69,6 @@ target_link_libraries(
Xrpl::opts
Xrpl::syslibs
secp256k1::secp256k1
wasmi::wasmi
xrpl.libpb
xxHash::xxhash
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>

View File

@@ -44,12 +44,18 @@ else()
set(pkg_type rpm)
endif()
# Unquoted below, so an empty value adds no argument at all.
set(pkg_variant_option "")
if(assert)
set(pkg_variant_option --variant=assert)
endif()
add_custom_target(
package
COMMAND
${CMAKE_SOURCE_DIR}/package/build_pkg.py --package-type=${pkg_type}
--build-dir=${CMAKE_BINARY_DIR} --pkg-release=${pkg_release}
--channel=UNRELEASED
${pkg_variant_option} --channel=UNRELEASED
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS xrpld validator-keys
COMMENT "Building Linux ${pkg_type} package"

View File

@@ -61,7 +61,6 @@ SETTING_DEFAULTS = {
"delegable": "Delegation::NotDelegable",
"amendment": "uint256{}",
"privileges": "Privilege::NoPriv",
"emittance": "Emittance::Emitable",
}

View File

@@ -3,7 +3,6 @@
"requires": [
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1782392402.420688",
"wasmi/1.0.9#1fecdab9b90c96698eb35ea99ca4f5cb%1782307153.343419",
"sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1782392403.185447",
"soci/4.0.3#e726491a03468795453f7c83fc924a96%1782392402.679521",
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1782307151.633168",

View File

@@ -36,7 +36,6 @@ class Xrpl(ConanFile):
"nudb/2.0.9",
"openssl/3.6.3",
"soci/4.0.3",
"wasmi/1.0.9",
"zlib/1.3.2",
]
@@ -150,6 +149,7 @@ class Xrpl(ConanFile):
self.requires("xxhash/0.8.3", transitive_headers=True)
exports_sources = (
"bin/default-loader-path.sh",
"CMakeLists.txt",
"cfg/*",
"cmake/*",
@@ -225,7 +225,6 @@ class Xrpl(ConanFile):
"soci::soci",
"secp256k1::secp256k1",
"sqlite3::sqlite",
"wasmi::wasmi",
"xxhash::xxhash",
"zlib::zlib",
]

View File

@@ -8,9 +8,6 @@ cxx = { version = "1.0.198", features = ["c++20"] }
[workspace.package]
edition = "2024"
[workspace.lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = [ 'cfg(coverage)', 'cfg(coverage_nightly)' ] }
[profile.release]
opt-level = 3
overflow-checks = true

View File

@@ -8,6 +8,3 @@ crate-type = ["staticlib"]
[dependencies]
cxx.workspace = true
[lints]
workspace = true

View File

@@ -1,5 +1,3 @@
#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
#[cxx::bridge(namespace = "rs::hello_world")]
mod ffi {
extern "Rust" {
@@ -10,14 +8,3 @@ mod ffi {
pub fn hello_world() -> String {
"hello_world".to_string()
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn hello_world_returns_hello_world() {
assert_eq!(hello_world(), "hello_world")
}
}

View File

@@ -6,7 +6,8 @@
`xrpld` is published as DEB and RPM packages for 64-bit x86 Linux.
Use APT on Debian-based distributions such as Debian and Ubuntu,
and YUM on Red Hat-based distributions such as RHEL, AlmaLinux, and Rocky Linux.
and DNF on Red Hat-based distributions such as RHEL, AlmaLinux, and Rocky Linux,
where `yum` is a symlink to `dnf`.
To build from source instead, see [BUILD.md](../BUILD.md).
## Release channels
@@ -81,7 +82,7 @@ wherever it appears in the repository configuration.
sudo apt -y install xrpld
```
### With the YUM package manager
### With the DNF package manager
1. Add the XRPL Foundation package-signing key:
@@ -109,9 +110,23 @@ wherever it appears in the repository configuration.
3. Install the `xrpld` package:
```bash
sudo yum install -y xrpld
sudo dnf install -y xrpld
```
### Optional: the assert-enabled build
Every channel also carries `xrpld-assert` as a DEB, the same build with assertions
enabled, for diagnosing a problem on a non-production server.
It installs the same files as `xrpld` and replaces it, so install one or the other:
```bash
sudo apt -y install xrpld-assert # APT removes xrpld itself
```
Switching stops the service, since it is a removal and an installation rather than an upgrade,
and APT starts it again.
Install `xrpld` the same way to switch back.
## The xrpld service
Both package managers install a systemd unit and enable it, so `xrpld` starts on boot.
@@ -121,7 +136,7 @@ Check whether it is already running:
systemctl status xrpld.service
```
The APT packages start it immediately as well; the YUM packages do not, so start it yourself:
The DEB packages start it immediately as well; the RPM packages do not, so start it yourself:
```bash
sudo systemctl start xrpld.service

View File

@@ -543,21 +543,8 @@ public:
setround(RoundingMode inMode);
/**
* Convert an integer to a RoundingMode, validating that it is in range.
* Returns which mantissa scale is currently in use for normalization.
*
* Returns std::nullopt if the value does not correspond to a valid
* RoundingMode.
*/
static std::optional<RoundingMode>
checkedRoundingMode(int mode) noexcept
{
if (mode < static_cast<int>(RoundingMode::ToNearest) ||
mode > static_cast<int>(RoundingMode::Upward))
return std::nullopt;
return static_cast<RoundingMode>(mode);
}
/**
* If you think you need to call this outside of unit tests, no you don't.
*/
static MantissaRange::MantissaScale

View File

@@ -94,7 +94,6 @@ struct Keys
static constexpr auto kBbtOptions = "bbt_options";
static constexpr auto kBgThreads = "bg_threads";
static constexpr auto kBlockSize = "block_size";
static constexpr auto kBytecodeSizeLimit = "bytecode_size_limit";
static constexpr auto kCacheAge = "cache_age";
static constexpr auto kCacheMb = "cache_mb";
static constexpr auto kCacheSize = "cache_size";
@@ -109,8 +108,6 @@ struct Keys
static constexpr auto kFileSizeMult = "file_size_mult";
static constexpr auto kFilterBits = "filter_bits";
static constexpr auto kFilterFull = "filter_full";
static constexpr auto kGasLimit = "gas_limit";
static constexpr auto kGasPrice = "gas_price";
static constexpr auto kHardSet = "hard_set";
static constexpr auto kHighThreads = "high_threads";
static constexpr auto kHoldTime = "hold_time";

View File

@@ -6,7 +6,6 @@
#include <xrpl/basics/TaggedCache.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/protocol/Fees.h>
#include <boost/asio.hpp>
@@ -247,9 +246,6 @@ public:
virtual DatabaseCon&
getWalletDB() = 0;
[[nodiscard]] virtual Fees
getFees() const = 0;
// Temporary: Get the underlying Application for functions that haven't
// been migrated yet. This should be removed once all code is migrated.
virtual Application&

View File

@@ -13,7 +13,6 @@
#include <xrpl/protocol/TxMeta.h>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <optional>
@@ -69,18 +68,6 @@ public:
deliver_ = amount;
}
void
setGasUsed(std::optional<std::uint32_t> const gasUsed)
{
gasUsed_ = gasUsed;
}
void
setVMReturnCode(std::int32_t const vmReturnCode)
{
vmReturnCode_ = vmReturnCode;
}
/**
* Get the number of modified entries
*/
@@ -101,8 +88,6 @@ public:
private:
std::optional<STAmount> deliver_;
std::optional<std::uint32_t> gasUsed_;
std::optional<std::int32_t> vmReturnCode_;
};
} // namespace xrpl

View File

@@ -1,82 +0,0 @@
#pragma once
#include <xrpl/ledger/OpenView.h>
#include <memory>
namespace xrpl {
class OpenViewSandbox
{
private:
OpenView& parent_;
std::unique_ptr<OpenView> sandbox_;
public:
using key_type = ReadView::key_type;
OpenViewSandbox(OpenView& parent)
: parent_(parent), sandbox_(std::make_unique<OpenView>(kBatchView, parent))
{
}
void
rawErase(std::shared_ptr<SLE> const& sle)
{
sandbox_->rawErase(sle);
}
void
rawInsert(std::shared_ptr<SLE> const& sle)
{
sandbox_->rawInsert(sle);
}
void
rawReplace(std::shared_ptr<SLE> const& sle)
{
sandbox_->rawReplace(sle);
}
void
rawDestroyXRP(XRPAmount const& fee)
{
sandbox_->rawDestroyXRP(fee);
}
void
rawTxInsert(
key_type const& key,
std::shared_ptr<Serializer const> const& txn,
std::shared_ptr<Serializer const> const& metaData)
{
sandbox_->rawTxInsert(key, txn, metaData);
}
void
commit()
{
sandbox_->apply(parent_);
sandbox_ = std::make_unique<OpenView>(kBatchView, parent_);
}
void
discard()
{
sandbox_ = std::make_unique<OpenView>(kBatchView, parent_);
}
OpenView const&
view() const
{
return *sandbox_;
}
OpenView&
view()
{
return *sandbox_;
}
};
} // namespace xrpl

View File

@@ -5,10 +5,6 @@
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
#include <xrpl/ledger/helpers/OfferHelpers.h>
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
#include <xrpl/ledger/helpers/TokenHelpers.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/Keylet.h>
@@ -279,27 +275,6 @@ doWithdraw(
STAmount const& amount,
beast::Journal j);
enum class SendIssuerHandling { ihSENDER_NOT_ALLOWED, ihRECEIVER_NOT_ALLOWED, ihIGNORE };
enum class SendEscrowHandling { ehIGNORE, ehCHECK };
enum class SendAuthHandling { ahCHECK_SENDER, ahCHECK_RECEIVER, ahBOTH, ahNEITHER };
enum class SendFreezeHandling { fhCHECK_SENDER, fhCHECK_RECEIVER, fhBOTH, fhNEITHER };
enum class SendTransferHandling { thIGNORE, thCHECK };
enum class SendBalanceHandling { bhIGNORE, bhCHECK };
TER
canTransferFT(
ReadView const& view,
AccountID const& sender,
AccountID const& receiver,
STAmount const& amount,
beast::Journal j,
SendIssuerHandling issuerHandling,
SendEscrowHandling escrowHandling,
SendAuthHandling authHandling,
SendFreezeHandling freezeHandling,
SendTransferHandling transferHandling,
SendBalanceHandling balanceHandling);
/**
* Deleter function prototype. Returns the status of the entry deletion
* (if should not be skipped) and if the entry should be skipped. The status

View File

@@ -16,7 +16,6 @@
#include <xrpl/protocol/XRPAmount.h>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <map>
#include <optional>
@@ -63,8 +62,6 @@ public:
TER ter,
std::optional<STAmount> const& deliver,
std::optional<uint256 const> const& parentBatchId,
std::optional<std::uint32_t> const& gasUsed,
std::optional<std::int32_t> const& vmReturnCode,
bool isDryRun,
beast::Journal j);

View File

@@ -1,102 +0,0 @@
#pragma once
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/STData.h>
#include <xrpl/protocol/STJson.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFlags.h>
#include <map>
namespace xrpl {
class ContractDataMap : public std::map<xrpl::AccountID, std::pair<bool, STJson>>
{
public:
uint32_t modifiedCount = 0;
};
class ContractEventMap : public std::map<std::string, STJson>
{
};
namespace contract {
/** The maximum number of data modifications in a single function. */
int64_t constexpr maxDataModifications = 1000;
/** The maximum number of bytes the data can occupy. */
int64_t constexpr maxContractDataSize = 1024;
/** The multiplier for contract data size calculations. */
int64_t constexpr dataByteMultiplier = 512;
/** The cost multiplier of creating a contract in bytes. */
int64_t constexpr createByteMultiplier = 500ULL;
/** The value to return when the fee calculation failed. */
int64_t constexpr feeCalculationFailed = 0x7FFFFFFFFFFFFFFFLL;
/** The maximum number of contract parameters that can be in a transaction. */
std::size_t constexpr maxContractParams = 8;
/** The maximum number of contract functions that can be in a transaction. */
std::size_t constexpr maxContractFunctions = 32;
int64_t
contractCreateFee(uint64_t byteCount);
NotTEC
preflightFunctions(STTx const& tx, beast::Journal j);
NotTEC
preflightInstanceParameters(STTx const& tx, beast::Journal j);
bool
validateParameterMapping(STArray const& params, STArray const& values, beast::Journal j);
NotTEC
preflightInstanceParameterValues(STTx const& tx, beast::Journal j);
NotTEC
preflightFlagParameters(STArray const& parameters, beast::Journal j);
bool
isValidParameterFlag(std::uint32_t flags);
TER
preclaimFlagParameters(
ReadView const& view,
AccountID const& sourceAccount,
AccountID const& contractAccount,
STArray const& parameters,
beast::Journal j);
TER
doApplyFlagParameters(
ApplyView& view,
STTx const& tx,
AccountID const& sourceAccount,
AccountID const& contractAccount,
STArray const& parameters,
XRPAmount const& priorBalance,
beast::Journal j);
TER
finalizeContractData(
ServiceRegistry& registry,
ApplyView& view,
AccountID const& contractAccount,
ContractDataMap const& dataMap,
ContractEventMap const& eventMap,
uint256 const& txnID);
} // namespace contract
} // namespace xrpl

View File

@@ -25,8 +25,6 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
#include <cstdint>
namespace xrpl {
template <ValidIssueType T>
@@ -274,18 +272,4 @@ escrowUnlockApplyHelper<MPTIssue>(
journal);
}
// calculateAdditionalReserve computes the owner count impact of an Escrow.
// An escrow without a FinishFunction costs 1 reserve. With a FinishFunction,
// each additional 500 bytes beyond the first 500 adds another reserve slot.
template <class T>
static int32_t
calculateAdditionalReserve(T const& finishFunction)
{
if (!finishFunction)
return 1;
// First 500 bytes included in the normal reserve
// Each additional 500 bytes requires an additional reserve
return 1 + (finishFunction->size() / 500);
}
} // namespace xrpl

View File

@@ -16,7 +16,6 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol/nft.h>
#include <cstddef>
#include <cstdint>
@@ -162,12 +161,4 @@ checkTrustlineDeepFrozen(
beast::Journal const j,
Issue const& issue);
TER
transferNFToken(
ApplyView& view,
AccountID const& buyer,
AccountID const& seller,
uint256 const& nftokenID,
beast::Journal j);
} // namespace xrpl::nft

View File

@@ -92,7 +92,7 @@ public:
void
importDatabase(Database& source) override
{
importInternal(*backend_.get(), source);
importInternal(*backend_, source);
}
void

View File

@@ -1,77 +0,0 @@
#pragma once
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFormats.h>
#include <xrpl/protocol/TxSettings.h>
#include <optional>
#include <string>
#include <unordered_map>
namespace xrpl {
/**
* We have both transaction type emitables and granular type emitables.
* Since we will reuse the TransactionFormats to parse the Transaction
* Emitables, only the GranularEmitableType is defined here. To prevent
* conflicts with TxType, the GranularEmitableType is always set to a value
* greater than the maximum value of uint16.
*/
enum GranularEmitableType : std::uint32_t {
#pragma push_macro("EMITABLE")
#undef EMITABLE
#define EMITABLE(type, txType, value) type = value,
#include <xrpl/protocol/detail/emitable.macro>
#undef EMITABLE
#pragma pop_macro("EMITABLE")
};
class Emitable
{
private:
Emitable();
std::unordered_map<std::uint16_t, Emittance> emitableTx_;
std::unordered_map<std::string, GranularEmitableType> granularEmitableMap_;
std::unordered_map<GranularEmitableType, std::string> granularNameMap_;
std::unordered_map<GranularEmitableType, TxType> granularTxTypeMap_;
public:
static Emitable const&
getInstance();
Emitable(Emitable const&) = delete;
Emitable&
operator=(Emitable const&) = delete;
std::optional<std::string>
getEmitableName(std::uint32_t const value) const;
std::optional<std::uint32_t>
getGranularValue(std::string const& name) const;
std::optional<std::string>
getGranularName(GranularEmitableType const& value) const;
std::optional<TxType>
getGranularTxType(GranularEmitableType const& gpType) const;
bool
isEmitable(std::uint32_t const& emitableValue) const;
// for tx level emitable, emitable value is equal to tx type plus one
uint32_t
txToEmitableType(TxType const& type) const;
// tx type value is emitable value minus one
TxType
emitableToTxType(uint32_t const& value) const;
};
} // namespace xrpl

View File

@@ -10,15 +10,6 @@ namespace xrpl {
// This was the reference fee units used in the old fee calculation.
inline constexpr std::uint32_t kFeeUnitsDeprecated = 10;
// Number of micro-drops in one drop.
constexpr std::uint32_t microDropsPerDrop{1'000'000};
/**
* Maximum Feature Extension fee settings.
*/
inline constexpr std::uint32_t kMaxGasLimit{2'000'000};
inline constexpr std::uint32_t kMaxBytecodeSizeLimit{200'000};
/**
* Reflects the fee settings for a particular ledger.
*
@@ -42,21 +33,6 @@ struct Fees
*/
XRPAmount increment{0};
/**
* @brief Gas limit for Feature Extensions (instructions).
*/
std::uint32_t gasLimit{0};
/**
* @brief Bytecode size limit for Feature Extensions (bytes).
*/
std::uint32_t bytecodeSizeLimit{0};
/**
* @brief Price of WASM gas (micro-drops).
*/
std::uint32_t gasPrice{0};
explicit Fees() = default;
Fees(Fees const&) = default;
Fees&

View File

@@ -237,12 +237,6 @@ page(Keylet const& root, std::uint64_t const index = 0) noexcept
Keylet
escrow(AccountID const& src, SeqProxy const& seq) noexcept;
inline Keylet
escrow(uint256 const& key) noexcept
{
return {ltESCROW, key};
}
/**
* A PaymentChannel
*/
@@ -392,22 +386,6 @@ permissionedDomain(AccountID const& account, SeqProxy const& seq) noexcept;
Keylet
permissionedDomain(uint256 const& domainID) noexcept;
Keylet
contractSource(uint256 const& contractHash) noexcept;
Keylet
contract(uint256 const& contractHash, AccountID const& owner, std::uint32_t seq) noexcept;
inline Keylet
contract(uint256 const& contractID)
{
return {ltCONTRACT, contractID};
}
Keylet
contractData(AccountID const& owner, AccountID const& contractAccount) noexcept;
} // namespace keylet
// Everything below is deprecated and should be removed in favor of keylets:

View File

@@ -85,6 +85,15 @@ enum LedgerEntryType : std::uint16_t {
*/
ltNICKNAME [[deprecated("This object type is not supported and should not be used.")]] = 0x006e,
/**
* A legacy, deprecated type.
*
* @deprecated **This object type is not supported and should not be used.**
* Support for this type of object was never implemented.
* No objects of this type were ever created.
*/
ltCONTRACT [[deprecated("This object type is not supported and should not be used.")]] = 0x0063,
/**
* A legacy, deprecated type.
*

View File

@@ -5,9 +5,11 @@
#include <xrpl/protocol/Concepts.h>
#include <xrpl/protocol/UintTypes.h>
#include <cstdint>
#include <ostream>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <variant>
namespace xrpl {
@@ -121,9 +123,32 @@ operator==(PathAsset const& lhs, PathAsset const& rhs)
template <typename Hasher>
void
hash_append(Hasher& h, PathAsset const& pathAsset)
hash_append(Hasher& h, PathAsset const& pathAsset) noexcept
{
std::visit([&]<ValidPathAsset T>(T const& e) { hash_append(h, e); }, pathAsset.value());
using beast::hash_append;
using Variant = std::remove_cvref_t<decltype(pathAsset.value())>;
static_assert(
std::variant_size_v<Variant> < 0xFFu,
"PathAsset's discriminant must fit in a byte, leaving 0xFF reserved.");
// std::visit is not noexcept: it throws bad_variant_access when the variant
// is valueless_by_exception.
if (pathAsset.value().valueless_by_exception()) [[unlikely]]
{
hash_append(h, static_cast<std::uint8_t>(0xFFu));
return;
}
hash_append(h, static_cast<std::uint8_t>(pathAsset.value().index()));
std::visit(
[&]<ValidPathAsset T>(T const& e) noexcept {
static_assert(
noexcept(hash_append(h, e)),
"Every PathAsset alternative must be nothrow-hashable.");
hash_append(h, e);
},
pathAsset.value());
}
inline bool

View File

@@ -12,7 +12,6 @@
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <limits>
namespace xrpl {
@@ -376,16 +375,6 @@ constexpr std::uint32_t kMaxInvestmentPeriod = std::chrono::seconds{std::chrono:
*/
constexpr std::uint8_t kMaxAssetCheckDepth = 5;
/**
* Maximum length of a Data field in Escrow object that can be updated by WASM code.
*/
constexpr std::size_t kMaxWasmDataLength = 1 * 1024; // 1KB
/**
* Maximum amount of data transfer across hostfunction<->wasm border.
*/
constexpr std::size_t kWasmTransferLimit = 1 << 20; // 1MB
/**
* A ledger index.
*/
@@ -555,11 +544,6 @@ constexpr std::size_t kEcClawbackProofLength = SECP256K1_COMPACT_CLAWBACK_PROOF_
*/
constexpr std::uint32_t kConfidentialFeeMultiplier = 9;
/**
* Maximum value a confidential MPT key epoch may reach.
*/
constexpr std::uint32_t kMaxKeyEpoch = std::numeric_limits<std::uint32_t>::max();
/**
* Compressed EC point prefix for even y-coordinate
*/

View File

@@ -34,9 +34,6 @@ class STNumber;
class STXChainBridge;
class STVector256;
class STCurrency;
class STData;
class STDataType;
class STJson;
// NOLINTBEGIN(readability-identifier-naming)
#pragma push_macro("XMACRO")
@@ -76,9 +73,6 @@ class STJson;
STYPE(STI_ISSUE, 24) \
STYPE(STI_XCHAIN_BRIDGE, 25) \
STYPE(STI_CURRENCY, 26) \
STYPE(STI_DATA, 27) \
STYPE(STI_DATATYPE, 28) \
STYPE(STI_JSON, 29) \
\
/* high-level types */ \
/* cannot be serialized inside other types */ \
@@ -365,9 +359,6 @@ using SF_NUMBER = TypedField<STNumber>;
using SF_VL = TypedField<STBlob>;
using SF_VECTOR256 = TypedField<STVector256>;
using SF_XCHAIN_BRIDGE = TypedField<STXChainBridge>;
using SF_DATA = TypedField<STData>;
using SF_DATATYPE = TypedField<STDataType>;
using SF_JSON = TypedField<STJson>;
//------------------------------------------------------------------------------

View File

@@ -1,289 +0,0 @@
#pragma once
#include <xrpl/basics/Buffer.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAccount.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/STBitString.h>
#include <xrpl/protocol/STInteger.h>
#include <xrpl/protocol/detail/STVar.h>
#include <cstdint>
#include <string>
#include <vector>
namespace xrpl {
class STData final : public STBase
{
private:
using data_type = detail::STVar;
std::uint16_t inner_type_;
data_type data_;
bool default_{true};
public:
using value_type = STData; // Although not directly holding a single value
STData(SField const& n);
STData(SField const& n, unsigned char);
STData(SField const& n, std::uint16_t);
STData(SField const& n, std::uint32_t);
STData(SField const& n, std::uint64_t);
STData(SField const& n, uint128 const&);
STData(SField const& n, uint160 const&);
STData(SField const& n, uint192 const&);
STData(SField const& n, uint256 const&);
STData(SField const& n, Blob const&);
STData(SField const& n, Slice const&);
STData(SField const& n, AccountID const&);
STData(SField const& n, STAmount const&);
STData(SField const& n, STIssue const&);
STData(SField const& n, STCurrency const&);
STData(SField const& n, STNumber const&);
STData(SerialIter& sit, SField const& name);
std::size_t
size() const;
SerializedTypeID
getSType() const override;
std::string
getInnerTypeString() const;
std::string
getText() const override;
json::Value getJson(JsonOptions) const override;
void
add(Serializer& s) const override;
bool
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;
SerializedTypeID
getInnerSType() const noexcept;
STBase*
makeFieldPresent();
void
setFieldU8(unsigned char);
void
setFieldU16(std::uint16_t);
void
setFieldU32(std::uint32_t);
void
setFieldU64(std::uint64_t);
void
setFieldH128(uint128 const&);
void
setFieldH160(uint160 const&);
void
setFieldH192(uint192 const&);
void
setFieldH256(uint256 const&);
void
setFieldVL(Blob const&);
void
setFieldVL(Slice const&);
void
setAccountID(AccountID const&);
void
setFieldAmount(STAmount const&);
void
setIssue(STIssue const&);
void
setCurrency(STCurrency const&);
void
setFieldNumber(STNumber const&);
unsigned char
getFieldU8() const;
std::uint16_t
getFieldU16() const;
std::uint32_t
getFieldU32() const;
std::uint64_t
getFieldU64() const;
uint128
getFieldH128() const;
uint160
getFieldH160() const;
uint192
getFieldH192() const;
uint256
getFieldH256() const;
Blob
getFieldVL() const;
AccountID
getAccountID() const;
STAmount const&
getFieldAmount() const;
STIssue
getFieldIssue() const;
STCurrency
getFieldCurrency() const;
STNumber
getFieldNumber() const;
private:
STBase*
copy(std::size_t n, void* buf) const override;
STBase*
move(std::size_t n, void* buf) override;
friend class detail::STVar;
// Implementation for getting (most) fields that return by value.
//
// The remove_cv and remove_reference are necessitated by the STBitString
// types. Their value() returns by const ref. We return those types
// by value.
template <
typename T,
typename V = typename std::remove_cv<
typename std::remove_reference<decltype(std::declval<T>().value())>::type>::type>
V
getFieldByValue() const;
// Implementations for getting (most) fields that return by const reference.
//
// If an absent optional field is deserialized we don't have anything
// obvious to return. So we insist on having the call provide an
// 'empty' value we return in that circumstance.
template <typename T, typename V>
V const&
getFieldByConstRef(V const& empty) const;
// Implementation for setting most fields with a setValue() method.
template <typename T, typename V>
void
setFieldUsingSetValue(V value);
// Implementation for setting fields using assignment
template <typename T>
void
setFieldUsingAssignment(T const& value);
};
//------------------------------------------------------------------------------
// Implementation
//------------------------------------------------------------------------------
inline SerializedTypeID
STData::getInnerSType() const noexcept
{
return static_cast<SerializedTypeID>(inner_type_);
}
template <typename T, typename V>
V
STData::getFieldByValue() const
{
STBase const* rf = &data_.get();
// if (!rf)
// throwFieldNotFound(getFName());
SerializedTypeID const id = rf->getSType();
if (id == STI_NOTPRESENT)
Throw<std::runtime_error>("Field not present");
T const* cf = dynamic_cast<T const*>(rf);
if (!cf)
Throw<std::runtime_error>("Wrong field type");
return cf->value();
}
// Implementations for getting (most) fields that return by const reference.
//
// If an absent optional field is deserialized we don't have anything
// obvious to return. So we insist on having the call provide an
// 'empty' value we return in that circumstance.
template <typename T, typename V>
V const&
STData::getFieldByConstRef(V const& empty) const
{
STBase const* rf = &data_.get();
// if (!rf)
// throwFieldNotFound(field);
SerializedTypeID const id = rf->getSType();
if (id == STI_NOTPRESENT)
return empty; // optional field not present
T const* cf = dynamic_cast<T const*>(rf);
if (!cf)
Throw<std::runtime_error>("Wrong field type");
return *cf;
}
// Implementation for setting most fields with a setValue() method.
template <typename T, typename V>
void
STData::setFieldUsingSetValue(V value)
{
static_assert(!std::is_lvalue_reference<V>::value, "");
STBase* rf = &data_.get();
// if (!rf)
// throwFieldNotFound(field);
if (rf->getSType() == STI_NOTPRESENT)
rf = makeFieldPresent();
T* cf = dynamic_cast<T*>(rf);
if (!cf)
Throw<std::runtime_error>("Wrong field type");
cf->setValue(std::move(value));
}
// Implementation for setting fields using assignment
template <typename T>
void
STData::setFieldUsingAssignment(T const& value)
{
STBase* rf = &data_.get();
// if (!rf)
// throwFieldNotFound(field);
// if (rf->getSType() == STI_NOTPRESENT)
// rf = makeFieldPresent(field);
T* cf = dynamic_cast<T*>(rf);
if (!cf)
Throw<std::runtime_error>("Wrong field type");
(*cf) = value;
}
//------------------------------------------------------------------------------
//
// Creation
//
//------------------------------------------------------------------------------
STData
dataFromJson(SField const& field, json::Value const& value);
} // namespace xrpl

View File

@@ -1,87 +0,0 @@
#pragma once
#include <xrpl/basics/Buffer.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAccount.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/STBitString.h>
#include <xrpl/protocol/STInteger.h>
#include <xrpl/protocol/detail/STVar.h>
#include <cstdint>
#include <string>
#include <vector>
namespace xrpl {
class STDataType final : public STBase
{
private:
std::uint16_t inner_type_;
bool default_{true};
public:
using value_type = STDataType; // Although not directly holding a single value
STDataType(SField const& n);
STDataType(SField const& n, SerializedTypeID);
STDataType(SerialIter& sit, SField const& name);
SerializedTypeID
getSType() const override;
std::string
getInnerTypeString() const;
std::string
getText() const override;
json::Value getJson(JsonOptions) const override;
void
add(Serializer& s) const override;
bool
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;
void setInnerSType(SerializedTypeID);
SerializedTypeID
getInnerSType() const noexcept;
STBase*
makeFieldPresent();
STBase*
copy(std::size_t n, void* buf) const override;
STBase*
move(std::size_t n, void* buf) override;
friend class detail::STVar;
};
//------------------------------------------------------------------------------
// Implementation
//------------------------------------------------------------------------------
inline SerializedTypeID
STDataType::getInnerSType() const noexcept
{
return static_cast<SerializedTypeID>(inner_type_);
}
//------------------------------------------------------------------------------
//
// Creation
//
//------------------------------------------------------------------------------
STDataType
dataTypeFromJson(SField const& field, json::Value const& value);
} // namespace xrpl

View File

@@ -1,193 +0,0 @@
#pragma once
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/Serializer.h>
#include <map>
#include <memory>
#include <string>
#include <variant>
#include <vector>
namespace xrpl {
/**
* STJson: Serialized Type for JSON-like structures (objects or arrays).
*
* Supports two modes:
* - Object: Key-value pairs where keys are VL-encoded strings
* - Array: Ordered list of values
*
* Values are [SType marker][VL-encoded SType serialization].
* Values can be any SType, including nested STJson.
*
* Serialization format: [type_byte][VL_length][data...]
* - type_byte: 0x00 = Object, 0x01 = Array
*/
class STJson : public STBase
{
public:
enum class JsonType : uint8_t { Object = 0x00, Array = 0x01 };
using value_type = STJson;
value_type
value() const
{
return *this;
}
using Key = std::string;
using Value = std::shared_ptr<STBase>;
using Map = std::map<Key, Value>;
using Array = std::vector<Value>;
STJson() = default;
explicit STJson(Map&& map);
explicit STJson(Array&& array);
explicit STJson(SField const& name);
explicit STJson(SerialIter& sit, SField const& name);
SerializedTypeID
getSType() const override;
// Type checking
bool
isArray() const;
bool
isObject() const;
JsonType
getType() const;
// Depth checking (0 = no nesting, 1 = one level of nesting)
int
getDepth() const;
// Parse from binary blob
static std::shared_ptr<STJson>
fromBlob(void const* data, std::size_t size);
// Parse from SerialIter
static std::shared_ptr<STJson>
fromSerialIter(SerialIter& sit);
// Serialize to binary
void
add(Serializer& s) const override;
// JSON representation
json::Value
getJson(JsonOptions options) const override;
bool
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;
// Blob representation
Blob
toBlob() const;
// STJson size
std::size_t
size() const;
// Object accessors (only valid when isObject() == true)
Map const&
getMap() const;
void
setObjectField(Key const& key, Value const& value);
std::optional<STJson::Value>
getObjectField(Key const& key) const;
void
setNestedObjectField(Key const& key, Key const& nestedKey, Value const& value);
std::optional<Value>
getNestedObjectField(Key const& key, Key const& nestedKey) const;
// Array accessors (only valid when isArray() == true)
Array const&
getArray() const;
void
pushArrayElement(Value const& value);
std::optional<Value>
getArrayElement(size_t index) const;
void
setArrayElement(size_t index, Value const& value);
void
setArrayElementField(size_t index, Key const& key, Value const& value);
std::optional<Value>
getArrayElementField(size_t index, Key const& key) const;
size_t
arraySize() const;
// Nested array accessors (for arrays stored in object fields)
void
setNestedArrayElement(Key const& key, size_t index, Value const& value);
void
setNestedArrayElementField(
Key const& key,
size_t index,
Key const& nestedKey,
Value const& value);
std::optional<Value>
getNestedArrayElement(Key const& key, size_t index) const;
std::optional<Value>
getNestedArrayElementField(Key const& key, size_t index, Key const& nestedKey) const;
// Factory for SType value from blob (with SType marker)
static Value
makeValueFromVLWithType(SerialIter& sit);
void
setValue(STJson const& v);
private:
std::variant<Map, Array> data_{Map{}};
bool default_{false};
// Helper: validate nesting depth (max 1 level)
void
validateDepth(Value const& value, int currentDepth) const;
// Helper: parse a single key-value pair from SerialIter
static std::pair<Key, Value>
parsePair(SerialIter& sit);
// Helper: parse array elements from SerialIter
static Array
parseArray(SerialIter& sit, int length);
// Helper: encode a key as VL
static void
addVLKey(Serializer& s, std::string const& str);
// Helper: encode a value as [SType marker][VL]
static void
addVLValue(Serializer& s, std::shared_ptr<STBase> const& value);
STBase*
copy(std::size_t n, void* buf) const override;
STBase*
move(std::size_t n, void* buf) override;
friend class detail::STVar;
};
} // namespace xrpl

View File

@@ -17,7 +17,6 @@
#include <xrpl/protocol/STBitString.h>
#include <xrpl/protocol/STCurrency.h>
#include <xrpl/protocol/STIssue.h>
#include <xrpl/protocol/STJson.h>
#include <xrpl/protocol/STPathSet.h>
#include <xrpl/protocol/STVector256.h>
#include <xrpl/protocol/Serializer.h>
@@ -233,10 +232,6 @@ public:
getFieldI32(SField const& field) const;
[[nodiscard]] AccountID
getAccountID(SField const& field) const;
STData
getFieldData(SField const& field) const;
STDataType
getFieldDataType(SField const& field) const;
[[nodiscard]] Blob
getFieldVL(SField const& field) const;
@@ -255,8 +250,6 @@ public:
getFieldCurrency(SField const& field) const;
[[nodiscard]] STNumber const&
getFieldNumber(SField const& field) const;
STJson const&
getFieldJson(SField const& field) const;
/**
* Get the value of a field.
@@ -370,9 +363,6 @@ public:
void
set(STBase&& v);
void
addFieldFromSlice(SField const& sfield, Slice const& data);
void
setFieldU8(SField const& field, unsigned char);
void
@@ -413,8 +403,6 @@ public:
setFieldArray(SField const& field, STArray const& v);
void
setFieldObject(SField const& field, STObject const& v);
void
setFieldJson(SField const& field, STJson const& v);
template <class Tag>
void

View File

@@ -12,6 +12,8 @@
#include <xrpl/protocol/UintTypes.h>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <utility>
#include <vector>
@@ -65,7 +67,7 @@ public:
PathAsset const& asset,
AccountID const& issuer);
[[nodiscard]] auto
[[nodiscard]] std::uint32_t
getNodeType() const;
[[nodiscard]] bool
@@ -109,9 +111,6 @@ public:
[[nodiscard]] bool
isType(Type const& pe) const;
[[nodiscard]] size_t
getHash() const;
bool
operator==(STPathElement const& t) const;
@@ -120,6 +119,17 @@ private:
getHash(STPathElement const& element);
};
template <class Hasher>
void
hash_append(Hasher& h, STPathElement const& e) noexcept
{
using beast::hash_append;
hash_append(h, (e.getNodeType() & STPathElement::TypeAccount) != 0u);
hash_append(h, e.getAccountID());
hash_append(h, e.getPathAsset());
hash_append(h, e.getIssuerID());
}
class STPath final : public CountedObject<STPath>
{
std::vector<STPathElement> path_;
@@ -176,9 +186,10 @@ template <class Hasher>
void
hash_append(Hasher& h, STPath const& p) noexcept
{
using beast::hash_append;
for (auto const& e : p)
{
beast::hash_append(h, e.getHash());
hash_append(h, e);
}
}
@@ -188,13 +199,39 @@ hash_append(Hasher& h, STPath const& p) noexcept
class STPathSet final : public STBase, public CountedObject<STPathSet>
{
std::vector<STPath> value_;
xrpl::hardened_hash_set<STPath> seenHashes_;
/**
* Deduplication index over `value_`, for pathfinding.
* The use of a std::unique_ptr is intentional as it
* only requires 8 additional bytes of storage for the pointer
* as opposed to 64 bytes with an optional. This keeps the size
* of the STPathSet to within the `STVar::kMaxSize` limit of 72 bytes.
*/
std::unique_ptr<hardened_hash_set<STPath>> seen_;
public:
struct DeduplicationTag
{
};
STPathSet() = default;
/**
* Deduplication tagged constructor.
* Use when you want to ensure that the STPathSet does not contain duplicate paths.
*/
explicit STPathSet(DeduplicationTag);
STPathSet(SField const& n);
STPathSet(SerialIter& sit, SField const& name);
STPathSet(STPathSet const& other);
STPathSet(STPathSet&&) = default;
STPathSet&
operator=(STPathSet const& other);
STPathSet&
operator=(STPathSet&&) = default;
~STPathSet() override = default;
void
add(Serializer& s) const override;
@@ -204,6 +241,16 @@ public:
[[nodiscard]] SerializedTypeID
getSType() const override;
/**
* @brief assembleAdd adds a path to the set by combining a base path and a tail element.
*
* @param base The base path.
* @param tail The tail element.
* @return true if the path was added, false if it was a duplicate and not added.
* @remarks Requires the STPathSet to be constructed with the DeduplicationTag. The return value
* indicates whether the combined path was inserted (true) or rejected as a duplicate (false).
* It is fine for callers to ignore the return value.
*/
bool
assembleAdd(STPath const& base, STPathElement const& tail);
@@ -229,22 +276,61 @@ public:
[[nodiscard]] bool
empty() const;
void
/**
* @brief pushBack adds a path to the set.
*
* @param e The path to add.
* @return true if the path was added, false if it was a duplicate and not added.
* @remarks If the STPathSet was constructed with the DeduplicationTag, then this method will
* check for duplicates and only add the path if it is not already present in the
* set. If the STPathSet was constructed without the DeduplicationTag,
* then this method will always add the path to the set, regardless of duplicates.
* It is fine for callers to ignore the return value.
*/
bool
pushBack(STPath const& e);
/**
* @brief emplaceBack adds a path to the set.
*
* @param args The arguments to construct the path with.
* @return true if the path was added, false if it was a duplicate and not added.
* @remarks If the STPathSet was constructed with the DeduplicationTag, then this method will
* check for duplicates and only add the path if it is not already present in the
* set. If the STPathSet was constructed without the DeduplicationTag,
* then this method will always add the path to the set, regardless of duplicates.
* It is fine for callers to ignore the return value.
* @note The path is constructed before the duplicate check, so on a false
* return the constructed path is discarded and any argument
* forwarded as an rvalue is left in a moved-from state. Use
* pushBack when the caller needs to keep its path on rejection.
*/
template <typename... Args>
void
bool
emplaceBack(Args&&... args);
[[nodiscard]] bool
contains(STPath const& path) const;
private:
STBase*
copy(std::size_t n, void* buf) const override;
STBase*
move(std::size_t n, void* buf) override;
/**
* @brief Append a path via `append`, then register it in the deduplication index.
*
* @param append Invoked with `value_`; must append exactly one path to it.
* @return true if the path was kept, false if it was a duplicate and was rolled back.
* @remarks Appends to the vector before touching the index, so that a failed allocation
* there leaves both containers untouched rather than leaving the index holding
* a path the vector does not. If the index insert reports a duplicate, or
* throws, the append is rolled back so the two containers stay consistent; in
* the throwing case the exception propagates. With no index (constructed
* without the DeduplicationTag) the append is unconditional.
*/
template <typename Append>
bool
appendUnique(Append&& append);
friend class detail::STVar;
};
@@ -336,7 +422,7 @@ inline STPathElement::STPathElement(
hashValue_ = getHash(*this);
}
inline auto
inline std::uint32_t
STPathElement::getNodeType() const
{
return type_;
@@ -545,25 +631,50 @@ STPathSet::empty() const
return value_.empty();
}
inline void
STPathSet::pushBack(STPath const& e)
template <typename Append>
inline bool
STPathSet::appendUnique(Append&& append)
{
value_.push_back(e);
seenHashes_.emplace(value_.back());
}
// Append to the vector first, so that a failed allocation there leaves both
// containers untouched rather than leaving the index holding a path the
// vector does not.
append(value_);
template <typename... Args>
inline void
STPathSet::emplaceBack(Args&&... args)
{
value_.emplace_back(std::forward<Args>(args)...);
seenHashes_.emplace(value_.back());
if (seen_ == nullptr)
{
return true;
}
try
{
if (!seen_->insert(value_.back()).second)
{
// Already present: roll back the append.
value_.pop_back();
return false;
}
}
catch (...)
{
// The index insert failed, so roll back the append to keep the vector
// and the index consistent.
value_.pop_back();
throw;
}
return true;
}
inline bool
STPathSet::contains(STPath const& path) const
STPathSet::pushBack(STPath const& e)
{
return seenHashes_.contains(path);
return appendUnique([&](auto& value) { value.push_back(e); });
}
template <typename... Args>
inline bool
STPathSet::emplaceBack(Args&&... args)
{
return appendUnique([&](auto& value) { value.emplace_back(std::forward<Args>(args)...); });
}
} // namespace xrpl

View File

@@ -124,6 +124,13 @@ public:
[[nodiscard]] NodeID const&
getNodeID() const noexcept;
/**
* Whether this validation carries a good signature.
*
* Reports false if the signature cannot be checked at all, so a caller
* cannot tell that apart from a bad signature. Either way the validation is
* unusable, and the reason is logged. Only a computed answer is remembered.
*/
[[nodiscard]] bool
isValid() const noexcept;

View File

@@ -10,6 +10,7 @@
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/SField.h>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <stdexcept>
@@ -25,6 +26,101 @@ private:
Blob data_;
public:
/**
* A header is never longer than this. The encoder fills a buffer of this
* size and writes only the bytes it used.
*/
static constexpr int kMaxNumberOfBytesInHeader = 3;
// A field whose size varies is stored as a header holding its length, then
// the field data. The header is 1, 2 or 3 bytes long. Nothing outside it says
// which, so the decoder reads the first byte and its value says how long the
// header is:
//
// 0 ... 192 kMin/kMaxValueOfFirstByteFor1ByteHeader
// 193 ... 240 kMin/kMaxValueOfFirstByteFor2ByteHeader
// 241 ... 254 kMin/kMaxValueOfFirstByteFor3ByteHeader
// 255 belongs to no header
//
// Each range starts one past the end of the range before it.
static constexpr int kMinValueOfFirstByteFor1ByteHeader = 0;
static constexpr int kMaxValueOfFirstByteFor1ByteHeader = 192;
static constexpr int kMinValueOfFirstByteFor2ByteHeader =
kMaxValueOfFirstByteFor1ByteHeader + 1;
static constexpr int kMaxValueOfFirstByteFor2ByteHeader = 240;
static constexpr int kMinValueOfFirstByteFor3ByteHeader =
kMaxValueOfFirstByteFor2ByteHeader + 1;
static constexpr int kMaxValueOfFirstByteFor3ByteHeader = 254;
// A length x too big for one byte is split across the header. For 2 bytes:
//
// first byte = 193 + (x - 193) / 256
// second byte = (x - 193) % 256
//
// so 300 is stored as 193, 107. For 3 bytes it is the same, from 241, with
// the remainder split across two bytes: 20,000 is stored as 241, 29, 95.
static constexpr int kNumberOfValuesInOneByte = 256;
static constexpr int kNumberOfValuesInTwoBytes =
kNumberOfValuesInOneByte * kNumberOfValuesInOneByte;
// Each header length therefore covers a range of field lengths:
//
// 0 ... 192 kMin/kMaxValueOfLengthFor1ByteHeader
// 193 ... 12,480 kMin/kMaxValueOfLengthFor2ByteHeader
// 12,481 ... 918,744 kMin/kMaxValueOfLengthFor3ByteHeader
//
// The encoder always uses the shortest header that fits.
/**
* A 1 byte header holds the length in the byte itself, so both ends of
* this range are the same numbers as the first byte's own range.
*/
static constexpr int kMinValueOfLengthFor1ByteHeader = kMinValueOfFirstByteFor1ByteHeader;
static constexpr int kMaxValueOfLengthFor1ByteHeader = kMaxValueOfFirstByteFor1ByteHeader;
static constexpr int kMinValueOfLengthFor2ByteHeader = kMaxValueOfLengthFor1ByteHeader + 1;
/**
* 48 values of the first byte mean a 2 byte header, and each of them covers
* 256 lengths. The 48 is worked out from the two range ends above, so it
* stays right if either of them changes.
*/
static constexpr int kMaxValueOfLengthFor2ByteHeader = kMinValueOfLengthFor2ByteHeader +
((kMaxValueOfFirstByteFor2ByteHeader - kMaxValueOfFirstByteFor1ByteHeader) *
kNumberOfValuesInOneByte) -
1;
static constexpr int kMinValueOfLengthFor3ByteHeader = kMaxValueOfLengthFor2ByteHeader + 1;
/**
* 14 values of the first byte mean a 3 byte header, and each of them covers
* 65,536 lengths. Counted the same way, that gives the largest length any
* header can state.
*
* Nothing is accepted or rejected against this. The assertion below uses it
* to check that every length the encoder writes is one a header can state.
*/
static constexpr int kMaxRepresentableLength = kMinValueOfLengthFor3ByteHeader +
((kMaxValueOfFirstByteFor3ByteHeader - kMaxValueOfFirstByteFor2ByteHeader) *
kNumberOfValuesInTwoBytes) -
1;
/**
* The largest length the encoder will write. This is the one number here
* that is picked rather than worked out. The decoder accepts nothing above
* it, so both sides agree on the same set of lengths.
*/
static constexpr int kMaxValueOfLengthFor3ByteHeader = 918744;
static_assert(
kMaxValueOfLengthFor3ByteHeader <= kMaxRepresentableLength,
"a length the encoder writes must be one a header can state");
explicit Serializer(int n = 256)
{
data_.reserve(n);
@@ -61,7 +157,7 @@ public:
// assemble functions
int
add8(unsigned char i);
add8(unsigned char byteValue);
int
add16(std::uint16_t i);
@@ -270,18 +366,90 @@ public:
return v.data_ == data_;
}
/**
* Works out how long a header is, from its first byte.
*
* Each overload of decodeVLLength below reads one header length, so call
* this first to learn which of them to call.
*
* @param firstByte First byte of the header, as read from the stream.
* @return How many bytes the whole header takes, counting firstByte: 1, 2
* or 3.
* @throws std::overflow_error if firstByte is the one value that starts no
* header.
*/
static int
decodeLengthLength(int b1);
decodeLengthLength(std::byte firstByte);
/**
* Reads the field length out of a 1 byte header.
*
* @param firstByte The single header byte, which is the length itself.
* @return Field length in bytes, from kMinValueOfLengthFor1ByteHeader to
* kMaxValueOfLengthFor1ByteHeader.
* @throws std::overflow_error if firstByte is big enough to mean a longer
* header, in which case it is not a length by itself.
*/
static int
decodeVLLength(int b1);
decodeVLLength(std::byte firstByte);
/**
* Reads the field length out of a 2 byte header.
*
* @param firstByte First header byte. Its value means a 2 byte header, and
* how far it sits into that range gives the top part of the length.
* @param secondByte Second header byte, holding the rest of the length.
* @return Field length in bytes, from kMinValueOfLengthFor2ByteHeader to
* kMaxValueOfLengthFor2ByteHeader.
* @throws std::overflow_error if firstByte is outside the range that means
* a 2 byte header.
*/
static int
decodeVLLength(int b1, int b2);
decodeVLLength(std::byte firstByte, std::byte secondByte);
/**
* Reads the field length out of a 3 byte header.
*
* @param firstByte First header byte. Its value means a 3 byte header, and
* how far it sits into that range gives the top part of the length.
* @param secondByte Second header byte, holding the middle part of the
* length.
* @param thirdByte Third header byte, holding the low part.
* @return Field length in bytes, from kMinValueOfLengthFor3ByteHeader to
* kMaxValueOfLengthFor3ByteHeader.
* @throws std::overflow_error if firstByte is outside the range that means
* a 3 byte header, or if the three bytes together state a length above
* kMaxValueOfLengthFor3ByteHeader, which the encoder would not write back.
*/
static int
decodeVLLength(int b1, int b2, int b3);
decodeVLLength(std::byte firstByte, std::byte secondByte, std::byte thirdByte);
private:
/**
* Works out how many bytes the header needs for the given length.
*
* This deliberately repeats the width choice addEncoded makes, so that
* addVL's assertion can compare the two. It has no other caller; do not
* reach for it as a utility.
*
* @param length Field length in bytes.
* @return How many header bytes it needs: 1, 2 or 3.
* @throws std::overflow_error if length is negative, or above
* kMaxValueOfLengthFor3ByteHeader.
*/
static int
encodeLengthLength(int length); // length to encode length
encodeLengthLength(int length);
/**
* Appends the length header for a field of the given length.
*
* The field's own data is not written; the caller appends it next.
*
* @param length Field length in bytes.
* @return Offset within this Serializer at which the header was written.
* @throws std::overflow_error if length is negative, or above
* kMaxValueOfLengthFor3ByteHeader.
*/
int
addEncoded(int length);
};
@@ -390,9 +558,15 @@ public:
void
getFieldID(int& type, int& name);
// Returns the size of the VL if the
// next object is a VL. Advances the iterator
// to the beginning of the VL.
/**
* Reads the length header at the read position and steps past it.
*
* @return Field length in bytes. The iterator is left on the first byte of
* the field data.
* @throws std::overflow_error if the header states a length the encoder could
* not have written.
* @throws std::runtime_error if the data runs out before the header does.
*/
int
getVLDataLength();

View File

@@ -129,11 +129,8 @@ enum TEMcodes : TERUnderlyingType {
temARRAY_TOO_LARGE,
temBAD_TRANSFER_FEE,
temINVALID_INNER_BATCH,
temBAD_MPT,
temBAD_CIPHERTEXT,
temINVALID_BYTECODE,
temTEMP_DISABLED,
};
//------------------------------------------------------------------------------
@@ -182,8 +179,6 @@ enum TEFcodes : TERUnderlyingType {
tefINVALID_LEDGER_FIX_TYPE,
tefNO_DST_PARTIAL,
tefBAD_PATH_COUNT,
tefNO_BYTECODE,
tefBYTECODE_NOT_INCLUDED,
};
//------------------------------------------------------------------------------
@@ -375,9 +370,6 @@ enum TECcodes : TERUnderlyingType {
tecNO_DELEGATE_PERMISSION = 198,
tecBAD_PROOF = 199,
tecNO_SPONSOR_PERMISSION = 200,
tecOUT_OF_GAS = 201,
tecBYTECODE_REJECTED = 202,
tecINVALID_PARAMETERS = 203,
};
//------------------------------------------------------------------------------

View File

@@ -238,21 +238,8 @@ inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
TF_FLAG(tfSponsorshipEnd, 0x00010000) \
TF_FLAG(tfSponsorshipCreate, 0x00020000) \
TF_FLAG(tfSponsorshipReassign, 0x00040000), \
MASK_ADJ(0)) \
\
TRANSACTION(Contract, \
TF_FLAG(tfImmutable, 0x00010000) \
TF_FLAG(tfCodeImmutable, 0x00020000) \
TF_FLAG(tfABIImmutable, 0x00040000) \
TF_FLAG(tfUndeletable, 0x00080000), \
MASK_ADJ(0))
constexpr std::uint32_t tfSendAmount = 0x00010000;
constexpr std::uint32_t tfSendNFToken = 0x00020000;
constexpr std::uint32_t tfAuthorizeToken = 0x00040000;
constexpr std::uint32_t tfContractParameterMask =
~(tfSendAmount | tfSendNFToken | tfAuthorizeToken);
// clang-format on
// Create all the flag values.

View File

@@ -95,12 +95,6 @@ public:
if (obj.isFieldPresent(sfParentBatchID))
parentBatchID_ = obj.getFieldH256(sfParentBatchID);
if (obj.isFieldPresent(sfGasUsed))
gasUsed_ = obj.getFieldU32(sfGasUsed);
if (obj.isFieldPresent(sfVMReturnCode))
vmReturnCode_ = obj.getFieldI32(sfVMReturnCode);
}
[[nodiscard]] std::optional<STAmount> const&
@@ -121,30 +115,6 @@ public:
parentBatchID_ = id;
}
void
setGasUsed(std::optional<std::uint32_t> const gasUsed)
{
gasUsed_ = gasUsed;
}
[[nodiscard]] std::optional<std::uint32_t> const&
getGasUsed() const
{
return gasUsed_;
}
void
setVMReturnCode(std::optional<std::int32_t> const vmReturnCode)
{
vmReturnCode_ = vmReturnCode;
}
[[nodiscard]] std::optional<std::int32_t> const&
getVMReturnCode() const
{
return vmReturnCode_;
}
private:
uint256 transactionID_;
std::uint32_t ledgerSeq_;
@@ -153,8 +123,6 @@ private:
std::optional<STAmount> deliveredAmount_;
std::optional<uint256> parentBatchID_;
std::optional<std::uint32_t> gasUsed_;
std::optional<std::int32_t> vmReturnCode_;
STArray nodes_;
};

View File

@@ -10,11 +10,6 @@ namespace xrpl {
enum class Delegation { Delegable, NotDelegable };
/**
* Whether a smart contract may emit a transaction of this type.
*/
enum class Emittance { Emitable, NotEmitable };
/**
* Operations a transaction is permitted to perform, as a bitfield.
*
@@ -96,11 +91,6 @@ struct TxSettings
* Operations this transaction is permitted to perform.
*/
Privilege privileges{Privilege::NoPriv};
/**
* Whether a smart contract may emit this transaction.
*/
Emittance emittance{Emittance::Emitable};
};
} // namespace xrpl

View File

@@ -34,10 +34,11 @@ concept ValidConstructSTArgs =
// and includes a small-object allocation optimization.
class STVar
{
private:
public:
// The largest "small object" we can accommodate
static constexpr std::size_t kMaxSize = 72;
private:
alignas(std::max_align_t) std::byte d_[kMaxSize] = {};
STBase* p_ = nullptr;

View File

@@ -1,19 +0,0 @@
#if !defined(EMITABLE)
#error "undefined macro: EMITABLE"
#endif
/**
* EMITABLE(name, type, txType, value)
*
* This macro defines a permission:
* name: the name of the permission.
* type: the GranularPermissionType enum.
* txType: the corresponding TxType for this permission.
* value: the uint32 numeric value for the enum type.
*/
/** This removes the contract account the ability to set or remove deposit auth. */
EMITABLE(AccountDepositAuth, ttACCOUNT_SET, 65537)
// ** This removes the contract account the ability to set or remove disable master key. */
EMITABLE(AccountDisableMaster, ttACCOUNT_SET, 65538)

View File

@@ -15,9 +15,7 @@
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FEATURE(SmartContract, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_4_0, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(SmartEscrow, Supported::No, VoteBehavior::DefaultNo)
XRPL_FEATURE(Sponsor, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(BatchV1_1, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(LendingProtocolV1_1, Supported::Yes, VoteBehavior::DefaultNo)
@@ -146,6 +144,3 @@ XRPL_RETIRE_FEATURE(SortedDirectories)
XRPL_RETIRE_FEATURE(TicketBatch)
XRPL_RETIRE_FEATURE(TickSize)
XRPL_RETIRE_FEATURE(TrustSetAuth)
XRPL_FEATURE(LendingProtocolV1_2, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_5_0, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(ConfidentialMPTKeyRotation, Supported::No, VoteBehavior::DefaultNo)

View File

@@ -153,7 +153,6 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
{sfAMMID, SoeOptional}, // pseudo-account designator
{sfVaultID, SoeOptional}, // pseudo-account designator
{sfLoanBrokerID, SoeOptional}, // pseudo-account designator
{sfContractID, SoeOptional}, // pseudo-account designator
}))
/** A ledger object which contains a list of object identifiers.
@@ -310,11 +309,6 @@ LEDGER_ENTRY(ltFEE_SETTINGS, 0x0073, FeeSettings, fee, ({
{sfBaseFeeDrops, SoeOptional},
{sfReserveBaseDrops, SoeOptional},
{sfReserveIncrementDrops, SoeOptional},
// Smart Escrow fields
{sfGasLimit, SoeOptional},
{sfBytecodeSizeLimit, SoeOptional},
{sfGasPrice, SoeOptional},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
}))
@@ -345,8 +339,6 @@ LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
{sfCondition, SoeOptional},
{sfCancelAfter, SoeOptional},
{sfFinishAfter, SoeOptional},
{sfBytecode, SoeOptional},
{sfData, SoeOptional},
{sfSourceTag, SoeOptional},
{sfDestinationTag, SoeOptional},
{sfOwnerNode, SoeRequired},
@@ -416,8 +408,6 @@ LEDGER_ENTRY(ltMPTOKEN_ISSUANCE, 0x007e, MPTokenIssuance, mpt_issuance, ({
{sfReferenceHolding, SoeOptional},
{sfIssuerEncryptionKey, SoeOptional},
{sfAuditorEncryptionKey, SoeOptional},
{sfIssuerKeyEpoch, SoeOptional},
{sfAuditorKeyEpoch, SoeOptional},
{sfConfidentialOutstandingAmount, SoeDefault},
}))
@@ -523,48 +513,6 @@ LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
// no PermissionedDomainID ever (use MPTIssuance.sfDomainID)
}))
/** A ledger object representing a contract source.
\sa keylet::contractSource
*/
LEDGER_ENTRY(ltCONTRACT_SOURCE, 0x0085, ContractSource, contract_source, ({
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfContractHash, SoeRequired},
{sfContractCode, SoeRequired},
{sfFunctions, SoeRequired},
{sfInstanceParameters, SoeOptional},
{sfReferenceCount, SoeRequired},
}))
/** A ledger object representing a contract.
\sa keylet::contract
*/
LEDGER_ENTRY(ltCONTRACT, 0x0086, Contract, contract, ({
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfSequence, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfOwner, SoeRequired},
{sfContractAccount, SoeRequired},
{sfContractHash, SoeRequired},
{sfInstanceParameterValues, SoeOptional},
{sfURI, SoeOptional},
}))
/** A ledger object representing a contract data.
\sa keylet::contractData
*/
LEDGER_ENTRY(ltCONTRACT_DATA, 0x0087, ContractData, contract_data, ({
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfOwner, SoeRequired},
{sfContractAccount, SoeRequired},
{sfContractJson, SoeRequired},
}))
/** Reserve 0x0084-0x0087 for future Vault-related objects. */
/** A ledger object representing a loan broker

View File

@@ -119,16 +119,6 @@ TYPED_SFIELD(sfRemainingOwnerCount, UINT32, 73)
TYPED_SFIELD(sfSponsorFlags, UINT32, 74)
TYPED_SFIELD(sfSubscriptionDate, UINT32, 75)
TYPED_SFIELD(sfRedemptionDate, UINT32, 76)
TYPED_SFIELD(sfIssuerKeyEpoch, UINT32, 77)
TYPED_SFIELD(sfAuditorKeyEpoch, UINT32, 78)
TYPED_SFIELD(sfIssuerKeyMirrorEpoch, UINT32, 79)
TYPED_SFIELD(sfAuditorKeyMirrorEpoch, UINT32, 80)
TYPED_SFIELD(sfGasLimit, UINT32, 81)
TYPED_SFIELD(sfBytecodeSizeLimit, UINT32, 82)
TYPED_SFIELD(sfGasPrice, UINT32, 83)
TYPED_SFIELD(sfGas, UINT32, 84)
TYPED_SFIELD(sfGasUsed, UINT32, 85)
TYPED_SFIELD(sfParameterFlag, UINT32, 86)
// 64-bit integers (common)
TYPED_SFIELD(sfIndexNext, UINT64, 1)
@@ -221,9 +211,6 @@ TYPED_SFIELD(sfLoanID, UINT256, 38)
TYPED_SFIELD(sfReferenceHolding, UINT256, 39)
TYPED_SFIELD(sfBlindingFactor, UINT256, 40)
TYPED_SFIELD(sfObjectID, UINT256, 41)
TYPED_SFIELD(sfContractHash, UINT256, 42)
TYPED_SFIELD(sfContractID, UINT256, 43,
SField::kSmdPseudoAccount | SField::kSmdDefault)
// number (common)
TYPED_SFIELD(sfNumber, NUMBER, 1)
@@ -247,7 +234,6 @@ TYPED_SFIELD(sfManagementFeeOutstanding, NUMBER, 17, SField::kSmdNeedsAsset
// 32-bit signed (common)
TYPED_SFIELD(sfLoanScale, INT32, 1)
TYPED_SFIELD(sfRemainingOwnerCountDelta, INT32, 2)
TYPED_SFIELD(sfVMReturnCode, INT32, 3)
// currency amount (common)
TYPED_SFIELD(sfAmount, AMOUNT, 1)
@@ -332,9 +318,6 @@ TYPED_SFIELD(sfAuditorEncryptedAmount, VL, 43)
TYPED_SFIELD(sfAuditorEncryptionKey, VL, 44)
TYPED_SFIELD(sfAmountCommitment, VL, 45)
TYPED_SFIELD(sfBalanceCommitment, VL, 46)
TYPED_SFIELD(sfBytecode, VL, 47)
TYPED_SFIELD(sfContractCode, VL, 48)
TYPED_SFIELD(sfFunctionName, VL, 49)
// account (common)
TYPED_SFIELD(sfAccount, ACCOUNT, 1)
@@ -366,7 +349,6 @@ TYPED_SFIELD(sfHighSponsor, ACCOUNT, 28)
TYPED_SFIELD(sfLowSponsor, ACCOUNT, 29)
TYPED_SFIELD(sfCounterpartySponsor, ACCOUNT, 30)
TYPED_SFIELD(sfSponsee, ACCOUNT, 31)
TYPED_SFIELD(sfContractAccount, ACCOUNT, 32)
// vector of 256-bit
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::kSmdNever)
@@ -428,10 +410,6 @@ UNTYPED_SFIELD(sfBatchSigner, OBJECT, 35)
UNTYPED_SFIELD(sfBook, OBJECT, 36)
UNTYPED_SFIELD(sfCounterpartySignature, OBJECT, 37, SField::kSmdDefault, SField::kNotSigning)
UNTYPED_SFIELD(sfSponsorSignature, OBJECT, 38, SField::kSmdDefault, SField::kNotSigning)
UNTYPED_SFIELD(sfFunction, OBJECT, 39)
UNTYPED_SFIELD(sfInstanceParameter, OBJECT, 40)
UNTYPED_SFIELD(sfInstanceParameterValue, OBJECT, 41)
UNTYPED_SFIELD(sfParameter, OBJECT, 42)
// array of objects (common)
// ARRAY/1 is reserved for end of array
@@ -464,10 +442,3 @@ UNTYPED_SFIELD(sfAcceptedCredentials, ARRAY, 28)
UNTYPED_SFIELD(sfPermissions, ARRAY, 29)
UNTYPED_SFIELD(sfRawTransactions, ARRAY, 30)
UNTYPED_SFIELD(sfBatchSigners, ARRAY, 31, SField::kSmdDefault, SField::kNotSigning)
UNTYPED_SFIELD(sfFunctions, ARRAY, 32)
UNTYPED_SFIELD(sfInstanceParameters, ARRAY, 33)
UNTYPED_SFIELD(sfInstanceParameterValues,ARRAY, 34)
UNTYPED_SFIELD(sfParameters, ARRAY, 35)
TYPED_SFIELD(sfParameterValue, DATA, 1, SField::kSmdDefault)
TYPED_SFIELD(sfParameterType, DATATYPE, 1)
TYPED_SFIELD(sfContractJson, JSON, 1)

View File

@@ -23,7 +23,6 @@
* Delegation delegable{Delegation::NotDelegable};
* uint256 amendment{};
* Privilege privileges{Privilege::NoPriv};
* Emittance emittance{Emittance::Emitable};
* };
*
* Name only the settings that differ from those defaults, in declaration
@@ -67,13 +66,11 @@ TRANSACTION(ttPAYMENT, 0, Payment,
#endif
TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate, ({.delegable = Delegation::Delegable}), ({
{sfDestination, SoeRequired},
{sfDestinationTag, SoeOptional},
{sfAmount, SoeRequired, SoeMptSupported},
{sfCondition, SoeOptional},
{sfCancelAfter, SoeOptional},
{sfFinishAfter, SoeOptional},
{sfBytecode, SoeOptional},
{sfData, SoeOptional},
{sfDestinationTag, SoeOptional},
}))
/** This transaction type completes an existing escrow. */
@@ -86,7 +83,6 @@ TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish, ({.delegable = Delegation::Delegab
{sfFulfillment, SoeOptional},
{sfCondition, SoeOptional},
{sfCredentialIDs, SoeOptional},
{sfGas, SoeOptional},
}))
@@ -123,9 +119,7 @@ TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel, ({.delegable = Delegation::Delegab
# include <xrpl/tx/transactors/account/SetRegularKey.h>
#endif
TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey,
({
.emittance = Emittance::NotEmitable,
}),
({}),
({
{sfRegularKey, SoeOptional},
}))
@@ -173,9 +167,7 @@ TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, ({.delegable = Delegation::Delega
# include <xrpl/tx/transactors/account/SignerListSet.h>
#endif
TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet,
({
.emittance = Emittance::NotEmitable,
}),
({}),
({
{sfSignerQuorum, SoeRequired},
{sfSignerEntries, SoeOptional},
@@ -253,12 +245,7 @@ TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel, ({.delegable = Delegation::Delegabl
#if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/payment/DepositPreauth.h>
#endif
TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth,
({
.delegable = Delegation::Delegable,
.emittance = Emittance::NotEmitable,
}),
({
TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth, ({.delegable = Delegation::Delegable}), ({
{sfAuthorize, SoeOptional},
{sfUnauthorize, SoeOptional},
{sfAuthorizeCredentials, SoeOptional},
@@ -282,7 +269,6 @@ TRANSACTION(ttTRUST_SET, 20, TrustSet, ({.delegable = Delegation::Delegable}), (
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
({
.privileges = Privilege::MustDeleteAcct,
.emittance = Emittance::NotEmitable,
}),
({
{sfDestination, SoeRequired},
@@ -772,7 +758,6 @@ TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete,
TRANSACTION(ttDELEGATE_SET, 64, DelegateSet,
({
.amendment = featurePermissionDelegationV1_1,
.emittance = Emittance::NotEmitable,
}),
({
{sfAuthorize, SoeRequired},
@@ -887,7 +872,6 @@ TRANSACTION(ttVAULT_CLAWBACK, 70, VaultClawback,
TRANSACTION(ttBATCH, 71, Batch,
({
.amendment = featureBatchV1_1,
.emittance = Emittance::NotEmitable,
}),
({
{sfRawTransactions, SoeRequired},
@@ -1147,105 +1131,6 @@ TRANSACTION(ttSPONSORSHIP_SET, 91, SponsorshipSet,
{sfRemainingOwnerCountDelta, SoeOptional},
}))
/** This transaction type creates the smart contract. */
#if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/contract/ContractCreate.h>
#endif
TRANSACTION(ttCONTRACT_CREATE, 92, ContractCreate,
({
.delegable = Delegation::Delegable,
.amendment = featureSmartContract,
.privileges = Privilege::CreatePseudoAcct,
}),
({
{sfContractCode, SoeOptional},
{sfContractHash, SoeOptional},
{sfFunctions, SoeOptional},
{sfInstanceParameters, SoeOptional},
{sfInstanceParameterValues, SoeOptional},
{sfURI, SoeOptional},
}))
/** This transaction type modifies the smart contract. */
#if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/contract/ContractModify.h>
#endif
TRANSACTION(ttCONTRACT_MODIFY, 93, ContractModify,
({
.delegable = Delegation::Delegable,
.amendment = featureSmartContract,
}),
({
{sfContractAccount, SoeOptional},
{sfOwner, SoeOptional},
{sfContractCode, SoeOptional},
{sfContractHash, SoeOptional},
{sfFunctions, SoeOptional},
{sfInstanceParameters, SoeOptional},
{sfInstanceParameterValues, SoeOptional},
{sfURI, SoeOptional},
}))
/** This transaction type deletes the smart contract. */
#if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/contract/ContractDelete.h>
#endif
TRANSACTION(ttCONTRACT_DELETE, 94, ContractDelete,
({
.delegable = Delegation::Delegable,
.amendment = featureSmartContract,
.privileges = Privilege::MustDeleteAcct,
}),
({
{sfContractAccount, SoeRequired},
}))
/** This transaction type claws back funds from the contract. */
#if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/contract/ContractClawback.h>
#endif
TRANSACTION(ttCONTRACT_CLAWBACK, 95, ContractClawback,
({
.delegable = Delegation::Delegable,
.amendment = featureSmartContract,
}),
({
{sfContractAccount, SoeOptional},
{sfAmount, SoeRequired, SoeMptSupported},
}))
/** This transaction type deletes user data. */
#if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/contract/ContractUserDelete.h>
#endif
TRANSACTION(ttCONTRACT_USER_DELETE, 96, ContractUserDelete,
({
.delegable = Delegation::Delegable,
.amendment = featureSmartContract,
.emittance = Emittance::NotEmitable,
}),
({
{sfContractAccount, SoeRequired},
{sfGas, SoeRequired},
}))
/** This transaction type calls the smart contract. */
#if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/contract/ContractCall.h>
#endif
TRANSACTION(ttCONTRACT_CALL, 97, ContractCall,
({
.delegable = Delegation::Delegable,
.amendment = featureSmartContract,
.emittance = Emittance::NotEmitable,
}),
({
{sfContractAccount, SoeRequired},
{sfFunctionName, SoeRequired},
{sfParameters, SoeOptional},
{sfGas, SoeRequired},
}))
/** This system-generated transaction type is used to update the status of the various amendments.
For details, see: https://xrpl.org/amendments.html
@@ -1254,9 +1139,7 @@ TRANSACTION(ttCONTRACT_CALL, 97, ContractCall,
# include <xrpl/tx/transactors/system/Change.h>
#endif
TRANSACTION(ttAMENDMENT, 100, EnableAmendment,
({
.emittance = Emittance::NotEmitable,
}),
({}),
({
{sfLedgerSequence, SoeRequired},
{sfAmendment, SoeRequired},
@@ -1266,9 +1149,7 @@ TRANSACTION(ttAMENDMENT, 100, EnableAmendment,
For details, see: https://xrpl.org/fee-voting.html
*/
TRANSACTION(ttFEE, 101, SetFee,
({
.emittance = Emittance::NotEmitable,
}),
({}),
({
{sfLedgerSequence, SoeOptional},
// Old version uses raw numbers
@@ -1280,10 +1161,6 @@ TRANSACTION(ttFEE, 101, SetFee,
{sfBaseFeeDrops, SoeOptional},
{sfReserveBaseDrops, SoeOptional},
{sfReserveIncrementDrops, SoeOptional},
// Smart Escrow fields
{sfGasLimit, SoeOptional},
{sfBytecodeSizeLimit, SoeOptional},
{sfGasPrice, SoeOptional},
}))
/** This system-generated transaction type is used to update the network's negative UNL
@@ -1291,9 +1168,7 @@ TRANSACTION(ttFEE, 101, SetFee,
For details, see: https://xrpl.org/negative-unl.html
*/
TRANSACTION(ttUNL_MODIFY, 102, UNLModify,
({
.emittance = Emittance::NotEmitable,
}),
({}),
({
{sfUNLModifyDisabling, SoeRequired},
{sfLedgerSequence, SoeRequired},

View File

@@ -189,7 +189,6 @@ JSS(confidential_balance_inbox); // out: mpt_holders (confidential MPT)
JSS(confidential_balance_spending); // out: mpt_holders (confidential MPT)
JSS(confidential_balance_version); // out: mpt_holders (confidential MPT)
JSS(consensus); // out: NetworkOPs, LedgerConsensus
JSS(contract_account); // out: ContractInfo
JSS(converge_time); // out: NetworkOPs
JSS(converge_time_s); // out: NetworkOPs
JSS(cookie); // out: NetworkOPs
@@ -253,9 +252,6 @@ JSS(expected_date); // out: any (warnings)
JSS(expected_date_UTC); // out: any (warnings)
JSS(expected_ledger_size); // out: TxQ
JSS(expiration); // out: AccountOffers, AccountChannels, ValidatorList, amm_info
JSS(gas_limit); // out: NetworkOPs
JSS(bytecode_size_limit); // out: NetworkOPs
JSS(gas_price); // out: NetworkOPs
JSS(fail_hard); // in: Sign, Submit
JSS(failed); // out: InboundLedger
JSS(feature); // in: Feature
@@ -282,8 +278,6 @@ JSS(frozen_balances); // out: GatewayBalances
JSS(full); // in: LedgerClearer, handlers/Ledger
JSS(full_reply); // out: PathFind
JSS(fullbelow_size); // out: GetCounts
JSS(function); // in: ContractInfo
JSS(functions); // out: ContractInfo
JSS(git); // out: server_info
JSS(good); // out: RPCVersion
JSS(hash); // out: NetworkOPs, InboundLedger, LedgerToJson, STTx; field
@@ -566,7 +560,6 @@ JSS(size); // out: get_aggregate_price
JSS(snapshot); // in: Subscribe
JSS(source_account); // in: PathRequest, RipplePathFind
JSS(source_amount); // in: PathRequest, RipplePathFind
JSS(source_code_uri); // out: ContractInfo
JSS(source_currencies); // in: PathRequest, RipplePathFind
JSS(source_tag); // out: AccountChannels
JSS(sponsee); // in: LedgerEntry
@@ -667,7 +660,6 @@ JSS(url); // in/out: Subscribe, Unsubscribe
JSS(url_password); // in: Subscribe
JSS(url_username); // in: Subscribe
JSS(urlgravatar); //
JSS(user_data); // out: ContractInfo
JSS(username); // in: Subscribe
JSS(validated); // out: NetworkOPs, RPCHelpers, AccountTx*, Tx
JSS(validator_list_expires); // out: NetworkOps, ValidatorList

View File

@@ -590,30 +590,6 @@ public:
{
return this->sle_->isFieldPresent(sfLoanBrokerID);
}
/**
* @brief Get sfContractID (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT256::type::value_type>
getContractID() const
{
if (hasContractID())
return this->sle_->at(sfContractID);
return std::nullopt;
}
/**
* @brief Check if sfContractID is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasContractID() const
{
return this->sle_->isFieldPresent(sfContractID);
}
};
/**
@@ -950,17 +926,6 @@ public:
return *this;
}
/**
* @brief Set sfContractID (SoeOptional)
* @return Reference to this builder for method chaining.
*/
AccountRootBuilder&
setContractID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
{
object_[sfContractID] = value;
return *this;
}
/**
* @brief Build and return the completed AccountRoot wrapper.
* @param index The ledger entry index.

View File

@@ -1,336 +0,0 @@
// This file is auto-generated. Do not edit.
#pragma once
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/protocol_autogen/LedgerEntryBase.h>
#include <xrpl/protocol_autogen/LedgerEntryBuilderBase.h>
#include <xrpl/json/json_value.h>
#include <stdexcept>
#include <optional>
namespace xrpl::ledger_entries {
class ContractBuilder;
/**
* @brief Ledger Entry: Contract
*
* Type: ltCONTRACT (0x0086)
* RPC Name: contract
*
* Immutable wrapper around SLE providing type-safe field access.
* Use ContractBuilder to construct new ledger entries.
*/
class Contract : public LedgerEntryBase
{
public:
static constexpr LedgerEntryType entryType = ltCONTRACT;
/**
* @brief Construct a Contract ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit Contract(SLE::const_pointer sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
if (sle_->getType() != entryType)
{
throw std::runtime_error("Invalid ledger entry type for Contract");
}
}
// Ledger entry-specific field getters
/**
* @brief Get sfPreviousTxnID (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT256::type::value_type
getPreviousTxnID() const
{
return this->sle_->at(sfPreviousTxnID);
}
/**
* @brief Get sfPreviousTxnLgrSeq (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT32::type::value_type
getPreviousTxnLgrSeq() const
{
return this->sle_->at(sfPreviousTxnLgrSeq);
}
/**
* @brief Get sfSequence (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT32::type::value_type
getSequence() const
{
return this->sle_->at(sfSequence);
}
/**
* @brief Get sfOwnerNode (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT64::type::value_type
getOwnerNode() const
{
return this->sle_->at(sfOwnerNode);
}
/**
* @brief Get sfOwner (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_ACCOUNT::type::value_type
getOwner() const
{
return this->sle_->at(sfOwner);
}
/**
* @brief Get sfContractAccount (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_ACCOUNT::type::value_type
getContractAccount() const
{
return this->sle_->at(sfContractAccount);
}
/**
* @brief Get sfContractHash (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT256::type::value_type
getContractHash() const
{
return this->sle_->at(sfContractHash);
}
/**
* @brief Get sfInstanceParameterValues (SoeOptional)
* @note This is an untyped field (unknown).
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
std::optional<std::reference_wrapper<STArray const>>
getInstanceParameterValues() const
{
if (this->sle_->isFieldPresent(sfInstanceParameterValues))
return this->sle_->getFieldArray(sfInstanceParameterValues);
return std::nullopt;
}
/**
* @brief Check if sfInstanceParameterValues is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasInstanceParameterValues() const
{
return this->sle_->isFieldPresent(sfInstanceParameterValues);
}
/**
* @brief Get sfURI (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getURI() const
{
if (hasURI())
return this->sle_->at(sfURI);
return std::nullopt;
}
/**
* @brief Check if sfURI is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasURI() const
{
return this->sle_->isFieldPresent(sfURI);
}
};
/**
* @brief Builder for Contract ledger entries.
*
* Provides a fluent interface for constructing ledger entries with method chaining.
* Uses STObject internally for flexible ledger entry construction.
* Inherits common field setters from LedgerEntryBuilderBase.
*/
class ContractBuilder : public LedgerEntryBuilderBase<ContractBuilder>
{
public:
/**
* @brief Construct a new ContractBuilder with required fields.
* @param previousTxnID The sfPreviousTxnID field value.
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
* @param sequence The sfSequence field value.
* @param ownerNode The sfOwnerNode field value.
* @param owner The sfOwner field value.
* @param contractAccount The sfContractAccount field value.
* @param contractHash The sfContractHash field value.
*/
ContractBuilder(std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq,std::decay_t<typename SF_UINT32::type::value_type> const& sequence,std::decay_t<typename SF_UINT64::type::value_type> const& ownerNode,std::decay_t<typename SF_ACCOUNT::type::value_type> const& owner,std::decay_t<typename SF_ACCOUNT::type::value_type> const& contractAccount,std::decay_t<typename SF_UINT256::type::value_type> const& contractHash)
: LedgerEntryBuilderBase<ContractBuilder>(ltCONTRACT)
{
setPreviousTxnID(previousTxnID);
setPreviousTxnLgrSeq(previousTxnLgrSeq);
setSequence(sequence);
setOwnerNode(ownerNode);
setOwner(owner);
setContractAccount(contractAccount);
setContractHash(contractHash);
}
/**
* @brief Construct a ContractBuilder from an existing SLE object.
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
ContractBuilder(SLE::const_pointer sle)
{
if (sle->at(sfLedgerEntryType) != ltCONTRACT)
{
throw std::runtime_error("Invalid ledger entry type for Contract");
}
object_ = *sle;
}
/**
* @brief Ledger entry-specific field setters
*/
/**
* @brief Set sfPreviousTxnID (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractBuilder&
setPreviousTxnID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
{
object_[sfPreviousTxnID] = value;
return *this;
}
/**
* @brief Set sfPreviousTxnLgrSeq (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractBuilder&
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfPreviousTxnLgrSeq] = value;
return *this;
}
/**
* @brief Set sfSequence (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractBuilder&
setSequence(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfSequence] = value;
return *this;
}
/**
* @brief Set sfOwnerNode (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractBuilder&
setOwnerNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
{
object_[sfOwnerNode] = value;
return *this;
}
/**
* @brief Set sfOwner (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractBuilder&
setOwner(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
{
object_[sfOwner] = value;
return *this;
}
/**
* @brief Set sfContractAccount (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractBuilder&
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
{
object_[sfContractAccount] = value;
return *this;
}
/**
* @brief Set sfContractHash (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractBuilder&
setContractHash(std::decay_t<typename SF_UINT256::type::value_type> const& value)
{
object_[sfContractHash] = value;
return *this;
}
/**
* @brief Set sfInstanceParameterValues (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractBuilder&
setInstanceParameterValues(STArray const& value)
{
object_.setFieldArray(sfInstanceParameterValues, value);
return *this;
}
/**
* @brief Set sfURI (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractBuilder&
setURI(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfURI] = value;
return *this;
}
/**
* @brief Build and return the completed Contract wrapper.
* @param index The ledger entry index.
* @return The constructed ledger entry wrapper.
*/
Contract
build(uint256 const& index)
{
return Contract{std::make_shared<SLE>(std::move(object_), index)};
}
};
} // namespace xrpl::ledger_entries

View File

@@ -1,241 +0,0 @@
// This file is auto-generated. Do not edit.
#pragma once
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/protocol_autogen/LedgerEntryBase.h>
#include <xrpl/protocol_autogen/LedgerEntryBuilderBase.h>
#include <xrpl/json/json_value.h>
#include <stdexcept>
#include <optional>
namespace xrpl::ledger_entries {
class ContractDataBuilder;
/**
* @brief Ledger Entry: ContractData
*
* Type: ltCONTRACT_DATA (0x0087)
* RPC Name: contract_data
*
* Immutable wrapper around SLE providing type-safe field access.
* Use ContractDataBuilder to construct new ledger entries.
*/
class ContractData : public LedgerEntryBase
{
public:
static constexpr LedgerEntryType entryType = ltCONTRACT_DATA;
/**
* @brief Construct a ContractData ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit ContractData(SLE::const_pointer sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
if (sle_->getType() != entryType)
{
throw std::runtime_error("Invalid ledger entry type for ContractData");
}
}
// Ledger entry-specific field getters
/**
* @brief Get sfPreviousTxnID (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT256::type::value_type
getPreviousTxnID() const
{
return this->sle_->at(sfPreviousTxnID);
}
/**
* @brief Get sfPreviousTxnLgrSeq (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT32::type::value_type
getPreviousTxnLgrSeq() const
{
return this->sle_->at(sfPreviousTxnLgrSeq);
}
/**
* @brief Get sfOwnerNode (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT64::type::value_type
getOwnerNode() const
{
return this->sle_->at(sfOwnerNode);
}
/**
* @brief Get sfOwner (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_ACCOUNT::type::value_type
getOwner() const
{
return this->sle_->at(sfOwner);
}
/**
* @brief Get sfContractAccount (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_ACCOUNT::type::value_type
getContractAccount() const
{
return this->sle_->at(sfContractAccount);
}
/**
* @brief Get sfContractJson (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_JSON::type::value_type
getContractJson() const
{
return this->sle_->at(sfContractJson);
}
};
/**
* @brief Builder for ContractData ledger entries.
*
* Provides a fluent interface for constructing ledger entries with method chaining.
* Uses STObject internally for flexible ledger entry construction.
* Inherits common field setters from LedgerEntryBuilderBase.
*/
class ContractDataBuilder : public LedgerEntryBuilderBase<ContractDataBuilder>
{
public:
/**
* @brief Construct a new ContractDataBuilder with required fields.
* @param previousTxnID The sfPreviousTxnID field value.
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
* @param ownerNode The sfOwnerNode field value.
* @param owner The sfOwner field value.
* @param contractAccount The sfContractAccount field value.
* @param contractJson The sfContractJson field value.
*/
ContractDataBuilder(std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq,std::decay_t<typename SF_UINT64::type::value_type> const& ownerNode,std::decay_t<typename SF_ACCOUNT::type::value_type> const& owner,std::decay_t<typename SF_ACCOUNT::type::value_type> const& contractAccount,std::decay_t<typename SF_JSON::type::value_type> const& contractJson)
: LedgerEntryBuilderBase<ContractDataBuilder>(ltCONTRACT_DATA)
{
setPreviousTxnID(previousTxnID);
setPreviousTxnLgrSeq(previousTxnLgrSeq);
setOwnerNode(ownerNode);
setOwner(owner);
setContractAccount(contractAccount);
setContractJson(contractJson);
}
/**
* @brief Construct a ContractDataBuilder from an existing SLE object.
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
ContractDataBuilder(SLE::const_pointer sle)
{
if (sle->at(sfLedgerEntryType) != ltCONTRACT_DATA)
{
throw std::runtime_error("Invalid ledger entry type for ContractData");
}
object_ = *sle;
}
/**
* @brief Ledger entry-specific field setters
*/
/**
* @brief Set sfPreviousTxnID (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractDataBuilder&
setPreviousTxnID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
{
object_[sfPreviousTxnID] = value;
return *this;
}
/**
* @brief Set sfPreviousTxnLgrSeq (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractDataBuilder&
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfPreviousTxnLgrSeq] = value;
return *this;
}
/**
* @brief Set sfOwnerNode (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractDataBuilder&
setOwnerNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
{
object_[sfOwnerNode] = value;
return *this;
}
/**
* @brief Set sfOwner (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractDataBuilder&
setOwner(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
{
object_[sfOwner] = value;
return *this;
}
/**
* @brief Set sfContractAccount (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractDataBuilder&
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
{
object_[sfContractAccount] = value;
return *this;
}
/**
* @brief Set sfContractJson (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractDataBuilder&
setContractJson(std::decay_t<typename SF_JSON::type::value_type> const& value)
{
object_[sfContractJson] = value;
return *this;
}
/**
* @brief Build and return the completed ContractData wrapper.
* @param index The ledger entry index.
* @return The constructed ledger entry wrapper.
*/
ContractData
build(uint256 const& index)
{
return ContractData{std::make_shared<SLE>(std::move(object_), index)};
}
};
} // namespace xrpl::ledger_entries

View File

@@ -1,278 +0,0 @@
// This file is auto-generated. Do not edit.
#pragma once
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/protocol_autogen/LedgerEntryBase.h>
#include <xrpl/protocol_autogen/LedgerEntryBuilderBase.h>
#include <xrpl/json/json_value.h>
#include <stdexcept>
#include <optional>
namespace xrpl::ledger_entries {
class ContractSourceBuilder;
/**
* @brief Ledger Entry: ContractSource
*
* Type: ltCONTRACT_SOURCE (0x0085)
* RPC Name: contract_source
*
* Immutable wrapper around SLE providing type-safe field access.
* Use ContractSourceBuilder to construct new ledger entries.
*/
class ContractSource : public LedgerEntryBase
{
public:
static constexpr LedgerEntryType entryType = ltCONTRACT_SOURCE;
/**
* @brief Construct a ContractSource ledger entry wrapper from an existing SLE object.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
explicit ContractSource(SLE::const_pointer sle)
: LedgerEntryBase(std::move(sle))
{
// Verify ledger entry type
if (sle_->getType() != entryType)
{
throw std::runtime_error("Invalid ledger entry type for ContractSource");
}
}
// Ledger entry-specific field getters
/**
* @brief Get sfPreviousTxnID (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT256::type::value_type
getPreviousTxnID() const
{
return this->sle_->at(sfPreviousTxnID);
}
/**
* @brief Get sfPreviousTxnLgrSeq (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT32::type::value_type
getPreviousTxnLgrSeq() const
{
return this->sle_->at(sfPreviousTxnLgrSeq);
}
/**
* @brief Get sfContractHash (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT256::type::value_type
getContractHash() const
{
return this->sle_->at(sfContractHash);
}
/**
* @brief Get sfContractCode (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_VL::type::value_type
getContractCode() const
{
return this->sle_->at(sfContractCode);
}
/**
* @brief Get sfFunctions (SoeRequired)
* @note This is an untyped field (unknown).
* @return The field value.
*/
[[nodiscard]]
STArray const&
getFunctions() const
{
return this->sle_->getFieldArray(sfFunctions);
}
/**
* @brief Get sfInstanceParameters (SoeOptional)
* @note This is an untyped field (unknown).
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
std::optional<std::reference_wrapper<STArray const>>
getInstanceParameters() const
{
if (this->sle_->isFieldPresent(sfInstanceParameters))
return this->sle_->getFieldArray(sfInstanceParameters);
return std::nullopt;
}
/**
* @brief Check if sfInstanceParameters is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasInstanceParameters() const
{
return this->sle_->isFieldPresent(sfInstanceParameters);
}
/**
* @brief Get sfReferenceCount (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT64::type::value_type
getReferenceCount() const
{
return this->sle_->at(sfReferenceCount);
}
};
/**
* @brief Builder for ContractSource ledger entries.
*
* Provides a fluent interface for constructing ledger entries with method chaining.
* Uses STObject internally for flexible ledger entry construction.
* Inherits common field setters from LedgerEntryBuilderBase.
*/
class ContractSourceBuilder : public LedgerEntryBuilderBase<ContractSourceBuilder>
{
public:
/**
* @brief Construct a new ContractSourceBuilder with required fields.
* @param previousTxnID The sfPreviousTxnID field value.
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
* @param contractHash The sfContractHash field value.
* @param contractCode The sfContractCode field value.
* @param functions The sfFunctions field value.
* @param referenceCount The sfReferenceCount field value.
*/
ContractSourceBuilder(std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq,std::decay_t<typename SF_UINT256::type::value_type> const& contractHash,std::decay_t<typename SF_VL::type::value_type> const& contractCode,STArray const& functions,std::decay_t<typename SF_UINT64::type::value_type> const& referenceCount)
: LedgerEntryBuilderBase<ContractSourceBuilder>(ltCONTRACT_SOURCE)
{
setPreviousTxnID(previousTxnID);
setPreviousTxnLgrSeq(previousTxnLgrSeq);
setContractHash(contractHash);
setContractCode(contractCode);
setFunctions(functions);
setReferenceCount(referenceCount);
}
/**
* @brief Construct a ContractSourceBuilder from an existing SLE object.
* @param sle The existing ledger entry to copy from.
* @throws std::runtime_error if the ledger entry type doesn't match.
*/
ContractSourceBuilder(SLE::const_pointer sle)
{
if (sle->at(sfLedgerEntryType) != ltCONTRACT_SOURCE)
{
throw std::runtime_error("Invalid ledger entry type for ContractSource");
}
object_ = *sle;
}
/**
* @brief Ledger entry-specific field setters
*/
/**
* @brief Set sfPreviousTxnID (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractSourceBuilder&
setPreviousTxnID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
{
object_[sfPreviousTxnID] = value;
return *this;
}
/**
* @brief Set sfPreviousTxnLgrSeq (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractSourceBuilder&
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfPreviousTxnLgrSeq] = value;
return *this;
}
/**
* @brief Set sfContractHash (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractSourceBuilder&
setContractHash(std::decay_t<typename SF_UINT256::type::value_type> const& value)
{
object_[sfContractHash] = value;
return *this;
}
/**
* @brief Set sfContractCode (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractSourceBuilder&
setContractCode(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfContractCode] = value;
return *this;
}
/**
* @brief Set sfFunctions (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractSourceBuilder&
setFunctions(STArray const& value)
{
object_.setFieldArray(sfFunctions, value);
return *this;
}
/**
* @brief Set sfInstanceParameters (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractSourceBuilder&
setInstanceParameters(STArray const& value)
{
object_.setFieldArray(sfInstanceParameters, value);
return *this;
}
/**
* @brief Set sfReferenceCount (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractSourceBuilder&
setReferenceCount(std::decay_t<typename SF_UINT64::type::value_type> const& value)
{
object_[sfReferenceCount] = value;
return *this;
}
/**
* @brief Build and return the completed ContractSource wrapper.
* @param index The ledger entry index.
* @return The constructed ledger entry wrapper.
*/
ContractSource
build(uint256 const& index)
{
return ContractSource{std::make_shared<SLE>(std::move(object_), index)};
}
};
} // namespace xrpl::ledger_entries

View File

@@ -174,54 +174,6 @@ public:
return this->sle_->isFieldPresent(sfFinishAfter);
}
/**
* @brief Get sfBytecode (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getBytecode() const
{
if (hasBytecode())
return this->sle_->at(sfBytecode);
return std::nullopt;
}
/**
* @brief Check if sfBytecode is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasBytecode() const
{
return this->sle_->isFieldPresent(sfBytecode);
}
/**
* @brief Get sfData (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getData() const
{
if (hasData())
return this->sle_->at(sfData);
return std::nullopt;
}
/**
* @brief Check if sfData is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasData() const
{
return this->sle_->isFieldPresent(sfData);
}
/**
* @brief Get sfSourceTag (SoeOptional)
* @return The field value, or std::nullopt if not present.
@@ -501,28 +453,6 @@ public:
return *this;
}
/**
* @brief Set sfBytecode (SoeOptional)
* @return Reference to this builder for method chaining.
*/
EscrowBuilder&
setBytecode(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfBytecode] = value;
return *this;
}
/**
* @brief Set sfData (SoeOptional)
* @return Reference to this builder for method chaining.
*/
EscrowBuilder&
setData(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfData] = value;
return *this;
}
/**
* @brief Set sfSourceTag (SoeOptional)
* @return Reference to this builder for method chaining.

View File

@@ -213,78 +213,6 @@ public:
return this->sle_->isFieldPresent(sfReserveIncrementDrops);
}
/**
* @brief Get sfGasLimit (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getGasLimit() const
{
if (hasGasLimit())
return this->sle_->at(sfGasLimit);
return std::nullopt;
}
/**
* @brief Check if sfGasLimit is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasGasLimit() const
{
return this->sle_->isFieldPresent(sfGasLimit);
}
/**
* @brief Get sfBytecodeSizeLimit (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getBytecodeSizeLimit() const
{
if (hasBytecodeSizeLimit())
return this->sle_->at(sfBytecodeSizeLimit);
return std::nullopt;
}
/**
* @brief Check if sfBytecodeSizeLimit is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasBytecodeSizeLimit() const
{
return this->sle_->isFieldPresent(sfBytecodeSizeLimit);
}
/**
* @brief Get sfGasPrice (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getGasPrice() const
{
if (hasGasPrice())
return this->sle_->at(sfGasPrice);
return std::nullopt;
}
/**
* @brief Check if sfGasPrice is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasGasPrice() const
{
return this->sle_->isFieldPresent(sfGasPrice);
}
/**
* @brief Get sfPreviousTxnID (SoeOptional)
* @return The field value, or std::nullopt if not present.
@@ -447,39 +375,6 @@ public:
return *this;
}
/**
* @brief Set sfGasLimit (SoeOptional)
* @return Reference to this builder for method chaining.
*/
FeeSettingsBuilder&
setGasLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGasLimit] = value;
return *this;
}
/**
* @brief Set sfBytecodeSizeLimit (SoeOptional)
* @return Reference to this builder for method chaining.
*/
FeeSettingsBuilder&
setBytecodeSizeLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfBytecodeSizeLimit] = value;
return *this;
}
/**
* @brief Set sfGasPrice (SoeOptional)
* @return Reference to this builder for method chaining.
*/
FeeSettingsBuilder&
setGasPrice(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGasPrice] = value;
return *this;
}
/**
* @brief Set sfPreviousTxnID (SoeOptional)
* @return Reference to this builder for method chaining.

View File

@@ -351,54 +351,6 @@ public:
return this->sle_->isFieldPresent(sfAuditorEncryptionKey);
}
/**
* @brief Get sfIssuerKeyEpoch (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getIssuerKeyEpoch() const
{
if (hasIssuerKeyEpoch())
return this->sle_->at(sfIssuerKeyEpoch);
return std::nullopt;
}
/**
* @brief Check if sfIssuerKeyEpoch is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasIssuerKeyEpoch() const
{
return this->sle_->isFieldPresent(sfIssuerKeyEpoch);
}
/**
* @brief Get sfAuditorKeyEpoch (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getAuditorKeyEpoch() const
{
if (hasAuditorKeyEpoch())
return this->sle_->at(sfAuditorKeyEpoch);
return std::nullopt;
}
/**
* @brief Check if sfAuditorKeyEpoch is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasAuditorKeyEpoch() const
{
return this->sle_->isFieldPresent(sfAuditorKeyEpoch);
}
/**
* @brief Get sfConfidentialOutstandingAmount (SoeDefault)
* @return The field value, or std::nullopt if not present.
@@ -648,28 +600,6 @@ public:
return *this;
}
/**
* @brief Set sfIssuerKeyEpoch (SoeOptional)
* @return Reference to this builder for method chaining.
*/
MPTokenIssuanceBuilder&
setIssuerKeyEpoch(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfIssuerKeyEpoch] = value;
return *this;
}
/**
* @brief Set sfAuditorKeyEpoch (SoeOptional)
* @return Reference to this builder for method chaining.
*/
MPTokenIssuanceBuilder&
setAuditorKeyEpoch(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfAuditorKeyEpoch] = value;
return *this;
}
/**
* @brief Set sfConfidentialOutstandingAmount (SoeDefault)
* @return Reference to this builder for method chaining.

View File

@@ -1,214 +0,0 @@
// This file is auto-generated. Do not edit.
#pragma once
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/protocol_autogen/TransactionBase.h>
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
#include <xrpl/json/json_value.h>
#include <stdexcept>
#include <optional>
namespace xrpl::transactions {
class ContractCallBuilder;
/**
* @brief Transaction: ContractCall
*
* Type: ttCONTRACT_CALL (97)
* Delegable: Delegation::Delegable
* Amendment: featureSmartContract
* Privileges: Privilege::NoPriv
*
* Immutable wrapper around STTx providing type-safe field access.
* Use ContractCallBuilder to construct new transactions.
*/
class ContractCall : public TransactionBase
{
public:
static constexpr xrpl::TxType txType = ttCONTRACT_CALL;
/**
* @brief Construct a ContractCall transaction wrapper from an existing STTx object.
* @throws std::runtime_error if the transaction type doesn't match.
*/
explicit ContractCall(std::shared_ptr<STTx const> tx)
: TransactionBase(std::move(tx))
{
// Verify transaction type
if (tx_->getTxnType() != txType)
{
throw std::runtime_error("Invalid transaction type for ContractCall");
}
}
// Transaction-specific field getters
/**
* @brief Get sfContractAccount (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_ACCOUNT::type::value_type
getContractAccount() const
{
return this->tx_->at(sfContractAccount);
}
/**
* @brief Get sfFunctionName (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_VL::type::value_type
getFunctionName() const
{
return this->tx_->at(sfFunctionName);
}
/**
* @brief Get sfParameters (SoeOptional)
* @note This is an untyped field.
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
std::optional<std::reference_wrapper<STArray const>>
getParameters() const
{
if (this->tx_->isFieldPresent(sfParameters))
return this->tx_->getFieldArray(sfParameters);
return std::nullopt;
}
/**
* @brief Check if sfParameters is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasParameters() const
{
return this->tx_->isFieldPresent(sfParameters);
}
/**
* @brief Get sfGas (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT32::type::value_type
getGas() const
{
return this->tx_->at(sfGas);
}
};
/**
* @brief Builder for ContractCall transactions.
*
* Provides a fluent interface for constructing transactions with method chaining.
* Uses STObject internally for flexible transaction construction.
* Inherits common field setters from TransactionBuilderBase.
*/
class ContractCallBuilder : public TransactionBuilderBase<ContractCallBuilder>
{
public:
/**
* @brief Construct a new ContractCallBuilder with required fields.
* @param account The account initiating the transaction.
* @param contractAccount The sfContractAccount field value.
* @param functionName The sfFunctionName field value.
* @param gas The sfGas field value.
* @param sequence Optional sequence number for the transaction.
* @param fee Optional fee for the transaction.
*/
ContractCallBuilder(SF_ACCOUNT::type::value_type account,
std::decay_t<typename SF_ACCOUNT::type::value_type> const& contractAccount, std::decay_t<typename SF_VL::type::value_type> const& functionName, std::decay_t<typename SF_UINT32::type::value_type> const& gas, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
)
: TransactionBuilderBase<ContractCallBuilder>(ttCONTRACT_CALL, account, sequence, fee)
{
setContractAccount(contractAccount);
setFunctionName(functionName);
setGas(gas);
}
/**
* @brief Construct a ContractCallBuilder from an existing STTx object.
* @param tx The existing transaction to copy from.
* @throws std::runtime_error if the transaction type doesn't match.
*/
ContractCallBuilder(std::shared_ptr<STTx const> tx)
{
if (tx->getTxnType() != ttCONTRACT_CALL)
{
throw std::runtime_error("Invalid transaction type for ContractCallBuilder");
}
object_ = *tx;
}
/**
* @brief Transaction-specific field setters
*/
/**
* @brief Set sfContractAccount (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractCallBuilder&
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
{
object_[sfContractAccount] = value;
return *this;
}
/**
* @brief Set sfFunctionName (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractCallBuilder&
setFunctionName(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfFunctionName] = value;
return *this;
}
/**
* @brief Set sfParameters (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractCallBuilder&
setParameters(STArray const& value)
{
object_.setFieldArray(sfParameters, value);
return *this;
}
/**
* @brief Set sfGas (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractCallBuilder&
setGas(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGas] = value;
return *this;
}
/**
* @brief Build and return the ContractCall wrapper.
* @param publicKey The public key for signing.
* @param secretKey The secret key for signing.
* @return The constructed transaction wrapper.
*/
ContractCall
build(PublicKey const& publicKey, SecretKey const& secretKey)
{
sign(publicKey, secretKey);
return ContractCall{std::make_shared<STTx>(std::move(object_))};
}
};
} // namespace xrpl::transactions

View File

@@ -1,170 +0,0 @@
// This file is auto-generated. Do not edit.
#pragma once
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/protocol_autogen/TransactionBase.h>
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
#include <xrpl/json/json_value.h>
#include <stdexcept>
#include <optional>
namespace xrpl::transactions {
class ContractClawbackBuilder;
/**
* @brief Transaction: ContractClawback
*
* Type: ttCONTRACT_CLAWBACK (95)
* Delegable: Delegation::Delegable
* Amendment: featureSmartContract
* Privileges: Privilege::NoPriv
*
* Immutable wrapper around STTx providing type-safe field access.
* Use ContractClawbackBuilder to construct new transactions.
*/
class ContractClawback : public TransactionBase
{
public:
static constexpr xrpl::TxType txType = ttCONTRACT_CLAWBACK;
/**
* @brief Construct a ContractClawback transaction wrapper from an existing STTx object.
* @throws std::runtime_error if the transaction type doesn't match.
*/
explicit ContractClawback(std::shared_ptr<STTx const> tx)
: TransactionBase(std::move(tx))
{
// Verify transaction type
if (tx_->getTxnType() != txType)
{
throw std::runtime_error("Invalid transaction type for ContractClawback");
}
}
// Transaction-specific field getters
/**
* @brief Get sfContractAccount (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
getContractAccount() const
{
if (hasContractAccount())
{
return this->tx_->at(sfContractAccount);
}
return std::nullopt;
}
/**
* @brief Check if sfContractAccount is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasContractAccount() const
{
return this->tx_->isFieldPresent(sfContractAccount);
}
/**
* @brief Get sfAmount (SoeRequired)
* @note This field supports MPT (Multi-Purpose Token) amounts.
* @return The field value.
*/
[[nodiscard]]
SF_AMOUNT::type::value_type
getAmount() const
{
return this->tx_->at(sfAmount);
}
};
/**
* @brief Builder for ContractClawback transactions.
*
* Provides a fluent interface for constructing transactions with method chaining.
* Uses STObject internally for flexible transaction construction.
* Inherits common field setters from TransactionBuilderBase.
*/
class ContractClawbackBuilder : public TransactionBuilderBase<ContractClawbackBuilder>
{
public:
/**
* @brief Construct a new ContractClawbackBuilder with required fields.
* @param account The account initiating the transaction.
* @param amount The sfAmount field value.
* @param sequence Optional sequence number for the transaction.
* @param fee Optional fee for the transaction.
*/
ContractClawbackBuilder(SF_ACCOUNT::type::value_type account,
std::decay_t<typename SF_AMOUNT::type::value_type> const& amount, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
)
: TransactionBuilderBase<ContractClawbackBuilder>(ttCONTRACT_CLAWBACK, account, sequence, fee)
{
setAmount(amount);
}
/**
* @brief Construct a ContractClawbackBuilder from an existing STTx object.
* @param tx The existing transaction to copy from.
* @throws std::runtime_error if the transaction type doesn't match.
*/
ContractClawbackBuilder(std::shared_ptr<STTx const> tx)
{
if (tx->getTxnType() != ttCONTRACT_CLAWBACK)
{
throw std::runtime_error("Invalid transaction type for ContractClawbackBuilder");
}
object_ = *tx;
}
/**
* @brief Transaction-specific field setters
*/
/**
* @brief Set sfContractAccount (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractClawbackBuilder&
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
{
object_[sfContractAccount] = value;
return *this;
}
/**
* @brief Set sfAmount (SoeRequired)
* @note This field supports MPT (Multi-Purpose Token) amounts.
* @return Reference to this builder for method chaining.
*/
ContractClawbackBuilder&
setAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
{
object_[sfAmount] = value;
return *this;
}
/**
* @brief Build and return the ContractClawback wrapper.
* @param publicKey The public key for signing.
* @param secretKey The secret key for signing.
* @return The constructed transaction wrapper.
*/
ContractClawback
build(PublicKey const& publicKey, SecretKey const& secretKey)
{
sign(publicKey, secretKey);
return ContractClawback{std::make_shared<STTx>(std::move(object_))};
}
};
} // namespace xrpl::transactions

View File

@@ -1,323 +0,0 @@
// This file is auto-generated. Do not edit.
#pragma once
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/protocol_autogen/TransactionBase.h>
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
#include <xrpl/json/json_value.h>
#include <stdexcept>
#include <optional>
namespace xrpl::transactions {
class ContractCreateBuilder;
/**
* @brief Transaction: ContractCreate
*
* Type: ttCONTRACT_CREATE (92)
* Delegable: Delegation::Delegable
* Amendment: featureSmartContract
* Privileges: Privilege::CreatePseudoAcct
*
* Immutable wrapper around STTx providing type-safe field access.
* Use ContractCreateBuilder to construct new transactions.
*/
class ContractCreate : public TransactionBase
{
public:
static constexpr xrpl::TxType txType = ttCONTRACT_CREATE;
/**
* @brief Construct a ContractCreate transaction wrapper from an existing STTx object.
* @throws std::runtime_error if the transaction type doesn't match.
*/
explicit ContractCreate(std::shared_ptr<STTx const> tx)
: TransactionBase(std::move(tx))
{
// Verify transaction type
if (tx_->getTxnType() != txType)
{
throw std::runtime_error("Invalid transaction type for ContractCreate");
}
}
// Transaction-specific field getters
/**
* @brief Get sfContractCode (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getContractCode() const
{
if (hasContractCode())
{
return this->tx_->at(sfContractCode);
}
return std::nullopt;
}
/**
* @brief Check if sfContractCode is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasContractCode() const
{
return this->tx_->isFieldPresent(sfContractCode);
}
/**
* @brief Get sfContractHash (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT256::type::value_type>
getContractHash() const
{
if (hasContractHash())
{
return this->tx_->at(sfContractHash);
}
return std::nullopt;
}
/**
* @brief Check if sfContractHash is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasContractHash() const
{
return this->tx_->isFieldPresent(sfContractHash);
}
/**
* @brief Get sfFunctions (SoeOptional)
* @note This is an untyped field.
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
std::optional<std::reference_wrapper<STArray const>>
getFunctions() const
{
if (this->tx_->isFieldPresent(sfFunctions))
return this->tx_->getFieldArray(sfFunctions);
return std::nullopt;
}
/**
* @brief Check if sfFunctions is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasFunctions() const
{
return this->tx_->isFieldPresent(sfFunctions);
}
/**
* @brief Get sfInstanceParameters (SoeOptional)
* @note This is an untyped field.
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
std::optional<std::reference_wrapper<STArray const>>
getInstanceParameters() const
{
if (this->tx_->isFieldPresent(sfInstanceParameters))
return this->tx_->getFieldArray(sfInstanceParameters);
return std::nullopt;
}
/**
* @brief Check if sfInstanceParameters is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasInstanceParameters() const
{
return this->tx_->isFieldPresent(sfInstanceParameters);
}
/**
* @brief Get sfInstanceParameterValues (SoeOptional)
* @note This is an untyped field.
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
std::optional<std::reference_wrapper<STArray const>>
getInstanceParameterValues() const
{
if (this->tx_->isFieldPresent(sfInstanceParameterValues))
return this->tx_->getFieldArray(sfInstanceParameterValues);
return std::nullopt;
}
/**
* @brief Check if sfInstanceParameterValues is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasInstanceParameterValues() const
{
return this->tx_->isFieldPresent(sfInstanceParameterValues);
}
/**
* @brief Get sfURI (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getURI() const
{
if (hasURI())
{
return this->tx_->at(sfURI);
}
return std::nullopt;
}
/**
* @brief Check if sfURI is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasURI() const
{
return this->tx_->isFieldPresent(sfURI);
}
};
/**
* @brief Builder for ContractCreate transactions.
*
* Provides a fluent interface for constructing transactions with method chaining.
* Uses STObject internally for flexible transaction construction.
* Inherits common field setters from TransactionBuilderBase.
*/
class ContractCreateBuilder : public TransactionBuilderBase<ContractCreateBuilder>
{
public:
/**
* @brief Construct a new ContractCreateBuilder with required fields.
* @param account The account initiating the transaction.
* @param sequence Optional sequence number for the transaction.
* @param fee Optional fee for the transaction.
*/
ContractCreateBuilder(SF_ACCOUNT::type::value_type account,
std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
)
: TransactionBuilderBase<ContractCreateBuilder>(ttCONTRACT_CREATE, account, sequence, fee)
{
}
/**
* @brief Construct a ContractCreateBuilder from an existing STTx object.
* @param tx The existing transaction to copy from.
* @throws std::runtime_error if the transaction type doesn't match.
*/
ContractCreateBuilder(std::shared_ptr<STTx const> tx)
{
if (tx->getTxnType() != ttCONTRACT_CREATE)
{
throw std::runtime_error("Invalid transaction type for ContractCreateBuilder");
}
object_ = *tx;
}
/**
* @brief Transaction-specific field setters
*/
/**
* @brief Set sfContractCode (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractCreateBuilder&
setContractCode(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfContractCode] = value;
return *this;
}
/**
* @brief Set sfContractHash (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractCreateBuilder&
setContractHash(std::decay_t<typename SF_UINT256::type::value_type> const& value)
{
object_[sfContractHash] = value;
return *this;
}
/**
* @brief Set sfFunctions (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractCreateBuilder&
setFunctions(STArray const& value)
{
object_.setFieldArray(sfFunctions, value);
return *this;
}
/**
* @brief Set sfInstanceParameters (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractCreateBuilder&
setInstanceParameters(STArray const& value)
{
object_.setFieldArray(sfInstanceParameters, value);
return *this;
}
/**
* @brief Set sfInstanceParameterValues (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractCreateBuilder&
setInstanceParameterValues(STArray const& value)
{
object_.setFieldArray(sfInstanceParameterValues, value);
return *this;
}
/**
* @brief Set sfURI (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractCreateBuilder&
setURI(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfURI] = value;
return *this;
}
/**
* @brief Build and return the ContractCreate wrapper.
* @param publicKey The public key for signing.
* @param secretKey The secret key for signing.
* @return The constructed transaction wrapper.
*/
ContractCreate
build(PublicKey const& publicKey, SecretKey const& secretKey)
{
sign(publicKey, secretKey);
return ContractCreate{std::make_shared<STTx>(std::move(object_))};
}
};
} // namespace xrpl::transactions

View File

@@ -1,131 +0,0 @@
// This file is auto-generated. Do not edit.
#pragma once
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/protocol_autogen/TransactionBase.h>
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
#include <xrpl/json/json_value.h>
#include <stdexcept>
#include <optional>
namespace xrpl::transactions {
class ContractDeleteBuilder;
/**
* @brief Transaction: ContractDelete
*
* Type: ttCONTRACT_DELETE (94)
* Delegable: Delegation::Delegable
* Amendment: featureSmartContract
* Privileges: Privilege::MustDeleteAcct
*
* Immutable wrapper around STTx providing type-safe field access.
* Use ContractDeleteBuilder to construct new transactions.
*/
class ContractDelete : public TransactionBase
{
public:
static constexpr xrpl::TxType txType = ttCONTRACT_DELETE;
/**
* @brief Construct a ContractDelete transaction wrapper from an existing STTx object.
* @throws std::runtime_error if the transaction type doesn't match.
*/
explicit ContractDelete(std::shared_ptr<STTx const> tx)
: TransactionBase(std::move(tx))
{
// Verify transaction type
if (tx_->getTxnType() != txType)
{
throw std::runtime_error("Invalid transaction type for ContractDelete");
}
}
// Transaction-specific field getters
/**
* @brief Get sfContractAccount (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_ACCOUNT::type::value_type
getContractAccount() const
{
return this->tx_->at(sfContractAccount);
}
};
/**
* @brief Builder for ContractDelete transactions.
*
* Provides a fluent interface for constructing transactions with method chaining.
* Uses STObject internally for flexible transaction construction.
* Inherits common field setters from TransactionBuilderBase.
*/
class ContractDeleteBuilder : public TransactionBuilderBase<ContractDeleteBuilder>
{
public:
/**
* @brief Construct a new ContractDeleteBuilder with required fields.
* @param account The account initiating the transaction.
* @param contractAccount The sfContractAccount field value.
* @param sequence Optional sequence number for the transaction.
* @param fee Optional fee for the transaction.
*/
ContractDeleteBuilder(SF_ACCOUNT::type::value_type account,
std::decay_t<typename SF_ACCOUNT::type::value_type> const& contractAccount, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
)
: TransactionBuilderBase<ContractDeleteBuilder>(ttCONTRACT_DELETE, account, sequence, fee)
{
setContractAccount(contractAccount);
}
/**
* @brief Construct a ContractDeleteBuilder from an existing STTx object.
* @param tx The existing transaction to copy from.
* @throws std::runtime_error if the transaction type doesn't match.
*/
ContractDeleteBuilder(std::shared_ptr<STTx const> tx)
{
if (tx->getTxnType() != ttCONTRACT_DELETE)
{
throw std::runtime_error("Invalid transaction type for ContractDeleteBuilder");
}
object_ = *tx;
}
/**
* @brief Transaction-specific field setters
*/
/**
* @brief Set sfContractAccount (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractDeleteBuilder&
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
{
object_[sfContractAccount] = value;
return *this;
}
/**
* @brief Build and return the ContractDelete wrapper.
* @param publicKey The public key for signing.
* @param secretKey The secret key for signing.
* @return The constructed transaction wrapper.
*/
ContractDelete
build(PublicKey const& publicKey, SecretKey const& secretKey)
{
sign(publicKey, secretKey);
return ContractDelete{std::make_shared<STTx>(std::move(object_))};
}
};
} // namespace xrpl::transactions

View File

@@ -1,397 +0,0 @@
// This file is auto-generated. Do not edit.
#pragma once
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/protocol_autogen/TransactionBase.h>
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
#include <xrpl/json/json_value.h>
#include <stdexcept>
#include <optional>
namespace xrpl::transactions {
class ContractModifyBuilder;
/**
* @brief Transaction: ContractModify
*
* Type: ttCONTRACT_MODIFY (93)
* Delegable: Delegation::Delegable
* Amendment: featureSmartContract
* Privileges: Privilege::NoPriv
*
* Immutable wrapper around STTx providing type-safe field access.
* Use ContractModifyBuilder to construct new transactions.
*/
class ContractModify : public TransactionBase
{
public:
static constexpr xrpl::TxType txType = ttCONTRACT_MODIFY;
/**
* @brief Construct a ContractModify transaction wrapper from an existing STTx object.
* @throws std::runtime_error if the transaction type doesn't match.
*/
explicit ContractModify(std::shared_ptr<STTx const> tx)
: TransactionBase(std::move(tx))
{
// Verify transaction type
if (tx_->getTxnType() != txType)
{
throw std::runtime_error("Invalid transaction type for ContractModify");
}
}
// Transaction-specific field getters
/**
* @brief Get sfContractAccount (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
getContractAccount() const
{
if (hasContractAccount())
{
return this->tx_->at(sfContractAccount);
}
return std::nullopt;
}
/**
* @brief Check if sfContractAccount is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasContractAccount() const
{
return this->tx_->isFieldPresent(sfContractAccount);
}
/**
* @brief Get sfOwner (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
getOwner() const
{
if (hasOwner())
{
return this->tx_->at(sfOwner);
}
return std::nullopt;
}
/**
* @brief Check if sfOwner is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasOwner() const
{
return this->tx_->isFieldPresent(sfOwner);
}
/**
* @brief Get sfContractCode (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getContractCode() const
{
if (hasContractCode())
{
return this->tx_->at(sfContractCode);
}
return std::nullopt;
}
/**
* @brief Check if sfContractCode is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasContractCode() const
{
return this->tx_->isFieldPresent(sfContractCode);
}
/**
* @brief Get sfContractHash (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT256::type::value_type>
getContractHash() const
{
if (hasContractHash())
{
return this->tx_->at(sfContractHash);
}
return std::nullopt;
}
/**
* @brief Check if sfContractHash is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasContractHash() const
{
return this->tx_->isFieldPresent(sfContractHash);
}
/**
* @brief Get sfFunctions (SoeOptional)
* @note This is an untyped field.
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
std::optional<std::reference_wrapper<STArray const>>
getFunctions() const
{
if (this->tx_->isFieldPresent(sfFunctions))
return this->tx_->getFieldArray(sfFunctions);
return std::nullopt;
}
/**
* @brief Check if sfFunctions is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasFunctions() const
{
return this->tx_->isFieldPresent(sfFunctions);
}
/**
* @brief Get sfInstanceParameters (SoeOptional)
* @note This is an untyped field.
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
std::optional<std::reference_wrapper<STArray const>>
getInstanceParameters() const
{
if (this->tx_->isFieldPresent(sfInstanceParameters))
return this->tx_->getFieldArray(sfInstanceParameters);
return std::nullopt;
}
/**
* @brief Check if sfInstanceParameters is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasInstanceParameters() const
{
return this->tx_->isFieldPresent(sfInstanceParameters);
}
/**
* @brief Get sfInstanceParameterValues (SoeOptional)
* @note This is an untyped field.
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
std::optional<std::reference_wrapper<STArray const>>
getInstanceParameterValues() const
{
if (this->tx_->isFieldPresent(sfInstanceParameterValues))
return this->tx_->getFieldArray(sfInstanceParameterValues);
return std::nullopt;
}
/**
* @brief Check if sfInstanceParameterValues is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasInstanceParameterValues() const
{
return this->tx_->isFieldPresent(sfInstanceParameterValues);
}
/**
* @brief Get sfURI (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getURI() const
{
if (hasURI())
{
return this->tx_->at(sfURI);
}
return std::nullopt;
}
/**
* @brief Check if sfURI is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasURI() const
{
return this->tx_->isFieldPresent(sfURI);
}
};
/**
* @brief Builder for ContractModify transactions.
*
* Provides a fluent interface for constructing transactions with method chaining.
* Uses STObject internally for flexible transaction construction.
* Inherits common field setters from TransactionBuilderBase.
*/
class ContractModifyBuilder : public TransactionBuilderBase<ContractModifyBuilder>
{
public:
/**
* @brief Construct a new ContractModifyBuilder with required fields.
* @param account The account initiating the transaction.
* @param sequence Optional sequence number for the transaction.
* @param fee Optional fee for the transaction.
*/
ContractModifyBuilder(SF_ACCOUNT::type::value_type account,
std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
)
: TransactionBuilderBase<ContractModifyBuilder>(ttCONTRACT_MODIFY, account, sequence, fee)
{
}
/**
* @brief Construct a ContractModifyBuilder from an existing STTx object.
* @param tx The existing transaction to copy from.
* @throws std::runtime_error if the transaction type doesn't match.
*/
ContractModifyBuilder(std::shared_ptr<STTx const> tx)
{
if (tx->getTxnType() != ttCONTRACT_MODIFY)
{
throw std::runtime_error("Invalid transaction type for ContractModifyBuilder");
}
object_ = *tx;
}
/**
* @brief Transaction-specific field setters
*/
/**
* @brief Set sfContractAccount (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractModifyBuilder&
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
{
object_[sfContractAccount] = value;
return *this;
}
/**
* @brief Set sfOwner (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractModifyBuilder&
setOwner(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
{
object_[sfOwner] = value;
return *this;
}
/**
* @brief Set sfContractCode (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractModifyBuilder&
setContractCode(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfContractCode] = value;
return *this;
}
/**
* @brief Set sfContractHash (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractModifyBuilder&
setContractHash(std::decay_t<typename SF_UINT256::type::value_type> const& value)
{
object_[sfContractHash] = value;
return *this;
}
/**
* @brief Set sfFunctions (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractModifyBuilder&
setFunctions(STArray const& value)
{
object_.setFieldArray(sfFunctions, value);
return *this;
}
/**
* @brief Set sfInstanceParameters (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractModifyBuilder&
setInstanceParameters(STArray const& value)
{
object_.setFieldArray(sfInstanceParameters, value);
return *this;
}
/**
* @brief Set sfInstanceParameterValues (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractModifyBuilder&
setInstanceParameterValues(STArray const& value)
{
object_.setFieldArray(sfInstanceParameterValues, value);
return *this;
}
/**
* @brief Set sfURI (SoeOptional)
* @return Reference to this builder for method chaining.
*/
ContractModifyBuilder&
setURI(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfURI] = value;
return *this;
}
/**
* @brief Build and return the ContractModify wrapper.
* @param publicKey The public key for signing.
* @param secretKey The secret key for signing.
* @return The constructed transaction wrapper.
*/
ContractModify
build(PublicKey const& publicKey, SecretKey const& secretKey)
{
sign(publicKey, secretKey);
return ContractModify{std::make_shared<STTx>(std::move(object_))};
}
};
} // namespace xrpl::transactions

View File

@@ -1,155 +0,0 @@
// This file is auto-generated. Do not edit.
#pragma once
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/protocol_autogen/TransactionBase.h>
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
#include <xrpl/json/json_value.h>
#include <stdexcept>
#include <optional>
namespace xrpl::transactions {
class ContractUserDeleteBuilder;
/**
* @brief Transaction: ContractUserDelete
*
* Type: ttCONTRACT_USER_DELETE (96)
* Delegable: Delegation::Delegable
* Amendment: featureSmartContract
* Privileges: Privilege::NoPriv
*
* Immutable wrapper around STTx providing type-safe field access.
* Use ContractUserDeleteBuilder to construct new transactions.
*/
class ContractUserDelete : public TransactionBase
{
public:
static constexpr xrpl::TxType txType = ttCONTRACT_USER_DELETE;
/**
* @brief Construct a ContractUserDelete transaction wrapper from an existing STTx object.
* @throws std::runtime_error if the transaction type doesn't match.
*/
explicit ContractUserDelete(std::shared_ptr<STTx const> tx)
: TransactionBase(std::move(tx))
{
// Verify transaction type
if (tx_->getTxnType() != txType)
{
throw std::runtime_error("Invalid transaction type for ContractUserDelete");
}
}
// Transaction-specific field getters
/**
* @brief Get sfContractAccount (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_ACCOUNT::type::value_type
getContractAccount() const
{
return this->tx_->at(sfContractAccount);
}
/**
* @brief Get sfGas (SoeRequired)
* @return The field value.
*/
[[nodiscard]]
SF_UINT32::type::value_type
getGas() const
{
return this->tx_->at(sfGas);
}
};
/**
* @brief Builder for ContractUserDelete transactions.
*
* Provides a fluent interface for constructing transactions with method chaining.
* Uses STObject internally for flexible transaction construction.
* Inherits common field setters from TransactionBuilderBase.
*/
class ContractUserDeleteBuilder : public TransactionBuilderBase<ContractUserDeleteBuilder>
{
public:
/**
* @brief Construct a new ContractUserDeleteBuilder with required fields.
* @param account The account initiating the transaction.
* @param contractAccount The sfContractAccount field value.
* @param gas The sfGas field value.
* @param sequence Optional sequence number for the transaction.
* @param fee Optional fee for the transaction.
*/
ContractUserDeleteBuilder(SF_ACCOUNT::type::value_type account,
std::decay_t<typename SF_ACCOUNT::type::value_type> const& contractAccount, std::decay_t<typename SF_UINT32::type::value_type> const& gas, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
)
: TransactionBuilderBase<ContractUserDeleteBuilder>(ttCONTRACT_USER_DELETE, account, sequence, fee)
{
setContractAccount(contractAccount);
setGas(gas);
}
/**
* @brief Construct a ContractUserDeleteBuilder from an existing STTx object.
* @param tx The existing transaction to copy from.
* @throws std::runtime_error if the transaction type doesn't match.
*/
ContractUserDeleteBuilder(std::shared_ptr<STTx const> tx)
{
if (tx->getTxnType() != ttCONTRACT_USER_DELETE)
{
throw std::runtime_error("Invalid transaction type for ContractUserDeleteBuilder");
}
object_ = *tx;
}
/**
* @brief Transaction-specific field setters
*/
/**
* @brief Set sfContractAccount (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractUserDeleteBuilder&
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
{
object_[sfContractAccount] = value;
return *this;
}
/**
* @brief Set sfGas (SoeRequired)
* @return Reference to this builder for method chaining.
*/
ContractUserDeleteBuilder&
setGas(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGas] = value;
return *this;
}
/**
* @brief Build and return the ContractUserDelete wrapper.
* @param publicKey The public key for signing.
* @param secretKey The secret key for signing.
* @return The constructed transaction wrapper.
*/
ContractUserDelete
build(PublicKey const& publicKey, SecretKey const& secretKey)
{
sign(publicKey, secretKey);
return ContractUserDelete{std::make_shared<STTx>(std::move(object_))};
}
};
} // namespace xrpl::transactions

View File

@@ -58,32 +58,6 @@ public:
return this->tx_->at(sfDestination);
}
/**
* @brief Get sfDestinationTag (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getDestinationTag() const
{
if (hasDestinationTag())
{
return this->tx_->at(sfDestinationTag);
}
return std::nullopt;
}
/**
* @brief Check if sfDestinationTag is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasDestinationTag() const
{
return this->tx_->isFieldPresent(sfDestinationTag);
}
/**
* @brief Get sfAmount (SoeRequired)
* @note This field supports MPT (Multi-Purpose Token) amounts.
@@ -175,55 +149,29 @@ public:
}
/**
* @brief Get sfBytecode (SoeOptional)
* @brief Get sfDestinationTag (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getBytecode() const
protocol_autogen::Optional<SF_UINT32::type::value_type>
getDestinationTag() const
{
if (hasBytecode())
if (hasDestinationTag())
{
return this->tx_->at(sfBytecode);
return this->tx_->at(sfDestinationTag);
}
return std::nullopt;
}
/**
* @brief Check if sfBytecode is present.
* @brief Check if sfDestinationTag is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasBytecode() const
hasDestinationTag() const
{
return this->tx_->isFieldPresent(sfBytecode);
}
/**
* @brief Get sfData (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getData() const
{
if (hasData())
{
return this->tx_->at(sfData);
}
return std::nullopt;
}
/**
* @brief Check if sfData is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasData() const
{
return this->tx_->isFieldPresent(sfData);
return this->tx_->isFieldPresent(sfDestinationTag);
}
};
@@ -284,17 +232,6 @@ public:
return *this;
}
/**
* @brief Set sfDestinationTag (SoeOptional)
* @return Reference to this builder for method chaining.
*/
EscrowCreateBuilder&
setDestinationTag(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfDestinationTag] = value;
return *this;
}
/**
* @brief Set sfAmount (SoeRequired)
* @note This field supports MPT (Multi-Purpose Token) amounts.
@@ -341,24 +278,13 @@ public:
}
/**
* @brief Set sfBytecode (SoeOptional)
* @brief Set sfDestinationTag (SoeOptional)
* @return Reference to this builder for method chaining.
*/
EscrowCreateBuilder&
setBytecode(std::decay_t<typename SF_VL::type::value_type> const& value)
setDestinationTag(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfBytecode] = value;
return *this;
}
/**
* @brief Set sfData (SoeOptional)
* @return Reference to this builder for method chaining.
*/
EscrowCreateBuilder&
setData(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfData] = value;
object_[sfDestinationTag] = value;
return *this;
}

View File

@@ -146,32 +146,6 @@ public:
{
return this->tx_->isFieldPresent(sfCredentialIDs);
}
/**
* @brief Get sfGas (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getGas() const
{
if (hasGas())
{
return this->tx_->at(sfGas);
}
return std::nullopt;
}
/**
* @brief Check if sfGas is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasGas() const
{
return this->tx_->isFieldPresent(sfGas);
}
};
/**
@@ -275,17 +249,6 @@ public:
return *this;
}
/**
* @brief Set sfGas (SoeOptional)
* @return Reference to this builder for method chaining.
*/
EscrowFinishBuilder&
setGas(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGas] = value;
return *this;
}
/**
* @brief Build and return the EscrowFinish wrapper.
* @param publicKey The public key for signing.

View File

@@ -254,84 +254,6 @@ public:
{
return this->tx_->isFieldPresent(sfReserveIncrementDrops);
}
/**
* @brief Get sfGasLimit (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getGasLimit() const
{
if (hasGasLimit())
{
return this->tx_->at(sfGasLimit);
}
return std::nullopt;
}
/**
* @brief Check if sfGasLimit is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasGasLimit() const
{
return this->tx_->isFieldPresent(sfGasLimit);
}
/**
* @brief Get sfBytecodeSizeLimit (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getBytecodeSizeLimit() const
{
if (hasBytecodeSizeLimit())
{
return this->tx_->at(sfBytecodeSizeLimit);
}
return std::nullopt;
}
/**
* @brief Check if sfBytecodeSizeLimit is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasBytecodeSizeLimit() const
{
return this->tx_->isFieldPresent(sfBytecodeSizeLimit);
}
/**
* @brief Get sfGasPrice (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getGasPrice() const
{
if (hasGasPrice())
{
return this->tx_->at(sfGasPrice);
}
return std::nullopt;
}
/**
* @brief Check if sfGasPrice is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasGasPrice() const
{
return this->tx_->isFieldPresent(sfGasPrice);
}
};
/**
@@ -464,39 +386,6 @@ public:
return *this;
}
/**
* @brief Set sfGasLimit (SoeOptional)
* @return Reference to this builder for method chaining.
*/
SetFeeBuilder&
setGasLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGasLimit] = value;
return *this;
}
/**
* @brief Set sfBytecodeSizeLimit (SoeOptional)
* @return Reference to this builder for method chaining.
*/
SetFeeBuilder&
setBytecodeSizeLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfBytecodeSizeLimit] = value;
return *this;
}
/**
* @brief Set sfGasPrice (SoeOptional)
* @return Reference to this builder for method chaining.
*/
SetFeeBuilder&
setGasPrice(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGasPrice] = value;
return *this;
}
/**
* @brief Build and return the SetFee wrapper.
* @param publicKey The public key for signing.

View File

@@ -270,11 +270,6 @@ public:
virtual bool
unsubConsensus(std::uint64_t uListener) = 0;
virtual bool
subContractEvent(ref ispListener) = 0;
virtual bool
unsubContractEvent(std::uint64_t uListener) = 0;
// VFALCO TODO Remove
// This was added for one particular partner, it
// "pushes" subscription data to a particular URL.

View File

@@ -259,9 +259,6 @@ public:
virtual void
pubValidation(std::shared_ptr<STValidation> const& val) = 0;
virtual void
pubContractEvent(std::string const& name, STJson const& event) = 0;
virtual void
stateAccounting(json::Value& obj) = 0;

View File

@@ -7,8 +7,8 @@
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ApplyViewImpl.h>
#include <xrpl/ledger/OpenView.h>
#include <xrpl/ledger/OpenViewSandbox.h>
#include <xrpl/ledger/RawView.h>
#include <xrpl/protocol/Book.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
@@ -16,11 +16,8 @@
#include <xrpl/protocol/XRPAmount.h>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <optional>
#include <queue>
#include <utility>
namespace xrpl {
@@ -63,12 +60,6 @@ public:
XRPAmount const baseFee;
beast::Journal const journal;
OpenView&
openView()
{
return base_.view();
}
ApplyView&
view()
{
@@ -104,51 +95,12 @@ public:
view_->deliver(amount);
}
/**
* Sets the gas used in the metadata
*/
void
setGasUsed(std::uint32_t const gasUsed)
{
gasUsed_ = gasUsed;
}
/**
* Sets the gas used in the metadata
*/
void
setVMReturnCode(std::int32_t const vmReturnCode)
{
vmReturnCode_ = vmReturnCode;
}
/**
* Sets the transactions emitted by this transaction
*/
void
setEmittedTxns(std::queue<std::shared_ptr<STTx const>> const emittedTxns)
{
emittedTxns_ = emittedTxns;
}
std::queue<std::shared_ptr<STTx const>>
getEmittedTxns()
{
return emittedTxns_;
}
/**
* Discard changes and start fresh.
*/
void
discard();
/**
* Finalize changes.
*/
void
finalize();
/**
* Apply the transaction result to the base.
*/
@@ -178,6 +130,14 @@ public:
view_->rawDestroyXRP(fee);
}
/**
* Registers a newly-created order book directory with the shared,
* process-wide OrderBookDB, unless this transaction is being applied
* under TapDryRun.
*/
void
addOrderBook(Book const& book);
ApplyViewContext
getApplyViewContext()
{
@@ -188,15 +148,12 @@ public:
}
private:
OpenViewSandbox base_;
OpenView& base_;
ApplyFlags flags_;
std::optional<ApplyViewImpl> view_;
// The ID of the batch transaction we are executing under, if set.
std::optional<uint256 const> parentBatchId_;
std::optional<std::uint32_t> gasUsed_;
std::optional<std::int32_t> vmReturnCode_;
std::queue<std::shared_ptr<STTx const>> emittedTxns_;
};
} // namespace xrpl

View File

@@ -13,8 +13,6 @@
namespace xrpl {
class Application;
class HashRouter;
class ServiceRegistry;
@@ -118,22 +116,6 @@ apply(
ApplyFlags flags,
beast::Journal journal);
/**
* Apply a transaction that is part of a batch.
*
* @param parentBatchId The ID of the enclosing `Batch` transaction.
*
* @see apply
*/
ApplyResult
apply(
ServiceRegistry& registry,
OpenView& view,
uint256 const& parentBatchId,
STTx const& tx,
ApplyFlags flags,
beast::Journal j);
/**
* Enum class for return value from `applyTransaction`
*

View File

@@ -12,6 +12,7 @@
#include <xrpl/protocol/XRPAmount.h>
#include <cstdint>
#include <expected>
#include <optional>
#include <utility>
@@ -393,16 +394,21 @@ preclaim(PreflightResult const& preflightResult, ServiceRegistry& registry, Open
*
* No validation is done or implied by this function.
*
* Caller is responsible for handling any exceptions.
* Since none should be thrown, that will usually
* mean terminating.
*
* Callers do not expect this function to throw; exceptions from a transactor's
* `calculateBaseFee` are caught and reported as an error instead.
* @param view The current open ledger.
* @param tx The transaction to be checked.
*
* @return The base fee.
* @return The base fee on success. Returns `std::unexpected(temUNKNOWN)` if the transaction
* type is not recognized, and `std::unexpected(tefEXCEPTION)` if the transactor's
* `calculateBaseFee` threw.
*
* @note Failure is reported as an error rather than a fee of zero because a
* zero (or default) fee would pass checkFee and let the transaction be
* applied for less than it owes. Callers that only need a fee hint may fall
* back to a default; callers deciding whether to apply should reject.
*/
XRPAmount
[[nodiscard]] std::expected<XRPAmount, TER>
calculateBaseFee(ReadView const& view, STTx const& tx);
/**

View File

@@ -38,9 +38,11 @@ namespace xrpl {
* f. A Loan must reference a live `ltLOAN_BROKER`, and that broker must
* reference a live `ltVAULT`.
* g. Post-conditions for the Loan paid down by a successful `ttLOAN_PAY`:
* `PaymentRemaining > 0` after: `PrincipalOutstanding` and
* `PaymentRemaining` strictly decrease; `NextPaymentDueDate`
* advances by N * `PaymentInterval`, N > 0.
* `PaymentRemaining > 0` after: neither `PrincipalOutstanding` nor
* `TotalValueOutstanding` increases, and at least one of them
* strictly decreases;
* `PaymentRemaining` strictly decreases;
* `NextPaymentDueDate` advances by N * `PaymentInterval`, N > 0.
* `PaymentRemaining == 0` after: pinned by checks 1 and 5b.
*
*/

View File

@@ -1,42 +0,0 @@
#pragma once
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/tx/ApplyContext.h>
#include <xrpl/tx/Transactor.h>
namespace xrpl {
// Define a function pointer type that can be used to delete ledger node types.
using DeleterFuncPtr = TER (*)(
ServiceRegistry& registry,
ApplyView& view,
AccountID const& account,
uint256 const& delIndex,
std::shared_ptr<SLE> const& sleDel,
beast::Journal j);
DeleterFuncPtr
nonObligationDeleter(LedgerEntryType t);
TER
deletePreclaim(
PreclaimContext const& ctx,
std::uint32_t seqDelta,
AccountID const account,
AccountID const dest,
bool isPseudoAccount = false);
TER
deleteDoApply(
ApplyContext& applyCtx,
STAmount const& accountBalance,
AccountID const& account,
AccountID const& dest);
} // namespace xrpl

View File

@@ -1,40 +0,0 @@
#pragma once
#include <xrpl/tx/Transactor.h>
namespace xrpl {
class ContractCall : public Transactor
{
public:
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;
explicit ContractCall(ApplyContext& ctx) : Transactor(ctx)
{
}
static XRPAmount
calculateBaseFee(ReadView const& view, STTx const& tx);
static NotTEC
preflight(PreflightContext const& ctx);
static TER
preclaim(PreclaimContext const& ctx);
TER
doApply() override;
void
visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override;
[[nodiscard]] bool
finalizeInvariants(
STTx const& tx,
TER result,
XRPAmount fee,
ReadView const& view,
beast::Journal const& j) override;
};
} // namespace xrpl

View File

@@ -1,37 +0,0 @@
#pragma once
#include <xrpl/tx/Transactor.h>
namespace xrpl {
class ContractClawback : public Transactor
{
public:
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;
explicit ContractClawback(ApplyContext& ctx) : Transactor(ctx)
{
}
static NotTEC
preflight(PreflightContext const& ctx);
static TER
preclaim(PreclaimContext const& ctx);
TER
doApply() override;
void
visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override;
[[nodiscard]] bool
finalizeInvariants(
STTx const& tx,
TER result,
XRPAmount fee,
ReadView const& view,
beast::Journal const& j) override;
};
} // namespace xrpl

View File

@@ -1,43 +0,0 @@
#pragma once
#include <xrpl/tx/Transactor.h>
namespace xrpl {
class ContractCreate : public Transactor
{
public:
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;
explicit ContractCreate(ApplyContext& ctx) : Transactor(ctx)
{
}
static XRPAmount
calculateBaseFee(ReadView const& view, STTx const& tx);
static std::uint32_t
getFlagsMask(PreflightContext const& ctx);
static NotTEC
preflight(PreflightContext const& ctx);
static TER
preclaim(PreclaimContext const& ctx);
TER
doApply() override;
void
visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override;
[[nodiscard]] bool
finalizeInvariants(
STTx const& tx,
TER result,
XRPAmount fee,
ReadView const& view,
beast::Journal const& j) override;
};
} // namespace xrpl

View File

@@ -1,45 +0,0 @@
#pragma once
#include <xrpl/tx/Transactor.h>
namespace xrpl {
class ContractDelete : public Transactor
{
public:
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;
explicit ContractDelete(ApplyContext& ctx) : Transactor(ctx)
{
}
static NotTEC
preflight(PreflightContext const& ctx);
static TER
preclaim(PreclaimContext const& ctx);
// Interface used by DeleteAccount
static TER
deleteContract(
ApplyView& view,
std::shared_ptr<SLE> const& sle,
AccountID const& account,
beast::Journal j);
TER
doApply() override;
void
visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override;
[[nodiscard]] bool
finalizeInvariants(
STTx const& tx,
TER result,
XRPAmount fee,
ReadView const& view,
beast::Journal const& j) override;
};
} // namespace xrpl

View File

@@ -1,40 +0,0 @@
#pragma once
#include <xrpl/tx/Transactor.h>
namespace xrpl {
class ContractModify : public Transactor
{
public:
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;
explicit ContractModify(ApplyContext& ctx) : Transactor(ctx)
{
}
static XRPAmount
calculateBaseFee(ReadView const& view, STTx const& tx);
static NotTEC
preflight(PreflightContext const& ctx);
static TER
preclaim(PreclaimContext const& ctx);
TER
doApply() override;
void
visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override;
[[nodiscard]] bool
finalizeInvariants(
STTx const& tx,
TER result,
XRPAmount fee,
ReadView const& view,
beast::Journal const& j) override;
};
} // namespace xrpl

View File

@@ -1,37 +0,0 @@
#pragma once
#include <xrpl/tx/Transactor.h>
namespace xrpl {
class ContractUserDelete : public Transactor
{
public:
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;
explicit ContractUserDelete(ApplyContext& ctx) : Transactor(ctx)
{
}
static NotTEC
preflight(PreflightContext const& ctx);
static TER
preclaim(PreclaimContext const& ctx);
TER
doApply() override;
void
visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override;
[[nodiscard]] bool
finalizeInvariants(
STTx const& tx,
TER result,
XRPAmount fee,
ReadView const& view,
beast::Journal const& j) override;
};
} // namespace xrpl

View File

@@ -20,21 +20,15 @@ public:
{
}
static bool
checkExtraFeatures(PreflightContext const& ctx);
static TxConsequences
makeTxConsequences(PreflightContext const& ctx);
static XRPAmount
calculateBaseFee(ReadView const& view, STTx const& tx);
static bool
checkExtraFeatures(PreflightContext const& ctx);
static NotTEC
preflight(PreflightContext const& ctx);
static NotTEC
preflightSigValidated(PreflightContext const& ctx);
static TER
preclaim(PreclaimContext const& ctx);

View File

@@ -26,6 +26,9 @@ private:
TER
bridgeOffers(SLE::ref buy, SLE::ref sell);
TER
transferNFToken(AccountID const& buyer, AccountID const& seller, uint256 const& nfTokenID);
public:
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;

View File

@@ -4,7 +4,6 @@
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/helpers/NFTokenHelpers.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>

View File

@@ -1,100 +0,0 @@
#pragma once
#include <xrpl/ledger/OpenView.h>
#include <xrpl/ledger/helpers/ContractUtils.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/STData.h>
#include <xrpl/protocol/STDataType.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/tx/ApplyContext.h>
#include <queue>
namespace xrpl {
struct ParameterValueVec
{
STData const value;
};
struct FunctionParameterValueVecWithName
{
Blob const name;
STData const value;
};
struct ParameterTypeVec
{
STDataType const type;
};
std::vector<ParameterValueVec>
getParameterValueVec(STArray const& functionParameters);
std::vector<ParameterTypeVec>
getParameterTypeVec(STArray const& functionParameters);
enum ExitType : uint8_t {
UNSET = 0,
WASM_ERROR = 1,
ROLLBACK = 2,
ACCEPT = 3,
};
struct ContractResult
{
uint256 const contractHash; // Hash of the contract code
Keylet const contractKeylet; // Keylet for the contract instance
Keylet const contractSourceKeylet; // Keylet for the contract source
Keylet const contractAccountKeylet; // Keylet for the contract account
AccountID const contractAccount; // AccountID of the contract account
std::uint32_t nextSequence; // Next sequence number for the contract account
AccountID const otxnAccount; // AccountID for the originating transaction
uint256 const otxnId; // ID for the originating transaction
std::string exitReason{""};
int64_t exitCode{-1};
ContractDataMap dataMap;
ContractEventMap eventMap;
std::queue<std::shared_ptr<STTx const>> emittedTxns{};
std::size_t changedDataCount{0};
};
struct ContractContext
{
ApplyContext& applyCtx;
std::vector<ParameterValueVec> instanceParameters;
std::vector<ParameterValueVec> functionParameters;
std::vector<STObject> built_txns;
int64_t expected_etxn_count{-1}; // expected emitted transaction count
std::map<uint256, bool> nonce_used{}; // nonces used in this execution
uint32_t generation = 0; // generation of the contract being executed
uint64_t burden = 0; // computational burden used
ContractResult result;
/**
* Persistent view used to track cumulative state from emitted
* transactions so that successive emits within the same WASM
* execution see the correct sequence numbers, balances, etc.
*/
std::optional<OpenView> emitView;
/**
* Return the emit view, lazily creating it on first use.
*
* The view is layered on top of the transactor's ApplyViewImpl
* (applyCtx.view()) so that reads automatically fall through to
* the transactor's pending state (e.g. the tfSendAmount balance
* transfer, consumed sequence number, paid fee) without needing
* to manually copy SLE changes.
*/
OpenView&
getEmitView()
{
if (!emitView)
emitView.emplace(static_cast<ReadView const*>(&applyCtx.view()));
return *emitView;
}
};
} // namespace xrpl

View File

@@ -1,95 +0,0 @@
#pragma once
#include <xrpl/tx/wasm/ContractContext.h>
#include <xrpl/tx/wasm/HostFunc.h>
#include <xrpl/tx/wasm/HostFuncImpl.h>
namespace xrpl {
class ContractHostFunctionsImpl : public WasmHostFunctionsImpl
{
ContractContext& contractCtx;
uint256 const contractId = contractCtx.result.contractKeylet.key;
public:
// Constructor for contract-specific functionality
ContractHostFunctionsImpl(ContractContext& contractContext)
: WasmHostFunctionsImpl(contractContext.applyCtx, contractContext.result.contractKeylet)
, contractCtx(contractContext)
{
}
// std::expected<Bytes, HostFunctionError>
// getFieldBytesFromSTData(xrpl::STData const& funcParam, std::uint32_t
// stTypeId);
std::expected<Bytes, HostFunctionError>
instanceParam(std::uint32_t index, std::uint32_t stTypeId) override;
std::expected<Bytes, HostFunctionError>
functionParam(std::uint32_t index, std::uint32_t stTypeId) override;
std::expected<Bytes, HostFunctionError>
getDataObjectField(AccountID const& account, std::string_view const& key) override;
std::expected<Bytes, HostFunctionError>
getDataNestedObjectField(
AccountID const& account,
std::string_view const& key,
std::string_view const& nestedKey) override;
std::expected<Bytes, HostFunctionError>
getDataArrayElementField(AccountID const& account, size_t index, std::string_view const& key)
override;
std::expected<Bytes, HostFunctionError>
getDataNestedArrayElementField(
AccountID const& account,
std::string_view const& key,
size_t index,
std::string_view const& nestedKey) override;
std::expected<int32_t, HostFunctionError>
setDataObjectField(
AccountID const& account,
std::string_view const& key,
STJson::Value const& value) override;
std::expected<int32_t, HostFunctionError>
setDataNestedObjectField(
AccountID const& account,
std::string_view const& nestedKey,
std::string_view const& key,
STJson::Value const& value) override;
std::expected<int32_t, HostFunctionError>
setDataArrayElementField(
AccountID const& account,
size_t index,
std::string_view const& key,
STJson::Value const& value) override;
std::expected<int32_t, HostFunctionError>
setDataNestedArrayElementField(
AccountID const& account,
std::string_view const& key,
size_t index,
std::string_view const& nestedKey,
STJson::Value const& value) override;
std::expected<int32_t, HostFunctionError>
buildTxn(std::uint16_t const& txType) override;
std::expected<int32_t, HostFunctionError>
addTxnField(std::uint32_t const& index, SField const& field, Slice const& data) override;
std::expected<int32_t, HostFunctionError>
emitBuiltTxn(std::uint32_t const& index) override;
std::expected<int32_t, HostFunctionError>
emitTxn(std::shared_ptr<STTx const> const& stxPtr) override;
std::expected<int32_t, HostFunctionError>
emitEvent(std::string_view const& eventName, STJson const& eventData) override;
};
} // namespace xrpl

View File

@@ -1,617 +0,0 @@
#pragma once
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STJson.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/tx/wasm/WasmCommon.h>
#include <cstdint>
#include <expected>
#include <functional>
#include <optional>
#include <stdexcept>
#include <string>
#include <string_view>
namespace xrpl {
namespace wasm_float {
std::string
floatToString(Slice const& data);
std::expected<Bytes, HostFunctionError>
floatFromIntImpl(int64_t x, int32_t mode);
std::expected<Bytes, HostFunctionError>
floatFromUintImpl(uint64_t x, int32_t mode);
std::expected<Bytes, HostFunctionError>
floatFromSTAmountImpl(STAmount const& x, int32_t mode);
std::expected<Bytes, HostFunctionError>
floatFromSTNumberImpl(STNumber const& x, int32_t mode);
std::expected<int64_t, HostFunctionError>
floatToIntImpl(Slice const& x, int32_t mode);
std::expected<FloatPair, HostFunctionError>
floatToMantExpImpl(Slice const& x);
std::expected<Bytes, HostFunctionError>
floatFromMantExpImpl(int64_t mantissa, int32_t exponent, int32_t mode);
std::expected<int32_t, HostFunctionError>
floatCompareImpl(Slice const& x, Slice const& y);
std::expected<Bytes, HostFunctionError>
floatAddImpl(Slice const& x, Slice const& y, int32_t mode);
std::expected<Bytes, HostFunctionError>
floatSubtractImpl(Slice const& x, Slice const& y, int32_t mode);
std::expected<Bytes, HostFunctionError>
floatMultiplyImpl(Slice const& x, Slice const& y, int32_t mode);
std::expected<Bytes, HostFunctionError>
floatDivideImpl(Slice const& x, Slice const& y, int32_t mode);
std::expected<Bytes, HostFunctionError>
floatRootImpl(Slice const& x, int32_t n, int32_t mode);
std::expected<Bytes, HostFunctionError>
floatPowerImpl(Slice const& x, int32_t n, int32_t mode);
} // namespace wasm_float
// Intended to work only through wasm runtime. Don't call them directly, except with unit tests
class HostFunctions
{
protected:
RTOptRef rt_;
beast::Journal j_;
public:
HostFunctions(beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) : j_(j)
{
}
void
setRT(WasmRuntimeWrapper& rt)
{
rt_ = rt;
}
void
resetRT()
{
rt_ = std::nullopt;
}
[[nodiscard]] WasmRuntimeWrapper&
getRT() const
{
if (!rt_)
Throw<std::logic_error>("Wasm runtime not set");
return rt_->get();
}
[[nodiscard]] beast::Journal
getJournal() const
{
return j_;
}
// LCOV_EXCL_START
[[nodiscard]] virtual bool
checkSelf() const
{
return true;
}
[[nodiscard]] virtual std::expected<std::uint32_t, HostFunctionError>
getLedgerSqn() const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<std::uint32_t, HostFunctionError>
getParentLedgerTime() const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Hash, HostFunctionError>
getParentLedgerHash() const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<uint32_t, HostFunctionError>
getBaseFee() const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
isAmendmentEnabled(uint256 const& amendmentId) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
isAmendmentEnabled(std::string_view const& amendmentName) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
cacheLedgerObj(uint256 const& objId, int32_t cacheIdx)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
getTxField(SField const& fname) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
getCurrentLedgerObjField(SField const& fname) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
getLedgerObjField(int32_t cacheIdx, SField const& fname) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
getTxNestedField(FieldLocator const& locator) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
getCurrentLedgerObjNestedField(FieldLocator const& locator) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
getLedgerObjNestedField(int32_t cacheIdx, FieldLocator const& locator) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
getTxArrayLen(SField const& fname) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
getCurrentLedgerObjArrayLen(SField const& fname) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
getTxNestedArrayLen(FieldLocator const& locator) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
getCurrentLedgerObjNestedArrayLen(FieldLocator const& locator) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
getLedgerObjNestedArrayLen(int32_t cacheIdx, FieldLocator const& locator) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
updateData(Slice const& data)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Hash, HostFunctionError>
computeSha512HalfHash(Slice const& data) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
accountKeylet(AccountID const& account) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
ammKeylet(Asset const& issue1, Asset const& issue2) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
checkKeylet(AccountID const& account, std::uint32_t seq) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType)
const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
didKeylet(AccountID const& account) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
delegateKeylet(AccountID const& account, AccountID const& authorize) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
escrowKeylet(AccountID const& account, std::uint32_t seq) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
trustLineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency)
const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
mptokenIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
mptokenKeylet(MPTID const& mptid, AccountID const& holder) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
nftokenOfferKeylet(AccountID const& account, std::uint32_t seq) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
offerKeylet(AccountID const& account, std::uint32_t seq) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
oracleKeylet(AccountID const& account, std::uint32_t docId) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
paychannelKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq)
const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
signerListKeylet(AccountID const& account) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
ticketKeylet(AccountID const& account, std::uint32_t seq) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
vaultKeylet(AccountID const& account, std::uint32_t seq) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
getNFT(AccountID const& account, uint256 const& nftId) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
getNFTIssuer(uint256 const& nftId) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<std::uint32_t, HostFunctionError>
getNFTTaxon(uint256 const& nftId) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
getNFTFlags(uint256 const& nftId) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
getNFTTransferFee(uint256 const& nftId) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<std::uint32_t, HostFunctionError>
getNFTSequence(uint256 const& nftId) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
// A no-op rather than Unimplemented: trace only writes to the local log.
// trace_wrap has already rendered the guest's buffer into `data`.
virtual void
trace(std::string_view const& msg, std::string_view const& data) const
{
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatFromInt(int64_t x, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatFromUint(uint64_t x, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatFromSTAmount(STAmount const& x, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatFromSTNumber(STNumber const& x, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int64_t, HostFunctionError>
floatToInt(Slice const& x, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<FloatPair, HostFunctionError>
floatToMantExp(Slice const& x) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatFromMantExp(int64_t mantissa, int32_t exponent, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<int32_t, HostFunctionError>
floatCompare(Slice const& x, Slice const& y) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatAdd(Slice const& x, Slice const& y, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatSubtract(Slice const& x, Slice const& y, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatMultiply(Slice const& x, Slice const& y, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatDivide(Slice const& x, Slice const& y, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatRoot(Slice const& x, int32_t n, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
[[nodiscard]] virtual std::expected<Bytes, HostFunctionError>
floatPower(Slice const& x, int32_t n, int32_t mode) const
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<Bytes, HostFunctionError>
instanceParam(std::uint32_t index, std::uint32_t stTypeId)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<Bytes, HostFunctionError>
functionParam(std::uint32_t index, std::uint32_t stTypeId)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<Bytes, HostFunctionError>
getDataObjectField(AccountID const& account, std::string_view const& key)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<Bytes, HostFunctionError>
getDataNestedObjectField(
AccountID const& account,
std::string_view const& key,
std::string_view const& nestedKey)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<Bytes, HostFunctionError>
getDataArrayElementField(AccountID const& account, size_t index, std::string_view const& key)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<Bytes, HostFunctionError>
getDataNestedArrayElementField(
AccountID const& account,
std::string_view const& key,
size_t index,
std::string_view const& nestedKey)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
setDataObjectField(
AccountID const& account,
std::string_view const& keyName,
STJson::Value const& value)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
setDataNestedObjectField(
AccountID const& account,
std::string_view const& nestedKey,
std::string_view const& key,
STJson::Value const& value)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
setDataArrayElementField(
AccountID const& account,
size_t index,
std::string_view const& key,
STJson::Value const& value)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
setDataNestedArrayElementField(
AccountID const& account,
std::string_view const& key,
size_t index,
std::string_view const& nestedKey,
STJson::Value const& value)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
buildTxn(std::uint16_t const& txType)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
addTxnField(std::uint32_t const& index, SField const& field, Slice const& data)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
emitBuiltTxn(std::uint32_t const& index)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
emitTxn(std::shared_ptr<STTx const> const& stxPtr)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual std::expected<int32_t, HostFunctionError>
emitEvent(std::string_view const& eventName, STJson const& eventData)
{
return std::unexpected(HostFunctionError::Unimplemented);
}
virtual ~HostFunctions() = default;
// LCOV_EXCL_STOP
};
using HFRef = std::reference_wrapper<HostFunctions>;
} // namespace xrpl

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