Compare commits

...
Author SHA1 Message Date
Bart fabd2070bd fix: Give every error code an HTTP status
Four rows of the error table name no HTTP status, so the `ErrorInfo`
constructor defaults them to 200. The `ripplerpc: "3.0"` envelope derives
the status from the code, so a reply reporting an error claims success
and anything reading the status, a load balancer above all, reads success
too. Give all four one: `actNotFound` answers 404, matching every
`*NotFound` sibling but `entryNotFound`, and `actMalformed`,
`alreadyMultisig` and `alreadySingleSig` answer 400. Then drop the
constructor that defaulted a status, so no row can omit one again. A gtest
lists by hand the codes that have no row, so an enumerator added without
one fails it, and asserts that every other code names a status other than
200.

No client reads a new status here. `legacyHttpStatus` reports 200 for
exactly those four rows, so the 3.0 envelope answers what it always has.
That list is closed, naming the rows that had no status of their own, so
a row added later reports whatever the table says. The test suite names
the two statuses it compares against most, 200 and 400, as `kOk` and
`kBadRequest`, and every existing assertion on them uses the name.
2026-10-25 12:06:11 -04:00
Bart 1f2a0d7991 style: Realign the error table
The columns of the error table had drifted apart as rows were added, so a reader scanning it follows a ragged edge and a new row has no alignment to copy. Realign all four columns on one set of widths inside the existing `clang-format off` guard, changing no row's content.
2026-10-25 12:06:11 -04:00
Bart 73611f8b20 fix: Mask every credential the server echoes, logs or prints
An error reply echoes the request that caused it, and masking covers four
fields at the top level of an object only. A `secret` nested inside
`params`, where the JSON-RPC transport puts it, comes back in the clear,
as does every other credential field at any depth, and only two sites
mask at all. Collect the names in one list and mask recursively, so
nesting stops mattering and a new field is added once. The list covers
the six names only a reply carries, which is how `wallet_propose` and
`validation_create` wrote a live key to the log; `validation_key` is the
same seed as `validation_seed` in RFC1751 words.

A log is an echo that outlives the reply, so one `loggable()` helper
masks and truncates together and every site that writes a request or a
reply out uses it, the `[rpc_startup]` command and its result included,
and the command line client logs the reply it receives parsed and
masked where it wrote the raw body, a `validation_create` answer among
them, and caps a body it cannot parse at the same length. An
`[rpc_startup]` line that does not parse was echoed raw at fatal, the
one case masking cannot reach, and then run as whatever the parser had
left; it is now reported by position only, since the parser's message
can quote a rejected number verbatim, and skipped. The `HTTP Reply` trace line in libxrpl, which cannot reach the
masker, now carries the status only; the body is logged beside it at
debug, masked when it carries a credential and otherwise as the string
already built for the wire, so a reply with no credential is serialized
once. No site logs an inbound request body at full length, so the method name,
at most the request size limit long, is the one thing a client chooses the
length of in the log. The request-duration line used to climb to warn
and error for a slow request with the request in it; the duration alone
still climbs, and the request stays at debug, so the duration line never
lifts text an anonymous client wrote to the default severity.

Three changes are visible to a caller. A credential in an echoed request
reads `<masked>` wherever it appears, nested inside `params` or a batch
entry too. The command line client masks `request_sent`, which carries
the `admin_password` it copies out of the config, so a failing
`./xrpld account_info rBogus` no longer prints a credential the operator
never typed. And a WebSocket frame that does not parse is answered with
its `size` rather than its body.
2026-10-25 12:06:10 -04:00
Bart 297f255988 refactor: Declare the JSON-RPC and ripplerpc version constants
`ripplerpc`, which selects the reply envelope and accepts three values,
and `jsonrpc`, which names the JSON-RPC protocol version, are spelled as
literals at every call site, so neither field has one place stating what
it accepts. Declare `kRippleRpcVersion1/2/3` beside the `api_version`
constants in ApiVersion.h and `kJsonRpcVersion` in a new
protocol/JsonRpc.h, and use them at every production site that reads
a value: the one in RPCCall.cpp that reads the pair, and the three in
ServerHandler.cpp that default, compare and gate on `ripplerpc`. Every
test site spelling a value as a C++ expression follows. A literal inside
a JSON string fixture is left alone, since substituting there means
assembling the JSON by concatenation. The three `ripplerpc` constants
are declared as one set, so the header states every value the field
accepts, and each has a production user in ServerHandler.cpp.

The two fields keep separate constants and separate headers although
both spell "2.0" today. The specification fixes `jsonrpc` at that value
while `ripplerpc` accepts three, and the `ripplerpc` constants go when
support for API versions 1 and 2 goes, where JSON-RPC is a protocol this
server keeps speaking.

ApiVersion.h's header comment named five constants by unprefixed
spellings that no longer exist, and read as a complete map of the file's
version constants, which it stops being here. Two jtx helpers,
`hasEnvelope2` and `setEnvelope2` in TestHelpers.h, replace the
assertion pair and the request pair that every rewritten test site
repeated. No value changes, on the wire or in a test.
2026-10-24 08:49:56 -04:00
Bart 89c01342c5 refactor: Let json::Value be compared and constructed from a string view
`json::Value` accepts `char const*`, `std::string` and
`json::StaticString`, so a caller holding a `std::string_view` has to
materialize a `std::string` whose characters are then copied a second
time into the value's own storage. Add the missing constructor, which
the `std::string` one delegates to, and an `operator==` that reads the
value's characters in place.

