mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-26 03:57:07 +00:00
Compare commits
308 Commits
develop
...
mvadari/sp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67b75372ea | ||
|
|
05d3614a19 | ||
|
|
018e736a3b | ||
|
|
4a3abc0407 | ||
|
|
1eef7473d3 | ||
|
|
c3b3bce35d | ||
|
|
d1a77b453e | ||
|
|
c2ab83c960 | ||
|
|
aac6be218a | ||
|
|
14986cc043 | ||
|
|
4fc781ef93 | ||
|
|
e52113956e | ||
|
|
f650d52ada | ||
|
|
64159eb040 | ||
|
|
942a950e93 | ||
|
|
d70eca3d7d | ||
|
|
7e5ac6f8cb | ||
|
|
03fb6d1e0c | ||
|
|
9ef1949309 | ||
|
|
595b612589 | ||
|
|
d561f0d84d | ||
|
|
3859fcad73 | ||
|
|
8d905ac21b | ||
|
|
0997b92de3 | ||
|
|
9e5b7281cf | ||
|
|
0bfdfa73ff | ||
|
|
39e819927f | ||
|
|
08357b196f | ||
|
|
bb4c443fe5 | ||
|
|
a669099f21 | ||
|
|
7624c18c76 | ||
|
|
ab7bbac8f9 | ||
|
|
960aaec91e | ||
|
|
f042cd8e25 | ||
|
|
9d4c4968ad | ||
|
|
b76652bdf4 | ||
|
|
405b314842 | ||
|
|
77ebc2921e | ||
|
|
c72fd59539 | ||
|
|
6f4365557d | ||
|
|
d792e03468 | ||
|
|
2b4ce0fc21 | ||
|
|
eb88c0ef6b | ||
|
|
50d5e2d996 | ||
|
|
bca6d8e515 | ||
|
|
86c90c8e5c | ||
|
|
0c683bfd66 | ||
|
|
33be9abbef | ||
|
|
aa70d6051b | ||
|
|
d057f07d0e | ||
|
|
688e568e39 | ||
|
|
3ad93af34d | ||
|
|
c5941d6b14 | ||
|
|
ee8d9ca73e | ||
|
|
462a0b2338 | ||
|
|
9b4ab67864 | ||
|
|
84bffad2bf | ||
|
|
b153213e83 | ||
|
|
c12eff6646 | ||
|
|
fbff1c065c | ||
|
|
e8deaa12d8 | ||
|
|
6ee071c5b0 | ||
|
|
381094498d | ||
|
|
c072b125a0 | ||
|
|
b2b2babe1e | ||
|
|
bb27479686 | ||
|
|
278e25d8ad | ||
|
|
773acf0af7 | ||
|
|
7639bd9061 | ||
|
|
207a33d3da | ||
|
|
52e7cdc24d | ||
|
|
dd82977e6c | ||
|
|
31bc25973a | ||
|
|
021eaa81bf | ||
|
|
84e84fbadf | ||
|
|
b6b317597f | ||
|
|
525adf122f | ||
|
|
16e4f24226 | ||
|
|
3df1e668da | ||
|
|
9264136b36 | ||
|
|
6bd2e911eb | ||
|
|
828b4753fe | ||
|
|
d524670bcd | ||
|
|
25de0ce1b1 | ||
|
|
4026af175b | ||
|
|
a115d73c56 | ||
|
|
71003699dc | ||
|
|
831f99862d | ||
|
|
4d2945323d | ||
|
|
700a528a25 | ||
|
|
07d0887efb | ||
|
|
3ea0067e6a | ||
|
|
5a195d2585 | ||
|
|
3f4e88c300 | ||
|
|
7c3ca98bd5 | ||
|
|
2505fa86f7 | ||
|
|
d0d4f1d153 | ||
|
|
41429dcc99 | ||
|
|
aacb8e4a68 | ||
|
|
98257d3b96 | ||
|
|
afcc3c6464 | ||
|
|
fd393685dd | ||
|
|
de64bc7855 | ||
|
|
1adaeac8a7 | ||
|
|
7ddda1b1e6 | ||
|
|
5280a185d0 | ||
|
|
64f699a974 | ||
|
|
968493f43b | ||
|
|
22bfc5e743 | ||
|
|
2f0adfae3b | ||
|
|
53bdfb2bc7 | ||
|
|
b695b4bf9b | ||
|
|
6d7ffcbb91 | ||
|
|
d1346fa3f6 | ||
|
|
d6803868a1 | ||
|
|
9a6432dd66 | ||
|
|
f8a8c2301c | ||
|
|
e40e15a866 | ||
|
|
6555001cd9 | ||
|
|
f13945eff9 | ||
|
|
b32ff18c21 | ||
|
|
8baec5634c | ||
|
|
37c95ead69 | ||
|
|
234d2e5414 | ||
|
|
024ab07eb4 | ||
|
|
d95b6e41e5 | ||
|
|
8d75f3bdc6 | ||
|
|
eb7e01de7e | ||
|
|
c79814a037 | ||
|
|
15be71469d | ||
|
|
c9666d7b45 | ||
|
|
839ba17dae | ||
|
|
85e1f2b16c | ||
|
|
8a05e3d93b | ||
|
|
8c8ecffe1f | ||
|
|
b9f1c97518 | ||
|
|
d1eb22b403 | ||
|
|
fb86735800 | ||
|
|
53f407e1bd | ||
|
|
99618877e4 | ||
|
|
062ece321b | ||
|
|
1ad6dd1846 | ||
|
|
4a91351bcd | ||
|
|
f86b255e73 | ||
|
|
178bb8f7e9 | ||
|
|
293394fbc6 | ||
|
|
dcfcb1f3fd | ||
|
|
2fd8e1be3c | ||
|
|
fe5fab00ed | ||
|
|
9cde57d284 | ||
|
|
9859ba85a8 | ||
|
|
f6d79f74d6 | ||
|
|
bf4fa37937 | ||
|
|
686f945909 | ||
|
|
c1e1be510f | ||
|
|
d1d613da27 | ||
|
|
392a913631 | ||
|
|
446681dc3d | ||
|
|
e1aee43359 | ||
|
|
fe075470f8 | ||
|
|
49c52695cb | ||
|
|
37f4ea94cb | ||
|
|
f8209087a3 | ||
|
|
d390bc7a87 | ||
|
|
4e87de7303 | ||
|
|
8d24afe59d | ||
|
|
527d7bbede | ||
|
|
4a205eb9d8 | ||
|
|
0a410024a5 | ||
|
|
8f8fc03800 | ||
|
|
40cf5993c1 | ||
|
|
7cdaa24e63 | ||
|
|
175a2dfd28 | ||
|
|
4cd8d0d178 | ||
|
|
5155a94015 | ||
|
|
c0de722cfa | ||
|
|
d7ab1b48e1 | ||
|
|
65768237cd | ||
|
|
5f385e0f9b | ||
|
|
ab1de456cc | ||
|
|
8be44c7fc4 | ||
|
|
87718bdb3b | ||
|
|
88e870b1c6 | ||
|
|
ce8049a17f | ||
|
|
990627fc9e | ||
|
|
1823d70b21 | ||
|
|
f333dd1b2e | ||
|
|
204138fb0e | ||
|
|
52ae31bb17 | ||
|
|
c3e5bcfafd | ||
|
|
3568df43c4 | ||
|
|
c321e1070d | ||
|
|
9e65dba253 | ||
|
|
5b91d815d1 | ||
|
|
f885f02ede | ||
|
|
1bc5a1bb43 | ||
|
|
ec05613472 | ||
|
|
f88e964dac | ||
|
|
ffb538242a | ||
|
|
1e8f6ce1b5 | ||
|
|
82b146bf03 | ||
|
|
0791ca164a | ||
|
|
dc325a93e7 | ||
|
|
edddf3fe4b | ||
|
|
cf03c4cb8f | ||
|
|
2813fea294 | ||
|
|
163a2acbf5 | ||
|
|
198f3f83db | ||
|
|
0f36de8ef5 | ||
|
|
ea29fe5ede | ||
|
|
f5e2195bbb | ||
|
|
e49d338cd8 | ||
|
|
d96998ce47 | ||
|
|
a9629ae325 | ||
|
|
7f0a940a43 | ||
|
|
c38cb902ad | ||
|
|
b5db59644a | ||
|
|
9d1b5eb373 | ||
|
|
af9d91bc72 | ||
|
|
3f9673510a | ||
|
|
a49cb91c73 | ||
|
|
fbf403aaa4 | ||
|
|
e03c7a9c96 | ||
|
|
cd62f7f4cf | ||
|
|
297083e27b | ||
|
|
13145f6db2 | ||
|
|
3e6d6c6f80 | ||
|
|
b4188a887a | ||
|
|
774917db22 | ||
|
|
965ecd3f27 | ||
|
|
d0bcca6bf1 | ||
|
|
4fe7e87b4f | ||
|
|
2337d340e5 | ||
|
|
5d597e3b69 | ||
|
|
d8dc000488 | ||
|
|
a65cf6e07d | ||
|
|
7f922c4919 | ||
|
|
754f597078 | ||
|
|
32cc7825f2 | ||
|
|
a6b0efff87 | ||
|
|
28c5cadbea | ||
|
|
9df0ad64d1 | ||
|
|
1441abcf01 | ||
|
|
8d32b0f856 | ||
|
|
d59772657e | ||
|
|
bc71d9c138 | ||
|
|
101b70f0e8 | ||
|
|
ee385e9d3b | ||
|
|
4126d53978 | ||
|
|
59c3d5bddc | ||
|
|
bc1ef1e839 | ||
|
|
5b64ff0dd6 | ||
|
|
1ee250881b | ||
|
|
75aaeb5aae | ||
|
|
b09666210d | ||
|
|
dbbfc1354c | ||
|
|
e82c300de7 | ||
|
|
d5a1314c47 | ||
|
|
699297f01a | ||
|
|
71b81b743e | ||
|
|
ec11763def | ||
|
|
cc4b07dbd6 | ||
|
|
b78885d98c | ||
|
|
0c93bd6f08 | ||
|
|
9694de92da | ||
|
|
c4b798e8ed | ||
|
|
350130911a | ||
|
|
ab4ac64c92 | ||
|
|
aeaf679deb | ||
|
|
ea72198a1d | ||
|
|
6eb453f07d | ||
|
|
d4947386d7 | ||
|
|
fed56b2eeb | ||
|
|
f7e1d4bbb9 | ||
|
|
613fe48d54 | ||
|
|
5dc63b64eb | ||
|
|
cc5e063438 | ||
|
|
453fd23512 | ||
|
|
89af81745b | ||
|
|
a43ae9a3ce | ||
|
|
2afe5707ab | ||
|
|
759f843020 | ||
|
|
5ac7bbf51b | ||
|
|
2a27280f1a | ||
|
|
6c0732ccbe | ||
|
|
20bce64946 | ||
|
|
110b222579 | ||
|
|
1cdf7bb745 | ||
|
|
4abd94e7ac | ||
|
|
6aa0331ffe | ||
|
|
4eea76ca92 | ||
|
|
8e895a3e7d | ||
|
|
e589b71ee0 | ||
|
|
02d8f9fbef | ||
|
|
9ff71aa109 | ||
|
|
2071b39d6a | ||
|
|
5e65813a52 | ||
|
|
abd8620c97 | ||
|
|
6e01f233e4 | ||
|
|
0bddc95444 | ||
|
|
67bdd099c8 | ||
|
|
f0addd81a1 | ||
|
|
a798c60a08 | ||
|
|
198ed72fe3 | ||
|
|
d40f8cc232 | ||
|
|
5b9c767b07 | ||
|
|
43c16f35f7 | ||
|
|
cad305ac7e |
@@ -11,7 +11,6 @@ Checks: "-*,
|
||||
bugprone-copy-constructor-init,
|
||||
bugprone-crtp-constructor-accessibility,
|
||||
bugprone-dangling-handle,
|
||||
bugprone-derived-method-shadowing-base-method,
|
||||
bugprone-dynamic-static-initializers,
|
||||
bugprone-empty-catch,
|
||||
bugprone-fold-init-type,
|
||||
@@ -22,7 +21,6 @@ Checks: "-*,
|
||||
bugprone-incorrect-roundings,
|
||||
bugprone-infinite-loop,
|
||||
bugprone-integer-division,
|
||||
bugprone-invalid-enum-default-initialization,
|
||||
bugprone-lambda-function-name,
|
||||
bugprone-macro-parentheses,
|
||||
bugprone-macro-repeated-side-effects,
|
||||
@@ -139,7 +137,6 @@ Checks: "-*,
|
||||
readability-enum-initial-value,
|
||||
readability-identifier-naming,
|
||||
readability-implicit-bool-conversion,
|
||||
readability-inconsistent-ifelse-braces,
|
||||
readability-make-member-function-const,
|
||||
readability-math-missing-parentheses,
|
||||
readability-misleading-indentation,
|
||||
@@ -148,9 +145,7 @@ Checks: "-*,
|
||||
readability-redundant-declaration,
|
||||
readability-redundant-inline-specifier,
|
||||
readability-redundant-member-init,
|
||||
readability-redundant-parentheses,
|
||||
readability-redundant-string-init,
|
||||
readability-redundant-typename,
|
||||
readability-reference-to-constructed-temporary,
|
||||
readability-simplify-boolean-expr,
|
||||
readability-static-definition-in-anonymous-namespace,
|
||||
@@ -158,8 +153,7 @@ Checks: "-*,
|
||||
readability-use-std-min-max
|
||||
"
|
||||
# ---
|
||||
# bugprone-narrowing-conversions, # This will break a lot of code but we should enable it in the future because it can eliminate a lot of bugs
|
||||
# misc-override-with-different-visibility, # Will be addressed in a future PR, but for now it generates too many warnings
|
||||
# bugprone-narrowing-conversions, # this will break a lot of code but we should enable it in the future because it can eliminate a lot of bugs
|
||||
# readability-inconsistent-declaration-parameter-name, # In this codebase this check will break a lot of arg names
|
||||
# readability-static-accessed-through-instance, # this check is probably unnecessary. It makes the code less readable
|
||||
# ---
|
||||
|
||||
@@ -96,6 +96,3 @@ function(verbose_find_path variable name)
|
||||
${ARGN}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(patch_nix_binary target)
|
||||
endfunction()
|
||||
|
||||
2
.github/actions/setup-conan/action.yml
vendored
2
.github/actions/setup-conan/action.yml
vendored
@@ -9,7 +9,7 @@ inputs:
|
||||
remote_url:
|
||||
description: "The URL of the Conan endpoint to use."
|
||||
required: false
|
||||
default: https://conan.xrplf.org/repository/conan/
|
||||
default: https://conan.ripplex.io
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
@@ -83,6 +83,7 @@ test.conditions > xrpl.basics
|
||||
test.conditions > xrpl.conditions
|
||||
test.consensus > test.csf
|
||||
test.consensus > test.jtx
|
||||
test.consensus > test.toplevel
|
||||
test.consensus > test.unit_test
|
||||
test.consensus > xrpl.basics
|
||||
test.consensus > xrpld.app
|
||||
|
||||
2
.github/scripts/strategy-matrix/linux.json
vendored
2
.github/scripts/strategy-matrix/linux.json
vendored
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"image_tag": "sha-e29b523",
|
||||
"image_tag": "sha-fe4c8ae",
|
||||
"configs": {
|
||||
"ubuntu": [
|
||||
{
|
||||
|
||||
2
.github/scripts/strategy-matrix/windows.json
vendored
2
.github/scripts/strategy-matrix/windows.json
vendored
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"platform": "windows/amd64",
|
||||
"runner": ["self-hosted", "Windows", "dev-box-windows-2026"],
|
||||
"runner": ["self-hosted", "Windows", "devbox"],
|
||||
"configs": [
|
||||
{ "build_type": "Release" },
|
||||
{
|
||||
|
||||
6
.github/workflows/build-nix-images.yml
vendored
6
.github/workflows/build-nix-images.yml
vendored
@@ -54,9 +54,9 @@ jobs:
|
||||
base_image: debian:bookworm
|
||||
- name: rhel
|
||||
base_image: registry.access.redhat.com/ubi9/ubi:latest
|
||||
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@ee03d31bcc4501d7599dc1b1ecd7a34af582ad1c
|
||||
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@c1b480188519e0cad040e6aa70db1cbc5a797e07
|
||||
with:
|
||||
image_name: xrpld/nix-${{ matrix.distro.name }}
|
||||
image_name: ghcr.io/xrplf/xrpld/nix-${{ matrix.distro.name }}
|
||||
dockerfile: nix/docker/Dockerfile
|
||||
base_image: ${{ matrix.distro.base_image }}
|
||||
push: ${{ github.event_name == 'push' }}
|
||||
push: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' }}
|
||||
|
||||
6
.github/workflows/build-packaging-images.yml
vendored
6
.github/workflows/build-packaging-images.yml
vendored
@@ -38,9 +38,9 @@ jobs:
|
||||
base_image: debian:bookworm
|
||||
- name: rhel
|
||||
base_image: registry.access.redhat.com/ubi9/ubi:latest
|
||||
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@ee03d31bcc4501d7599dc1b1ecd7a34af582ad1c
|
||||
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@c1b480188519e0cad040e6aa70db1cbc5a797e07
|
||||
with:
|
||||
image_name: xrpld/packaging-${{ matrix.distro.name }}
|
||||
image_name: ghcr.io/xrplf/xrpld/packaging-${{ matrix.distro.name }}
|
||||
dockerfile: package/Dockerfile
|
||||
base_image: ${{ matrix.distro.base_image }}
|
||||
push: ${{ github.event_name == 'push' }}
|
||||
push: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' }}
|
||||
|
||||
2
.github/workflows/check-pr-description.yml
vendored
2
.github/workflows/check-pr-description.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Write PR body to file
|
||||
env:
|
||||
|
||||
7
.github/workflows/on-pr.yml
vendored
7
.github/workflows/on-pr.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- name: Determine changed files
|
||||
# This step checks whether any files have changed that should
|
||||
# cause the next jobs to run. We do it this way rather than
|
||||
@@ -70,7 +70,6 @@ jobs:
|
||||
.github/workflows/reusable-upload-recipe.yml
|
||||
.clang-tidy
|
||||
.codecov.yml
|
||||
bin/check-tools.sh
|
||||
cfg/**
|
||||
cmake/**
|
||||
conan/**
|
||||
@@ -154,8 +153,8 @@ jobs:
|
||||
if: ${{ github.repository == 'XRPLF/rippled' && needs.should-run.outputs.go == 'true' && github.event_name == 'pull_request' && startsWith(github.event.pull_request.base.ref, 'release') }}
|
||||
uses: ./.github/workflows/reusable-upload-recipe.yml
|
||||
secrets:
|
||||
remote_username: ${{ secrets.NEXUS_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }}
|
||||
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
|
||||
|
||||
notify-clio:
|
||||
needs: upload-recipe
|
||||
|
||||
4
.github/workflows/on-tag.yml
vendored
4
.github/workflows/on-tag.yml
vendored
@@ -20,8 +20,8 @@ jobs:
|
||||
if: ${{ github.repository == 'XRPLF/rippled' }}
|
||||
uses: ./.github/workflows/reusable-upload-recipe.yml
|
||||
secrets:
|
||||
remote_username: ${{ secrets.NEXUS_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }}
|
||||
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
|
||||
|
||||
build-test:
|
||||
if: ${{ github.repository == 'XRPLF/rippled' }}
|
||||
|
||||
5
.github/workflows/on-trigger.yml
vendored
5
.github/workflows/on-trigger.yml
vendored
@@ -27,7 +27,6 @@ on:
|
||||
- ".github/workflows/reusable-upload-recipe.yml"
|
||||
- ".clang-tidy"
|
||||
- ".codecov.yml"
|
||||
- "bin/check-tools.sh"
|
||||
- "cfg/**"
|
||||
- "cmake/**"
|
||||
- "conan/**"
|
||||
@@ -98,8 +97,8 @@ jobs:
|
||||
if: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' && github.ref == 'refs/heads/develop' }}
|
||||
uses: ./.github/workflows/reusable-upload-recipe.yml
|
||||
secrets:
|
||||
remote_username: ${{ secrets.NEXUS_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }}
|
||||
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
|
||||
|
||||
package:
|
||||
needs: build-test
|
||||
|
||||
2
.github/workflows/pre-commit.yml
vendored
2
.github/workflows/pre-commit.yml
vendored
@@ -14,7 +14,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@e06d4138c9ec8dceeb7c818645faa38087ea9e3d
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@312aaab296060ff89d7f798dcab59f019bea6e02
|
||||
with:
|
||||
runs_on: ubuntu-latest
|
||||
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-41ec7c1" }'
|
||||
|
||||
4
.github/workflows/publish-docs.yml
vendored
4
.github/workflows/publish-docs.yml
vendored
@@ -41,10 +41,10 @@ env:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-e29b523
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-fe4c8ae
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@c47daebb2f9db64ffbac71b47d68a661498d5ce8
|
||||
|
||||
21
.github/workflows/reusable-build-test-config.yml
vendored
21
.github/workflows/reusable-build-test-config.yml
vendored
@@ -82,7 +82,7 @@ jobs:
|
||||
name: ${{ inputs.config_name }}
|
||||
runs-on: ${{ fromJSON(inputs.runs_on) }}
|
||||
container: ${{ inputs.image != '' && inputs.image || null }}
|
||||
timeout-minutes: ${{ inputs.sanitizers != '' && 360 || 180 }}
|
||||
timeout-minutes: ${{ inputs.sanitizers != '' && 360 || 90 }}
|
||||
env:
|
||||
# Use a namespace to keep the objects separate for each configuration.
|
||||
CCACHE_NAMESPACE: ${{ inputs.config_name }}
|
||||
@@ -110,7 +110,7 @@ jobs:
|
||||
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@c47daebb2f9db64ffbac71b47d68a661498d5ce8
|
||||
@@ -163,7 +163,7 @@ jobs:
|
||||
CMAKE_ARGS: ${{ inputs.cmake_args }}
|
||||
run: |
|
||||
cmake \
|
||||
-G '${{ runner.os == 'Windows' && 'Visual Studio 18 2026' || 'Ninja' }}' \
|
||||
-G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
|
||||
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
|
||||
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
||||
${CMAKE_ARGS} \
|
||||
@@ -229,6 +229,21 @@ jobs:
|
||||
--parallel "${BUILD_NPROC}" \
|
||||
--target "${CMAKE_TARGET}"
|
||||
|
||||
# This step is needed to allow running in non-Nix environments
|
||||
- name: Patch binary to use default loader and remove rpath (Linux)
|
||||
if: ${{ runner.os == 'Linux' && env.SANITIZERS_ENABLED == 'false' }}
|
||||
run: |
|
||||
loader="$(/tmp/loader-path.sh)"
|
||||
patchelf --set-interpreter "${loader}" --remove-rpath "${{ env.BUILD_DIR }}/xrpld"
|
||||
|
||||
# We're only running aarch64 Linux builds in Ubuntu-based images, so this is kept simple
|
||||
- name: Install libatomic (Linux aarch64)
|
||||
if: ${{ runner.os == 'Linux' && runner.arch == 'ARM64' }}
|
||||
run: |
|
||||
apt update --yes
|
||||
apt install -y --no-install-recommends \
|
||||
libatomic1
|
||||
|
||||
- name: Show ccache statistics
|
||||
if: ${{ inputs.ccache_enabled }}
|
||||
run: |
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- name: Check levelization
|
||||
run: python .github/scripts/levelization/generate.py
|
||||
- name: Check for differences
|
||||
|
||||
2
.github/workflows/reusable-check-rename.yml
vendored
2
.github/workflows/reusable-check-rename.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- name: Check definitions
|
||||
run: .github/scripts/rename/definitions.sh .
|
||||
- name: Check copyright notices
|
||||
|
||||
6
.github/workflows/reusable-clang-tidy.yml
vendored
6
.github/workflows/reusable-clang-tidy.yml
vendored
@@ -32,20 +32,20 @@ jobs:
|
||||
if: ${{ inputs.check_only_changed }}
|
||||
permissions:
|
||||
contents: read
|
||||
uses: XRPLF/actions/.github/workflows/determine-tidy-files.yml@c7045074aafe9fb92fa537aa4446f81fbfc17e8b
|
||||
uses: XRPLF/actions/.github/workflows/determine-tidy-files.yml@312aaab296060ff89d7f798dcab59f019bea6e02
|
||||
|
||||
run-clang-tidy:
|
||||
name: Run clang tidy
|
||||
needs: [determine-files]
|
||||
if: ${{ always() && !cancelled() && (!inputs.check_only_changed || needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.clang_tidy_config_changed == 'true') }}
|
||||
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
|
||||
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-e29b523"
|
||||
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-fe4c8ae"
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@c47daebb2f9db64ffbac71b47d68a661498d5ce8
|
||||
|
||||
24
.github/workflows/reusable-package.yml
vendored
24
.github/workflows/reusable-package.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
matrix: ${{ steps.generate.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
@@ -39,8 +39,23 @@ jobs:
|
||||
working-directory: .github/scripts/strategy-matrix
|
||||
run: ./generate.py --packaging >>"${GITHUB_OUTPUT}"
|
||||
|
||||
generate-version:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github/actions/generate-version
|
||||
src/libxrpl/protocol/BuildInfo.cpp
|
||||
- name: Generate version
|
||||
id: version
|
||||
uses: ./.github/actions/generate-version
|
||||
|
||||
package:
|
||||
needs: [generate-matrix]
|
||||
needs: [generate-matrix, generate-version]
|
||||
if: ${{ github.event.repository.visibility == 'public' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -54,7 +69,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Download pre-built binary
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
@@ -67,13 +82,14 @@ jobs:
|
||||
|
||||
- name: Build package
|
||||
env:
|
||||
PKG_VERSION: ${{ needs.generate-version.outputs.version }}
|
||||
PKG_RELEASE: ${{ inputs.pkg_release }}
|
||||
run: ./package/build_pkg.sh
|
||||
|
||||
- name: Upload package artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: ${{ matrix.artifact_name }}-pkg
|
||||
name: ${{ matrix.artifact_name }}-pkg-${{ needs.generate-version.outputs.version }}
|
||||
path: |
|
||||
${{ env.BUILD_DIR }}/debbuild/*.deb
|
||||
${{ env.BUILD_DIR }}/debbuild/*.ddeb
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
matrix: ${{ steps.generate.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
|
||||
24
.github/workflows/reusable-upload-recipe.yml
vendored
24
.github/workflows/reusable-upload-recipe.yml
vendored
@@ -14,7 +14,7 @@ on:
|
||||
description: "The URL of the Conan endpoint to use."
|
||||
required: false
|
||||
type: string
|
||||
default: https://conan.xrplf.org/repository/conan/
|
||||
default: https://conan.ripplex.io
|
||||
|
||||
secrets:
|
||||
remote_username:
|
||||
@@ -40,14 +40,10 @@ defaults:
|
||||
jobs:
|
||||
upload:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-e29b523
|
||||
env:
|
||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||
CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.remote_username }}
|
||||
CONAN_PASSWORD_XRPLF: ${{ secrets.remote_password }}
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-fe4c8ae
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Generate build version number
|
||||
id: version
|
||||
@@ -60,9 +56,15 @@ jobs:
|
||||
remote_url: ${{ inputs.remote_url }}
|
||||
|
||||
- name: Log into Conan remote
|
||||
run: conan remote login "${REMOTE_NAME}" "${CONAN_LOGIN_USERNAME_XRPLF}" --password "${CONAN_PASSWORD_XRPLF}"
|
||||
env:
|
||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||
REMOTE_USERNAME: ${{ secrets.remote_username }}
|
||||
REMOTE_PASSWORD: ${{ secrets.remote_password }}
|
||||
run: conan remote login "${REMOTE_NAME}" "${REMOTE_USERNAME}" --password "${REMOTE_PASSWORD}"
|
||||
|
||||
- name: Upload Conan recipe (version)
|
||||
env:
|
||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||
run: |
|
||||
conan export . --version=${{ steps.version.outputs.version }}
|
||||
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/${{ steps.version.outputs.version }}
|
||||
@@ -71,6 +73,8 @@ jobs:
|
||||
# 'develop' branch, see on-trigger.yml.
|
||||
- name: Upload Conan recipe (develop)
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
env:
|
||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||
run: |
|
||||
conan export . --version=develop
|
||||
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/develop
|
||||
@@ -79,6 +83,8 @@ jobs:
|
||||
# one of the 'release' branches, see on-pr.yml.
|
||||
- name: Upload Conan recipe (rc)
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
env:
|
||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||
run: |
|
||||
conan export . --version=rc
|
||||
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/rc
|
||||
@@ -87,6 +93,8 @@ jobs:
|
||||
# release, see on-tag.yml.
|
||||
- name: Upload Conan recipe (release)
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
env:
|
||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||
run: |
|
||||
conan export . --version=release
|
||||
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/release
|
||||
|
||||
8
.github/workflows/upload-conan-deps.yml
vendored
8
.github/workflows/upload-conan-deps.yml
vendored
@@ -34,7 +34,7 @@ on:
|
||||
|
||||
env:
|
||||
CONAN_REMOTE_NAME: xrplf
|
||||
CONAN_REMOTE_URL: https://conan.xrplf.org/repository/conan/
|
||||
CONAN_REMOTE_URL: https://conan.ripplex.io
|
||||
NPROC_SUBTRACT: 2
|
||||
|
||||
concurrency:
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@c47daebb2f9db64ffbac71b47d68a661498d5ce8
|
||||
@@ -108,12 +108,10 @@ jobs:
|
||||
|
||||
- name: Log into Conan remote
|
||||
if: ${{ github.repository == 'XRPLF/rippled' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
|
||||
run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.NEXUS_REMOTE_USERNAME }}" --password "${{ secrets.NEXUS_REMOTE_PASSWORD }}"
|
||||
run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}"
|
||||
|
||||
- name: Upload Conan packages
|
||||
if: ${{ github.repository == 'XRPLF/rippled' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
|
||||
env:
|
||||
FORCE_OPTION: ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }}
|
||||
CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.NEXUS_REMOTE_USERNAME }}
|
||||
CONAN_PASSWORD_XRPLF: ${{ secrets.NEXUS_REMOTE_PASSWORD }}
|
||||
run: conan upload "*" --remote="${CONAN_REMOTE_NAME}" --confirm ${FORCE_OPTION}
|
||||
|
||||
@@ -15,7 +15,6 @@ repos:
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
args: [--maxkb=400, --enforce-all]
|
||||
- id: check-executables-have-shebangs
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-merge-conflict
|
||||
@@ -36,18 +35,13 @@ repos:
|
||||
language: python
|
||||
types_or: [c++, c]
|
||||
exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/
|
||||
- id: fix-pragma-once
|
||||
name: fix missing '#pragma once' declarations in header files
|
||||
language: python
|
||||
entry: ./bin/pre-commit/fix_pragma_once.py
|
||||
files: \.(h|hpp)$
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: dd18dad857d6133e90bbe478f4f2f22ec0030269 # frozen: v22.1.5
|
||||
hooks:
|
||||
- id: clang-format
|
||||
args: [--style=file]
|
||||
types_or: [c++, c, proto]
|
||||
"types_or": [c++, c, proto]
|
||||
exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/
|
||||
|
||||
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
|
||||
|
||||
2
BUILD.md
2
BUILD.md
@@ -101,7 +101,7 @@ More information on customizing Conan can be found in the [Advanced Conan config
|
||||
Run the following command to add the `xrplf` remote, which hosts some of our dependencies:
|
||||
|
||||
```bash
|
||||
conan remote add --index 0 --force xrplf https://conan.xrplf.org/repository/conan/
|
||||
conan remote add --index 0 --force xrplf https://conan.ripplex.io
|
||||
```
|
||||
|
||||
### Set Up Ccache
|
||||
|
||||
@@ -57,8 +57,6 @@ if(target)
|
||||
)
|
||||
endif()
|
||||
|
||||
include(PatchNixBinary)
|
||||
|
||||
include(XrplSanity)
|
||||
include(XrplVersion)
|
||||
include(XrplSettings)
|
||||
|
||||
@@ -90,19 +90,16 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
|
||||
check perl
|
||||
check pkg-config
|
||||
check vim
|
||||
check zip
|
||||
|
||||
# These tools are present in our Linux CI images and in local development
|
||||
# setups, but not in the macOS CI environment. So check them everywhere
|
||||
# except when running in CI on macOS.
|
||||
if [ "${os}" = "linux" ] || [ -z "${CI:-}" ]; then
|
||||
check clang-format
|
||||
check dot
|
||||
check doxygen
|
||||
check gcovr
|
||||
check gh
|
||||
check git-cliff
|
||||
check git-lfs
|
||||
check gpg
|
||||
# pre-commit, or its alternative implementation prek
|
||||
check pre-commit sh -c 'pre-commit --version || prek --version'
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Adds "#pragma once" to the top of header files that don't already have it.
|
||||
|
||||
Usage: ./bin/pre-commit/fix_pragma_once.py <file1> <file2> ...
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
PRAGMA_ONCE = "#pragma once\n\n"
|
||||
|
||||
|
||||
def fix_pragma_once(path: Path) -> bool:
|
||||
original = path.read_text(encoding="utf-8")
|
||||
if PRAGMA_ONCE not in original:
|
||||
path.write_text(PRAGMA_ONCE + original, encoding="utf-8")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def main() -> int:
|
||||
files = [Path(f) for f in sys.argv[1:]]
|
||||
success = True
|
||||
|
||||
for path in files:
|
||||
success &= fix_pragma_once(path)
|
||||
|
||||
return 0 if success else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -56,16 +56,3 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown architecture: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Sanitizers
|
||||
# --------------------------------------------------------------------
|
||||
# SANITIZERS is injected by the Conan toolchain when a sanitizer build is
|
||||
# requested (see conan/profiles/sanitizers). The flags are applied to the
|
||||
# 'common' target in XrplSanitizers; this flag lets other modules know a
|
||||
# sanitizer build is active without depending on that module.
|
||||
if(DEFINED SANITIZERS)
|
||||
set(SANITIZERS_ENABLED TRUE)
|
||||
else()
|
||||
set(SANITIZERS_ENABLED FALSE)
|
||||
endif()
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
#[===================================================================[
|
||||
Patch executables to run in non-Nix environments.
|
||||
|
||||
The Nix-based CI image links binaries against an ELF interpreter (loader)
|
||||
that lives in the Nix store, so the resulting binaries don't run elsewhere
|
||||
(including once installed from the .deb package). `patch_nix_binary` adds a
|
||||
POST_BUILD step that resets the interpreter to the system default loader and
|
||||
drops the rpath.
|
||||
|
||||
This is only active inside the Nix-based image, detected by the presence of
|
||||
/tmp/loader-path.sh (shipped by that image, resolves the default loader). It
|
||||
is skipped for sanitizer builds, whose runtime libraries are resolved through
|
||||
the rpath. Everywhere else `patch_nix_binary` is a no-op.
|
||||
#]===================================================================]
|
||||
|
||||
include_guard(GLOBAL)
|
||||
|
||||
include(CompilationEnv)
|
||||
|
||||
# Provided by the Nix-based CI image; prints the system default ELF loader path.
|
||||
set(_loader_path_script "/tmp/loader-path.sh")
|
||||
|
||||
if(is_linux AND NOT SANITIZERS_ENABLED AND EXISTS "${_loader_path_script}")
|
||||
execute_process(
|
||||
COMMAND "${_loader_path_script}"
|
||||
OUTPUT_VARIABLE DEFAULT_LOADER_PATH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
find_program(PATCHELF_COMMAND patchelf REQUIRED)
|
||||
set(PATCH_NIX_BINARIES TRUE)
|
||||
message(
|
||||
STATUS
|
||||
"Binaries will be patched to use loader '${DEFAULT_LOADER_PATH}'"
|
||||
)
|
||||
else()
|
||||
set(PATCH_NIX_BINARIES FALSE)
|
||||
endif()
|
||||
|
||||
function(patch_nix_binary target)
|
||||
if(NOT PATCH_NIX_BINARIES)
|
||||
return()
|
||||
endif()
|
||||
add_custom_command(
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND
|
||||
"${PATCHELF_COMMAND}" --set-interpreter "${DEFAULT_LOADER_PATH}"
|
||||
--remove-rpath "$<TARGET_FILE:${target}>"
|
||||
COMMENT "Patching ${target}: set default loader, remove rpath"
|
||||
VERBATIM
|
||||
)
|
||||
endfunction()
|
||||
@@ -154,15 +154,6 @@ else()
|
||||
>
|
||||
)
|
||||
|
||||
# On aarch64, libatomic is required for atomic operations. It is not needed on x86_64.
|
||||
# Linking it statically on Linux
|
||||
if(is_arm64 AND is_linux)
|
||||
target_link_options(
|
||||
common
|
||||
INTERFACE -Wl,--push-state -Wl,-Bstatic -latomic -Wl,--pop-state
|
||||
)
|
||||
endif()
|
||||
|
||||
# Keep -stdlib=libstdc++ off the compile commands, but preserve it for linking.
|
||||
#
|
||||
# Conan turns `compiler.libcxx=libstdc++` into `-stdlib=libstdc++` and puts it in
|
||||
|
||||
@@ -247,7 +247,6 @@ target_link_modules(
|
||||
|
||||
if(xrpld)
|
||||
add_executable(xrpld)
|
||||
patch_nix_binary(xrpld)
|
||||
if(tests)
|
||||
target_compile_definitions(xrpld PUBLIC ENABLE_TESTS)
|
||||
target_compile_definitions(
|
||||
|
||||
@@ -28,6 +28,7 @@ endif()
|
||||
set(package_env
|
||||
SRC_DIR=${CMAKE_SOURCE_DIR}
|
||||
BUILD_DIR=${CMAKE_BINARY_DIR}
|
||||
PKG_VERSION=${xrpld_version}
|
||||
PKG_RELEASE=${pkg_release}
|
||||
)
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
include_guard(GLOBAL)
|
||||
include(CompilationEnv)
|
||||
|
||||
if(NOT SANITIZERS_ENABLED)
|
||||
if(NOT DEFINED SANITIZERS)
|
||||
set(SANITIZERS_ENABLED FALSE)
|
||||
return()
|
||||
endif()
|
||||
set(SANITIZERS_ENABLED TRUE)
|
||||
|
||||
message(STATUS "=== Configuring Sanitizers ===")
|
||||
message(STATUS " SANITIZERS: ${SANITIZERS}")
|
||||
|
||||
64
conan.lock
64
conan.lock
@@ -1,43 +1,43 @@
|
||||
{
|
||||
"version": "0.5",
|
||||
"requires": [
|
||||
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708",
|
||||
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1782392402.420688",
|
||||
"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",
|
||||
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1782392413.075713",
|
||||
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1782392402.431897",
|
||||
"protobuf/6.33.5#ff253ead763bd8d9904a52979cd21e81%1782392410.233933",
|
||||
"openssl/3.6.3#1163d4ddc603907084d08a6a0c6e580f%1782307150.583886",
|
||||
"nudb/2.0.9#11149c73f8f2baff9a0198fe25971fc7%1782392402.297166",
|
||||
"lz4/1.10.0#982d9b673900f665a1da109e09c17cab%1782392402.164188",
|
||||
"libiconv/1.17#9923bc6dc6f106646d6967e0039a5ada%1782392792.775744",
|
||||
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1782392402.420732",
|
||||
"libarchive/3.8.7#c446109bd1f1d8ba7936c94189bc50e6%1782392403.066892",
|
||||
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1777558780.503",
|
||||
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
|
||||
"sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1776096494.149",
|
||||
"soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231",
|
||||
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",
|
||||
"secp256k1/0.7.1#481881709eb0bdd0185a12b912bbe8ad%1770910500.329",
|
||||
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1765850186.86",
|
||||
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1774398111.888",
|
||||
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1774467363.12",
|
||||
"openssl/3.6.2#4789bbf131b77d0515d15e094c8f697f%1778071755.506",
|
||||
"nudb/2.0.9#11149c73f8f2baff9a0198fe25971fc7%1775040983.408",
|
||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914",
|
||||
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492",
|
||||
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1765842973.03",
|
||||
"libarchive/3.8.7#c446109bd1f1d8ba7936c94189bc50e6%1776147552.838",
|
||||
"jemalloc/5.3.1#1fc58d55316041f10fbc1e8a2eae632a%1776700028.228",
|
||||
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1782392402.791979",
|
||||
"grpc/1.81.1#5217e6ef0544c42b46f4af35d5e7f649%1782307148.845616",
|
||||
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1782307148.15562",
|
||||
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1782392402.538492",
|
||||
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1782392402.681654",
|
||||
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1782392402.296732",
|
||||
"boost/1.91.0#ea540ca2133d831b560036aa24dece3c%1782392419.475605",
|
||||
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1782307147.395833"
|
||||
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152",
|
||||
"grpc/1.78.1#b1a9e74b145cc471bed4dc64dc6eb2c1%1774467387.342",
|
||||
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1765850143.772",
|
||||
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772",
|
||||
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1774439234.681",
|
||||
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1765850143.837",
|
||||
"boost/1.91.0#ea540ca2133d831b560036aa24dece3c%1778050991.9",
|
||||
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196"
|
||||
],
|
||||
"build_requires": [
|
||||
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708",
|
||||
"strawberryperl/5.32.1.1#8d114504d172cfea8ea1662d09b6333e%1782395692.540639",
|
||||
"protobuf/6.33.5#ff253ead763bd8d9904a52979cd21e81%1782392410.233933",
|
||||
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1782395690.33162",
|
||||
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1777558780.503",
|
||||
"strawberryperl/5.32.1.1#8d114504d172cfea8ea1662d09b6333e%1774447376.964",
|
||||
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1774467363.12",
|
||||
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1765850144.707",
|
||||
"msys2/cci.latest#d22fe7b2808f5fd34d0a7923ace9c54f%1770657326.649",
|
||||
"m4/1.4.19#34c4bbc3eeebe98ca6edf2f52d602e7d%1777282960.259",
|
||||
"cmake/4.3.3#840cf00ea09777e05c2050a50a82c722%1782392418.696091",
|
||||
"b2/5.4.2#ffd6084a119587e70f11cd45d1a386e2%1782392402.624226",
|
||||
"m4/1.4.19#4523e4347b55cd26ae918bd5770cab9a%1778062762.471",
|
||||
"cmake/4.3.0#b939a42e98f593fb34d3a8c5cc860359%1774439249.183",
|
||||
"b2/5.4.2#ffd6084a119587e70f11cd45d1a386e2%1774439233.447",
|
||||
"automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56",
|
||||
"autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86",
|
||||
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1782307147.395833"
|
||||
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196"
|
||||
],
|
||||
"python_requires": [],
|
||||
"overrides": {
|
||||
@@ -57,7 +57,7 @@
|
||||
"boost/1.91.0"
|
||||
],
|
||||
"lz4/[>=1.9.4 <2]": [
|
||||
"lz4/1.10.0#982d9b673900f665a1da109e09c17cab"
|
||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504"
|
||||
]
|
||||
},
|
||||
"config_requires": []
|
||||
|
||||
@@ -14,7 +14,7 @@ export CONAN_HOME="$TEMP_DIR"
|
||||
# Ensure that the xrplf remote is the first to be consulted, so any recipes we
|
||||
# patched are used. We also add it there to not created huge diff when the
|
||||
# official Conan Center Index is updated.
|
||||
conan remote add --force --index 0 xrplf https://conan.xrplf.org/repository/conan/
|
||||
conan remote add --force --index 0 xrplf https://conan.ripplex.io
|
||||
|
||||
# Delete any existing lockfile.
|
||||
rm -f conan.lock
|
||||
|
||||
@@ -28,10 +28,10 @@ class Xrpl(ConanFile):
|
||||
|
||||
requires = [
|
||||
"ed25519/2015.03",
|
||||
"grpc/1.81.1",
|
||||
"grpc/1.78.1",
|
||||
"libarchive/3.8.7",
|
||||
"nudb/2.0.9",
|
||||
"openssl/3.6.3",
|
||||
"openssl/3.6.2",
|
||||
"secp256k1/0.7.1",
|
||||
"soci/4.0.3",
|
||||
"zlib/1.3.2",
|
||||
|
||||
@@ -271,6 +271,8 @@ words:
|
||||
- sles
|
||||
- soci
|
||||
- socidb
|
||||
- sponsee
|
||||
- sponsees
|
||||
- SRPMS
|
||||
- sslws
|
||||
- statsd
|
||||
@@ -301,7 +303,6 @@ words:
|
||||
- txs
|
||||
- ubsan
|
||||
- UBSAN
|
||||
- ufdio
|
||||
- umant
|
||||
- unacquired
|
||||
- unambiguity
|
||||
|
||||
2
docs/build/advanced_conan.md
vendored
2
docs/build/advanced_conan.md
vendored
@@ -34,7 +34,7 @@ higher index than the default Conan Center remote, so it is consulted first. You
|
||||
can do this by running:
|
||||
|
||||
```bash
|
||||
conan remote add --index 0 --force xrplf https://conan.xrplf.org/repository/conan/
|
||||
conan remote add --index 0 --force xrplf https://conan.ripplex.io
|
||||
```
|
||||
|
||||
Alternatively, you can pull our recipes from the repository and export them locally:
|
||||
|
||||
@@ -12,8 +12,8 @@ template <int Window, typename Clock>
|
||||
class DecayingSample
|
||||
{
|
||||
public:
|
||||
using value_type = Clock::duration::rep;
|
||||
using time_point = Clock::time_point;
|
||||
using value_type = typename Clock::duration::rep;
|
||||
using time_point = typename Clock::time_point;
|
||||
|
||||
DecayingSample() = delete;
|
||||
|
||||
@@ -93,7 +93,7 @@ template <int HalfLife, class Clock>
|
||||
class DecayWindow
|
||||
{
|
||||
public:
|
||||
using time_point = Clock::time_point;
|
||||
using time_point = typename Clock::time_point;
|
||||
|
||||
explicit DecayWindow(time_point now) : when_(now)
|
||||
{
|
||||
|
||||
@@ -206,7 +206,8 @@ private:
|
||||
#ifndef JLOG
|
||||
#define JLOG(x) \
|
||||
if (!(x)) \
|
||||
; \
|
||||
{ \
|
||||
} \
|
||||
else \
|
||||
x
|
||||
#endif
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <xrpl/beast/insight/Insight.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
@@ -18,22 +17,6 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Replace-policy tags selecting how TaggedCache::canonicalizeImpl resolves a
|
||||
// collision when the key already exists (defined in TaggedCache.ipp):
|
||||
// - ReplaceCached: always replace the cached value with `data`. `data` is
|
||||
// never written back and may be const.
|
||||
// - ReplaceClient: keep the cached value and write it back into `data` (the
|
||||
// client's pointer), which must therefore be writable.
|
||||
// - ReplaceDynamically: call the supplied callback to decide per call; `data`
|
||||
// is written back when the cached value is kept, so it must be writable.
|
||||
struct ReplaceCached;
|
||||
struct ReplaceClient;
|
||||
struct ReplaceDynamically;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/** Map/cache combination.
|
||||
This class implements a cache and a map. The cache keeps objects alive
|
||||
in the map. The map allows multiple code paths that reference objects
|
||||
@@ -113,32 +96,6 @@ public:
|
||||
bool
|
||||
del(key_type const& key, bool valid);
|
||||
|
||||
private:
|
||||
// Selects the `data` parameter type of canonicalizeImpl from the replace
|
||||
// policy: const for detail::ReplaceCached (never written back), otherwise
|
||||
// writable.
|
||||
template <typename Policy>
|
||||
using CanonicalizeClientPointerType = std::conditional_t<
|
||||
std::is_same_v<detail::ReplaceCached, Policy>,
|
||||
SharedPointerType const&,
|
||||
SharedPointerType&>;
|
||||
|
||||
/** Shared implementation of the canonicalize family.
|
||||
|
||||
`policy` selects how a collision is resolved when `key` already exists:
|
||||
detail::ReplaceCached, detail::ReplaceClient or
|
||||
detail::ReplaceDynamically. For ReplaceDynamically `replaceCallback` is
|
||||
invoked with the existing strong pointer and returns whether to replace
|
||||
the cached value with `data`; for the tag policies it is unused.
|
||||
*/
|
||||
template <class Policy, class Callback = std::nullptr_t>
|
||||
bool
|
||||
canonicalizeImpl(
|
||||
key_type const& key,
|
||||
CanonicalizeClientPointerType<Policy> data,
|
||||
Policy policy,
|
||||
Callback&& replaceCallback = nullptr);
|
||||
|
||||
public:
|
||||
/** Replace aliased objects with originals.
|
||||
|
||||
@@ -147,52 +104,19 @@ public:
|
||||
This routine eliminates the duplicate and performs a replacement
|
||||
on the callers shared pointer if needed.
|
||||
|
||||
`replaceCallback` is a callable taking the existing strong pointer and
|
||||
returning whether to replace the cached value with `data` (true) or to
|
||||
keep the cached value and write it back into `data` (false). Because the
|
||||
write-back case mutates `data`, `data` must be writable.
|
||||
|
||||
@param key The key corresponding to the object
|
||||
@param data A shared pointer to the data corresponding to the object.
|
||||
@param replaceCallback A callable (existing strong pointer -> bool).
|
||||
@param replace Function that decides if cache should be replaced
|
||||
|
||||
@return `true` if an existing live entry was found and used; `false` if a new entry was
|
||||
inserted or an expired tracked entry was re-cached.
|
||||
**/
|
||||
template <class Callback>
|
||||
@return `true` If the key already existed.
|
||||
*/
|
||||
template <class R>
|
||||
bool
|
||||
canonicalize(key_type const& key, SharedPointerType& data, Callback&& replaceCallback);
|
||||
canonicalize(key_type const& key, SharedPointerType& data, R&& replaceCallback);
|
||||
|
||||
/** Insert/update the canonical entry for `key`, always replacing the
|
||||
cached value with `data`.
|
||||
|
||||
If an entry already exists for `key`, the cached value is unconditionally
|
||||
replaced with `data`; otherwise `data` is inserted. `data` is never
|
||||
written back, so it may be const.
|
||||
|
||||
@param key The key corresponding to the object.
|
||||
@param data A shared pointer to the data corresponding to the object.
|
||||
|
||||
@return `true` if an existing live entry was found and used; `false` if a new entry was
|
||||
inserted or an expired tracked entry was re-cached.
|
||||
**/
|
||||
bool
|
||||
canonicalizeReplaceCache(key_type const& key, SharedPointerType const& data);
|
||||
|
||||
/** Insert the canonical entry for `key`, keeping any existing cached value.
|
||||
|
||||
If an entry already exists for `key`, the cached value is kept and
|
||||
written back into `data` so the caller ends up with the canonical
|
||||
object; otherwise `data` is inserted. Because `data` may be overwritten
|
||||
it must be writable.
|
||||
|
||||
@param key The key corresponding to the object.
|
||||
@param data A shared pointer to the data corresponding to the object;
|
||||
updated to the canonical value when one already exists.
|
||||
|
||||
@return `true` if an existing live entry was found and used; `false` if a new entry was
|
||||
inserted or an expired tracked entry was re-cached.
|
||||
**/
|
||||
bool
|
||||
canonicalizeReplaceClient(key_type const& key, SharedPointerType& data);
|
||||
|
||||
@@ -338,7 +262,7 @@ private:
|
||||
sweepHelper(
|
||||
clock_type::time_point const& whenExpire,
|
||||
[[maybe_unused]] clock_type::time_point const& now,
|
||||
KeyValueCacheType::map_type& partition,
|
||||
typename KeyValueCacheType::map_type& partition,
|
||||
SweptPointersVector& stuffToSweep,
|
||||
std::atomic<int>& allRemovals,
|
||||
std::scoped_lock<std::recursive_mutex> const&);
|
||||
@@ -347,7 +271,7 @@ private:
|
||||
sweepHelper(
|
||||
clock_type::time_point const& whenExpire,
|
||||
clock_type::time_point const& now,
|
||||
KeyOnlyCacheType::map_type& partition,
|
||||
typename KeyOnlyCacheType::map_type& partition,
|
||||
SweptPointersVector&,
|
||||
std::atomic<int>& allRemovals,
|
||||
std::scoped_lock<std::recursive_mutex> const&);
|
||||
|
||||
@@ -5,30 +5,6 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Replace-policy tags selecting how TaggedCache::canonicalizeImpl resolves a
|
||||
// collision when the key already exists:
|
||||
// - ReplaceCached: always replace the cached value with `data`. `data` is
|
||||
// never written back and may be const.
|
||||
// - ReplaceClient: keep the cached value and write it back into `data` (the
|
||||
// client's pointer), which must therefore be writable.
|
||||
// - ReplaceDynamically: call the supplied callback to decide per call; `data`
|
||||
// is written back when the cached value is kept, so it must be writable.
|
||||
struct ReplaceCached
|
||||
{
|
||||
};
|
||||
|
||||
struct ReplaceClient
|
||||
{
|
||||
};
|
||||
|
||||
struct ReplaceDynamically
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <
|
||||
class Key,
|
||||
class T,
|
||||
@@ -324,29 +300,13 @@ template <
|
||||
class Hash,
|
||||
class KeyEqual,
|
||||
class Mutex>
|
||||
template <class Policy, class Callback>
|
||||
template <class R>
|
||||
inline bool
|
||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||
canonicalizeImpl(
|
||||
key_type const& key,
|
||||
CanonicalizeClientPointerType<Policy> data,
|
||||
[[maybe_unused]] Policy policy,
|
||||
[[maybe_unused]] Callback&& replaceCallback)
|
||||
canonicalize(key_type const& key, SharedPointerType& data, R&& replaceCallback)
|
||||
{
|
||||
// Return canonical value, store if needed, refresh in cache
|
||||
// Return values: true=we had the data already
|
||||
|
||||
// `Policy` is one of:
|
||||
// - detail::ReplaceCached: always replace the cached value with `data`;
|
||||
// `data` is never written back and may be const.
|
||||
// - detail::ReplaceClient: keep the cached value and write it back into
|
||||
// `data` (the client's pointer), which must therefore be writable.
|
||||
// - detail::ReplaceDynamically: call `replaceCallback` to decide at run
|
||||
// time; `data` must be writable.
|
||||
// For the latter two the write-back below requires a mutable `data`, so
|
||||
// passing a const argument is a compile error.
|
||||
constexpr bool replaceCached = std::is_same_v<Policy, detail::ReplaceCached>;
|
||||
|
||||
std::scoped_lock const lock(mutex_);
|
||||
|
||||
auto cit = cache_.find(key);
|
||||
@@ -364,14 +324,13 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
Entry& entry = cit->second;
|
||||
entry.touch(clock_.now());
|
||||
|
||||
auto shouldReplaceCached = [&] {
|
||||
if constexpr (replaceCached)
|
||||
auto shouldReplace = [&] {
|
||||
if constexpr (std::is_invocable_r_v<bool, R>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if constexpr (std::is_same_v<Policy, detail::ReplaceClient>)
|
||||
{
|
||||
return false;
|
||||
// The reason for this extra complexity is for intrusive
|
||||
// strong/weak combo getting a strong is relatively expensive
|
||||
// and not needed for many cases.
|
||||
return replaceCallback();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -381,11 +340,11 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
|
||||
if (entry.isCached())
|
||||
{
|
||||
if (shouldReplaceCached())
|
||||
if (shouldReplace())
|
||||
{
|
||||
entry.ptr = data;
|
||||
}
|
||||
else if constexpr (!replaceCached)
|
||||
else
|
||||
{
|
||||
data = entry.ptr.getStrong();
|
||||
}
|
||||
@@ -397,11 +356,11 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
|
||||
if (cachedData)
|
||||
{
|
||||
if (shouldReplaceCached())
|
||||
if (shouldReplace())
|
||||
{
|
||||
entry.ptr = data;
|
||||
}
|
||||
else if constexpr (!replaceCached)
|
||||
else
|
||||
{
|
||||
entry.ptr.convertToStrong();
|
||||
data = cachedData;
|
||||
@@ -417,24 +376,6 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
return false;
|
||||
}
|
||||
|
||||
template <
|
||||
class Key,
|
||||
class T,
|
||||
bool IsKeyCache,
|
||||
class SharedWeakUnionPointer,
|
||||
class SharedPointerType,
|
||||
class Hash,
|
||||
class KeyEqual,
|
||||
class Mutex>
|
||||
template <class Callback>
|
||||
inline bool
|
||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||
canonicalize(key_type const& key, SharedPointerType& data, Callback&& replaceCallback)
|
||||
{
|
||||
return canonicalizeImpl(
|
||||
key, data, detail::ReplaceDynamically{}, std::forward<Callback>(replaceCallback));
|
||||
}
|
||||
|
||||
template <
|
||||
class Key,
|
||||
class T,
|
||||
@@ -448,7 +389,7 @@ inline bool
|
||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||
canonicalizeReplaceCache(key_type const& key, SharedPointerType const& data)
|
||||
{
|
||||
return canonicalizeImpl(key, data, detail::ReplaceCached{});
|
||||
return canonicalize(key, const_cast<SharedPointerType&>(data), []() { return true; });
|
||||
}
|
||||
|
||||
template <
|
||||
@@ -464,7 +405,7 @@ inline bool
|
||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||
canonicalizeReplaceClient(key_type const& key, SharedPointerType& data)
|
||||
{
|
||||
return canonicalizeImpl(key, data, detail::ReplaceClient{});
|
||||
return canonicalize(key, data, []() { return false; });
|
||||
}
|
||||
|
||||
template <
|
||||
@@ -735,7 +676,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
sweepHelper(
|
||||
clock_type::time_point const& whenExpire,
|
||||
[[maybe_unused]] clock_type::time_point const& now,
|
||||
KeyValueCacheType::map_type& partition,
|
||||
typename KeyValueCacheType::map_type& partition,
|
||||
SweptPointersVector& stuffToSweep,
|
||||
std::atomic<int>& allRemovals,
|
||||
std::scoped_lock<std::recursive_mutex> const&)
|
||||
@@ -815,7 +756,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
sweepHelper(
|
||||
clock_type::time_point const& whenExpire,
|
||||
clock_type::time_point const& now,
|
||||
KeyOnlyCacheType::map_type& partition,
|
||||
typename KeyOnlyCacheType::map_type& partition,
|
||||
SweptPointersVector&,
|
||||
std::atomic<int>& allRemovals,
|
||||
std::scoped_lock<std::recursive_mutex> const&)
|
||||
|
||||
@@ -75,7 +75,7 @@ private:
|
||||
detail::seed_pair seeds_{detail::makeSeedPair<>()};
|
||||
|
||||
public:
|
||||
using result_type = HashAlgorithm::result_type;
|
||||
using result_type = typename HashAlgorithm::result_type;
|
||||
|
||||
HardenedHash() = default;
|
||||
|
||||
|
||||
@@ -57,8 +57,8 @@ public:
|
||||
{
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
partition_map_type* map{nullptr};
|
||||
partition_map_type::iterator ait{};
|
||||
map_type::iterator mit;
|
||||
typename partition_map_type::iterator ait{};
|
||||
typename map_type::iterator mit;
|
||||
|
||||
Iterator() = default;
|
||||
|
||||
@@ -126,8 +126,8 @@ public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
partition_map_type* map{nullptr};
|
||||
partition_map_type::iterator ait{};
|
||||
map_type::iterator mit;
|
||||
typename partition_map_type::iterator ait{};
|
||||
typename map_type::iterator mit;
|
||||
|
||||
ConstIterator() = default;
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ static_assert(
|
||||
namespace detail {
|
||||
|
||||
// Determines if a type can be called like an Engine
|
||||
// NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
|
||||
template <class Engine, class Result = typename Engine::result_type>
|
||||
using is_engine = std::is_invocable_r<Result, Engine>;
|
||||
} // namespace detail
|
||||
|
||||
@@ -18,8 +18,8 @@ template <class Clock>
|
||||
class IOLatencyProbe
|
||||
{
|
||||
private:
|
||||
using duration = Clock::duration;
|
||||
using time_point = Clock::time_point;
|
||||
using duration = typename Clock::duration;
|
||||
using time_point = typename Clock::time_point;
|
||||
|
||||
std::recursive_mutex mutex_;
|
||||
std::condition_variable_any cond_;
|
||||
|
||||
@@ -34,10 +34,10 @@ template <class Clock>
|
||||
class AbstractClock
|
||||
{
|
||||
public:
|
||||
using rep = Clock::rep;
|
||||
using period = Clock::period;
|
||||
using duration = Clock::duration;
|
||||
using time_point = Clock::time_point;
|
||||
using rep = typename Clock::rep;
|
||||
using period = typename Clock::period;
|
||||
using duration = typename Clock::duration;
|
||||
using time_point = typename Clock::time_point;
|
||||
using clock_type = Clock;
|
||||
|
||||
static bool const is_steady = Clock::is_steady; // NOLINT(readability-identifier-naming)
|
||||
|
||||
@@ -20,10 +20,10 @@ public:
|
||||
|
||||
explicit BasicSecondsClock() = default;
|
||||
|
||||
using rep = Clock::rep;
|
||||
using period = Clock::period;
|
||||
using duration = Clock::duration;
|
||||
using time_point = Clock::time_point;
|
||||
using rep = typename Clock::rep;
|
||||
using period = typename Clock::period;
|
||||
using duration = typename Clock::duration;
|
||||
using time_point = typename Clock::time_point;
|
||||
|
||||
static bool const is_steady = // NOLINT(readability-identifier-naming)
|
||||
Clock::is_steady;
|
||||
|
||||
@@ -16,15 +16,15 @@ template <bool IsConst, class Iterator>
|
||||
class AgedContainerIterator
|
||||
{
|
||||
public:
|
||||
using iterator_category = std::iterator_traits<Iterator>::iterator_category;
|
||||
using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
|
||||
using value_type = std::conditional_t<
|
||||
IsConst,
|
||||
typename Iterator::value_type::Stashed::value_type const,
|
||||
typename Iterator::value_type::Stashed::value_type>;
|
||||
using difference_type = std::iterator_traits<Iterator>::difference_type;
|
||||
using difference_type = typename std::iterator_traits<Iterator>::difference_type;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
using time_point = Iterator::value_type::Stashed::time_point;
|
||||
using time_point = typename Iterator::value_type::Stashed::time_point;
|
||||
|
||||
AgedContainerIterator() = default;
|
||||
|
||||
|
||||
@@ -62,8 +62,8 @@ class AgedOrderedContainer
|
||||
{
|
||||
public:
|
||||
using clock_type = AbstractClock<Clock>;
|
||||
using time_point = clock_type::time_point;
|
||||
using duration = clock_type::duration;
|
||||
using time_point = typename clock_type::time_point;
|
||||
using duration = typename clock_type::duration;
|
||||
using key_type = Key;
|
||||
using mapped_type = T;
|
||||
using value_type = std::conditional_t<IsMap, std::pair<Key const, T>, Key>;
|
||||
@@ -94,8 +94,8 @@ private:
|
||||
{
|
||||
explicit Stashed() = default;
|
||||
|
||||
using value_type = AgedOrderedContainer::value_type;
|
||||
using time_point = AgedOrderedContainer::time_point;
|
||||
using value_type = typename AgedOrderedContainer::value_type;
|
||||
using time_point = typename AgedOrderedContainer::time_point;
|
||||
};
|
||||
|
||||
Element(time_point const& when, value_type const& value) : value(value), when(when)
|
||||
@@ -192,8 +192,8 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
using list_type =
|
||||
boost::intrusive::make_list<Element, boost::intrusive::constant_time_size<false>>::type;
|
||||
using list_type = typename boost::intrusive::
|
||||
make_list<Element, boost::intrusive::constant_time_size<false>>::type;
|
||||
|
||||
using cont_type = std::conditional_t<
|
||||
IsMulti,
|
||||
@@ -206,7 +206,8 @@ private:
|
||||
boost::intrusive::constant_time_size<true>,
|
||||
boost::intrusive::compare<KeyValueCompare>>::type>;
|
||||
|
||||
using ElementAllocator = std::allocator_traits<Allocator>::template rebind_alloc<Element>;
|
||||
using ElementAllocator =
|
||||
typename std::allocator_traits<Allocator>::template rebind_alloc<Element>;
|
||||
|
||||
using ElementAllocatorTraits = std::allocator_traits<ElementAllocator>;
|
||||
|
||||
@@ -372,8 +373,8 @@ public:
|
||||
using allocator_type = Allocator;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using pointer = std::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = std::allocator_traits<Allocator>::const_pointer;
|
||||
using pointer = typename std::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;
|
||||
|
||||
// A set iterator (IsMap==false) is always const
|
||||
// because the elements of a set are immutable.
|
||||
@@ -616,7 +617,7 @@ public:
|
||||
bool MaybeMulti = IsMulti,
|
||||
bool MaybeMap = IsMap,
|
||||
class = std::enable_if_t<MaybeMap && !MaybeMulti>>
|
||||
std::conditional<IsMap, T, void*>::type const&
|
||||
typename std::conditional<IsMap, T, void*>::type const&
|
||||
at(K const& k) const;
|
||||
|
||||
template <
|
||||
@@ -1145,7 +1146,7 @@ private:
|
||||
void
|
||||
touch(
|
||||
beast::detail::AgedContainerIterator<IsConst, Iterator> pos,
|
||||
clock_type::time_point const& now);
|
||||
typename clock_type::time_point const& now);
|
||||
|
||||
template <
|
||||
bool MaybePropagate = std::allocator_traits<Allocator>::propagate_on_container_swap::value>
|
||||
@@ -1392,7 +1393,7 @@ AgedOrderedContainer<IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::at(K co
|
||||
|
||||
template <bool IsMulti, bool IsMap, class Key, class T, class Clock, class Compare, class Allocator>
|
||||
template <class K, bool MaybeMulti, bool MaybeMap, class>
|
||||
std::conditional<IsMap, T, void*>::type const&
|
||||
typename std::conditional<IsMap, T, void*>::type const&
|
||||
AgedOrderedContainer<IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::at(K const& k) const
|
||||
{
|
||||
auto const iter(cont_.find(k, std::cref(config_.keyCompare())));
|
||||
@@ -1731,7 +1732,7 @@ AgedOrderedContainer<IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::operato
|
||||
cend(),
|
||||
other.cbegin(),
|
||||
other.cend(),
|
||||
[&eq, &other](value_type const& lhs, Other::value_type const& rhs) {
|
||||
[&eq, &other](value_type const& lhs, typename Other::value_type const& rhs) {
|
||||
return eq(extract(lhs), other.extract(rhs));
|
||||
});
|
||||
}
|
||||
@@ -1743,7 +1744,7 @@ template <bool IsConst, class Iterator, class>
|
||||
void
|
||||
AgedOrderedContainer<IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::touch(
|
||||
beast::detail::AgedContainerIterator<IsConst, Iterator> pos,
|
||||
clock_type::time_point const& now)
|
||||
typename clock_type::time_point const& now)
|
||||
{
|
||||
auto& e(*pos.iterator());
|
||||
e.when = now;
|
||||
|
||||
@@ -67,8 +67,8 @@ class AgedUnorderedContainer
|
||||
{
|
||||
public:
|
||||
using clock_type = AbstractClock<Clock>;
|
||||
using time_point = clock_type::time_point;
|
||||
using duration = clock_type::duration;
|
||||
using time_point = typename clock_type::time_point;
|
||||
using duration = typename clock_type::duration;
|
||||
using key_type = Key;
|
||||
using mapped_type = T;
|
||||
using value_type = std::conditional_t<IsMap, std::pair<Key const, T>, Key>;
|
||||
@@ -99,8 +99,8 @@ private:
|
||||
{
|
||||
explicit Stashed() = default;
|
||||
|
||||
using value_type = AgedUnorderedContainer::value_type;
|
||||
using time_point = AgedUnorderedContainer::time_point;
|
||||
using value_type = typename AgedUnorderedContainer::value_type;
|
||||
using time_point = typename AgedUnorderedContainer::time_point;
|
||||
};
|
||||
|
||||
Element(time_point const& when, value_type const& value) : value(value), when(when)
|
||||
@@ -201,8 +201,8 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
using list_type =
|
||||
boost::intrusive::make_list<Element, boost::intrusive::constant_time_size<false>>::type;
|
||||
using list_type = typename boost::intrusive::
|
||||
make_list<Element, boost::intrusive::constant_time_size<false>>::type;
|
||||
|
||||
using cont_type = std::conditional_t<
|
||||
IsMulti,
|
||||
@@ -219,14 +219,16 @@ private:
|
||||
boost::intrusive::equal<KeyValueEqual>,
|
||||
boost::intrusive::cache_begin<true>>::type>;
|
||||
|
||||
using bucket_type = cont_type::bucket_type;
|
||||
using bucket_traits = cont_type::bucket_traits;
|
||||
using bucket_type = typename cont_type::bucket_type;
|
||||
using bucket_traits = typename cont_type::bucket_traits;
|
||||
|
||||
using ElementAllocator = std::allocator_traits<Allocator>::template rebind_alloc<Element>;
|
||||
using ElementAllocator =
|
||||
typename std::allocator_traits<Allocator>::template rebind_alloc<Element>;
|
||||
|
||||
using ElementAllocatorTraits = std::allocator_traits<ElementAllocator>;
|
||||
|
||||
using BucketAllocator = std::allocator_traits<Allocator>::template rebind_alloc<Element>;
|
||||
using BucketAllocator =
|
||||
typename std::allocator_traits<Allocator>::template rebind_alloc<Element>;
|
||||
|
||||
using BucketAllocatorTraits = std::allocator_traits<BucketAllocator>;
|
||||
|
||||
@@ -540,8 +542,8 @@ public:
|
||||
using allocator_type = Allocator;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using pointer = std::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = std::allocator_traits<Allocator>::const_pointer;
|
||||
using pointer = typename std::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;
|
||||
|
||||
// A set iterator (IsMap==false) is always const
|
||||
// because the elements of a set are immutable.
|
||||
@@ -848,7 +850,7 @@ public:
|
||||
bool MaybeMulti = IsMulti,
|
||||
bool MaybeMap = IsMap,
|
||||
class = std::enable_if_t<MaybeMap && !MaybeMulti>>
|
||||
std::conditional<IsMap, T, void*>::type const&
|
||||
typename std::conditional<IsMap, T, void*>::type const&
|
||||
at(K const& k) const;
|
||||
|
||||
template <
|
||||
@@ -1412,7 +1414,7 @@ private:
|
||||
void
|
||||
touch(
|
||||
beast::detail::AgedContainerIterator<IsConst, Iterator> pos,
|
||||
clock_type::time_point const& now)
|
||||
typename clock_type::time_point const& now)
|
||||
{
|
||||
auto& e(*pos.iterator());
|
||||
e.when = now;
|
||||
@@ -2109,7 +2111,7 @@ template <
|
||||
class KeyEqual,
|
||||
class Allocator>
|
||||
template <class K, bool MaybeMulti, bool MaybeMap, class>
|
||||
std::conditional<IsMap, T, void*>::type const&
|
||||
typename std::conditional<IsMap, T, void*>::type const&
|
||||
AgedUnorderedContainer<IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>::at(
|
||||
K const& k) const
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ struct CopyConst<T const, U>
|
||||
{
|
||||
explicit CopyConst() = default;
|
||||
|
||||
using type = std::remove_const<U>::type const;
|
||||
using type = typename std::remove_const<U>::type const;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
@@ -56,7 +56,7 @@ class ListIterator
|
||||
{
|
||||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = beast::detail::CopyConst<N, typename N::value_type>::type;
|
||||
using value_type = typename beast::detail::CopyConst<N, typename N::value_type>::type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
@@ -259,7 +259,7 @@ template <typename T, typename Tag = void>
|
||||
class List
|
||||
{
|
||||
public:
|
||||
using Node = detail::ListNode<T, Tag>;
|
||||
using Node = typename detail::ListNode<T, Tag>;
|
||||
|
||||
using value_type = T;
|
||||
using pointer = value_type*;
|
||||
|
||||
@@ -12,13 +12,13 @@ template <class Container, bool IsConst>
|
||||
class LockFreeStackIterator
|
||||
{
|
||||
protected:
|
||||
using Node = Container::Node;
|
||||
using Node = typename Container::Node;
|
||||
using NodePtr = std::conditional_t<IsConst, Node const*, Node*>;
|
||||
|
||||
public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = Container::value_type;
|
||||
using difference_type = Container::difference_type;
|
||||
using value_type = typename Container::value_type;
|
||||
using difference_type = typename Container::difference_type;
|
||||
using pointer =
|
||||
std::conditional_t<IsConst, typename Container::const_pointer, typename Container::pointer>;
|
||||
using reference = std::
|
||||
|
||||
@@ -11,7 +11,7 @@ struct Uhash
|
||||
{
|
||||
Uhash() = default;
|
||||
|
||||
using result_type = Hasher::result_type;
|
||||
using result_type = typename Hasher::result_type;
|
||||
|
||||
template <class T>
|
||||
result_type
|
||||
|
||||
@@ -102,7 +102,7 @@ Result
|
||||
split(FwdIt first, FwdIt last, Char delim)
|
||||
{
|
||||
using namespace detail;
|
||||
using string = Result::value_type;
|
||||
using string = typename Result::value_type;
|
||||
|
||||
Result result;
|
||||
|
||||
|
||||
@@ -32,11 +32,11 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = cont_type::value_type;
|
||||
using size_type = cont_type::size_type;
|
||||
using difference_type = cont_type::difference_type;
|
||||
using iterator = cont_type::const_iterator;
|
||||
using const_iterator = cont_type::const_iterator;
|
||||
using value_type = typename cont_type::value_type;
|
||||
using size_type = typename cont_type::size_type;
|
||||
using difference_type = typename cont_type::difference_type;
|
||||
using iterator = typename cont_type::const_iterator;
|
||||
using const_iterator = typename cont_type::const_iterator;
|
||||
|
||||
/** Returns `true` if the container is empty. */
|
||||
[[nodiscard]] bool
|
||||
|
||||
@@ -48,7 +48,7 @@ private:
|
||||
std::size_t cases = 0;
|
||||
std::size_t total = 0;
|
||||
std::size_t failed = 0;
|
||||
clock_type::time_point start = clock_type::now();
|
||||
typename clock_type::time_point start = clock_type::now();
|
||||
|
||||
explicit SuiteResults(std::string name = "") : name(std::move(name))
|
||||
{
|
||||
@@ -60,7 +60,7 @@ private:
|
||||
|
||||
struct Results
|
||||
{
|
||||
using run_time = std::pair<std::string, clock_type::duration>;
|
||||
using run_time = std::pair<std::string, typename clock_type::duration>;
|
||||
|
||||
static constexpr auto kMaxTop = 10;
|
||||
|
||||
@@ -69,7 +69,7 @@ private:
|
||||
std::size_t total = 0;
|
||||
std::size_t failed = 0;
|
||||
std::vector<run_time> top;
|
||||
clock_type::time_point start = clock_type::now();
|
||||
typename clock_type::time_point start = clock_type::now();
|
||||
|
||||
void
|
||||
add(SuiteResults const& r);
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
|
||||
private:
|
||||
static std::string
|
||||
fmtdur(clock_type::duration const& d);
|
||||
fmtdur(typename clock_type::duration const& d);
|
||||
|
||||
void
|
||||
onSuiteBegin(SuiteInfo const& info) override;
|
||||
@@ -141,7 +141,9 @@ Reporter<Unused>::Results::add(SuiteResults const& r)
|
||||
top.begin(),
|
||||
top.end(),
|
||||
elapsed,
|
||||
[](run_time const& t1, clock_type::duration const& t2) { return t1.second > t2; });
|
||||
[](run_time const& t1, typename clock_type::duration const& t2) {
|
||||
return t1.second > t2;
|
||||
});
|
||||
if (iter != top.end())
|
||||
{
|
||||
if (top.size() == kMaxTop)
|
||||
@@ -179,7 +181,7 @@ Reporter<Unused>::~Reporter()
|
||||
|
||||
template <class Unused>
|
||||
std::string
|
||||
Reporter<Unused>::fmtdur(clock_type::duration const& d)
|
||||
Reporter<Unused>::fmtdur(typename clock_type::duration const& d)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
auto const ms = duration_cast<milliseconds>(d);
|
||||
|
||||
@@ -411,9 +411,9 @@ class BasicLogstream : public std::basic_ostream<CharT, Traits>
|
||||
{
|
||||
using char_type = CharT;
|
||||
using traits_type = Traits;
|
||||
using int_type = traits_type::int_type;
|
||||
using pos_type = traits_type::pos_type;
|
||||
using off_type = traits_type::off_type;
|
||||
using int_type = typename traits_type::int_type;
|
||||
using pos_type = typename traits_type::pos_type;
|
||||
using off_type = typename traits_type::off_type;
|
||||
|
||||
detail::LogStreamBuf<CharT, Traits> buf_;
|
||||
|
||||
|
||||
@@ -15,6 +15,6 @@ struct MaybeConst
|
||||
|
||||
/** Alias for omitting `typename`. */
|
||||
template <bool IsConst, class T>
|
||||
using maybe_const_t = MaybeConst<IsConst, T>::type;
|
||||
using maybe_const_t = typename MaybeConst<IsConst, T>::type;
|
||||
|
||||
} // namespace beast
|
||||
|
||||
@@ -13,7 +13,7 @@ template <class Generator>
|
||||
void
|
||||
rngfill(void* const buffer, std::size_t const bytes, Generator& g)
|
||||
{
|
||||
using result_type = Generator::result_type;
|
||||
using result_type = typename Generator::result_type;
|
||||
constexpr std::size_t kResultSize = sizeof(result_type);
|
||||
|
||||
std::uint8_t* const bufferStart = static_cast<std::uint8_t*>(buffer);
|
||||
@@ -42,7 +42,7 @@ template <
|
||||
void
|
||||
rngfill(std::array<std::uint8_t, N>& a, Generator& g)
|
||||
{
|
||||
using result_type = Generator::result_type;
|
||||
using result_type = typename Generator::result_type;
|
||||
auto i = N / sizeof(result_type);
|
||||
result_type* p = reinterpret_cast<result_type*>(a.data());
|
||||
while (i--)
|
||||
|
||||
@@ -566,7 +566,6 @@ public:
|
||||
using SelfType = ValueConstIterator;
|
||||
|
||||
ValueConstIterator() = default;
|
||||
ValueConstIterator(ValueConstIterator const& other) = default;
|
||||
|
||||
private:
|
||||
/*! \internal Use by Value to create an iterator.
|
||||
@@ -575,12 +574,12 @@ private:
|
||||
|
||||
public:
|
||||
SelfType&
|
||||
operator=(SelfType const& other);
|
||||
operator=(ValueIteratorBase const& other);
|
||||
|
||||
SelfType
|
||||
operator++(int)
|
||||
{
|
||||
SelfType const temp(*this);
|
||||
SelfType temp(*this);
|
||||
++*this;
|
||||
return temp;
|
||||
}
|
||||
@@ -588,7 +587,7 @@ public:
|
||||
SelfType
|
||||
operator--(int)
|
||||
{
|
||||
SelfType const temp(*this);
|
||||
SelfType temp(*this);
|
||||
--*this;
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -37,8 +37,6 @@ reduceOffer(auto const& amount)
|
||||
|
||||
enum class IsDeposit : bool { No = false, Yes = true };
|
||||
|
||||
inline Number const kAMMInvariantRelativeTolerance{1, -11};
|
||||
|
||||
/** Calculate LP Tokens given AMM pool reserves.
|
||||
* @param asset1 AMM one side of the pool reserve
|
||||
* @param asset2 AMM another side of the pool reserve
|
||||
@@ -740,30 +738,6 @@ ammPoolHolds(
|
||||
AuthHandling authHandling,
|
||||
beast::Journal const j);
|
||||
|
||||
/** Check AMM pool product invariant after an AMM operation that changes LP tokens
|
||||
* (deposit/withdraw/clawback) from an already calculated pool product mean.
|
||||
* Returns tecPRECISION_LOSS if poolProductMean < newLPTokenBalance beyond the
|
||||
* invariant tolerance,
|
||||
* tesSUCCESS otherwise. Skips check when newLPTokenBalance is zero (last withdrawal).
|
||||
*/
|
||||
TER
|
||||
checkAMMPrecisionLoss(Number const& poolProductMean, STAmount const& newLPTokenBalance);
|
||||
|
||||
/** Check AMM pool product invariant after an AMM operation that changes LP tokens
|
||||
* (deposit/withdraw/clawback).
|
||||
* Returns tecPRECISION_LOSS if sqrt(asset1 * asset2) < newLPTokenBalance beyond
|
||||
* the invariant tolerance,
|
||||
* tesSUCCESS otherwise. Skips check when newLPTokenBalance is zero (last withdrawal).
|
||||
*/
|
||||
TER
|
||||
checkAMMPrecisionLoss(
|
||||
ReadView const& view,
|
||||
AccountID const& ammAccountID,
|
||||
Asset const& asset1,
|
||||
Asset const& asset2,
|
||||
STAmount const& newLPTokenBalance,
|
||||
beast::Journal const j);
|
||||
|
||||
/** Get AMM pool and LP token balances. If both optIssue are
|
||||
* provided then they are used as the AMM token pair issues.
|
||||
* Otherwise the missing issues are fetched from ammSle.
|
||||
|
||||
@@ -33,9 +33,96 @@ isGlobalFrozen(ReadView const& view, AccountID const& issuer);
|
||||
[[nodiscard]] XRPAmount
|
||||
xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j);
|
||||
|
||||
/** Returns the account reserve, in drops.
|
||||
Actual owner count can be adjusted by delta in ownerCountAdj
|
||||
The reserve is calculated as
|
||||
(ownerCount + "sponsoring object count" - "sponsored object count" + additionalOwnerCount) *
|
||||
increment + (1 if not sponsored account + sponsoringAccountCount) * "reserve base"
|
||||
*/
|
||||
[[nodiscard]] XRPAmount
|
||||
accountReserve(
|
||||
ReadView const& view,
|
||||
SLE::const_ref sle,
|
||||
beast::Journal j,
|
||||
std::int32_t ownerCountAdj = 0,
|
||||
std::int32_t reserveCountAdj = 0);
|
||||
|
||||
[[nodiscard]] inline XRPAmount
|
||||
accountReserve(
|
||||
ReadView const& view,
|
||||
AccountID const& id,
|
||||
beast::Journal j,
|
||||
std::int32_t ownerCountAdj = 0,
|
||||
std::int32_t reserveCountAdj = 0)
|
||||
{
|
||||
return accountReserve(view, view.read(keylet::account(id)), j, ownerCountAdj, reserveCountAdj);
|
||||
}
|
||||
|
||||
XRPAmount
|
||||
baseAccountReserve(ReadView const& view, std::int32_t ownerCount);
|
||||
|
||||
[[nodiscard]] TER
|
||||
checkInsufficientReserve(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
SLE::const_ref accSle,
|
||||
STAmount const& accBalance,
|
||||
SLE::const_ref sponsorSle,
|
||||
std::int32_t ownerCountDelta,
|
||||
std::int32_t reserveCountDelta = 0,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
|
||||
|
||||
std::uint32_t
|
||||
ownerCount(
|
||||
ReadView const& view,
|
||||
SLE::const_ref sle,
|
||||
beast::Journal j,
|
||||
std::int32_t ownerCountAdj = 0);
|
||||
|
||||
/** Adjust the owner count up or down. */
|
||||
void
|
||||
adjustOwnerCount(ApplyView& view, SLE::ref sle, std::int32_t amount, beast::Journal j);
|
||||
adjustOwnerCount(
|
||||
ApplyView& view,
|
||||
SLE::ref accountSle,
|
||||
SLE::ref sponsorSle,
|
||||
std::int32_t amount,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
|
||||
|
||||
inline void
|
||||
adjustOwnerCount(
|
||||
ApplyView& view,
|
||||
AccountID const& account,
|
||||
std::optional<AccountID> const& sponsor,
|
||||
std::int32_t amount,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
{
|
||||
adjustOwnerCount(
|
||||
view,
|
||||
view.peek(keylet::account(account)),
|
||||
sponsor ? view.peek(keylet::account(*sponsor)) : SLE::pointer(),
|
||||
amount,
|
||||
j);
|
||||
}
|
||||
|
||||
void
|
||||
adjustOwnerCountObj(
|
||||
ApplyView& view,
|
||||
SLE::ref accountSle,
|
||||
SLE::ref objectSle,
|
||||
std::int32_t amount,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
|
||||
|
||||
inline void
|
||||
adjustOwnerCountObj(
|
||||
ApplyView& view,
|
||||
AccountID const& account,
|
||||
SLE::ref objectSle,
|
||||
std::int32_t amount,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
{
|
||||
SLE::ref accountSle = view.peek(keylet::account(account));
|
||||
adjustOwnerCountObj(view, accountSle, objectSle, amount, j);
|
||||
}
|
||||
|
||||
/** Returns IOU issuer transfer fee as Rate. Rate specifies
|
||||
* the fee as fractions of 1 billion. For example, 1% transfer rate
|
||||
@@ -71,7 +158,7 @@ getPseudoAccountFields();
|
||||
- null pointer
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isPseudoAccount(SLE::const_pointer sleAcct, std::set<SField const*> const& pseudoFieldFilter = {});
|
||||
isPseudoAccount(SLE::const_ref sleAcct, std::set<SField const*> const& pseudoFieldFilter = {});
|
||||
|
||||
/** Convenience overload that reads the account from the view. */
|
||||
[[nodiscard]] inline bool
|
||||
|
||||
@@ -23,9 +23,13 @@ checkTxPermission(SLE::const_ref delegate, STTx const& tx);
|
||||
* @param delegate The delegate account.
|
||||
* @param type Used to determine which granted granular permissions to load,
|
||||
* based on the transaction type.
|
||||
* @return the granted granular permissions tied to the transaction type.
|
||||
* @param granularPermissions Granted granular permissions tied to the
|
||||
* transaction type.
|
||||
*/
|
||||
std::unordered_set<GranularPermissionType>
|
||||
getGranularPermission(SLE::const_ref delegate, TxType const& type);
|
||||
void
|
||||
loadGranularPermission(
|
||||
SLE::const_ref delegate,
|
||||
TxType const& type,
|
||||
std::unordered_set<GranularPermissionType>& granularPermissions);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/MPTAmount.h>
|
||||
@@ -17,6 +18,7 @@ template <ValidIssueType T>
|
||||
TER
|
||||
escrowUnlockApplyHelper(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
Rate lockedRate,
|
||||
SLE::ref sleDest,
|
||||
STAmount const& xrpBalance,
|
||||
@@ -31,6 +33,7 @@ template <>
|
||||
inline TER
|
||||
escrowUnlockApplyHelper<Issue>(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
Rate lockedRate,
|
||||
SLE::ref sleDest,
|
||||
STAmount const& xrpBalance,
|
||||
@@ -56,8 +59,13 @@ escrowUnlockApplyHelper<Issue>(
|
||||
if (!view.exists(trustLineKey) && createAsset)
|
||||
{
|
||||
// Can the account cover the trust line's reserve?
|
||||
if (std::uint32_t const ownerCount = {sleDest->at(sfOwnerCount)};
|
||||
xrpBalance < view.fees().accountReserve(ownerCount + 1))
|
||||
auto const sponsorSle = getTxReserveSponsor(view, tx);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ret =
|
||||
checkInsufficientReserve(view, tx, sleDest, xrpBalance, *sponsorSle, 1, 0, journal);
|
||||
!isTesSuccess(ret))
|
||||
{
|
||||
JLOG(journal.trace()) << "Trust line does not exist. "
|
||||
"Insufficient reserve to create line.";
|
||||
@@ -84,6 +92,7 @@ escrowUnlockApplyHelper<Issue>(
|
||||
Issue(currency, receiver), // limit of zero
|
||||
0, // quality in
|
||||
0, // quality out
|
||||
*sponsorSle, // sponsor
|
||||
journal); // journal
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
@@ -161,6 +170,7 @@ template <>
|
||||
inline TER
|
||||
escrowUnlockApplyHelper<MPTIssue>(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
Rate lockedRate,
|
||||
SLE::ref sleDest,
|
||||
STAmount const& xrpBalance,
|
||||
@@ -176,24 +186,31 @@ escrowUnlockApplyHelper<MPTIssue>(
|
||||
|
||||
auto const mptID = amount.get<MPTIssue>().getMptID();
|
||||
auto const issuanceKey = keylet::mptIssuance(mptID);
|
||||
if (!view.exists(keylet::mptoken(issuanceKey.key, receiver)) && createAsset && !receiverIssuer)
|
||||
auto const mptKeylet = keylet::mptoken(issuanceKey.key, receiver);
|
||||
if (!view.exists(mptKeylet) && createAsset && !receiverIssuer)
|
||||
{
|
||||
if (std::uint32_t const ownerCount = {sleDest->at(sfOwnerCount)};
|
||||
xrpBalance < view.fees().accountReserve(ownerCount + 1))
|
||||
{
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
auto const sponsorSle = getTxReserveSponsor(view, tx);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ter = createMPToken(view, mptID, receiver, 0); !isTesSuccess(ter))
|
||||
if (auto const ret =
|
||||
checkInsufficientReserve(view, tx, sleDest, xrpBalance, *sponsorSle, 1, 0, journal);
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
if (auto const ter = createMPToken(view, mptID, receiver, *sponsorSle, 0);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
// update owner count.
|
||||
adjustOwnerCount(view, sleDest, 1, journal);
|
||||
adjustOwnerCount(view, sleDest, *sponsorSle, 1, journal);
|
||||
auto mptSle = view.peek(mptKeylet);
|
||||
addSponsorToLedgerEntry(mptSle, *sponsorSle);
|
||||
}
|
||||
|
||||
if (!view.exists(keylet::mptoken(issuanceKey.key, receiver)) && !receiverIssuer)
|
||||
if (!view.exists(mptKeylet) && !receiverIssuer)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
auto const xferRate = transferRate(view, amount);
|
||||
|
||||
100
include/xrpl/ledger/helpers/FundingSource.h
Normal file
100
include/xrpl/ledger/helpers/FundingSource.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// FundingSource hides the AccountRoot-vs-Sponsorship-object dispatch behind
|
||||
// one type, so call sites that need to read or debit a balance don't have to
|
||||
// branch on "is this sponsored, and if so, how" at every step.
|
||||
enum class FundingKind {
|
||||
AccountRoot, // funded from an Account's sfBalance
|
||||
Sponsorship, // funded from a Sponsorship object's sfFeeAmount
|
||||
};
|
||||
|
||||
struct FundingSource
|
||||
{
|
||||
FundingKind kind;
|
||||
Keylet keylet;
|
||||
AccountID accountId;
|
||||
};
|
||||
|
||||
// Both funding sources for a transaction, plus tx-level flags that apply
|
||||
// equally to fee and reserve sources.
|
||||
struct TxPayers
|
||||
{
|
||||
AccountID initiator; // tx[sfAccount]
|
||||
FundingSource feeSource;
|
||||
FundingSource reserveSource;
|
||||
bool isCoSigned; // tx has sfSponsorSignature
|
||||
bool isDelegate; // tx has sfDelegate
|
||||
};
|
||||
|
||||
// The SField used to read or write the balance on this source's SLE.
|
||||
inline SF_AMOUNT const&
|
||||
balanceField(FundingKind kind)
|
||||
{
|
||||
return kind == FundingKind::Sponsorship ? sfFeeAmount : sfBalance;
|
||||
}
|
||||
|
||||
// Resolve fee + reserve funding sources for `tx` against `view`.
|
||||
// Pure function of inputs; safe to call from preclaim or doApply.
|
||||
[[nodiscard]] TxPayers
|
||||
resolveTxPayers(ReadView const& view, STTx const& tx);
|
||||
|
||||
// Read the spendable balance from a source's SLE. Returns beast::kZero when
|
||||
// the SLE is null or the balance field is absent.
|
||||
[[nodiscard]] XRPAmount
|
||||
sourceBalance(SLE::const_ref sle, FundingKind kind);
|
||||
|
||||
// Apply a Sponsorship object's sfMaxFee cap, if present. For AccountRoot
|
||||
// sources this is a no-op and returns `amount` unchanged.
|
||||
[[nodiscard]] XRPAmount
|
||||
capFeeBySource(SLE::const_ref sle, FundingKind kind, XRPAmount amount);
|
||||
|
||||
// Deduct `amount` from `src`'s balance field. Handles the Sponsorship case
|
||||
// where draining sfFeeAmount to zero requires makeFieldAbsent (sfFeeAmount
|
||||
// is soeOptional on ltSPONSORSHIP). Updates the SLE in `view`.
|
||||
[[nodiscard]] TER
|
||||
debitSource(ApplyView& view, FundingSource const& src, XRPAmount amount);
|
||||
|
||||
// Verify the reserve payer has sufficient balance for the proposed owner-
|
||||
// count and reserve-count deltas. When a Sponsorship SLE exists, also caps
|
||||
// against its sfRemainingOwnerCount.
|
||||
[[nodiscard]] TER
|
||||
checkReserve(
|
||||
ApplyView& view,
|
||||
TxPayers const& payers,
|
||||
std::int32_t ownerCountDelta,
|
||||
std::int32_t reserveCountDelta,
|
||||
beast::Journal j);
|
||||
|
||||
// Apply +/- delta to every owner-count field implicated by this tx, and (for
|
||||
// positive deltas on sponsored txs) stamp the reserve sponsor onto the new
|
||||
// ledger entry's sponsor field. Counts updated:
|
||||
// initiator.OwnerCount (always)
|
||||
// initiator.SponsoredOwnerCount (if reserve-sponsored)
|
||||
// reserveSponsor.SponsoringOwnerCount(if reserve-sponsored)
|
||||
// Sponsorship.RemainingOwnerCount (-delta, when SLE exists and delta > 0)
|
||||
void
|
||||
adjustOwnerCount(
|
||||
ApplyView& view,
|
||||
SLE::ref objectSle,
|
||||
TxPayers const& payers,
|
||||
std::int32_t delta,
|
||||
beast::Journal j,
|
||||
SF_ACCOUNT const& sponsorField = sfSponsor);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -72,6 +72,7 @@ canAddHolding(ReadView const& view, MPTIssue const& mptIssue);
|
||||
[[nodiscard]] TER
|
||||
authorizeMPToken(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
XRPAmount const& priorBalance,
|
||||
MPTID const& mptIssuanceID,
|
||||
AccountID const& account,
|
||||
@@ -103,6 +104,7 @@ requireAuth(
|
||||
[[nodiscard]] TER
|
||||
enforceMPTokenAuthorization(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
MPTID const& mptIssuanceID,
|
||||
AccountID const& account,
|
||||
XRPAmount const& priorBalance,
|
||||
@@ -189,6 +191,7 @@ canMPTTradeAndTransfer(
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
MPTIssue const& mptIssue,
|
||||
@@ -197,6 +200,7 @@ addEmptyHolding(
|
||||
[[nodiscard]] TER
|
||||
removeEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& accountID,
|
||||
MPTIssue const& mptIssue,
|
||||
beast::Journal journal);
|
||||
@@ -228,6 +232,7 @@ createMPToken(
|
||||
ApplyView& view,
|
||||
MPTID const& mptIssuanceID,
|
||||
AccountID const& account,
|
||||
SLE::ref sponsorSle,
|
||||
std::uint32_t const flags);
|
||||
|
||||
TER
|
||||
@@ -235,6 +240,7 @@ checkCreateMPT(
|
||||
xrpl::ApplyView& view,
|
||||
xrpl::MPTIssue const& mptIssue,
|
||||
xrpl::AccountID const& holder,
|
||||
SLE::ref sponsorSle,
|
||||
beast::Journal j);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -39,7 +39,7 @@ findTokenAndPage(ApplyView& view, AccountID const& owner, uint256 const& nftoken
|
||||
|
||||
/** Insert the token in the owner's token directory. */
|
||||
TER
|
||||
insertToken(ApplyView& view, AccountID owner, STObject&& nft);
|
||||
insertToken(ApplyView& view, STTx const& tx, AccountID owner, SLE::ref sponsorSle, STObject&& nft);
|
||||
|
||||
/** Remove the token from the owner's token directory. */
|
||||
TER
|
||||
@@ -107,6 +107,7 @@ tokenOfferCreatePreclaim(
|
||||
TER
|
||||
tokenOfferCreateApply(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& acctID,
|
||||
STAmount const& amount,
|
||||
std::optional<AccountID> const& dest,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/ledger/View.h>
|
||||
|
||||
namespace xrpl::permissioned_dex {
|
||||
|
||||
@@ -149,6 +149,7 @@ trustCreate(
|
||||
// Issuer should be the account being set.
|
||||
std::uint32_t uQualityIn,
|
||||
std::uint32_t uQualityOut,
|
||||
SLE::ref sponsorSle,
|
||||
beast::Journal j);
|
||||
|
||||
[[nodiscard]] TER
|
||||
@@ -229,6 +230,7 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
Issue const& issue,
|
||||
|
||||
143
include/xrpl/ledger/helpers/SponsorHelpers.h
Normal file
143
include/xrpl/ledger/helpers/SponsorHelpers.h
Normal file
@@ -0,0 +1,143 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
|
||||
#include <expected>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
inline bool
|
||||
isFeeSponsored(STTx const& tx)
|
||||
{
|
||||
return (tx.getFieldU32(sfSponsorFlags) & spfSponsorFee) != 0u;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isReserveSponsored(STTx const& tx)
|
||||
{
|
||||
return (tx.getFieldU32(sfSponsorFlags) & spfSponsorReserve) != 0u;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isSponsorReserveCoSigning(STTx const& tx)
|
||||
{
|
||||
if (!tx.isFieldPresent(sfSponsorSignature))
|
||||
return false;
|
||||
return isReserveSponsored(tx);
|
||||
}
|
||||
|
||||
inline std::optional<AccountID>
|
||||
getTxReserveSponsorAccountID(STTx const& tx)
|
||||
{
|
||||
if (tx.isFieldPresent(sfSponsor) && isReserveSponsored(tx))
|
||||
{
|
||||
return tx.getAccountID(sfSponsor);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
inline std::expected<SLE::pointer, TER>
|
||||
getTxReserveSponsor(ApplyView& view, STTx const& tx)
|
||||
{
|
||||
auto const sponsorID = getTxReserveSponsorAccountID(tx);
|
||||
if (sponsorID)
|
||||
{
|
||||
auto sle = view.peek(keylet::account(*sponsorID));
|
||||
|
||||
// already checked in Transactor::checkSponsor
|
||||
if (!sle)
|
||||
return std::unexpected(tecINTERNAL);
|
||||
return sle;
|
||||
}
|
||||
return SLE::pointer();
|
||||
}
|
||||
|
||||
inline std::expected<SLE::const_pointer, TER>
|
||||
getTxReserveSponsor(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
auto const sponsorID = getTxReserveSponsorAccountID(tx);
|
||||
if (sponsorID)
|
||||
{
|
||||
auto sle = view.read(keylet::account(*sponsorID));
|
||||
|
||||
// already checked in Transactor::checkSponsor
|
||||
if (!sle)
|
||||
return std::unexpected(tecINTERNAL);
|
||||
return sle;
|
||||
}
|
||||
return SLE::pointer();
|
||||
}
|
||||
|
||||
inline std::optional<AccountID>
|
||||
getLedgerEntryReserveSponsorAccountID(SLE::const_ref sle, SF_ACCOUNT const& field = sfSponsor)
|
||||
{
|
||||
if (sle->isFieldPresent(field))
|
||||
return sle->getAccountID(field);
|
||||
return {};
|
||||
}
|
||||
|
||||
inline SLE::pointer
|
||||
getLedgerEntryReserveSponsor(
|
||||
ApplyView& view,
|
||||
SLE::const_ref sle,
|
||||
SF_ACCOUNT const& field = sfSponsor)
|
||||
{
|
||||
auto const sponsorID = getLedgerEntryReserveSponsorAccountID(sle, field);
|
||||
if (sponsorID)
|
||||
return view.peek(keylet::account(*sponsorID));
|
||||
return {};
|
||||
}
|
||||
|
||||
inline SLE::const_pointer
|
||||
getLedgerEntryReserveSponsor(
|
||||
ReadView const& view,
|
||||
SLE::const_ref sle,
|
||||
SF_ACCOUNT const& field = sfSponsor)
|
||||
{
|
||||
auto const sponsorID = getLedgerEntryReserveSponsorAccountID(sle, field);
|
||||
if (sponsorID)
|
||||
return view.read(keylet::account(*sponsorID));
|
||||
return {};
|
||||
}
|
||||
|
||||
inline void
|
||||
addSponsorToLedgerEntry(
|
||||
SLE::ref sle,
|
||||
SLE::const_ref sponsorSle,
|
||||
SF_ACCOUNT const& field = sfSponsor)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(sle->getType() == ltRIPPLE_STATE && (field == sfHighSponsor || field == sfLowSponsor)) ||
|
||||
(sle->getType() != ltRIPPLE_STATE && field == sfSponsor),
|
||||
"addSponsorToLedgerEntry : Invalid field to the LedgerEntry");
|
||||
if (sponsorSle)
|
||||
sle->setAccountID(field, sponsorSle->getAccountID(sfAccount));
|
||||
}
|
||||
|
||||
inline void
|
||||
removeSponsorFromLedgerEntry(SLE::ref sle, SF_ACCOUNT const& field = sfSponsor)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(sle->getType() == ltRIPPLE_STATE && (field == sfHighSponsor || field == sfLowSponsor)) ||
|
||||
(sle->getType() != ltRIPPLE_STATE && field == sfSponsor),
|
||||
"removeSponsorFromLedgerEntry : Invalid field to the LedgerEntry");
|
||||
if (sle->isFieldPresent(field))
|
||||
sle->makeFieldAbsent(field);
|
||||
}
|
||||
|
||||
// namespace sponsor
|
||||
// {
|
||||
// // Accessing the ledger to check if provided sponsor is valid.
|
||||
// [[nodiscard]] TER
|
||||
// valid(ReadView const& view, STTx const& tx, beast::Journal j)
|
||||
// {
|
||||
// }
|
||||
// }
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -231,6 +231,7 @@ canAddHolding(ReadView const& view, Asset const& asset);
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
Asset const& asset,
|
||||
@@ -239,6 +240,7 @@ addEmptyHolding(
|
||||
[[nodiscard]] TER
|
||||
removeEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& accountID,
|
||||
Asset const& asset,
|
||||
beast::Journal journal);
|
||||
@@ -299,6 +301,7 @@ accountSend(
|
||||
AccountID const& to,
|
||||
STAmount const& saAmount,
|
||||
beast::Journal j,
|
||||
SLE::ref sponsorSle = {},
|
||||
WaiveTransferFee waiveFee = WaiveTransferFee::No,
|
||||
AllowMPTOverflow allowOverflow = AllowMPTOverflow::No);
|
||||
|
||||
@@ -316,6 +319,7 @@ accountSendMulti(
|
||||
Asset const& asset,
|
||||
MultiplePaymentDestinations const& receivers,
|
||||
beast::Journal j,
|
||||
SLE::ref sponsorSle,
|
||||
WaiveTransferFee waiveFee = WaiveTransferFee::No);
|
||||
|
||||
[[nodiscard]] TER
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/STVector256.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
|
||||
@@ -33,17 +33,6 @@ struct Fees
|
||||
: base(base), reserve(reserve), increment(increment)
|
||||
{
|
||||
}
|
||||
|
||||
/** Returns the account reserve given the owner count, in drops.
|
||||
|
||||
The reserve is calculated as the reserve base plus
|
||||
the reserve increment times the number of increments.
|
||||
*/
|
||||
[[nodiscard]] XRPAmount
|
||||
accountReserve(std::size_t ownerCount) const
|
||||
{
|
||||
return reserve + ownerCount * increment;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -151,6 +151,10 @@ static TicketT const kTicket{};
|
||||
Keylet
|
||||
signers(AccountID const& account) noexcept;
|
||||
|
||||
/** A Sponsorship */
|
||||
Keylet
|
||||
sponsorship(AccountID const& sponsor, AccountID const& sponsee) noexcept;
|
||||
|
||||
/** A Check */
|
||||
/** @{ */
|
||||
Keylet
|
||||
|
||||
@@ -118,13 +118,13 @@ public:
|
||||
}
|
||||
|
||||
// begin() and end() are provided for testing purposes.
|
||||
[[nodiscard]] std::forward_list<Item>::const_iterator
|
||||
[[nodiscard]] typename std::forward_list<Item>::const_iterator
|
||||
begin() const
|
||||
{
|
||||
return formats_.begin();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::forward_list<Item>::const_iterator
|
||||
[[nodiscard]] typename std::forward_list<Item>::const_iterator
|
||||
end() const
|
||||
{
|
||||
return formats_.end();
|
||||
|
||||
@@ -180,12 +180,12 @@ enum LedgerEntryType : std::uint16_t {
|
||||
LSF_FLAG(lsfMPTCanClawback, 0x00000040)) \
|
||||
\
|
||||
LEDGER_OBJECT(MPTokenIssuanceMutable, \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanLock, 0x00000002) \
|
||||
LSF_FLAG(lsmfMPTCanEnableRequireAuth, 0x00000004) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanEscrow, 0x00000008) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanTrade, 0x00000010) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanTransfer, 0x00000020) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanClawback, 0x00000040) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanLock, 0x00000002) \
|
||||
LSF_FLAG(lsmfMPTCanMutateRequireAuth, 0x00000004) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanEscrow, 0x00000008) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanTrade, 0x00000010) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanTransfer, 0x00000020) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanClawback, 0x00000040) \
|
||||
LSF_FLAG(lsmfMPTCanMutateMetadata, 0x00010000) \
|
||||
LSF_FLAG(lsmfMPTCanMutateTransferFee, 0x00020000)) \
|
||||
\
|
||||
@@ -203,7 +203,11 @@ enum LedgerEntryType : std::uint16_t {
|
||||
LEDGER_OBJECT(Loan, \
|
||||
LSF_FLAG(lsfLoanDefault, 0x00010000) \
|
||||
LSF_FLAG(lsfLoanImpaired, 0x00020000) \
|
||||
LSF_FLAG(lsfLoanOverpayment, 0x00040000)) /* True, loan allows overpayments */
|
||||
LSF_FLAG(lsfLoanOverpayment, 0x00040000)) /* True, loan allows overpayments */ \
|
||||
\
|
||||
LEDGER_OBJECT(Sponsorship, \
|
||||
LSF_FLAG(lsfSponsorshipRequireSignForFee, 0x00010000) \
|
||||
LSF_FLAG(lsfSponsorshipRequireSignForReserve, 0x00020000))
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -7,13 +7,8 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class STTx;
|
||||
|
||||
/**
|
||||
* We have both transaction type permissions and granular type permissions.
|
||||
* Since we will reuse the TransactionFormats to parse the Transaction
|
||||
@@ -24,15 +19,15 @@ class STTx;
|
||||
// Macro-generated, complex
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
|
||||
enum GranularPermissionType : std::uint32_t {
|
||||
#pragma push_macro("GRANULAR_PERMISSION")
|
||||
#undef GRANULAR_PERMISSION
|
||||
#pragma push_macro("PERMISSION")
|
||||
#undef PERMISSION
|
||||
|
||||
#define GRANULAR_PERMISSION(name, txType, value, ...) name = (value),
|
||||
#define PERMISSION(type, txType, value) type = (value),
|
||||
|
||||
#include <xrpl/protocol/detail/permissions.macro>
|
||||
|
||||
#undef GRANULAR_PERMISSION
|
||||
#pragma pop_macro("GRANULAR_PERMISSION")
|
||||
#undef PERMISSION
|
||||
#pragma pop_macro("PERMISSION")
|
||||
};
|
||||
|
||||
// Injected bare enumerators (xrpl::delegable / xrpl::notDelegable) are required by preprocessor
|
||||
@@ -45,30 +40,15 @@ class Permission
|
||||
private:
|
||||
Permission();
|
||||
|
||||
struct GranularPermissionEntry
|
||||
{
|
||||
std::string name;
|
||||
TxType txType;
|
||||
std::uint32_t permittedFlags;
|
||||
SOTemplate permittedFields;
|
||||
std::unordered_map<std::uint16_t, uint256> txFeatureMap_;
|
||||
|
||||
GranularPermissionEntry(
|
||||
std::string name,
|
||||
TxType txType,
|
||||
std::uint32_t permittedFlags,
|
||||
std::vector<SOElement> fields);
|
||||
};
|
||||
std::unordered_map<std::uint16_t, Delegation> delegableTx_;
|
||||
|
||||
struct TxDelegationEntry
|
||||
{
|
||||
uint256 amendment;
|
||||
Delegation delegable{NotDelegable};
|
||||
};
|
||||
std::unordered_map<std::string, GranularPermissionType> granularPermissionMap_;
|
||||
|
||||
std::unordered_set<TxType> granularTxTypes_;
|
||||
std::unordered_map<TxType, TxDelegationEntry> txDelegationMap_;
|
||||
std::unordered_map<std::string, GranularPermissionType> granularPermissionsByName_;
|
||||
std::unordered_map<GranularPermissionType, GranularPermissionEntry> granularPermissions_;
|
||||
std::unordered_map<GranularPermissionType, std::string> granularNameMap_;
|
||||
|
||||
std::unordered_map<GranularPermissionType, TxType> granularTxTypeMap_;
|
||||
|
||||
public:
|
||||
static Permission const&
|
||||
@@ -79,52 +59,30 @@ public:
|
||||
operator=(Permission const&) = delete;
|
||||
|
||||
[[nodiscard]] std::optional<std::string>
|
||||
getPermissionName(std::uint32_t value) const;
|
||||
getPermissionName(std::uint32_t const value) const;
|
||||
|
||||
[[nodiscard]] std::optional<std::uint32_t>
|
||||
getGranularValue(std::string const& name) const;
|
||||
|
||||
[[nodiscard]] std::optional<std::string>
|
||||
getGranularName(GranularPermissionType value) const;
|
||||
getGranularName(GranularPermissionType const& value) const;
|
||||
|
||||
[[nodiscard]] std::optional<TxType>
|
||||
getGranularTxType(GranularPermissionType gpType) const;
|
||||
getGranularTxType(GranularPermissionType const& gpType) const;
|
||||
|
||||
// Returns a reference to avoid copying uint256 - 32 bytes. std::optional
|
||||
// cannot hold references directly, so std::reference_wrapper is used.
|
||||
[[nodiscard]] std::optional<std::reference_wrapper<uint256 const>>
|
||||
getTxFeature(TxType txType) const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
isDelegable(std::uint32_t permissionValue, Rules const& rules) const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
hasGranularPermissions(TxType txType) const;
|
||||
isDelegable(std::uint32_t const& permissionValue, Rules const& rules) const;
|
||||
|
||||
// for tx level permission, permission value is equal to tx type plus one
|
||||
[[nodiscard]] static uint32_t
|
||||
txToPermissionType(TxType type);
|
||||
static uint32_t
|
||||
txToPermissionType(TxType const& type);
|
||||
|
||||
// tx type value is permission value minus one
|
||||
[[nodiscard]] static TxType
|
||||
permissionToTxType(std::uint32_t value);
|
||||
|
||||
/**
|
||||
* @brief Verifies a delegated transaction against its granular permission template.
|
||||
*
|
||||
* @note WARNING: Do not move this check before standard transaction-level
|
||||
* format checks, which is in preclaim. This function assumes the transaction's
|
||||
* base structural integrity (fees, sequence, signatures) has already been
|
||||
* validated.
|
||||
*
|
||||
* @param tx The transaction to verify.
|
||||
* @param heldPermissions The granular permissions that the sender hold.
|
||||
* @return true if the transaction fields and flags comply with the granular template.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
checkGranularSandbox(
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType> const& heldPermissions) const;
|
||||
static TxType
|
||||
permissionToTxType(uint32_t const& value);
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -163,7 +163,7 @@ STBitString<Bits>::setValue(BaseUInt<Bits, Tag> const& v)
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
STBitString<Bits>::value_type const&
|
||||
typename STBitString<Bits>::value_type const&
|
||||
STBitString<Bits>::value() const
|
||||
{
|
||||
return value_;
|
||||
|
||||
@@ -120,7 +120,7 @@ STInteger<Integer>::operator=(value_type const& v)
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline STInteger<Integer>::value_type
|
||||
inline typename STInteger<Integer>::value_type
|
||||
STInteger<Integer>::value() const noexcept
|
||||
{
|
||||
return value_;
|
||||
|
||||
@@ -243,7 +243,7 @@ public:
|
||||
@throws STObject::FieldErr if the field is not present.
|
||||
*/
|
||||
template <class T>
|
||||
T::value_type
|
||||
typename T::value_type
|
||||
operator[](TypedField<T> const& f) const;
|
||||
|
||||
/** Get the value of a field as a std::optional
|
||||
@@ -290,7 +290,7 @@ public:
|
||||
@throws STObject::FieldErr if the field is not present.
|
||||
*/
|
||||
template <class T>
|
||||
[[nodiscard]] T::value_type
|
||||
[[nodiscard]] typename T::value_type
|
||||
at(TypedField<T> const& f) const;
|
||||
|
||||
/** Get the value of a field as std::optional
|
||||
@@ -478,7 +478,7 @@ template <class T>
|
||||
class STObject::Proxy
|
||||
{
|
||||
public:
|
||||
using value_type = T::value_type;
|
||||
using value_type = typename T::value_type;
|
||||
|
||||
[[nodiscard]] value_type
|
||||
value() const;
|
||||
@@ -513,10 +513,13 @@ protected:
|
||||
template <typename U>
|
||||
concept IsArithmeticNumber =
|
||||
std::is_arithmetic_v<U> || std::is_same_v<U, Number> || std::is_same_v<U, STAmount>;
|
||||
template <typename U, typename Value = U::value_type, typename Unit = U::unit_type>
|
||||
template <
|
||||
typename U,
|
||||
typename Value = typename U::value_type,
|
||||
typename Unit = typename U::unit_type>
|
||||
concept IsArithmeticValueUnit = std::is_same_v<U, unit::ValueUnit<Unit, Value>> &&
|
||||
IsArithmeticNumber<Value> && std::is_class_v<Unit>;
|
||||
template <typename U, typename Value = U::value_type>
|
||||
template <typename U, typename Value = typename U::value_type>
|
||||
concept IsArithmeticST = !IsArithmeticValueUnit<U> && IsArithmeticNumber<Value>;
|
||||
template <typename U>
|
||||
concept IsArithmetic = IsArithmeticNumber<U> || IsArithmeticST<U> || IsArithmeticValueUnit<U>;
|
||||
@@ -531,7 +534,7 @@ template <class T>
|
||||
class STObject::ValueProxy : public Proxy<T>
|
||||
{
|
||||
private:
|
||||
using value_type = T::value_type;
|
||||
using value_type = typename T::value_type;
|
||||
|
||||
public:
|
||||
ValueProxy(ValueProxy const&) = default;
|
||||
@@ -573,7 +576,7 @@ template <class T>
|
||||
class STObject::OptionalProxy : public Proxy<T>
|
||||
{
|
||||
private:
|
||||
using value_type = T::value_type;
|
||||
using value_type = typename T::value_type;
|
||||
|
||||
using optional_type = std::optional<std::decay_t<value_type>>;
|
||||
|
||||
@@ -837,7 +840,7 @@ operator typename STObject::OptionalProxy<T>::optional_type() const
|
||||
}
|
||||
|
||||
template <class T>
|
||||
STObject::OptionalProxy<T>::optional_type
|
||||
typename STObject::OptionalProxy<T>::optional_type
|
||||
STObject::OptionalProxy<T>::operator~() const
|
||||
{
|
||||
return optionalValue();
|
||||
@@ -930,7 +933,7 @@ STObject::OptionalProxy<T>::optionalValue() const -> optional_type
|
||||
}
|
||||
|
||||
template <class T>
|
||||
STObject::OptionalProxy<T>::value_type
|
||||
typename STObject::OptionalProxy<T>::value_type
|
||||
STObject::OptionalProxy<T>::valueOr(value_type val) const
|
||||
{
|
||||
return engaged() ? this->value() : val;
|
||||
@@ -1037,7 +1040,7 @@ STObject::getPIndex(int offset)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T::value_type
|
||||
typename T::value_type
|
||||
STObject::operator[](TypedField<T> const& f) const
|
||||
{
|
||||
return at(f);
|
||||
@@ -1065,7 +1068,7 @@ STObject::operator[](OptionaledField<T> const& of) -> OptionalProxy<T>
|
||||
}
|
||||
|
||||
template <class T>
|
||||
[[nodiscard]] T::value_type
|
||||
[[nodiscard]] typename T::value_type
|
||||
STObject::at(TypedField<T> const& f) const
|
||||
{
|
||||
auto const b = peekAtPField(f);
|
||||
|
||||
@@ -220,6 +220,7 @@ enum TERcodes : TERUnderlyingType {
|
||||
// create a pseudo-account
|
||||
terNO_DELEGATE_PERMISSION, // Delegate does not have permission
|
||||
terLOCKED, // MPT is locked
|
||||
terNO_SPONSORSHIP, // No sponsorship found
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -358,6 +359,7 @@ enum TECcodes : TERUnderlyingType {
|
||||
tecLIMIT_EXCEEDED = 195,
|
||||
tecPSEUDO_ACCOUNT = 196,
|
||||
tecPRECISION_LOSS = 197,
|
||||
tecNO_SPONSOR_PERMISSION = 198,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -657,13 +659,13 @@ inline bool
|
||||
isTesSuccess(TER x) noexcept
|
||||
{
|
||||
// Makes use of TERSubset::operator bool()
|
||||
return !x;
|
||||
return !(x);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTecClaim(TER x) noexcept
|
||||
{
|
||||
return (x >= tecCLAIM);
|
||||
return ((x) >= tecCLAIM);
|
||||
}
|
||||
|
||||
std::unordered_map<TERUnderlyingType, std::pair<char const* const, char const* const>> const&
|
||||
|
||||
@@ -102,7 +102,8 @@ inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
|
||||
TRANSACTION(Payment, \
|
||||
TF_FLAG(tfNoRippleDirect, 0x00010000) \
|
||||
TF_FLAG(tfPartialPayment, 0x00020000) \
|
||||
TF_FLAG(tfLimitQuality, 0x00040000), \
|
||||
TF_FLAG(tfLimitQuality, 0x00040000) \
|
||||
TF_FLAG(tfSponsorCreatedAccount, 0x00080000), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(TrustSet, \
|
||||
@@ -214,6 +215,20 @@ inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
|
||||
TF_FLAG(tfLoanDefault, 0x00010000) \
|
||||
TF_FLAG(tfLoanImpair, 0x00020000) \
|
||||
TF_FLAG(tfLoanUnimpair, 0x00040000), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(SponsorshipSet, \
|
||||
TF_FLAG(tfSponsorshipSetRequireSignForFee, 0x00010000) \
|
||||
TF_FLAG(tfSponsorshipClearRequireSignForFee, 0x00020000) \
|
||||
TF_FLAG(tfSponsorshipSetRequireSignForReserve, 0x00040000) \
|
||||
TF_FLAG(tfSponsorshipClearRequireSignForReserve, 0x00080000) \
|
||||
TF_FLAG(tfDeleteObject, 0x00100000), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(SponsorshipTransfer, \
|
||||
TF_FLAG(tfSponsorshipEnd, 0x00000001) \
|
||||
TF_FLAG(tfSponsorshipCreate, 0x00000002) \
|
||||
TF_FLAG(tfSponsorshipReassign, 0x00000004), \
|
||||
MASK_ADJ(0))
|
||||
|
||||
// clang-format on
|
||||
@@ -338,35 +353,44 @@ getAllTxFlags()
|
||||
inline constexpr FlagValue tfMPTPaymentMask = ~(tfUniversal | tfPartialPayment);
|
||||
inline constexpr FlagValue tfTrustSetPermissionMask =
|
||||
~(tfUniversal | tfSetfAuth | tfSetFreeze | tfClearFreeze);
|
||||
inline constexpr FlagValue tfSponsorshipSetPermissionMask =
|
||||
~(tfUniversal | tfSponsorshipSetRequireSignForFee | tfSponsorshipSetRequireSignForReserve |
|
||||
tfSponsorshipClearRequireSignForFee | tfSponsorshipClearRequireSignForReserve);
|
||||
|
||||
// MPTokenIssuanceCreate MutableFlags:
|
||||
// Indicating specific fields or flags may be changed after issuance.
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanLock = lsmfMPTCanEnableCanLock;
|
||||
inline constexpr FlagValue tmfMPTCanEnableRequireAuth = lsmfMPTCanEnableRequireAuth;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanEscrow = lsmfMPTCanEnableCanEscrow;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanTrade = lsmfMPTCanEnableCanTrade;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanTransfer = lsmfMPTCanEnableCanTransfer;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanClawback = lsmfMPTCanEnableCanClawback;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanLock = lsmfMPTCanMutateCanLock;
|
||||
inline constexpr FlagValue tmfMPTCanMutateRequireAuth = lsmfMPTCanMutateRequireAuth;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanEscrow = lsmfMPTCanMutateCanEscrow;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanTrade = lsmfMPTCanMutateCanTrade;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanTransfer = lsmfMPTCanMutateCanTransfer;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanClawback = lsmfMPTCanMutateCanClawback;
|
||||
inline constexpr FlagValue tmfMPTCanMutateMetadata = lsmfMPTCanMutateMetadata;
|
||||
inline constexpr FlagValue tmfMPTCanMutateTransferFee = lsmfMPTCanMutateTransferFee;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceCreateMutableMask =
|
||||
~(tmfMPTCanEnableCanLock | tmfMPTCanEnableRequireAuth | tmfMPTCanEnableCanEscrow |
|
||||
tmfMPTCanEnableCanTrade | tmfMPTCanEnableCanTransfer | tmfMPTCanEnableCanClawback |
|
||||
~(tmfMPTCanMutateCanLock | tmfMPTCanMutateRequireAuth | tmfMPTCanMutateCanEscrow |
|
||||
tmfMPTCanMutateCanTrade | tmfMPTCanMutateCanTransfer | tmfMPTCanMutateCanClawback |
|
||||
tmfMPTCanMutateMetadata | tmfMPTCanMutateTransferFee);
|
||||
|
||||
// MPTokenIssuanceSet MutableFlags:
|
||||
// Enable mutable capability flags. These flags are one-way: once enabled,
|
||||
// the corresponding capability cannot be disabled by MPTokenIssuanceSet.
|
||||
// Set or Clear flags.
|
||||
|
||||
inline constexpr FlagValue tmfMPTSetCanLock = 0x00000001;
|
||||
inline constexpr FlagValue tmfMPTSetRequireAuth = 0x00000002;
|
||||
inline constexpr FlagValue tmfMPTSetCanEscrow = 0x00000004;
|
||||
inline constexpr FlagValue tmfMPTSetCanTrade = 0x00000008;
|
||||
inline constexpr FlagValue tmfMPTSetCanTransfer = 0x00000010;
|
||||
inline constexpr FlagValue tmfMPTSetCanClawback = 0x00000020;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceSetMutableMask =
|
||||
~(tmfMPTSetCanLock | tmfMPTSetRequireAuth | tmfMPTSetCanEscrow | tmfMPTSetCanTrade |
|
||||
tmfMPTSetCanTransfer | tmfMPTSetCanClawback);
|
||||
inline constexpr FlagValue tmfMPTClearCanLock = 0x00000002;
|
||||
inline constexpr FlagValue tmfMPTSetRequireAuth = 0x00000004;
|
||||
inline constexpr FlagValue tmfMPTClearRequireAuth = 0x00000008;
|
||||
inline constexpr FlagValue tmfMPTSetCanEscrow = 0x00000010;
|
||||
inline constexpr FlagValue tmfMPTClearCanEscrow = 0x00000020;
|
||||
inline constexpr FlagValue tmfMPTSetCanTrade = 0x00000040;
|
||||
inline constexpr FlagValue tmfMPTClearCanTrade = 0x00000080;
|
||||
inline constexpr FlagValue tmfMPTSetCanTransfer = 0x00000100;
|
||||
inline constexpr FlagValue tmfMPTClearCanTransfer = 0x00000200;
|
||||
inline constexpr FlagValue tmfMPTSetCanClawback = 0x00000400;
|
||||
inline constexpr FlagValue tmfMPTClearCanClawback = 0x00000800;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceSetMutableMask = ~(
|
||||
tmfMPTSetCanLock | tmfMPTClearCanLock | tmfMPTSetRequireAuth | tmfMPTClearRequireAuth |
|
||||
tmfMPTSetCanEscrow | tmfMPTClearCanEscrow | tmfMPTSetCanTrade | tmfMPTClearCanTrade |
|
||||
tmfMPTSetCanTransfer | tmfMPTClearCanTransfer | tmfMPTSetCanClawback | tmfMPTClearCanClawback);
|
||||
|
||||
// Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between accounts allowed a
|
||||
// TrustLine to be added to the issuer of that token without explicit permission from that issuer.
|
||||
@@ -439,6 +463,11 @@ getAsfFlagMap()
|
||||
#pragma pop_macro("ACCOUNTSET_FLAG_TO_MAP")
|
||||
#pragma pop_macro("ACCOUNTSET_FLAGS")
|
||||
|
||||
// Sponsor flags (spf)
|
||||
|
||||
inline constexpr FlagValue spfSponsorFee = 1;
|
||||
inline constexpr FlagValue spfSponsorReserve = 2;
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
// NOLINTEND(readability-identifier-naming)
|
||||
|
||||
@@ -391,7 +391,7 @@ mulDivU(Source1 value, Dest mul, Source2 div)
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
using desttype = Dest::value_type;
|
||||
using desttype = typename Dest::value_type;
|
||||
constexpr auto kMax = std::numeric_limits<desttype>::max();
|
||||
|
||||
// Shortcuts, since these happen a lot in the real world
|
||||
|
||||
@@ -379,16 +379,16 @@ public:
|
||||
[[nodiscard]] STArray
|
||||
toSTArray() const;
|
||||
|
||||
[[nodiscard]] AttCollection::const_iterator
|
||||
[[nodiscard]] typename AttCollection::const_iterator
|
||||
begin() const;
|
||||
|
||||
[[nodiscard]] AttCollection::const_iterator
|
||||
[[nodiscard]] typename AttCollection::const_iterator
|
||||
end() const;
|
||||
|
||||
AttCollection::iterator
|
||||
typename AttCollection::iterator
|
||||
begin();
|
||||
|
||||
AttCollection::iterator
|
||||
typename AttCollection::iterator
|
||||
end();
|
||||
|
||||
template <class F>
|
||||
@@ -419,7 +419,7 @@ operator==(
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
inline XChainAttestationsBase<TAttestation>::AttCollection const&
|
||||
inline typename XChainAttestationsBase<TAttestation>::AttCollection const&
|
||||
XChainAttestationsBase<TAttestation>::attestations() const
|
||||
{
|
||||
return attestations_;
|
||||
|
||||
@@ -15,16 +15,17 @@
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
|
||||
XRPL_FEATURE(Sponsor, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Cleanup3_3_0, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Cleanup3_2_0, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(MPTokensV2, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Cleanup3_1_3, Supported::Yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (BatchInnerSigs, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(LendingProtocol, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionDelegationV1_1, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionDelegationV1_1, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (DirectoryLimit, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (IncludeKeyletFields, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DynamicMPT, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DynamicMPT, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (TokenEscrowV1, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PriceOracleOrder, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (MPTDeliveredAmount, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -127,29 +127,32 @@ LEDGER_ENTRY(ltTICKET, 0x0054, Ticket, ticket, ({
|
||||
\sa keylet::account
|
||||
*/
|
||||
LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
|
||||
{sfAccount, SoeRequired},
|
||||
{sfSequence, SoeRequired},
|
||||
{sfBalance, SoeRequired},
|
||||
{sfOwnerCount, SoeRequired},
|
||||
{sfPreviousTxnID, SoeRequired},
|
||||
{sfPreviousTxnLgrSeq, SoeRequired},
|
||||
{sfAccountTxnID, SoeOptional},
|
||||
{sfRegularKey, SoeOptional},
|
||||
{sfEmailHash, SoeOptional},
|
||||
{sfWalletLocator, SoeOptional},
|
||||
{sfWalletSize, SoeOptional},
|
||||
{sfMessageKey, SoeOptional},
|
||||
{sfTransferRate, SoeOptional},
|
||||
{sfDomain, SoeOptional},
|
||||
{sfTickSize, SoeOptional},
|
||||
{sfTicketCount, SoeOptional},
|
||||
{sfNFTokenMinter, SoeOptional},
|
||||
{sfMintedNFTokens, SoeDefault},
|
||||
{sfBurnedNFTokens, SoeDefault},
|
||||
{sfFirstNFTokenSequence, SoeOptional},
|
||||
{sfAMMID, SoeOptional}, // pseudo-account designator
|
||||
{sfVaultID, SoeOptional}, // pseudo-account designator
|
||||
{sfLoanBrokerID, SoeOptional}, // pseudo-account designator
|
||||
{sfAccount, SoeRequired},
|
||||
{sfSequence, SoeRequired},
|
||||
{sfBalance, SoeRequired},
|
||||
{sfOwnerCount, SoeRequired},
|
||||
{sfPreviousTxnID, SoeRequired},
|
||||
{sfPreviousTxnLgrSeq, SoeRequired},
|
||||
{sfAccountTxnID, SoeOptional},
|
||||
{sfRegularKey, SoeOptional},
|
||||
{sfEmailHash, SoeOptional},
|
||||
{sfWalletLocator, SoeOptional},
|
||||
{sfWalletSize, SoeOptional},
|
||||
{sfMessageKey, SoeOptional},
|
||||
{sfTransferRate, SoeOptional},
|
||||
{sfDomain, SoeOptional},
|
||||
{sfTickSize, SoeOptional},
|
||||
{sfTicketCount, SoeOptional},
|
||||
{sfNFTokenMinter, SoeOptional},
|
||||
{sfMintedNFTokens, SoeDefault},
|
||||
{sfBurnedNFTokens, SoeDefault},
|
||||
{sfFirstNFTokenSequence, SoeOptional},
|
||||
{sfSponsoredOwnerCount, SoeDefault},
|
||||
{sfSponsoringOwnerCount, SoeDefault},
|
||||
{sfSponsoringAccountCount, SoeDefault},
|
||||
{sfAMMID, SoeOptional}, // pseudo-account designator
|
||||
{sfVaultID, SoeOptional}, // pseudo-account designator
|
||||
{sfLoanBrokerID, SoeOptional}, // pseudo-account designator
|
||||
}))
|
||||
|
||||
/** A ledger object which contains a list of object identifiers.
|
||||
@@ -286,6 +289,8 @@ LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, state, ({
|
||||
{sfHighNode, SoeOptional},
|
||||
{sfHighQualityIn, SoeOptional},
|
||||
{sfHighQualityOut, SoeOptional},
|
||||
{sfHighSponsor, SoeOptional},
|
||||
{sfLowSponsor, SoeOptional},
|
||||
}))
|
||||
|
||||
/** The ledger object which lists the network's fee settings.
|
||||
@@ -607,5 +612,20 @@ LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
|
||||
{sfLoanScale, SoeDefault},
|
||||
}))
|
||||
|
||||
/** A ledger object representing a sponsorship.
|
||||
\sa keylet::sponsorship
|
||||
*/
|
||||
LEDGER_ENTRY(ltSPONSORSHIP, 0x0090, Sponsorship, sponsorship, ({
|
||||
{sfPreviousTxnID, SoeRequired},
|
||||
{sfPreviousTxnLgrSeq, SoeRequired},
|
||||
{sfOwner, SoeRequired},
|
||||
{sfSponsee, SoeRequired},
|
||||
{sfFeeAmount, SoeOptional},
|
||||
{sfMaxFee, SoeOptional},
|
||||
{sfRemainingOwnerCount, SoeDefault},
|
||||
{sfOwnerNode, SoeRequired},
|
||||
{sfSponseeNode, SoeRequired},
|
||||
}))
|
||||
|
||||
#undef EXPAND
|
||||
#undef LEDGER_ENTRY_DUPLICATE
|
||||
|
||||
@@ -1,74 +1,55 @@
|
||||
#if !defined(GRANULAR_PERMISSION)
|
||||
#error "undefined macro: GRANULAR_PERMISSION"
|
||||
#if !defined(PERMISSION)
|
||||
#error "undefined macro: PERMISSION"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* GRANULAR_PERMISSION(name, txType, value, allowedFlags, allowedFields)
|
||||
* PERMISSION(name, type, txType, value)
|
||||
*
|
||||
* Defines a granular permission:
|
||||
* name: the granular permission name.
|
||||
* txType: the corresponding TxType for this permission.
|
||||
* value: the uint32 numeric value for the enum type.
|
||||
* allowedFlags: transaction flags permitted under this permission.
|
||||
* allowedFields: transaction fields permitted under this permission.
|
||||
* This macro defines a permission:
|
||||
* name: the name of the permission.
|
||||
* type: the GranularPermissionType enum.
|
||||
* txType: the corresponding TxType for this permission.
|
||||
* value: the uint32 numeric value for the enum type.
|
||||
*/
|
||||
|
||||
/** Grants the ability to authorize a trustline. */
|
||||
GRANULAR_PERMISSION(TrustlineAuthorize, ttTRUST_SET, 65537, tfUniversal | tfSetfAuth,
|
||||
({{sfLimitAmount, SoeRequired}}))
|
||||
/** This permission grants the delegated account the ability to authorize a trustline. */
|
||||
PERMISSION(TrustlineAuthorize, ttTRUST_SET, 65537)
|
||||
|
||||
/** Grants the ability to freeze a trustline. */
|
||||
GRANULAR_PERMISSION(TrustlineFreeze, ttTRUST_SET, 65538, tfUniversal | tfSetFreeze,
|
||||
({{sfLimitAmount, SoeRequired}}))
|
||||
/** This permission grants the delegated account the ability to freeze a trustline. */
|
||||
PERMISSION(TrustlineFreeze, ttTRUST_SET, 65538)
|
||||
|
||||
/** Grants the ability to unfreeze a trustline. */
|
||||
GRANULAR_PERMISSION(TrustlineUnfreeze, ttTRUST_SET, 65539, tfUniversal | tfClearFreeze,
|
||||
({{sfLimitAmount, SoeRequired}}))
|
||||
/** This permission grants the delegated account the ability to unfreeze a trustline. */
|
||||
PERMISSION(TrustlineUnfreeze, ttTRUST_SET, 65539)
|
||||
|
||||
/** Grants the ability to set Domain. */
|
||||
GRANULAR_PERMISSION(AccountDomainSet, ttACCOUNT_SET, 65540, tfUniversal,
|
||||
({{sfDomain, SoeOptional}}))
|
||||
/** This permission grants the delegated account the ability to set Domain. */
|
||||
PERMISSION(AccountDomainSet, ttACCOUNT_SET, 65540)
|
||||
|
||||
/** Grants the ability to set EmailHash. */
|
||||
GRANULAR_PERMISSION(AccountEmailHashSet, ttACCOUNT_SET, 65541, tfUniversal,
|
||||
({{sfEmailHash, SoeOptional}}))
|
||||
/** This permission grants the delegated account the ability to set EmailHashSet. */
|
||||
PERMISSION(AccountEmailHashSet, ttACCOUNT_SET, 65541)
|
||||
|
||||
/** Grants the ability to set MessageKey. */
|
||||
GRANULAR_PERMISSION(AccountMessageKeySet, ttACCOUNT_SET, 65542, tfUniversal,
|
||||
({{sfMessageKey, SoeOptional}}))
|
||||
/** This permission grants the delegated account the ability to set MessageKey. */
|
||||
PERMISSION(AccountMessageKeySet, ttACCOUNT_SET, 65542)
|
||||
|
||||
/** Grants the ability to set TransferRate. */
|
||||
GRANULAR_PERMISSION(AccountTransferRateSet, ttACCOUNT_SET, 65543, tfUniversal,
|
||||
({{sfTransferRate, SoeOptional}}))
|
||||
/** This permission grants the delegated account the ability to set TransferRate. */
|
||||
PERMISSION(AccountTransferRateSet, ttACCOUNT_SET, 65543)
|
||||
|
||||
/** Grants the ability to set TickSize. */
|
||||
GRANULAR_PERMISSION(AccountTickSizeSet, ttACCOUNT_SET, 65544, tfUniversal,
|
||||
({{sfTickSize, SoeOptional}}))
|
||||
/** This permission grants the delegated account the ability to set TickSize. */
|
||||
PERMISSION(AccountTickSizeSet, ttACCOUNT_SET, 65544)
|
||||
|
||||
/** Grants the ability to mint payment (sending account is the issuer). Cross-currency payments are disallowed. */
|
||||
GRANULAR_PERMISSION(PaymentMint, ttPAYMENT, 65545, tfUniversal,
|
||||
({{sfDestination, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfSendMax, SoeOptional},
|
||||
{sfInvoiceID, SoeOptional},
|
||||
{sfDestinationTag, SoeOptional},
|
||||
{sfCredentialIDs, SoeOptional}}))
|
||||
/** This permission grants the delegated account the ability to mint payment, which means sending a payment for a currency where the sending account is the issuer. */
|
||||
PERMISSION(PaymentMint, ttPAYMENT, 65545)
|
||||
|
||||
/** Grants the ability to burn payment (destination account is the issuer). Cross-currency payments are disallowed. */
|
||||
GRANULAR_PERMISSION(PaymentBurn, ttPAYMENT, 65546, tfUniversal,
|
||||
({{sfDestination, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfSendMax, SoeOptional},
|
||||
{sfInvoiceID, SoeOptional},
|
||||
{sfDestinationTag, SoeOptional},
|
||||
{sfCredentialIDs, SoeOptional}}))
|
||||
/** This permission grants the delegated account the ability to burn payment, which means sending a payment for a currency where the destination account is the issuer */
|
||||
PERMISSION(PaymentBurn, ttPAYMENT, 65546)
|
||||
|
||||
/** Grants the ability to lock an MPToken. */
|
||||
GRANULAR_PERMISSION(MPTokenIssuanceLock, ttMPTOKEN_ISSUANCE_SET, 65547, tfUniversal | tfMPTLock,
|
||||
({{sfMPTokenIssuanceID, SoeRequired},
|
||||
{sfHolder, SoeOptional}}))
|
||||
/** This permission grants the delegated account the ability to lock MPToken. */
|
||||
PERMISSION(MPTokenIssuanceLock, ttMPTOKEN_ISSUANCE_SET, 65547)
|
||||
|
||||
/** Grants the ability to unlock an MPToken. */
|
||||
GRANULAR_PERMISSION(MPTokenIssuanceUnlock, ttMPTOKEN_ISSUANCE_SET, 65548, tfUniversal | tfMPTUnlock,
|
||||
({{sfMPTokenIssuanceID, SoeRequired},
|
||||
{sfHolder, SoeOptional}}))
|
||||
/** This permission grants the delegated account the ability to unlock MPToken. */
|
||||
PERMISSION(MPTokenIssuanceUnlock, ttMPTOKEN_ISSUANCE_SET, 65548)
|
||||
|
||||
/** This permission grants the delegated account the ability to set SponsorFee. */
|
||||
PERMISSION(SponsorFee, ttSPONSORSHIP_SET, 65549)
|
||||
|
||||
/** This permission grants the delegated account the ability to set SponsorReserve. */
|
||||
PERMISSION(SponsorReserve, ttSPONSORSHIP_SET, 65550)
|
||||
|
||||
@@ -113,6 +113,11 @@ TYPED_SFIELD(sfInterestRate, UINT32, 65) // 1/10 basis points (bi
|
||||
TYPED_SFIELD(sfLateInterestRate, UINT32, 66) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfCloseInterestRate, UINT32, 67) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfOverpaymentInterestRate, UINT32, 68) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfSponsoredOwnerCount, UINT32, 69)
|
||||
TYPED_SFIELD(sfSponsoringOwnerCount, UINT32, 70)
|
||||
TYPED_SFIELD(sfSponsoringAccountCount, UINT32, 71)
|
||||
TYPED_SFIELD(sfRemainingOwnerCount, UINT32, 72)
|
||||
TYPED_SFIELD(sfSponsorFlags, UINT32, 73)
|
||||
|
||||
// 64-bit integers (common)
|
||||
TYPED_SFIELD(sfIndexNext, UINT64, 1)
|
||||
@@ -146,6 +151,7 @@ TYPED_SFIELD(sfSubjectNode, UINT64, 28)
|
||||
TYPED_SFIELD(sfLockedAmount, UINT64, 29, SField::kSmdBaseTen|SField::kSmdDefault)
|
||||
TYPED_SFIELD(sfVaultNode, UINT64, 30)
|
||||
TYPED_SFIELD(sfLoanBrokerNode, UINT64, 31)
|
||||
TYPED_SFIELD(sfSponseeNode, UINT64, 32)
|
||||
|
||||
// 128-bit
|
||||
TYPED_SFIELD(sfEmailHash, UINT128, 1)
|
||||
@@ -206,6 +212,7 @@ TYPED_SFIELD(sfLoanBrokerID, UINT256, 37,
|
||||
SField::kSmdPseudoAccount | SField::kSmdDefault)
|
||||
TYPED_SFIELD(sfLoanID, UINT256, 38)
|
||||
TYPED_SFIELD(sfReferenceHolding, UINT256, 39)
|
||||
TYPED_SFIELD(sfObjectID, UINT256, 40)
|
||||
|
||||
// number (common)
|
||||
TYPED_SFIELD(sfNumber, NUMBER, 1)
|
||||
@@ -265,6 +272,8 @@ TYPED_SFIELD(sfPrice, AMOUNT, 28)
|
||||
TYPED_SFIELD(sfSignatureReward, AMOUNT, 29)
|
||||
TYPED_SFIELD(sfMinAccountCreateAmount, AMOUNT, 30)
|
||||
TYPED_SFIELD(sfLPTokenBalance, AMOUNT, 31)
|
||||
TYPED_SFIELD(sfFeeAmount, AMOUNT, 32)
|
||||
TYPED_SFIELD(sfMaxFee, AMOUNT, 33)
|
||||
|
||||
// variable length (common)
|
||||
TYPED_SFIELD(sfPublicKey, VL, 1)
|
||||
@@ -325,6 +334,11 @@ TYPED_SFIELD(sfIssuingChainDoor, ACCOUNT, 23)
|
||||
TYPED_SFIELD(sfSubject, ACCOUNT, 24)
|
||||
TYPED_SFIELD(sfBorrower, ACCOUNT, 25)
|
||||
TYPED_SFIELD(sfCounterparty, ACCOUNT, 26)
|
||||
TYPED_SFIELD(sfSponsor, ACCOUNT, 27)
|
||||
TYPED_SFIELD(sfHighSponsor, ACCOUNT, 28)
|
||||
TYPED_SFIELD(sfLowSponsor, ACCOUNT, 29)
|
||||
TYPED_SFIELD(sfCounterpartySponsor, ACCOUNT, 30)
|
||||
TYPED_SFIELD(sfSponsee, ACCOUNT, 31)
|
||||
|
||||
// vector of 256-bit
|
||||
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::kSmdNever)
|
||||
@@ -389,6 +403,7 @@ UNTYPED_SFIELD(sfRawTransaction, OBJECT, 34)
|
||||
UNTYPED_SFIELD(sfBatchSigner, OBJECT, 35)
|
||||
UNTYPED_SFIELD(sfBook, OBJECT, 36)
|
||||
UNTYPED_SFIELD(sfCounterpartySignature, OBJECT, 37, SField::kSmdDefault, SField::kNotSigning)
|
||||
UNTYPED_SFIELD(sfSponsorSignature, OBJECT, 38, SField::kSmdDefault, SField::kNotSigning)
|
||||
|
||||
// array of objects (common)
|
||||
// ARRAY/1 is reserved for end of array
|
||||
|
||||
@@ -1077,6 +1077,35 @@ TRANSACTION(ttLOAN_PAY, 84, LoanPay,
|
||||
{sfAmount, SoeRequired, SoeMptSupported},
|
||||
}))
|
||||
|
||||
/** This transaction transfer sponsorship */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/sponsor/SponsorshipTransfer.h>
|
||||
#endif
|
||||
TRANSACTION(ttSPONSORSHIP_TRANSFER, 85, SponsorshipTransfer,
|
||||
Delegation::Delegable,
|
||||
featureSponsor,
|
||||
MayModifyVault,
|
||||
({
|
||||
{sfObjectID, SoeOptional},
|
||||
{sfSponsee, SoeOptional},
|
||||
}))
|
||||
|
||||
/** This transaction create sponsorship object */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/sponsor/SponsorshipSet.h>
|
||||
#endif
|
||||
TRANSACTION(ttSPONSORSHIP_SET, 86, SponsorshipSet,
|
||||
Delegation::Delegable,
|
||||
featureSponsor,
|
||||
NoPriv,
|
||||
({
|
||||
{sfCounterpartySponsor, SoeOptional},
|
||||
{sfSponsee, SoeOptional},
|
||||
{sfFeeAmount, SoeOptional},
|
||||
{sfMaxFee, SoeOptional},
|
||||
{sfRemainingOwnerCount, SoeOptional},
|
||||
}))
|
||||
|
||||
/** This system-generated transaction type is used to update the status of the various amendments.
|
||||
|
||||
For details, see: https://xrpl.org/amendments.html
|
||||
|
||||
@@ -206,7 +206,7 @@ sha512Half(Args const&... args)
|
||||
sha512_half_hasher h;
|
||||
using beast::hash_append;
|
||||
hash_append(h, args...);
|
||||
return static_cast<sha512_half_hasher::result_type>(h);
|
||||
return static_cast<typename sha512_half_hasher::result_type>(h);
|
||||
}
|
||||
|
||||
/** Returns the SHA512-Half of a series of objects.
|
||||
@@ -222,7 +222,7 @@ sha512HalfS(Args const&... args)
|
||||
sha512_half_hasher_s h;
|
||||
using beast::hash_append;
|
||||
hash_append(h, args...);
|
||||
return static_cast<sha512_half_hasher_s::result_type>(h);
|
||||
return static_cast<typename sha512_half_hasher_s::result_type>(h);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -552,6 +552,9 @@ JSS(source_account); // in: PathRequest, RipplePathFind
|
||||
JSS(source_amount); // in: PathRequest, RipplePathFind
|
||||
JSS(source_currencies); // in: PathRequest, RipplePathFind
|
||||
JSS(source_tag); // out: AccountChannels
|
||||
JSS(sponsee); // in: LedgerEntry
|
||||
JSS(sponsor); // in: LedgerEntry
|
||||
JSS(sponsored); // in: AccountObjects
|
||||
JSS(stand_alone); // out: NetworkOPs
|
||||
JSS(standard_deviation); // out: get_aggregate_price
|
||||
JSS(start); // in: TxHistory
|
||||
|
||||
@@ -447,6 +447,78 @@ public:
|
||||
return this->sle_->isFieldPresent(sfFirstNFTokenSequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsoredOwnerCount (SoeDefault)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getSponsoredOwnerCount() const
|
||||
{
|
||||
if (hasSponsoredOwnerCount())
|
||||
return this->sle_->at(sfSponsoredOwnerCount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSponsoredOwnerCount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSponsoredOwnerCount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfSponsoredOwnerCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsoringOwnerCount (SoeDefault)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getSponsoringOwnerCount() const
|
||||
{
|
||||
if (hasSponsoringOwnerCount())
|
||||
return this->sle_->at(sfSponsoringOwnerCount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSponsoringOwnerCount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSponsoringOwnerCount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfSponsoringOwnerCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsoringAccountCount (SoeDefault)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getSponsoringAccountCount() const
|
||||
{
|
||||
if (hasSponsoringAccountCount())
|
||||
return this->sle_->at(sfSponsoringAccountCount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSponsoringAccountCount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSponsoringAccountCount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfSponsoringAccountCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAMMID (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
@@ -786,6 +858,39 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsoredOwnerCount (SoeDefault)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
AccountRootBuilder&
|
||||
setSponsoredOwnerCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsoredOwnerCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsoringOwnerCount (SoeDefault)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
AccountRootBuilder&
|
||||
setSponsoringOwnerCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsoringOwnerCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsoringAccountCount (SoeDefault)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
AccountRootBuilder&
|
||||
setSponsoringAccountCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsoringAccountCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAMMID (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
|
||||
@@ -243,6 +243,54 @@ public:
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfHighQualityOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfHighSponsor (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getHighSponsor() const
|
||||
{
|
||||
if (hasHighSponsor())
|
||||
return this->sle_->at(sfHighSponsor);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfHighSponsor is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasHighSponsor() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfHighSponsor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfLowSponsor (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getLowSponsor() const
|
||||
{
|
||||
if (hasLowSponsor())
|
||||
return this->sle_->at(sfLowSponsor);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfLowSponsor is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasLowSponsor() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfLowSponsor);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -410,6 +458,28 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfHighSponsor (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
RippleStateBuilder&
|
||||
setHighSponsor(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfHighSponsor] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfLowSponsor (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
RippleStateBuilder&
|
||||
setLowSponsor(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfLowSponsor] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed RippleState wrapper.
|
||||
* @param index The ledger entry index.
|
||||
|
||||
344
include/xrpl/protocol_autogen/ledger_entries/Sponsorship.h
Normal file
344
include/xrpl/protocol_autogen/ledger_entries/Sponsorship.h
Normal file
@@ -0,0 +1,344 @@
|
||||
// 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 SponsorshipBuilder;
|
||||
|
||||
/**
|
||||
* @brief Ledger Entry: Sponsorship
|
||||
*
|
||||
* Type: ltSPONSORSHIP (0x0090)
|
||||
* RPC Name: sponsorship
|
||||
*
|
||||
* Immutable wrapper around SLE providing type-safe field access.
|
||||
* Use SponsorshipBuilder to construct new ledger entries.
|
||||
*/
|
||||
class Sponsorship : public LedgerEntryBase
|
||||
{
|
||||
public:
|
||||
static constexpr LedgerEntryType entryType = ltSPONSORSHIP;
|
||||
|
||||
/**
|
||||
* @brief Construct a Sponsorship ledger entry wrapper from an existing SLE object.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
explicit Sponsorship(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 Sponsorship");
|
||||
}
|
||||
}
|
||||
|
||||
// Ledger entry-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnID (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT256::type::value_type
|
||||
getPreviousTxnID() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnLgrSeq (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT32::type::value_type
|
||||
getPreviousTxnLgrSeq() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnLgrSeq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwner (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getOwner() const
|
||||
{
|
||||
return this->sle_->at(sfOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsee (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getSponsee() const
|
||||
{
|
||||
return this->sle_->at(sfSponsee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfFeeAmount (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getFeeAmount() const
|
||||
{
|
||||
if (hasFeeAmount())
|
||||
return this->sle_->at(sfFeeAmount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfFeeAmount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasFeeAmount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfFeeAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfMaxFee (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getMaxFee() const
|
||||
{
|
||||
if (hasMaxFee())
|
||||
return this->sle_->at(sfMaxFee);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfMaxFee is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasMaxFee() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfMaxFee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfRemainingOwnerCount (SoeDefault)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getRemainingOwnerCount() const
|
||||
{
|
||||
if (hasRemainingOwnerCount())
|
||||
return this->sle_->at(sfRemainingOwnerCount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfRemainingOwnerCount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasRemainingOwnerCount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfRemainingOwnerCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwnerNode (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getOwnerNode() const
|
||||
{
|
||||
return this->sle_->at(sfOwnerNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponseeNode (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getSponseeNode() const
|
||||
{
|
||||
return this->sle_->at(sfSponseeNode);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for Sponsorship 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 SponsorshipBuilder : public LedgerEntryBuilderBase<SponsorshipBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new SponsorshipBuilder with required fields.
|
||||
* @param previousTxnID The sfPreviousTxnID field value.
|
||||
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
|
||||
* @param owner The sfOwner field value.
|
||||
* @param sponsee The sfSponsee field value.
|
||||
* @param ownerNode The sfOwnerNode field value.
|
||||
* @param sponseeNode The sfSponseeNode field value.
|
||||
*/
|
||||
SponsorshipBuilder(std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq,std::decay_t<typename SF_ACCOUNT::type::value_type> const& owner,std::decay_t<typename SF_ACCOUNT::type::value_type> const& sponsee,std::decay_t<typename SF_UINT64::type::value_type> const& ownerNode,std::decay_t<typename SF_UINT64::type::value_type> const& sponseeNode)
|
||||
: LedgerEntryBuilderBase<SponsorshipBuilder>(ltSPONSORSHIP)
|
||||
{
|
||||
setPreviousTxnID(previousTxnID);
|
||||
setPreviousTxnLgrSeq(previousTxnLgrSeq);
|
||||
setOwner(owner);
|
||||
setSponsee(sponsee);
|
||||
setOwnerNode(ownerNode);
|
||||
setSponseeNode(sponseeNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a SponsorshipBuilder 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.
|
||||
*/
|
||||
SponsorshipBuilder(SLE::const_pointer sle)
|
||||
{
|
||||
if (sle->at(sfLedgerEntryType) != ltSPONSORSHIP)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for Sponsorship");
|
||||
}
|
||||
object_ = *sle;
|
||||
}
|
||||
|
||||
/** @brief Ledger entry-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnID (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
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.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnLgrSeq] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwner (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setOwner(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwner] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsee (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setSponsee(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsee] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFeeAmount (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setFeeAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfFeeAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfMaxFee (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setMaxFee(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfMaxFee] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfRemainingOwnerCount (SoeDefault)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setRemainingOwnerCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfRemainingOwnerCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwnerNode (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setOwnerNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwnerNode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponseeNode (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setSponseeNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponseeNode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed Sponsorship wrapper.
|
||||
* @param index The ledger entry index.
|
||||
* @return The constructed ledger entry wrapper.
|
||||
*/
|
||||
Sponsorship
|
||||
build(uint256 const& index)
|
||||
{
|
||||
return Sponsorship{std::make_shared<SLE>(std::move(object_), index)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::ledger_entries
|
||||
290
include/xrpl/protocol_autogen/transactions/SponsorshipSet.h
Normal file
290
include/xrpl/protocol_autogen/transactions/SponsorshipSet.h
Normal file
@@ -0,0 +1,290 @@
|
||||
// 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 SponsorshipSetBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: SponsorshipSet
|
||||
*
|
||||
* Type: ttSPONSORSHIP_SET (86)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureSponsor
|
||||
* Privileges: NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use SponsorshipSetBuilder to construct new transactions.
|
||||
*/
|
||||
class SponsorshipSet : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttSPONSORSHIP_SET;
|
||||
|
||||
/**
|
||||
* @brief Construct a SponsorshipSet transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit SponsorshipSet(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 SponsorshipSet");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfCounterpartySponsor (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getCounterpartySponsor() const
|
||||
{
|
||||
if (hasCounterpartySponsor())
|
||||
{
|
||||
return this->tx_->at(sfCounterpartySponsor);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfCounterpartySponsor is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasCounterpartySponsor() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfCounterpartySponsor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsee (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getSponsee() const
|
||||
{
|
||||
if (hasSponsee())
|
||||
{
|
||||
return this->tx_->at(sfSponsee);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSponsee is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSponsee() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfSponsee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfFeeAmount (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getFeeAmount() const
|
||||
{
|
||||
if (hasFeeAmount())
|
||||
{
|
||||
return this->tx_->at(sfFeeAmount);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfFeeAmount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasFeeAmount() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfFeeAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfMaxFee (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getMaxFee() const
|
||||
{
|
||||
if (hasMaxFee())
|
||||
{
|
||||
return this->tx_->at(sfMaxFee);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfMaxFee is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasMaxFee() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfMaxFee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfRemainingOwnerCount (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getRemainingOwnerCount() const
|
||||
{
|
||||
if (hasRemainingOwnerCount())
|
||||
{
|
||||
return this->tx_->at(sfRemainingOwnerCount);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfRemainingOwnerCount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasRemainingOwnerCount() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfRemainingOwnerCount);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for SponsorshipSet 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 SponsorshipSetBuilder : public TransactionBuilderBase<SponsorshipSetBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new SponsorshipSetBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
SponsorshipSetBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<SponsorshipSetBuilder>(ttSPONSORSHIP_SET, account, sequence, fee)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a SponsorshipSetBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
SponsorshipSetBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttSPONSORSHIP_SET)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for SponsorshipSetBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/** @brief Transaction-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfCounterpartySponsor (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipSetBuilder&
|
||||
setCounterpartySponsor(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfCounterpartySponsor] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsee (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipSetBuilder&
|
||||
setSponsee(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsee] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFeeAmount (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipSetBuilder&
|
||||
setFeeAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfFeeAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfMaxFee (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipSetBuilder&
|
||||
setMaxFee(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfMaxFee] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfRemainingOwnerCount (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipSetBuilder&
|
||||
setRemainingOwnerCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfRemainingOwnerCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the SponsorshipSet wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
SponsorshipSet
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return SponsorshipSet{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
179
include/xrpl/protocol_autogen/transactions/SponsorshipTransfer.h
Normal file
179
include/xrpl/protocol_autogen/transactions/SponsorshipTransfer.h
Normal file
@@ -0,0 +1,179 @@
|
||||
// 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 SponsorshipTransferBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: SponsorshipTransfer
|
||||
*
|
||||
* Type: ttSPONSORSHIP_TRANSFER (85)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureSponsor
|
||||
* Privileges: MayModifyVault
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use SponsorshipTransferBuilder to construct new transactions.
|
||||
*/
|
||||
class SponsorshipTransfer : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttSPONSORSHIP_TRANSFER;
|
||||
|
||||
/**
|
||||
* @brief Construct a SponsorshipTransfer transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit SponsorshipTransfer(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 SponsorshipTransfer");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfObjectID (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT256::type::value_type>
|
||||
getObjectID() const
|
||||
{
|
||||
if (hasObjectID())
|
||||
{
|
||||
return this->tx_->at(sfObjectID);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfObjectID is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasObjectID() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfObjectID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsee (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getSponsee() const
|
||||
{
|
||||
if (hasSponsee())
|
||||
{
|
||||
return this->tx_->at(sfSponsee);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSponsee is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSponsee() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfSponsee);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for SponsorshipTransfer 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 SponsorshipTransferBuilder : public TransactionBuilderBase<SponsorshipTransferBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new SponsorshipTransferBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
SponsorshipTransferBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<SponsorshipTransferBuilder>(ttSPONSORSHIP_TRANSFER, account, sequence, fee)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a SponsorshipTransferBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
SponsorshipTransferBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttSPONSORSHIP_TRANSFER)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for SponsorshipTransferBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/** @brief Transaction-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfObjectID (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipTransferBuilder&
|
||||
setObjectID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfObjectID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsee (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipTransferBuilder&
|
||||
setSponsee(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsee] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the SponsorshipTransfer wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
SponsorshipTransfer
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return SponsorshipTransfer{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
static constexpr auto kDefaultCacheTargetSize = 0;
|
||||
|
||||
using key_type = uint256;
|
||||
using clock_type = CacheType::clock_type;
|
||||
using clock_type = typename CacheType::clock_type;
|
||||
|
||||
/** Construct the cache.
|
||||
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/WrappedSink.h>
|
||||
#include <xrpl/ledger/helpers/FundingSource.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
#include <xrpl/protocol/Permissions.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -223,63 +224,11 @@ public:
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function can be overridden to introduce additional semantic constraints beyond the
|
||||
* granular template validation for granular permissions. It is called by the base
|
||||
* invokeCheckPermission method only after the transaction has successfully passed
|
||||
* checkGranularSandbox.
|
||||
*/
|
||||
static NotTEC
|
||||
checkGranularSemantics(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType> const& heldGranularPermissions)
|
||||
{
|
||||
return tesSUCCESS;
|
||||
}
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
|
||||
/**
|
||||
* Checks whether the transaction is authorized to be executed by the delegated account.
|
||||
* This function enforces the strict permission check hierarchy. It is explicitly
|
||||
* designed NOT to be overridden. Derived transactors must instead implement
|
||||
* checkGranularSemantics to add custom validation logic for granular permissions.
|
||||
*
|
||||
* The evaluation proceeds as follows:
|
||||
* - If transaction-level permission is granted, the function immediately returns tesSUCCESS.
|
||||
* - If transaction-level permission is not granted, the function checks whether the transaction
|
||||
* matches the granular permission template defined in permissions.macro. If it does, it then
|
||||
* calls checkGranularSemantics to perform any additional, fine-grained validation.
|
||||
*
|
||||
*/
|
||||
template <class T>
|
||||
static NotTEC
|
||||
invokeCheckPermission(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
// heldGranularPermissions is passed by reference into checkPermission.
|
||||
// It is populated with the sender’s granular permissions only when the sender
|
||||
// lacks tx-level permission but has granular permissions that satisfy the
|
||||
// granular permission template.
|
||||
//
|
||||
// - result is terNO_DELEGATE_PERMISSION: return immediately.
|
||||
// - result is tesSUCCESS and heldGranularPermissions is empty: tx-level permission was
|
||||
// granted, so we returned success before populating it.
|
||||
// - result is tesSUCCESS and heldGranularPermissions is not empty: tx-level permission was
|
||||
// not granted, but the held granular permissions passed checkGranularSandbox, so we proceed
|
||||
// to checkGranularSemantics.
|
||||
//
|
||||
// WARNING: Do not simplify checkPermission to return only
|
||||
// heldGranularPermissions or the ter code. Both the result and the
|
||||
// populated set are required to enforce the strict permission hierarchy
|
||||
// described above.
|
||||
std::unordered_set<GranularPermissionType> heldGranularPermissions;
|
||||
if (NotTEC const result = checkPermission(view, tx, heldGranularPermissions);
|
||||
!isTesSuccess(result) || heldGranularPermissions.empty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return T::checkGranularSemantics(view, tx, heldGranularPermissions);
|
||||
}
|
||||
checkSponsor(ReadView const& view, STTx const& tx);
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
// Interface used by AccountDelete
|
||||
@@ -409,24 +358,13 @@ protected:
|
||||
unit::ValueUnit<Unit, T> min = unit::ValueUnit<Unit, T>{});
|
||||
|
||||
private:
|
||||
static NotTEC
|
||||
checkPermission(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType>& heldGranularPermissions);
|
||||
|
||||
std::pair<TER, XRPAmount>
|
||||
reset(XRPAmount fee);
|
||||
|
||||
TER
|
||||
consumeSeqProxy(SLE::pointer const& sleAccount);
|
||||
|
||||
TER
|
||||
payFee();
|
||||
|
||||
std::tuple<TER, XRPAmount, bool>
|
||||
processPersistentChanges(TER result, XRPAmount fee);
|
||||
|
||||
static NotTEC
|
||||
checkSingleSign(
|
||||
ReadView const& view,
|
||||
@@ -434,7 +372,6 @@ private:
|
||||
AccountID const& idAccount,
|
||||
SLE::const_pointer sleAccount,
|
||||
beast::Journal const j);
|
||||
|
||||
static NotTEC
|
||||
checkMultiSign(
|
||||
ReadView const& view,
|
||||
|
||||
@@ -15,9 +15,7 @@ class ValidAMM
|
||||
std::optional<AccountID> ammAccount_;
|
||||
std::optional<STAmount> lptAMMBalanceAfter_;
|
||||
std::optional<STAmount> lptAMMBalanceBefore_;
|
||||
std::optional<STAmount> lptAMMBalanceBeforeDeletion_;
|
||||
bool ammPoolChanged_{false};
|
||||
bool ammDeleted_{false};
|
||||
|
||||
public:
|
||||
enum class ZeroAllowed : bool { No = false, Yes = true };
|
||||
@@ -37,17 +35,12 @@ private:
|
||||
[[nodiscard]] bool
|
||||
finalizeCreate(STTx const&, ReadView const&, bool enforce, beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
finalizeDelete(bool enforce, bool enforceAMMDelete, TER res, beast::Journal const&) const;
|
||||
finalizeDelete(bool enforce, TER res, beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
finalizeDeposit(STTx const&, ReadView const&, bool enforce, beast::Journal const&) const;
|
||||
// Includes clawback
|
||||
[[nodiscard]] bool
|
||||
finalizeWithdraw(
|
||||
STTx const&,
|
||||
ReadView const&,
|
||||
bool enforce,
|
||||
bool enforceAMMDelete,
|
||||
beast::Journal const&) const;
|
||||
finalizeWithdraw(STTx const&, ReadView const&, bool enforce, beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
finalizeDEX(bool enforce, beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user