mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-22 19:47:17 +00:00
Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
097cb5e89b | ||
|
|
a818f25203 | ||
|
|
3fa2accfdf | ||
|
|
d3a71b2b42 | ||
|
|
025aa71930 | ||
|
|
ef5064eeb9 | ||
|
|
c2e739f670 | ||
|
|
15fac6250d | ||
|
|
3608433514 | ||
|
|
7939339a65 | ||
|
|
4ea2db2eda | ||
|
|
d4ffe32534 | ||
|
|
7354816f65 | ||
|
|
12cb3932f3 | ||
|
|
dc64a8daac |
No files matched your search
+1
-2
@@ -198,6 +198,7 @@ words:
|
||||
- mptokens
|
||||
- mpts
|
||||
- mtgox
|
||||
- mudhra
|
||||
- multisig
|
||||
- multisign
|
||||
- multisigned
|
||||
@@ -318,7 +319,6 @@ words:
|
||||
- sttx
|
||||
- stvar
|
||||
- stvector
|
||||
- stxchainattestations
|
||||
- summands
|
||||
- superpeer
|
||||
- superpeers
|
||||
@@ -377,7 +377,6 @@ words:
|
||||
- writeme
|
||||
- wsrch
|
||||
- wthread
|
||||
- xbridge
|
||||
- xchain
|
||||
- xcrun
|
||||
- ximinez
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"image_tag": "sha-3d526d4",
|
||||
"image_tag": "sha-d3a71b2",
|
||||
"configs": {
|
||||
"ubuntu": [
|
||||
{
|
||||
@@ -74,7 +74,7 @@
|
||||
"extra_cmake_args": "-Dvalidator_keys=ON",
|
||||
"package": {
|
||||
"type": "deb",
|
||||
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-e6055dd"
|
||||
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-d3a71b2"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -86,7 +86,7 @@
|
||||
"extra_cmake_args": "-Dvalidator_keys=ON -Dassert=ON",
|
||||
"package": {
|
||||
"type": "deb",
|
||||
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-e6055dd",
|
||||
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-d3a71b2",
|
||||
"variant": "assert"
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,7 @@
|
||||
"extra_cmake_args": "-Dvalidator_keys=ON",
|
||||
"package": {
|
||||
"type": "rpm",
|
||||
"image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-e6055dd"
|
||||
"image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-d3a71b2"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -24,6 +24,7 @@ on:
|
||||
- "!nix/devshell.nix"
|
||||
- "!nix/check-tools/**"
|
||||
- "bin/check-tools.sh"
|
||||
- "bin/check-distrusted-roots.sh"
|
||||
- "bin/nix/default-loader-path.sh"
|
||||
- "bin/install/sanitizer-libs.sh"
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -10,6 +10,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/build-packaging-images.yml"
|
||||
- "bin/check-distrusted-roots.sh"
|
||||
- "bin/install/packaging-tools.sh"
|
||||
- "package/images/packaging/**"
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -10,6 +10,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/build-pre-commit-image.yml"
|
||||
- "bin/check-distrusted-roots.sh"
|
||||
- "bin/pre-commit/Dockerfile"
|
||||
- "rust-toolchain.toml"
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -8,6 +8,7 @@ on:
|
||||
branches:
|
||||
- "develop"
|
||||
- "release/*"
|
||||
- "staging/*"
|
||||
paths:
|
||||
- "crates/**/Cargo.toml"
|
||||
- "crates/Cargo.lock"
|
||||
@@ -34,7 +35,7 @@ permissions:
|
||||
jobs:
|
||||
audit:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||
permissions:
|
||||
contents: read
|
||||
# Needed to open an issue on scheduled failures.
|
||||
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ jobs:
|
||||
- should-run
|
||||
- build-test
|
||||
# Only run when committing to a PR that targets a release branch.
|
||||
if: ${{ github.repository == 'XRPLF/rippled' && needs.should-run.outputs.go == 'true' && github.event_name == 'pull_request' && startsWith(github.event.pull_request.base.ref, 'release') }}
|
||||
if: ${{ github.repository == 'XRPLF/rippled' && needs.should-run.outputs.go == 'true' && github.event_name == 'pull_request' && startsWith(github.event.pull_request.base.ref, 'release/') }}
|
||||
uses: ./.github/workflows/reusable-upload-recipe.yml
|
||||
secrets:
|
||||
remote_username: ${{ secrets.NEXUS_REMOTE_USERNAME }}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
# This workflow runs all workflows to build and test the code on various Linux
|
||||
# flavors, as well as on MacOS and Windows, on a scheduled basis, on merge into
|
||||
# the 'develop' or 'release*' branches, or when requested manually. Upon pushes
|
||||
# to the develop branch it also uploads the libxrpl recipe to the Conan remote.
|
||||
# the 'develop', 'release/*' or 'staging/*' branches, or when requested
|
||||
# manually. Upon pushes to the develop branch, it also uploads the libxrpl
|
||||
# recipe to the Conan remote.
|
||||
name: Trigger
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "develop"
|
||||
- "release*"
|
||||
- "release/*"
|
||||
- "staging/*"
|
||||
paths:
|
||||
# These paths are unique to `on-trigger.yml`.
|
||||
- ".github/workflows/on-trigger.yml"
|
||||
@@ -62,9 +64,9 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
# When a PR is merged into the develop branch it will be assigned a unique
|
||||
# When a PR is merged into the develop branch, it will be assigned a unique
|
||||
# group identifier, so execution will continue even if another PR is merged
|
||||
# while it is still running. In all other cases the group identifier is shared
|
||||
# while it is still running. In all other cases, the group identifier is shared
|
||||
# per branch, so that any in-progress runs are cancelled when a new commit is
|
||||
# pushed.
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' && github.sha || github.ref }}
|
||||
@@ -98,7 +100,7 @@ jobs:
|
||||
# However, we do not enable ccache for events targeting a release branch,
|
||||
# to protect against the rare case that the output produced by ccache is
|
||||
# not identical to a regular compilation.
|
||||
ccache_enabled: ${{ github.repository_owner == 'XRPLF' && !startsWith(github.ref, 'refs/heads/release') }}
|
||||
ccache_enabled: ${{ github.repository_owner == 'XRPLF' && !startsWith(github.ref, 'refs/heads/release/') }}
|
||||
os: ${{ matrix.os }}
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@@ -8,13 +8,14 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- "develop"
|
||||
- "release*"
|
||||
- "release/*"
|
||||
- "staging/*"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
|
||||
run-hooks:
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@d7f2acb47d9662e1e2f8b1f5feffa6d21cc3290a
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@6a52459a658649a0aeaab4ebd6a8f25173f6f16f
|
||||
with:
|
||||
runs_on: ubuntu-latest
|
||||
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-70b8fd3" }'
|
||||
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-d3a71b2" }'
|
||||
@@ -41,13 +41,13 @@ env:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||
with:
|
||||
enable_ccache: ${{ inputs.ccache_enabled }}
|
||||
|
||||
|
||||
@@ -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-3d526d4"
|
||||
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-d3a71b2"
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
@@ -225,7 +225,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ permissions:
|
||||
jobs:
|
||||
clippy:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
|
||||
coverage:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
|
||||
doc:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
@@ -40,7 +40,7 @@ defaults:
|
||||
jobs:
|
||||
upload:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3d526d4
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-d3a71b2
|
||||
env:
|
||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||
CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.remote_username }}
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@8e98d61f011fd2a67f3fde5f0f075662c099a527
|
||||
uses: XRPLF/actions/prepare-runner@6645b8721d3810be1c59f4180315249e59bf1312
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@ This version is supported by all `xrpld` versions. For WebSocket and HTTP JSON-R
|
||||
|
||||
Version 3.5.0 is not yet released.
|
||||
|
||||
### Breaking changes in 3.5.0
|
||||
|
||||
- The `XChainBridge` amendment and its ledger entries and transactions are removed. `XChainBridge` and `fixXChainRewardRounding` are now obsolete and can no longer be voted for; neither was ever enabled on Mainnet. `ledger_entry` no longer accepts `bridge`, `xchain_owned_claim_id`, or `xchain_owned_create_account_claim_id`; `account_objects` no longer accepts those values in `type`; and `server_definitions` no longer lists the removed ledger entry types, transaction types, fields, and the `XChainBridge` serialized type.
|
||||
- `subscribe` (`ledger` stream): The deprecated `fee_ref` field has been removed unconditionally from both the `subscribe` response and the `ledgerClosed` stream messages. It was previously only omitted when the `XRPFees` amendment was enabled; that amendment has now been retired, so the field is never returned. This applies to all API versions.
|
||||
|
||||
### Additions in 3.5.0
|
||||
|
||||
- `subscribe`, `unsubscribe`: Added an optional `mpt_issuances` request field, an array of MPT issuance IDs (hex strings). Subscribers receive the same `transaction` message as the `transactions` stream for each validated transaction whose metadata affects a subscribed issuance. MPT issuance subscriptions count toward the per-connection subscription limit. An empty array, a non-array value, or an invalid ID returns `invalidParams`. ([#5671](https://github.com/XRPLF/rippled/pull/5671))
|
||||
@@ -38,6 +43,8 @@ Version 3.5.0 is not yet released.
|
||||
- `account_currencies`, `account_nfts`, `account_offers`: A request with more than one problem may now report a different one of them. An invalid `ledger_hash` or `ledger_index` is reported before an invalid or missing `account`. An invalid `limit` or `marker` is reported before `lgrNotFound` or `actNotFound`, and for `account_offers` also before `actMalformed`. A request with a single problem returns the same error as before. [#8561](https://github.com/XRPLF/rippled/pull/8561)
|
||||
- `deposit_authorized`: A `credentials` entry that is all zeros (for example `"0"` or 64 `0` characters) now returns a `badCredentials` error instead of looking up a credential that can never exist.
|
||||
- `account_info`, `account_lines`, `account_channels`: A request with more than one problem may now report a different one of them. An invalid `ledger_hash` or `ledger_index` is reported before a missing or invalid `account`, or `ident` for `account_info`. For `account_lines`, a `peer` that is not a string, or an invalid `limit` or `marker`, is reported before `lgrNotFound`, `actNotFound` or a malformed `account`, and an invalid `limit` or `marker` also before a malformed `peer`. For `account_channels`, a malformed `account` is reported before `lgrNotFound`, and an invalid `destination_account`, `limit` or `marker` before `lgrNotFound` or `actNotFound`. A request with a single problem returns the same error as before. [#8573](https://github.com/XRPLF/rippled/pull/8573)
|
||||
- `deposit_authorized`, `nft_buy_offers`, `nft_sell_offers`: A request with more than one problem may now report a different one of them. An invalid `ledger_hash` or `ledger_index` is reported before a missing or invalid `source_account`, `destination_account` or `nft_id`, and for `nft_buy_offers` / `nft_sell_offers` also before an invalid `limit`. For `deposit_authorized`, an invalid `credentials` array is reported before `lgrNotFound`, `srcActNotFound`, `dstActNotFound` or `badCredentials`. For `nft_buy_offers` and `nft_sell_offers`, an invalid `marker` is reported before `lgrNotFound` or `objectNotFound`. A request with a single problem returns the same error as before. [#8613](https://github.com/XRPLF/rippled/pull/8613)
|
||||
- `nft_buy_offers`, `nft_sell_offers`: An `nft_id` that is an array or an object now returns an `invalidParams` error instead of an `internal` error. [#8613](https://github.com/XRPLF/rippled/pull/8613)
|
||||
|
||||
### Bugfixes in 3.5.0
|
||||
|
||||
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# check-distrusted-roots.sh — fail if a CA bundle trusts a root of the
|
||||
# compromised eMudhra intermediates; see https://emudhra.we-have-a-problem.com/.
|
||||
#
|
||||
# Usage: check-distrusted-roots.sh [ca-bundle]
|
||||
# Defaults to the system bundle (Debian or RHEL path).
|
||||
#
|
||||
# Roots are matched by SHA-256 fingerprint, needing only bash, base64 and
|
||||
# sha256sum (nixos/nix has no awk). Only plain CERTIFICATE blocks are checked:
|
||||
# OpenSSL's TRUSTED CERTIFICATE blocks carry their own trust settings, which is
|
||||
# how nixpkgs' cacert marks a blacklisted root as rejected.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
declare -A ROOTS=(
|
||||
[d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4]="AAA Certificate Services"
|
||||
[86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b]="emSign ECC Root CA - G3"
|
||||
)
|
||||
|
||||
BUNDLE="${1:-}"
|
||||
if [ -z "${BUNDLE}" ]; then
|
||||
for CANDIDATE in /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt; do
|
||||
if [ -f "${CANDIDATE}" ]; then
|
||||
BUNDLE="${CANDIDATE}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
STATUS=0
|
||||
COUNT=0
|
||||
PEM=""
|
||||
while IFS= read -r LINE || [ -n "${LINE}" ]; do
|
||||
case "${LINE}" in
|
||||
"-----BEGIN CERTIFICATE-----") PEM="" ;;
|
||||
"-----END CERTIFICATE-----")
|
||||
COUNT=$((COUNT + 1))
|
||||
FINGERPRINT="$(base64 -d <<<"${PEM}" | sha256sum)" || {
|
||||
echo "ERROR: certificate ${COUNT} in ${BUNDLE} is not valid base64" >&2
|
||||
exit 1
|
||||
}
|
||||
ROOT="${ROOTS[${FINGERPRINT%% *}]:-}"
|
||||
if [ -n "${ROOT}" ]; then
|
||||
echo "ERROR: ${BUNDLE} trusts '${ROOT}'" >&2
|
||||
STATUS=1
|
||||
fi
|
||||
;;
|
||||
# Lines outside a CERTIFICATE block only collect until the next BEGIN.
|
||||
*) PEM+="${LINE}" ;;
|
||||
esac
|
||||
done <"${BUNDLE:?no system CA bundle found}"
|
||||
|
||||
# An empty or unparsable bundle would otherwise pass.
|
||||
if [ "${COUNT}" -eq 0 ]; then
|
||||
echo "ERROR: ${BUNDLE} has no certificates" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "${BUNDLE}: checked ${COUNT} certificates"
|
||||
exit "${STATUS}"
|
||||
@@ -58,6 +58,14 @@ function install() {
|
||||
rpm-build \
|
||||
rpm-sign \
|
||||
systemd-rpm-macros
|
||||
|
||||
# AlmaLinux's ca-certificates still trusts the root of the compromised
|
||||
# eMudhra intermediates; see https://emudhra.we-have-a-problem.com/.
|
||||
# TODO: drop once it ships a fix.
|
||||
trust extract --format=pem-bundle \
|
||||
--filter="pkcs11:object=emSign%20ECC%20Root%20CA%20-%20G3;type=cert" \
|
||||
/etc/pki/ca-trust/source/blocklist/emSign_ECC_Root_CA_-_G3.pem
|
||||
update-ca-trust
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
+25
-10
@@ -9,13 +9,14 @@ ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN <<EOF
|
||||
pkgs=()
|
||||
pkgs+=(curl) # Required to install nix.
|
||||
pkgs+=(doxygen) # Needed for Clio's check-doxygen-docs.sh.
|
||||
pkgs+=(git) # Required for prepare-runner.
|
||||
pkgs+=(libatomic1) # Required to run pre-commit provided `node`.
|
||||
pkgs+=(python3) # Python 3 interpreter.
|
||||
pkgs+=(python3-pip) # Package manager for Python applications.
|
||||
pkgs+=(xz-utils) # Required to install nix
|
||||
pkgs+=(ca-certificates) # Trust store for curl, git, pip and nix.
|
||||
pkgs+=(curl) # Required to install nix.
|
||||
pkgs+=(doxygen) # Needed for Clio's check-doxygen-docs.sh.
|
||||
pkgs+=(git) # Required for prepare-runner.
|
||||
pkgs+=(libatomic1) # Required to run pre-commit provided `node`.
|
||||
pkgs+=(python3) # Python 3 interpreter.
|
||||
pkgs+=(python3-venv) # Virtual environment for Python applications.
|
||||
pkgs+=(xz-utils) # Required to install nix
|
||||
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends "${pkgs[@]}"
|
||||
@@ -23,9 +24,21 @@ apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
EOF
|
||||
|
||||
# Sanity-check that the system CA bundle distrusts the compromised eMudhra roots,
|
||||
# before pip and the nix installer download anything with it.
|
||||
RUN --mount=type=bind,source=bin/check-distrusted-roots.sh,target=/check-distrusted-roots.sh \
|
||||
/check-distrusted-roots.sh
|
||||
|
||||
# Ahead of the system Python on PATH,
|
||||
# so `python3` and `pip` resolve to the venv and installs stay out of the system Python.
|
||||
ENV VIRTUAL_ENV="/opt/venv"
|
||||
ENV PATH="${VIRTUAL_ENV}/bin:${PATH}"
|
||||
|
||||
ARG PRE_COMMIT_VERSION=4.6.2
|
||||
RUN pip install --no-cache --break-system-packages \
|
||||
pre-commit==${PRE_COMMIT_VERSION}
|
||||
RUN <<EOF
|
||||
python3 -m venv "${VIRTUAL_ENV}"
|
||||
pip install --no-cache pre-commit==${PRE_COMMIT_VERSION}
|
||||
EOF
|
||||
|
||||
RUN sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon --yes
|
||||
|
||||
@@ -33,7 +46,9 @@ RUN sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --dae
|
||||
# so nix is available in all shells including non-interactive shells (e.g., GitHub Actions).
|
||||
ENV PATH="/nix/var/nix/profiles/default/bin:${PATH}"
|
||||
ENV NIX_PROFILES="/nix/var/nix/profiles/default"
|
||||
ENV NIX_SSL_CERT_FILE="/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
||||
# The system bundle gets security updates through apt;
|
||||
# the one in the Nix profile is frozen at the installer's nixpkgs.
|
||||
ENV NIX_SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt"
|
||||
|
||||
# Verify nix installation
|
||||
RUN nix --version
|
||||
|
||||
@@ -304,7 +304,9 @@ if(xrpld)
|
||||
account_nfts
|
||||
account_offers
|
||||
book_changes
|
||||
deposit_authorized
|
||||
ledger
|
||||
nft_offers_common
|
||||
transaction_entry
|
||||
)
|
||||
target_sources(xrpld PRIVATE ${rpcspec_instantiations})
|
||||
|
||||
+2
-2
@@ -3,11 +3,11 @@
|
||||
"requires": [
|
||||
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708",
|
||||
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1782392402.420688",
|
||||
"xrpl-rpc-spec/0.1.25#2daa763e2d86ccc4ad0a0fa4d1983e9f%1791907455.579992",
|
||||
"xrpl-rpc-spec/0.1.29#852afc87cac32aca93cc50a985d73fe0%1792359643.19817",
|
||||
"sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1782392403.185447",
|
||||
"soci/4.0.3#e726491a03468795453f7c83fc924a96%1782392402.679521",
|
||||
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1782307151.633168",
|
||||
"secp256k1/0.7.1#b1f450b7f78a36fff75bb6934a356f3a%1782338841.3729",
|
||||
"secp256k1/0.7.1#f4d16a4d907dd057598954476ca6f88c%1792234329.790275",
|
||||
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1782392413.075713",
|
||||
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1782392402.431897",
|
||||
"protobuf/6.33.5#ff253ead763bd8d9904a52979cd21e81%1782392410.233933",
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ class Xrpl(ConanFile):
|
||||
"nudb/2.0.9",
|
||||
"openssl/3.6.3",
|
||||
"soci/4.0.3",
|
||||
"xrpl-rpc-spec/0.1.25",
|
||||
"xrpl-rpc-spec/0.1.29",
|
||||
"zlib/1.3.2",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/SLEBase.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <typename ViewT>
|
||||
class BridgeEntry : public SLEBase<ViewT, ltBRIDGE>
|
||||
{
|
||||
public:
|
||||
using Base = SLEBase<ViewT, ltBRIDGE>;
|
||||
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using Base::Base;
|
||||
|
||||
explicit BridgeEntry(
|
||||
STXChainBridge const& bridge,
|
||||
STXChainBridge::ChainType chainType,
|
||||
Base::ViewRefType view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: Base(keylet::bridge(bridge, chainType), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using BridgeEntryR = BridgeEntry<ReadView>;
|
||||
using BridgeEntryW = BridgeEntry<ApplyView>;
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,38 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/SLEBase.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <typename ViewT>
|
||||
class XChainOwnedClaimIDEntry : public SLEBase<ViewT, ltXCHAIN_OWNED_CLAIM_ID>
|
||||
{
|
||||
public:
|
||||
using Base = SLEBase<ViewT, ltXCHAIN_OWNED_CLAIM_ID>;
|
||||
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using Base::Base;
|
||||
|
||||
explicit XChainOwnedClaimIDEntry(
|
||||
STXChainBridge const& bridge,
|
||||
std::uint64_t seq,
|
||||
Base::ViewRefType view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: Base(keylet::xChainClaimID(bridge, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using XChainOwnedClaimIDEntryR = XChainOwnedClaimIDEntry<ReadView>;
|
||||
using XChainOwnedClaimIDEntryW = XChainOwnedClaimIDEntry<ApplyView>;
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/SLEBase.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <typename ViewT>
|
||||
class XChainOwnedCreateAccountClaimIDEntry
|
||||
: public SLEBase<ViewT, ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID>
|
||||
{
|
||||
public:
|
||||
using Base = SLEBase<ViewT, ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID>;
|
||||
|
||||
// Inherit base constructors: adopt an existing SLE, or resolve one from a
|
||||
// Keylet against the view.
|
||||
using Base::Base;
|
||||
|
||||
explicit XChainOwnedCreateAccountClaimIDEntry(
|
||||
STXChainBridge const& bridge,
|
||||
std::uint64_t seq,
|
||||
Base::ViewRefType view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: Base(keylet::xChainCreateAccountClaimID(bridge, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using XChainOwnedCreateAccountClaimIDEntryR = XChainOwnedCreateAccountClaimIDEntry<ReadView>;
|
||||
using XChainOwnedCreateAccountClaimIDEntryW = XChainOwnedCreateAccountClaimIDEntry<ApplyView>;
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -142,11 +142,11 @@ deleteProposal(ApplyView& view, SLE::pointer const& sleProposal, beast::Journal
|
||||
* off-ledger signatures it carries, and any change to a non-signature field
|
||||
* results in a false-return value.
|
||||
*
|
||||
* Signature (PaymentChannelClaim and the XChain attestation transactions)
|
||||
* is deliberately not compared: it is outside the account's own TxnSignature
|
||||
* even for an ordinary submission, so a proposal cannot bind it more tightly
|
||||
* than the signatures it collects do, and those transactors still validate a
|
||||
* substituted value exactly as they would for an ordinary submission.
|
||||
* Signature (PaymentChannelClaim) is deliberately not compared: it is
|
||||
* outside the account's own TxnSignature even for an ordinary submission, so
|
||||
* a proposal cannot bind it more tightly than the signatures it collects do,
|
||||
* and that transactor still validates a substituted value exactly as it would
|
||||
* for an ordinary submission.
|
||||
* MasterSignature appears in no transaction format.
|
||||
*
|
||||
* @param proposedTx The proposal's ProposedTransaction field.
|
||||
|
||||
@@ -74,12 +74,6 @@ invalidAMMAssetPair(
|
||||
std::optional<std::uint8_t>
|
||||
ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot);
|
||||
|
||||
/**
|
||||
* Return true if required AMM amendment is enabled
|
||||
*/
|
||||
bool
|
||||
ammEnabled(Rules const&);
|
||||
|
||||
/**
|
||||
* Convert to the fee from the basis points
|
||||
* @param tfee trading fee in {0, 1000}
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Deprecated constant for backwards compatibility with pre-XRPFees amendment.
|
||||
// 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.
|
||||
inline constexpr std::uint32_t microDropsPerDrop{1'000'000};
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
@@ -321,17 +320,6 @@ amm(UInt256 const& amm) noexcept;
|
||||
Keylet
|
||||
delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept;
|
||||
|
||||
Keylet
|
||||
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType);
|
||||
|
||||
// `seq` is stored as `sfXChainClaimID` in the object
|
||||
Keylet
|
||||
xChainClaimID(STXChainBridge const& bridge, std::uint64_t const seq);
|
||||
|
||||
// `seq` is stored as `sfXChainAccountCreateCount` in the object
|
||||
Keylet
|
||||
xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t const seq);
|
||||
|
||||
Keylet
|
||||
did(AccountID const& account) noexcept;
|
||||
|
||||
|
||||
@@ -103,6 +103,32 @@ enum LedgerEntryType : std::uint16_t {
|
||||
*/
|
||||
ltGENERATOR_MAP [[deprecated("This object type is not supported and should not be used.")]] =
|
||||
0x0067,
|
||||
|
||||
/**
|
||||
* A deprecated type, removed with the XChainBridge amendment.
|
||||
*
|
||||
* @deprecated **This object type is not supported and should not be used.**
|
||||
* The XChainBridge amendment was never enabled on Mainnet.
|
||||
*/
|
||||
ltBRIDGE [[deprecated("This object type is not supported and should not be used.")]] = 0x0069,
|
||||
|
||||
/**
|
||||
* A deprecated type, removed with the XChainBridge amendment.
|
||||
*
|
||||
* @deprecated **This object type is not supported and should not be used.**
|
||||
* The XChainBridge amendment was never enabled on Mainnet.
|
||||
*/
|
||||
ltXCHAIN_OWNED_CLAIM_ID
|
||||
[[deprecated("This object type is not supported and should not be used.")]] = 0x0071,
|
||||
|
||||
/**
|
||||
* A deprecated type, removed with the XChainBridge amendment.
|
||||
*
|
||||
* @deprecated **This object type is not supported and should not be used.**
|
||||
* The XChainBridge amendment was never enabled on Mainnet.
|
||||
*/
|
||||
ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID
|
||||
[[deprecated("This object type is not supported and should not be used.")]] = 0x0074,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,7 +31,6 @@ class STBitString;
|
||||
template <class>
|
||||
class STInteger;
|
||||
class STNumber;
|
||||
class STXChainBridge;
|
||||
class STVector256;
|
||||
class STCurrency;
|
||||
|
||||
@@ -71,7 +70,7 @@ class STCurrency;
|
||||
STYPE(STI_UINT384, 22) \
|
||||
STYPE(STI_UINT512, 23) \
|
||||
STYPE(STI_ISSUE, 24) \
|
||||
STYPE(STI_XCHAIN_BRIDGE, 25) \
|
||||
/* 25 is reserved */ \
|
||||
STYPE(STI_CURRENCY, 26) \
|
||||
\
|
||||
/* high-level types */ \
|
||||
@@ -361,7 +360,6 @@ using SF_CURRENCY = TypedField<STCurrency>;
|
||||
using SF_NUMBER = TypedField<STNumber>;
|
||||
using SF_VL = TypedField<STBlob>;
|
||||
using SF_VECTOR256 = TypedField<STVector256>;
|
||||
using SF_XCHAIN_BRIDGE = TypedField<STXChainBridge>;
|
||||
// NOLINTEND(readability-identifier-naming)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/SOTemplate.h>
|
||||
#include <xrpl/protocol/STAccount.h> // IWYU pragma: keep
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/STBitString.h>
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAccount.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/STIssue.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class Serializer;
|
||||
class STObject;
|
||||
|
||||
class STXChainBridge final : public STBase, public CountedObject<STXChainBridge>
|
||||
{
|
||||
STAccount lockingChainDoor_{sfLockingChainDoor};
|
||||
STIssue lockingChainIssue_{sfLockingChainIssue};
|
||||
STAccount issuingChainDoor_{sfIssuingChainDoor};
|
||||
STIssue issuingChainIssue_{sfIssuingChainIssue};
|
||||
|
||||
public:
|
||||
using value_type = STXChainBridge;
|
||||
|
||||
enum class ChainType { Locking, Issuing };
|
||||
|
||||
static ChainType
|
||||
otherChain(ChainType ct);
|
||||
|
||||
static ChainType
|
||||
srcChain(bool wasLockingChainSend);
|
||||
|
||||
static ChainType
|
||||
dstChain(bool wasLockingChainSend);
|
||||
|
||||
STXChainBridge();
|
||||
|
||||
explicit STXChainBridge(SField const& name);
|
||||
|
||||
STXChainBridge(STXChainBridge const& rhs) = default;
|
||||
|
||||
STXChainBridge(STObject const& o);
|
||||
|
||||
STXChainBridge(
|
||||
AccountID const& srcChainDoor,
|
||||
Issue const& srcChainIssue,
|
||||
AccountID const& dstChainDoor,
|
||||
Issue const& dstChainIssue);
|
||||
|
||||
explicit STXChainBridge(json::Value const& v);
|
||||
|
||||
explicit STXChainBridge(SField const& name, json::Value const& v);
|
||||
|
||||
explicit STXChainBridge(SerialIter& sit, SField const& name);
|
||||
|
||||
STXChainBridge&
|
||||
operator=(STXChainBridge const& rhs) = default;
|
||||
|
||||
[[nodiscard]] std::string
|
||||
getText() const override;
|
||||
|
||||
[[nodiscard]] STObject
|
||||
toSTObject() const;
|
||||
|
||||
[[nodiscard]] AccountID const&
|
||||
lockingChainDoor() const;
|
||||
|
||||
[[nodiscard]] Issue const&
|
||||
lockingChainIssue() const;
|
||||
|
||||
[[nodiscard]] AccountID const&
|
||||
issuingChainDoor() const;
|
||||
|
||||
[[nodiscard]] Issue const&
|
||||
issuingChainIssue() const;
|
||||
|
||||
[[nodiscard]] AccountID const&
|
||||
door(ChainType ct) const;
|
||||
|
||||
[[nodiscard]] Issue const&
|
||||
issue(ChainType ct) const;
|
||||
|
||||
[[nodiscard]] SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
[[nodiscard]] json::Value getJson(JsonOptions) const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
isEquivalent(STBase const& t) const override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
isDefault() const override;
|
||||
|
||||
[[nodiscard]] value_type const&
|
||||
value() const noexcept;
|
||||
|
||||
private:
|
||||
static std::unique_ptr<STXChainBridge>
|
||||
construct(SerialIter&, SField const& name);
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend bool
|
||||
operator==(STXChainBridge const& lhs, STXChainBridge const& rhs);
|
||||
|
||||
friend bool
|
||||
operator<(STXChainBridge const& lhs, STXChainBridge const& rhs);
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(STXChainBridge const& lhs, STXChainBridge const& rhs)
|
||||
{
|
||||
return std::tie(
|
||||
lhs.lockingChainDoor_,
|
||||
lhs.lockingChainIssue_,
|
||||
lhs.issuingChainDoor_,
|
||||
lhs.issuingChainIssue_) ==
|
||||
std::tie(
|
||||
rhs.lockingChainDoor_,
|
||||
rhs.lockingChainIssue_,
|
||||
rhs.issuingChainDoor_,
|
||||
rhs.issuingChainIssue_);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(STXChainBridge const& lhs, STXChainBridge const& rhs)
|
||||
{
|
||||
return std::tie(
|
||||
lhs.lockingChainDoor_,
|
||||
lhs.lockingChainIssue_,
|
||||
lhs.issuingChainDoor_,
|
||||
lhs.issuingChainIssue_) <
|
||||
std::tie(
|
||||
rhs.lockingChainDoor_,
|
||||
rhs.lockingChainIssue_,
|
||||
rhs.issuingChainDoor_,
|
||||
rhs.issuingChainIssue_);
|
||||
}
|
||||
|
||||
inline AccountID const&
|
||||
STXChainBridge::lockingChainDoor() const
|
||||
{
|
||||
return lockingChainDoor_.value();
|
||||
};
|
||||
|
||||
inline Issue const&
|
||||
STXChainBridge::lockingChainIssue() const
|
||||
{
|
||||
return lockingChainIssue_.value().get<Issue>();
|
||||
};
|
||||
|
||||
inline AccountID const&
|
||||
STXChainBridge::issuingChainDoor() const
|
||||
{
|
||||
return issuingChainDoor_.value();
|
||||
};
|
||||
|
||||
inline Issue const&
|
||||
STXChainBridge::issuingChainIssue() const
|
||||
{
|
||||
return issuingChainIssue_.value().get<Issue>();
|
||||
};
|
||||
|
||||
inline STXChainBridge::value_type const&
|
||||
STXChainBridge::value() const noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline AccountID const&
|
||||
STXChainBridge::door(ChainType ct) const
|
||||
{
|
||||
if (ct == ChainType::Locking)
|
||||
return lockingChainDoor();
|
||||
return issuingChainDoor();
|
||||
}
|
||||
|
||||
inline Issue const&
|
||||
STXChainBridge::issue(ChainType ct) const
|
||||
{
|
||||
if (ct == ChainType::Locking)
|
||||
return lockingChainIssue();
|
||||
return issuingChainIssue();
|
||||
}
|
||||
|
||||
inline STXChainBridge::ChainType
|
||||
STXChainBridge::otherChain(ChainType ct)
|
||||
{
|
||||
if (ct == ChainType::Locking)
|
||||
return ChainType::Issuing;
|
||||
return ChainType::Locking;
|
||||
}
|
||||
|
||||
inline STXChainBridge::ChainType
|
||||
STXChainBridge::srcChain(bool wasLockingChainSend)
|
||||
{
|
||||
if (wasLockingChainSend)
|
||||
return ChainType::Locking;
|
||||
return ChainType::Issuing;
|
||||
}
|
||||
|
||||
inline STXChainBridge::ChainType
|
||||
STXChainBridge::dstChain(bool wasLockingChainSend)
|
||||
{
|
||||
if (wasLockingChainSend)
|
||||
return ChainType::Issuing;
|
||||
return ChainType::Locking;
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -189,10 +189,6 @@ inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
|
||||
TF_FLAG(tfClawTwoAssets, 0x00000001), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(XChainModifyBridge, \
|
||||
TF_FLAG(tfClearAccountCreateAmount, 0x00010000), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(VaultCreate, \
|
||||
TF_FLAG(tfVaultPrivate, lsfVaultPrivate) \
|
||||
TF_FLAG(tfVaultShareNonTransferable, 0x00020000), \
|
||||
|
||||
@@ -73,6 +73,54 @@ enum TxType : std::uint16_t
|
||||
* This transaction type installs a hook.
|
||||
*/
|
||||
TtHookSet [[maybe_unused]] = 22,
|
||||
|
||||
/**
|
||||
* This transaction type was removed with the XChainBridge amendment, which was never enabled
|
||||
* on Mainnet. The value is reserved for historical purposes.
|
||||
*/
|
||||
TtXChainCreateClaimID [[deprecated("This transaction type is not supported and should not be used.")]] = 41,
|
||||
|
||||
/**
|
||||
* This transaction type was removed with the XChainBridge amendment, which was never enabled
|
||||
* on Mainnet. The value is reserved for historical purposes.
|
||||
*/
|
||||
TtXChainCommit [[deprecated("This transaction type is not supported and should not be used.")]] = 42,
|
||||
|
||||
/**
|
||||
* This transaction type was removed with the XChainBridge amendment, which was never enabled
|
||||
* on Mainnet. The value is reserved for historical purposes.
|
||||
*/
|
||||
TtXChainClaim [[deprecated("This transaction type is not supported and should not be used.")]] = 43,
|
||||
|
||||
/**
|
||||
* This transaction type was removed with the XChainBridge amendment, which was never enabled
|
||||
* on Mainnet. The value is reserved for historical purposes.
|
||||
*/
|
||||
TtXChainAccountCreateCommit [[deprecated("This transaction type is not supported and should not be used.")]] = 44,
|
||||
|
||||
/**
|
||||
* This transaction type was removed with the XChainBridge amendment, which was never enabled
|
||||
* on Mainnet. The value is reserved for historical purposes.
|
||||
*/
|
||||
TtXChainAddClaimAttestation [[deprecated("This transaction type is not supported and should not be used.")]] = 45,
|
||||
|
||||
/**
|
||||
* This transaction type was removed with the XChainBridge amendment, which was never enabled
|
||||
* on Mainnet. The value is reserved for historical purposes.
|
||||
*/
|
||||
TtXChainAddAccountCreateAttestation [[deprecated("This transaction type is not supported and should not be used.")]] = 46,
|
||||
|
||||
/**
|
||||
* This transaction type was removed with the XChainBridge amendment, which was never enabled
|
||||
* on Mainnet. The value is reserved for historical purposes.
|
||||
*/
|
||||
TtXChainModifyBridge [[deprecated("This transaction type is not supported and should not be used.")]] = 47,
|
||||
|
||||
/**
|
||||
* This transaction type was removed with the XChainBridge amendment, which was never enabled
|
||||
* on Mainnet. The value is reserved for historical purposes.
|
||||
*/
|
||||
TtXChainCreateBridge [[deprecated("This transaction type is not supported and should not be used.")]] = 48,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -1,471 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Buffer.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
#include <xrpl/protocol/SecretKey.h>
|
||||
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
namespace attestations {
|
||||
|
||||
struct AttestationBase
|
||||
{
|
||||
// Account associated with the public key
|
||||
AccountID attestationSignerAccount;
|
||||
// Public key from the witness server attesting to the event
|
||||
PublicKey publicKey;
|
||||
// Signature from the witness server attesting to the event
|
||||
Buffer signature;
|
||||
// Account on the sending chain that triggered the event (sent the
|
||||
// transaction)
|
||||
AccountID sendingAccount;
|
||||
// Amount transferred on the sending chain
|
||||
STAmount sendingAmount;
|
||||
// Account on the destination chain that collects a share of the attestation
|
||||
// reward
|
||||
AccountID rewardAccount;
|
||||
// Amount was transferred on the locking chain
|
||||
bool wasLockingChainSend;
|
||||
|
||||
explicit AttestationBase(
|
||||
AccountID attestationSignerAccount,
|
||||
PublicKey const& publicKey,
|
||||
Buffer signature,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount sendingAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend);
|
||||
|
||||
AttestationBase(AttestationBase const&) = default;
|
||||
|
||||
virtual ~AttestationBase() = default;
|
||||
|
||||
AttestationBase&
|
||||
operator=(AttestationBase const&) = default;
|
||||
|
||||
// verify that the signature attests to the data.
|
||||
[[nodiscard]] bool
|
||||
verify(STXChainBridge const& bridge) const;
|
||||
|
||||
protected:
|
||||
explicit AttestationBase(STObject const& o);
|
||||
explicit AttestationBase(json::Value const& v);
|
||||
|
||||
[[nodiscard]] static bool
|
||||
equalHelper(AttestationBase const& lhs, AttestationBase const& rhs);
|
||||
|
||||
[[nodiscard]] static bool
|
||||
sameEventHelper(AttestationBase const& lhs, AttestationBase const& rhs);
|
||||
|
||||
void
|
||||
addHelper(STObject& o) const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] virtual std::vector<std::uint8_t>
|
||||
message(STXChainBridge const& bridge) const = 0;
|
||||
};
|
||||
|
||||
// Attest to a regular cross-chain transfer
|
||||
struct AttestationClaim : AttestationBase
|
||||
{
|
||||
std::uint64_t claimID;
|
||||
std::optional<AccountID> dst;
|
||||
|
||||
explicit AttestationClaim(
|
||||
AccountID attestationSignerAccount,
|
||||
PublicKey const& publicKey,
|
||||
Buffer signature,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t claimId,
|
||||
std::optional<AccountID> const& dst);
|
||||
|
||||
explicit AttestationClaim(
|
||||
STXChainBridge const& bridge,
|
||||
AccountID attestationSignerAccount,
|
||||
PublicKey const& publicKey,
|
||||
SecretKey const& secretKey,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t claimId,
|
||||
std::optional<AccountID> const& dst);
|
||||
|
||||
explicit AttestationClaim(STObject const& o);
|
||||
explicit AttestationClaim(json::Value const& v);
|
||||
|
||||
[[nodiscard]] STObject
|
||||
toSTObject() const;
|
||||
|
||||
// return true if the two attestations attest to the same thing
|
||||
[[nodiscard]] bool
|
||||
sameEvent(AttestationClaim const& rhs) const;
|
||||
|
||||
[[nodiscard]] static std::vector<std::uint8_t>
|
||||
message(
|
||||
STXChainBridge const& bridge,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t claimID,
|
||||
std::optional<AccountID> const& dst);
|
||||
|
||||
[[nodiscard]] bool
|
||||
validAmounts() const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::vector<std::uint8_t>
|
||||
message(STXChainBridge const& bridge) const override;
|
||||
|
||||
friend bool
|
||||
operator==(AttestationClaim const& lhs, AttestationClaim const& rhs);
|
||||
};
|
||||
|
||||
struct CmpByClaimID
|
||||
{
|
||||
bool
|
||||
operator()(AttestationClaim const& lhs, AttestationClaim const& rhs) const
|
||||
{
|
||||
return lhs.claimID < rhs.claimID;
|
||||
}
|
||||
};
|
||||
|
||||
// Attest to a cross-chain transfer that creates an account
|
||||
struct AttestationCreateAccount : AttestationBase
|
||||
{
|
||||
// createCount on the sending chain. This is the value of the `CreateCount`
|
||||
// field of the bridge on the sending chain when the transaction was
|
||||
// executed.
|
||||
std::uint64_t createCount;
|
||||
// Account to create on the destination chain
|
||||
AccountID toCreate;
|
||||
// Total amount of the reward pool
|
||||
STAmount rewardAmount;
|
||||
|
||||
explicit AttestationCreateAccount(STObject const& o);
|
||||
|
||||
explicit AttestationCreateAccount(json::Value const& v);
|
||||
|
||||
explicit AttestationCreateAccount(
|
||||
AccountID attestationSignerAccount,
|
||||
PublicKey const& publicKey,
|
||||
Buffer signature,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
STAmount rewardAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t createCount,
|
||||
AccountID const& toCreate);
|
||||
|
||||
explicit AttestationCreateAccount(
|
||||
STXChainBridge const& bridge,
|
||||
AccountID attestationSignerAccount,
|
||||
PublicKey const& publicKey,
|
||||
SecretKey const& secretKey,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
STAmount const& rewardAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t createCount,
|
||||
AccountID const& toCreate);
|
||||
|
||||
[[nodiscard]] STObject
|
||||
toSTObject() const;
|
||||
|
||||
// return true if the two attestations attest to the same thing
|
||||
[[nodiscard]] bool
|
||||
sameEvent(AttestationCreateAccount const& rhs) const;
|
||||
|
||||
friend bool
|
||||
operator==(AttestationCreateAccount const& lhs, AttestationCreateAccount const& rhs);
|
||||
|
||||
[[nodiscard]] static std::vector<std::uint8_t>
|
||||
message(
|
||||
STXChainBridge const& bridge,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
STAmount const& rewardAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t createCount,
|
||||
AccountID const& dst);
|
||||
|
||||
[[nodiscard]] bool
|
||||
validAmounts() const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::vector<std::uint8_t>
|
||||
message(STXChainBridge const& bridge) const override;
|
||||
};
|
||||
|
||||
struct CmpByCreateCount
|
||||
{
|
||||
bool
|
||||
operator()(AttestationCreateAccount const& lhs, AttestationCreateAccount const& rhs) const
|
||||
{
|
||||
return lhs.createCount < rhs.createCount;
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace attestations
|
||||
|
||||
// Result when checking when two attestation match.
|
||||
enum class AttestationMatch {
|
||||
// One of the fields doesn't match, and it isn't the dst field
|
||||
NonDstMismatch,
|
||||
// all of the fields match, except the dst field
|
||||
MatchExceptDst,
|
||||
// all of the fields match
|
||||
Match,
|
||||
};
|
||||
|
||||
struct XChainClaimAttestation
|
||||
{
|
||||
using TSignedAttestation = attestations::AttestationClaim;
|
||||
static SField const& arrayFieldName;
|
||||
|
||||
AccountID keyAccount;
|
||||
PublicKey publicKey;
|
||||
STAmount amount;
|
||||
AccountID rewardAccount;
|
||||
bool wasLockingChainSend;
|
||||
std::optional<AccountID> dst;
|
||||
|
||||
struct MatchFields
|
||||
{
|
||||
STAmount amount;
|
||||
bool wasLockingChainSend;
|
||||
std::optional<AccountID> dst;
|
||||
MatchFields(TSignedAttestation const& att);
|
||||
MatchFields(STAmount a, bool b, std::optional<AccountID> const& d)
|
||||
: amount{std::move(a)}, wasLockingChainSend{b}, dst{d}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
explicit XChainClaimAttestation(
|
||||
AccountID const& keyAccount,
|
||||
PublicKey const& publicKey,
|
||||
STAmount const& amount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::optional<AccountID> const& dst);
|
||||
|
||||
explicit XChainClaimAttestation(
|
||||
STAccount const& keyAccount,
|
||||
PublicKey const& publicKey,
|
||||
STAmount const& amount,
|
||||
STAccount const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::optional<STAccount> const& dst);
|
||||
|
||||
explicit XChainClaimAttestation(TSignedAttestation const& claimAtt);
|
||||
|
||||
explicit XChainClaimAttestation(STObject const& o);
|
||||
|
||||
explicit XChainClaimAttestation(json::Value const& v);
|
||||
|
||||
[[nodiscard]] AttestationMatch
|
||||
match(MatchFields const& rhs) const;
|
||||
|
||||
[[nodiscard]] STObject
|
||||
toSTObject() const;
|
||||
|
||||
friend bool
|
||||
operator==(XChainClaimAttestation const& lhs, XChainClaimAttestation const& rhs);
|
||||
};
|
||||
|
||||
struct XChainCreateAccountAttestation
|
||||
{
|
||||
using TSignedAttestation = attestations::AttestationCreateAccount;
|
||||
static SField const& arrayFieldName;
|
||||
|
||||
AccountID keyAccount;
|
||||
PublicKey publicKey;
|
||||
STAmount amount;
|
||||
STAmount rewardAmount;
|
||||
AccountID rewardAccount;
|
||||
bool wasLockingChainSend;
|
||||
AccountID dst;
|
||||
|
||||
struct MatchFields
|
||||
{
|
||||
STAmount amount;
|
||||
STAmount rewardAmount;
|
||||
bool wasLockingChainSend;
|
||||
AccountID dst;
|
||||
|
||||
MatchFields(TSignedAttestation const& att);
|
||||
};
|
||||
|
||||
explicit XChainCreateAccountAttestation(
|
||||
AccountID const& keyAccount,
|
||||
PublicKey const& publicKey,
|
||||
STAmount const& amount,
|
||||
STAmount const& rewardAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
AccountID const& dst);
|
||||
|
||||
explicit XChainCreateAccountAttestation(TSignedAttestation const& claimAtt);
|
||||
|
||||
explicit XChainCreateAccountAttestation(STObject const& o);
|
||||
|
||||
explicit XChainCreateAccountAttestation(json::Value const& v);
|
||||
|
||||
[[nodiscard]] STObject
|
||||
toSTObject() const;
|
||||
|
||||
[[nodiscard]] AttestationMatch
|
||||
match(MatchFields const& rhs) const;
|
||||
|
||||
friend bool
|
||||
operator==(
|
||||
XChainCreateAccountAttestation const& lhs,
|
||||
XChainCreateAccountAttestation const& rhs);
|
||||
};
|
||||
|
||||
// Attestations from witness servers for a particular claim ID and bridge.
|
||||
// Only one attestation per signature is allowed.
|
||||
template <class TAttestation>
|
||||
class XChainAttestationsBase
|
||||
{
|
||||
public:
|
||||
using AttCollection = std::vector<TAttestation>;
|
||||
|
||||
private:
|
||||
// Set a max number of allowed attestations to limit the amount of memory
|
||||
// allocated and processing time. This number is much larger than the actual
|
||||
// number of attestation a server would ever expect.
|
||||
static constexpr std::uint32_t kMaxAttestations = 256;
|
||||
AttCollection attestations_;
|
||||
|
||||
protected:
|
||||
// Prevent slicing to the base class
|
||||
~XChainAttestationsBase() = default;
|
||||
|
||||
public:
|
||||
XChainAttestationsBase() = default;
|
||||
XChainAttestationsBase(XChainAttestationsBase const& rhs) = default;
|
||||
XChainAttestationsBase&
|
||||
operator=(XChainAttestationsBase const& rhs) = default;
|
||||
|
||||
explicit XChainAttestationsBase(AttCollection&& sigs);
|
||||
|
||||
explicit XChainAttestationsBase(json::Value const& v);
|
||||
|
||||
explicit XChainAttestationsBase(STArray const& arr);
|
||||
|
||||
[[nodiscard]] STArray
|
||||
toSTArray() const;
|
||||
|
||||
[[nodiscard]] AttCollection::const_iterator
|
||||
begin() const;
|
||||
|
||||
[[nodiscard]] AttCollection::const_iterator
|
||||
end() const;
|
||||
|
||||
AttCollection::iterator
|
||||
begin();
|
||||
|
||||
AttCollection::iterator
|
||||
end();
|
||||
|
||||
template <class F>
|
||||
std::size_t
|
||||
eraseIf(F&& f);
|
||||
|
||||
[[nodiscard]] std::size_t
|
||||
size() const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
empty() const;
|
||||
|
||||
[[nodiscard]] AttCollection const&
|
||||
attestations() const;
|
||||
|
||||
template <class T>
|
||||
void
|
||||
emplaceBack(T&& att);
|
||||
};
|
||||
|
||||
template <class TAttestation>
|
||||
[[nodiscard]] inline bool
|
||||
operator==(
|
||||
XChainAttestationsBase<TAttestation> const& lhs,
|
||||
XChainAttestationsBase<TAttestation> const& rhs)
|
||||
{
|
||||
return lhs.attestations() == rhs.attestations();
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
inline XChainAttestationsBase<TAttestation>::AttCollection const&
|
||||
XChainAttestationsBase<TAttestation>::attestations() const
|
||||
{
|
||||
return attestations_;
|
||||
};
|
||||
|
||||
template <class TAttestation>
|
||||
template <class T>
|
||||
inline void
|
||||
XChainAttestationsBase<TAttestation>::emplaceBack(T&& att)
|
||||
{
|
||||
attestations_.emplace_back(std::forward<T>(att));
|
||||
};
|
||||
|
||||
template <class TAttestation>
|
||||
template <class F>
|
||||
inline std::size_t
|
||||
XChainAttestationsBase<TAttestation>::eraseIf(F&& f)
|
||||
{
|
||||
return std::erase_if(attestations_, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
inline std::size_t
|
||||
XChainAttestationsBase<TAttestation>::size() const
|
||||
{
|
||||
return attestations_.size();
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
inline bool
|
||||
XChainAttestationsBase<TAttestation>::empty() const
|
||||
{
|
||||
return attestations_.empty();
|
||||
}
|
||||
|
||||
class XChainClaimAttestations final : public XChainAttestationsBase<XChainClaimAttestation>
|
||||
{
|
||||
using TBase = XChainAttestationsBase<XChainClaimAttestation>;
|
||||
using TBase::TBase;
|
||||
};
|
||||
|
||||
class XChainCreateAccountAttestations final
|
||||
: public XChainAttestationsBase<XChainCreateAccountAttestation>
|
||||
{
|
||||
using TBase = XChainAttestationsBase<XChainCreateAccountAttestation>;
|
||||
using TBase::TBase;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -62,14 +62,9 @@ XRPL_FIX (EnforceNFTokenTrustline, Supported::Yes, VoteBehavior::DefaultNo
|
||||
XRPL_FIX (ReducedOffersV2, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(NFTokenMintOffer, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PreviousTxnID, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (XChainRewardRounding, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (EmptyDID, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PriceOracle, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (FillOrKill, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DID, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(XChainBridge, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(AMM, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(XRPFees, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (RemoveNFTokenAutoTrustLine, Supported::Yes, VoteBehavior::DefaultYes)
|
||||
|
||||
// The following amendments are obsolete, but must remain supported
|
||||
@@ -85,6 +80,9 @@ XRPL_FIX (RemoveNFTokenAutoTrustLine, Supported::Yes, VoteBehavior::DefaultYe
|
||||
// to vote for it, the feature can be removed entirely from the code. Until
|
||||
// then the feature needs to be marked explicitly as obsolete, e.g.
|
||||
// XRPL_FEATURE(Example, Supported::yes, VoteBehavior::Obsolete)
|
||||
XRPL_FEATURE(XChainBridge, Supported::Yes, VoteBehavior::Obsolete)
|
||||
XRPL_FIX (XChainRewardRounding, Supported::Yes, VoteBehavior::Obsolete)
|
||||
|
||||
// The following amendments have been active for at least two years. Their
|
||||
// pre-amendment code has been removed and the identifiers are deprecated.
|
||||
// All known amendments and amendments that may appear in a validated ledger
|
||||
@@ -109,6 +107,7 @@ XRPL_RETIRE_FIX(AMMOverflowOffer)
|
||||
XRPL_RETIRE_FIX(AMMv1_1)
|
||||
XRPL_RETIRE_FIX(CheckThreading)
|
||||
XRPL_RETIRE_FIX(DisallowIncomingV1)
|
||||
XRPL_RETIRE_FIX(FillOrKill)
|
||||
XRPL_RETIRE_FIX(InnerObjTemplate)
|
||||
XRPL_RETIRE_FIX(MasterKeyAsRegularKey)
|
||||
XRPL_RETIRE_FIX(NonFungibleTokensV1_2)
|
||||
@@ -123,6 +122,7 @@ XRPL_RETIRE_FIX(TakerDryOfferRemoval)
|
||||
XRPL_RETIRE_FIX(TrustLinesToSelf)
|
||||
XRPL_RETIRE_FIX(UniversalNumber)
|
||||
|
||||
XRPL_RETIRE_FEATURE(AMM)
|
||||
XRPL_RETIRE_FEATURE(Checks)
|
||||
XRPL_RETIRE_FEATURE(CheckCashMakesTrustLine)
|
||||
XRPL_RETIRE_FEATURE(Clawback)
|
||||
@@ -151,3 +151,4 @@ XRPL_RETIRE_FEATURE(SortedDirectories)
|
||||
XRPL_RETIRE_FEATURE(TicketBatch)
|
||||
XRPL_RETIRE_FEATURE(TickSize)
|
||||
XRPL_RETIRE_FEATURE(TrustSetAuth)
|
||||
XRPL_RETIRE_FEATURE(XRPFees)
|
||||
@@ -206,23 +206,6 @@ LEDGER_ENTRY(ltLEDGER_HASHES, 0x0068, LedgerHashes, hashes, ({
|
||||
{sfHashes, SoeRequired},
|
||||
}))
|
||||
|
||||
/** The ledger object which lists details about sidechains.
|
||||
|
||||
\sa keylet::bridge
|
||||
*/
|
||||
LEDGER_ENTRY(ltBRIDGE, 0x0069, Bridge, bridge, ({
|
||||
{sfAccount, SoeRequired},
|
||||
{sfSignatureReward, SoeRequired},
|
||||
{sfMinAccountCreateAmount, SoeOptional},
|
||||
{sfXChainBridge, SoeRequired},
|
||||
{sfXChainClaimID, SoeRequired},
|
||||
{sfXChainAccountCreateCount, SoeRequired},
|
||||
{sfXChainAccountClaimCount, SoeRequired},
|
||||
{sfOwnerNode, SoeRequired},
|
||||
{sfPreviousTxnID, SoeRequired},
|
||||
{sfPreviousTxnLgrSeq, SoeRequired},
|
||||
}))
|
||||
|
||||
/** A ledger object which describes an offer on the DEX.
|
||||
|
||||
\sa keylet::offer
|
||||
@@ -255,22 +238,6 @@ LEDGER_ENTRY_DUPLICATE(ltDEPOSIT_PREAUTH, 0x0070, DepositPreauth, deposit_preaut
|
||||
{sfAuthorizeCredentials, SoeOptional},
|
||||
}))
|
||||
|
||||
/** A claim id for a cross chain transaction.
|
||||
|
||||
\sa keylet::xChainClaimID
|
||||
*/
|
||||
LEDGER_ENTRY(ltXCHAIN_OWNED_CLAIM_ID, 0x0071, XChainOwnedClaimID, xchain_owned_claim_id, ({
|
||||
{sfAccount, SoeRequired},
|
||||
{sfXChainBridge, SoeRequired},
|
||||
{sfXChainClaimID, SoeRequired},
|
||||
{sfOtherChainSource, SoeRequired},
|
||||
{sfXChainClaimAttestations, SoeRequired},
|
||||
{sfSignatureReward, SoeRequired},
|
||||
{sfOwnerNode, SoeRequired},
|
||||
{sfPreviousTxnID, SoeRequired},
|
||||
{sfPreviousTxnLgrSeq, SoeRequired},
|
||||
}))
|
||||
|
||||
/** A ledger object which describes a bidirectional trust line.
|
||||
|
||||
@note Per Vinnie Falco this should be renamed to ltTRUST_LINE
|
||||
@@ -318,20 +285,6 @@ LEDGER_ENTRY(ltFEE_SETTINGS, 0x0073, FeeSettings, fee, ({
|
||||
{sfPreviousTxnLgrSeq, SoeOptional},
|
||||
}))
|
||||
|
||||
/** A claim id for a cross chain create account transaction.
|
||||
|
||||
\sa keylet::xChainCreateAccountClaimID
|
||||
*/
|
||||
LEDGER_ENTRY(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID, 0x0074, XChainOwnedCreateAccountClaimID, xchain_owned_create_account_claim_id, ({
|
||||
{sfAccount, SoeRequired},
|
||||
{sfXChainBridge, SoeRequired},
|
||||
{sfXChainAccountCreateCount, SoeRequired},
|
||||
{sfXChainCreateAccountAttestations, SoeRequired},
|
||||
{sfOwnerNode, SoeRequired},
|
||||
{sfPreviousTxnID, SoeRequired},
|
||||
{sfPreviousTxnLgrSeq, SoeRequired},
|
||||
}))
|
||||
|
||||
/** A ledger object describing a single escrow.
|
||||
|
||||
\sa keylet::escrow
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#error "undefined macro: TYPED_SFIELD"
|
||||
#endif
|
||||
|
||||
// A code marked "reserved" is not assigned to a field. Do not reuse a reserved
|
||||
// code until a year or two after its field was removed, so that no supported
|
||||
// release or tool still knows the old meaning.
|
||||
|
||||
// untyped
|
||||
UNTYPED_SFIELD(sfLedgerEntry, LEDGERENTRY, 257)
|
||||
@@ -23,8 +26,7 @@ TYPED_SFIELD(sfLEVersion, UINT8, 6)
|
||||
// 8-bit integers (uncommon)
|
||||
TYPED_SFIELD(sfTickSize, UINT8, 16)
|
||||
TYPED_SFIELD(sfUNLModifyDisabling, UINT8, 17)
|
||||
// 18 unused
|
||||
TYPED_SFIELD(sfWasLockingChainSend, UINT8, 19)
|
||||
// 18 to 19 reserved
|
||||
TYPED_SFIELD(sfWithdrawalPolicy, UINT8, 20)
|
||||
TYPED_SFIELD(sfContractResult, UINT8, 21)
|
||||
TYPED_SFIELD(sfVaultKind, UINT8, 22)
|
||||
@@ -39,7 +41,7 @@ TYPED_SFIELD(sfDiscountedFee, UINT16, 6)
|
||||
|
||||
// 16-bit integers (uncommon)
|
||||
TYPED_SFIELD(sfVersion, UINT16, 16)
|
||||
// 17 to 20 unused
|
||||
// 17 to 20 reserved
|
||||
TYPED_SFIELD(sfLedgerFixType, UINT16, 21)
|
||||
TYPED_SFIELD(sfManagementFeeRate, UINT16, 22) // 1/10 basis points (bips)
|
||||
|
||||
@@ -90,7 +92,7 @@ TYPED_SFIELD(sfTicketSequence, UINT32, 41)
|
||||
TYPED_SFIELD(sfNFTokenTaxon, UINT32, 42)
|
||||
TYPED_SFIELD(sfMintedNFTokens, UINT32, 43)
|
||||
TYPED_SFIELD(sfBurnedNFTokens, UINT32, 44)
|
||||
// 45 to 47 unused
|
||||
// 45 to 47 reserved
|
||||
TYPED_SFIELD(sfVoteWeight, UINT32, 48)
|
||||
TYPED_SFIELD(sfFirstNFTokenSequence, UINT32, 50)
|
||||
TYPED_SFIELD(sfOracleDocumentID, UINT32, 51)
|
||||
@@ -145,11 +147,9 @@ TYPED_SFIELD(sfNFTokenOfferNode, UINT64, 12)
|
||||
TYPED_SFIELD(sfEmitBurden, UINT64, 13)
|
||||
|
||||
// 64-bit integers (uncommon)
|
||||
// 16 to 18 unused
|
||||
// 16 to 18 reserved
|
||||
TYPED_SFIELD(sfReferenceCount, UINT64, 19)
|
||||
TYPED_SFIELD(sfXChainClaimID, UINT64, 20)
|
||||
TYPED_SFIELD(sfXChainAccountCreateCount, UINT64, 21)
|
||||
TYPED_SFIELD(sfXChainAccountClaimCount, UINT64, 22)
|
||||
// 20 to 22 reserved
|
||||
TYPED_SFIELD(sfAssetPrice, UINT64, 23)
|
||||
TYPED_SFIELD(sfMaximumAmount, UINT64, 24, SField::kSmdBaseTen|SField::kSmdDefault)
|
||||
TYPED_SFIELD(sfOutstandingAmount, UINT64, 25, SField::kSmdBaseTen|SField::kSmdDefault)
|
||||
@@ -199,7 +199,7 @@ TYPED_SFIELD(sfBookDirectory, UINT256, 16)
|
||||
TYPED_SFIELD(sfInvoiceID, UINT256, 17)
|
||||
TYPED_SFIELD(sfNickname, UINT256, 18)
|
||||
TYPED_SFIELD(sfAmendment, UINT256, 19)
|
||||
// 20 unused
|
||||
// 20 reserved
|
||||
TYPED_SFIELD(sfDigest, UINT256, 21)
|
||||
TYPED_SFIELD(sfChannel, UINT256, 22)
|
||||
TYPED_SFIELD(sfConsensusHash, UINT256, 23)
|
||||
@@ -209,7 +209,7 @@ TYPED_SFIELD(sfPreviousPageMin, UINT256, 26)
|
||||
TYPED_SFIELD(sfNextPageMin, UINT256, 27)
|
||||
TYPED_SFIELD(sfNFTokenBuyOffer, UINT256, 28)
|
||||
TYPED_SFIELD(sfNFTokenSellOffer, UINT256, 29)
|
||||
// 30 to 33 unused
|
||||
// 30 to 33 reserved
|
||||
TYPED_SFIELD(sfDomainID, UINT256, 34)
|
||||
TYPED_SFIELD(sfVaultID, UINT256, 35,
|
||||
SField::kSmdPseudoAccount | SField::kSmdDefault)
|
||||
@@ -268,7 +268,7 @@ TYPED_SFIELD(sfMinimumOffer, AMOUNT, 16)
|
||||
TYPED_SFIELD(sfRippleEscrow, AMOUNT, 17)
|
||||
TYPED_SFIELD(sfDeliveredAmount, AMOUNT, 18)
|
||||
TYPED_SFIELD(sfNFTokenBrokerFee, AMOUNT, 19)
|
||||
// 20 to 21 unused
|
||||
// 20 to 21 reserved
|
||||
// currency amount (fees)
|
||||
TYPED_SFIELD(sfBaseFeeDrops, AMOUNT, 22)
|
||||
TYPED_SFIELD(sfReserveBaseDrops, AMOUNT, 23)
|
||||
@@ -279,8 +279,7 @@ TYPED_SFIELD(sfLPTokenOut, AMOUNT, 25)
|
||||
TYPED_SFIELD(sfLPTokenIn, AMOUNT, 26)
|
||||
TYPED_SFIELD(sfEPrice, AMOUNT, 27)
|
||||
TYPED_SFIELD(sfPrice, AMOUNT, 28)
|
||||
TYPED_SFIELD(sfSignatureReward, AMOUNT, 29)
|
||||
TYPED_SFIELD(sfMinAccountCreateAmount, AMOUNT, 30)
|
||||
// 29 to 30 reserved
|
||||
TYPED_SFIELD(sfLPTokenBalance, AMOUNT, 31)
|
||||
TYPED_SFIELD(sfFeeAmount, AMOUNT, 32)
|
||||
TYPED_SFIELD(sfMaxFee, AMOUNT, 33)
|
||||
@@ -309,7 +308,7 @@ TYPED_SFIELD(sfMasterSignature, VL, 18, SField::kSmdDefault, SFi
|
||||
TYPED_SFIELD(sfUNLModifyValidator, VL, 19)
|
||||
TYPED_SFIELD(sfValidatorToDisable, VL, 20)
|
||||
TYPED_SFIELD(sfValidatorToReEnable, VL, 21)
|
||||
// 22 to 25 unused
|
||||
// 22 to 25 reserved
|
||||
TYPED_SFIELD(sfDIDDocument, VL, 26)
|
||||
TYPED_SFIELD(sfData, VL, 27)
|
||||
TYPED_SFIELD(sfAssetClass, VL, 28)
|
||||
@@ -343,7 +342,7 @@ TYPED_SFIELD(sfDestination, ACCOUNT, 3)
|
||||
TYPED_SFIELD(sfIssuer, ACCOUNT, 4)
|
||||
TYPED_SFIELD(sfAuthorize, ACCOUNT, 5)
|
||||
TYPED_SFIELD(sfUnauthorize, ACCOUNT, 6)
|
||||
// 7 unused
|
||||
// 7 reserved
|
||||
TYPED_SFIELD(sfRegularKey, ACCOUNT, 8)
|
||||
TYPED_SFIELD(sfNFTokenMinter, ACCOUNT, 9)
|
||||
TYPED_SFIELD(sfEmitCallback, ACCOUNT, 10)
|
||||
@@ -351,13 +350,7 @@ TYPED_SFIELD(sfHolder, ACCOUNT, 11)
|
||||
TYPED_SFIELD(sfDelegate, ACCOUNT, 12)
|
||||
|
||||
// account (uncommon)
|
||||
// 16 unused
|
||||
TYPED_SFIELD(sfOtherChainSource, ACCOUNT, 18)
|
||||
TYPED_SFIELD(sfOtherChainDestination, ACCOUNT, 19)
|
||||
TYPED_SFIELD(sfAttestationSignerAccount, ACCOUNT, 20)
|
||||
TYPED_SFIELD(sfAttestationRewardAccount, ACCOUNT, 21)
|
||||
TYPED_SFIELD(sfLockingChainDoor, ACCOUNT, 22)
|
||||
TYPED_SFIELD(sfIssuingChainDoor, ACCOUNT, 23)
|
||||
// 16 to 23 reserved
|
||||
TYPED_SFIELD(sfSubject, ACCOUNT, 24)
|
||||
TYPED_SFIELD(sfBorrower, ACCOUNT, 25)
|
||||
TYPED_SFIELD(sfCounterparty, ACCOUNT, 26)
|
||||
@@ -383,14 +376,10 @@ TYPED_SFIELD(sfBaseAsset, CURRENCY, 1)
|
||||
TYPED_SFIELD(sfQuoteAsset, CURRENCY, 2)
|
||||
|
||||
// issue
|
||||
TYPED_SFIELD(sfLockingChainIssue, ISSUE, 1)
|
||||
TYPED_SFIELD(sfIssuingChainIssue, ISSUE, 2)
|
||||
// 1 to 2 reserved
|
||||
TYPED_SFIELD(sfAsset, ISSUE, 3)
|
||||
TYPED_SFIELD(sfAsset2, ISSUE, 4)
|
||||
|
||||
// bridge
|
||||
TYPED_SFIELD(sfXChainBridge, XCHAIN_BRIDGE, 1)
|
||||
|
||||
// inner object
|
||||
// OBJECT/1 is reserved for end of object
|
||||
UNTYPED_SFIELD(sfTransactionMetaData, OBJECT, 2)
|
||||
@@ -405,22 +394,19 @@ UNTYPED_SFIELD(sfMemo, OBJECT, 10)
|
||||
UNTYPED_SFIELD(sfSignerEntry, OBJECT, 11)
|
||||
UNTYPED_SFIELD(sfNFToken, OBJECT, 12)
|
||||
UNTYPED_SFIELD(sfEmitDetails, OBJECT, 13)
|
||||
// 14 unused
|
||||
// 14 reserved
|
||||
UNTYPED_SFIELD(sfPermission, OBJECT, 15)
|
||||
|
||||
// inner object (uncommon)
|
||||
UNTYPED_SFIELD(sfSigner, OBJECT, 16)
|
||||
// 17 unused
|
||||
// 17 reserved
|
||||
UNTYPED_SFIELD(sfMajority, OBJECT, 18)
|
||||
UNTYPED_SFIELD(sfDisabledValidator, OBJECT, 19)
|
||||
// 20 to 24 unused
|
||||
// 20 to 24 reserved
|
||||
UNTYPED_SFIELD(sfVoteEntry, OBJECT, 25)
|
||||
UNTYPED_SFIELD(sfAuctionSlot, OBJECT, 26)
|
||||
UNTYPED_SFIELD(sfAuthAccount, OBJECT, 27)
|
||||
UNTYPED_SFIELD(sfXChainClaimProofSig, OBJECT, 28)
|
||||
UNTYPED_SFIELD(sfXChainCreateAccountProofSig, OBJECT, 29)
|
||||
UNTYPED_SFIELD(sfXChainClaimAttestationCollectionElement, OBJECT, 30)
|
||||
UNTYPED_SFIELD(sfXChainCreateAccountAttestationCollectionElement, OBJECT, 31)
|
||||
// 28 to 31 reserved
|
||||
UNTYPED_SFIELD(sfPriceData, OBJECT, 32)
|
||||
UNTYPED_SFIELD(sfCredential, OBJECT, 33)
|
||||
UNTYPED_SFIELD(sfRawTransaction, OBJECT, 34)
|
||||
@@ -442,17 +428,14 @@ UNTYPED_SFIELD(sfSufficient, ARRAY, 7)
|
||||
UNTYPED_SFIELD(sfAffectedNodes, ARRAY, 8)
|
||||
UNTYPED_SFIELD(sfMemos, ARRAY, 9)
|
||||
UNTYPED_SFIELD(sfNFTokens, ARRAY, 10)
|
||||
// 11 unused
|
||||
// 11 reserved
|
||||
UNTYPED_SFIELD(sfVoteSlots, ARRAY, 12)
|
||||
UNTYPED_SFIELD(sfAdditionalBooks, ARRAY, 13)
|
||||
|
||||
// array of objects (uncommon)
|
||||
UNTYPED_SFIELD(sfMajorities, ARRAY, 16)
|
||||
UNTYPED_SFIELD(sfDisabledValidators, ARRAY, 17)
|
||||
// 18 to 20 unused
|
||||
UNTYPED_SFIELD(sfXChainClaimAttestations, ARRAY, 21)
|
||||
UNTYPED_SFIELD(sfXChainCreateAccountAttestations, ARRAY, 22)
|
||||
// 23 unused
|
||||
// 18 to 23 reserved
|
||||
UNTYPED_SFIELD(sfPriceDataSeries, ARRAY, 24)
|
||||
UNTYPED_SFIELD(sfAuthAccounts, ARRAY, 25)
|
||||
UNTYPED_SFIELD(sfAuthorizeCredentials, ARRAY, 26)
|
||||
|
||||
@@ -372,7 +372,6 @@ TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback,
|
||||
TRANSACTION(ttAMM_CREATE, 35, AMMCreate,
|
||||
({
|
||||
.delegable = Delegation::Delegable,
|
||||
.amendment = featureAMM,
|
||||
.privileges = Privilege::CreatePseudoAcct | Privilege::MayCreateMpt,
|
||||
}),
|
||||
({
|
||||
@@ -386,7 +385,7 @@ TRANSACTION(ttAMM_CREATE, 35, AMMCreate,
|
||||
# include <xrpl/tx/transactors/dex/AMMDeposit.h>
|
||||
#endif
|
||||
TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit,
|
||||
({.delegable = Delegation::Delegable, .amendment = featureAMM}),
|
||||
({.delegable = Delegation::Delegable}),
|
||||
({
|
||||
{sfAsset, SoeRequired, SoeMptSupported},
|
||||
{sfAsset2, SoeRequired, SoeMptSupported},
|
||||
@@ -404,7 +403,6 @@ TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit,
|
||||
TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw,
|
||||
({
|
||||
.delegable = Delegation::Delegable,
|
||||
.amendment = featureAMM,
|
||||
.privileges = Privilege::MayDeleteAcct | Privilege::MayAuthorizeMpt,
|
||||
}),
|
||||
({
|
||||
@@ -421,7 +419,7 @@ TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw,
|
||||
# include <xrpl/tx/transactors/dex/AMMVote.h>
|
||||
#endif
|
||||
TRANSACTION(ttAMM_VOTE, 38, AMMVote,
|
||||
({.delegable = Delegation::Delegable, .amendment = featureAMM}),
|
||||
({.delegable = Delegation::Delegable}),
|
||||
({
|
||||
{sfAsset, SoeRequired, SoeMptSupported},
|
||||
{sfAsset2, SoeRequired, SoeMptSupported},
|
||||
@@ -433,7 +431,7 @@ TRANSACTION(ttAMM_VOTE, 38, AMMVote,
|
||||
# include <xrpl/tx/transactors/dex/AMMBid.h>
|
||||
#endif
|
||||
TRANSACTION(ttAMM_BID, 39, AMMBid,
|
||||
({.delegable = Delegation::Delegable, .amendment = featureAMM}),
|
||||
({.delegable = Delegation::Delegable}),
|
||||
({
|
||||
{sfAsset, SoeRequired, SoeMptSupported},
|
||||
{sfAsset2, SoeRequired, SoeMptSupported},
|
||||
@@ -449,7 +447,6 @@ TRANSACTION(ttAMM_BID, 39, AMMBid,
|
||||
TRANSACTION(ttAMM_DELETE, 40, AMMDelete,
|
||||
({
|
||||
.delegable = Delegation::Delegable,
|
||||
.amendment = featureAMM,
|
||||
.privileges = Privilege::MustDeleteAcct | Privilege::MayDeleteMpt,
|
||||
}),
|
||||
({
|
||||
@@ -457,111 +454,7 @@ TRANSACTION(ttAMM_DELETE, 40, AMMDelete,
|
||||
{sfAsset2, SoeRequired, SoeMptSupported},
|
||||
}))
|
||||
|
||||
/** This transactions creates a crosschain sequence number */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/bridge/XChainBridge.h>
|
||||
#endif
|
||||
TRANSACTION(ttXCHAIN_CREATE_CLAIM_ID, 41, XChainCreateClaimID,
|
||||
({.delegable = Delegation::Delegable, .amendment = featureXChainBridge}),
|
||||
({
|
||||
{sfXChainBridge, SoeRequired},
|
||||
{sfSignatureReward, SoeRequired},
|
||||
{sfOtherChainSource, SoeRequired},
|
||||
}))
|
||||
|
||||
/** This transactions initiates a crosschain transaction */
|
||||
TRANSACTION(ttXCHAIN_COMMIT, 42, XChainCommit,
|
||||
({.delegable = Delegation::Delegable, .amendment = featureXChainBridge}),
|
||||
({
|
||||
{sfXChainBridge, SoeRequired},
|
||||
{sfXChainClaimID, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfOtherChainDestination, SoeOptional},
|
||||
}))
|
||||
|
||||
/** This transaction completes a crosschain transaction */
|
||||
TRANSACTION(ttXCHAIN_CLAIM, 43, XChainClaim,
|
||||
({.delegable = Delegation::Delegable, .amendment = featureXChainBridge}),
|
||||
({
|
||||
{sfXChainBridge, SoeRequired},
|
||||
{sfXChainClaimID, SoeRequired},
|
||||
{sfDestination, SoeRequired},
|
||||
{sfDestinationTag, SoeOptional},
|
||||
{sfAmount, SoeRequired},
|
||||
}))
|
||||
|
||||
/** This transaction initiates a crosschain account create transaction */
|
||||
TRANSACTION(ttXCHAIN_ACCOUNT_CREATE_COMMIT, 44, XChainAccountCreateCommit,
|
||||
({.delegable = Delegation::Delegable, .amendment = featureXChainBridge}),
|
||||
({
|
||||
{sfXChainBridge, SoeRequired},
|
||||
{sfDestination, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfSignatureReward, SoeRequired},
|
||||
}))
|
||||
|
||||
/** This transaction adds an attestation to a claim */
|
||||
TRANSACTION(ttXCHAIN_ADD_CLAIM_ATTESTATION, 45, XChainAddClaimAttestation,
|
||||
({
|
||||
.delegable = Delegation::Delegable,
|
||||
.amendment = featureXChainBridge,
|
||||
.privileges = Privilege::CreateAcct,
|
||||
}),
|
||||
({
|
||||
{sfXChainBridge, SoeRequired},
|
||||
|
||||
{sfAttestationSignerAccount, SoeRequired},
|
||||
{sfPublicKey, SoeRequired},
|
||||
{sfSignature, SoeRequired},
|
||||
{sfOtherChainSource, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfAttestationRewardAccount, SoeRequired},
|
||||
{sfWasLockingChainSend, SoeRequired},
|
||||
|
||||
{sfXChainClaimID, SoeRequired},
|
||||
{sfDestination, SoeOptional},
|
||||
}))
|
||||
|
||||
/** This transaction adds an attestation to an account */
|
||||
TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46, XChainAddAccountCreateAttestation,
|
||||
({
|
||||
.delegable = Delegation::Delegable,
|
||||
.amendment = featureXChainBridge,
|
||||
.privileges = Privilege::CreateAcct,
|
||||
}),
|
||||
({
|
||||
{sfXChainBridge, SoeRequired},
|
||||
|
||||
{sfAttestationSignerAccount, SoeRequired},
|
||||
{sfPublicKey, SoeRequired},
|
||||
{sfSignature, SoeRequired},
|
||||
{sfOtherChainSource, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfAttestationRewardAccount, SoeRequired},
|
||||
{sfWasLockingChainSend, SoeRequired},
|
||||
|
||||
{sfXChainAccountCreateCount, SoeRequired},
|
||||
{sfDestination, SoeRequired},
|
||||
{sfSignatureReward, SoeRequired},
|
||||
}))
|
||||
|
||||
/** This transaction modifies a sidechain */
|
||||
TRANSACTION(ttXCHAIN_MODIFY_BRIDGE, 47, XChainModifyBridge,
|
||||
({.delegable = Delegation::Delegable, .amendment = featureXChainBridge}),
|
||||
({
|
||||
{sfXChainBridge, SoeRequired},
|
||||
{sfSignatureReward, SoeOptional},
|
||||
{sfMinAccountCreateAmount, SoeOptional},
|
||||
}))
|
||||
|
||||
/** This transactions creates a sidechain */
|
||||
TRANSACTION(ttXCHAIN_CREATE_BRIDGE, 48, XChainCreateBridge,
|
||||
({.delegable = Delegation::Delegable, .amendment = featureXChainBridge}),
|
||||
({
|
||||
{sfXChainBridge, SoeRequired},
|
||||
{sfSignatureReward, SoeRequired},
|
||||
{sfMinAccountCreateAmount, SoeOptional},
|
||||
}))
|
||||
// 41 to 48 deprecated
|
||||
|
||||
/** This transaction type creates or updates a DID */
|
||||
#if TRANSACTION_INCLUDE
|
||||
|
||||
@@ -159,7 +159,6 @@ JSS(both); // in: Subscribe, Unsubscribe
|
||||
JSS(both_sides); // in: Subscribe, Unsubscribe
|
||||
JSS(branch); // out: server_info
|
||||
JSS(broadcast); // out: SubmitTransaction
|
||||
JSS(bridge_account); // in: LedgerEntry
|
||||
JSS(build_path); // in: TransactionSign
|
||||
JSS(build_version); // out: NetworkOPs
|
||||
JSS(cancel_after); // out: AccountChannels
|
||||
@@ -263,7 +262,6 @@ JSS(fee_base); // out: NetworkOPs
|
||||
JSS(fee_div_max); // in: TransactionSign
|
||||
JSS(fee_level); // out: AccountInfo
|
||||
JSS(fee_mult_max); // in: TransactionSign
|
||||
JSS(fee_ref); // out: NetworkOPs, DEPRECATED
|
||||
JSS(fetch_pack); // out: NetworkOPs
|
||||
JSS(FIELDS); // out: RPC server_definitions
|
||||
// matches definitions.json format
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
#include <xrpl/protocol/SecretKey.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
|
||||
@@ -1,348 +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 BridgeBuilder;
|
||||
|
||||
/**
|
||||
* @brief Ledger Entry: Bridge
|
||||
*
|
||||
* Type: ltBRIDGE (0x0069)
|
||||
* RPC Name: bridge
|
||||
*
|
||||
* Immutable wrapper around SLE providing type-safe field access.
|
||||
* Use BridgeBuilder to construct new ledger entries.
|
||||
*/
|
||||
class Bridge : public LedgerEntryBase
|
||||
{
|
||||
public:
|
||||
static constexpr LedgerEntryType entryType = ltBRIDGE;
|
||||
|
||||
/**
|
||||
* @brief Construct a Bridge ledger entry wrapper from an existing SLE object.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
explicit Bridge(SLE::const_pointer sle)
|
||||
: LedgerEntryBase(std::move(sle))
|
||||
{
|
||||
// Verify ledger entry type
|
||||
if (sle_->getType() != entryType)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for Bridge");
|
||||
}
|
||||
}
|
||||
|
||||
// Ledger entry-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfAccount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getAccount() const
|
||||
{
|
||||
return this->sle_->at(sfAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSignatureReward (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getSignatureReward() const
|
||||
{
|
||||
return this->sle_->at(sfSignatureReward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfMinAccountCreateAmount (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getMinAccountCreateAmount() const
|
||||
{
|
||||
if (hasMinAccountCreateAmount())
|
||||
return this->sle_->at(sfMinAccountCreateAmount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfMinAccountCreateAmount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasMinAccountCreateAmount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfMinAccountCreateAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->sle_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainClaimID (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getXChainClaimID() const
|
||||
{
|
||||
return this->sle_->at(sfXChainClaimID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainAccountCreateCount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getXChainAccountCreateCount() const
|
||||
{
|
||||
return this->sle_->at(sfXChainAccountCreateCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainAccountClaimCount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getXChainAccountClaimCount() const
|
||||
{
|
||||
return this->sle_->at(sfXChainAccountClaimCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwnerNode (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getOwnerNode() const
|
||||
{
|
||||
return this->sle_->at(sfOwnerNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 Builder for Bridge 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 BridgeBuilder : public LedgerEntryBuilderBase<BridgeBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new BridgeBuilder with required fields.
|
||||
* @param account The sfAccount field value.
|
||||
* @param signatureReward The sfSignatureReward field value.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param xChainClaimID The sfXChainClaimID field value.
|
||||
* @param xChainAccountCreateCount The sfXChainAccountCreateCount field value.
|
||||
* @param xChainAccountClaimCount The sfXChainAccountClaimCount field value.
|
||||
* @param ownerNode The sfOwnerNode field value.
|
||||
* @param previousTxnID The sfPreviousTxnID field value.
|
||||
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
|
||||
*/
|
||||
BridgeBuilder(std::decay_t<typename SF_ACCOUNT::type::value_type> const& account,std::decay_t<typename SF_AMOUNT::type::value_type> const& signatureReward,std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge,std::decay_t<typename SF_UINT64::type::value_type> const& xChainClaimID,std::decay_t<typename SF_UINT64::type::value_type> const& xChainAccountCreateCount,std::decay_t<typename SF_UINT64::type::value_type> const& xChainAccountClaimCount,std::decay_t<typename SF_UINT64::type::value_type> const& ownerNode,std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq)
|
||||
: LedgerEntryBuilderBase<BridgeBuilder>(ltBRIDGE)
|
||||
{
|
||||
setAccount(account);
|
||||
setSignatureReward(signatureReward);
|
||||
setXChainBridge(xChainBridge);
|
||||
setXChainClaimID(xChainClaimID);
|
||||
setXChainAccountCreateCount(xChainAccountCreateCount);
|
||||
setXChainAccountClaimCount(xChainAccountClaimCount);
|
||||
setOwnerNode(ownerNode);
|
||||
setPreviousTxnID(previousTxnID);
|
||||
setPreviousTxnLgrSeq(previousTxnLgrSeq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a BridgeBuilder 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.
|
||||
*/
|
||||
BridgeBuilder(SLE::const_pointer sle)
|
||||
{
|
||||
if (sle->at(sfLedgerEntryType) != ltBRIDGE)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for Bridge");
|
||||
}
|
||||
object_ = *sle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ledger entry-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfAccount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
BridgeBuilder&
|
||||
setAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSignatureReward (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
BridgeBuilder&
|
||||
setSignatureReward(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSignatureReward] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfMinAccountCreateAmount (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
BridgeBuilder&
|
||||
setMinAccountCreateAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfMinAccountCreateAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
BridgeBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainClaimID (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
BridgeBuilder&
|
||||
setXChainClaimID(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainClaimID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainAccountCreateCount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
BridgeBuilder&
|
||||
setXChainAccountCreateCount(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainAccountCreateCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainAccountClaimCount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
BridgeBuilder&
|
||||
setXChainAccountClaimCount(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainAccountClaimCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwnerNode (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
BridgeBuilder&
|
||||
setOwnerNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwnerNode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnID (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
BridgeBuilder&
|
||||
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.
|
||||
*/
|
||||
BridgeBuilder&
|
||||
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnLgrSeq] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed Bridge wrapper.
|
||||
* @param index The ledger entry index.
|
||||
* @return The constructed ledger entry wrapper.
|
||||
*/
|
||||
Bridge
|
||||
build(UInt256 const& index)
|
||||
{
|
||||
return Bridge{std::make_shared<SLE>(std::move(object_), index)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::ledger_entries
|
||||
@@ -1,314 +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 XChainOwnedClaimIDBuilder;
|
||||
|
||||
/**
|
||||
* @brief Ledger Entry: XChainOwnedClaimID
|
||||
*
|
||||
* Type: ltXCHAIN_OWNED_CLAIM_ID (0x0071)
|
||||
* RPC Name: xchain_owned_claim_id
|
||||
*
|
||||
* Immutable wrapper around SLE providing type-safe field access.
|
||||
* Use XChainOwnedClaimIDBuilder to construct new ledger entries.
|
||||
*/
|
||||
class XChainOwnedClaimID : public LedgerEntryBase
|
||||
{
|
||||
public:
|
||||
static constexpr LedgerEntryType entryType = ltXCHAIN_OWNED_CLAIM_ID;
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainOwnedClaimID ledger entry wrapper from an existing SLE object.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
explicit XChainOwnedClaimID(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 XChainOwnedClaimID");
|
||||
}
|
||||
}
|
||||
|
||||
// Ledger entry-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfAccount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getAccount() const
|
||||
{
|
||||
return this->sle_->at(sfAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->sle_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainClaimID (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getXChainClaimID() const
|
||||
{
|
||||
return this->sle_->at(sfXChainClaimID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOtherChainSource (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getOtherChainSource() const
|
||||
{
|
||||
return this->sle_->at(sfOtherChainSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainClaimAttestations (SoeRequired)
|
||||
* @note This is an untyped field (unknown).
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
STArray const&
|
||||
getXChainClaimAttestations() const
|
||||
{
|
||||
return this->sle_->getFieldArray(sfXChainClaimAttestations);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSignatureReward (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getSignatureReward() const
|
||||
{
|
||||
return this->sle_->at(sfSignatureReward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwnerNode (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getOwnerNode() const
|
||||
{
|
||||
return this->sle_->at(sfOwnerNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 Builder for XChainOwnedClaimID 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 XChainOwnedClaimIDBuilder : public LedgerEntryBuilderBase<XChainOwnedClaimIDBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new XChainOwnedClaimIDBuilder with required fields.
|
||||
* @param account The sfAccount field value.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param xChainClaimID The sfXChainClaimID field value.
|
||||
* @param otherChainSource The sfOtherChainSource field value.
|
||||
* @param xChainClaimAttestations The sfXChainClaimAttestations field value.
|
||||
* @param signatureReward The sfSignatureReward field value.
|
||||
* @param ownerNode The sfOwnerNode field value.
|
||||
* @param previousTxnID The sfPreviousTxnID field value.
|
||||
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder(std::decay_t<typename SF_ACCOUNT::type::value_type> const& account,std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge,std::decay_t<typename SF_UINT64::type::value_type> const& xChainClaimID,std::decay_t<typename SF_ACCOUNT::type::value_type> const& otherChainSource,STArray const& xChainClaimAttestations,std::decay_t<typename SF_AMOUNT::type::value_type> const& signatureReward,std::decay_t<typename SF_UINT64::type::value_type> const& ownerNode,std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq)
|
||||
: LedgerEntryBuilderBase<XChainOwnedClaimIDBuilder>(ltXCHAIN_OWNED_CLAIM_ID)
|
||||
{
|
||||
setAccount(account);
|
||||
setXChainBridge(xChainBridge);
|
||||
setXChainClaimID(xChainClaimID);
|
||||
setOtherChainSource(otherChainSource);
|
||||
setXChainClaimAttestations(xChainClaimAttestations);
|
||||
setSignatureReward(signatureReward);
|
||||
setOwnerNode(ownerNode);
|
||||
setPreviousTxnID(previousTxnID);
|
||||
setPreviousTxnLgrSeq(previousTxnLgrSeq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainOwnedClaimIDBuilder 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.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder(SLE::const_pointer sle)
|
||||
{
|
||||
if (sle->at(sfLedgerEntryType) != ltXCHAIN_OWNED_CLAIM_ID)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for XChainOwnedClaimID");
|
||||
}
|
||||
object_ = *sle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ledger entry-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfAccount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder&
|
||||
setAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainClaimID (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder&
|
||||
setXChainClaimID(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainClaimID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOtherChainSource (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder&
|
||||
setOtherChainSource(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOtherChainSource] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainClaimAttestations (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder&
|
||||
setXChainClaimAttestations(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfXChainClaimAttestations, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSignatureReward (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder&
|
||||
setSignatureReward(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSignatureReward] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwnerNode (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder&
|
||||
setOwnerNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwnerNode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnID (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder&
|
||||
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.
|
||||
*/
|
||||
XChainOwnedClaimIDBuilder&
|
||||
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnLgrSeq] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed XChainOwnedClaimID wrapper.
|
||||
* @param index The ledger entry index.
|
||||
* @return The constructed ledger entry wrapper.
|
||||
*/
|
||||
XChainOwnedClaimID
|
||||
build(UInt256 const& index)
|
||||
{
|
||||
return XChainOwnedClaimID{std::make_shared<SLE>(std::move(object_), index)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::ledger_entries
|
||||
@@ -1,266 +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 XChainOwnedCreateAccountClaimIDBuilder;
|
||||
|
||||
/**
|
||||
* @brief Ledger Entry: XChainOwnedCreateAccountClaimID
|
||||
*
|
||||
* Type: ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID (0x0074)
|
||||
* RPC Name: xchain_owned_create_account_claim_id
|
||||
*
|
||||
* Immutable wrapper around SLE providing type-safe field access.
|
||||
* Use XChainOwnedCreateAccountClaimIDBuilder to construct new ledger entries.
|
||||
*/
|
||||
class XChainOwnedCreateAccountClaimID : public LedgerEntryBase
|
||||
{
|
||||
public:
|
||||
static constexpr LedgerEntryType entryType = ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID;
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainOwnedCreateAccountClaimID ledger entry wrapper from an existing SLE object.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
explicit XChainOwnedCreateAccountClaimID(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 XChainOwnedCreateAccountClaimID");
|
||||
}
|
||||
}
|
||||
|
||||
// Ledger entry-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfAccount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getAccount() const
|
||||
{
|
||||
return this->sle_->at(sfAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->sle_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainAccountCreateCount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getXChainAccountCreateCount() const
|
||||
{
|
||||
return this->sle_->at(sfXChainAccountCreateCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainCreateAccountAttestations (SoeRequired)
|
||||
* @note This is an untyped field (unknown).
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
STArray const&
|
||||
getXChainCreateAccountAttestations() const
|
||||
{
|
||||
return this->sle_->getFieldArray(sfXChainCreateAccountAttestations);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwnerNode (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getOwnerNode() const
|
||||
{
|
||||
return this->sle_->at(sfOwnerNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 Builder for XChainOwnedCreateAccountClaimID 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 XChainOwnedCreateAccountClaimIDBuilder : public LedgerEntryBuilderBase<XChainOwnedCreateAccountClaimIDBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new XChainOwnedCreateAccountClaimIDBuilder with required fields.
|
||||
* @param account The sfAccount field value.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param xChainAccountCreateCount The sfXChainAccountCreateCount field value.
|
||||
* @param xChainCreateAccountAttestations The sfXChainCreateAccountAttestations field value.
|
||||
* @param ownerNode The sfOwnerNode field value.
|
||||
* @param previousTxnID The sfPreviousTxnID field value.
|
||||
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
|
||||
*/
|
||||
XChainOwnedCreateAccountClaimIDBuilder(std::decay_t<typename SF_ACCOUNT::type::value_type> const& account,std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge,std::decay_t<typename SF_UINT64::type::value_type> const& xChainAccountCreateCount,STArray const& xChainCreateAccountAttestations,std::decay_t<typename SF_UINT64::type::value_type> const& ownerNode,std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq)
|
||||
: LedgerEntryBuilderBase<XChainOwnedCreateAccountClaimIDBuilder>(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID)
|
||||
{
|
||||
setAccount(account);
|
||||
setXChainBridge(xChainBridge);
|
||||
setXChainAccountCreateCount(xChainAccountCreateCount);
|
||||
setXChainCreateAccountAttestations(xChainCreateAccountAttestations);
|
||||
setOwnerNode(ownerNode);
|
||||
setPreviousTxnID(previousTxnID);
|
||||
setPreviousTxnLgrSeq(previousTxnLgrSeq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainOwnedCreateAccountClaimIDBuilder 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.
|
||||
*/
|
||||
XChainOwnedCreateAccountClaimIDBuilder(SLE::const_pointer sle)
|
||||
{
|
||||
if (sle->at(sfLedgerEntryType) != ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for XChainOwnedCreateAccountClaimID");
|
||||
}
|
||||
object_ = *sle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ledger entry-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfAccount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedCreateAccountClaimIDBuilder&
|
||||
setAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedCreateAccountClaimIDBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainAccountCreateCount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedCreateAccountClaimIDBuilder&
|
||||
setXChainAccountCreateCount(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainAccountCreateCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainCreateAccountAttestations (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedCreateAccountClaimIDBuilder&
|
||||
setXChainCreateAccountAttestations(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfXChainCreateAccountAttestations, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwnerNode (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedCreateAccountClaimIDBuilder&
|
||||
setOwnerNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwnerNode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnID (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainOwnedCreateAccountClaimIDBuilder&
|
||||
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.
|
||||
*/
|
||||
XChainOwnedCreateAccountClaimIDBuilder&
|
||||
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnLgrSeq] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed XChainOwnedCreateAccountClaimID wrapper.
|
||||
* @param index The ledger entry index.
|
||||
* @return The constructed ledger entry wrapper.
|
||||
*/
|
||||
XChainOwnedCreateAccountClaimID
|
||||
build(UInt256 const& index)
|
||||
{
|
||||
return XChainOwnedCreateAccountClaimID{std::make_shared<SLE>(std::move(object_), index)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::ledger_entries
|
||||
@@ -20,7 +20,7 @@ class AMMBidBuilder;
|
||||
*
|
||||
* Type: ttAMM_BID (39)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Amendment: UInt256{}
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
|
||||
@@ -20,7 +20,7 @@ class AMMCreateBuilder;
|
||||
*
|
||||
* Type: ttAMM_CREATE (35)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Amendment: UInt256{}
|
||||
* Privileges: Privilege::CreatePseudoAcct | Privilege::MayCreateMpt
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
|
||||
@@ -20,7 +20,7 @@ class AMMDeleteBuilder;
|
||||
*
|
||||
* Type: ttAMM_DELETE (40)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Amendment: UInt256{}
|
||||
* Privileges: Privilege::MustDeleteAcct | Privilege::MayDeleteMpt
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
|
||||
@@ -20,7 +20,7 @@ class AMMDepositBuilder;
|
||||
*
|
||||
* Type: ttAMM_DEPOSIT (36)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Amendment: UInt256{}
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
|
||||
@@ -20,7 +20,7 @@ class AMMVoteBuilder;
|
||||
*
|
||||
* Type: ttAMM_VOTE (38)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Amendment: UInt256{}
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
|
||||
@@ -20,7 +20,7 @@ class AMMWithdrawBuilder;
|
||||
*
|
||||
* Type: ttAMM_WITHDRAW (37)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Amendment: UInt256{}
|
||||
* Privileges: Privilege::MayDeleteAcct | Privilege::MayAuthorizeMpt
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
|
||||
@@ -1,203 +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 XChainAccountCreateCommitBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: XChainAccountCreateCommit
|
||||
*
|
||||
* Type: ttXCHAIN_ACCOUNT_CREATE_COMMIT (44)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureXChainBridge
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use XChainAccountCreateCommitBuilder to construct new transactions.
|
||||
*/
|
||||
class XChainAccountCreateCommit : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttXCHAIN_ACCOUNT_CREATE_COMMIT;
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainAccountCreateCommit transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit XChainAccountCreateCommit(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 XChainAccountCreateCommit");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->tx_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfDestination (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getDestination() const
|
||||
{
|
||||
return this->tx_->at(sfDestination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAmount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getAmount() const
|
||||
{
|
||||
return this->tx_->at(sfAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSignatureReward (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getSignatureReward() const
|
||||
{
|
||||
return this->tx_->at(sfSignatureReward);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for XChainAccountCreateCommit 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 XChainAccountCreateCommitBuilder : public TransactionBuilderBase<XChainAccountCreateCommitBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new XChainAccountCreateCommitBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param destination The sfDestination field value.
|
||||
* @param amount The sfAmount field value.
|
||||
* @param signatureReward The sfSignatureReward field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
XChainAccountCreateCommitBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge, std::decay_t<typename SF_ACCOUNT::type::value_type> const& destination, std::decay_t<typename SF_AMOUNT::type::value_type> const& amount, std::decay_t<typename SF_AMOUNT::type::value_type> const& signatureReward, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<XChainAccountCreateCommitBuilder>(ttXCHAIN_ACCOUNT_CREATE_COMMIT, account, sequence, fee)
|
||||
{
|
||||
setXChainBridge(xChainBridge);
|
||||
setDestination(destination);
|
||||
setAmount(amount);
|
||||
setSignatureReward(signatureReward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainAccountCreateCommitBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
XChainAccountCreateCommitBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttXCHAIN_ACCOUNT_CREATE_COMMIT)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for XChainAccountCreateCommitBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transaction-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAccountCreateCommitBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfDestination (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAccountCreateCommitBuilder&
|
||||
setDestination(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfDestination] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAmount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAccountCreateCommitBuilder&
|
||||
setAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSignatureReward (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAccountCreateCommitBuilder&
|
||||
setSignatureReward(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSignatureReward] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the XChainAccountCreateCommit wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
XChainAccountCreateCommit
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return XChainAccountCreateCommit{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,371 +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 XChainAddAccountCreateAttestationBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: XChainAddAccountCreateAttestation
|
||||
*
|
||||
* Type: ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION (46)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureXChainBridge
|
||||
* Privileges: Privilege::CreateAcct
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use XChainAddAccountCreateAttestationBuilder to construct new transactions.
|
||||
*/
|
||||
class XChainAddAccountCreateAttestation : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION;
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainAddAccountCreateAttestation transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit XChainAddAccountCreateAttestation(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 XChainAddAccountCreateAttestation");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->tx_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAttestationSignerAccount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getAttestationSignerAccount() const
|
||||
{
|
||||
return this->tx_->at(sfAttestationSignerAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfPublicKey (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_VL::type::value_type
|
||||
getPublicKey() const
|
||||
{
|
||||
return this->tx_->at(sfPublicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSignature (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_VL::type::value_type
|
||||
getSignature() const
|
||||
{
|
||||
return this->tx_->at(sfSignature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOtherChainSource (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getOtherChainSource() const
|
||||
{
|
||||
return this->tx_->at(sfOtherChainSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAmount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getAmount() const
|
||||
{
|
||||
return this->tx_->at(sfAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAttestationRewardAccount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getAttestationRewardAccount() const
|
||||
{
|
||||
return this->tx_->at(sfAttestationRewardAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfWasLockingChainSend (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT8::type::value_type
|
||||
getWasLockingChainSend() const
|
||||
{
|
||||
return this->tx_->at(sfWasLockingChainSend);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainAccountCreateCount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getXChainAccountCreateCount() const
|
||||
{
|
||||
return this->tx_->at(sfXChainAccountCreateCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfDestination (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getDestination() const
|
||||
{
|
||||
return this->tx_->at(sfDestination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSignatureReward (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getSignatureReward() const
|
||||
{
|
||||
return this->tx_->at(sfSignatureReward);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for XChainAddAccountCreateAttestation 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 XChainAddAccountCreateAttestationBuilder : public TransactionBuilderBase<XChainAddAccountCreateAttestationBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new XChainAddAccountCreateAttestationBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param attestationSignerAccount The sfAttestationSignerAccount field value.
|
||||
* @param publicKey The sfPublicKey field value.
|
||||
* @param signature The sfSignature field value.
|
||||
* @param otherChainSource The sfOtherChainSource field value.
|
||||
* @param amount The sfAmount field value.
|
||||
* @param attestationRewardAccount The sfAttestationRewardAccount field value.
|
||||
* @param wasLockingChainSend The sfWasLockingChainSend field value.
|
||||
* @param xChainAccountCreateCount The sfXChainAccountCreateCount field value.
|
||||
* @param destination The sfDestination field value.
|
||||
* @param signatureReward The sfSignatureReward field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge, std::decay_t<typename SF_ACCOUNT::type::value_type> const& attestationSignerAccount, std::decay_t<typename SF_VL::type::value_type> const& publicKey, std::decay_t<typename SF_VL::type::value_type> const& signature, std::decay_t<typename SF_ACCOUNT::type::value_type> const& otherChainSource, std::decay_t<typename SF_AMOUNT::type::value_type> const& amount, std::decay_t<typename SF_ACCOUNT::type::value_type> const& attestationRewardAccount, std::decay_t<typename SF_UINT8::type::value_type> const& wasLockingChainSend, std::decay_t<typename SF_UINT64::type::value_type> const& xChainAccountCreateCount, std::decay_t<typename SF_ACCOUNT::type::value_type> const& destination, std::decay_t<typename SF_AMOUNT::type::value_type> const& signatureReward, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<XChainAddAccountCreateAttestationBuilder>(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, account, sequence, fee)
|
||||
{
|
||||
setXChainBridge(xChainBridge);
|
||||
setAttestationSignerAccount(attestationSignerAccount);
|
||||
setPublicKey(publicKey);
|
||||
setSignature(signature);
|
||||
setOtherChainSource(otherChainSource);
|
||||
setAmount(amount);
|
||||
setAttestationRewardAccount(attestationRewardAccount);
|
||||
setWasLockingChainSend(wasLockingChainSend);
|
||||
setXChainAccountCreateCount(xChainAccountCreateCount);
|
||||
setDestination(destination);
|
||||
setSignatureReward(signatureReward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainAddAccountCreateAttestationBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for XChainAddAccountCreateAttestationBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transaction-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAttestationSignerAccount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setAttestationSignerAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAttestationSignerAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPublicKey (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setPublicKey(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPublicKey] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSignature (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setSignature(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSignature] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOtherChainSource (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setOtherChainSource(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOtherChainSource] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAmount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAttestationRewardAccount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setAttestationRewardAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAttestationRewardAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfWasLockingChainSend (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setWasLockingChainSend(std::decay_t<typename SF_UINT8::type::value_type> const& value)
|
||||
{
|
||||
object_[sfWasLockingChainSend] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainAccountCreateCount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setXChainAccountCreateCount(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainAccountCreateCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfDestination (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setDestination(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfDestination] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSignatureReward (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddAccountCreateAttestationBuilder&
|
||||
setSignatureReward(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSignatureReward] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the XChainAddAccountCreateAttestation wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
XChainAddAccountCreateAttestation
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return XChainAddAccountCreateAttestation{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,360 +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 XChainAddClaimAttestationBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: XChainAddClaimAttestation
|
||||
*
|
||||
* Type: ttXCHAIN_ADD_CLAIM_ATTESTATION (45)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureXChainBridge
|
||||
* Privileges: Privilege::CreateAcct
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use XChainAddClaimAttestationBuilder to construct new transactions.
|
||||
*/
|
||||
class XChainAddClaimAttestation : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttXCHAIN_ADD_CLAIM_ATTESTATION;
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainAddClaimAttestation transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit XChainAddClaimAttestation(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 XChainAddClaimAttestation");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->tx_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAttestationSignerAccount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getAttestationSignerAccount() const
|
||||
{
|
||||
return this->tx_->at(sfAttestationSignerAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfPublicKey (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_VL::type::value_type
|
||||
getPublicKey() const
|
||||
{
|
||||
return this->tx_->at(sfPublicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSignature (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_VL::type::value_type
|
||||
getSignature() const
|
||||
{
|
||||
return this->tx_->at(sfSignature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOtherChainSource (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getOtherChainSource() const
|
||||
{
|
||||
return this->tx_->at(sfOtherChainSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAmount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getAmount() const
|
||||
{
|
||||
return this->tx_->at(sfAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAttestationRewardAccount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getAttestationRewardAccount() const
|
||||
{
|
||||
return this->tx_->at(sfAttestationRewardAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfWasLockingChainSend (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT8::type::value_type
|
||||
getWasLockingChainSend() const
|
||||
{
|
||||
return this->tx_->at(sfWasLockingChainSend);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainClaimID (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getXChainClaimID() const
|
||||
{
|
||||
return this->tx_->at(sfXChainClaimID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfDestination (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getDestination() const
|
||||
{
|
||||
if (hasDestination())
|
||||
{
|
||||
return this->tx_->at(sfDestination);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfDestination is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasDestination() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfDestination);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for XChainAddClaimAttestation 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 XChainAddClaimAttestationBuilder : public TransactionBuilderBase<XChainAddClaimAttestationBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new XChainAddClaimAttestationBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param attestationSignerAccount The sfAttestationSignerAccount field value.
|
||||
* @param publicKey The sfPublicKey field value.
|
||||
* @param signature The sfSignature field value.
|
||||
* @param otherChainSource The sfOtherChainSource field value.
|
||||
* @param amount The sfAmount field value.
|
||||
* @param attestationRewardAccount The sfAttestationRewardAccount field value.
|
||||
* @param wasLockingChainSend The sfWasLockingChainSend field value.
|
||||
* @param xChainClaimID The sfXChainClaimID field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge, std::decay_t<typename SF_ACCOUNT::type::value_type> const& attestationSignerAccount, std::decay_t<typename SF_VL::type::value_type> const& publicKey, std::decay_t<typename SF_VL::type::value_type> const& signature, std::decay_t<typename SF_ACCOUNT::type::value_type> const& otherChainSource, std::decay_t<typename SF_AMOUNT::type::value_type> const& amount, std::decay_t<typename SF_ACCOUNT::type::value_type> const& attestationRewardAccount, std::decay_t<typename SF_UINT8::type::value_type> const& wasLockingChainSend, std::decay_t<typename SF_UINT64::type::value_type> const& xChainClaimID, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<XChainAddClaimAttestationBuilder>(ttXCHAIN_ADD_CLAIM_ATTESTATION, account, sequence, fee)
|
||||
{
|
||||
setXChainBridge(xChainBridge);
|
||||
setAttestationSignerAccount(attestationSignerAccount);
|
||||
setPublicKey(publicKey);
|
||||
setSignature(signature);
|
||||
setOtherChainSource(otherChainSource);
|
||||
setAmount(amount);
|
||||
setAttestationRewardAccount(attestationRewardAccount);
|
||||
setWasLockingChainSend(wasLockingChainSend);
|
||||
setXChainClaimID(xChainClaimID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainAddClaimAttestationBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttXCHAIN_ADD_CLAIM_ATTESTATION)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for XChainAddClaimAttestationBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transaction-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAttestationSignerAccount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder&
|
||||
setAttestationSignerAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAttestationSignerAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPublicKey (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder&
|
||||
setPublicKey(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPublicKey] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSignature (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder&
|
||||
setSignature(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSignature] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOtherChainSource (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder&
|
||||
setOtherChainSource(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOtherChainSource] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAmount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder&
|
||||
setAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAttestationRewardAccount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder&
|
||||
setAttestationRewardAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAttestationRewardAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfWasLockingChainSend (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder&
|
||||
setWasLockingChainSend(std::decay_t<typename SF_UINT8::type::value_type> const& value)
|
||||
{
|
||||
object_[sfWasLockingChainSend] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainClaimID (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder&
|
||||
setXChainClaimID(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainClaimID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfDestination (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainAddClaimAttestationBuilder&
|
||||
setDestination(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfDestination] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the XChainAddClaimAttestation wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
XChainAddClaimAttestation
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return XChainAddClaimAttestation{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,240 +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 XChainClaimBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: XChainClaim
|
||||
*
|
||||
* Type: ttXCHAIN_CLAIM (43)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureXChainBridge
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use XChainClaimBuilder to construct new transactions.
|
||||
*/
|
||||
class XChainClaim : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttXCHAIN_CLAIM;
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainClaim transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit XChainClaim(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 XChainClaim");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->tx_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainClaimID (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getXChainClaimID() const
|
||||
{
|
||||
return this->tx_->at(sfXChainClaimID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfDestination (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getDestination() const
|
||||
{
|
||||
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)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getAmount() const
|
||||
{
|
||||
return this->tx_->at(sfAmount);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for XChainClaim 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 XChainClaimBuilder : public TransactionBuilderBase<XChainClaimBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new XChainClaimBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param xChainClaimID The sfXChainClaimID field value.
|
||||
* @param destination The sfDestination field value.
|
||||
* @param amount The sfAmount field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
XChainClaimBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge, std::decay_t<typename SF_UINT64::type::value_type> const& xChainClaimID, std::decay_t<typename SF_ACCOUNT::type::value_type> const& destination, 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<XChainClaimBuilder>(ttXCHAIN_CLAIM, account, sequence, fee)
|
||||
{
|
||||
setXChainBridge(xChainBridge);
|
||||
setXChainClaimID(xChainClaimID);
|
||||
setDestination(destination);
|
||||
setAmount(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainClaimBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
XChainClaimBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttXCHAIN_CLAIM)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for XChainClaimBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transaction-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainClaimBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainClaimID (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainClaimBuilder&
|
||||
setXChainClaimID(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainClaimID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfDestination (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainClaimBuilder&
|
||||
setDestination(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfDestination] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfDestinationTag (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainClaimBuilder&
|
||||
setDestinationTag(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfDestinationTag] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAmount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainClaimBuilder&
|
||||
setAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the XChainClaim wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
XChainClaim
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return XChainClaim{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,216 +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 XChainCommitBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: XChainCommit
|
||||
*
|
||||
* Type: ttXCHAIN_COMMIT (42)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureXChainBridge
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use XChainCommitBuilder to construct new transactions.
|
||||
*/
|
||||
class XChainCommit : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttXCHAIN_COMMIT;
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainCommit transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit XChainCommit(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 XChainCommit");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->tx_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainClaimID (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getXChainClaimID() const
|
||||
{
|
||||
return this->tx_->at(sfXChainClaimID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAmount (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getAmount() const
|
||||
{
|
||||
return this->tx_->at(sfAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOtherChainDestination (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getOtherChainDestination() const
|
||||
{
|
||||
if (hasOtherChainDestination())
|
||||
{
|
||||
return this->tx_->at(sfOtherChainDestination);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfOtherChainDestination is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasOtherChainDestination() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfOtherChainDestination);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for XChainCommit 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 XChainCommitBuilder : public TransactionBuilderBase<XChainCommitBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new XChainCommitBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param xChainClaimID The sfXChainClaimID field value.
|
||||
* @param amount The sfAmount field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
XChainCommitBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge, std::decay_t<typename SF_UINT64::type::value_type> const& xChainClaimID, 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<XChainCommitBuilder>(ttXCHAIN_COMMIT, account, sequence, fee)
|
||||
{
|
||||
setXChainBridge(xChainBridge);
|
||||
setXChainClaimID(xChainClaimID);
|
||||
setAmount(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainCommitBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
XChainCommitBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttXCHAIN_COMMIT)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for XChainCommitBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transaction-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainCommitBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainClaimID (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainCommitBuilder&
|
||||
setXChainClaimID(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainClaimID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAmount (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainCommitBuilder&
|
||||
setAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOtherChainDestination (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainCommitBuilder&
|
||||
setOtherChainDestination(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOtherChainDestination] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the XChainCommit wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
XChainCommit
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return XChainCommit{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,192 +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 XChainCreateBridgeBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: XChainCreateBridge
|
||||
*
|
||||
* Type: ttXCHAIN_CREATE_BRIDGE (48)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureXChainBridge
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use XChainCreateBridgeBuilder to construct new transactions.
|
||||
*/
|
||||
class XChainCreateBridge : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttXCHAIN_CREATE_BRIDGE;
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainCreateBridge transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit XChainCreateBridge(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 XChainCreateBridge");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->tx_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSignatureReward (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getSignatureReward() const
|
||||
{
|
||||
return this->tx_->at(sfSignatureReward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfMinAccountCreateAmount (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getMinAccountCreateAmount() const
|
||||
{
|
||||
if (hasMinAccountCreateAmount())
|
||||
{
|
||||
return this->tx_->at(sfMinAccountCreateAmount);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfMinAccountCreateAmount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasMinAccountCreateAmount() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfMinAccountCreateAmount);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for XChainCreateBridge 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 XChainCreateBridgeBuilder : public TransactionBuilderBase<XChainCreateBridgeBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new XChainCreateBridgeBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param signatureReward The sfSignatureReward field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
XChainCreateBridgeBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge, std::decay_t<typename SF_AMOUNT::type::value_type> const& signatureReward, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<XChainCreateBridgeBuilder>(ttXCHAIN_CREATE_BRIDGE, account, sequence, fee)
|
||||
{
|
||||
setXChainBridge(xChainBridge);
|
||||
setSignatureReward(signatureReward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainCreateBridgeBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
XChainCreateBridgeBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttXCHAIN_CREATE_BRIDGE)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for XChainCreateBridgeBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transaction-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainCreateBridgeBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSignatureReward (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainCreateBridgeBuilder&
|
||||
setSignatureReward(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSignatureReward] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfMinAccountCreateAmount (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainCreateBridgeBuilder&
|
||||
setMinAccountCreateAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfMinAccountCreateAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the XChainCreateBridge wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
XChainCreateBridge
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return XChainCreateBridge{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,179 +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 XChainCreateClaimIDBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: XChainCreateClaimID
|
||||
*
|
||||
* Type: ttXCHAIN_CREATE_CLAIM_ID (41)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureXChainBridge
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use XChainCreateClaimIDBuilder to construct new transactions.
|
||||
*/
|
||||
class XChainCreateClaimID : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttXCHAIN_CREATE_CLAIM_ID;
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainCreateClaimID transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit XChainCreateClaimID(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 XChainCreateClaimID");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->tx_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSignatureReward (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getSignatureReward() const
|
||||
{
|
||||
return this->tx_->at(sfSignatureReward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOtherChainSource (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getOtherChainSource() const
|
||||
{
|
||||
return this->tx_->at(sfOtherChainSource);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for XChainCreateClaimID 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 XChainCreateClaimIDBuilder : public TransactionBuilderBase<XChainCreateClaimIDBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new XChainCreateClaimIDBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param signatureReward The sfSignatureReward field value.
|
||||
* @param otherChainSource The sfOtherChainSource field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
XChainCreateClaimIDBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge, std::decay_t<typename SF_AMOUNT::type::value_type> const& signatureReward, std::decay_t<typename SF_ACCOUNT::type::value_type> const& otherChainSource, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<XChainCreateClaimIDBuilder>(ttXCHAIN_CREATE_CLAIM_ID, account, sequence, fee)
|
||||
{
|
||||
setXChainBridge(xChainBridge);
|
||||
setSignatureReward(signatureReward);
|
||||
setOtherChainSource(otherChainSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainCreateClaimIDBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
XChainCreateClaimIDBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttXCHAIN_CREATE_CLAIM_ID)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for XChainCreateClaimIDBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transaction-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainCreateClaimIDBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSignatureReward (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainCreateClaimIDBuilder&
|
||||
setSignatureReward(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSignatureReward] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOtherChainSource (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainCreateClaimIDBuilder&
|
||||
setOtherChainSource(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOtherChainSource] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the XChainCreateClaimID wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
XChainCreateClaimID
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return XChainCreateClaimID{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,205 +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 XChainModifyBridgeBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: XChainModifyBridge
|
||||
*
|
||||
* Type: ttXCHAIN_MODIFY_BRIDGE (47)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureXChainBridge
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use XChainModifyBridgeBuilder to construct new transactions.
|
||||
*/
|
||||
class XChainModifyBridge : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttXCHAIN_MODIFY_BRIDGE;
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainModifyBridge transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit XChainModifyBridge(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 XChainModifyBridge");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfXChainBridge (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_XCHAIN_BRIDGE::type::value_type
|
||||
getXChainBridge() const
|
||||
{
|
||||
return this->tx_->at(sfXChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSignatureReward (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getSignatureReward() const
|
||||
{
|
||||
if (hasSignatureReward())
|
||||
{
|
||||
return this->tx_->at(sfSignatureReward);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSignatureReward is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSignatureReward() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfSignatureReward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfMinAccountCreateAmount (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getMinAccountCreateAmount() const
|
||||
{
|
||||
if (hasMinAccountCreateAmount())
|
||||
{
|
||||
return this->tx_->at(sfMinAccountCreateAmount);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfMinAccountCreateAmount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasMinAccountCreateAmount() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfMinAccountCreateAmount);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for XChainModifyBridge 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 XChainModifyBridgeBuilder : public TransactionBuilderBase<XChainModifyBridgeBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new XChainModifyBridgeBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param xChainBridge The sfXChainBridge field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
XChainModifyBridgeBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& xChainBridge, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<XChainModifyBridgeBuilder>(ttXCHAIN_MODIFY_BRIDGE, account, sequence, fee)
|
||||
{
|
||||
setXChainBridge(xChainBridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a XChainModifyBridgeBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
XChainModifyBridgeBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttXCHAIN_MODIFY_BRIDGE)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for XChainModifyBridgeBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transaction-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfXChainBridge (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainModifyBridgeBuilder&
|
||||
setXChainBridge(std::decay_t<typename SF_XCHAIN_BRIDGE::type::value_type> const& value)
|
||||
{
|
||||
object_[sfXChainBridge] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSignatureReward (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainModifyBridgeBuilder&
|
||||
setSignatureReward(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSignatureReward] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfMinAccountCreateAmount (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
XChainModifyBridgeBuilder&
|
||||
setMinAccountCreateAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfMinAccountCreateAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the XChainModifyBridge wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
XChainModifyBridge
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return XChainModifyBridge{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class ReadView;
|
||||
|
||||
/**
|
||||
* @brief Invariants for TransactionProposal ledger entries.
|
||||
*
|
||||
* - Only transaction types implementing proposal lifecycle operations may
|
||||
* create or modify proposals, and a failed one leaves no proposal effect.
|
||||
* - A proposal is deleted only by TransactionProposalCancel or together with
|
||||
* the Ticket it is keyed to, and a deleted Ticket takes the proposal keyed
|
||||
* to it along.
|
||||
* - Collected signer arrays remain sorted, unique, and bounded.
|
||||
*/
|
||||
class ValidTransactionProposal
|
||||
{
|
||||
// The Ticket each deleted proposal was keyed to; a proposal may go with
|
||||
// its Ticket, or by Cancel, and no other way.
|
||||
std::vector<uint256> ticketsOfDeletedProposals_;
|
||||
// The proposal each deleted Ticket was keyed to, whether or not one
|
||||
// existed; none may survive its Ticket.
|
||||
std::vector<Keylet> proposalsOfDeletedTickets_;
|
||||
std::set<uint256> deletedTickets_;
|
||||
std::uint32_t created_ = 0;
|
||||
std::uint32_t modified_ = 0;
|
||||
std::uint32_t deleted_ = 0;
|
||||
bool invalidSignerArrays_ = false;
|
||||
|
||||
public:
|
||||
void
|
||||
visitEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after);
|
||||
|
||||
[[nodiscard]] bool
|
||||
finalize(STTx const& tx, TER result, XRPAmount, ReadView const& view, beast::Journal const& j)
|
||||
const;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/invariants/AMMInvariant.h>
|
||||
#include <xrpl/tx/invariants/CosignerInvariant.h>
|
||||
#include <xrpl/tx/invariants/DirectoryInvariant.h>
|
||||
#include <xrpl/tx/invariants/FreezeInvariant.h>
|
||||
#include <xrpl/tx/invariants/LoanBrokerInvariant.h>
|
||||
@@ -483,6 +484,7 @@ using InvariantChecks = std::tuple<
|
||||
ValidAmounts,
|
||||
ValidMPTTransfer,
|
||||
ObjectHasPseudoAccount,
|
||||
ValidTransactionProposal,
|
||||
SponsorshipOwnerCountsMatch,
|
||||
SponsorshipAccountCountMatchesField>;
|
||||
|
||||
|
||||
@@ -818,13 +818,10 @@ flow(
|
||||
* TakerPays. We reverse pays and gets because during crossing
|
||||
* we are taking, therefore the owner must deliver the full TakerPays and
|
||||
* the entire TakerGets doesn't have to be spent.
|
||||
* Pre-fixFillOrKill amendment code fails if the entire TakerGets
|
||||
* is not spent. fixFillOrKill addresses this issue.
|
||||
* 2. If tfSell is also set then the owner must spend the entire TakerGets
|
||||
* even if it means obtaining more than TakerPays. Since the pays and gets
|
||||
* are reversed, the owner must send the entire TakerGets.
|
||||
*/
|
||||
bool const fillOrKillEnabled = baseView.rules().enabled(fixFillOrKill);
|
||||
|
||||
if (actualOut != outReq)
|
||||
{
|
||||
@@ -840,13 +837,9 @@ flow(
|
||||
}
|
||||
if (!partialPayment)
|
||||
{
|
||||
// If we're offerCrossing a !partialPayment, then we're handling tfFillOrKill.
|
||||
// Pre-fixFillOrKill amendment:
|
||||
// That case is handled below; not here.
|
||||
// fixFillOrKill amendment:
|
||||
// That case is handled here if tfSell is also not set; i.e, case 1.
|
||||
if (offerCrossing == OfferCrossing::No ||
|
||||
(fillOrKillEnabled && offerCrossing != OfferCrossing::Sell))
|
||||
// If partialPayment is false, the caller requires full outReq (payments, or FillOrKill
|
||||
// offers).
|
||||
if (offerCrossing != OfferCrossing::Sell)
|
||||
{
|
||||
return {tecPATH_PARTIAL, actualIn, actualOut, std::move(ofrsToRmOnFail)};
|
||||
}
|
||||
@@ -856,16 +849,10 @@ flow(
|
||||
return {tecPATH_DRY, std::move(ofrsToRmOnFail)};
|
||||
}
|
||||
}
|
||||
if (offerCrossing != OfferCrossing::No &&
|
||||
(!partialPayment && (!fillOrKillEnabled || offerCrossing == OfferCrossing::Sell)))
|
||||
if (!partialPayment && offerCrossing == OfferCrossing::Sell)
|
||||
{
|
||||
// If we're offer crossing and partialPayment is *not* true, then
|
||||
// we're handling a FillOrKill offer. In this case remainingIn must
|
||||
// be zero (all funds must be consumed) or else we kill the offer.
|
||||
// Pre-fixFillOrKill amendment:
|
||||
// Handles both cases 1. and 2.
|
||||
// fixFillOrKill amendment:
|
||||
// Handles 2. 1. is handled above and falls through for tfSell.
|
||||
// we're handling a FillOrKill offer.
|
||||
XRPL_ASSERT(remainingIn, "xrpl::flow : nonzero remainingIn");
|
||||
if (remainingIn && *remainingIn != beast::kZero)
|
||||
return {tecPATH_PARTIAL, actualIn, actualOut, std::move(ofrsToRmOnFail)};
|
||||
|
||||
@@ -1,336 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
constexpr size_t kXbridgeMaxAccountCreateClaims = 128;
|
||||
|
||||
// Attach a new bridge to a door account. Once this is done, the cross-chain
|
||||
// transfer transactions may be used to transfer funds from this account.
|
||||
class XChainCreateBridge : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;
|
||||
|
||||
explicit XChainCreateBridge(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
|
||||
void
|
||||
visitInvariantEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after) override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
finalizeInvariants(
|
||||
STTx const& tx,
|
||||
TER result,
|
||||
XRPAmount fee,
|
||||
ReadView const& view,
|
||||
beast::Journal const& j) override;
|
||||
};
|
||||
|
||||
class BridgeModify : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;
|
||||
|
||||
explicit BridgeModify(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
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::ConstRef before, SLE::ConstRef after) override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
finalizeInvariants(
|
||||
STTx const& tx,
|
||||
TER result,
|
||||
XRPAmount fee,
|
||||
ReadView const& view,
|
||||
beast::Journal const& j) override;
|
||||
};
|
||||
|
||||
using XChainModifyBridge = BridgeModify;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Claim funds from a `XChainCommit` transaction. This is normally not needed,
|
||||
// but may be used to handle transaction failures or if the destination account
|
||||
// was not specified in the `XChainCommit` transaction. It may only be used
|
||||
// after a quorum of signatures have been sent from the witness servers.
|
||||
//
|
||||
// If the transaction succeeds in moving funds, the referenced `XChainClaimID`
|
||||
// ledger object will be destroyed. This prevents transaction replay. If the
|
||||
// transaction fails, the `XChainClaimID` will not be destroyed and the
|
||||
// transaction may be re-run with different parameters.
|
||||
class XChainClaim : public Transactor
|
||||
{
|
||||
public:
|
||||
// Blocker since we cannot accurately calculate the consequences
|
||||
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Blocker;
|
||||
|
||||
explicit XChainClaim(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
|
||||
void
|
||||
visitInvariantEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after) override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
finalizeInvariants(
|
||||
STTx const& tx,
|
||||
TER result,
|
||||
XRPAmount fee,
|
||||
ReadView const& view,
|
||||
beast::Journal const& j) override;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Put assets into trust on the locking-chain so they may be wrapped on the
|
||||
// issuing-chain, or return wrapped assets on the issuing-chain so they can be
|
||||
// unlocked on the locking-chain. The second step in a cross-chain transfer.
|
||||
class XChainCommit : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Custom;
|
||||
|
||||
static TxConsequences
|
||||
makeTxConsequences(PreflightContext const& ctx);
|
||||
|
||||
explicit XChainCommit(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
|
||||
void
|
||||
visitInvariantEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after) override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
finalizeInvariants(
|
||||
STTx const& tx,
|
||||
TER result,
|
||||
XRPAmount fee,
|
||||
ReadView const& view,
|
||||
beast::Journal const& j) override;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Create a new claim id owned by the account. This is the first step in a
|
||||
// cross-chain transfer. The claim id must be created on the destination chain
|
||||
// before the `XChainCommit` transaction (which must reference this number) can
|
||||
// be sent on the source chain. The account that will send the `XChainCommit` on
|
||||
// the source chain must be specified in this transaction (see note on the
|
||||
// `SourceAccount` field in the `XChainClaimID` ledger object for
|
||||
// justification). The actual sequence number must be retrieved from a validated
|
||||
// ledger.
|
||||
class XChainCreateClaimID : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;
|
||||
|
||||
explicit XChainCreateClaimID(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
|
||||
void
|
||||
visitInvariantEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after) override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
finalizeInvariants(
|
||||
STTx const& tx,
|
||||
TER result,
|
||||
XRPAmount fee,
|
||||
ReadView const& view,
|
||||
beast::Journal const& j) override;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Provide attestations from a witness server attesting to events on
|
||||
// the other chain. The signatures must be from one of the keys on the door's
|
||||
// signer's list at the time the signature was provided. However, if the
|
||||
// signature list changes between the time the signature was submitted and the
|
||||
// quorum is reached, the new signature set is used and some of the currently
|
||||
// collected signatures may be removed. Also note the reward is only sent to
|
||||
// accounts that have keys on the current list.
|
||||
class XChainAddClaimAttestation : public Transactor
|
||||
{
|
||||
public:
|
||||
// Blocker since we cannot accurately calculate the consequences
|
||||
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Blocker;
|
||||
|
||||
explicit XChainAddClaimAttestation(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
|
||||
void
|
||||
visitInvariantEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after) override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
finalizeInvariants(
|
||||
STTx const& tx,
|
||||
TER result,
|
||||
XRPAmount fee,
|
||||
ReadView const& view,
|
||||
beast::Journal const& j) override;
|
||||
};
|
||||
|
||||
class XChainAddAccountCreateAttestation : public Transactor
|
||||
{
|
||||
public:
|
||||
// Blocker since we cannot accurately calculate the consequences
|
||||
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Blocker;
|
||||
|
||||
explicit XChainAddAccountCreateAttestation(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
|
||||
void
|
||||
visitInvariantEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after) override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
finalizeInvariants(
|
||||
STTx const& tx,
|
||||
TER result,
|
||||
XRPAmount fee,
|
||||
ReadView const& view,
|
||||
beast::Journal const& j) override;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// This is a special transaction used for creating accounts through a
|
||||
// cross-chain transfer. A normal cross-chain transfer requires a "chain claim
|
||||
// id" (which requires an existing account on the destination chain). One
|
||||
// purpose of the "chain claim id" is to prevent transaction replay. For this
|
||||
// transaction, we use a different mechanism: the accounts must be claimed on
|
||||
// the destination chain in the same order that the `XChainCreateAccountCommit`
|
||||
// transactions occurred on the source chain.
|
||||
//
|
||||
// This transaction can only be used for XRP to XRP bridges.
|
||||
//
|
||||
// IMPORTANT: This transaction should only be enabled if the witness
|
||||
// attestations will be reliably delivered to the destination chain. If the
|
||||
// signatures are not delivered (for example, the chain relies on user wallets
|
||||
// to collect signatures) then account creation would be blocked for all
|
||||
// transactions that happened after the one waiting on attestations. This could
|
||||
// be used maliciously. To disable this transaction on XRP to XRP bridges, the
|
||||
// bridge's `MinAccountCreateAmount` should not be present.
|
||||
//
|
||||
// Note: If this account already exists, the XRP is transferred to the existing
|
||||
// account. However, note that unlike the `XChainCommit` transaction, there is
|
||||
// no error handling mechanism. If the claim transaction fails, there is no
|
||||
// mechanism for refunds. The funds are permanently lost. This transaction
|
||||
// should still only be used for account creation.
|
||||
class XChainCreateAccountCommit : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Normal;
|
||||
|
||||
explicit XChainCreateAccountCommit(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
|
||||
void
|
||||
visitInvariantEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after) override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
finalizeInvariants(
|
||||
STTx const& tx,
|
||||
TER result,
|
||||
XRPAmount fee,
|
||||
ReadView const& view,
|
||||
beast::Journal const& j) override;
|
||||
};
|
||||
|
||||
using XChainAccountCreateCommit = XChainCreateAccountCommit;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // namespace xrpl
|
||||
+12
-3
@@ -7,17 +7,26 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (import ./packages.nix { inherit pkgs customGlibc; }) commonPackages;
|
||||
inherit (import ./packages.nix { inherit pkgs customGlibc; }) cacert commonPackages;
|
||||
|
||||
# Each forces something absent on the other platform, so both stay lazy.
|
||||
linux = import ./linux.nix { inherit pkgs customGlibc; };
|
||||
darwin = import ./darwin.nix { inherit pkgs; };
|
||||
|
||||
# Nix-built tools (git, curl, Conan's certifi) read NIX_SSL_CERT_FILE, which
|
||||
# the macOS runners point at their Nix profile's bundle, frozen at install
|
||||
# time. The Linux images set it in nix/docker/Dockerfile.
|
||||
caEnv = {
|
||||
NIX_SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||
};
|
||||
|
||||
# What a buildEnv cannot express: environment variables. $GITHUB_ENV format;
|
||||
# `set -a; . env; set +a` loads it in a shell.
|
||||
darwinEnv = pkgs.writeTextDir "share/xrpld-ci-env/env" (
|
||||
pkgs.lib.concatStrings (
|
||||
pkgs.lib.mapAttrsToList (name: value: "${name}=${value}\n") (darwin.sdkEnv // darwin.libresolvEnv)
|
||||
pkgs.lib.mapAttrsToList (name: value: "${name}=${value}\n") (
|
||||
darwin.sdkEnv // darwin.libresolvEnv // caEnv
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -33,7 +42,7 @@ in
|
||||
++ [
|
||||
# CA certificate bundle so HTTPS clients (git, curl, conan) can verify
|
||||
# TLS connections without ca-certificates being installed in the system.
|
||||
pkgs.cacert
|
||||
cacert
|
||||
];
|
||||
pathsToLink = [
|
||||
"/bin"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{ pkgs, customGlibc, ... }:
|
||||
let
|
||||
inherit (import ./packages.nix { inherit pkgs; })
|
||||
cacert
|
||||
commonPackages
|
||||
gccPackage
|
||||
gccVersion
|
||||
@@ -53,6 +54,17 @@ let
|
||||
unset _xrpl_conan_stamp
|
||||
'';
|
||||
|
||||
# Nix's Python certifi (used by Conan) reads only NIX_SSL_CERT_FILE. Swap
|
||||
# Nix's default profile bundle, frozen at install time, for the patched cacert,
|
||||
# but leave a bundle the user chose (e.g. with a proxy CA) alone.
|
||||
caHook = ''
|
||||
case "''${NIX_SSL_CERT_FILE:-}" in
|
||||
"" | /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt | "$HOME/.nix-profile/etc/ssl/certs/ca-bundle.crt")
|
||||
export NIX_SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
|
||||
;;
|
||||
esac
|
||||
'';
|
||||
|
||||
# Not sdkEnv: a shell's stdenv already sets that up. Prepended so the stub
|
||||
# beats the nixpkgs libresolv this shell's tooling drags in.
|
||||
darwinLibresolvHook = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin (
|
||||
@@ -122,6 +134,7 @@ let
|
||||
echo "Welcome to xrpld development shell";
|
||||
${compilerVersionHook}
|
||||
${darwinLibresolvHook}
|
||||
${caHook}
|
||||
${conanHook}
|
||||
${pkgs.lib.optionalString plain plainWarningHook}
|
||||
'';
|
||||
|
||||
@@ -53,9 +53,11 @@ ENV PATH="/nix/ci-env/bin:${PATH}"
|
||||
|
||||
# Point HTTPS clients (git, curl, conan, ...) at the CA bundle shipped in the
|
||||
# Nix CI environment, so TLS verification works without ca-certificates being
|
||||
# installed in the system.
|
||||
# installed in the system. Nix's Python certifi (used by Conan) reads only
|
||||
# NIX_SSL_CERT_FILE, falling back to its own copy otherwise.
|
||||
ENV SSL_CERT_FILE="/nix/ci-env/etc/ssl/certs/ca-bundle.crt"
|
||||
ENV GIT_SSL_CAINFO="/nix/ci-env/etc/ssl/certs/ca-bundle.crt"
|
||||
ENV NIX_SSL_CERT_FILE="/nix/ci-env/etc/ssl/certs/ca-bundle.crt"
|
||||
|
||||
# Externally-built dynamically-linked ELF binaries hard-code the loader path
|
||||
# (e.g. /lib64/ld-linux-x86-64.so.2) in their PT_INTERP header. Install it
|
||||
@@ -107,7 +109,13 @@ COPY nix/docker/test_files/rust/run-binaries.sh /tmp/test_files/rust/run-binarie
|
||||
COPY --from=final /tmp/cpp-bins /tmp/cpp-bins
|
||||
COPY --from=final /tmp/rust-bins /tmp/rust-bins
|
||||
|
||||
# Sanity-check that the CA bundle shipped in the Nix CI environment distrusts
|
||||
# the compromised eMudhra roots.
|
||||
COPY bin/check-distrusted-roots.sh /tmp/check-distrusted-roots.sh
|
||||
COPY --from=final /nix/ci-env/etc/ssl/certs/ca-bundle.crt /tmp/ca-bundle.crt
|
||||
|
||||
RUN <<EOF
|
||||
/tmp/check-distrusted-roots.sh /tmp/ca-bundle.crt
|
||||
if echo "${BASE_IMAGE}" | grep -qiE 'nixos'; then
|
||||
echo "Skipping runnning binaries on NixOS."
|
||||
else
|
||||
|
||||
@@ -30,6 +30,16 @@ let
|
||||
exec ${pkgs.python3}/bin/python3 ${llvmPackages.clang-unwrapped}/bin/run-clang-tidy "$@"
|
||||
'';
|
||||
|
||||
# Distrusts the roots of the compromised eMudhra intermediates;
|
||||
# see https://emudhra.we-have-a-problem.com/.
|
||||
# TODO: revert to plain pkgs.cacert once nixpkgs ships cacert >= 3.131.1.
|
||||
cacert = pkgs.cacert.override {
|
||||
blacklist = [
|
||||
"Comodo AAA Services root"
|
||||
"emSign ECC Root CA - G3"
|
||||
];
|
||||
};
|
||||
|
||||
# Conan 2.33 is the first release whose settings.yml accepts clang 23.
|
||||
# TODO: drop once nixpkgs ships it.
|
||||
conan = pkgs.conan.overridePythonAttrs (old: {
|
||||
@@ -114,6 +124,7 @@ let
|
||||
in
|
||||
{
|
||||
inherit
|
||||
cacert
|
||||
gccVersion
|
||||
llvmVersion
|
||||
gccPackage
|
||||
|
||||
@@ -13,7 +13,9 @@ Vcs-Browser: https://github.com/XRPLF/rippled
|
||||
|
||||
Package: @PKG@
|
||||
Architecture: any
|
||||
# The default config fetches validator lists over verified HTTPS.
|
||||
Depends:
|
||||
ca-certificates,
|
||||
${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Description: XRP Ledger daemon
|
||||
|
||||
@@ -5,5 +5,9 @@ FROM ${BASE_IMAGE}
|
||||
RUN --mount=type=bind,source=bin/install/packaging-tools.sh,target=/install-packaging-tools.sh \
|
||||
/install-packaging-tools.sh
|
||||
|
||||
# Sanity-check that the system CA bundle distrusts the compromised eMudhra roots.
|
||||
RUN --mount=type=bind,source=bin/check-distrusted-roots.sh,target=/check-distrusted-roots.sh \
|
||||
/check-distrusted-roots.sh
|
||||
|
||||
# See package/README.md, "Publishing from other repositories".
|
||||
COPY package/images/packaging/publish_pkg.py /usr/local/bin/publish_pkg.py
|
||||
@@ -20,6 +20,8 @@ URL: https://github.com/XRPLF/rippled
|
||||
|
||||
ExclusiveArch: x86_64 aarch64
|
||||
BuildRequires: systemd-rpm-macros
|
||||
# The default config fetches validator lists over verified HTTPS.
|
||||
Requires: ca-certificates
|
||||
|
||||
# A variant owns the same paths, so it stands in for the plain package.
|
||||
%if "%{?pkg_variant}" != ""
|
||||
|
||||
@@ -183,23 +183,9 @@ Ledger::Ledger(
|
||||
|
||||
{
|
||||
auto const sle = std::make_shared<SLE>(keylet::feeSettings());
|
||||
// Whether featureXRPFees is supported will depend on startup options.
|
||||
if (std::ranges::find(amendments, featureXRPFees) != amendments.end())
|
||||
{
|
||||
sle->at(sfBaseFeeDrops) = fees.base;
|
||||
sle->at(sfReserveBaseDrops) = fees.reserve;
|
||||
sle->at(sfReserveIncrementDrops) = fees.increment;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto const f = fees.base.dropsAs<std::uint64_t>())
|
||||
sle->at(sfBaseFee) = *f;
|
||||
if (auto const f = fees.reserve.dropsAs<std::uint32_t>())
|
||||
sle->at(sfReserveBase) = *f;
|
||||
if (auto const f = fees.increment.dropsAs<std::uint32_t>())
|
||||
sle->at(sfReserveIncrement) = *f;
|
||||
sle->at(sfReferenceFeeUnits) = kFeeUnitsDeprecated;
|
||||
}
|
||||
sle->at(sfBaseFeeDrops) = fees.base;
|
||||
sle->at(sfReserveBaseDrops) = fees.reserve;
|
||||
sle->at(sfReserveIncrementDrops) = fees.increment;
|
||||
if (std::ranges::find(amendments, featureSmartEscrow) != amendments.end())
|
||||
{
|
||||
sle->at(sfGasLimit) = fees.gasLimit;
|
||||
@@ -677,11 +663,6 @@ Ledger::setup()
|
||||
// Should be all of one or the other, but not both
|
||||
ret = false;
|
||||
}
|
||||
if (!rules_.enabled(featureXRPFees) && newFees)
|
||||
{
|
||||
// Can't populate the new fees before the amendment is enabled
|
||||
ret = false;
|
||||
}
|
||||
if (!rules_.enabled(featureSmartEscrow) && extensionFees)
|
||||
{
|
||||
// Can't populate the extension fees before the amendment is
|
||||
|
||||
@@ -43,6 +43,9 @@ constexpr auto kProposalTxTypes = std::to_array<TxType>({
|
||||
bool
|
||||
isValidProposalTxnType(STObject const& proposedTx)
|
||||
{
|
||||
if (!proposedTx.isFieldPresent(sfTransactionType))
|
||||
return false;
|
||||
|
||||
auto const type = proposedTx.getFieldU16(sfTransactionType);
|
||||
|
||||
if (std::ranges::find(kProposalTxTypes, type) != kProposalTxTypes.end())
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Concepts.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STInteger.h> // IWYU pragma: keep
|
||||
@@ -125,10 +123,4 @@ ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot)
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool
|
||||
ammEnabled(Rules const& rules)
|
||||
{
|
||||
return rules.enabled(featureAMM);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -12,8 +12,6 @@
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
@@ -105,9 +103,6 @@ enum class LedgerNameSpace : std::uint16_t {
|
||||
NftokenBuyOffers = 'h',
|
||||
NftokenSellOffers = 'i',
|
||||
Amm = 'A',
|
||||
Bridge = 'H',
|
||||
XchainClaimId = 'Q',
|
||||
XchainCreateAccountClaimId = 'K',
|
||||
Did = 'I',
|
||||
Oracle = 'R',
|
||||
MPTokenIssuance = '~',
|
||||
@@ -125,6 +120,9 @@ enum class LedgerNameSpace : std::uint16_t {
|
||||
Contract [[deprecated]] = 'c',
|
||||
Generator [[deprecated]] = 'g',
|
||||
Nickname [[deprecated]] = 'n',
|
||||
Bridge [[deprecated]] = 'H',
|
||||
XchainClaimId [[deprecated]] = 'Q',
|
||||
XchainCreateAccountClaimId [[deprecated]] = 'K',
|
||||
};
|
||||
|
||||
template <class... Args>
|
||||
@@ -527,44 +525,6 @@ delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept
|
||||
return {ltDELEGATE, indexHash(LedgerNameSpace::Delegate, account, authorizedAccount)};
|
||||
}
|
||||
|
||||
Keylet
|
||||
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType)
|
||||
{
|
||||
// A door account can support multiple bridges. On the locking chain
|
||||
// there can only be one bridge per lockingChainCurrency. On the issuing
|
||||
// chain there can only be one bridge per issuingChainCurrency.
|
||||
auto const& issue = bridge.issue(chainType);
|
||||
return {ltBRIDGE, indexHash(LedgerNameSpace::Bridge, bridge.door(chainType), issue.currency)};
|
||||
}
|
||||
|
||||
Keylet
|
||||
xChainClaimID(STXChainBridge const& bridge, std::uint64_t const seq)
|
||||
{
|
||||
return {
|
||||
ltXCHAIN_OWNED_CLAIM_ID,
|
||||
indexHash(
|
||||
LedgerNameSpace::XchainClaimId,
|
||||
bridge.lockingChainDoor(),
|
||||
bridge.lockingChainIssue(),
|
||||
bridge.issuingChainDoor(),
|
||||
bridge.issuingChainIssue(),
|
||||
seq)};
|
||||
}
|
||||
|
||||
Keylet
|
||||
xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t const seq)
|
||||
{
|
||||
return {
|
||||
ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID,
|
||||
indexHash(
|
||||
LedgerNameSpace::XchainCreateAccountClaimId,
|
||||
bridge.lockingChainDoor(),
|
||||
bridge.lockingChainIssue(),
|
||||
bridge.issuingChainDoor(),
|
||||
bridge.issuingChainIssue(),
|
||||
seq)};
|
||||
}
|
||||
|
||||
Keylet
|
||||
did(AccountID const& account) noexcept
|
||||
{
|
||||
|
||||
@@ -65,58 +65,6 @@ InnerObjectFormats::InnerObjectFormats()
|
||||
{sfAuthAccounts, SoeOptional},
|
||||
});
|
||||
|
||||
add(sfXChainClaimAttestationCollectionElement.jsonName,
|
||||
sfXChainClaimAttestationCollectionElement.getCode(),
|
||||
{
|
||||
{sfAttestationSignerAccount, SoeRequired},
|
||||
{sfPublicKey, SoeRequired},
|
||||
{sfSignature, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfAccount, SoeRequired},
|
||||
{sfAttestationRewardAccount, SoeRequired},
|
||||
{sfWasLockingChainSend, SoeRequired},
|
||||
{sfXChainClaimID, SoeRequired},
|
||||
{sfDestination, SoeOptional},
|
||||
});
|
||||
|
||||
add(sfXChainCreateAccountAttestationCollectionElement.jsonName,
|
||||
sfXChainCreateAccountAttestationCollectionElement.getCode(),
|
||||
{
|
||||
{sfAttestationSignerAccount, SoeRequired},
|
||||
{sfPublicKey, SoeRequired},
|
||||
{sfSignature, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfAccount, SoeRequired},
|
||||
{sfAttestationRewardAccount, SoeRequired},
|
||||
{sfWasLockingChainSend, SoeRequired},
|
||||
{sfXChainAccountCreateCount, SoeRequired},
|
||||
{sfDestination, SoeRequired},
|
||||
{sfSignatureReward, SoeRequired},
|
||||
});
|
||||
|
||||
add(sfXChainClaimProofSig.jsonName,
|
||||
sfXChainClaimProofSig.getCode(),
|
||||
{
|
||||
{sfAttestationSignerAccount, SoeRequired},
|
||||
{sfPublicKey, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfAttestationRewardAccount, SoeRequired},
|
||||
{sfWasLockingChainSend, SoeRequired},
|
||||
{sfDestination, SoeOptional},
|
||||
});
|
||||
|
||||
add(sfXChainCreateAccountProofSig.jsonName,
|
||||
sfXChainCreateAccountProofSig.getCode(),
|
||||
{
|
||||
{sfAttestationSignerAccount, SoeRequired},
|
||||
{sfPublicKey, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfSignatureReward, SoeRequired},
|
||||
{sfAttestationRewardAccount, SoeRequired},
|
||||
{sfWasLockingChainSend, SoeRequired},
|
||||
{sfDestination, SoeRequired},
|
||||
});
|
||||
|
||||
add(sfAuthAccount.jsonName,
|
||||
sfAuthAccount.getCode(),
|
||||
{
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/STIssue.h>
|
||||
#include <xrpl/protocol/STNumber.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/STPathSet.h>
|
||||
#include <xrpl/protocol/STVector256.h>
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
@@ -956,18 +956,6 @@ parseLeaf(
|
||||
}
|
||||
break;
|
||||
|
||||
case STI_XCHAIN_BRIDGE:
|
||||
try
|
||||
{
|
||||
ret = detail::makeStvar<STXChainBridge>(STXChainBridge(field, value));
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
error = invalidData(jsonName, fieldName);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case STI_CURRENCY:
|
||||
try
|
||||
{
|
||||
|
||||
@@ -47,9 +47,6 @@ STValidation::validationFormat()
|
||||
{sfCloseTime, SoeOptional},
|
||||
{sfLoadFee, SoeOptional},
|
||||
{sfAmendments, SoeOptional},
|
||||
{sfBaseFee, SoeOptional},
|
||||
{sfReserveBase, SoeOptional},
|
||||
{sfReserveIncrement, SoeOptional},
|
||||
{sfSigningTime, SoeRequired},
|
||||
{sfSigningPubKey, SoeRequired},
|
||||
{sfSignature, SoeRequired},
|
||||
@@ -57,7 +54,6 @@ STValidation::validationFormat()
|
||||
{sfCookie, SoeDefault},
|
||||
{sfValidatedHash, SoeOptional},
|
||||
{sfServerVersion, SoeOptional},
|
||||
// featureXRPFees
|
||||
{sfBaseFeeDrops, SoeOptional},
|
||||
{sfReserveBaseDrops, SoeOptional},
|
||||
{sfReserveIncrementDrops, SoeOptional},
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/STPathSet.h>
|
||||
#include <xrpl/protocol/STVector256.h>
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
|
||||
#include <stdexcept>
|
||||
@@ -217,9 +216,6 @@ STVar::constructST(SerializedTypeID id, int depth, Args&&... args)
|
||||
case STI_ISSUE:
|
||||
construct<STIssue>(std::forward<Args>(args)...);
|
||||
return;
|
||||
case STI_XCHAIN_BRIDGE:
|
||||
construct<STXChainBridge>(std::forward<Args>(args)...);
|
||||
return;
|
||||
case STI_CURRENCY:
|
||||
construct<STCurrency>(std::forward<Args>(args)...);
|
||||
return;
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
#include <xrpl/protocol/STXChainBridge.h>
|
||||
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAccount.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <format>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
STXChainBridge::STXChainBridge() : STBase{sfXChainBridge}
|
||||
{
|
||||
}
|
||||
|
||||
STXChainBridge::STXChainBridge(SField const& name) : STBase{name}
|
||||
{
|
||||
}
|
||||
|
||||
STXChainBridge::STXChainBridge(
|
||||
AccountID const& srcChainDoor,
|
||||
Issue const& srcChainIssue,
|
||||
AccountID const& dstChainDoor,
|
||||
Issue const& dstChainIssue)
|
||||
: STBase{sfXChainBridge}
|
||||
, lockingChainDoor_{sfLockingChainDoor, srcChainDoor}
|
||||
, lockingChainIssue_{sfLockingChainIssue, srcChainIssue}
|
||||
, issuingChainDoor_{sfIssuingChainDoor, dstChainDoor}
|
||||
, issuingChainIssue_{sfIssuingChainIssue, dstChainIssue}
|
||||
{
|
||||
}
|
||||
|
||||
STXChainBridge::STXChainBridge(STObject const& o)
|
||||
: STBase{sfXChainBridge}
|
||||
, lockingChainDoor_{sfLockingChainDoor, o[sfLockingChainDoor]}
|
||||
, lockingChainIssue_{sfLockingChainIssue, o[sfLockingChainIssue]}
|
||||
, issuingChainDoor_{sfIssuingChainDoor, o[sfIssuingChainDoor]}
|
||||
, issuingChainIssue_{sfIssuingChainIssue, o[sfIssuingChainIssue]}
|
||||
{
|
||||
}
|
||||
|
||||
STXChainBridge::STXChainBridge(json::Value const& v) : STXChainBridge{sfXChainBridge, v}
|
||||
{
|
||||
}
|
||||
|
||||
STXChainBridge::STXChainBridge(SField const& name, json::Value const& v) : STBase{name}
|
||||
{
|
||||
if (!v.isObject())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"STXChainBridge can only be specified with a 'object' Json value");
|
||||
}
|
||||
|
||||
auto const checkExtra = [](json::Value const& v) {
|
||||
static auto const kBridgeJson =
|
||||
xrpl::STXChainBridge().getJson(xrpl::JsonOptions::Values::None);
|
||||
for (auto it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
std::string const name = it.memberName();
|
||||
if (!kBridgeJson.isMember(name))
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
std::format("STXChainBridge extra field detected: {}", name));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
checkExtra(v);
|
||||
|
||||
json::Value const& lockingChainDoorStr = v[jss::LockingChainDoor];
|
||||
json::Value const& lockingChainIssue = v[jss::LockingChainIssue];
|
||||
json::Value const& issuingChainDoorStr = v[jss::IssuingChainDoor];
|
||||
json::Value const& issuingChainIssue = v[jss::IssuingChainIssue];
|
||||
|
||||
if (!lockingChainDoorStr.isString())
|
||||
{
|
||||
Throw<std::runtime_error>("STXChainBridge LockingChainDoor must be a string Json value");
|
||||
}
|
||||
if (!issuingChainDoorStr.isString())
|
||||
{
|
||||
Throw<std::runtime_error>("STXChainBridge IssuingChainDoor must be a string Json value");
|
||||
}
|
||||
|
||||
auto const lockingChainDoor = parseBase58<AccountID>(lockingChainDoorStr.asString());
|
||||
auto const issuingChainDoor = parseBase58<AccountID>(issuingChainDoorStr.asString());
|
||||
if (!lockingChainDoor)
|
||||
{
|
||||
Throw<std::runtime_error>("STXChainBridge LockingChainDoor must be a valid account");
|
||||
}
|
||||
if (!issuingChainDoor)
|
||||
{
|
||||
Throw<std::runtime_error>("STXChainBridge IssuingChainDoor must be a valid account");
|
||||
}
|
||||
|
||||
lockingChainDoor_ = STAccount{sfLockingChainDoor, *lockingChainDoor};
|
||||
lockingChainIssue_ = STIssue{sfLockingChainIssue, issueFromJson(lockingChainIssue)};
|
||||
issuingChainDoor_ = STAccount{sfIssuingChainDoor, *issuingChainDoor};
|
||||
issuingChainIssue_ = STIssue{sfIssuingChainIssue, issueFromJson(issuingChainIssue)};
|
||||
}
|
||||
|
||||
STXChainBridge::STXChainBridge(SerialIter& sit, SField const& name)
|
||||
: STBase{name}
|
||||
, lockingChainDoor_{sit, sfLockingChainDoor}
|
||||
, lockingChainIssue_{sit, sfLockingChainIssue}
|
||||
, issuingChainDoor_{sit, sfIssuingChainDoor}
|
||||
, issuingChainIssue_{sit, sfIssuingChainIssue}
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
STXChainBridge::add(Serializer& s) const
|
||||
{
|
||||
lockingChainDoor_.add(s);
|
||||
lockingChainIssue_.add(s);
|
||||
issuingChainDoor_.add(s);
|
||||
issuingChainIssue_.add(s);
|
||||
}
|
||||
|
||||
json::Value
|
||||
STXChainBridge::getJson(JsonOptions jo) const
|
||||
{
|
||||
json::Value v;
|
||||
v[jss::LockingChainDoor] = lockingChainDoor_.getJson(jo);
|
||||
v[jss::LockingChainIssue] = lockingChainIssue_.getJson(jo);
|
||||
v[jss::IssuingChainDoor] = issuingChainDoor_.getJson(jo);
|
||||
v[jss::IssuingChainIssue] = issuingChainIssue_.getJson(jo);
|
||||
return v;
|
||||
}
|
||||
|
||||
std::string
|
||||
STXChainBridge::getText() const
|
||||
{
|
||||
return std::format(
|
||||
"{{ {} = {}, {} = {}, {} = {}, {} = {} }}",
|
||||
sfLockingChainDoor.getName(),
|
||||
lockingChainDoor_.getText(),
|
||||
sfLockingChainIssue.getName(),
|
||||
lockingChainIssue_.getText(),
|
||||
sfIssuingChainDoor.getName(),
|
||||
issuingChainDoor_.getText(),
|
||||
sfIssuingChainIssue.getName(),
|
||||
issuingChainIssue_.getText());
|
||||
}
|
||||
|
||||
STObject
|
||||
STXChainBridge::toSTObject() const
|
||||
{
|
||||
STObject o{sfXChainBridge};
|
||||
o[sfLockingChainDoor] = lockingChainDoor_;
|
||||
o[sfLockingChainIssue] = lockingChainIssue_;
|
||||
o[sfIssuingChainDoor] = issuingChainDoor_;
|
||||
o[sfIssuingChainIssue] = issuingChainIssue_;
|
||||
return o;
|
||||
}
|
||||
|
||||
SerializedTypeID
|
||||
STXChainBridge::getSType() const
|
||||
{
|
||||
return STI_XCHAIN_BRIDGE;
|
||||
}
|
||||
|
||||
bool
|
||||
STXChainBridge::isEquivalent(STBase const& t) const
|
||||
{
|
||||
auto const* v = dynamic_cast<STXChainBridge const*>(&t);
|
||||
return (v != nullptr) && (*v == *this);
|
||||
}
|
||||
|
||||
bool
|
||||
STXChainBridge::isDefault() const
|
||||
{
|
||||
return lockingChainDoor_.isDefault() && lockingChainIssue_.isDefault() &&
|
||||
issuingChainDoor_.isDefault() && issuingChainIssue_.isDefault();
|
||||
}
|
||||
|
||||
std::unique_ptr<STXChainBridge>
|
||||
STXChainBridge::construct(SerialIter& sit, SField const& name)
|
||||
{
|
||||
return std::make_unique<STXChainBridge>(sit, name);
|
||||
}
|
||||
|
||||
STBase*
|
||||
STXChainBridge::copy(std::size_t n, void* buf) const
|
||||
{
|
||||
return emplace(n, buf, *this);
|
||||
}
|
||||
|
||||
STBase*
|
||||
STXChainBridge::move(std::size_t n, void* buf)
|
||||
{
|
||||
return emplace(n, buf, std::move(*this));
|
||||
}
|
||||
} // namespace xrpl
|
||||
@@ -1,706 +0,0 @@
|
||||
#include <xrpl/protocol/XChainAttestations.h>
|
||||
|
||||
#include <xrpl/basics/Buffer.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAccount.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STArray.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/SecretKey.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/json_get_or_throw.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
namespace attestations {
|
||||
|
||||
AttestationBase::AttestationBase(
|
||||
AccountID attestationSignerAccount,
|
||||
PublicKey const& publicKey,
|
||||
Buffer signature,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount sendingAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend)
|
||||
: attestationSignerAccount{attestationSignerAccount}
|
||||
, publicKey{publicKey}
|
||||
, signature{std::move(signature)}
|
||||
, sendingAccount{sendingAccount}
|
||||
, sendingAmount{std::move(sendingAmount)}
|
||||
, rewardAccount{rewardAccount}
|
||||
, wasLockingChainSend{wasLockingChainSend}
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
AttestationBase::equalHelper(AttestationBase const& lhs, AttestationBase const& rhs)
|
||||
{
|
||||
return std::tie(
|
||||
lhs.attestationSignerAccount,
|
||||
lhs.publicKey,
|
||||
lhs.signature,
|
||||
lhs.sendingAccount,
|
||||
lhs.sendingAmount,
|
||||
lhs.rewardAccount,
|
||||
lhs.wasLockingChainSend) ==
|
||||
std::tie(
|
||||
rhs.attestationSignerAccount,
|
||||
rhs.publicKey,
|
||||
rhs.signature,
|
||||
rhs.sendingAccount,
|
||||
rhs.sendingAmount,
|
||||
rhs.rewardAccount,
|
||||
rhs.wasLockingChainSend);
|
||||
}
|
||||
|
||||
bool
|
||||
AttestationBase::sameEventHelper(AttestationBase const& lhs, AttestationBase const& rhs)
|
||||
{
|
||||
return std::tie(lhs.sendingAccount, lhs.sendingAmount, lhs.wasLockingChainSend) ==
|
||||
std::tie(rhs.sendingAccount, rhs.sendingAmount, rhs.wasLockingChainSend);
|
||||
}
|
||||
|
||||
bool
|
||||
AttestationBase::verify(STXChainBridge const& bridge) const
|
||||
{
|
||||
std::vector<std::uint8_t> const msg = message(bridge);
|
||||
return xrpl::verify(publicKey, makeSlice(msg), signature);
|
||||
}
|
||||
|
||||
AttestationBase::AttestationBase(STObject const& o)
|
||||
: attestationSignerAccount{o[sfAttestationSignerAccount]}
|
||||
, publicKey{o[sfPublicKey]}
|
||||
, signature{o[sfSignature]}
|
||||
, sendingAccount{o[sfAccount]}
|
||||
, sendingAmount{o[sfAmount]}
|
||||
, rewardAccount{o[sfAttestationRewardAccount]}
|
||||
, wasLockingChainSend{bool(o[sfWasLockingChainSend])}
|
||||
{
|
||||
}
|
||||
|
||||
AttestationBase::AttestationBase(json::Value const& v)
|
||||
: attestationSignerAccount{json::getOrThrow<AccountID>(v, sfAttestationSignerAccount)}
|
||||
, publicKey{json::getOrThrow<PublicKey>(v, sfPublicKey)}
|
||||
, signature{json::getOrThrow<Buffer>(v, sfSignature)}
|
||||
, sendingAccount{json::getOrThrow<AccountID>(v, sfAccount)}
|
||||
, sendingAmount{json::getOrThrow<STAmount>(v, sfAmount)}
|
||||
, rewardAccount{json::getOrThrow<AccountID>(v, sfAttestationRewardAccount)}
|
||||
, wasLockingChainSend{json::getOrThrow<bool>(v, sfWasLockingChainSend)}
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AttestationBase::addHelper(STObject& o) const
|
||||
{
|
||||
o[sfAttestationSignerAccount] = attestationSignerAccount;
|
||||
o[sfPublicKey] = publicKey;
|
||||
o[sfSignature] = signature;
|
||||
o[sfAmount] = sendingAmount;
|
||||
o[sfAccount] = sendingAccount;
|
||||
o[sfAttestationRewardAccount] = rewardAccount;
|
||||
o[sfWasLockingChainSend] = wasLockingChainSend;
|
||||
}
|
||||
|
||||
AttestationClaim::AttestationClaim(
|
||||
AccountID attestationSignerAccount,
|
||||
PublicKey const& publicKey,
|
||||
Buffer signature,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t claimId,
|
||||
std::optional<AccountID> const& dst)
|
||||
: AttestationBase(
|
||||
attestationSignerAccount,
|
||||
publicKey,
|
||||
std::move(signature),
|
||||
sendingAccount,
|
||||
sendingAmount,
|
||||
rewardAccount,
|
||||
wasLockingChainSend)
|
||||
, claimID{claimId}
|
||||
, dst{dst}
|
||||
{
|
||||
}
|
||||
|
||||
AttestationClaim::AttestationClaim(
|
||||
STXChainBridge const& bridge,
|
||||
AccountID attestationSignerAccount,
|
||||
PublicKey const& publicKey,
|
||||
SecretKey const& secretKey,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t claimId,
|
||||
std::optional<AccountID> const& dst)
|
||||
: AttestationClaim{
|
||||
attestationSignerAccount,
|
||||
publicKey,
|
||||
Buffer{},
|
||||
sendingAccount,
|
||||
sendingAmount,
|
||||
rewardAccount,
|
||||
wasLockingChainSend,
|
||||
claimId,
|
||||
dst}
|
||||
{
|
||||
auto const toSign = message(bridge);
|
||||
signature = sign(publicKey, secretKey, makeSlice(toSign));
|
||||
}
|
||||
|
||||
AttestationClaim::AttestationClaim(STObject const& o)
|
||||
: AttestationBase(o), claimID{o[sfXChainClaimID]}, dst{o[~sfDestination]}
|
||||
{
|
||||
}
|
||||
|
||||
AttestationClaim::AttestationClaim(json::Value const& v)
|
||||
: AttestationBase{v}, claimID{json::getOrThrow<std::uint64_t>(v, sfXChainClaimID)}
|
||||
{
|
||||
if (v.isMember(sfDestination.getJsonName()))
|
||||
dst = json::getOrThrow<AccountID>(v, sfDestination);
|
||||
}
|
||||
|
||||
STObject
|
||||
AttestationClaim::toSTObject() const
|
||||
{
|
||||
STObject o = STObject::makeInnerObject(sfXChainClaimAttestationCollectionElement);
|
||||
addHelper(o);
|
||||
o[sfXChainClaimID] = claimID;
|
||||
if (dst)
|
||||
o[sfDestination] = *dst;
|
||||
return o;
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t>
|
||||
AttestationClaim::message(
|
||||
STXChainBridge const& bridge,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t claimID,
|
||||
std::optional<AccountID> const& dst)
|
||||
{
|
||||
STObject o{sfGeneric};
|
||||
// Serialize in SField order to make python serializers easier to write
|
||||
o[sfXChainClaimID] = claimID;
|
||||
o[sfAmount] = sendingAmount;
|
||||
if (dst)
|
||||
o[sfDestination] = *dst;
|
||||
o[sfOtherChainSource] = sendingAccount;
|
||||
o[sfAttestationRewardAccount] = rewardAccount;
|
||||
o[sfWasLockingChainSend] = wasLockingChainSend ? 1 : 0;
|
||||
o[sfXChainBridge] = bridge;
|
||||
|
||||
Serializer s;
|
||||
o.add(s);
|
||||
|
||||
return std::move(s.modData());
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t>
|
||||
AttestationClaim::message(STXChainBridge const& bridge) const
|
||||
{
|
||||
return AttestationClaim::message(
|
||||
bridge, sendingAccount, sendingAmount, rewardAccount, wasLockingChainSend, claimID, dst);
|
||||
}
|
||||
|
||||
bool
|
||||
AttestationClaim::validAmounts() const
|
||||
{
|
||||
return isLegalNet(sendingAmount);
|
||||
}
|
||||
|
||||
bool
|
||||
AttestationClaim::sameEvent(AttestationClaim const& rhs) const
|
||||
{
|
||||
return AttestationClaim::sameEventHelper(*this, rhs) &&
|
||||
tie(claimID, dst) == tie(rhs.claimID, rhs.dst);
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(AttestationClaim const& lhs, AttestationClaim const& rhs)
|
||||
{
|
||||
return AttestationClaim::equalHelper(lhs, rhs) &&
|
||||
tie(lhs.claimID, lhs.dst) == tie(rhs.claimID, rhs.dst);
|
||||
}
|
||||
|
||||
AttestationCreateAccount::AttestationCreateAccount(STObject const& o)
|
||||
: AttestationBase(o)
|
||||
, createCount{o[sfXChainAccountCreateCount]}
|
||||
, toCreate{o[sfDestination]}
|
||||
, rewardAmount{o[sfSignatureReward]}
|
||||
{
|
||||
}
|
||||
|
||||
AttestationCreateAccount::AttestationCreateAccount(json::Value const& v)
|
||||
: AttestationBase{v}
|
||||
, createCount{json::getOrThrow<std::uint64_t>(v, sfXChainAccountCreateCount)}
|
||||
, toCreate{json::getOrThrow<AccountID>(v, sfDestination)}
|
||||
, rewardAmount{json::getOrThrow<STAmount>(v, sfSignatureReward)}
|
||||
{
|
||||
}
|
||||
|
||||
AttestationCreateAccount::AttestationCreateAccount(
|
||||
AccountID attestationSignerAccount,
|
||||
PublicKey const& publicKey,
|
||||
Buffer signature,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
STAmount rewardAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t createCount,
|
||||
AccountID const& toCreate)
|
||||
: AttestationBase(
|
||||
attestationSignerAccount,
|
||||
publicKey,
|
||||
std::move(signature),
|
||||
sendingAccount,
|
||||
sendingAmount,
|
||||
rewardAccount,
|
||||
wasLockingChainSend)
|
||||
, createCount{createCount}
|
||||
, toCreate{toCreate}
|
||||
, rewardAmount{std::move(rewardAmount)}
|
||||
{
|
||||
}
|
||||
|
||||
AttestationCreateAccount::AttestationCreateAccount(
|
||||
STXChainBridge const& bridge,
|
||||
AccountID attestationSignerAccount,
|
||||
PublicKey const& publicKey,
|
||||
SecretKey const& secretKey,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
STAmount const& rewardAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t createCount,
|
||||
AccountID const& toCreate)
|
||||
: AttestationCreateAccount{
|
||||
attestationSignerAccount,
|
||||
publicKey,
|
||||
Buffer{},
|
||||
sendingAccount,
|
||||
sendingAmount,
|
||||
rewardAmount,
|
||||
rewardAccount,
|
||||
wasLockingChainSend,
|
||||
createCount,
|
||||
toCreate}
|
||||
{
|
||||
auto const toSign = message(bridge);
|
||||
signature = sign(publicKey, secretKey, makeSlice(toSign));
|
||||
}
|
||||
|
||||
STObject
|
||||
AttestationCreateAccount::toSTObject() const
|
||||
{
|
||||
STObject o = STObject::makeInnerObject(sfXChainCreateAccountAttestationCollectionElement);
|
||||
addHelper(o);
|
||||
|
||||
o[sfXChainAccountCreateCount] = createCount;
|
||||
o[sfDestination] = toCreate;
|
||||
o[sfSignatureReward] = rewardAmount;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t>
|
||||
AttestationCreateAccount::message(
|
||||
STXChainBridge const& bridge,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
STAmount const& rewardAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t createCount,
|
||||
AccountID const& dst)
|
||||
{
|
||||
STObject o{sfGeneric};
|
||||
// Serialize in SField order to make python serializers easier to write
|
||||
o[sfXChainAccountCreateCount] = createCount;
|
||||
o[sfAmount] = sendingAmount;
|
||||
o[sfSignatureReward] = rewardAmount;
|
||||
o[sfDestination] = dst;
|
||||
o[sfOtherChainSource] = sendingAccount;
|
||||
o[sfAttestationRewardAccount] = rewardAccount;
|
||||
o[sfWasLockingChainSend] = wasLockingChainSend ? 1 : 0;
|
||||
o[sfXChainBridge] = bridge;
|
||||
|
||||
Serializer s;
|
||||
o.add(s);
|
||||
|
||||
return std::move(s.modData());
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t>
|
||||
AttestationCreateAccount::message(STXChainBridge const& bridge) const
|
||||
{
|
||||
return AttestationCreateAccount::message(
|
||||
bridge,
|
||||
sendingAccount,
|
||||
sendingAmount,
|
||||
rewardAmount,
|
||||
rewardAccount,
|
||||
wasLockingChainSend,
|
||||
createCount,
|
||||
toCreate);
|
||||
}
|
||||
|
||||
bool
|
||||
AttestationCreateAccount::validAmounts() const
|
||||
{
|
||||
return isLegalNet(rewardAmount) && isLegalNet(sendingAmount);
|
||||
}
|
||||
|
||||
bool
|
||||
AttestationCreateAccount::sameEvent(AttestationCreateAccount const& rhs) const
|
||||
{
|
||||
return AttestationCreateAccount::sameEventHelper(*this, rhs) &&
|
||||
std::tie(createCount, toCreate, rewardAmount) ==
|
||||
std::tie(rhs.createCount, rhs.toCreate, rhs.rewardAmount);
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(AttestationCreateAccount const& lhs, AttestationCreateAccount const& rhs)
|
||||
{
|
||||
return AttestationCreateAccount::equalHelper(lhs, rhs) &&
|
||||
std::tie(lhs.createCount, lhs.toCreate, lhs.rewardAmount) ==
|
||||
std::tie(rhs.createCount, rhs.toCreate, rhs.rewardAmount);
|
||||
}
|
||||
|
||||
} // namespace attestations
|
||||
|
||||
SField const& XChainClaimAttestation::arrayFieldName{sfXChainClaimAttestations};
|
||||
SField const& XChainCreateAccountAttestation::arrayFieldName{sfXChainCreateAccountAttestations};
|
||||
|
||||
XChainClaimAttestation::XChainClaimAttestation(
|
||||
AccountID const& keyAccount,
|
||||
PublicKey const& publicKey,
|
||||
STAmount const& amount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::optional<AccountID> const& dst)
|
||||
: keyAccount(keyAccount)
|
||||
, publicKey(publicKey)
|
||||
, amount(sfAmount, amount)
|
||||
, rewardAccount(rewardAccount)
|
||||
, wasLockingChainSend(wasLockingChainSend)
|
||||
, dst(dst)
|
||||
{
|
||||
}
|
||||
|
||||
XChainClaimAttestation::XChainClaimAttestation(
|
||||
STAccount const& keyAccount,
|
||||
PublicKey const& publicKey,
|
||||
STAmount const& amount,
|
||||
STAccount const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::optional<STAccount> const& dst)
|
||||
: XChainClaimAttestation{
|
||||
keyAccount.value(),
|
||||
publicKey,
|
||||
amount,
|
||||
rewardAccount.value(),
|
||||
wasLockingChainSend,
|
||||
dst ? std::optional<AccountID>{dst->value()} : std::nullopt}
|
||||
{
|
||||
}
|
||||
|
||||
XChainClaimAttestation::XChainClaimAttestation(STObject const& o)
|
||||
: XChainClaimAttestation{
|
||||
o[sfAttestationSignerAccount],
|
||||
PublicKey{o[sfPublicKey]},
|
||||
o[sfAmount],
|
||||
o[sfAttestationRewardAccount],
|
||||
o[sfWasLockingChainSend] != 0,
|
||||
o[~sfDestination]} {};
|
||||
|
||||
XChainClaimAttestation::XChainClaimAttestation(json::Value const& v)
|
||||
: XChainClaimAttestation{
|
||||
json::getOrThrow<AccountID>(v, sfAttestationSignerAccount),
|
||||
json::getOrThrow<PublicKey>(v, sfPublicKey),
|
||||
json::getOrThrow<STAmount>(v, sfAmount),
|
||||
json::getOrThrow<AccountID>(v, sfAttestationRewardAccount),
|
||||
json::getOrThrow<bool>(v, sfWasLockingChainSend),
|
||||
std::nullopt}
|
||||
{
|
||||
if (v.isMember(sfDestination.getJsonName()))
|
||||
dst = json::getOrThrow<AccountID>(v, sfDestination);
|
||||
};
|
||||
|
||||
XChainClaimAttestation::XChainClaimAttestation(
|
||||
XChainClaimAttestation::TSignedAttestation const& claimAtt)
|
||||
: XChainClaimAttestation{
|
||||
claimAtt.attestationSignerAccount,
|
||||
claimAtt.publicKey,
|
||||
claimAtt.sendingAmount,
|
||||
claimAtt.rewardAccount,
|
||||
claimAtt.wasLockingChainSend,
|
||||
claimAtt.dst}
|
||||
{
|
||||
}
|
||||
|
||||
STObject
|
||||
XChainClaimAttestation::toSTObject() const
|
||||
{
|
||||
STObject o = STObject::makeInnerObject(sfXChainClaimProofSig);
|
||||
o[sfAttestationSignerAccount] = STAccount{sfAttestationSignerAccount, keyAccount};
|
||||
o[sfPublicKey] = publicKey;
|
||||
o[sfAmount] = STAmount{sfAmount, amount};
|
||||
o[sfAttestationRewardAccount] = STAccount{sfAttestationRewardAccount, rewardAccount};
|
||||
o[sfWasLockingChainSend] = wasLockingChainSend;
|
||||
if (dst)
|
||||
o[sfDestination] = STAccount{sfDestination, *dst};
|
||||
return o;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(XChainClaimAttestation const& lhs, XChainClaimAttestation const& rhs)
|
||||
{
|
||||
return std::tie(
|
||||
lhs.keyAccount,
|
||||
lhs.publicKey,
|
||||
lhs.amount,
|
||||
lhs.rewardAccount,
|
||||
lhs.wasLockingChainSend,
|
||||
lhs.dst) ==
|
||||
std::tie(
|
||||
rhs.keyAccount,
|
||||
rhs.publicKey,
|
||||
rhs.amount,
|
||||
rhs.rewardAccount,
|
||||
rhs.wasLockingChainSend,
|
||||
rhs.dst);
|
||||
}
|
||||
|
||||
XChainClaimAttestation::MatchFields::MatchFields(
|
||||
XChainClaimAttestation::TSignedAttestation const& att)
|
||||
: amount{att.sendingAmount}, wasLockingChainSend{att.wasLockingChainSend}, dst{att.dst}
|
||||
{
|
||||
}
|
||||
|
||||
AttestationMatch
|
||||
XChainClaimAttestation::match(XChainClaimAttestation::MatchFields const& rhs) const
|
||||
{
|
||||
if (std::tie(amount, wasLockingChainSend) != std::tie(rhs.amount, rhs.wasLockingChainSend))
|
||||
return AttestationMatch::NonDstMismatch;
|
||||
if (dst != rhs.dst)
|
||||
return AttestationMatch::MatchExceptDst;
|
||||
return AttestationMatch::Match;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
XChainCreateAccountAttestation::XChainCreateAccountAttestation(
|
||||
AccountID const& keyAccount,
|
||||
PublicKey const& publicKey,
|
||||
STAmount const& amount,
|
||||
STAmount const& rewardAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
AccountID const& dst)
|
||||
: keyAccount(keyAccount)
|
||||
, publicKey(publicKey)
|
||||
, amount(sfAmount, amount)
|
||||
, rewardAmount(sfSignatureReward, rewardAmount)
|
||||
, rewardAccount(rewardAccount)
|
||||
, wasLockingChainSend(wasLockingChainSend)
|
||||
, dst(dst)
|
||||
{
|
||||
}
|
||||
|
||||
XChainCreateAccountAttestation::XChainCreateAccountAttestation(STObject const& o)
|
||||
: XChainCreateAccountAttestation{
|
||||
o[sfAttestationSignerAccount],
|
||||
PublicKey{o[sfPublicKey]},
|
||||
o[sfAmount],
|
||||
o[sfSignatureReward],
|
||||
o[sfAttestationRewardAccount],
|
||||
o[sfWasLockingChainSend] != 0,
|
||||
o[sfDestination]} {};
|
||||
|
||||
XChainCreateAccountAttestation::XChainCreateAccountAttestation(json::Value const& v)
|
||||
: XChainCreateAccountAttestation{
|
||||
json::getOrThrow<AccountID>(v, sfAttestationSignerAccount),
|
||||
json::getOrThrow<PublicKey>(v, sfPublicKey),
|
||||
json::getOrThrow<STAmount>(v, sfAmount),
|
||||
json::getOrThrow<STAmount>(v, sfSignatureReward),
|
||||
json::getOrThrow<AccountID>(v, sfAttestationRewardAccount),
|
||||
json::getOrThrow<bool>(v, sfWasLockingChainSend),
|
||||
json::getOrThrow<AccountID>(v, sfDestination)}
|
||||
{
|
||||
}
|
||||
|
||||
XChainCreateAccountAttestation::XChainCreateAccountAttestation(
|
||||
XChainCreateAccountAttestation::TSignedAttestation const& createAtt)
|
||||
: XChainCreateAccountAttestation{
|
||||
createAtt.attestationSignerAccount,
|
||||
createAtt.publicKey,
|
||||
createAtt.sendingAmount,
|
||||
createAtt.rewardAmount,
|
||||
createAtt.rewardAccount,
|
||||
createAtt.wasLockingChainSend,
|
||||
createAtt.toCreate}
|
||||
{
|
||||
}
|
||||
|
||||
STObject
|
||||
XChainCreateAccountAttestation::toSTObject() const
|
||||
{
|
||||
STObject o = STObject::makeInnerObject(sfXChainCreateAccountProofSig);
|
||||
|
||||
o[sfAttestationSignerAccount] = STAccount{sfAttestationSignerAccount, keyAccount};
|
||||
o[sfPublicKey] = publicKey;
|
||||
o[sfAmount] = STAmount{sfAmount, amount};
|
||||
o[sfSignatureReward] = STAmount{sfSignatureReward, rewardAmount};
|
||||
o[sfAttestationRewardAccount] = STAccount{sfAttestationRewardAccount, rewardAccount};
|
||||
o[sfWasLockingChainSend] = wasLockingChainSend;
|
||||
o[sfDestination] = STAccount{sfDestination, dst};
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
XChainCreateAccountAttestation::MatchFields::MatchFields(
|
||||
XChainCreateAccountAttestation::TSignedAttestation const& att)
|
||||
: amount{att.sendingAmount}
|
||||
, rewardAmount(att.rewardAmount)
|
||||
, wasLockingChainSend{att.wasLockingChainSend}
|
||||
, dst{att.toCreate}
|
||||
{
|
||||
}
|
||||
|
||||
AttestationMatch
|
||||
XChainCreateAccountAttestation::match(XChainCreateAccountAttestation::MatchFields const& rhs) const
|
||||
{
|
||||
if (std::tie(amount, rewardAmount, wasLockingChainSend) !=
|
||||
std::tie(rhs.amount, rhs.rewardAmount, rhs.wasLockingChainSend))
|
||||
return AttestationMatch::NonDstMismatch;
|
||||
if (dst != rhs.dst)
|
||||
return AttestationMatch::MatchExceptDst;
|
||||
return AttestationMatch::Match;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(XChainCreateAccountAttestation const& lhs, XChainCreateAccountAttestation const& rhs)
|
||||
{
|
||||
return std::tie(
|
||||
lhs.keyAccount,
|
||||
lhs.publicKey,
|
||||
lhs.amount,
|
||||
lhs.rewardAmount,
|
||||
lhs.rewardAccount,
|
||||
lhs.wasLockingChainSend,
|
||||
lhs.dst) ==
|
||||
std::tie(
|
||||
rhs.keyAccount,
|
||||
rhs.publicKey,
|
||||
rhs.amount,
|
||||
rhs.rewardAmount,
|
||||
rhs.rewardAccount,
|
||||
rhs.wasLockingChainSend,
|
||||
rhs.dst);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
template <class TAttestation>
|
||||
XChainAttestationsBase<TAttestation>::XChainAttestationsBase(
|
||||
XChainAttestationsBase<TAttestation>::AttCollection&& atts)
|
||||
: attestations_{std::move(atts)}
|
||||
{
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
XChainAttestationsBase<TAttestation>::AttCollection::const_iterator
|
||||
XChainAttestationsBase<TAttestation>::begin() const
|
||||
{
|
||||
return attestations_.begin();
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
XChainAttestationsBase<TAttestation>::AttCollection::const_iterator
|
||||
XChainAttestationsBase<TAttestation>::end() const
|
||||
{
|
||||
return attestations_.end();
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
XChainAttestationsBase<TAttestation>::AttCollection::iterator
|
||||
XChainAttestationsBase<TAttestation>::begin()
|
||||
{
|
||||
return attestations_.begin();
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
XChainAttestationsBase<TAttestation>::AttCollection::iterator
|
||||
XChainAttestationsBase<TAttestation>::end()
|
||||
{
|
||||
return attestations_.end();
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
XChainAttestationsBase<TAttestation>::XChainAttestationsBase(json::Value const& v)
|
||||
{
|
||||
if (!v.isObject())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"XChainAttestationsBase can only be specified with an 'object' "
|
||||
"Json value");
|
||||
}
|
||||
|
||||
attestations_ = [&] {
|
||||
auto const jAtts = v[jss::attestations];
|
||||
|
||||
if (jAtts.size() > kMaxAttestations)
|
||||
Throw<std::runtime_error>("XChainAttestationsBase exceeded max number of attestations");
|
||||
|
||||
std::vector<TAttestation> r;
|
||||
r.reserve(jAtts.size());
|
||||
for (auto const& a : jAtts)
|
||||
r.emplace_back(a);
|
||||
return r;
|
||||
}();
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
XChainAttestationsBase<TAttestation>::XChainAttestationsBase(STArray const& arr)
|
||||
{
|
||||
if (arr.size() > kMaxAttestations)
|
||||
Throw<std::runtime_error>("XChainAttestationsBase exceeded max number of attestations");
|
||||
|
||||
attestations_.reserve(arr.size());
|
||||
for (auto const& o : arr)
|
||||
attestations_.emplace_back(o);
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
STArray
|
||||
XChainAttestationsBase<TAttestation>::toSTArray() const
|
||||
{
|
||||
STArray r{TAttestation::arrayFieldName, attestations_.size()};
|
||||
for (auto const& e : attestations_)
|
||||
r.emplaceBack(e.toSTObject());
|
||||
return r;
|
||||
}
|
||||
|
||||
template class XChainAttestationsBase<XChainClaimAttestation>;
|
||||
template class XChainAttestationsBase<XChainCreateAccountAttestation>;
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <xrpl/protocol/detail/transactions.macro>
|
||||
|
||||
#undef TRANSACTION
|
||||
#undef TRANSACTION_INCLUDE
|
||||
|
||||
#pragma pop_macro("TRANSACTION")
|
||||
|
||||
// DO NOT INCLUDE TRANSACTOR HEADER FILES HERE.
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
#include <xrpl/tx/invariants/CosignerInvariant.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STArray.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
namespace {
|
||||
|
||||
bool
|
||||
validSignerArray(STArray const& signers, std::size_t limit, SField const& elementName)
|
||||
{
|
||||
if (signers.size() > limit)
|
||||
return false;
|
||||
|
||||
std::optional<AccountID> previous;
|
||||
for (auto const& signer : signers)
|
||||
{
|
||||
if (signer.getFName() != elementName || !signer.isFieldPresent(sfAccount))
|
||||
return false;
|
||||
|
||||
auto const account = signer.getAccountID(sfAccount);
|
||||
if (previous && account <= *previous)
|
||||
return false;
|
||||
previous = account;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
validNestedSigners(STObject const& signature)
|
||||
{
|
||||
return !signature.isFieldPresent(sfSigners) ||
|
||||
validSignerArray(signature.getFieldArray(sfSigners), STTx::kMaxMultiSigners, sfSigner);
|
||||
}
|
||||
|
||||
bool
|
||||
validSignerArrays(STObject const& proposedTx)
|
||||
{
|
||||
if (!validNestedSigners(proposedTx))
|
||||
return false;
|
||||
|
||||
for (auto const* field :
|
||||
std::array<SField const*, 2>{&sfCounterpartySignature, &sfSponsorSignature})
|
||||
{
|
||||
if (proposedTx.isFieldPresent(*field) &&
|
||||
!validNestedSigners(proposedTx.getFieldObject(*field)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!proposedTx.isFieldPresent(sfBatchSigners))
|
||||
return true;
|
||||
|
||||
auto const& batchSigners = proposedTx.getFieldArray(sfBatchSigners);
|
||||
if (!validSignerArray(batchSigners, kMaxBatchSigners, sfBatchSigner))
|
||||
return false;
|
||||
|
||||
return std::ranges::all_of(
|
||||
batchSigners, [](auto const& batchSigner) { return validNestedSigners(batchSigner); });
|
||||
}
|
||||
|
||||
// The Ticket a proposal is keyed to: the one its proposed transaction spends.
|
||||
uint256
|
||||
proposalTicketKey(SLE const& proposal)
|
||||
{
|
||||
auto const& proposedTx = proposal.getFieldObject(sfProposedTransaction);
|
||||
return keylet::ticket(
|
||||
proposedTx.getAccountID(sfAccount),
|
||||
SeqProxy::rawTicket(proposedTx.getFieldU32(sfTicketSequence)))
|
||||
.key;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void
|
||||
ValidTransactionProposal::visitEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after)
|
||||
{
|
||||
// `after` is always present (on deletion it holds the final state), so it
|
||||
// alone determines the entry type. LedgerEntryTypesMatch owns malformed
|
||||
// type transitions; skip them rather than read one side with the other's
|
||||
// schema.
|
||||
if (!after || (before && before->getType() != after->getType()))
|
||||
return;
|
||||
|
||||
auto const type = after->getType();
|
||||
|
||||
// Consuming a Ticket deletes the proposal keyed to it (XLS-0103 §4.5).
|
||||
// Remember each Ticket that went, so finalize can tell a proposal deleted
|
||||
// with its Ticket from one that simply vanished, and the proposal each
|
||||
// Ticket was keyed to, so finalize can check that none stayed behind.
|
||||
if (type == ltTICKET)
|
||||
{
|
||||
if (isDelete)
|
||||
{
|
||||
deletedTickets_.insert(after->key());
|
||||
proposalsOfDeletedTickets_.push_back(
|
||||
keylet::txProposal(
|
||||
after->getAccountID(sfAccount), after->getFieldU32(sfTicketSequence)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != ltTRANSACTION_PROPOSAL)
|
||||
return;
|
||||
|
||||
if (!before)
|
||||
{
|
||||
++created_;
|
||||
}
|
||||
else if (isDelete)
|
||||
{
|
||||
++deleted_;
|
||||
ticketsOfDeletedProposals_.push_back(proposalTicketKey(*before));
|
||||
}
|
||||
else
|
||||
{
|
||||
++modified_;
|
||||
}
|
||||
|
||||
// A live proposal's signer lists must stay submittable: within size
|
||||
// limits, sorted by account, and free of duplicates.
|
||||
if (!isDelete && !validSignerArrays(after->getFieldObject(sfProposedTransaction)))
|
||||
invalidSignerArrays_ = true;
|
||||
}
|
||||
|
||||
bool
|
||||
ValidTransactionProposal::finalize(
|
||||
STTx const& tx,
|
||||
TER result,
|
||||
XRPAmount,
|
||||
ReadView const& view,
|
||||
beast::Journal const& j) const
|
||||
{
|
||||
if (!view.rules().enabled(featureCosign))
|
||||
return true;
|
||||
|
||||
if (invalidSignerArrays_)
|
||||
{
|
||||
JLOG(j.fatal()) << "Invariant failed: TransactionProposal signer arrays are not canonical.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// A proposal leaves the ledger in two ways (XLS-0103 §4.5): a
|
||||
// TransactionProposalCancel deletes the proposal it names, and consuming
|
||||
// the Ticket a proposal is keyed to deletes the proposal with it, whether
|
||||
// the proposed transaction executed (or failed with a claimed-fee tec) or
|
||||
// AccountDelete swept the target's Tickets.
|
||||
std::uint32_t deletedWithTicket = 0;
|
||||
for (auto const& ticketKey : ticketsOfDeletedProposals_)
|
||||
{
|
||||
if (deletedTickets_.contains(ticketKey))
|
||||
++deletedWithTicket;
|
||||
}
|
||||
|
||||
bool const succeeded = isTesSuccess(result);
|
||||
bool effectsMatch = false;
|
||||
if (tx.getTxnType() == ttTRANSACTION_PROPOSAL_CREATE)
|
||||
{
|
||||
effectsMatch = created_ == (succeeded ? 1u : 0u) && modified_ == 0 && deleted_ == 0;
|
||||
}
|
||||
else if (tx.getTxnType() == ttTRANSACTION_PROPOSAL_CANCEL)
|
||||
{
|
||||
// A Cancel deletes one proposal and nothing else. It cannot
|
||||
// spend a reserved Ticket, so no proposal goes with its Ticket here.
|
||||
effectsMatch = created_ == 0 && modified_ == 0 && deletedWithTicket == 0 &&
|
||||
deleted_ == (succeeded ? 1u : 0u);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Any other transaction deletes a proposal only together with its
|
||||
// Ticket, and modifies at most one, only as a successful
|
||||
// SponsorshipTransfer.
|
||||
// TODO: extend this when TransactionProposalSign is implemented.
|
||||
std::uint32_t const modifiable =
|
||||
tx.getTxnType() == ttSPONSORSHIP_TRANSFER && succeeded ? 1 : 0;
|
||||
effectsMatch = created_ == 0 && modified_ <= modifiable && deleted_ == deletedWithTicket;
|
||||
}
|
||||
|
||||
if (!effectsMatch)
|
||||
{
|
||||
JLOG(j.fatal())
|
||||
<< "Invariant failed: TransactionProposal changes do not match transaction result.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// The other direction of the deletion rule: ticketDelete deletes the
|
||||
// proposal keyed to a Ticket along with it (XLS-0103 §4.5), so no
|
||||
// proposal may outlive its Ticket, orphaned on a key that can no longer
|
||||
// be spent.
|
||||
bool const orphaned = std::ranges::any_of(
|
||||
proposalsOfDeletedTickets_, [&view](Keylet const& keylet) { return view.exists(keylet); });
|
||||
if (orphaned)
|
||||
{
|
||||
JLOG(j.fatal())
|
||||
<< "Invariant failed: TransactionProposal outlived the Ticket it is keyed to.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -935,8 +935,12 @@ ValidClawback::finalize(
|
||||
return !mptV2Enabled;
|
||||
}
|
||||
|
||||
// IOU balances keep 16 significant digits, so a clawback
|
||||
// much smaller than the balance changes it by a rounded
|
||||
// amount, possibly zero. Compare with the same rounded
|
||||
// subtraction the balance update performs.
|
||||
if (*afterBalance > *beforeBalance ||
|
||||
(*beforeBalance - *afterBalance) != std::min(*beforeBalance, clawAmount))
|
||||
*afterBalance != *beforeBalance - std::min(*beforeBalance, clawAmount))
|
||||
{
|
||||
JLOG(j.fatal())
|
||||
<< "Invariant failed: trustline clawback balance change is invalid";
|
||||
|
||||
@@ -254,6 +254,15 @@ private:
|
||||
TAmounts<TIn, TOut> const& stepAmt,
|
||||
TOut const& ownerGives) const;
|
||||
|
||||
template <template <typename, typename> typename Offer>
|
||||
void
|
||||
tryConsumeOffer(
|
||||
PaymentSandbox& sb,
|
||||
Offer<TIn, TOut>& offer,
|
||||
TAmounts<TIn, TOut> const& ofrAmt,
|
||||
TAmounts<TIn, TOut> const& stepAmt,
|
||||
TOut const& ownerGives) const;
|
||||
|
||||
// If clobQuality is available and has a better quality then return nullopt,
|
||||
// otherwise if amm liquidity is available return AMM offer adjusted based
|
||||
// on clobQuality.
|
||||
@@ -810,10 +819,11 @@ BookStep<TIn, TOut, TDerived>::forEachOffer(
|
||||
auto const amtIn = [&](TIn const& in) { return capInMPT && *maxIn_ < in ? *maxIn_ : in; };
|
||||
try
|
||||
{
|
||||
// All arithmetic in this block runs before the offer is consumed.
|
||||
// A crafted MPTokensV2 offer can overflow while transfer rates or
|
||||
// crossing limits are applied; remove that unusable offer instead
|
||||
// of letting it persist as a tecINTERNAL source.
|
||||
// crossing limits are applied, here or in the callback's
|
||||
// limitStepIn()/limitStepOut(); remove that unusable offer instead
|
||||
// of letting it persist as a tecINTERNAL source. Overflows while
|
||||
// consuming the offer are handled by tryConsumeOffer().
|
||||
stpAmt.in = mulRatio(amtIn(ofrAmt.in), ofrInRate, QUALITY_ONE, /*roundUp*/ true);
|
||||
|
||||
// owner pays the transfer fee. An MPT gross-up that doesn't fit in
|
||||
@@ -941,16 +951,9 @@ BookStep<TIn, TOut, TDerived>::forEachOffer(
|
||||
removeOffer("Removing offer with overflowing amount calculation");
|
||||
return true;
|
||||
}
|
||||
// An overflow can only be produced by a crafted MPT offer, and MPT
|
||||
// offers require featureMPTokensV2 (enforced at OfferCreate
|
||||
// preflight). So the amendment is always enabled when we get here
|
||||
// and this legacy re-throw is unreachable in practice.
|
||||
// LCOV_EXCL_START
|
||||
XRPL_ASSERT(
|
||||
sb.rules().enabled(featureMPTokensV2),
|
||||
"xrpl::BookStep::forEachOffer : overflow implies MPTokensV2");
|
||||
// Legacy behavior: the exception escapes flow() and the
|
||||
// transaction fails with tecINTERNAL.
|
||||
throw;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
};
|
||||
|
||||
@@ -991,6 +994,32 @@ BookStep<TIn, TOut, TDerived>::forEachOffer(
|
||||
return {offers.permToRemove(), counter.count()};
|
||||
}
|
||||
|
||||
template <class TIn, class TOut, class TDerived>
|
||||
template <template <typename, typename> typename Offer>
|
||||
void
|
||||
BookStep<TIn, TOut, TDerived>::tryConsumeOffer(
|
||||
PaymentSandbox& sb,
|
||||
Offer<TIn, TOut>& offer,
|
||||
TAmounts<TIn, TOut> const& ofrAmt,
|
||||
TAmounts<TIn, TOut> const& stepAmt,
|
||||
TOut const& ownerGives) const
|
||||
{
|
||||
try
|
||||
{
|
||||
// Under MPTokensV2, an overflow while consuming the offer fails the
|
||||
// strand instead of being handled by forEachOffer().
|
||||
consumeOffer(sb, offer, ofrAmt, stepAmt, ownerGives);
|
||||
}
|
||||
catch (std::overflow_error const&)
|
||||
{
|
||||
if (sb.rules().enabled(featureMPTokensV2))
|
||||
{
|
||||
Throw<FlowException>(tecINTERNAL, "Overflow while consuming offer");
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template <class TIn, class TOut, class TDerived>
|
||||
template <template <typename, typename> typename Offer>
|
||||
void
|
||||
@@ -1192,7 +1221,7 @@ BookStep<TIn, TOut, TDerived>::revImp(
|
||||
savedOuts.insert(stpAmt.out);
|
||||
result = TAmounts<TIn, TOut>(sum(savedIns), sum(savedOuts));
|
||||
remainingOut = out - result.out;
|
||||
this->consumeOffer(sb, offer, ofrAmt, stpAmt, ownerGives);
|
||||
this->tryConsumeOffer(sb, offer, ofrAmt, stpAmt, ownerGives);
|
||||
// return true b/c even if the payment is satisfied,
|
||||
// we need to consume the offer. An offer limited by what the
|
||||
// issuer can issue is not consumed, though: its remainder is still
|
||||
@@ -1224,7 +1253,7 @@ BookStep<TIn, TOut, TDerived>::revImp(
|
||||
savedOuts.insert(remainingOut);
|
||||
result.in = sum(savedIns);
|
||||
result.out = out;
|
||||
this->consumeOffer(sb, offer, ofrAdjAmt, stpAdjAmt, ownerGivesAdj);
|
||||
this->tryConsumeOffer(sb, offer, ofrAdjAmt, stpAdjAmt, ownerGivesAdj);
|
||||
|
||||
// Explicitly check whether the offer is funded. Given that we have
|
||||
// (stpAmt.out > remainingOut), it's natural to assume the offer
|
||||
@@ -1408,7 +1437,7 @@ BookStep<TIn, TOut, TDerived>::fwdImp(
|
||||
savedOuts = std::move(savedOutsAdj);
|
||||
result = resultAdj;
|
||||
remainingIn = in - result.in;
|
||||
this->consumeOffer(sb, offer, ofrAdjAmt, stpAdjAmt, ownerGivesAdj);
|
||||
this->tryConsumeOffer(sb, offer, ofrAdjAmt, stpAdjAmt, ownerGivesAdj);
|
||||
|
||||
// When the mantissas of two iou amounts differ by less than ten, then
|
||||
// subtracting them leaves a result of zero. This can cause the check
|
||||
@@ -1512,6 +1541,18 @@ BookStep<TIn, TOut, TDerived>::check(StrandContext const& ctx) const
|
||||
return temBAD_PATH;
|
||||
}
|
||||
|
||||
// An issuer paying with its own MPT issues it into the first book. A
|
||||
// holder-sourced strand records the MPT in the first MPTEndpointStep and
|
||||
// so rejects a later book that outputs it again; do the same here. The
|
||||
// step after such a book issues the MPT a second time and the payment
|
||||
// engine cannot keep the two within MaximumAmount once StrandFlow
|
||||
// rebuilds the sandbox on a limiting step.
|
||||
if (ctx.isFirst && book_.in.holds<MPTIssue>() && book_.in.getIssuer() == ctx.strandSrc &&
|
||||
ctx.view.rules().enabled(featureMPTokensV2))
|
||||
{
|
||||
ctx.seenDirectAssets[0].insert(book_.in);
|
||||
}
|
||||
|
||||
// Do not allow two books to output the same issue. This may cause offers on
|
||||
// one step to unfund offers in another step.
|
||||
if (!ctx.seenBookOuts.insert(book_.out).second ||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -874,15 +875,18 @@ MPTEndpointStep<TDerived>::check(StrandContext const& ctx) const
|
||||
|
||||
// pure issue/redeem can't be frozen (issuer/holder)
|
||||
// For the first step: check global freeze of the step's own asset.
|
||||
// For the last step: check only the per-holder MPToken lock.
|
||||
// For the last step: check only the per-holder lock.
|
||||
// Global freeze of the deliver asset is not checked here
|
||||
// because MPT semantics allow issuer<->holder transfers even when globally
|
||||
// locked — only holder-to-holder DEX paths are restricted.
|
||||
// For both steps: a vault share inherits the freeze of the vault's
|
||||
// underlying asset.
|
||||
if (!(ctx.isLast && ctx.isFirst))
|
||||
{
|
||||
auto const& account = ctx.isFirst ? src_ : dst_;
|
||||
bool const frozen = (ctx.isFirst && isGlobalFrozen(ctx.view, mptIssue_)) ||
|
||||
isIndividualFrozen(ctx.view, account, mptIssue_);
|
||||
isIndividualFrozen(ctx.view, account, mptIssue_) ||
|
||||
isVaultPseudoAccountFrozen(ctx.view, account, mptIssue_, 0);
|
||||
if (frozen)
|
||||
return terLOCKED;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -36,14 +36,8 @@ namespace xrpl {
|
||||
bool
|
||||
AMMBid::checkExtraFeatures(PreflightContext const& ctx)
|
||||
{
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return false;
|
||||
|
||||
if (!ctx.rules.enabled(featureMPTokensV2) &&
|
||||
(ctx.tx[sfAsset].holds<MPTIssue>() || ctx.tx[sfAsset2].holds<MPTIssue>()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return ctx.rules.enabled(featureMPTokensV2) ||
|
||||
(!ctx.tx[sfAsset].holds<MPTIssue>() && !ctx.tx[sfAsset2].holds<MPTIssue>());
|
||||
}
|
||||
|
||||
NotTEC
|
||||
|
||||
@@ -39,14 +39,8 @@ namespace xrpl {
|
||||
bool
|
||||
AMMCreate::checkExtraFeatures(PreflightContext const& ctx)
|
||||
{
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return false;
|
||||
|
||||
if (!ctx.rules.enabled(featureMPTokensV2) &&
|
||||
(ctx.tx[sfAmount].holds<MPTIssue>() || ctx.tx[sfAmount2].holds<MPTIssue>()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return ctx.rules.enabled(featureMPTokensV2) ||
|
||||
(!ctx.tx[sfAmount].holds<MPTIssue>() && !ctx.tx[sfAmount2].holds<MPTIssue>());
|
||||
}
|
||||
|
||||
NotTEC
|
||||
|
||||
@@ -20,9 +20,6 @@ namespace xrpl {
|
||||
bool
|
||||
AMMDelete::checkExtraFeatures(PreflightContext const& ctx)
|
||||
{
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return false;
|
||||
|
||||
return ctx.rules.enabled(featureMPTokensV2) ||
|
||||
(!ctx.tx[sfAsset].holds<MPTIssue>() && !ctx.tx[sfAsset2].holds<MPTIssue>());
|
||||
}
|
||||
|
||||
@@ -36,9 +36,6 @@ namespace xrpl {
|
||||
bool
|
||||
AMMDeposit::checkExtraFeatures(PreflightContext const& ctx)
|
||||
{
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return false;
|
||||
|
||||
auto const amount = ctx.tx[~sfAmount];
|
||||
auto const amount2 = ctx.tx[~sfAmount2];
|
||||
|
||||
|
||||
@@ -30,9 +30,6 @@ namespace xrpl {
|
||||
bool
|
||||
AMMVote::checkExtraFeatures(PreflightContext const& ctx)
|
||||
{
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return false;
|
||||
|
||||
return ctx.rules.enabled(featureMPTokensV2) ||
|
||||
(!ctx.tx[sfAsset].holds<MPTIssue>() && !ctx.tx[sfAsset2].holds<MPTIssue>());
|
||||
}
|
||||
|
||||
@@ -44,9 +44,6 @@ namespace xrpl {
|
||||
bool
|
||||
AMMWithdraw::checkExtraFeatures(PreflightContext const& ctx)
|
||||
{
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return false;
|
||||
|
||||
auto const amount = ctx.tx[~sfAmount];
|
||||
auto const amount2 = ctx.tx[~sfAmount2];
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ TransactionProposalCancel::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
// Never read the zero keylet. Preflight already rejected a zero
|
||||
// ProposalID, and no real proposal can have one (every ProposalID is a
|
||||
// hash), so reaching here with zero is an internal error. (and a mathematical rarity. )
|
||||
// hash), so reaching here with zero is an internal error (and a mathematical rarity).
|
||||
if (proposalID == beast::kZero)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -88,43 +88,15 @@ Change::preclaim(PreclaimContext const& ctx)
|
||||
switch (ctx.tx.getTxnType())
|
||||
{
|
||||
case ttFEE:
|
||||
if (ctx.view.rules().enabled(featureXRPFees))
|
||||
{
|
||||
// The ttFEE transaction format defines these fields as
|
||||
// optional, but once the XRPFees feature is enabled, they are
|
||||
// required.
|
||||
if (!ctx.tx.isFieldPresent(sfBaseFeeDrops) ||
|
||||
!ctx.tx.isFieldPresent(sfReserveBaseDrops) ||
|
||||
!ctx.tx.isFieldPresent(sfReserveIncrementDrops))
|
||||
return temMALFORMED;
|
||||
// The ttFEE transaction format defines these fields as
|
||||
// optional, but once the XRPFees feature is enabled, they are
|
||||
// forbidden.
|
||||
if (ctx.tx.isFieldPresent(sfBaseFee) ||
|
||||
ctx.tx.isFieldPresent(sfReferenceFeeUnits) ||
|
||||
ctx.tx.isFieldPresent(sfReserveBase) ||
|
||||
ctx.tx.isFieldPresent(sfReserveIncrement))
|
||||
return temMALFORMED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The ttFEE transaction format formerly defined these fields
|
||||
// as required. When the XRPFees feature was implemented, they
|
||||
// were changed to be optional. Until the feature has been
|
||||
// enabled, they are required.
|
||||
if (!ctx.tx.isFieldPresent(sfBaseFee) ||
|
||||
!ctx.tx.isFieldPresent(sfReferenceFeeUnits) ||
|
||||
!ctx.tx.isFieldPresent(sfReserveBase) ||
|
||||
!ctx.tx.isFieldPresent(sfReserveIncrement))
|
||||
return temMALFORMED;
|
||||
// The ttFEE transaction format defines these fields as
|
||||
// optional, but without the XRPFees feature, they are
|
||||
// forbidden.
|
||||
if (ctx.tx.isFieldPresent(sfBaseFeeDrops) ||
|
||||
ctx.tx.isFieldPresent(sfReserveBaseDrops) ||
|
||||
ctx.tx.isFieldPresent(sfReserveIncrementDrops))
|
||||
return temDISABLED;
|
||||
}
|
||||
// The XRPFees feature has been retired, these fields are required now.
|
||||
if (!ctx.tx.isFieldPresent(sfBaseFeeDrops) ||
|
||||
!ctx.tx.isFieldPresent(sfReserveBaseDrops) ||
|
||||
!ctx.tx.isFieldPresent(sfReserveIncrementDrops))
|
||||
return temMALFORMED;
|
||||
// The XRPFees feature has been retired, these fields are forbidden now.
|
||||
if (ctx.tx.isFieldPresent(sfBaseFee) || ctx.tx.isFieldPresent(sfReferenceFeeUnits) ||
|
||||
ctx.tx.isFieldPresent(sfReserveBase) || ctx.tx.isFieldPresent(sfReserveIncrement))
|
||||
return temMALFORMED;
|
||||
if (ctx.view.rules().enabled(featureSmartEscrow))
|
||||
{
|
||||
if (!ctx.tx.isFieldPresent(sfGasLimit) ||
|
||||
@@ -306,19 +278,12 @@ Change::applyFee()
|
||||
auto const set = [](FeeSettingsEntryW& feeObject, STTx const& tx, auto const&... fields) {
|
||||
((feeObject->at(fields) = tx[fields]), ...);
|
||||
};
|
||||
if (view().rules().enabled(featureXRPFees))
|
||||
{
|
||||
set(feeObject, ctx_.tx, sfBaseFeeDrops, sfReserveBaseDrops, sfReserveIncrementDrops);
|
||||
// Ensure the old fields are removed
|
||||
feeObject->makeFieldAbsent(sfBaseFee);
|
||||
feeObject->makeFieldAbsent(sfReferenceFeeUnits);
|
||||
feeObject->makeFieldAbsent(sfReserveBase);
|
||||
feeObject->makeFieldAbsent(sfReserveIncrement);
|
||||
}
|
||||
else
|
||||
{
|
||||
set(feeObject, ctx_.tx, sfBaseFee, sfReferenceFeeUnits, sfReserveBase, sfReserveIncrement);
|
||||
}
|
||||
set(feeObject, ctx_.tx, sfBaseFeeDrops, sfReserveBaseDrops, sfReserveIncrementDrops);
|
||||
// Ensure the old fields are removed
|
||||
feeObject->makeFieldAbsent(sfBaseFee);
|
||||
feeObject->makeFieldAbsent(sfReferenceFeeUnits);
|
||||
feeObject->makeFieldAbsent(sfReserveBase);
|
||||
feeObject->makeFieldAbsent(sfReserveIncrement);
|
||||
if (view().rules().enabled(featureSmartEscrow))
|
||||
{
|
||||
set(feeObject, ctx_.tx, sfGasLimit, sfBytecodeSizeLimit, sfGasPrice);
|
||||
|
||||
@@ -179,13 +179,12 @@ TrustSet::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
// This might be nullptr
|
||||
auto const sleDst = ctx.view.read(keylet::account(uDstAccountID));
|
||||
if ((ammEnabled(ctx.view.rules()) || ctx.view.rules().enabled(featureSingleAssetVault)) &&
|
||||
sleDst == nullptr)
|
||||
if (sleDst == nullptr)
|
||||
return tecNO_DST;
|
||||
|
||||
// If the destination has opted to disallow incoming trustlines
|
||||
// then honour that flag
|
||||
if (sleDst && sleDst->isFlag(lsfDisallowIncomingTrustline) &&
|
||||
if (sleDst->isFlag(lsfDisallowIncomingTrustline) &&
|
||||
!ctx.view.exists(keylet::trustLine(id, uDstAccountID, currency)))
|
||||
{
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
+18
-50
@@ -21,6 +21,8 @@
|
||||
#include <test/jtx/trust.h>
|
||||
#include <test/jtx/txflags.h>
|
||||
|
||||
#include <xrpld/core/Config.h>
|
||||
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
@@ -3190,16 +3192,6 @@ private:
|
||||
AMM amm(env, gw_, XRP(1'000), USD(1'010), false, 1'000);
|
||||
json::Value const tx = amm.bid({.account = alice_, .bidMin = 500});
|
||||
|
||||
{
|
||||
auto const jtx = env.jt(tx, Seq(1), Fee(baseFee));
|
||||
env.app().config().features.erase(featureAMM);
|
||||
PreflightContext const pfCtx(
|
||||
env.app(), *jtx.stx, env.current()->rules(), TapNone, env.journal);
|
||||
auto const pf = Transactor::invokePreflight<AMMBid>(pfCtx);
|
||||
BEAST_EXPECT(pf == temDISABLED);
|
||||
env.app().config().features.insert(featureAMM);
|
||||
}
|
||||
|
||||
{
|
||||
auto jtx = env.jt(tx, Seq(1), Fee(baseFee));
|
||||
jtx.jv["TxnSignature"] = "deadbeef";
|
||||
@@ -4179,27 +4171,6 @@ private:
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
testAmendment()
|
||||
{
|
||||
testcase("Amendment");
|
||||
using namespace jtx;
|
||||
Env env{*this, testableAmendments() - featureAMM};
|
||||
|
||||
{
|
||||
fund(env, gw_, {alice_}, {USD(1'000)}, Fund::All);
|
||||
AMM amm(env, alice_, XRP(1'000), USD(1'000), Ter(temDISABLED));
|
||||
|
||||
env(amm.bid({.bidMax = 1000}), Ter(temMALFORMED));
|
||||
env(amm.bid({}), Ter(temDISABLED));
|
||||
amm.vote(VoteArg{.tfee = 100, .err = Ter(temDISABLED)});
|
||||
amm.withdraw(WithdrawArg{.tokens = 100, .err = Ter(temMALFORMED)});
|
||||
amm.withdraw(WithdrawArg{.err = Ter(temDISABLED)});
|
||||
amm.deposit(DepositArg{.asset1In = USD(100), .err = Ter(temDISABLED)});
|
||||
amm.ammDelete(alice_, Ter(temDISABLED));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testFlags()
|
||||
{
|
||||
@@ -5799,27 +5770,25 @@ private:
|
||||
return input.lpTokenBalanceAlt.value_or(input.lpTokenBalance);
|
||||
}();
|
||||
|
||||
{
|
||||
BEAST_EXPECT(amm.expectBalances(goodUsdGH, goodUsdBIT, lpTokenBalance));
|
||||
BEAST_EXPECT(amm.expectBalances(goodUsdGH, goodUsdBIT, lpTokenBalance));
|
||||
|
||||
// Invariant: LPToken balance must not change in a
|
||||
// payment or a swap transaction
|
||||
BEAST_EXPECT(amm.getLPTokensBalance() == preSwapLPTokenBalance);
|
||||
// Invariant: LPToken balance must not change in a
|
||||
// payment or a swap transaction
|
||||
BEAST_EXPECT(amm.getLPTokensBalance() == preSwapLPTokenBalance);
|
||||
|
||||
// Invariant: The square root of (product of the pool
|
||||
// balances) must be at least the LPTokenBalance
|
||||
Number const sqrtPoolProduct = root2(goodUsdGH * goodUsdBIT);
|
||||
// Invariant: The square root of (product of the pool
|
||||
// balances) must be at least the LPTokenBalance
|
||||
Number const sqrtPoolProduct = root2(goodUsdGH * goodUsdBIT);
|
||||
|
||||
// Include a tiny tolerance for the test cases using
|
||||
// .goodUsdGH{usdGH, uint64_t(35'44113971506987),
|
||||
// -14}, .goodUsdBIT{usdBIT,
|
||||
// uint64_t(2'821579689703915), -15},
|
||||
// These two values multiply
|
||||
// to 99.99999999999994227040383754105 which gets
|
||||
// internally rounded to 100, due to representation
|
||||
// error.
|
||||
BEAST_EXPECT((sqrtPoolProduct + Number{1, -14} >= input.lpTokenBalance));
|
||||
}
|
||||
// Include a tiny tolerance for the test cases using
|
||||
// .goodUsdGH{usdGH, uint64_t(35'44113971506987),
|
||||
// -14}, .goodUsdBIT{usdBIT,
|
||||
// uint64_t(2'821579689703915), -15},
|
||||
// These two values multiply
|
||||
// to 99.99999999999994227040383754105 which gets
|
||||
// internally rounded to 100, due to representation
|
||||
// error.
|
||||
BEAST_EXPECT((sqrtPoolProduct + Number{1, -14} >= lpTokenBalance));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6866,7 +6835,6 @@ private:
|
||||
testBasicPaymentEngine(all - fixReducedOffersV2);
|
||||
testBasicPaymentEngine(all - fixAMMv1_3 - fixReducedOffersV2);
|
||||
testAMMTokens();
|
||||
testAmendment();
|
||||
testFlags();
|
||||
testRippling();
|
||||
testAMMAndCLOB(all);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
@@ -894,8 +895,9 @@ public:
|
||||
auto const jNoCred = credentials::ledgerEntry(env, becky, carol, credType);
|
||||
BEAST_EXPECT(
|
||||
jNoCred.isObject() && jNoCred.isMember(jss::result) &&
|
||||
jNoCred[jss::result].isMember(jss::error) &&
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound");
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jNoCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jNoCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
testcase("Credentials that aren't required");
|
||||
@@ -918,8 +920,9 @@ public:
|
||||
|
||||
BEAST_EXPECT(
|
||||
jNoCred.isObject() && jNoCred.isMember(jss::result) &&
|
||||
jNoCred[jss::result].isMember(jss::error) &&
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound");
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jNoCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jNoCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -957,8 +960,9 @@ public:
|
||||
|
||||
BEAST_EXPECT(
|
||||
jNoCred.isObject() && jNoCred.isMember(jss::result) &&
|
||||
jNoCred[jss::result].isMember(jss::error) &&
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound");
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jNoCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jNoCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
testcase("Expired credentials");
|
||||
@@ -994,8 +998,9 @@ public:
|
||||
auto jv = credentials::ledgerEntry(env, john, carol, credType);
|
||||
BEAST_EXPECT(
|
||||
jv.isObject() && jv.isMember(jss::result) &&
|
||||
jv[jss::result].isMember(jss::error) &&
|
||||
jv[jss::result][jss::error] == "entryNotFound");
|
||||
jv[jss::result][jss::error] == "entryNotFound" &&
|
||||
jv[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jv[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1079,8 +1084,9 @@ public:
|
||||
auto const jv = credentials::ledgerEntry(env, becky, carol, credType);
|
||||
BEAST_EXPECT(
|
||||
jv.isObject() && jv.isMember(jss::result) &&
|
||||
jv[jss::result].isMember(jss::error) &&
|
||||
jv[jss::result][jss::error] == "entryNotFound");
|
||||
jv[jss::result][jss::error] == "entryNotFound" &&
|
||||
jv[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jv[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1121,8 +1127,9 @@ public:
|
||||
auto const jv = credentials::ledgerEntry(env, becky, carol, credType);
|
||||
BEAST_EXPECT(
|
||||
jv.isObject() && jv.isMember(jss::result) &&
|
||||
jv[jss::result].isMember(jss::error) &&
|
||||
jv[jss::result][jss::error] == "entryNotFound");
|
||||
jv[jss::result][jss::error] == "entryNotFound" &&
|
||||
jv[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jv[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Batch.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
@@ -2800,6 +2801,7 @@ class Batch_test : public beast::unit_test::Suite
|
||||
auto const jrr = env.rpc("submit", strHex(slice))[jss::result];
|
||||
expect(
|
||||
jrr[jss::status] == "error" && jrr[jss::error] == "invalidTransaction" &&
|
||||
!jrr.isMember(jss::error_code) && jrr[jss::error_message].isNull() &&
|
||||
jrr[jss::error_exception] ==
|
||||
"fails local checks: Batch inner transactions are never "
|
||||
"considered validly signed.",
|
||||
@@ -5407,7 +5409,10 @@ class Batch_test : public beast::unit_test::Suite
|
||||
|
||||
// The delegated payment never applied.
|
||||
BEAST_EXPECT(env.balance(mallory) == preMallory);
|
||||
BEAST_EXPECT(env.rpc("tx", txIDs[1])[jss::result][jss::error] == "txnNotFound");
|
||||
auto const txResult = env.rpc("tx", txIDs[1])[jss::result];
|
||||
BEAST_EXPECT(txResult[jss::error] == "txnNotFound");
|
||||
BEAST_EXPECT(txResult[jss::error_code] == RpcTxnNotFound);
|
||||
BEAST_EXPECT(txResult[jss::error_message] == "Transaction not found.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5818,7 +5823,10 @@ class Batch_test : public beast::unit_test::Suite
|
||||
validateClosedLedger(env, testCases);
|
||||
|
||||
// verify jv2 is not present in the closed ledger.
|
||||
BEAST_EXPECT(env.rpc("tx", txIDs[1])[jss::result][jss::error] == "txnNotFound");
|
||||
auto const txResult = env.rpc("tx", txIDs[1])[jss::result];
|
||||
BEAST_EXPECT(txResult[jss::error] == "txnNotFound");
|
||||
BEAST_EXPECT(txResult[jss::error_code] == RpcTxnNotFound);
|
||||
BEAST_EXPECT(txResult[jss::error_message] == "Transaction not found.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 211 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user