Compare commits

...
148 changed files with 1271 additions and 18185 deletions

No files matched your search

+1 -2
View File
@@ -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
+4 -4
View File
@@ -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"
}
}
]
+1
View File
@@ -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:
+1 -1
View File
@@ -35,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.
+1 -1
View File
@@ -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
+2 -2
View File
@@ -15,7 +15,7 @@ on:
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" }'
+2 -2
View File
@@ -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 }}
+2 -2
View File
@@ -34,7 +34,7 @@ jobs:
needs: [determine-files]
if: ${{ needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.need_full_run == 'true' }}
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-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
+2 -2
View File
@@ -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
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
+7
View File
@@ -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
+60
View File
@@ -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}"
+8
View File
@@ -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
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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",
]
-36
View File
@@ -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.
-6
View File
@@ -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}
-4
View File
@@ -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};
-12
View File
@@ -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;
+26
View File
@@ -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,
};
/**
+1 -3
View File
@@ -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)
//------------------------------------------------------------------------------
+1
View File
@@ -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>
-224
View File
@@ -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
-4
View File
@@ -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), \
+48
View File
@@ -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
-471
View File
@@ -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
+6 -5
View File
@@ -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
+22 -39
View File
@@ -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)
+4 -111
View File
@@ -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
-2
View File
@@ -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
+5 -18
View File
@@ -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
View File
@@ -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"
+13
View File
@@ -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}
'';
+9 -1
View File
@@ -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
+11
View File
@@ -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
+2
View File
@@ -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
+4
View File
@@ -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
+2
View File
@@ -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}" != ""
+3 -22
View File
@@ -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
-8
View File
@@ -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
+3 -43
View File
@@ -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(),
{
+1 -13
View File
@@ -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
{
-4
View File
@@ -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},
-4
View File
@@ -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;
-204
View File
@@ -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
-706
View File
@@ -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
File diff suppressed because it is too large. Load diff
+2 -8
View File
@@ -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
+2 -8
View File
@@ -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];
+15 -50
View File
@@ -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
View File
@@ -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);
+1 -15
View File
@@ -2844,20 +2844,6 @@ class Delegate_test : public beast::unit_test::Suite
// NFTokenAcceptOffer are not included, they are tested separately.
std::unordered_map<std::string, UInt256> txRequiredFeatures{
{"AMMClawback", featureAMMClawback},
{"AMMCreate", featureAMM},
{"AMMDeposit", featureAMM},
{"AMMWithdraw", featureAMM},
{"AMMVote", featureAMM},
{"AMMBid", featureAMM},
{"AMMDelete", featureAMM},
{"XChainCreateClaimID", featureXChainBridge},
{"XChainCommit", featureXChainBridge},
{"XChainClaim", featureXChainBridge},
{"XChainAccountCreateCommit", featureXChainBridge},
{"XChainAddClaimAttestation", featureXChainBridge},
{"XChainAddAccountCreateAttestation", featureXChainBridge},
{"XChainModifyBridge", featureXChainBridge},
{"XChainCreateBridge", featureXChainBridge},
{"DIDSet", featureDID},
{"DIDDelete", featureDID},
{"OracleSet", featurePriceOracle},
@@ -3014,7 +3000,7 @@ class Delegate_test : public beast::unit_test::Suite
// DO NOT modify expectedDelegableCount unless all scenarios, including
// edge cases, have been fully tested and verified.
// ====================================================================
std::size_t const expectedDelegableCount = 57;
std::size_t const expectedDelegableCount = 49;
BEAST_EXPECTS(
delegableCount == expectedDelegableCount,
+73 -212
View File
@@ -44,10 +44,6 @@ namespace xrpl::test {
struct FeeSettingsFields
{
std::optional<std::uint64_t> baseFee = std::nullopt;
std::optional<std::uint32_t> reserveBase = std::nullopt;
std::optional<std::uint32_t> reserveIncrement = std::nullopt;
std::optional<std::uint32_t> referenceFeeUnits = std::nullopt;
std::optional<XRPAmount> baseFeeDrops = std::nullopt;
std::optional<XRPAmount> reserveBaseDrops = std::nullopt;
std::optional<XRPAmount> reserveIncrementDrops = std::nullopt;
@@ -67,28 +63,14 @@ createFeeTx(
obj.setAccountID(sfAccount, AccountID());
obj.setFieldU32(sfLedgerSequence, seq);
if (rules.enabled(featureXRPFees))
{
// New XRPFees format - all three fields are REQUIRED
obj.setFieldAmount(
sfBaseFeeDrops, fields.baseFeeDrops ? *fields.baseFeeDrops : XRPAmount{0});
obj.setFieldAmount(
sfReserveBaseDrops,
fields.reserveBaseDrops ? *fields.reserveBaseDrops : XRPAmount{0});
obj.setFieldAmount(
sfReserveIncrementDrops,
fields.reserveIncrementDrops ? *fields.reserveIncrementDrops : XRPAmount{0});
}
else
{
// Legacy format - all four fields are REQUIRED
obj.setFieldU64(sfBaseFee, fields.baseFee ? *fields.baseFee : 0);
obj.setFieldU32(sfReserveBase, fields.reserveBase ? *fields.reserveBase : 0);
obj.setFieldU32(
sfReserveIncrement, fields.reserveIncrement ? *fields.reserveIncrement : 0);
obj.setFieldU32(
sfReferenceFeeUnits, fields.referenceFeeUnits ? *fields.referenceFeeUnits : 0);
}
// XRPFees feature has been retired - all three fields are REQUIRED
obj.setFieldAmount(
sfBaseFeeDrops, fields.baseFeeDrops ? *fields.baseFeeDrops : XRPAmount{0});
obj.setFieldAmount(
sfReserveBaseDrops, fields.reserveBaseDrops ? *fields.reserveBaseDrops : XRPAmount{0});
obj.setFieldAmount(
sfReserveIncrementDrops,
fields.reserveIncrementDrops ? *fields.reserveIncrementDrops : XRPAmount{0});
if (rules.enabled(featureSmartEscrow) || forceAllFields)
{
obj.setFieldU32(sfGasLimit, fields.gasLimit ? *fields.gasLimit : 0);
@@ -100,61 +82,35 @@ createFeeTx(
return STTx(ttFEE, fill);
}
// A ttFEE transaction that omits the (now mandatory) *Drops fields.
STTx
createInvalidFeeTx(
Rules const& rules,
std::uint32_t seq,
bool missingRequiredFields = true,
bool wrongFeatureFields = false,
std::uint32_t uniqueValue = 42)
createFeeTxMissingRequiredFields(std::uint32_t seq)
{
auto const fill = [&](auto& obj) {
return STTx(ttFEE, [&](auto& obj) {
obj.setAccountID(sfAccount, AccountID());
obj.setFieldU32(sfLedgerSequence, seq);
});
}
// A ttFEE transaction that carries all the required *Drops fields, but also
// the pre-XRPFees legacy fields, which are forbidden now that XRPFees has
// been retired.
STTx
createFeeTxWithLegacyFields(std::uint32_t seq)
{
return STTx(ttFEE, [&](auto& obj) {
obj.setAccountID(sfAccount, AccountID());
obj.setFieldU32(sfLedgerSequence, seq);
if (wrongFeatureFields)
{
if (rules.enabled(featureXRPFees))
{
obj.setFieldU64(sfBaseFee, 10 + uniqueValue);
obj.setFieldU32(sfReserveBase, 200000);
obj.setFieldU32(sfReserveIncrement, 50000);
obj.setFieldU32(sfReferenceFeeUnits, 10);
}
else
{
obj.setFieldAmount(sfBaseFeeDrops, XRPAmount{10 + uniqueValue});
obj.setFieldAmount(sfReserveBaseDrops, XRPAmount{200000});
obj.setFieldAmount(sfReserveIncrementDrops, XRPAmount{50000});
}
}
else if (!missingRequiredFields)
{
// Create valid transaction (all required fields present)
if (rules.enabled(featureXRPFees))
{
obj.setFieldAmount(sfBaseFeeDrops, XRPAmount{10 + uniqueValue});
obj.setFieldAmount(sfReserveBaseDrops, XRPAmount{200000});
obj.setFieldAmount(sfReserveIncrementDrops, XRPAmount{50000});
}
else
{
obj.setFieldU64(sfBaseFee, 10 + uniqueValue);
obj.setFieldU32(sfReserveBase, 200000);
obj.setFieldU32(sfReserveIncrement, 50000);
obj.setFieldU32(sfReferenceFeeUnits, 10);
}
if (rules.enabled(featureSmartEscrow))
{
obj.setFieldU32(sfGasLimit, 100 + uniqueValue);
obj.setFieldU32(sfBytecodeSizeLimit, 200 + uniqueValue);
obj.setFieldU32(sfGasPrice, 300 + uniqueValue);
}
}
// If missingRequiredFields is true, we don't add the required fields
// (default behavior)
};
return STTx(ttFEE, fill);
obj.setFieldAmount(sfBaseFeeDrops, XRPAmount{10});
obj.setFieldAmount(sfReserveBaseDrops, XRPAmount{200000});
obj.setFieldAmount(sfReserveIncrementDrops, XRPAmount{50000});
obj.setFieldU64(sfBaseFee, 10);
obj.setFieldU32(sfReserveBase, 200000);
obj.setFieldU32(sfReserveIncrement, 50000);
obj.setFieldU32(sfReferenceFeeUnits, 10);
});
}
TER
@@ -180,38 +136,18 @@ verifyFeeObject(
return feeObject->at(field) == expected;
};
if (rules.enabled(featureXRPFees))
{
if (feeObject->isFieldPresent(sfBaseFee) || feeObject->isFieldPresent(sfReserveBase) ||
feeObject->isFieldPresent(sfReserveIncrement) ||
feeObject->isFieldPresent(sfReferenceFeeUnits))
return false;
if (feeObject->isFieldPresent(sfBaseFee) || feeObject->isFieldPresent(sfReserveBase) ||
feeObject->isFieldPresent(sfReserveIncrement) ||
feeObject->isFieldPresent(sfReferenceFeeUnits))
return false;
if (!checkEquality(sfBaseFeeDrops, expected.baseFeeDrops.value_or(XRPAmount{0})))
return false;
if (!checkEquality(sfReserveBaseDrops, expected.reserveBaseDrops.value_or(XRPAmount{0})))
return false;
if (!checkEquality(
sfReserveIncrementDrops, expected.reserveIncrementDrops.value_or(XRPAmount{0})))
return false;
}
else
{
if (feeObject->isFieldPresent(sfBaseFeeDrops) ||
feeObject->isFieldPresent(sfReserveBaseDrops) ||
feeObject->isFieldPresent(sfReserveIncrementDrops))
return false;
// Read sfBaseFee as a hex string and compare to expected.baseFee
if (!checkEquality(sfBaseFee, expected.baseFee))
return false;
if (!checkEquality(sfReserveBase, expected.reserveBase))
return false;
if (!checkEquality(sfReserveIncrement, expected.reserveIncrement))
return false;
if (!checkEquality(sfReferenceFeeUnits, expected.referenceFeeUnits))
return false;
}
if (!checkEquality(sfBaseFeeDrops, expected.baseFeeDrops.value_or(XRPAmount{0})))
return false;
if (!checkEquality(sfReserveBaseDrops, expected.reserveBaseDrops.value_or(XRPAmount{0})))
return false;
if (!checkEquality(
sfReserveIncrementDrops, expected.reserveIncrementDrops.value_or(XRPAmount{0})))
return false;
if (rules.enabled(featureSmartEscrow))
{
if (!checkEquality(sfGasLimit, expected.gasLimit.value_or(0)))
@@ -381,38 +317,7 @@ class FeeVote_test : public beast::unit_test::Suite
{
testcase("Basic SetFee transaction");
// Test with XRPFees disabled (legacy format)
{
jtx::Env env(*this, jtx::testableAmendments() - featureXRPFees - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
env.app().config().fees.toFees(),
std::vector<UInt256>{},
env.app().getNodeFamily());
// Create the next ledger to apply transaction to
ledger = std::make_shared<Ledger>(*ledger, env.app().getTimeKeeper().closeTime());
// Test successful fee transaction with legacy fields
FeeSettingsFields const fields{
.baseFee = 10,
.reserveBase = 200000,
.reserveIncrement = 50000,
.referenceFeeUnits = 10,
};
auto const feeTx = createFeeTx(ledger->rules(), ledger->seq(), fields);
OpenView accum(ledger.get());
BEAST_EXPECT(isTesSuccess(applyFeeAndTestResult(env, accum, feeTx)));
accum.apply(*ledger);
// Verify fee object was created/updated correctly
BEAST_EXPECT(verifyFeeObject(ledger, ledger->rules(), fields));
}
// Test with XRPFees enabled (new format)
// Test without SmartEscrow
{
jtx::Env env(*this, jtx::testableAmendments() - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
@@ -441,7 +346,7 @@ class FeeVote_test : public beast::unit_test::Suite
BEAST_EXPECT(verifyFeeObject(ledger, ledger->rules(), fields));
}
// Test with both XRPFees and SmartEscrow enabled
// Test with SmartEscrow enabled
{
jtx::Env env(*this, jtx::testableAmendments());
auto ledger = std::make_shared<Ledger>(
@@ -583,30 +488,6 @@ class FeeVote_test : public beast::unit_test::Suite
{
testcase("Fee Transaction Validation");
{
jtx::Env env(*this, jtx::testableAmendments() - featureXRPFees - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
env.app().config().fees.toFees(),
std::vector<UInt256>{},
env.app().getNodeFamily());
// Create the next ledger to apply transaction to
ledger = std::make_shared<Ledger>(*ledger, env.app().getTimeKeeper().closeTime());
// Test transaction with missing required legacy fields
auto const invalidTx =
createInvalidFeeTx(ledger->rules(), ledger->seq(), true, false, 1);
OpenView accum(ledger.get());
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, invalidTx)));
// Test transaction with new format fields when XRPFees is disabled
auto const disallowedTx =
createInvalidFeeTx(ledger->rules(), ledger->seq(), false, true, 2);
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, disallowedTx)));
}
{
jtx::Env env(*this, jtx::testableAmendments() - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
@@ -619,20 +500,30 @@ class FeeVote_test : public beast::unit_test::Suite
// Create the next ledger to apply transaction to
ledger = std::make_shared<Ledger>(*ledger, env.app().getTimeKeeper().closeTime());
// Test transaction with missing required new fields
auto const invalidTx =
createInvalidFeeTx(ledger->rules(), ledger->seq(), true, false, 3);
OpenView accum(ledger.get());
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, invalidTx)));
// Test transaction with legacy fields when XRPFees is enabled
auto const disallowedTx =
createInvalidFeeTx(ledger->rules(), ledger->seq(), false, true, 4);
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, disallowedTx)));
// Test transaction with missing required new fields
auto const missingTx = createFeeTxMissingRequiredFields(ledger->seq());
BEAST_EXPECT(applyFeeAndTestResult(env, accum, missingTx) == temMALFORMED);
// Test transaction that has all the required fields but also carries
// the legacy fields. Now that XRPFees is retired those are forbidden,
// and rejected with temMALFORMED rather than the former temDISABLED.
auto const disallowedTx = createFeeTxWithLegacyFields(ledger->seq());
BEAST_EXPECT(applyFeeAndTestResult(env, accum, disallowedTx) == temMALFORMED);
Serializer s;
disallowedTx.add(s);
SerialIter sit(s.slice());
STTx const parsedTx(sit);
BEAST_EXPECT(parsedTx.getFieldU64(sfBaseFee) == 10);
BEAST_EXPECT(parsedTx.getFieldU32(sfReferenceFeeUnits) == 10);
BEAST_EXPECT(parsedTx.getFieldU32(sfReserveBase) == 200000);
BEAST_EXPECT(parsedTx.getFieldU32(sfReserveIncrement) == 50000);
}
{
jtx::Env env(*this, jtx::testableAmendments() | featureXRPFees | featureSmartEscrow);
jtx::Env env(*this, jtx::testableAmendments());
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
@@ -643,16 +534,15 @@ class FeeVote_test : public beast::unit_test::Suite
// Create the next ledger to apply transaction to
ledger = std::make_shared<Ledger>(*ledger, env.app().getTimeKeeper().closeTime());
// Test transaction with missing required new fields
auto const invalidTx =
createInvalidFeeTx(ledger->rules(), ledger->seq(), true, false, 5);
OpenView accum(ledger.get());
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, invalidTx)));
// Test transaction with legacy fields when XRPFees is enabled
auto const disallowedTx =
createInvalidFeeTx(ledger->rules(), ledger->seq(), false, true, 6);
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, disallowedTx)));
// Test transaction with missing required new fields
auto const missingTx = createFeeTxMissingRequiredFields(ledger->seq());
BEAST_EXPECT(applyFeeAndTestResult(env, accum, missingTx) == temMALFORMED);
// Test transaction with legacy fields
auto const disallowedTx = createFeeTxWithLegacyFields(ledger->seq());
BEAST_EXPECT(applyFeeAndTestResult(env, accum, disallowedTx) == temMALFORMED);
// Valid XRP fee fields, but none of the gas fields
STTx const noGasTx(ttFEE, [&](auto& obj) {
@@ -881,7 +771,7 @@ class FeeVote_test : public beast::unit_test::Suite
setup.accountReserve = 1234567;
setup.ownerReserve = 7654321;
// Test with XRPFees enabled
// Test without SmartEscrow
{
Env env(*this, testableAmendments() - featureSmartEscrow);
auto feeVote = makeFeeVote(setup, env.app().getJournal("FeeVote"));
@@ -911,35 +801,6 @@ class FeeVote_test : public beast::unit_test::Suite
BEAST_EXPECT(val->getFieldAmount(sfBaseFeeDrops) == XRPAmount(setup.referenceFee));
}
// Test with XRPFees disabled (legacy format)
{
Env env(*this, testableAmendments() - featureXRPFees - featureSmartEscrow);
auto feeVote = makeFeeVote(setup, env.app().getJournal("FeeVote"));
auto const ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
env.app().config().fees.toFees(),
std::vector<UInt256>{},
env.app().getNodeFamily());
auto const sec = randomSecretKey();
auto const pub = derivePublicKey(KeyType::Secp256k1, sec);
auto const val = std::make_shared<STValidation>(
env.app().getTimeKeeper().now(), pub, sec, calcNodeID(pub), [](STValidation& v) {
v.setFieldU32(sfLedgerSequence, 12345);
});
auto const& currentFees = ledger->fees();
feeVote->doValidation(currentFees, ledger->rules(), *val);
// In legacy mode, should vote using legacy fields
BEAST_EXPECT(val->isFieldPresent(sfBaseFee));
BEAST_EXPECT(val->getFieldU64(sfBaseFee) == setup.referenceFee);
}
// A local target of 0 is not emitted on the validation; the field is
// omitted so peers treat it as noVote.
{
@@ -1180,7 +1041,7 @@ class FeeVote_test : public beast::unit_test::Suite
using namespace jtx;
Env env(*this, testableAmendments() | featureXRPFees | featureSmartEscrow);
Env env(*this, testableAmendments());
// establish what the current fees are
BEAST_EXPECT(env.current()->fees().base == XRPAmount{UNIT_TEST_REFERENCE_FEE});
-67
View File
@@ -15,7 +15,6 @@
#include <test/jtx/fee.h>
#include <test/jtx/flags.h>
#include <test/jtx/mpt.h>
#include <test/jtx/multisign.h>
#include <test/jtx/offer.h>
#include <test/jtx/paths.h>
#include <test/jtx/pay.h>
@@ -26,7 +25,6 @@
#include <test/jtx/trust.h>
#include <test/jtx/txflags.h>
#include <test/jtx/vault.h>
#include <test/jtx/xchain_bridge.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/strHex.h>
@@ -1934,7 +1932,6 @@ class MPToken_test : public beast::unit_test::Suite
Account const carol("carol");
MPTIssue const issue(makeMptID(1, alice));
STAmount mpt{issue, UINT64_C(100)};
auto const jvb = bridge(alice, usd, alice, usd);
for (auto const& feature : {features, features - featureMPTokensV1})
{
Env env{*this, feature};
@@ -2086,70 +2083,6 @@ class MPToken_test : public beast::unit_test::Suite
};
trustSet(sfLimitAmount);
trustSet(sfFee);
// XChainCommit
{
json::Value const jv = xchainCommit(alice, jvb, 1, mpt);
test(jv, jss::Amount.cStr());
}
// XChainClaim
{
json::Value const jv = xchainClaim(alice, jvb, 1, mpt, alice);
test(jv, jss::Amount.cStr());
}
// XChainCreateClaimID
{
json::Value const jv = xchainCreateClaimId(alice, jvb, mpt, alice);
test(jv, sfSignatureReward.fieldName);
}
// XChainAddClaimAttestation
{
json::Value const jv =
claimAttestation(alice, jvb, alice, mpt, alice, true, 1, alice, Signer(alice));
test(jv, jss::Amount.cStr());
}
// XChainAddAccountCreateAttestation
{
json::Value jv = createAccountAttestation(
alice, jvb, alice, mpt, XRP(10), alice, false, 1, alice, Signer(alice));
for (auto const& field : {sfAmount.fieldName, sfSignatureReward.fieldName})
{
jv[field] = mpt.getJson(JsonOptions::Values::None);
test(jv, field);
}
}
// XChainAccountCreateCommit
{
json::Value jv = sidechainXchainAccountCreate(alice, jvb, alice, mpt, XRP(10));
for (auto const& field : {sfAmount.fieldName, sfSignatureReward.fieldName})
{
jv[field] = mpt.getJson(JsonOptions::Values::None);
test(jv, field);
}
}
// XChain[Create|Modify]Bridge
auto const bridgeTx = [&](json::StaticString const& tt,
STAmount const& rewardAmount,
STAmount const& minAccountAmount,
std::string const& field) {
json::Value jv;
jv[jss::TransactionType] = tt;
jv[jss::Account] = alice.human();
jv[sfXChainBridge.fieldName] = jvb;
jv[sfSignatureReward.fieldName] = rewardAmount.getJson(JsonOptions::Values::None);
jv[sfMinAccountCreateAmount.fieldName] =
minAccountAmount.getJson(JsonOptions::Values::None);
test(jv, field);
};
auto reward = STAmount{sfSignatureReward, mpt};
auto minAmount = STAmount{sfMinAccountCreateAmount, usd(10)};
for (SField const& field :
{std::ref(sfSignatureReward), std::ref(sfMinAccountCreateAmount)})
{
bridgeTx(jss::XChainCreateBridge, reward, minAmount, field.fieldName);
bridgeTx(jss::XChainModifyBridge, reward, minAmount, field.fieldName);
reward = STAmount{sfSignatureReward, usd(10)};
minAmount = STAmount{sfMinAccountCreateAmount, mpt};
}
// SponsorshipSet
{
json::Value jv;
+182
View File
@@ -19,12 +19,18 @@
#include <test/jtx/trust.h>
#include <test/jtx/txflags.h>
#include <xrpld/rpc/Context.h>
#include <xrpld/rpc/RPCHandler.h>
#include <xrpld/rpc/Role.h>
#include <xrpld/rpc/detail/Tuning.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/random.h>
#include <xrpl/basics/strHex.h>
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/core/Job.h>
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
@@ -41,8 +47,12 @@
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/protocol/nft.h>
#include <xrpl/resource/Charge.h>
#include <xrpl/resource/Consumer.h>
#include <xrpl/resource/Fees.h>
#include <algorithm>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <functional>
@@ -4888,6 +4898,176 @@ class NFTokenBaseUtil_test : public beast::unit_test::Suite
}
}
void
testNftXxxOffersInvalidParams(FeatureBitset features)
{
testcase("nft_buy_offers and nft_sell_offers invalid params");
using namespace test::jtx;
Env env{*this, features};
Account const issuer{"issuer"};
Account const buyer{"buyer"};
env.fund(XRP(10000), issuer, buyer);
env.close();
UInt256 const nftID{token::getNextID(env, issuer, 0u, tfTransferable)};
env(token::mint(issuer, 0), Txflags(tfTransferable));
env.close();
env(token::createOffer(issuer, nftID, XRP(100)), Txflags(tfSellNFToken));
env(token::createOffer(issuer, nftID, XRP(200)), Txflags(tfSellNFToken));
env(token::createOffer(buyer, nftID, XRP(50)), token::Owner(issuer));
env(token::createOffer(buyer, nftID, XRP(60)), token::Owner(issuer));
env.close();
for (auto const* request : {"nft_buy_offers", "nft_sell_offers"})
{
auto const query = [&env, request](json::Value const& params) {
return env.rpc("json", request, to_string(params))[jss::result];
};
auto const withField = [&nftID](json::StaticString field, json::Value value) {
json::Value params;
params[jss::nft_id] = to_string(nftID);
params[field] = std::move(value);
return params;
};
auto const expectError = [this](json::Value const& result, std::string const& message) {
BEAST_EXPECT(result[jss::error] == "invalidParams");
BEAST_EXPECT(result[jss::error_message] == message);
};
expectError(query(json::ValueType::Object), "Missing field 'nft_id'.");
for (json::Value const& nftId : {
json::Value{"NOTHEX"},
json::Value{json::ValueType::Array},
json::Value{json::ValueType::Object},
})
{
json::Value params;
params[jss::nft_id] = nftId;
expectError(query(params), "Invalid field 'nft_id'.");
}
expectError(
query(withField(jss::limit, "1")), "Invalid field 'limit', not unsigned integer.");
expectError(
query(withField(jss::limit, -1)), "Invalid field 'limit', not unsigned integer.");
expectError(query(withField(jss::limit, 0)), "Invalid field 'limit'.");
{
json::Value const result = query(withField(jss::limit, json::ValueType::Null));
BEAST_EXPECT(!result.isMember(jss::error));
BEAST_EXPECT(result[jss::offers].size() == 2);
}
{
json::Value const result = query(withField(jss::limit, 1));
BEAST_EXPECT(!result.isMember(jss::error));
BEAST_EXPECT(result[jss::offers].size() == 1);
BEAST_EXPECT(result[jss::limit] == 1);
BEAST_EXPECT(result.isMember(jss::marker));
}
expectError(query(withField(jss::marker, 5)), "Invalid field 'marker', not string.");
expectError(query(withField(jss::marker, "NOTHEX")), "Invalid parameters.");
}
}
void
testNftXxxOffersNonAdminLimit(FeatureBitset features)
{
testcase("nft_buy_offers and nft_sell_offers non-admin limit");
using namespace test::jtx;
Env env{*this, features};
Account const issuer{"issuer"};
Account const buyer{"buyer"};
env.fund(XRP(1000000), issuer, buyer);
env.close();
UInt256 const nftID{token::getNextID(env, issuer, 0u, tfTransferable)};
env(token::mint(issuer, 0), Txflags(tfTransferable));
env.close();
auto const& range = rpc::tuning::kNftOffers;
for (auto i = 1u; i <= range.rmax + 1; ++i)
{
env(token::createOffer(issuer, nftID, XRP(i)), Txflags(tfSellNFToken));
env(token::createOffer(buyer, nftID, XRP(i)), token::Owner(issuer));
if (i % 5 == 0)
env.close();
}
env.close();
auto const userQuery = [this, &env, &nftID](char const* request, unsigned int limit) {
auto& app = env.app();
resource::Charge loadType = resource::kFeeReferenceRpc;
resource::Consumer c;
rpc::JsonContext context{
{
.j = env.journal,
.app = app,
.loadType = loadType,
.netOps = app.getOPs(),
.ledgerMaster = app.getLedgerMaster(),
.consumer = c,
.role = Role::USER,
.coro = {},
.infoSub = {},
.apiVersion = rpc::kApiVersionIfUnspecified,
},
{},
// NOLINTNEXTLINE(readability-trailing-comma) fix-it drops comma after `{}`
{},
};
json::Value params;
params[jss::command] = request;
params[jss::nft_id] = to_string(nftID);
params[jss::limit] = limit;
json::Value result;
Gate g;
auto const job =
app.getJobQueue().postCoro(JtClient, "RPC-Client", [&](auto const& coro) {
context.params = std::move(params);
context.coro = coro;
rpc::doCommand(context, result);
g.signal();
});
if (!BEAST_EXPECT(job))
return result;
using namespace std::chrono_literals;
BEAST_EXPECT(g.waitFor(5s));
job->join();
return result;
};
for (auto const* request : {"nft_buy_offers", "nft_sell_offers"})
{
{
json::Value const result = userQuery(request, 1);
BEAST_EXPECT(!result.isMember(jss::error));
BEAST_EXPECT(result[jss::offers].size() == range.rmin);
BEAST_EXPECT(result[jss::limit] == range.rmin);
BEAST_EXPECT(result.isMember(jss::marker));
}
{
json::Value const result = userQuery(request, range.rmax * 2);
BEAST_EXPECT(!result.isMember(jss::error));
BEAST_EXPECT(result[jss::offers].size() == range.rmax);
BEAST_EXPECT(result[jss::limit] == range.rmax);
BEAST_EXPECT(result.isMember(jss::marker));
}
}
}
void
testNFTokenNegOffer(FeatureBitset features)
{
@@ -7610,6 +7790,8 @@ protected:
testNFTokenDeleteAccount(features);
testNftXxxOffers(features);
testNftXxxOffersMarkerWrongSide(features);
testNftXxxOffersInvalidParams(features);
testNftXxxOffersNonAdminLimit(features);
testNFTokenNegOffer(features);
testIOUWithTransferFee(features);
testBrokeredSaleToSelf(features);
+15 -26
View File
@@ -6564,57 +6564,46 @@ public:
// tfFillOrKill, TakerPays must be filled
{
TER const err = features[fixFillOrKill] ? TER(tesSUCCESS) : tecKILLED;
env(offer(maker, XRP(100), usd(100)));
env.close();
env(offer(taker, usd(100), XRP(101)), Txflags(tfFillOrKill), Ter(err));
env(offer(taker, usd(100), XRP(101)), Txflags(tfFillOrKill));
env.close();
makerXRPBalance -= txFee(env, 1);
takerXRPBalance -= txFee(env, 1);
if (err == tesSUCCESS)
{
makerUSDBalance -= usd(100);
takerUSDBalance += usd(100);
makerXRPBalance += XRP(100).value();
takerXRPBalance -= XRP(100).value();
}
makerUSDBalance -= usd(100);
takerUSDBalance += usd(100);
makerXRPBalance += XRP(100).value();
takerXRPBalance -= XRP(100).value();
BEAST_EXPECT(expectOffers(env, taker, 0));
env(offer(maker, usd(100), XRP(100)));
env.close();
env(offer(taker, XRP(100), usd(101)), Txflags(tfFillOrKill), Ter(err));
env(offer(taker, XRP(100), usd(101)), Txflags(tfFillOrKill));
env.close();
makerXRPBalance -= txFee(env, 1);
takerXRPBalance -= txFee(env, 1);
if (err == tesSUCCESS)
{
makerUSDBalance += usd(100);
takerUSDBalance -= usd(100);
makerXRPBalance -= XRP(100).value();
takerXRPBalance += XRP(100).value();
}
makerUSDBalance += usd(100);
takerUSDBalance -= usd(100);
makerXRPBalance -= XRP(100).value();
takerXRPBalance += XRP(100).value();
BEAST_EXPECT(expectOffers(env, taker, 0));
env(offer(maker, usd(100), eur(100)));
env.close();
env(offer(taker, eur(100), usd(101)), Txflags(tfFillOrKill), Ter(err));
env(offer(taker, eur(100), usd(101)), Txflags(tfFillOrKill));
env.close();
makerXRPBalance -= txFee(env, 1);
takerXRPBalance -= txFee(env, 1);
if (err == tesSUCCESS)
{
makerUSDBalance += usd(100);
takerUSDBalance -= usd(100);
makerEURBalance -= eur(100);
takerEURBalance += eur(100);
}
makerUSDBalance += usd(100);
takerUSDBalance -= usd(100);
makerEURBalance -= eur(100);
takerEURBalance += eur(100);
BEAST_EXPECT(expectOffers(env, taker, 0));
}
+17 -64
View File
@@ -5235,59 +5235,48 @@ public:
auto makerXRPBalance = env.balance(maker, XRP).value();
auto takerXRPBalance = env.balance(taker, XRP).value();
// tfFillOrKill, TakerPays must be filled
// TakerPays must be filled
{
TER const err = features[fixFillOrKill] ? TER(tesSUCCESS) : tecKILLED;
env(offer(maker, XRP(100), usd(100)));
env.close();
env(offer(taker, usd(100), XRP(101)), Txflags(tfFillOrKill), Ter(err));
env(offer(taker, usd(100), XRP(101)), Txflags(tfFillOrKill));
env.close();
makerXRPBalance -= txFee(env, 1);
takerXRPBalance -= txFee(env, 1);
if (isTesSuccess(err))
{
makerUSDBalance -= usd(100);
takerUSDBalance += usd(100);
makerXRPBalance += XRP(100).value();
takerXRPBalance -= XRP(100).value();
}
makerUSDBalance -= usd(100);
takerUSDBalance += usd(100);
makerXRPBalance += XRP(100).value();
takerXRPBalance -= XRP(100).value();
BEAST_EXPECT(expectOffers(env, taker, 0));
env(offer(maker, usd(100), XRP(100)));
env.close();
env(offer(taker, XRP(100), usd(101)), Txflags(tfFillOrKill), Ter(err));
env(offer(taker, XRP(100), usd(101)), Txflags(tfFillOrKill));
env.close();
makerXRPBalance -= txFee(env, 1);
takerXRPBalance -= txFee(env, 1);
if (isTesSuccess(err))
{
makerUSDBalance += usd(100);
takerUSDBalance -= usd(100);
makerXRPBalance -= XRP(100).value();
takerXRPBalance += XRP(100).value();
}
makerUSDBalance += usd(100);
takerUSDBalance -= usd(100);
makerXRPBalance -= XRP(100).value();
takerXRPBalance += XRP(100).value();
BEAST_EXPECT(expectOffers(env, taker, 0));
env(offer(maker, usd(100), eur(100)));
env.close();
env(offer(taker, eur(100), usd(101)), Txflags(tfFillOrKill), Ter(err));
env(offer(taker, eur(100), usd(101)), Txflags(tfFillOrKill));
env.close();
makerXRPBalance -= txFee(env, 1);
takerXRPBalance -= txFee(env, 1);
if (isTesSuccess(err))
{
makerUSDBalance += usd(100);
takerUSDBalance -= usd(100);
makerEURBalance -= eur(100);
takerEURBalance += eur(100);
}
makerUSDBalance += usd(100);
takerUSDBalance -= usd(100);
makerEURBalance -= eur(100);
takerEURBalance += eur(100);
BEAST_EXPECT(expectOffers(env, taker, 0));
}
@@ -5447,47 +5436,11 @@ public:
run() override
{
testAll(allFeatures - featurePermissionedDEX);
testAll(allFeatures);
testFalseAssert();
}
};
class OfferWOSmallQOffers_test : public OfferBaseUtil_test
{
void
run() override
{
testAll(allFeatures - fixFillOrKill - featurePermissionedDEX);
}
};
class OfferAllFeatures_test : public OfferBaseUtil_test
{
void
run() override
{
testAll(allFeatures);
}
};
class Offer_manual_test : public OfferBaseUtil_test
{
void
run() override
{
using namespace jtx;
FeatureBitset const all{testableAmendments()};
FeatureBitset const fillOrKill{fixFillOrKill};
FeatureBitset const permDEX{featurePermissionedDEX};
testAll(all - fillOrKill - permDEX);
testAll(all - permDEX);
testAll(all);
}
};
BEAST_DEFINE_TESTSUITE_PRIO(OfferBaseUtil, app, xrpl, 2);
BEAST_DEFINE_TESTSUITE_PRIO(OfferWOSmallQOffers, app, xrpl, 2);
BEAST_DEFINE_TESTSUITE_PRIO(OfferAllFeatures, app, xrpl, 2);
BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(Offer_manual, app, xrpl, 20);
} // namespace xrpl::test
+4 -17
View File
@@ -30,19 +30,9 @@ struct PseudoTx_test : public beast::unit_test::Suite
res.emplace_back(ttFEE, [&](auto& obj) {
obj[sfAccount] = AccountID();
obj[sfLedgerSequence] = seq;
if (rules.enabled(featureXRPFees))
{
obj[sfBaseFeeDrops] = XRPAmount{0};
obj[sfReserveBaseDrops] = XRPAmount{0};
obj[sfReserveIncrementDrops] = XRPAmount{0};
}
else
{
obj[sfBaseFee] = 0;
obj[sfReserveBase] = 0;
obj[sfReserveIncrement] = 0;
obj[sfReferenceFeeUnits] = 0;
}
obj[sfBaseFeeDrops] = XRPAmount{0};
obj[sfReserveBaseDrops] = XRPAmount{0};
obj[sfReserveIncrementDrops] = XRPAmount{0};
if (rules.enabled(featureSmartEscrow))
{
obj[sfGasLimit] = 0;
@@ -76,7 +66,7 @@ struct PseudoTx_test : public beast::unit_test::Suite
}
void
testPrevented(FeatureBitset features)
testPrevented(FeatureBitset features = test::jtx::testableAmendments())
{
using namespace jtx;
Env env(*this, features);
@@ -111,10 +101,7 @@ struct PseudoTx_test : public beast::unit_test::Suite
{
using namespace test::jtx;
FeatureBitset const all{testableAmendments()};
FeatureBitset const xrpFees{featureXRPFees};
testPrevented(all - featureXRPFees - featureSmartEscrow);
testPrevented(all - featureXRPFees);
testPrevented(all - featureSmartEscrow);
testPrevented(all);
testAllowed();
+34 -15
View File
@@ -1368,7 +1368,7 @@ public:
charlieSeq + 2 == env.seq(charlie),
"charlie: "s + std::to_string(charlieSeq) + ", " + std::to_string(env.seq(charlie)));
BEAST_EXPECTS(
dariaSeq + 1 == env.seq(daria),
dariaSeq == env.seq(daria),
"daria: "s + std::to_string(dariaSeq) + ", " + std::to_string(env.seq(daria)));
BEAST_EXPECTS(
elmoSeq + 1 == env.seq(elmo),
@@ -1377,7 +1377,7 @@ public:
fredSeq == env.seq(fred),
"fred: "s + std::to_string(fredSeq) + ", " + std::to_string(env.seq(fred)));
BEAST_EXPECTS(
gwenSeq == env.seq(gwen),
gwenSeq + 1 == env.seq(gwen),
"gwen: "s + std::to_string(gwenSeq) + ", " + std::to_string(env.seq(gwen)));
BEAST_EXPECTS(
hankSeq + 1 == env.seq(hank),
@@ -1388,10 +1388,10 @@ public:
//++aliceSeq;
++bobSeq;
++(++charlieSeq);
++dariaSeq;
// ++dariaSeq;
++elmoSeq;
// ++fredSeq;
//++gwenSeq;
++gwenSeq;
++hankSeq;
auto const getTxsQueued = [&] {
@@ -2840,18 +2840,24 @@ public:
// may not reduce to 8.
env.close();
checkMetrics(*this, env, 9, 50, 6, 5);
BEAST_EXPECT(env.seq(alice) == aliceSeq + 15);
BEAST_EXPECTS(
env.seq(alice) == aliceSeq + 16,
"alice: " + std::to_string(aliceSeq + 16) + ", " + std::to_string(env.seq(alice)));
// Close ledger 7. That should remove 4 more of alice's transactions.
// Close ledger 7. That should remove 3 more of alice's transactions.
env.close();
checkMetrics(*this, env, 2, 60, 7, 6);
BEAST_EXPECT(env.seq(alice) == aliceSeq + 19);
BEAST_EXPECTS(
env.seq(alice) == aliceSeq + 19,
"alice: " + std::to_string(aliceSeq + 19) + ", " + std::to_string(env.seq(alice)));
// Close one last ledger to see all of alice's transactions moved
// into the ledger, including the tickets
env.close();
checkMetrics(*this, env, 0, 70, 2, 7);
BEAST_EXPECT(env.seq(alice) == aliceSeq + 21);
BEAST_EXPECTS(
env.seq(alice) == aliceSeq + 21,
"alice: " + std::to_string(aliceSeq + 21) + ", " + std::to_string(env.seq(alice)));
}
void
@@ -4439,7 +4445,9 @@ public:
// pushing the local fee up really high and then hoping that we
// outrace LoadManager undoing our work.
for (int i = 0; i < 30; ++i)
{
env.app().getFeeTrack().raiseLocalFee();
}
// Now close the ledger, which will attempt to process alice's
// and bob's queued transactions.
@@ -4507,13 +4515,24 @@ public:
// by queueing another low fee transaction into that spot.
env(noop(bob), ticket::Use(bobTicketSeq + 0), Fee(baseFee * 1.2), Ter(terQUEUED));
// Verify that bob's second transaction was removed from the queue
// by queueing another low fee transaction into that spot.
env(noop(bob), ticket::Use(bobTicketSeq + 1), Fee(baseFee * 1.1), Ter(terQUEUED));
// Verify that the last entry in bob's queue is still there
// by trying to replace it and having that fail.
env(noop(bob), ticket::Use(bobTicketSeq + 2), Ter(telCAN_NOT_QUEUE_FEE));
// The following two TXs should consist of
// - 1 tx that is queued
// - 1 tx that cannot be queued.
// There seems to be a bit of a race condition based on the raiseLocalFee above
// that can produce a different result on Debian bookworm.
// Ultimately we are wanting to check if exactly one of bob's txs is dropped penalized.
auto const ter =
env(noop(bob), ticket::Use(bobTicketSeq + 1), Fee(baseFee * 1.1), Ter(std::ignore))
.ter();
if (ter == terQUEUED)
{
env(noop(bob), ticket::Use(bobTicketSeq + 2), Ter(telCAN_NOT_QUEUE_FEE));
}
else
{
BEAST_EXPECT(ter == telCAN_NOT_QUEUE_FEE);
env(noop(bob), ticket::Use(bobTicketSeq + 2), Fee(baseFee * 1.1), Ter(terQUEUED));
}
}
void
File diff suppressed because it is too large. Load diff
-44
View File
@@ -1,44 +0,0 @@
#pragma once
#include <xrpl/basics/Buffer.h>
#include <xrpl/protocol/AccountID.h>
#include <cstdint>
#include <optional>
namespace xrpl {
class PublicKey;
class SecretKey;
class STXChainBridge;
class STAmount;
namespace test::jtx {
Buffer
signClaimAttestation(
PublicKey const& pk,
SecretKey const& sk,
STXChainBridge const& bridge,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t claimID,
std::optional<AccountID> const& dst);
Buffer
signCreateAccountAttestation(
PublicKey const& pk,
SecretKey const& sk,
STXChainBridge const& bridge,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
STAmount const& rewardAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t createCount,
AccountID const& dst);
} // namespace test::jtx
} // namespace xrpl
-57
View File
@@ -1,57 +0,0 @@
#include <test/jtx/attester.h>
#include <xrpl/basics/Buffer.h>
#include <xrpl/basics/Slice.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/SecretKey.h>
#include <xrpl/protocol/XChainAttestations.h>
#include <cstdint>
#include <optional>
namespace xrpl::test::jtx {
Buffer
signClaimAttestation(
PublicKey const& pk,
SecretKey const& sk,
STXChainBridge const& bridge,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t claimID,
std::optional<AccountID> const& dst)
{
auto const toSign = attestations::AttestationClaim::message(
bridge, sendingAccount, sendingAmount, rewardAccount, wasLockingChainSend, claimID, dst);
return sign(pk, sk, makeSlice(toSign));
}
Buffer
signCreateAccountAttestation(
PublicKey const& pk,
SecretKey const& sk,
STXChainBridge const& bridge,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
STAmount const& rewardAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t createCount,
AccountID const& dst)
{
auto const toSign = attestations::AttestationCreateAccount::message(
bridge,
sendingAccount,
sendingAmount,
rewardAmount,
rewardAccount,
wasLockingChainSend,
createCount,
dst);
return sign(pk, sk, makeSlice(toSign));
}
} // namespace xrpl::test::jtx
-487
View File
@@ -1,487 +0,0 @@
#include <test/jtx/xchain_bridge.h>
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
#include <test/jtx/amount.h>
#include <test/jtx/attester.h>
#include <test/jtx/multisign.h>
#include <xrpl/basics/strHex.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/KeyType.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/STInteger.h>
#include <xrpl/protocol/jss.h>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <string>
#include <vector>
namespace xrpl::test::jtx {
// use this for creating a bridge for a transaction
json::Value
bridge(
Account const& lockingChainDoor,
Issue const& lockingChainIssue,
Account const& issuingChainDoor,
Issue const& issuingChainIssue)
{
json::Value jv;
jv[jss::LockingChainDoor] = lockingChainDoor.human();
jv[jss::LockingChainIssue] = toJson(lockingChainIssue);
jv[jss::IssuingChainDoor] = issuingChainDoor.human();
jv[jss::IssuingChainIssue] = toJson(issuingChainIssue);
return jv;
}
// use this for creating a bridge for a rpc query
json::Value
bridgeRpc(
Account const& lockingChainDoor,
Issue const& lockingChainIssue,
Account const& issuingChainDoor,
Issue const& issuingChainIssue)
{
json::Value jv;
jv[jss::LockingChainDoor] = lockingChainDoor.human();
jv[jss::LockingChainIssue] = toJson(lockingChainIssue);
jv[jss::IssuingChainDoor] = issuingChainDoor.human();
jv[jss::IssuingChainIssue] = toJson(issuingChainIssue);
return jv;
}
json::Value
bridgeCreate(
Account const& acc,
json::Value const& bridge,
STAmount const& reward,
std::optional<STAmount> const& minAccountCreate)
{
json::Value jv;
jv[jss::Account] = acc.human();
jv[sfXChainBridge.getJsonName()] = bridge;
jv[sfSignatureReward.getJsonName()] = reward.getJson(JsonOptions::Values::None);
if (minAccountCreate)
{
jv[sfMinAccountCreateAmount.getJsonName()] =
minAccountCreate->getJson(JsonOptions::Values::None);
}
jv[jss::TransactionType] = jss::XChainCreateBridge;
return jv;
}
json::Value
bridgeModify(
Account const& acc,
json::Value const& bridge,
std::optional<STAmount> const& reward,
std::optional<STAmount> const& minAccountCreate)
{
json::Value jv;
jv[jss::Account] = acc.human();
jv[sfXChainBridge.getJsonName()] = bridge;
if (reward)
jv[sfSignatureReward.getJsonName()] = reward->getJson(JsonOptions::Values::None);
if (minAccountCreate)
{
jv[sfMinAccountCreateAmount.getJsonName()] =
minAccountCreate->getJson(JsonOptions::Values::None);
}
jv[jss::TransactionType] = jss::XChainModifyBridge;
return jv;
}
json::Value
xchainCreateClaimId(
Account const& acc,
json::Value const& bridge,
STAmount const& reward,
Account const& otherChainSource)
{
json::Value jv;
jv[jss::Account] = acc.human();
jv[sfXChainBridge.getJsonName()] = bridge;
jv[sfSignatureReward.getJsonName()] = reward.getJson(JsonOptions::Values::None);
jv[sfOtherChainSource.getJsonName()] = otherChainSource.human();
jv[jss::TransactionType] = jss::XChainCreateClaimID;
return jv;
}
json::Value
xchainCommit(
Account const& acc,
json::Value const& bridge,
std::uint32_t claimID,
AnyAmount const& amt,
std::optional<Account> const& dst)
{
json::Value jv;
jv[jss::Account] = acc.human();
jv[sfXChainBridge.getJsonName()] = bridge;
jv[sfXChainClaimID.getJsonName()] = claimID;
jv[jss::Amount] = amt.value.getJson(JsonOptions::Values::None);
if (dst)
jv[sfOtherChainDestination.getJsonName()] = dst->human();
jv[jss::TransactionType] = jss::XChainCommit;
return jv;
}
json::Value
xchainClaim(
Account const& acc,
json::Value const& bridge,
std::uint32_t claimID,
AnyAmount const& amt,
Account const& dst)
{
json::Value jv;
jv[sfAccount.getJsonName()] = acc.human();
jv[sfXChainBridge.getJsonName()] = bridge;
jv[sfXChainClaimID.getJsonName()] = claimID;
jv[sfDestination.getJsonName()] = dst.human();
jv[sfAmount.getJsonName()] = amt.value.getJson(JsonOptions::Values::None);
jv[jss::TransactionType] = jss::XChainClaim;
return jv;
}
json::Value
sidechainXchainAccountCreate(
Account const& acc,
json::Value const& bridge,
Account const& dst,
AnyAmount const& amt,
AnyAmount const& reward)
{
json::Value jv;
jv[sfAccount.getJsonName()] = acc.human();
jv[sfXChainBridge.getJsonName()] = bridge;
jv[sfDestination.getJsonName()] = dst.human();
jv[sfAmount.getJsonName()] = amt.value.getJson(JsonOptions::Values::None);
jv[sfSignatureReward.getJsonName()] = reward.value.getJson(JsonOptions::Values::None);
jv[jss::TransactionType] = jss::XChainAccountCreateCommit;
return jv;
}
json::Value
claimAttestation(
jtx::Account const& submittingAccount,
json::Value const& jvBridge,
jtx::Account const& sendingAccount,
jtx::AnyAmount const& sendingAmount,
jtx::Account const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t claimID,
std::optional<jtx::Account> const& dst,
jtx::Signer const& signer)
{
STXChainBridge const stBridge(jvBridge);
auto const& pk = signer.account.pk();
auto const& sk = signer.account.sk();
auto const sig = signClaimAttestation(
pk,
sk,
stBridge,
sendingAccount,
sendingAmount.value,
rewardAccount,
wasLockingChainSend,
claimID,
dst);
json::Value result;
result[sfAccount.getJsonName()] = submittingAccount.human();
result[sfXChainBridge.getJsonName()] = jvBridge;
result[sfAttestationSignerAccount.getJsonName()] = signer.account.human();
result[sfPublicKey.getJsonName()] = strHex(pk.slice());
result[sfSignature.getJsonName()] = strHex(sig);
result[sfOtherChainSource.getJsonName()] = toBase58(sendingAccount);
result[sfAmount.getJsonName()] = sendingAmount.value.getJson(JsonOptions::Values::None);
result[sfAttestationRewardAccount.getJsonName()] = toBase58(rewardAccount);
result[sfWasLockingChainSend.getJsonName()] = wasLockingChainSend ? 1 : 0;
result[sfXChainClaimID.getJsonName()] = STUInt64{claimID}.getJson(JsonOptions::Values::None);
if (dst)
result[sfDestination.getJsonName()] = toBase58(*dst);
result[jss::TransactionType] = jss::XChainAddClaimAttestation;
return result;
}
json::Value
createAccountAttestation(
jtx::Account const& submittingAccount,
json::Value const& jvBridge,
jtx::Account const& sendingAccount,
jtx::AnyAmount const& sendingAmount,
jtx::AnyAmount const& rewardAmount,
jtx::Account const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t createCount,
jtx::Account const& dst,
jtx::Signer const& signer)
{
STXChainBridge const stBridge(jvBridge);
auto const& pk = signer.account.pk();
auto const& sk = signer.account.sk();
auto const sig = jtx::signCreateAccountAttestation(
pk,
sk,
stBridge,
sendingAccount,
sendingAmount.value,
rewardAmount.value,
rewardAccount,
wasLockingChainSend,
createCount,
dst);
json::Value result;
result[sfAccount.getJsonName()] = submittingAccount.human();
result[sfXChainBridge.getJsonName()] = jvBridge;
result[sfAttestationSignerAccount.getJsonName()] = signer.account.human();
result[sfPublicKey.getJsonName()] = strHex(pk.slice());
result[sfSignature.getJsonName()] = strHex(sig);
result[sfOtherChainSource.getJsonName()] = toBase58(sendingAccount);
result[sfAmount.getJsonName()] = sendingAmount.value.getJson(JsonOptions::Values::None);
result[sfAttestationRewardAccount.getJsonName()] = toBase58(rewardAccount);
result[sfWasLockingChainSend.getJsonName()] = wasLockingChainSend ? 1 : 0;
result[sfXChainAccountCreateCount.getJsonName()] =
STUInt64{createCount}.getJson(JsonOptions::Values::None);
result[sfDestination.getJsonName()] = toBase58(dst);
result[sfSignatureReward.getJsonName()] = rewardAmount.value.getJson(JsonOptions::Values::None);
result[jss::TransactionType] = jss::XChainAddAccountCreateAttestation;
return result;
}
JValueVec
claimAttestations(
jtx::Account const& submittingAccount,
json::Value const& jvBridge,
jtx::Account const& sendingAccount,
jtx::AnyAmount const& sendingAmount,
std::vector<jtx::Account> const& rewardAccounts,
bool wasLockingChainSend,
std::uint64_t claimID,
std::optional<jtx::Account> const& dst,
std::vector<jtx::Signer> const& signers,
std::size_t const numAtts,
std::size_t const fromIdx)
{
assert(fromIdx + numAtts <= rewardAccounts.size());
assert(fromIdx + numAtts <= signers.size());
JValueVec vec;
vec.reserve(numAtts);
for (auto i = fromIdx; i < fromIdx + numAtts; ++i)
{
vec.emplace_back(claimAttestation(
submittingAccount,
jvBridge,
sendingAccount,
sendingAmount,
rewardAccounts[i],
wasLockingChainSend,
claimID,
dst,
signers[i]));
}
return vec;
}
JValueVec
createAccountAttestations(
jtx::Account const& submittingAccount,
json::Value const& jvBridge,
jtx::Account const& sendingAccount,
jtx::AnyAmount const& sendingAmount,
jtx::AnyAmount const& rewardAmount,
std::vector<jtx::Account> const& rewardAccounts,
bool wasLockingChainSend,
std::uint64_t createCount,
jtx::Account const& dst,
std::vector<jtx::Signer> const& signers,
std::size_t const numAtts,
std::size_t const fromIdx)
{
assert(fromIdx + numAtts <= rewardAccounts.size());
assert(fromIdx + numAtts <= signers.size());
JValueVec vec;
vec.reserve(numAtts);
for (auto i = fromIdx; i < fromIdx + numAtts; ++i)
{
vec.emplace_back(createAccountAttestation(
submittingAccount,
jvBridge,
sendingAccount,
sendingAmount,
rewardAmount,
rewardAccounts[i],
wasLockingChainSend,
createCount,
dst,
signers[i]));
}
return vec;
}
XChainBridgeObjects::XChainBridgeObjects()
: mcDoor("mcDoor")
, mcAlice("mcAlice")
, mcBob("mcBob")
, mcCarol("mcCarol")
, mcGw("mcGw")
, scDoor("scDoor")
, scAlice("scAlice")
, scBob("scBob")
, scCarol("scCarol")
, scGw("scGw")
, scAttester("scAttester")
, scReward("scReward")
, mcuDoor("mcuDoor")
, mcuAlice("mcuAlice")
, mcuBob("mcuBob")
, mcuCarol("mcuCarol")
, mcuGw("mcuGw")
, scuDoor("scuDoor")
, scuAlice("scuAlice")
, scuBob("scuBob")
, scuCarol("scuCarol")
, scuGw("scuGw")
, mcUSD(mcGw["USD"])
, scUSD(scGw["USD"])
, jvXRPBridgeRPC(bridgeRpc(mcDoor, xrpIssue(), Account::kMaster, xrpIssue()))
, jvb(bridge(mcDoor, xrpIssue(), Account::kMaster, xrpIssue()))
, jvub(bridge(mcuDoor, xrpIssue(), Account::kMaster, xrpIssue()))
, features(testableAmendments() | FeatureBitset{featureXChainBridge})
, signers([] {
static constexpr int kNumSigners = kUtXchainDefaultNumSigners;
std::vector<Signer> result;
result.reserve(kNumSigners);
for (int i = 0; i < kNumSigners; ++i)
{
using namespace std::literals;
auto const a = Account(
"signer_"s + std::to_string(i), (i % 2) ? KeyType::Ed25519 : KeyType::Secp256k1);
result.emplace_back(a);
}
return result;
}())
, altSigners([] {
static constexpr int kNumSigners = kUtXchainDefaultNumSigners;
std::vector<Signer> result;
result.reserve(kNumSigners);
for (int i = 0; i < kNumSigners; ++i)
{
using namespace std::literals;
auto const a = Account(
"alt_signer_"s + std::to_string(i),
(i % 2) ? KeyType::Ed25519 : KeyType::Secp256k1);
result.emplace_back(a);
}
return result;
}())
, payee([&] {
std::vector<Account> r;
r.reserve(signers.size());
for (int i = 0, e = signers.size(); i != e; ++i)
{
r.push_back(scReward);
}
return r;
}())
, payees([&] {
std::vector<Account> r;
r.reserve(signers.size());
for (int i = 0, e = signers.size(); i != e; ++i)
{
using namespace std::literals;
auto const a = Account("reward_"s + std::to_string(i));
r.push_back(a);
}
return r;
}())
, reward(XRP(1))
, splitRewardQuorum(divide(reward, STAmount(kUtXchainDefaultQuorum), reward.get<Issue>()))
, splitRewardEveryone(divide(reward, STAmount(kUtXchainDefaultNumSigners), reward.get<Issue>()))
, tinyReward(drops(37))
, tinyRewardSplit(
(divide(tinyReward, STAmount(kUtXchainDefaultQuorum), tinyReward.get<Issue>())))
, tinyRewardRemainder(
tinyReward -
multiply(tinyRewardSplit, STAmount(kUtXchainDefaultQuorum), tinyReward.get<Issue>()))
, oneXrp(XRP(1))
, xrpDust(divide(oneXrp, STAmount(10000), oneXrp.get<Issue>()))
{
}
void
XChainBridgeObjects::createMcBridgeObjects(Env& mcEnv)
{
STAmount const xrpFunds{XRP(10000)};
mcEnv.fund(xrpFunds, mcDoor, mcAlice, mcBob, mcCarol, mcGw);
// Signer's list must match the attestation signers
mcEnv(jtx::signers(mcDoor, signers.size(), signers));
// create XRP bridges in both direction
auto const reward = XRP(1);
STAmount const minCreate = XRP(20);
mcEnv(bridgeCreate(mcDoor, jvb, reward, minCreate));
mcEnv.close();
}
void
XChainBridgeObjects::createScBridgeObjects(Env& scEnv)
{
STAmount const xrpFunds{XRP(10000)};
scEnv.fund(xrpFunds, scDoor, scAlice, scBob, scCarol, scGw, scAttester, scReward);
// Signer's list must match the attestation signers
scEnv(jtx::signers(Account::kMaster, signers.size(), signers));
// create XRP bridges in both direction
auto const reward = XRP(1);
STAmount const minCreate = XRP(20);
scEnv(bridgeCreate(Account::kMaster, jvb, reward, minCreate));
scEnv.close();
}
void
XChainBridgeObjects::createBridgeObjects(Env& mcEnv, Env& scEnv)
{
createMcBridgeObjects(mcEnv);
createScBridgeObjects(scEnv);
}
} // namespace xrpl::test::jtx
-239
View File
@@ -1,239 +0,0 @@
#pragma once
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
#include <test/jtx/amount.h>
#include <test/jtx/multisign.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/SField.h>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <vector>
namespace xrpl::test::jtx {
using JValueVec = std::vector<json::Value>;
constexpr std::size_t kUtXchainDefaultNumSigners = 5;
constexpr std::size_t kUtXchainDefaultQuorum = 4;
json::Value
bridge(
Account const& lockingChainDoor,
Issue const& lockingChainIssue,
Account const& issuingChainDoor,
Issue const& issuingChainIssue);
json::Value
bridgeCreate(
Account const& acc,
json::Value const& bridge,
STAmount const& reward,
std::optional<STAmount> const& minAccountCreate = std::nullopt);
json::Value
bridgeModify(
Account const& acc,
json::Value const& bridge,
std::optional<STAmount> const& reward,
std::optional<STAmount> const& minAccountCreate = std::nullopt);
json::Value
xchainCreateClaimId(
Account const& acc,
json::Value const& bridge,
STAmount const& reward,
Account const& otherChainSource);
json::Value
xchainCommit(
Account const& acc,
json::Value const& bridge,
std::uint32_t claimID,
AnyAmount const& amt,
std::optional<Account> const& dst = std::nullopt);
json::Value
xchainClaim(
Account const& acc,
json::Value const& bridge,
std::uint32_t claimID,
AnyAmount const& amt,
Account const& dst);
json::Value
sidechainXchainAccountCreate(
Account const& acc,
json::Value const& bridge,
Account const& dst,
AnyAmount const& amt,
AnyAmount const& xChainFee);
json::Value
sidechainXchainAccountClaim(
Account const& acc,
json::Value const& bridge,
Account const& dst,
AnyAmount const& amt);
json::Value
claimAttestation(
jtx::Account const& submittingAccount,
json::Value const& jvBridge,
jtx::Account const& sendingAccount,
jtx::AnyAmount const& sendingAmount,
jtx::Account const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t claimID,
std::optional<jtx::Account> const& dst,
jtx::Signer const& signer);
json::Value
createAccountAttestation(
jtx::Account const& submittingAccount,
json::Value const& jvBridge,
jtx::Account const& sendingAccount,
jtx::AnyAmount const& sendingAmount,
jtx::AnyAmount const& rewardAmount,
jtx::Account const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t createCount,
jtx::Account const& dst,
jtx::Signer const& signer);
JValueVec
claimAttestations(
jtx::Account const& submittingAccount,
json::Value const& jvBridge,
jtx::Account const& sendingAccount,
jtx::AnyAmount const& sendingAmount,
std::vector<jtx::Account> const& rewardAccounts,
bool wasLockingChainSend,
std::uint64_t claimID,
std::optional<jtx::Account> const& dst,
std::vector<jtx::Signer> const& signers,
std::size_t const numAtts = kUtXchainDefaultQuorum,
std::size_t const fromIdx = 0);
JValueVec
createAccountAttestations(
jtx::Account const& submittingAccount,
json::Value const& jvBridge,
jtx::Account const& sendingAccount,
jtx::AnyAmount const& sendingAmount,
jtx::AnyAmount const& rewardAmount,
std::vector<jtx::Account> const& rewardAccounts,
bool wasLockingChainSend,
std::uint64_t createCount,
jtx::Account const& dst,
std::vector<jtx::Signer> const& signers,
std::size_t const numAtts = kUtXchainDefaultQuorum,
std::size_t const fromIdx = 0);
struct XChainBridgeObjects
{
// funded accounts
Account const mcDoor;
Account const mcAlice;
Account const mcBob;
Account const mcCarol;
Account const mcGw;
Account const scDoor;
Account const scAlice;
Account const scBob;
Account const scCarol;
Account const scGw;
Account const scAttester;
Account const scReward;
// unfunded accounts
Account const mcuDoor;
Account const mcuAlice;
Account const mcuBob;
Account const mcuCarol;
Account const mcuGw;
Account const scuDoor;
Account const scuAlice;
Account const scuBob;
Account const scuCarol;
Account const scuGw;
IOU const mcUSD;
IOU const scUSD;
json::Value const jvXRPBridgeRPC;
json::Value jvb; // standard xrp bridge def for tx
json::Value jvub; // standard xrp bridge def for tx, unfunded accounts
FeatureBitset const features;
std::vector<Signer> const signers;
std::vector<Signer> const altSigners;
std::vector<Account> const payee;
std::vector<Account> const payees;
std::uint32_t const quorum{kUtXchainDefaultQuorum};
STAmount const reward; // 1 xrp
STAmount const splitRewardQuorum; // 250,000 drops
STAmount const splitRewardEveryone; // 200,000 drops
STAmount const tinyReward; // 37 drops
STAmount const tinyRewardSplit; // 9 drops
STAmount const tinyRewardRemainder; // 1 drops
STAmount const oneXrp;
STAmount const xrpDust;
static constexpr int kDropPerXrp = 1000000;
XChainBridgeObjects();
void
createMcBridgeObjects(Env& mcEnv);
void
createScBridgeObjects(Env& scEnv);
void
createBridgeObjects(Env& mcEnv, Env& scEnv);
JValueVec
attCreateAcctVec(
std::uint64_t createCount,
jtx::AnyAmount const& amt,
jtx::Account const& dst,
std::size_t const numAtts,
std::size_t const fromIdx = 0)
{
return createAccountAttestations(
scAttester,
jvb,
mcCarol,
amt,
reward,
payees,
true,
createCount,
dst,
signers,
numAtts,
fromIdx);
}
[[nodiscard]] json::Value
createBridge(
Account const& acc,
json::Value const& bridge = json::ValueType::Null,
STAmount const& reward = XRP(1),
std::optional<STAmount> const& minAccountCreate = std::nullopt) const
{
return bridgeCreate(
acc, bridge == json::ValueType::Null ? jvb : bridge, reward, minAccountCreate);
}
};
} // namespace xrpl::test::jtx
Loaded 100 of 148 files, more files were not shown because too many files have changed in this diff. Show more