The comparison is constrained to `std::string_view` exactly rather than
taking a view by plain overload. A string literal converts equally well
to a view and to a Value, so a plain overload makes every
`value == "literal"` ambiguous, and a literal `0`, which converts to a
view through `char const*` as well as to a Value, with it.

No reply changes. The two spellings differ only for a view holding an
embedded NUL, which the Value comparison stops at. The `method: "batch"`
check in `ServerHandler.cpp` is the operator's first production user, so
that comparison stops building a `Value` from the literal on every
request.
2026-10-24 08:49:55 -04:00
Bart 8f49ff629d refactor: Remove a publish loop nothing can enter
`pubProposedAccountTransaction` declares an `accountHistoryNotify` vector,
never inserts into it, and then tests it and iterates it. The vector is a
local, so the proof is the function itself: between the declaration and the
loop there are exactly two mentions of it, the condition and the loop, and
neither adds an element. Its sibling `pubAccountTransaction` fills its own
copy, which is what makes the empty one here read as live code.

The compiler corroborates it: with the loop gone the message becomes
`MultiApiJson const`, which is possible only because that loop was its sole
mutator. Nothing is lost with the assertion above the loop either. It held
that a `transJson` result carries no member named `account_history_tx_stream`.
No code writes one: outside the two assertions, the token appears in the
`subscribe` and `unsubscribe` request handlers only. The identical assertion
stays where the loop it guards is live.

No subscriber sees a difference. An account-history subscription is
registered in `subAccountHistory_` alone, so it was never in the map this
function reads, and it receives its transactions from
`pubAccountTransaction`. The same function's guard on three subscription maps
also goes: an earlier return leaves `subRTAccount_` non-empty, so the
condition cannot be false.
2026-10-24 08:49:54 -04:00
Ayaz Salikhov 1f46f75318 build: Don't apply clang-tidy fixes twice via header symlinks (#8636) 2026-10-23 19:28:52 +00:00
Ayaz Salikhov 097cb5e89b fix: Update images/prepare-runner to not trust eMudhra certs (#8631) 2026-10-22 18:05:38 +00:00
a818f25203 refactor: Retire XRPFees amendment (#7349)
Co-authored-by: Mayukha Vadari <[email protected]>
Co-authored-by: Valentin Balaschenko <[email protected]>
Co-authored-by: Ayaz Salikhov <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-22 17:11:24 +00:00
3fa2accfdf refactor: Retire AMM amendment and AMMOverflowOffer fix (#7357)
Co-authored-by: Bart <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-10-22 15:27:46 +00:00
Ayaz Salikhov d3a71b2b42 fix: Don't trust eMudhra certificates (#8629) 2026-10-22 15:01:37 +00:00
Timothy Banks 025aa71930 refactor: Retire FillOrKill fix (#7366) 2026-10-21 16:12:29 +00:00
Mayukha Vadari ef5064eeb9 feat: Remove XChainBridge feature (#8255) 2026-10-20 20:37:02 +00:00
Alex KremerandAyaz Salikhov c2e739f670 refactor: Migrate handlers to rpc-spec (E) (#8613)
Co-authored-by: Ayaz Salikhov <[email protected]>
2026-10-20 15:39:27 +00:00
Alex Kremer 15fac6250d chore: Simplify account and ident checks via rpc-spec (#8620) 2026-10-20 13:25:47 +00:00
184 changed files with 3458 additions and 18793 deletions

No files matched your search

+5 -1
View File
@@ -140,5 +140,9 @@ CheckOptions:
readability-identifier-naming.GlobalFunctionIgnoredRegexp: "^(to_string|hash_append|tuple_hash)$"
HeaderFilterRegex: '^.*/(tests?|xrpl|xrpld)/.*\.(h|hpp|ipp)$'
ExcludeHeaderFilterRegex: '^.*/protocol_autogen/.*\.(h|hpp)$|^.*\.pb\.h$'
# Skip headers reached via add_module's symlinks (<build-dir>/modules/xrpl.lib*/...).
# verify_headers already checks each one under its real path,
# so reporting it twice would also apply its fixes twice.
# .ipp files are kept: they are only ever reached via the symlink.
ExcludeHeaderFilterRegex: '^.*/protocol_autogen/.*\.(h|hpp)$|^.*\.pb\.h$|^.*/modules/xrpl\.lib[^/]+/.*\.(h|hpp)$'
WarningsAsErrors: "*"
+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
@@ -175,6 +175,7 @@ test.server > xrpl.basics
test.server > xrpl.config
test.server > xrpld.app
test.server > xrpld.core
test.server > xrpld.rpc
test.server > xrpl.json
test.server > xrpl.protocol
test.server > xrpl.server
+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
+16
View File
@@ -22,10 +22,24 @@ API version 2 is available in `xrpld` version 2.0.0 and later. See [API-VERSION-
This version is supported by all `xrpld` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
## Unreleased
### Bugfixes
- Every credential-bearing field is masked wherever a request or a reply is echoed, logged or printed: `admin_password`, `admin_user`, `master_key`, `master_seed`, `master_seed_hex`, `passphrase`, `password`, `secret`, `seed`, `seed_hex`, `url_password`, `url_username`, `username`, `validation_key`, `validation_private_key` and `validation_seed`. The one list applies to a request echoed back in an error reply and to every request and reply written to the log. Nesting no longer matters, so a credential inside `params` is masked too. Six of the sixteen names, `master_key`, `master_seed`, `master_seed_hex`, `validation_key`, `validation_private_key` and `validation_seed`, occur only in a reply, which is how `wallet_propose` and `validation_create` used to write a live private key to the log. The `id`, `jsonrpc`, `ripplerpc` and `api_version` members a legacy reply echoes from the request are masked the same way. The command line client's trace of a reply's header covers the header only, not the body bytes read with it. A request or reply written to the log is truncated at 10,000 characters. An `[rpc_startup]` line that does not parse is reported by its position in the section alone, never by its text or by the parser's message, and no command runs for it.
- The command line client no longer prints a credential the operator did not type. A failing command echoes the request it built under `request_sent`, which carries the `admin_password` the client copies out of `[port_rpc]` in the config, so `./xrpld account_info rBogus` printed that password to stdout and into any captured output. `request_sent` is now masked. The `rpc` member beside it, which echoes the arguments as they were typed, is unchanged. The command line client also no longer writes an unparsed `json` or `ripple_path_find` argument to its trace log before parsing it, where a `secret` inside that argument could not be masked; it logs the parsed request instead, masked. The reply it receives is logged the same way, parsed and masked, where the raw body was written before, a `validation_create` answer included.
- A WebSocket frame that does not parse, or exceeds the request size limit, is answered `{"type": "error", "error": "jsonInvalid", "size": <bytes>}`. The frame's body is reported by size rather than echoed back in a `value` member, since a body that does not parse has no fields to mask. A client that read `value` gets `size` instead.
- Four error codes that named no HTTP status of their own, and so answered 200 on a reply reporting an error, now name one: `actMalformed`, `alreadyMultisig` and `alreadySingleSig` answer 400, and `actNotFound` answers 404. **No shipped envelope reports these four.** A request sending `ripplerpc: "3.0"` still receives 200 for all four, as it always has, so `account_info` on a malformed account or one the ledger does not hold answers 200 exactly as before.
## XRP Ledger server version 3.5.0
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 +52,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
+4 -3
View File
@@ -365,14 +365,15 @@ With this set, the hook will run as part of `git commit` alongside the other pre
Then run clang-tidy on your local changes:
```
run-clang-tidy -p build -allow-no-checks src tests
run-clang-tidy -p build -allow-no-checks include src tests
```
This will check all source files in the `src`, `include` and `tests` directories using the compile commands from your `build` directory.
This will check all source files in the `include`, `src` and `tests` directories using the compile commands from your `build` directory.
Headers are checked on their own, which requires the `verify_headers` CMake option (ON by default).
If you wish to automatically fix whatever clang-tidy finds _and_ is capable of fixing, add `-fix -format` to the above command:
```
run-clang-tidy -p build -quiet -fix -format -allow-no-checks src tests
run-clang-tidy -p build -quiet -fix -format -allow-no-checks include src tests
```
`-format` reformats the fixed code with [`.clang-format`](./.clang-format); without it the fixes are inserted in LLVM style and the `clang-format` hook rewrites them afterwards.
+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
+15 -66
View File
@@ -5,15 +5,6 @@ The script determines the staged files itself (see `pass_filenames: false` in
.pre-commit-config.yaml) so run-clang-tidy is run once and handles parallelism
internally: pre-commit would otherwise split the files across parallel hook
invocations that race when fixes edit a shared header.
Fixes are collected with `-export-fixes` and applied by clang-apply-replacements
in a separate step rather than with run-clang-tidy's `-fix`. The `add_module`
build isolates each module's headers behind a per-module symlink directory
(build/modules/<module>/...), so a header reachable from several translation
units is referenced through different paths that all resolve to the same source
file. clang-apply-replacements deduplicates identical replacements by their
literal path, so those paths must be canonicalised to the real source path
first; otherwise the same fix is applied once per path and corrupts the header.
"""
from __future__ import annotations
@@ -23,7 +14,6 @@ import re
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
# Extensions run-clang-tidy can analyse: `.cpp` translation units and, thanks to
@@ -31,11 +21,6 @@ from pathlib import Path
# compile_commands.json entry). `.ipp` fragments have no entry and are skipped.
TIDY_EXTENSIONS = {".cpp", ".h", ".hpp"}
# A single-quoted `FilePath:` entry in an -export-fixes YAML file, allowing the
# `- ` marker that precedes it inside a `Replacements:` sequence. clang-tidy
# emits paths single-quoted and doubles any embedded quote per YAML rules.
FILEPATH_RE = re.compile(r"^(\s*(?:-\s+)?FilePath:\s*)'((?:[^']|'')*)'\s*$")
def clang_tidy_major() -> str | None:
"""Major version of the `clang-tidy` on PATH, which run-clang-tidy invokes."""
@@ -79,25 +64,6 @@ def staged_files(repo_root: Path) -> list[Path]:
return [repo_root / rel for rel in output.splitlines() if rel]
def canonicalize_fix_paths(fixes_dir: Path) -> None:
"""Rewrite every `FilePath` in the exported fixes to its real source path.
A header included through a module's isolation symlink is recorded under that
symlink's path; collapsing all paths to the same real file lets
clang-apply-replacements recognise the per-translation-unit duplicates and
apply each fix once.
"""
for yaml in fixes_dir.glob("*.yaml"):
lines = []
for line in yaml.read_text().splitlines():
if m := FILEPATH_RE.match(line):
path = m.group(2).replace("''", "'")
real = os.path.realpath(path).replace("'", "''")
line = f"{m.group(1)}'{real}'"
lines.append(line)
yaml.write_text("\n".join(lines) + "\n")
def main():
if not os.environ.get("TIDY"):
return 0
@@ -116,19 +82,10 @@ def main():
version = clang_tidy_major()
run_clang_tidy = find_tool("run-clang-tidy", version)
clang_apply_replacements = find_tool("clang-apply-replacements", version)
missing = [
name
for name, path in (
("run-clang-tidy", run_clang_tidy),
("clang-apply-replacements", clang_apply_replacements),
)
if not path
]
if missing:
if not run_clang_tidy:
tried = f" (tried the '-{version}' suffix too)" if version else ""
print(
f"clang-tidy check failed: TIDY is enabled but {' and '.join(missing)} "
f"clang-tidy check failed: TIDY is enabled but run-clang-tidy "
f"was not found in PATH{tried}.",
file=sys.stderr,
)
@@ -143,27 +100,19 @@ def main():
)
return 1
with tempfile.TemporaryDirectory() as fixes_dir:
result = subprocess.run(
[
run_clang_tidy,
"-quiet",
"-p",
build_dir,
"-export-fixes",
fixes_dir,
"-allow-no-checks",
]
+ files
)
canonicalize_fix_paths(Path(fixes_dir))
# `FormatStyle` in .clang-tidy does not reach this path,
# so ask for the repository style here.
applied = subprocess.run(
[clang_apply_replacements, "--format", "--style=file", fixes_dir]
)
return result.returncode or applied.returncode
result = subprocess.run(
[
run_clang_tidy,
"-quiet",
"-p",
build_dir,
"-fix",
"-format",
"-allow-no-checks",
]
+ files
)
return result.returncode
if __name__ == "__main__":
+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 -1
View File
@@ -34,11 +34,12 @@ include(create_symbolic_link)
# sometimes `PUBLIC` and sometimes `PRIVATE`.
# The Cs are all guaranteed to be unique.
# We can guarantee a unique X per target by using
# `${CMAKE_CURRENT_BINARY_DIR}/include/${target}`.
# `${CMAKE_CURRENT_BINARY_DIR}/modules/${target}`.
#
# isolate_headers(target A B scope)
function(isolate_headers target A B scope)
file(RELATIVE_PATH C "${A}" "${B}")
# Keep in sync with ExcludeHeaderFilterRegex in .clang-tidy.
set(X "${CMAKE_CURRENT_BINARY_DIR}/modules/${target}")
set(Y "${X}/${C}")
cmake_path(GET Y PARENT_PATH parent)
+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",
]
+37
View File
@@ -3,11 +3,13 @@
#include <xrpl/basics/Number.h>
#include <xrpl/json/json_forwards.h>
#include <concepts>
#include <cstring>
#include <iterator>
#include <limits>
#include <map>
#include <string>
#include <string_view>
#include <vector>
/**
@@ -198,6 +200,15 @@ public:
*/
Value(StaticString const& value);
Value(std::string const& value);
/**
* @brief Constructs a value from a string view.
*
* The characters are copied, so the view need not outlive the call and need
* not be NUL-terminated.
*
* @param value The characters to copy.
*/
Value(std::string_view value);
Value(bool value);
Value(Value const& other);
~Value();
@@ -472,6 +483,32 @@ toJson(xrpl::Number const& number)
bool
operator==(Value const&, Value const&);
/**
* Compares a value with a string view, reading the value's characters in place
* rather than building a Value from the view.
*
* Constrained to the exact type: a string literal converts equally well to a
* view and to a Value, so a plain overload makes `value == "literal"`
* ambiguous.
*
* @param x The value to compare.
* @param y The characters to compare it against.
* @return Whether `x` is a string whose characters up to its first NUL are
* exactly the characters of `y`.
*/
template <class T>
requires std::same_as<T, std::string_view>
bool
operator==(Value const& x, T y)
{
if (!x.isString())
return false;
// A string `Value` can hold a null pointer, which names no characters, so it equals no view.
char const* const s = x.asCString();
return s != nullptr && std::string_view{s} == y;
}
bool
operator<(Value const&, Value const&);
-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}
+17 -17
View File
@@ -6,31 +6,21 @@
#include <xrpl/protocol/jss.h>
#include <cstddef>
#include <string_view>
#include <type_traits>
#include <utility>
namespace xrpl {
/**
* API version numbers used in later API versions
* The `api_version` numbers this server serves.
*
* Requests with a version number in the range
* [apiMinimumSupportedVersion, apiMaximumSupportedVersion]
* are supported.
* A request naming a version in [kApiMinimumSupportedVersion,
* kApiMaximumSupportedVersion] is served. With `[beta_rpc_api]` set to `1` in
* the config the range extends to kApiBetaVersion.
*
* If [beta_rpc_api] is enabled in config, the version numbers
* in the range [apiMinimumSupportedVersion, apiBetaVersion]
* are supported.
*
* Network Requests without explicit version numbers use
* apiVersionIfUnspecified. apiVersionIfUnspecified is 1,
* because all the RPC requests with a version >= 2 must
* explicitly specify the version in the requests.
* Note that apiVersionIfUnspecified will be lower than
* apiMinimumSupportedVersion when we stop supporting API
* version 1.
*
* Command line Requests use apiCommandLineVersion.
* A request naming no version is served at kApiVersionIfUnspecified, which is 1
* because a request wanting any later version states it.
*/
namespace rpc {
@@ -57,6 +47,16 @@ static_assert(kApiMaximumSupportedVersion >= kApiMinimumSupportedVersion);
static_assert(kApiBetaVersion >= kApiMaximumSupportedVersion);
static_assert(kApiMaximumValidVersion >= kApiMaximumSupportedVersion);
/**
* Values accepted in the `ripplerpc` request field, which selects the shape of
* the JSON-RPC reply envelope. Distinct from `kJsonRpcVersion` in JsonRpc.h,
* which names the JSON-RPC protocol itself, and from the `api_version`
* constants above, which select the content of the response.
*/
inline constexpr std::string_view kRippleRpcVersion1{"1.0"};
inline constexpr std::string_view kRippleRpcVersion2{"2.0"};
inline constexpr std::string_view kRippleRpcVersion3{"3.0"};
inline void
setVersion(json::Value& parent, unsigned int apiVersion, bool betaEnabled)
{
-5
View File
@@ -180,11 +180,6 @@ struct ErrorInfo
{
}
constexpr ErrorInfo(ErrorCodeI code, char const* token, char const* message)
: code(code), token(token), message(message), httpStatus(200)
{
}
constexpr ErrorInfo(ErrorCodeI code, char const* token, char const* message, int httpStatus)
: code(code), token(token), message(message), httpStatus(httpStatus)
{
-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;
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include <string_view>
namespace xrpl::rpc {
/**
* Constants of the JSON-RPC 2.0 protocol itself.
*
* Kept apart from the `api_version` and `ripplerpc` constants in ApiVersion.h,
* which go when support for API versions 1 and 2 goes.
*/
/**
* Value of the `jsonrpc` member of a request and of its reply, fixed at "2.0"
* by the JSON-RPC specification.
*/
inline constexpr std::string_view kJsonRpcVersion{"2.0"};
} // namespace xrpl::rpc
+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
+1 -3
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
@@ -562,7 +560,7 @@ JSS(signing_key); // out: NetworkOPs
JSS(signing_keys); // out: ValidatorList
JSS(signing_time); // out: NetworkOPs
JSS(signer_lists); // in/out: AccountInfo
JSS(size); // out: get_aggregate_price
JSS(size); // out: get_aggregate_price, ServerHandler
JSS(snapshot); // in: Subscribe
JSS(source_account); // in: PathRequest, RipplePathFind
JSS(source_amount); // in: PathRequest, RipplePathFind
@@ -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
+12
View File
@@ -7,6 +7,18 @@
namespace xrpl {
/**
* Writes an HTTP reply carrying @p strMsg with status @p nStatus to @p output,
* and logs the status at trace. The body is not logged here: it may carry a
* credential this library cannot mask, so the caller logs it masked.
*
* A 401 with an empty body is answered with the fixed authentication page.
*
* @param nStatus The HTTP status code.
* @param strMsg The body.
* @param output Where the reply bytes are written.
* @param j The journal the status is logged to.
*/
void
httpReply(int nStatus, std::string const& strMsg, json::Output const&, beast::Journal j);
+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
+13 -2
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: {
@@ -52,8 +62,8 @@ let
# version-suffixed name first and fall back to a system binary on the PATH
# when Nix doesn't provide it:
# - Conan's Boost recipe looks up `g++-<major>` before plain `g++`.
# - bin/pre-commit/clang_tidy_check.py looks up `run-clang-tidy-<v>` and
# `clang-apply-replacements-<v>` before the unsuffixed names.
# - bin/pre-commit/clang_tidy_check.py looks up `run-clang-tidy-<v>`
# before the unsuffixed name.
# On a host that also has the matching system binary
# (e.g. Ubuntu's `/usr/bin/g++-<v>` or `clang-tidy-<v>`),
# the probe escapes Nix and mixes a system tool into the Nix environment.
@@ -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}" != ""
+8 -3
View File
@@ -15,6 +15,7 @@
#include <cstring>
#include <limits>
#include <string>
#include <string_view>
#include <utility>
namespace json {
@@ -241,10 +242,14 @@ Value::Value(xrpl::Number const& value) : type_(ValueType::String), allocated_(t
value_.stringVal = valueAllocator()->duplicateStringValue(tmp.c_str(), tmp.length());
}
Value::Value(std::string const& value) : type_(ValueType::String), allocated_(true)
Value::Value(std::string const& value) : Value(std::string_view{value})
{
value_.stringVal =
valueAllocator()->duplicateStringValue(value.c_str(), (unsigned int)value.length());
}
Value::Value(std::string_view value) : type_(ValueType::String), allocated_(true)
{
value_.stringVal = valueAllocator()->duplicateStringValue(
value.data(), static_cast<unsigned int>(value.length()));
}
Value::Value(StaticString const& value) : type_(ValueType::String)
+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
+12 -1
View File
@@ -30,6 +30,7 @@
#include <optional>
#include <ostream>
#include <string>
#include <string_view>
namespace xrpl {
@@ -363,12 +364,22 @@ public:
}
}
/**
* Reads the status line and headers of the reply, then the body.
*
* @param ecResult The outcome of the read that delivered the header.
* @param bytesTransferred The length of the header through its `\r\n\r\n`
* delimiter; the buffer can hold body bytes read past it.
*/
void
handleHeader(boost::system::error_code const& ecResult, std::size_t bytesTransferred)
{
std::string strHeader{
{std::istreambuf_iterator<char>(&header_)}, std::istreambuf_iterator<char>()};
JLOG(j_.trace()) << "Header: \"" << strHeader << "\"";
// The trace covers the header only: the bytes read past the delimiter are body, which can
// carry a credential.
JLOG(j_.trace()) << "Header: \"" << std::string_view{strHeader}.substr(0, bytesTransferred)
<< "\"";
static boost::regex const kReStatus{R"(\`HTTP/1\S+ (\d{3}) .*\')"}; // HTTP/1.1 200 OK
static boost::regex const kReSize{
-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
+78 -74
View File
@@ -20,88 +20,92 @@ namespace detail {
// will remain in the object file. But the string literals will remain.
//
// There's a certain amount of tension in determining the correct HTTP
// status to associate with a given RPC error. Initially all RPC errors
// returned 200 (OK). And that's the default behavior if no HTTP status code
// is specified below.
// status to associate with a given RPC error. Every row below names its
// HTTP status, and a row that omits it does not compile, since ErrorInfo has
// no constructor that leaves the status out.
//
// The codes currently selected target the load balancer fail-over use case.
// If a query fails on one node but is likely to have a positive outcome
// on a different node, then the failure should return a 4xx/5xx range
// status code.
// The rows below are aligned by hand into four columns, so that a wrong status or a mistyped token
// is visible by scanning one column. That cannot be had inside the 100-column limit once the
// longest enumerator and the longest message sit in one row. So this region is exempt from the
// limit by design rather than by oversight.
// clang-format off
static constexpr ErrorInfo kUnorderedErrorInfos[]{
{RpcActMalformed, "actMalformed", "Account malformed."},
{RpcActNotFound, "actNotFound", "Account not found."},
{RpcAlreadyMultisig, "alreadyMultisig", "Already multisigned."},
{RpcAlreadySingleSig, "alreadySingleSig", "Already single-signed."},
{RpcAmendmentBlocked, "amendmentBlocked", "Amendment blocked, need upgrade.", 503},
{RpcExpiredValidatorList, "unlBlocked", "Validator list expired.", 503},
{RpcAtxDeprecated, "deprecated", "Use the new API or specify a ledger range.", 400},
{RpcBadKeyType, "badKeyType", "Bad key type.", 400},
{RpcBadFeature, "badFeature", "Feature unknown or invalid.", 500},
{RpcBadIssuer, "badIssuer", "Issuer account malformed.", 400},
{RpcBadMarket, "badMarket", "No such market.", 404},
{RpcBadSecret, "badSecret", "Secret does not match account.", 403},
{RpcBadSeed, "badSeed", "Disallowed seed.", 403},
{RpcBadSyntax, "badSyntax", "Syntax error.", 400},
{RpcChannelMalformed, "channelMalformed", "Payment channel is malformed.", 400},
{RpcChannelAmtMalformed, "channelAmtMalformed", "Payment channel amount is malformed.", 400},
{RpcCommandMissing, "commandMissing", "Missing command entry.", 400},
{RpcDbDeserialization, "dbDeserialization", "Database deserialization error.", 502},
{RpcDstActMalformed, "dstActMalformed", "Destination account is malformed.", 400},
{RpcDstActMissing, "dstActMissing", "Destination account not provided.", 400},
{RpcDstActNotFound, "dstActNotFound", "Destination account not found.", 404},
{RpcDstAmtMalformed, "dstAmtMalformed", "Destination amount/currency/issuer is malformed.", 400},
{RpcDstAmtMissing, "dstAmtMissing", "Destination amount/currency/issuer is missing.", 400},
{RpcDstIsrMalformed, "dstIsrMalformed", "Destination issuer is malformed.", 400},
{RpcExcessiveLgrRange, "excessiveLgrRange", "Ledger range exceeds 1000.", 400},
{RpcForbidden, "forbidden", "Bad credentials.", 403},
{RpcHighFee, "highFee", "Current transaction fee exceeds your limit.", 402},
{RpcInternal, "internal", "Internal error.", 500},
{RpcInvalidLgrRange, "invalidLgrRange", "Ledger range is invalid.", 400},
{RpcInvalidParams, "invalidParams", "Invalid parameters.", 400},
{RpcInvalidHotwallet, "invalidHotWallet", "Invalid hotwallet.", 400},
{RpcIssueMalformed, "issueMalformed", "Issue is malformed.", 400},
{RpcJsonRpc, "json_rpc", "JSON-RPC transport error.", 500},
{RpcLgrIdxsInvalid, "lgrIdxsInvalid", "Ledger indexes invalid.", 400},
{RpcLgrIdxMalformed, "lgrIdxMalformed", "Ledger index malformed.", 400},
{RpcLgrNotFound, "lgrNotFound", "Ledger not found.", 404},
{RpcLgrNotValidated, "lgrNotValidated", "Ledger not validated.", 202},
{RpcMasterDisabled, "masterDisabled", "Master key is disabled.", 403},
{RpcNotEnabled, "notEnabled", "Not enabled in configuration.", 501},
{RpcNotImpl, "notImpl", "Not implemented.", 501},
{RpcNotReady, "notReady", "Not ready to handle this request.", 503},
{RpcNotSupported, "notSupported", "Operation not supported.", 501},
{RpcNoClosed, "noClosed", "Closed ledger is unavailable.", 503},
{RpcNoCurrent, "noCurrent", "Current ledger is unavailable.", 503},
{RpcNotSynced, "notSynced", "Not synced to the network.", 503},
{RpcNoEvents, "noEvents", "Current transport does not support events.", 405},
{RpcNoNetwork, "noNetwork", "Not synced to the network.", 503},
{RpcWrongNetwork, "wrongNetwork", "Wrong network.", 503},
{RpcNoPermission, "noPermission", "You don't have permission for this command.", 401},
{RpcNoPfRequest, "noPathRequest", "No pathfinding request in progress.", 404},
{RpcObjectNotFound, "objectNotFound", "The requested object was not found.", 404},
{RpcPublicMalformed, "publicMalformed", "Public key is malformed.", 400},
{RpcSendmaxMalformed, "sendMaxMalformed", "SendMax amount malformed.", 400},
{RpcSigningMalformed, "signingMalformed", "Signing of transaction is malformed.", 400},
{RpcSlowDown, "slowDown", "You are placing too much load on the server.", 429},
{RpcSrcActMalformed, "srcActMalformed", "Source account is malformed.", 400},
{RpcSrcActMissing, "srcActMissing", "Source account not provided.", 400},
{RpcSrcActNotFound, "srcActNotFound", "Source account not found.", 404},
{RpcDelegateActNotFound, "delegateActNotFound", "Delegate account not found.", 404},
{RpcSrcCurMalformed, "srcCurMalformed", "Source currency is malformed.", 400},
{RpcSrcIsrMalformed, "srcIsrMalformed", "Source issuer is malformed.", 400},
{RpcStreamMalformed, "malformedStream", "Stream malformed.", 400},
{RpcTooBusy, "tooBusy", "The server is too busy to help you now.", 503},
{RpcTxnNotFound, "txnNotFound", "Transaction not found.", 404},
{RpcUnknownCommand, "unknownCmd", "Unknown method.", 405},
{RpcOracleMalformed, "oracleMalformed", "Oracle request is malformed.", 400},
{RpcBadCredentials, "badCredentials", "Credentials do not exist, are not accepted, or have expired.", 400},
{RpcTxSigned, "transactionSigned", "Transaction should not be signed.", 400},
{RpcDomainMalformed, "domainMalformed", "Domain is malformed.", 400},
{RpcEntryNotFound, "entryNotFound", "Entry not found.", 400},
{RpcUnexpectedLedgerType, "unexpectedLedgerType", "Unexpected ledger type.", 400},
{RpcActMalformed, "actMalformed", "Account malformed.", 400},
{RpcActNotFound, "actNotFound", "Account not found.", 404},
{RpcAlreadyMultisig, "alreadyMultisig", "Already multisigned.", 400},
{RpcAlreadySingleSig, "alreadySingleSig", "Already single-signed.", 400},
{RpcAmendmentBlocked, "amendmentBlocked", "Amendment blocked, need upgrade.", 503},
{RpcExpiredValidatorList, "unlBlocked", "Validator list expired.", 503},
{RpcAtxDeprecated, "deprecated", "Use the new API or specify a ledger range.", 400},
{RpcBadKeyType, "badKeyType", "Bad key type.", 400},
{RpcBadFeature, "badFeature", "Feature unknown or invalid.", 500},
{RpcBadIssuer, "badIssuer", "Issuer account malformed.", 400},
{RpcBadMarket, "badMarket", "No such market.", 404},
{RpcBadSecret, "badSecret", "Secret does not match account.", 403},
{RpcBadSeed, "badSeed", "Disallowed seed.", 403},
{RpcBadSyntax, "badSyntax", "Syntax error.", 400},
{RpcChannelMalformed, "channelMalformed", "Payment channel is malformed.", 400},
{RpcChannelAmtMalformed, "channelAmtMalformed", "Payment channel amount is malformed.", 400},
{RpcCommandMissing, "commandMissing", "Missing command entry.", 400},
{RpcDbDeserialization, "dbDeserialization", "Database deserialization error.", 502},
{RpcDstActMalformed, "dstActMalformed", "Destination account is malformed.", 400},
{RpcDstActMissing, "dstActMissing", "Destination account not provided.", 400},
{RpcDstActNotFound, "dstActNotFound", "Destination account not found.", 404},
{RpcDstAmtMalformed, "dstAmtMalformed", "Destination amount/currency/issuer is malformed.", 400},
{RpcDstAmtMissing, "dstAmtMissing", "Destination amount/currency/issuer is missing.", 400},
{RpcDstIsrMalformed, "dstIsrMalformed", "Destination issuer is malformed.", 400},
{RpcExcessiveLgrRange, "excessiveLgrRange", "Ledger range exceeds 1000.", 400},
{RpcForbidden, "forbidden", "Bad credentials.", 403},
{RpcHighFee, "highFee", "Current transaction fee exceeds your limit.", 402},
{RpcInternal, "internal", "Internal error.", 500},
{RpcInvalidLgrRange, "invalidLgrRange", "Ledger range is invalid.", 400},
{RpcInvalidParams, "invalidParams", "Invalid parameters.", 400},
{RpcInvalidHotwallet, "invalidHotWallet", "Invalid hotwallet.", 400},
{RpcIssueMalformed, "issueMalformed", "Issue is malformed.", 400},
{RpcJsonRpc, "json_rpc", "JSON-RPC transport error.", 500},
{RpcLgrIdxsInvalid, "lgrIdxsInvalid", "Ledger indexes invalid.", 400},
{RpcLgrIdxMalformed, "lgrIdxMalformed", "Ledger index malformed.", 400},
{RpcLgrNotFound, "lgrNotFound", "Ledger not found.", 404},
{RpcLgrNotValidated, "lgrNotValidated", "Ledger not validated.", 202},
{RpcMasterDisabled, "masterDisabled", "Master key is disabled.", 403},
{RpcNotEnabled, "notEnabled", "Not enabled in configuration.", 501},
{RpcNotImpl, "notImpl", "Not implemented.", 501},
{RpcNotReady, "notReady", "Not ready to handle this request.", 503},
{RpcNotSupported, "notSupported", "Operation not supported.", 501},
{RpcNoClosed, "noClosed", "Closed ledger is unavailable.", 503},
{RpcNoCurrent, "noCurrent", "Current ledger is unavailable.", 503},
{RpcNotSynced, "notSynced", "Not synced to the network.", 503},
{RpcNoEvents, "noEvents", "Current transport does not support events.", 405},
{RpcNoNetwork, "noNetwork", "Not synced to the network.", 503},
{RpcWrongNetwork, "wrongNetwork", "Wrong network.", 503},
{RpcNoPermission, "noPermission", "You don't have permission for this command.", 401},
{RpcNoPfRequest, "noPathRequest", "No pathfinding request in progress.", 404},
{RpcObjectNotFound, "objectNotFound", "The requested object was not found.", 404},
{RpcPublicMalformed, "publicMalformed", "Public key is malformed.", 400},
{RpcSendmaxMalformed, "sendMaxMalformed", "SendMax amount malformed.", 400},
{RpcSigningMalformed, "signingMalformed", "Signing of transaction is malformed.", 400},
{RpcSlowDown, "slowDown", "You are placing too much load on the server.", 429},
{RpcSrcActMalformed, "srcActMalformed", "Source account is malformed.", 400},
{RpcSrcActMissing, "srcActMissing", "Source account not provided.", 400},
{RpcSrcActNotFound, "srcActNotFound", "Source account not found.", 404},
{RpcDelegateActNotFound, "delegateActNotFound", "Delegate account not found.", 404},
{RpcSrcCurMalformed, "srcCurMalformed", "Source currency is malformed.", 400},
{RpcSrcIsrMalformed, "srcIsrMalformed", "Source issuer is malformed.", 400},
{RpcStreamMalformed, "malformedStream", "Stream malformed.", 400},
{RpcTooBusy, "tooBusy", "The server is too busy to help you now.", 503},
{RpcTxnNotFound, "txnNotFound", "Transaction not found.", 404},
{RpcUnknownCommand, "unknownCmd", "Unknown method.", 405},
{RpcOracleMalformed, "oracleMalformed", "Oracle request is malformed.", 400},
{RpcBadCredentials, "badCredentials", "Credentials do not exist, are not accepted, or have expired.", 400},
{RpcTxSigned, "transactionSigned", "Transaction should not be signed.", 400},
{RpcDomainMalformed, "domainMalformed", "Domain is malformed.", 400},
{RpcEntryNotFound, "entryNotFound", "Entry not found.", 400},
{RpcUnexpectedLedgerType, "unexpectedLedgerType", "Unexpected ledger type.", 400},
};
// clang-format on
+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
+4 -1
View File
@@ -33,7 +33,10 @@ getHTTPHeaderTimestamp()
void
httpReply(int nStatus, std::string const& content, json::Output const& output, beast::Journal j)
{
JLOG(j.trace()) << "HTTP Reply " << nStatus << " " << content;
// The status only. The body is a reply, which carries a credential when the
// command is a keygen, and this library cannot mask one: the caller logs the
// masked body at debug.
JLOG(j.trace()) << "HTTP Reply " << nStatus;
if (content.empty() && nStatus == 401)
{
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;
Loaded 100 of 184 files, more files were not shown because too many files have changed in this diff. Show more