mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Compare commits
105 Commits
3.0.0-rc2
...
ripple/con
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c8ec2eb7e | ||
|
|
c754aa3bca | ||
|
|
b94c95b3e9 | ||
|
|
8365148b5c | ||
|
|
c03866bf0f | ||
|
|
389afc5f06 | ||
|
|
7b04eaae81 | ||
|
|
1343019509 | ||
|
|
cd75e630a2 | ||
|
|
ec57fbdc5f | ||
|
|
4fe67f5715 | ||
|
|
b18dece145 | ||
|
|
63a08560ca | ||
|
|
8ac8a47c99 | ||
|
|
12c4b5a632 | ||
|
|
25c5e3b17f | ||
|
|
8eb233c2ea | ||
|
|
50fc93f742 | ||
|
|
ab45a8a737 | ||
|
|
dfafb141cc | ||
|
|
4e32d2ed98 | ||
|
|
fa69918124 | ||
|
|
cbbb2b1be0 | ||
|
|
cf2d763fa1 | ||
|
|
44d885e39b | ||
|
|
2dd1d682ac | ||
|
|
4cb1084c02 | ||
|
|
8d1b3b3994 | ||
|
|
b39d7a6519 | ||
|
|
b0910e359e | ||
|
|
44e027e516 | ||
|
|
3af758145c | ||
|
|
a10f42a3aa | ||
|
|
efd4c1b95d | ||
|
|
f8b4f692f1 | ||
|
|
80a3ae6386 | ||
|
|
48d38c1e2c | ||
|
|
553fb5be3b | ||
|
|
f3d4d4341b | ||
|
|
efa917d9f3 | ||
|
|
bd3bc917f8 | ||
|
|
ed5d6f3e22 | ||
|
|
a8e4da0b11 | ||
|
|
1dd60242de | ||
|
|
76611c3f46 | ||
|
|
5efaf0c328 | ||
|
|
0aa23933ea | ||
|
|
21f3c12d85 | ||
|
|
7d5ed0cd8d | ||
|
|
ddb518ad09 | ||
|
|
d9960d5ba0 | ||
|
|
91fa6b2295 | ||
|
|
76f774e22d | ||
|
|
f4f7618173 | ||
|
|
66f16469f9 | ||
|
|
1845b1c656 | ||
|
|
3899e3f36c | ||
|
|
e192ffe964 | ||
|
|
e4a8ba51f9 | ||
|
|
35e4fad557 | ||
|
|
2bf77cc8f6 | ||
|
|
5e33ca56fd | ||
|
|
8e9cb3c1da | ||
|
|
18d92058e3 | ||
|
|
7c39c810eb | ||
|
|
a7792ebcae | ||
|
|
83ee3788e1 | ||
|
|
ae719b86d3 | ||
|
|
dd722f8b3f | ||
|
|
30190a5feb | ||
|
|
f24d584f29 | ||
|
|
da3fbcd25b | ||
|
|
daa1303b5a | ||
|
|
a636fe5871 | ||
|
|
afb6e0e41b | ||
|
|
5523557226 | ||
|
|
bbc3071fd1 | ||
|
|
b64707f53b | ||
|
|
0b113f371f | ||
|
|
b4c894c1ba | ||
|
|
8fdc639206 | ||
|
|
92281a4ede | ||
|
|
e80642fc12 | ||
|
|
640ce4988f | ||
|
|
a422855ea7 | ||
|
|
108f90586c | ||
|
|
519d1dbc34 | ||
|
|
3d44758e5a | ||
|
|
97bc94a7f6 | ||
|
|
34619f2504 | ||
|
|
3509de9c5f | ||
|
|
459d0da010 | ||
|
|
8637d606a4 | ||
|
|
8456b8275e | ||
|
|
3c88786bb0 | ||
|
|
46ba8a28fe | ||
|
|
5ecde3cf39 | ||
|
|
620fb26823 | ||
|
|
6b6b213cf5 | ||
|
|
f61086b43c | ||
|
|
176fd2b6e4 | ||
|
|
5a89641d98 | ||
|
|
beefa248a6 | ||
|
|
e919a25ecb | ||
|
|
c3fdbc0430 |
@@ -17,7 +17,7 @@ Loop: xrpld.app xrpld.rpc
|
||||
xrpld.rpc > xrpld.app
|
||||
|
||||
Loop: xrpld.app xrpld.shamap
|
||||
xrpld.app > xrpld.shamap
|
||||
xrpld.shamap ~= xrpld.app
|
||||
|
||||
Loop: xrpld.core xrpld.perflog
|
||||
xrpld.perflog == xrpld.core
|
||||
|
||||
@@ -8,6 +8,10 @@ libxrpl.ledger > xrpl.ledger
|
||||
libxrpl.ledger > xrpl.protocol
|
||||
libxrpl.net > xrpl.basics
|
||||
libxrpl.net > xrpl.net
|
||||
libxrpl.nodestore > xrpl.basics
|
||||
libxrpl.nodestore > xrpl.json
|
||||
libxrpl.nodestore > xrpl.nodestore
|
||||
libxrpl.nodestore > xrpl.protocol
|
||||
libxrpl.protocol > xrpl.basics
|
||||
libxrpl.protocol > xrpl.json
|
||||
libxrpl.protocol > xrpl.protocol
|
||||
@@ -18,6 +22,9 @@ libxrpl.server > xrpl.basics
|
||||
libxrpl.server > xrpl.json
|
||||
libxrpl.server > xrpl.protocol
|
||||
libxrpl.server > xrpl.server
|
||||
libxrpl.shamap > xrpl.basics
|
||||
libxrpl.shamap > xrpl.protocol
|
||||
libxrpl.shamap > xrpl.shamap
|
||||
test.app > test.jtx
|
||||
test.app > test.rpc
|
||||
test.app > test.toplevel
|
||||
@@ -25,11 +32,11 @@ test.app > test.unit_test
|
||||
test.app > xrpl.basics
|
||||
test.app > xrpld.app
|
||||
test.app > xrpld.core
|
||||
test.app > xrpld.nodestore
|
||||
test.app > xrpld.overlay
|
||||
test.app > xrpld.rpc
|
||||
test.app > xrpl.json
|
||||
test.app > xrpl.ledger
|
||||
test.app > xrpl.nodestore
|
||||
test.app > xrpl.protocol
|
||||
test.app > xrpl.resource
|
||||
test.basics > test.jtx
|
||||
@@ -86,8 +93,7 @@ test.nodestore > test.toplevel
|
||||
test.nodestore > test.unit_test
|
||||
test.nodestore > xrpl.basics
|
||||
test.nodestore > xrpld.core
|
||||
test.nodestore > xrpld.nodestore
|
||||
test.nodestore > xrpld.unity
|
||||
test.nodestore > xrpl.nodestore
|
||||
test.overlay > test.jtx
|
||||
test.overlay > test.toplevel
|
||||
test.overlay > test.unit_test
|
||||
@@ -95,8 +101,8 @@ test.overlay > xrpl.basics
|
||||
test.overlay > xrpld.app
|
||||
test.overlay > xrpld.overlay
|
||||
test.overlay > xrpld.peerfinder
|
||||
test.overlay > xrpld.shamap
|
||||
test.overlay > xrpl.protocol
|
||||
test.overlay > xrpl.shamap
|
||||
test.peerfinder > test.beast
|
||||
test.peerfinder > test.unit_test
|
||||
test.peerfinder > xrpl.basics
|
||||
@@ -131,9 +137,9 @@ test.server > xrpl.json
|
||||
test.server > xrpl.server
|
||||
test.shamap > test.unit_test
|
||||
test.shamap > xrpl.basics
|
||||
test.shamap > xrpld.nodestore
|
||||
test.shamap > xrpld.shamap
|
||||
test.shamap > xrpl.nodestore
|
||||
test.shamap > xrpl.protocol
|
||||
test.shamap > xrpl.shamap
|
||||
test.toplevel > test.csf
|
||||
test.toplevel > xrpl.json
|
||||
test.unit_test > xrpl.basics
|
||||
@@ -144,6 +150,8 @@ xrpl.json > xrpl.basics
|
||||
xrpl.ledger > xrpl.basics
|
||||
xrpl.ledger > xrpl.protocol
|
||||
xrpl.net > xrpl.basics
|
||||
xrpl.nodestore > xrpl.basics
|
||||
xrpl.nodestore > xrpl.protocol
|
||||
xrpl.protocol > xrpl.basics
|
||||
xrpl.protocol > xrpl.json
|
||||
xrpl.resource > xrpl.basics
|
||||
@@ -152,17 +160,21 @@ xrpl.resource > xrpl.protocol
|
||||
xrpl.server > xrpl.basics
|
||||
xrpl.server > xrpl.json
|
||||
xrpl.server > xrpl.protocol
|
||||
xrpl.shamap > xrpl.basics
|
||||
xrpl.shamap > xrpl.nodestore
|
||||
xrpl.shamap > xrpl.protocol
|
||||
xrpld.app > test.unit_test
|
||||
xrpld.app > xrpl.basics
|
||||
xrpld.app > xrpld.conditions
|
||||
xrpld.app > xrpld.consensus
|
||||
xrpld.app > xrpld.nodestore
|
||||
xrpld.app > xrpld.perflog
|
||||
xrpld.app > xrpl.json
|
||||
xrpld.app > xrpl.ledger
|
||||
xrpld.app > xrpl.net
|
||||
xrpld.app > xrpl.nodestore
|
||||
xrpld.app > xrpl.protocol
|
||||
xrpld.app > xrpl.resource
|
||||
xrpld.app > xrpl.shamap
|
||||
xrpld.conditions > xrpl.basics
|
||||
xrpld.conditions > xrpl.protocol
|
||||
xrpld.consensus > xrpl.basics
|
||||
@@ -172,11 +184,6 @@ xrpld.core > xrpl.basics
|
||||
xrpld.core > xrpl.json
|
||||
xrpld.core > xrpl.net
|
||||
xrpld.core > xrpl.protocol
|
||||
xrpld.nodestore > xrpl.basics
|
||||
xrpld.nodestore > xrpld.core
|
||||
xrpld.nodestore > xrpld.unity
|
||||
xrpld.nodestore > xrpl.json
|
||||
xrpld.nodestore > xrpl.protocol
|
||||
xrpld.overlay > xrpl.basics
|
||||
xrpld.overlay > xrpld.core
|
||||
xrpld.overlay > xrpld.peerfinder
|
||||
@@ -192,13 +199,11 @@ xrpld.perflog > xrpl.basics
|
||||
xrpld.perflog > xrpl.json
|
||||
xrpld.rpc > xrpl.basics
|
||||
xrpld.rpc > xrpld.core
|
||||
xrpld.rpc > xrpld.nodestore
|
||||
xrpld.rpc > xrpl.json
|
||||
xrpld.rpc > xrpl.ledger
|
||||
xrpld.rpc > xrpl.net
|
||||
xrpld.rpc > xrpl.nodestore
|
||||
xrpld.rpc > xrpl.protocol
|
||||
xrpld.rpc > xrpl.resource
|
||||
xrpld.rpc > xrpl.server
|
||||
xrpld.shamap > xrpl.basics
|
||||
xrpld.shamap > xrpld.nodestore
|
||||
xrpld.shamap > xrpl.protocol
|
||||
xrpld.shamap > xrpl.shamap
|
||||
|
||||
6
.github/scripts/strategy-matrix/generate.py
vendored
6
.github/scripts/strategy-matrix/generate.py
vendored
@@ -130,14 +130,16 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
if os['distro_name'] == 'rhel' and architecture['platform'] == 'linux/arm64':
|
||||
continue
|
||||
|
||||
# We skip all clang 20+ on arm64 due to Boost build error.
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' in ['clang-20', 'clang-21'] and architecture['platform'] == 'linux/arm64':
|
||||
# We skip all clang-20 on arm64 due to boost 1.86 build error
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-20' and architecture['platform'] == 'linux/arm64':
|
||||
continue
|
||||
|
||||
# Enable code coverage for Debian Bookworm using GCC 15 in Debug and no
|
||||
# Unity on linux/amd64
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
|
||||
cmake_args = f'-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0 {cmake_args}'
|
||||
cmake_target = 'coverage'
|
||||
build_only = True
|
||||
|
||||
# Generate a unique name for the configuration, e.g. macos-arm64-debug
|
||||
# or debian-bookworm-gcc-12-amd64-release-unity.
|
||||
|
||||
76
.github/scripts/strategy-matrix/linux.json
vendored
76
.github/scripts/strategy-matrix/linux.json
vendored
@@ -15,196 +15,168 @@
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "0525eae"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "13",
|
||||
"image_sha": "0525eae"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "0525eae"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "15",
|
||||
"image_sha": "0525eae"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "16",
|
||||
"image_sha": "0525eae"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "17",
|
||||
"image_sha": "0525eae"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "18",
|
||||
"image_sha": "0525eae"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "19",
|
||||
"image_sha": "0525eae"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "20",
|
||||
"image_sha": "0525eae"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "trixie",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "0525eae"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "trixie",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "15",
|
||||
"image_sha": "0525eae"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "trixie",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "20",
|
||||
"image_sha": "0525eae"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "trixie",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "21",
|
||||
"image_sha": "0525eae"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "8",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "8",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "13",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "10",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "10",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "jammy",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "13",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "16",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "17",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "18",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "19",
|
||||
"image_sha": "e1782cd"
|
||||
"image_sha": "97ba375"
|
||||
}
|
||||
],
|
||||
"build_type": ["Debug", "Release"],
|
||||
|
||||
2
.github/workflows/on-pr.yml
vendored
2
.github/workflows/on-pr.yml
vendored
@@ -115,7 +115,7 @@ jobs:
|
||||
needs:
|
||||
- should-run
|
||||
- build-test
|
||||
if: ${{ needs.should-run.outputs.go == 'true' && (startsWith(github.base_ref, 'release') || github.base_ref == 'master') }}
|
||||
if: ${{ needs.should-run.outputs.go == 'true' && contains(fromJSON('["release", "master"]'), github.ref_name) }}
|
||||
uses: ./.github/workflows/reusable-notify-clio.yml
|
||||
secrets:
|
||||
clio_notify_token: ${{ secrets.CLIO_NOTIFY_TOKEN }}
|
||||
|
||||
6
.github/workflows/on-trigger.yml
vendored
6
.github/workflows/on-trigger.yml
vendored
@@ -14,7 +14,9 @@ on:
|
||||
- "master"
|
||||
paths:
|
||||
# These paths are unique to `on-trigger.yml`.
|
||||
- ".github/workflows/reusable-check-missing-commits.yml"
|
||||
- ".github/workflows/on-trigger.yml"
|
||||
- ".github/workflows/publish-docs.yml"
|
||||
|
||||
# Keep the paths below in sync with those in `on-pr.yml`.
|
||||
- ".github/actions/build-deps/**"
|
||||
@@ -61,6 +63,10 @@ defaults:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check-missing-commits:
|
||||
if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && contains(fromJSON('["develop", "release"]'), github.ref_name) }}
|
||||
uses: ./.github/workflows/reusable-check-missing-commits.yml
|
||||
|
||||
build-test:
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
|
||||
182
.github/workflows/reusable-build-test-config.yml
vendored
182
.github/workflows/reusable-build-test-config.yml
vendored
@@ -7,23 +7,19 @@ on:
|
||||
description: "The directory where to build."
|
||||
required: true
|
||||
type: string
|
||||
|
||||
build_only:
|
||||
description: 'Whether to only build or to build and test the code ("true", "false").'
|
||||
required: true
|
||||
type: boolean
|
||||
|
||||
build_type:
|
||||
description: 'The build type to use ("Debug", "Release").'
|
||||
type: string
|
||||
required: true
|
||||
|
||||
cmake_args:
|
||||
description: "Additional arguments to pass to CMake."
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
cmake_target:
|
||||
description: "The CMake target to build."
|
||||
type: string
|
||||
@@ -33,7 +29,6 @@ on:
|
||||
description: Runner to run the job on as a JSON string
|
||||
required: true
|
||||
type: string
|
||||
|
||||
image:
|
||||
description: "The image to run in (leave empty to run natively)"
|
||||
required: true
|
||||
@@ -55,159 +50,28 @@ on:
|
||||
description: "The Codecov token to use for uploading coverage reports."
|
||||
required: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
build-and-test:
|
||||
name: ${{ inputs.config_name }}
|
||||
runs-on: ${{ fromJSON(inputs.runs_on) }}
|
||||
container: ${{ inputs.image != '' && inputs.image || null }}
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
ENABLED_VOIDSTAR: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }}
|
||||
ENABLED_COVERAGE: ${{ contains(inputs.cmake_args, '-Dcoverage=ON') }}
|
||||
steps:
|
||||
- name: Cleanup workspace (macOS and Windows)
|
||||
if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }}
|
||||
uses: XRPLF/actions/.github/actions/cleanup-workspace@01b244d2718865d427b499822fbd3f15e7197fcc
|
||||
build:
|
||||
uses: ./.github/workflows/reusable-build.yml
|
||||
with:
|
||||
build_dir: ${{ inputs.build_dir }}
|
||||
build_type: ${{ inputs.build_type }}
|
||||
cmake_args: ${{ inputs.cmake_args }}
|
||||
cmake_target: ${{ inputs.cmake_target }}
|
||||
runs_on: ${{ inputs.runs_on }}
|
||||
image: ${{ inputs.image }}
|
||||
config_name: ${{ inputs.config_name }}
|
||||
nproc_subtract: ${{ inputs.nproc_subtract }}
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
|
||||
with:
|
||||
disable_ccache: false
|
||||
|
||||
- name: Print build environment
|
||||
uses: ./.github/actions/print-env
|
||||
|
||||
- name: Get number of processors
|
||||
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
|
||||
id: nproc
|
||||
with:
|
||||
subtract: ${{ inputs.nproc_subtract }}
|
||||
|
||||
- name: Setup Conan
|
||||
uses: ./.github/actions/setup-conan
|
||||
|
||||
- name: Build dependencies
|
||||
uses: ./.github/actions/build-deps
|
||||
with:
|
||||
build_dir: ${{ inputs.build_dir }}
|
||||
build_nproc: ${{ steps.nproc.outputs.nproc }}
|
||||
build_type: ${{ inputs.build_type }}
|
||||
# Set the verbosity to "quiet" for Windows to avoid an excessive
|
||||
# amount of logs. For other OSes, the "verbose" logs are more useful.
|
||||
log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
env:
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
CMAKE_ARGS: ${{ inputs.cmake_args }}
|
||||
run: |
|
||||
cmake \
|
||||
-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} \
|
||||
..
|
||||
|
||||
- name: Build the binary
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
env:
|
||||
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
CMAKE_TARGET: ${{ inputs.cmake_target }}
|
||||
run: |
|
||||
cmake \
|
||||
--build . \
|
||||
--config "${BUILD_TYPE}" \
|
||||
--parallel "${BUILD_NPROC}" \
|
||||
--target "${CMAKE_TARGET}"
|
||||
|
||||
- name: Upload rippled artifact (Linux)
|
||||
if: ${{ github.repository_owner == 'XRPLF' && runner.os == 'Linux' }}
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
env:
|
||||
BUILD_DIR: ${{ inputs.build_dir }}
|
||||
with:
|
||||
name: rippled-${{ inputs.config_name }}
|
||||
path: ${{ env.BUILD_DIR }}/rippled
|
||||
retention-days: 3
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Check linking (Linux)
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
run: |
|
||||
ldd ./rippled
|
||||
if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then
|
||||
echo 'The binary is statically linked.'
|
||||
else
|
||||
echo 'The binary is dynamically linked.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Verify presence of instrumentation (Linux)
|
||||
if: ${{ runner.os == 'Linux' && env.ENABLED_VOIDSTAR == 'true' }}
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
run: |
|
||||
./rippled --version | grep libvoidstar
|
||||
|
||||
- name: Run the separate tests
|
||||
if: ${{ !inputs.build_only }}
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
# Windows locks some of the build files while running tests, and parallel jobs can collide
|
||||
env:
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
PARALLELISM: ${{ runner.os == 'Windows' && '1' || steps.nproc.outputs.nproc }}
|
||||
run: |
|
||||
ctest \
|
||||
--output-on-failure \
|
||||
-C "${BUILD_TYPE}" \
|
||||
-j "${PARALLELISM}"
|
||||
|
||||
- name: Run the embedded tests
|
||||
if: ${{ !inputs.build_only }}
|
||||
working-directory: ${{ runner.os == 'Windows' && format('{0}/{1}', inputs.build_dir, inputs.build_type) || inputs.build_dir }}
|
||||
env:
|
||||
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
|
||||
run: |
|
||||
./rippled --unittest --unittest-jobs "${BUILD_NPROC}"
|
||||
|
||||
- name: Debug failure (Linux)
|
||||
if: ${{ failure() && runner.os == 'Linux' && !inputs.build_only }}
|
||||
run: |
|
||||
echo "IPv4 local port range:"
|
||||
cat /proc/sys/net/ipv4/ip_local_port_range
|
||||
echo "Netstat:"
|
||||
netstat -an
|
||||
|
||||
- name: Prepare coverage report
|
||||
if: ${{ !inputs.build_only && env.ENABLED_COVERAGE == 'true' }}
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
env:
|
||||
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
run: |
|
||||
cmake \
|
||||
--build . \
|
||||
--config "${BUILD_TYPE}" \
|
||||
--parallel "${BUILD_NPROC}" \
|
||||
--target coverage
|
||||
|
||||
- name: Upload coverage report
|
||||
if: ${{ github.repository_owner == 'XRPLF' && !inputs.build_only && env.ENABLED_COVERAGE == 'true' }}
|
||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
|
||||
with:
|
||||
disable_search: true
|
||||
disable_telem: true
|
||||
fail_ci_if_error: true
|
||||
files: ${{ inputs.build_dir }}/coverage.xml
|
||||
plugins: noop
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
verbose: true
|
||||
test:
|
||||
needs: build
|
||||
uses: ./.github/workflows/reusable-test.yml
|
||||
with:
|
||||
run_tests: ${{ !inputs.build_only }}
|
||||
verify_voidstar: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }}
|
||||
runs_on: ${{ inputs.runs_on }}
|
||||
image: ${{ inputs.image }}
|
||||
config_name: ${{ inputs.config_name }}
|
||||
nproc_subtract: ${{ inputs.nproc_subtract }}
|
||||
|
||||
154
.github/workflows/reusable-build.yml
vendored
Normal file
154
.github/workflows/reusable-build.yml
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
name: Build rippled
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
build_dir:
|
||||
description: "The directory where to build."
|
||||
required: true
|
||||
type: string
|
||||
build_type:
|
||||
description: 'The build type to use ("Debug", "Release").'
|
||||
required: true
|
||||
type: string
|
||||
cmake_args:
|
||||
description: "Additional arguments to pass to CMake."
|
||||
required: true
|
||||
type: string
|
||||
cmake_target:
|
||||
description: "The CMake target to build."
|
||||
required: true
|
||||
type: string
|
||||
|
||||
runs_on:
|
||||
description: Runner to run the job on as a JSON string
|
||||
required: true
|
||||
type: string
|
||||
image:
|
||||
description: "The image to run in (leave empty to run natively)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
config_name:
|
||||
description: "The name of the configuration."
|
||||
required: true
|
||||
type: string
|
||||
|
||||
nproc_subtract:
|
||||
description: "The number of processors to subtract when calculating parallelism."
|
||||
required: true
|
||||
type: number
|
||||
|
||||
secrets:
|
||||
CODECOV_TOKEN:
|
||||
description: "The Codecov token to use for uploading coverage reports."
|
||||
required: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build ${{ inputs.config_name }}
|
||||
runs-on: ${{ fromJSON(inputs.runs_on) }}
|
||||
container: ${{ inputs.image != '' && inputs.image || null }}
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Cleanup workspace
|
||||
if: ${{ runner.os == 'macOS' }}
|
||||
uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
|
||||
with:
|
||||
disable_ccache: false
|
||||
|
||||
- name: Print build environment
|
||||
uses: ./.github/actions/print-env
|
||||
|
||||
- name: Get number of processors
|
||||
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
|
||||
id: nproc
|
||||
with:
|
||||
subtract: ${{ inputs.nproc_subtract }}
|
||||
|
||||
- name: Setup Conan
|
||||
uses: ./.github/actions/setup-conan
|
||||
|
||||
- name: Build dependencies
|
||||
uses: ./.github/actions/build-deps
|
||||
with:
|
||||
build_dir: ${{ inputs.build_dir }}
|
||||
build_nproc: ${{ steps.nproc.outputs.nproc }}
|
||||
build_type: ${{ inputs.build_type }}
|
||||
# Set the verbosity to "quiet" for Windows to avoid an excessive
|
||||
# amount of logs. For other OSes, the "verbose" logs are more useful.
|
||||
log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
env:
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
CMAKE_ARGS: ${{ inputs.cmake_args }}
|
||||
run: |
|
||||
cmake \
|
||||
-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} \
|
||||
..
|
||||
|
||||
- name: Build the binary
|
||||
shell: bash
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
env:
|
||||
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
CMAKE_TARGET: ${{ inputs.cmake_target }}
|
||||
run: |
|
||||
cmake \
|
||||
--build . \
|
||||
--config "${BUILD_TYPE}" \
|
||||
--parallel ${BUILD_NPROC} \
|
||||
--target "${CMAKE_TARGET}"
|
||||
|
||||
- name: Put built binaries in one location
|
||||
shell: bash
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
env:
|
||||
BUILD_TYPE_DIR: ${{ runner.os == 'Windows' && inputs.build_type || '' }}
|
||||
CMAKE_TARGET: ${{ inputs.cmake_target }}
|
||||
run: |
|
||||
mkdir -p ./binaries/doctest/
|
||||
|
||||
cp ./${BUILD_TYPE_DIR}/rippled* ./binaries/
|
||||
if [ "${CMAKE_TARGET}" != 'coverage' ]; then
|
||||
cp ./src/tests/libxrpl/${BUILD_TYPE_DIR}/xrpl.test.* ./binaries/doctest/
|
||||
fi
|
||||
|
||||
- name: Upload rippled artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
env:
|
||||
BUILD_DIR: ${{ inputs.build_dir }}
|
||||
with:
|
||||
name: rippled-${{ inputs.config_name }}
|
||||
path: ${{ env.BUILD_DIR }}/binaries/
|
||||
retention-days: 3
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload coverage report
|
||||
if: ${{ github.repository_owner == 'XRPLF' && inputs.cmake_target == 'coverage' }}
|
||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
|
||||
with:
|
||||
disable_search: true
|
||||
disable_telem: true
|
||||
fail_ci_if_error: true
|
||||
files: ${{ inputs.build_dir }}/coverage.xml
|
||||
plugins: noop
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
verbose: true
|
||||
62
.github/workflows/reusable-check-missing-commits.yml
vendored
Normal file
62
.github/workflows/reusable-check-missing-commits.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
# This workflow checks that all commits in the "master" branch are also in the
|
||||
# "release" and "develop" branches, and that all commits in the "release" branch
|
||||
# are also in the "develop" branch.
|
||||
name: Check for missing commits
|
||||
|
||||
# This workflow can only be triggered by other workflows.
|
||||
on: workflow_call
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-missing-commits
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Check for missing commits
|
||||
env:
|
||||
MESSAGE: |
|
||||
|
||||
If you are reading this, then the commits indicated above are missing
|
||||
from the "develop" and/or "release" branch. Do a reverse-merge as soon
|
||||
as possible. See CONTRIBUTING.md for instructions.
|
||||
run: |
|
||||
set -o pipefail
|
||||
# Branches are ordered by how "canonical" they are. Every commit in one
|
||||
# branch should be in all the branches behind it.
|
||||
order=(master release develop)
|
||||
branches=()
|
||||
for branch in "${order[@]}"; do
|
||||
# Check that the branches exist so that this job will work on forked
|
||||
# repos, which don't necessarily have master and release branches.
|
||||
echo "Checking if ${branch} exists."
|
||||
if git ls-remote --exit-code --heads origin \
|
||||
refs/heads/${branch} > /dev/null; then
|
||||
branches+=(origin/${branch})
|
||||
fi
|
||||
done
|
||||
|
||||
prior=()
|
||||
for branch in "${branches[@]}"; do
|
||||
if [[ ${#prior[@]} -ne 0 ]]; then
|
||||
echo "Checking ${prior[@]} for commits missing from ${branch}."
|
||||
git log --oneline --no-merges "${prior[@]}" \
|
||||
^$branch | tee -a "missing-commits.txt"
|
||||
echo
|
||||
fi
|
||||
prior+=("${branch}")
|
||||
done
|
||||
|
||||
if [[ $(cat missing-commits.txt | wc -l) -ne 0 ]]; then
|
||||
echo "${MESSAGE}"
|
||||
exit 1
|
||||
fi
|
||||
@@ -18,10 +18,6 @@ on:
|
||||
description: "The generated strategy matrix."
|
||||
value: ${{ jobs.generate-matrix.outputs.matrix }}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
generate-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
111
.github/workflows/reusable-test.yml
vendored
Normal file
111
.github/workflows/reusable-test.yml
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
name: Test rippled
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
verify_voidstar:
|
||||
description: "Whether to verify the presence of voidstar instrumentation."
|
||||
required: true
|
||||
type: boolean
|
||||
run_tests:
|
||||
description: "Whether to run unit tests"
|
||||
required: true
|
||||
type: boolean
|
||||
|
||||
runs_on:
|
||||
description: Runner to run the job on as a JSON string
|
||||
required: true
|
||||
type: string
|
||||
image:
|
||||
description: "The image to run in (leave empty to run natively)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
config_name:
|
||||
description: "The name of the configuration."
|
||||
required: true
|
||||
type: string
|
||||
|
||||
nproc_subtract:
|
||||
description: "The number of processors to subtract when calculating parallelism."
|
||||
required: true
|
||||
type: number
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test ${{ inputs.config_name }}
|
||||
runs-on: ${{ fromJSON(inputs.runs_on) }}
|
||||
container: ${{ inputs.image != '' && inputs.image || null }}
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Cleanup workspace
|
||||
if: ${{ runner.os == 'macOS' }}
|
||||
uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
|
||||
|
||||
- name: Get number of processors
|
||||
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
|
||||
id: nproc
|
||||
with:
|
||||
subtract: ${{ inputs.nproc_subtract }}
|
||||
|
||||
- name: Download rippled artifact
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: rippled-${{ inputs.config_name }}
|
||||
|
||||
- name: Make binary executable (Linux and macOS)
|
||||
shell: bash
|
||||
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
|
||||
run: |
|
||||
chmod +x ./rippled
|
||||
|
||||
- name: Check linking (Linux)
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
shell: bash
|
||||
run: |
|
||||
ldd ./rippled
|
||||
if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then
|
||||
echo 'The binary is statically linked.'
|
||||
else
|
||||
echo 'The binary is dynamically linked.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Verifying presence of instrumentation
|
||||
if: ${{ inputs.verify_voidstar }}
|
||||
shell: bash
|
||||
run: |
|
||||
./rippled --version | grep libvoidstar
|
||||
|
||||
- name: Run the embedded tests
|
||||
if: ${{ inputs.run_tests }}
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
|
||||
run: |
|
||||
./rippled --unittest --unittest-jobs ${BUILD_NPROC}
|
||||
|
||||
- name: Run the separate tests
|
||||
if: ${{ inputs.run_tests }}
|
||||
env:
|
||||
EXT: ${{ runner.os == 'Windows' && '.exe' || '' }}
|
||||
shell: bash
|
||||
run: |
|
||||
for test_file in ./doctest/*${EXT}; do
|
||||
echo "Executing $test_file"
|
||||
chmod +x "$test_file"
|
||||
if [[ "${{ runner.os }}" == "Windows" && "$test_file" == "./doctest/xrpl.test.net.exe" ]]; then
|
||||
echo "Skipping $test_file on Windows"
|
||||
else
|
||||
"$test_file"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Debug failure (Linux)
|
||||
if: ${{ failure() && runner.os == 'Linux' && inputs.run_tests }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "IPv4 local port range:"
|
||||
cat /proc/sys/net/ipv4/ip_local_port_range
|
||||
echo "Netstat:"
|
||||
netstat -an
|
||||
10
.github/workflows/upload-conan-deps.yml
vendored
10
.github/workflows/upload-conan-deps.yml
vendored
@@ -40,10 +40,6 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
# Generate the strategy matrix to be used by the following job.
|
||||
generate-matrix:
|
||||
@@ -62,9 +58,9 @@ jobs:
|
||||
runs-on: ${{ matrix.architecture.runner }}
|
||||
container: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-{4}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version, matrix.os.image_sha) || null }}
|
||||
steps:
|
||||
- name: Cleanup workspace (macOS and Windows)
|
||||
if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }}
|
||||
uses: XRPLF/actions/.github/actions/cleanup-workspace@01b244d2718865d427b499822fbd3f15e7197fcc
|
||||
- name: Cleanup workspace
|
||||
if: ${{ runner.os == 'macOS' }}
|
||||
uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
|
||||
@@ -34,5 +34,6 @@ repos:
|
||||
exclude: |
|
||||
(?x)^(
|
||||
external/.*|
|
||||
.github/scripts/levelization/results/.*\.txt
|
||||
.github/scripts/levelization/results/.*\.txt|
|
||||
conan\.lock
|
||||
)$
|
||||
|
||||
19
BUILD.md
19
BUILD.md
@@ -495,18 +495,18 @@ A coverage report is created when the following steps are completed, in order:
|
||||
|
||||
1. `rippled` binary built with instrumentation data, enabled by the `coverage`
|
||||
option mentioned above
|
||||
2. completed one or more run of the unit tests, which populates coverage capture data
|
||||
2. completed run of unit tests, which populates coverage capture data
|
||||
3. completed run of the `gcovr` tool (which internally invokes either `gcov` or `llvm-cov`)
|
||||
to assemble both instrumentation data and the coverage capture data into a coverage report
|
||||
|
||||
The last step of the above is automated into a single target `coverage`. The instrumented
|
||||
The above steps are automated into a single target `coverage`. The instrumented
|
||||
`rippled` binary can also be used for regular development or testing work, at
|
||||
the cost of extra disk space utilization and a small performance hit
|
||||
(to store coverage capture data). Since `rippled` binary is simply a dependency of the
|
||||
coverage report target, it is possible to re-run the `coverage` target without
|
||||
rebuilding the `rippled` binary. Note, running of the unit tests before the `coverage`
|
||||
target is left to the developer. Each such run will append to the coverage data
|
||||
collected in the build directory.
|
||||
(to store coverage capture). In case of a spurious failure of unit tests, it is
|
||||
possible to re-run the `coverage` target without rebuilding the `rippled` binary
|
||||
(since it is simply a dependency of the coverage report target). It is also possible
|
||||
to select only specific tests for the purpose of the coverage report, by setting
|
||||
the `coverage_test` variable in `cmake`
|
||||
|
||||
The default coverage report format is `html-details`, but the user
|
||||
can override it to any of the formats listed in `Builds/CMake/CodeCoverage.cmake`
|
||||
@@ -515,6 +515,11 @@ to generate more than one format at a time by setting the `coverage_extra_args`
|
||||
variable in `cmake`. The specific command line used to run the `gcovr` tool will be
|
||||
displayed if the `CODE_COVERAGE_VERBOSE` variable is set.
|
||||
|
||||
By default, the code coverage tool runs parallel unit tests with `--unittest-jobs`
|
||||
set to the number of available CPU cores. This may cause spurious test
|
||||
errors on Apple. Developers can override the number of unit test jobs with
|
||||
the `coverage_test_parallelism` variable in `cmake`.
|
||||
|
||||
Example use with some cmake variables set:
|
||||
|
||||
```
|
||||
|
||||
@@ -975,6 +975,47 @@
|
||||
# number of ledger records online. Must be greater
|
||||
# than or equal to ledger_history.
|
||||
#
|
||||
# Optional keys for NuDB only:
|
||||
#
|
||||
# nudb_block_size EXPERIMENTAL: Block size in bytes for NuDB storage.
|
||||
# Must be a power of 2 between 4096 and 32768. Default is 4096.
|
||||
#
|
||||
# This parameter controls the fundamental storage unit
|
||||
# size for NuDB's internal data structures. The choice
|
||||
# of block size can significantly impact performance
|
||||
# depending on your storage hardware and filesystem:
|
||||
#
|
||||
# - 4096 bytes: Optimal for most standard SSDs and
|
||||
# traditional filesystems (ext4, NTFS, HFS+).
|
||||
# Provides good balance of performance and storage
|
||||
# efficiency. Recommended for most deployments.
|
||||
# Minimizes memory footprint and provides consistent
|
||||
# low-latency access patterns across diverse hardware.
|
||||
#
|
||||
# - 8192-16384 bytes: May improve performance on
|
||||
# high-end NVMe SSDs and copy-on-write filesystems
|
||||
# like ZFS or Btrfs that benefit from larger block
|
||||
# alignment. Can reduce metadata overhead for large
|
||||
# databases. Offers better sequential throughput and
|
||||
# reduced I/O operations at the cost of higher memory
|
||||
# usage per operation.
|
||||
#
|
||||
# - 32768 bytes (32K): Maximum supported block size
|
||||
# for high-performance scenarios with very fast
|
||||
# storage. May increase memory usage and reduce
|
||||
# efficiency for smaller databases. Best suited for
|
||||
# enterprise environments with abundant RAM.
|
||||
#
|
||||
# Performance testing is recommended before deploying
|
||||
# any non-default block size in production environments.
|
||||
#
|
||||
# Note: This setting cannot be changed after database
|
||||
# creation without rebuilding the entire database.
|
||||
# Choose carefully based on your hardware and expected
|
||||
# database size.
|
||||
#
|
||||
# Example: nudb_block_size=4096
|
||||
#
|
||||
# These keys modify the behavior of online_delete, and thus are only
|
||||
# relevant if online_delete is defined and non-zero:
|
||||
#
|
||||
@@ -1471,6 +1512,7 @@ secure_gateway = 127.0.0.1
|
||||
[node_db]
|
||||
type=NuDB
|
||||
path=/var/lib/rippled/db/nudb
|
||||
nudb_block_size=4096
|
||||
online_delete=512
|
||||
advisory_delete=0
|
||||
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
macro(group_sources_in source_dir curdir)
|
||||
file(GLOB children RELATIVE ${source_dir}/${curdir}
|
||||
${source_dir}/${curdir}/*)
|
||||
foreach (child ${children})
|
||||
if (IS_DIRECTORY ${source_dir}/${curdir}/${child})
|
||||
group_sources_in(${source_dir} ${curdir}/${child})
|
||||
else()
|
||||
string(REPLACE "/" "\\" groupname ${curdir})
|
||||
source_group(${groupname} FILES
|
||||
${source_dir}/${curdir}/${child})
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
macro(group_sources curdir)
|
||||
group_sources_in(${PROJECT_SOURCE_DIR} ${curdir})
|
||||
endmacro()
|
||||
|
||||
macro (exclude_from_default target_)
|
||||
set_target_properties (${target_} PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
set_target_properties (${target_} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON)
|
||||
|
||||
@@ -109,9 +109,6 @@
|
||||
# - add a new function add_code_coverage_to_target
|
||||
# - remove some unused code
|
||||
#
|
||||
# 2025-11-11, Bronek Kozicki
|
||||
# - make EXECUTABLE and EXECUTABLE_ARGS optional
|
||||
#
|
||||
# USAGE:
|
||||
#
|
||||
# 1. Copy this file into your cmake modules path.
|
||||
@@ -320,10 +317,6 @@ function(setup_target_for_coverage_gcovr)
|
||||
set(Coverage_FORMAT xml)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED Coverage_EXECUTABLE AND DEFINED Coverage_EXECUTABLE_ARGS)
|
||||
message(FATAL_ERROR "EXECUTABLE_ARGS must not be set if EXECUTABLE is not set")
|
||||
endif()
|
||||
|
||||
if("--output" IN_LIST GCOVR_ADDITIONAL_ARGS)
|
||||
message(FATAL_ERROR "Unsupported --output option detected in GCOVR_ADDITIONAL_ARGS! Aborting...")
|
||||
else()
|
||||
@@ -405,18 +398,17 @@ function(setup_target_for_coverage_gcovr)
|
||||
endforeach()
|
||||
|
||||
# Set up commands which will be run to generate coverage data
|
||||
# If EXECUTABLE is not set, the user is expected to run the tests manually
|
||||
# before running the coverage target NAME
|
||||
if(DEFINED Coverage_EXECUTABLE)
|
||||
set(GCOVR_EXEC_TESTS_CMD
|
||||
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
)
|
||||
endif()
|
||||
# Run tests
|
||||
set(GCOVR_EXEC_TESTS_CMD
|
||||
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
)
|
||||
|
||||
# Create folder
|
||||
if(DEFINED GCOVR_CREATE_FOLDER)
|
||||
set(GCOVR_FOLDER_CMD
|
||||
${CMAKE_COMMAND} -E make_directory ${GCOVR_CREATE_FOLDER})
|
||||
else()
|
||||
set(GCOVR_FOLDER_CMD echo) # dummy
|
||||
endif()
|
||||
|
||||
# Running gcovr
|
||||
@@ -433,13 +425,11 @@ function(setup_target_for_coverage_gcovr)
|
||||
if(CODE_COVERAGE_VERBOSE)
|
||||
message(STATUS "Executed command report")
|
||||
|
||||
if(NOT "${GCOVR_EXEC_TESTS_CMD}" STREQUAL "")
|
||||
message(STATUS "Command to run tests: ")
|
||||
string(REPLACE ";" " " GCOVR_EXEC_TESTS_CMD_SPACED "${GCOVR_EXEC_TESTS_CMD}")
|
||||
message(STATUS "${GCOVR_EXEC_TESTS_CMD_SPACED}")
|
||||
endif()
|
||||
message(STATUS "Command to run tests: ")
|
||||
string(REPLACE ";" " " GCOVR_EXEC_TESTS_CMD_SPACED "${GCOVR_EXEC_TESTS_CMD}")
|
||||
message(STATUS "${GCOVR_EXEC_TESTS_CMD_SPACED}")
|
||||
|
||||
if(NOT "${GCOVR_FOLDER_CMD}" STREQUAL "")
|
||||
if(NOT GCOVR_FOLDER_CMD STREQUAL "echo")
|
||||
message(STATUS "Command to create a folder: ")
|
||||
string(REPLACE ";" " " GCOVR_FOLDER_CMD_SPACED "${GCOVR_FOLDER_CMD}")
|
||||
message(STATUS "${GCOVR_FOLDER_CMD_SPACED}")
|
||||
|
||||
@@ -12,7 +12,7 @@ if (static OR MSVC)
|
||||
else ()
|
||||
set (Boost_USE_STATIC_RUNTIME OFF)
|
||||
endif ()
|
||||
find_dependency (Boost
|
||||
find_dependency (Boost 1.70
|
||||
COMPONENTS
|
||||
chrono
|
||||
container
|
||||
@@ -45,10 +45,12 @@ if (static OR APPLE OR MSVC)
|
||||
set (OPENSSL_USE_STATIC_LIBS ON)
|
||||
endif ()
|
||||
set (OPENSSL_MSVC_STATIC_RT ON)
|
||||
find_dependency (OpenSSL 1.1.1 REQUIRED)
|
||||
find_dependency (OpenSSL REQUIRED)
|
||||
find_dependency (ZLIB)
|
||||
find_dependency (date)
|
||||
if (TARGET ZLIB::ZLIB)
|
||||
set_target_properties(OpenSSL::Crypto PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES ZLIB::ZLIB)
|
||||
endif ()
|
||||
|
||||
include ("${CMAKE_CURRENT_LIST_DIR}/RippleTargets.cmake")
|
||||
|
||||
@@ -16,13 +16,16 @@ set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
target_compile_definitions (common
|
||||
INTERFACE
|
||||
$<$<CONFIG:Debug>:DEBUG _DEBUG>
|
||||
$<$<AND:$<BOOL:${profile}>,$<NOT:$<BOOL:${assert}>>>:NDEBUG>)
|
||||
# ^^^^ NOTE: CMAKE release builds already have NDEBUG
|
||||
# defined, so no need to add it explicitly except for
|
||||
# this special case of (profile ON) and (assert OFF)
|
||||
# -- presumably this is because we don't want profile
|
||||
# builds asserting unless asserts were specifically
|
||||
# requested
|
||||
#[===[
|
||||
NOTE: CMAKE release builds already have NDEBUG defined, so no need to add it
|
||||
explicitly except for the special case of (profile ON) and (assert OFF).
|
||||
Presumably this is because we don't want profile builds asserting unless
|
||||
asserts were specifically requested.
|
||||
]===]
|
||||
$<$<AND:$<BOOL:${profile}>,$<NOT:$<BOOL:${assert}>>>:NDEBUG>
|
||||
# TODO: Remove once we have migrated functions from OpenSSL 1.x to 3.x.
|
||||
OPENSSL_SUPPRESS_DEPRECATED
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
# remove existing exception flag since we set it to -EHa
|
||||
|
||||
@@ -53,14 +53,15 @@ add_library(xrpl.imports.main INTERFACE)
|
||||
|
||||
target_link_libraries(xrpl.imports.main
|
||||
INTERFACE
|
||||
LibArchive::LibArchive
|
||||
OpenSSL::Crypto
|
||||
Ripple::boost
|
||||
Ripple::opts
|
||||
Ripple::syslibs
|
||||
absl::random_random
|
||||
date::date
|
||||
ed25519::ed25519
|
||||
LibArchive::LibArchive
|
||||
OpenSSL::Crypto
|
||||
Ripple::boost
|
||||
Ripple::libs
|
||||
Ripple::opts
|
||||
Ripple::syslibs
|
||||
secp256k1::secp256k1
|
||||
xrpl.libpb
|
||||
xxHash::xxhash
|
||||
@@ -72,7 +73,10 @@ include(target_link_modules)
|
||||
|
||||
# Level 01
|
||||
add_module(xrpl beast)
|
||||
target_link_libraries(xrpl.libxrpl.beast PUBLIC xrpl.imports.main)
|
||||
target_link_libraries(xrpl.libxrpl.beast PUBLIC
|
||||
xrpl.imports.main
|
||||
xrpl.libpb
|
||||
)
|
||||
|
||||
# Level 02
|
||||
add_module(xrpl basics)
|
||||
@@ -108,6 +112,21 @@ target_link_libraries(xrpl.libxrpl.net PUBLIC
|
||||
add_module(xrpl server)
|
||||
target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol)
|
||||
|
||||
add_module(xrpl nodestore)
|
||||
target_link_libraries(xrpl.libxrpl.nodestore PUBLIC
|
||||
xrpl.libxrpl.basics
|
||||
xrpl.libxrpl.json
|
||||
xrpl.libxrpl.protocol
|
||||
)
|
||||
|
||||
add_module(xrpl shamap)
|
||||
target_link_libraries(xrpl.libxrpl.shamap PUBLIC
|
||||
xrpl.libxrpl.basics
|
||||
xrpl.libxrpl.crypto
|
||||
xrpl.libxrpl.protocol
|
||||
xrpl.libxrpl.nodestore
|
||||
)
|
||||
|
||||
add_module(xrpl ledger)
|
||||
target_link_libraries(xrpl.libxrpl.ledger PUBLIC
|
||||
xrpl.libxrpl.basics
|
||||
@@ -133,6 +152,8 @@ target_link_modules(xrpl PUBLIC
|
||||
protocol
|
||||
resource
|
||||
server
|
||||
nodestore
|
||||
shamap
|
||||
net
|
||||
ledger
|
||||
)
|
||||
|
||||
@@ -11,9 +11,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(PROCESSOR_COUNT)
|
||||
|
||||
include(CodeCoverage)
|
||||
|
||||
# The instructions for these commands come from the `CodeCoverage` module,
|
||||
@@ -29,13 +26,15 @@ list(APPEND GCOVR_ADDITIONAL_ARGS
|
||||
--exclude-throw-branches
|
||||
--exclude-noncode-lines
|
||||
--exclude-unreachable-branches -s
|
||||
-j ${PROCESSOR_COUNT})
|
||||
-j ${coverage_test_parallelism})
|
||||
|
||||
setup_target_for_coverage_gcovr(
|
||||
NAME coverage
|
||||
FORMAT ${coverage_format}
|
||||
EXECUTABLE rippled
|
||||
EXECUTABLE_ARGS --unittest$<$<BOOL:${coverage_test}>:=${coverage_test}> --unittest-jobs ${coverage_test_parallelism} --quiet --unittest-log
|
||||
EXCLUDE "src/test" "src/tests" "include/xrpl/beast/test" "include/xrpl/beast/unit_test" "${CMAKE_BINARY_DIR}/pb-xrpl.libpb"
|
||||
DEPENDENCIES rippled xrpl.tests
|
||||
DEPENDENCIES rippled
|
||||
)
|
||||
|
||||
add_code_coverage_to_target(opts INTERFACE)
|
||||
|
||||
@@ -8,20 +8,23 @@ install (
|
||||
TARGETS
|
||||
common
|
||||
opts
|
||||
ripple_syslibs
|
||||
ripple_boost
|
||||
ripple_libs
|
||||
ripple_syslibs
|
||||
xrpl.imports.main
|
||||
xrpl.libpb
|
||||
xrpl.libxrpl
|
||||
xrpl.libxrpl.basics
|
||||
xrpl.libxrpl.beast
|
||||
xrpl.libxrpl.crypto
|
||||
xrpl.libxrpl.json
|
||||
xrpl.libxrpl.ledger
|
||||
xrpl.libxrpl.net
|
||||
xrpl.libxrpl.nodestore
|
||||
xrpl.libxrpl.protocol
|
||||
xrpl.libxrpl.resource
|
||||
xrpl.libxrpl.ledger
|
||||
xrpl.libxrpl.server
|
||||
xrpl.libxrpl.net
|
||||
xrpl.libxrpl
|
||||
xrpl.libxrpl.shamap
|
||||
antithesis-sdk-cpp
|
||||
EXPORT RippleExports
|
||||
LIBRARY DESTINATION lib
|
||||
@@ -38,7 +41,7 @@ install(CODE "
|
||||
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
|
||||
include(create_symbolic_link)
|
||||
create_symbolic_link(xrpl \
|
||||
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple)
|
||||
\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple)
|
||||
")
|
||||
|
||||
install (EXPORT RippleExports
|
||||
@@ -72,7 +75,7 @@ if (is_root_project AND TARGET rippled)
|
||||
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
|
||||
include(create_symbolic_link)
|
||||
create_symbolic_link(rippled${suffix} \
|
||||
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix})
|
||||
\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix})
|
||||
")
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#[===================================================================[
|
||||
sanity checks
|
||||
convenience variables and sanity checks
|
||||
#]===================================================================]
|
||||
|
||||
get_property(is_multiconfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
@@ -16,19 +16,39 @@ if (NOT is_multiconfig)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
get_directory_property(has_parent PARENT_DIRECTORY)
|
||||
if (has_parent)
|
||||
set (is_root_project OFF)
|
||||
else ()
|
||||
set (is_root_project ON)
|
||||
endif ()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES ".*Clang") # both Clang and AppleClang
|
||||
set (is_clang TRUE)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND
|
||||
CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0)
|
||||
message (FATAL_ERROR "This project requires clang 16 or later")
|
||||
CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
|
||||
message (FATAL_ERROR "This project requires clang 8 or later")
|
||||
endif ()
|
||||
# TODO min AppleClang version check ?
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set (is_gcc TRUE)
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)
|
||||
message (FATAL_ERROR "This project requires GCC 12 or later")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
|
||||
message (FATAL_ERROR "This project requires GCC 8 or later")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set (is_linux TRUE)
|
||||
else ()
|
||||
set (is_linux FALSE)
|
||||
endif ()
|
||||
|
||||
if ("$ENV{CI}" STREQUAL "true" OR "$ENV{CONTINUOUS_INTEGRATION}" STREQUAL "true")
|
||||
set (is_ci TRUE)
|
||||
else ()
|
||||
set (is_ci FALSE)
|
||||
endif ()
|
||||
|
||||
# check for in-source build and fail
|
||||
if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||
message (FATAL_ERROR "Builds (in-source) are not allowed in "
|
||||
|
||||
@@ -1,25 +1,10 @@
|
||||
#[===================================================================[
|
||||
declare options and variables
|
||||
declare user options/settings
|
||||
#]===================================================================]
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set (is_linux TRUE)
|
||||
else()
|
||||
set(is_linux FALSE)
|
||||
endif()
|
||||
include(ProcessorCount)
|
||||
|
||||
if("$ENV{CI}" STREQUAL "true" OR "$ENV{CONTINUOUS_INTEGRATION}" STREQUAL "true")
|
||||
set(is_ci TRUE)
|
||||
else()
|
||||
set(is_ci FALSE)
|
||||
endif()
|
||||
|
||||
get_directory_property(has_parent PARENT_DIRECTORY)
|
||||
if(has_parent)
|
||||
set(is_root_project OFF)
|
||||
else()
|
||||
set(is_root_project ON)
|
||||
endif()
|
||||
ProcessorCount(PROCESSOR_COUNT)
|
||||
|
||||
option(assert "Enables asserts, even in release builds" OFF)
|
||||
|
||||
@@ -40,28 +25,29 @@ if(unity)
|
||||
endif()
|
||||
set(CMAKE_UNITY_BUILD ON CACHE BOOL "Do a unity build")
|
||||
endif()
|
||||
|
||||
if(is_clang AND is_linux)
|
||||
option(voidstar "Enable Antithesis instrumentation." OFF)
|
||||
endif()
|
||||
|
||||
if(is_gcc OR is_clang)
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(PROCESSOR_COUNT)
|
||||
|
||||
option(coverage "Generates coverage info." OFF)
|
||||
option(profile "Add profiling flags" OFF)
|
||||
set(coverage_test_parallelism "${PROCESSOR_COUNT}" CACHE STRING
|
||||
"Unit tests parallelism for the purpose of coverage report.")
|
||||
set(coverage_format "html-details" CACHE STRING
|
||||
"Output format of the coverage report.")
|
||||
set(coverage_extra_args "" CACHE STRING
|
||||
"Additional arguments to pass to gcovr.")
|
||||
set(coverage_test "" CACHE STRING
|
||||
"On gcc & clang, the specific unit test(s) to run for coverage. Default is all tests.")
|
||||
if(coverage_test AND NOT coverage)
|
||||
set(coverage ON CACHE BOOL "gcc/clang only" FORCE)
|
||||
endif()
|
||||
option(wextra "compile with extra gcc/clang warnings enabled" ON)
|
||||
else()
|
||||
set(profile OFF CACHE BOOL "gcc/clang only" FORCE)
|
||||
set(coverage OFF CACHE BOOL "gcc/clang only" FORCE)
|
||||
set(wextra OFF CACHE BOOL "gcc/clang only" FORCE)
|
||||
endif()
|
||||
|
||||
if(is_linux)
|
||||
option(BUILD_SHARED_LIBS "build shared ripple libraries" OFF)
|
||||
option(static "link protobuf, openssl, libc++, and boost statically" ON)
|
||||
@@ -78,13 +64,11 @@ else()
|
||||
set(use_gold OFF CACHE BOOL "gold linker, linux only" FORCE)
|
||||
set(use_mold OFF CACHE BOOL "mold linker, linux only" FORCE)
|
||||
endif()
|
||||
|
||||
if(is_clang)
|
||||
option(use_lld "enables detection of lld linker" ON)
|
||||
else()
|
||||
set(use_lld OFF CACHE BOOL "try lld linker, clang only" FORCE)
|
||||
endif()
|
||||
|
||||
option(jemalloc "Enables jemalloc for heap profiling" OFF)
|
||||
option(werr "treat warnings as errors" OFF)
|
||||
option(local_protobuf
|
||||
@@ -118,26 +102,38 @@ if(san)
|
||||
message(FATAL_ERROR "${san} sanitizer does not seem to be supported by your compiler")
|
||||
endif()
|
||||
endif()
|
||||
set(container_label "" CACHE STRING "tag to use for package building containers")
|
||||
option(packages_only
|
||||
"ONLY generate package building targets. This is special use-case and almost \
|
||||
certainly not what you want. Use with caution as you won't be able to build \
|
||||
any compiled targets locally." OFF)
|
||||
option(have_package_container
|
||||
"Sometimes you already have the tagged container you want to use for package \
|
||||
building and you don't want docker to rebuild it. This flag will detach the \
|
||||
dependency of the package build from the container build. It's an advanced \
|
||||
use case and most likely you should not be touching this flag." OFF)
|
||||
|
||||
# the remaining options are obscure and rarely used
|
||||
option(beast_no_unit_test_inline
|
||||
"Prevents unit test definitions from being inserted into global table"
|
||||
OFF)
|
||||
option(single_io_service_thread
|
||||
"Restricts the number of threads calling io_service::run to one. \
|
||||
"Restricts the number of threads calling io_context::run to one. \
|
||||
This can be useful when debugging."
|
||||
OFF)
|
||||
option(boost_show_deprecated
|
||||
"Allow boost to fail on deprecated usage. Only useful if you're trying\
|
||||
to find deprecated calls."
|
||||
OFF)
|
||||
option(beast_hashers
|
||||
"Use local implementations for sha/ripemd hashes (experimental, not recommended)"
|
||||
OFF)
|
||||
|
||||
if(WIN32)
|
||||
option(beast_disable_autolink "Disables autolinking of system libraries on WIN32" OFF)
|
||||
else()
|
||||
set(beast_disable_autolink OFF CACHE BOOL "WIN32 only" FORCE)
|
||||
endif()
|
||||
|
||||
if(coverage)
|
||||
message(STATUS "coverage build requested - forcing Debug build")
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "build type" FORCE)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
option (validator_keys "Enables building of validator-keys-tool as a separate target (imported via FetchContent)" OFF)
|
||||
option (validator_keys "Enables building of validator-keys tool as a separate target (imported via FetchContent)" OFF)
|
||||
|
||||
if (validator_keys)
|
||||
git_branch (current_branch)
|
||||
@@ -6,17 +6,15 @@ if (validator_keys)
|
||||
if (NOT (current_branch STREQUAL "release"))
|
||||
set (current_branch "master")
|
||||
endif ()
|
||||
message (STATUS "tracking ValidatorKeys branch: ${current_branch}")
|
||||
message (STATUS "Tracking ValidatorKeys branch: ${current_branch}")
|
||||
|
||||
FetchContent_Declare (
|
||||
validator_keys_src
|
||||
validator_keys
|
||||
GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git
|
||||
GIT_TAG "${current_branch}"
|
||||
)
|
||||
FetchContent_GetProperties (validator_keys_src)
|
||||
if (NOT validator_keys_src_POPULATED)
|
||||
message (STATUS "Pausing to download ValidatorKeys...")
|
||||
FetchContent_Populate (validator_keys_src)
|
||||
endif ()
|
||||
add_subdirectory (${validator_keys_src_SOURCE_DIR} ${CMAKE_BINARY_DIR}/validator-keys)
|
||||
FetchContent_MakeAvailable(validator_keys)
|
||||
set_target_properties(validator-keys PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
endif ()
|
||||
|
||||
@@ -24,6 +24,7 @@ target_link_libraries(ripple_boost
|
||||
Boost::date_time
|
||||
Boost::filesystem
|
||||
Boost::json
|
||||
Boost::process
|
||||
Boost::program_options
|
||||
Boost::regex
|
||||
Boost::system
|
||||
|
||||
@@ -22,4 +22,20 @@ function(xrpl_add_test name)
|
||||
UNITY_BUILD_BATCH_SIZE 0) # Adjust as needed
|
||||
|
||||
add_test(NAME ${target} COMMAND ${target})
|
||||
set_tests_properties(
|
||||
${target} PROPERTIES
|
||||
FIXTURES_REQUIRED ${target}_fixture
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME ${target}.build
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
--build ${CMAKE_BINARY_DIR}
|
||||
--config $<CONFIG>
|
||||
--target ${target}
|
||||
)
|
||||
set_tests_properties(${target}.build PROPERTIES
|
||||
FIXTURES_SETUP ${target}_fixture
|
||||
)
|
||||
endfunction()
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"rocksdb/10.0.1#85537f46e538974d67da0c3977de48ac%1756234304.347",
|
||||
"re2/20230301#dfd6e2bf050eb90ddd8729cfb4c844a4%1756234257.976",
|
||||
"protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1756234251.614",
|
||||
"openssl/1.1.1w#a8f0792d7c5121b954578a7149d23e03%1756223730.729",
|
||||
"openssl/3.5.4#a1d5835cc6ed5c5b8f3cd5b9b5d24205%1759746684.671",
|
||||
"nudb/2.0.9#c62cfd501e57055a7e0d8ee3d5e5427d%1756234237.107",
|
||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1756234228.999",
|
||||
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1756223727.64",
|
||||
@@ -21,7 +21,7 @@
|
||||
"date/3.0.4#f74bbba5a08fa388256688743136cb6f%1756234217.493",
|
||||
"c-ares/1.34.5#b78b91e7cfb1f11ce777a285bbf169c6%1756234217.915",
|
||||
"bzip2/1.0.8#00b4a4658791c1f06914e087f0e792f5%1756234261.716",
|
||||
"boost/1.83.0#5d975011d65b51abb2d2f6eb8386b368%1754325043.336",
|
||||
"boost/1.88.0#8852c0b72ce8271fb8ff7c53456d4983%1756223752.326",
|
||||
"abseil/20230802.1#f0f91485b111dc9837a68972cb19ca7b%1756234220.907"
|
||||
],
|
||||
"build_requires": [
|
||||
@@ -46,7 +46,7 @@
|
||||
"lz4/1.10.0"
|
||||
],
|
||||
"boost/1.83.0": [
|
||||
"boost/1.83.0"
|
||||
"boost/1.88.0"
|
||||
],
|
||||
"sqlite3/3.44.2": [
|
||||
"sqlite3/3.49.1"
|
||||
|
||||
@@ -26,9 +26,6 @@ grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-templat
|
||||
{% if compiler == "apple-clang" and compiler_version >= 17 %}
|
||||
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
|
||||
{% endif %}
|
||||
{% if compiler == "clang" and compiler_version == 16 %}
|
||||
tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS']
|
||||
{% endif %}
|
||||
{% if compiler == "gcc" and compiler_version < 13 %}
|
||||
tools.build:cxxflags+=['-Wno-restrict']
|
||||
{% endif %}
|
||||
|
||||
@@ -27,7 +27,7 @@ class Xrpl(ConanFile):
|
||||
'grpc/1.50.1',
|
||||
'libarchive/3.8.1',
|
||||
'nudb/2.0.9',
|
||||
'openssl/1.1.1w',
|
||||
'openssl/3.5.4',
|
||||
'soci/4.0.3',
|
||||
'zlib/1.3.1',
|
||||
]
|
||||
@@ -100,11 +100,13 @@ class Xrpl(ConanFile):
|
||||
def configure(self):
|
||||
if self.settings.compiler == 'apple-clang':
|
||||
self.options['boost'].visibility = 'global'
|
||||
if self.settings.compiler in ['clang', 'gcc']:
|
||||
self.options['boost'].without_cobalt = True
|
||||
|
||||
def requirements(self):
|
||||
# Conan 2 requires transitive headers to be specified
|
||||
transitive_headers_opt = {'transitive_headers': True} if conan_version.split('.')[0] == '2' else {}
|
||||
self.requires('boost/1.83.0', force=True, **transitive_headers_opt)
|
||||
self.requires('boost/1.88.0', force=True, **transitive_headers_opt)
|
||||
self.requires('date/3.0.4', **transitive_headers_opt)
|
||||
self.requires('lz4/1.10.0', force=True)
|
||||
self.requires('protobuf/3.21.12', force=True)
|
||||
@@ -175,6 +177,7 @@ class Xrpl(ConanFile):
|
||||
'boost::filesystem',
|
||||
'boost::json',
|
||||
'boost::program_options',
|
||||
'boost::process',
|
||||
'boost::regex',
|
||||
'boost::system',
|
||||
'boost::thread',
|
||||
|
||||
2
external/secp256k1/include/secp256k1.h
vendored
2
external/secp256k1/include/secp256k1.h
vendored
@@ -541,7 +541,7 @@ SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
|
||||
/** Verify an ECDSA signature.
|
||||
*
|
||||
* Returns: 1: correct signature
|
||||
* 0: incorrect or unparsable signature
|
||||
* 0: incorrect or unparseable signature
|
||||
* Args: ctx: pointer to a context object
|
||||
* In: sig: the signature being verified.
|
||||
* msghash32: the 32-byte message hash being verified.
|
||||
|
||||
@@ -32,15 +32,6 @@ class Number;
|
||||
std::string
|
||||
to_string(Number const& amount);
|
||||
|
||||
template <typename T>
|
||||
constexpr bool
|
||||
isPowerOfTen(T value)
|
||||
{
|
||||
while (value >= 10 && value % 10 == 0)
|
||||
value /= 10;
|
||||
return value == 1;
|
||||
}
|
||||
|
||||
class Number
|
||||
{
|
||||
using rep = std::int64_t;
|
||||
@@ -50,9 +41,7 @@ class Number
|
||||
public:
|
||||
// The range for the mantissa when normalized
|
||||
constexpr static std::int64_t minMantissa = 1'000'000'000'000'000LL;
|
||||
static_assert(isPowerOfTen(minMantissa));
|
||||
constexpr static std::int64_t maxMantissa = minMantissa * 10 - 1;
|
||||
static_assert(maxMantissa == 9'999'999'999'999'999LL);
|
||||
constexpr static std::int64_t maxMantissa = 9'999'999'999'999'999LL;
|
||||
|
||||
// The range for the exponent when normalized
|
||||
constexpr static int minExponent = -32768;
|
||||
@@ -162,7 +151,22 @@ public:
|
||||
}
|
||||
|
||||
Number
|
||||
truncate() const noexcept;
|
||||
truncate() const noexcept
|
||||
{
|
||||
if (exponent_ >= 0 || mantissa_ == 0)
|
||||
return *this;
|
||||
|
||||
Number ret = *this;
|
||||
while (ret.exponent_ < 0 && ret.mantissa_ != 0)
|
||||
{
|
||||
ret.exponent_ += 1;
|
||||
ret.mantissa_ /= rep(10);
|
||||
}
|
||||
// We are guaranteed that normalize() will never throw an exception
|
||||
// because exponent is either negative or zero at this point.
|
||||
ret.normalize();
|
||||
return ret;
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator>(Number const& x, Number const& y) noexcept
|
||||
@@ -207,8 +211,6 @@ private:
|
||||
class Guard;
|
||||
};
|
||||
|
||||
constexpr static Number numZero{};
|
||||
|
||||
inline constexpr Number::Number(rep mantissa, int exponent, unchecked) noexcept
|
||||
: mantissa_{mantissa}, exponent_{exponent}
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <xrpl/basics/Resolver.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
explicit ResolverAsio() = default;
|
||||
|
||||
static std::unique_ptr<ResolverAsio>
|
||||
New(boost::asio::io_service&, beast::Journal);
|
||||
New(boost::asio::io_context&, beast::Journal);
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
@@ -176,7 +176,7 @@ public:
|
||||
@param count the number of items the slab allocator can allocate; note
|
||||
that a count of 0 is valid and means that the allocator
|
||||
is, effectively, disabled. This can be very useful in some
|
||||
contexts (e.g. when minimal memory usage is needed) and
|
||||
contexts (e.g. when mimimal memory usage is needed) and
|
||||
allows for graceful failure.
|
||||
*/
|
||||
constexpr explicit SlabAllocator(
|
||||
|
||||
@@ -565,7 +565,7 @@ operator<=>(base_uint<Bits, Tag> const& lhs, base_uint<Bits, Tag> const& rhs)
|
||||
// This comparison might seem wrong on a casual inspection because it
|
||||
// compares data internally stored as std::uint32_t byte-by-byte. But
|
||||
// note that the underlying data is stored in big endian, even if the
|
||||
// platform is little endian. This makes the comparison correct.
|
||||
// plaform is little endian. This makes the comparison correct.
|
||||
//
|
||||
// FIXME: use std::lexicographical_compare_three_way once support is
|
||||
// added to MacOS.
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace ripple {
|
||||
|
||||
/*
|
||||
* MSVC 2019 version 16.9.0 added [[nodiscard]] to the std comparison
|
||||
* operator() functions. boost::bimap checks that the comparator is a
|
||||
* operator() functions. boost::bimap checks that the comparitor is a
|
||||
* BinaryFunction, in part by calling the function and ignoring the value.
|
||||
* These two things don't play well together. These wrapper classes simply
|
||||
* strip [[nodiscard]] from operator() for use in boost::bimap.
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <boost/asio/basic_waitable_timer.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
@@ -32,7 +33,7 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Measures handler latency on an io_service queue. */
|
||||
/** Measures handler latency on an io_context queue. */
|
||||
template <class Clock>
|
||||
class io_latency_probe
|
||||
{
|
||||
@@ -44,12 +45,12 @@ private:
|
||||
std::condition_variable_any m_cond;
|
||||
std::size_t m_count;
|
||||
duration const m_period;
|
||||
boost::asio::io_service& m_ios;
|
||||
boost::asio::io_context& m_ios;
|
||||
boost::asio::basic_waitable_timer<std::chrono::steady_clock> m_timer;
|
||||
bool m_cancel;
|
||||
|
||||
public:
|
||||
io_latency_probe(duration const& period, boost::asio::io_service& ios)
|
||||
io_latency_probe(duration const& period, boost::asio::io_context& ios)
|
||||
: m_count(1)
|
||||
, m_period(period)
|
||||
, m_ios(ios)
|
||||
@@ -64,16 +65,16 @@ public:
|
||||
cancel(lock, true);
|
||||
}
|
||||
|
||||
/** Return the io_service associated with the latency probe. */
|
||||
/** Return the io_context associated with the latency probe. */
|
||||
/** @{ */
|
||||
boost::asio::io_service&
|
||||
get_io_service()
|
||||
boost::asio::io_context&
|
||||
get_io_context()
|
||||
{
|
||||
return m_ios;
|
||||
}
|
||||
|
||||
boost::asio::io_service const&
|
||||
get_io_service() const
|
||||
boost::asio::io_context const&
|
||||
get_io_context() const
|
||||
{
|
||||
return m_ios;
|
||||
}
|
||||
@@ -109,8 +110,10 @@ public:
|
||||
std::lock_guard lock(m_mutex);
|
||||
if (m_cancel)
|
||||
throw std::logic_error("io_latency_probe is canceled");
|
||||
m_ios.post(sample_op<Handler>(
|
||||
std::forward<Handler>(handler), Clock::now(), false, this));
|
||||
boost::asio::post(
|
||||
m_ios,
|
||||
sample_op<Handler>(
|
||||
std::forward<Handler>(handler), Clock::now(), false, this));
|
||||
}
|
||||
|
||||
/** Initiate continuous i/o latency sampling.
|
||||
@@ -124,8 +127,10 @@ public:
|
||||
std::lock_guard lock(m_mutex);
|
||||
if (m_cancel)
|
||||
throw std::logic_error("io_latency_probe is canceled");
|
||||
m_ios.post(sample_op<Handler>(
|
||||
std::forward<Handler>(handler), Clock::now(), true, this));
|
||||
boost::asio::post(
|
||||
m_ios,
|
||||
sample_op<Handler>(
|
||||
std::forward<Handler>(handler), Clock::now(), true, this));
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -236,12 +241,13 @@ private:
|
||||
// The latency is too high to maintain the desired
|
||||
// period so don't bother with a timer.
|
||||
//
|
||||
m_probe->m_ios.post(
|
||||
boost::asio::post(
|
||||
m_probe->m_ios,
|
||||
sample_op<Handler>(m_handler, now, m_repeat, m_probe));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_probe->m_timer.expires_from_now(when - now);
|
||||
m_probe->m_timer.expires_after(when - now);
|
||||
m_probe->m_timer.async_wait(
|
||||
sample_op<Handler>(m_handler, now, m_repeat, m_probe));
|
||||
}
|
||||
@@ -254,7 +260,8 @@ private:
|
||||
if (!m_probe)
|
||||
return;
|
||||
typename Clock::time_point const now(Clock::now());
|
||||
m_probe->m_ios.post(
|
||||
boost::asio::post(
|
||||
m_probe->m_ios,
|
||||
sample_op<Handler>(m_handler, now, m_repeat, m_probe));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
#ifndef BEAST_TEST_YIELD_TO_HPP
|
||||
#define BEAST_TEST_YIELD_TO_HPP
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/spawn.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/thread/csbl/memory/allocator_arg.hpp>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
@@ -29,10 +31,12 @@ namespace test {
|
||||
class enable_yield_to
|
||||
{
|
||||
protected:
|
||||
boost::asio::io_service ios_;
|
||||
boost::asio::io_context ios_;
|
||||
|
||||
private:
|
||||
boost::optional<boost::asio::io_service::work> work_;
|
||||
boost::optional<boost::asio::executor_work_guard<
|
||||
boost::asio::io_context::executor_type>>
|
||||
work_;
|
||||
std::vector<std::thread> threads_;
|
||||
std::mutex m_;
|
||||
std::condition_variable cv_;
|
||||
@@ -42,7 +46,8 @@ public:
|
||||
/// The type of yield context passed to functions.
|
||||
using yield_context = boost::asio::yield_context;
|
||||
|
||||
explicit enable_yield_to(std::size_t concurrency = 1) : work_(ios_)
|
||||
explicit enable_yield_to(std::size_t concurrency = 1)
|
||||
: work_(boost::asio::make_work_guard(ios_))
|
||||
{
|
||||
threads_.reserve(concurrency);
|
||||
while (concurrency--)
|
||||
@@ -56,9 +61,9 @@ public:
|
||||
t.join();
|
||||
}
|
||||
|
||||
/// Return the `io_service` associated with the object
|
||||
boost::asio::io_service&
|
||||
get_io_service()
|
||||
/// Return the `io_context` associated with the object
|
||||
boost::asio::io_context&
|
||||
get_io_context()
|
||||
{
|
||||
return ios_;
|
||||
}
|
||||
@@ -111,13 +116,18 @@ enable_yield_to::spawn(F0&& f, FN&&... fn)
|
||||
{
|
||||
boost::asio::spawn(
|
||||
ios_,
|
||||
boost::allocator_arg,
|
||||
boost::context::fixedsize_stack(2 * 1024 * 1024),
|
||||
[&](yield_context yield) {
|
||||
f(yield);
|
||||
std::lock_guard lock{m_};
|
||||
if (--running_ == 0)
|
||||
cv_.notify_all();
|
||||
},
|
||||
boost::coroutines::attributes(2 * 1024 * 1024));
|
||||
[](std::exception_ptr e) {
|
||||
if (e)
|
||||
std::rethrow_exception(e);
|
||||
});
|
||||
spawn(fn...);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
|
||||
The argument string is available to suites and
|
||||
allows for customization of the test. Each suite
|
||||
defines its own syntax for the argument string.
|
||||
defines its own syntax for the argumnet string.
|
||||
The same argument is passed to all suites.
|
||||
*/
|
||||
void
|
||||
|
||||
@@ -32,7 +32,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
// The duplication is because Visual Studio 2019 cannot compile that header
|
||||
// even with the option -Zc:__cplusplus added.
|
||||
#define ALWAYS(cond, message, ...) assert((message) && (cond))
|
||||
#define ALWAYS_OR_UNREACHABLE(cond, message) assert((message) && (cond))
|
||||
#define ALWAYS_OR_UNREACHABLE(cond, message, ...) assert((message) && (cond))
|
||||
#define SOMETIMES(cond, message, ...)
|
||||
#define REACHABLE(message, ...)
|
||||
#define UNREACHABLE(message, ...) assert((message) && false)
|
||||
|
||||
@@ -217,7 +217,7 @@ Reader::parse(Value& root, BufferSequence const& bs)
|
||||
std::string s;
|
||||
s.reserve(buffer_size(bs));
|
||||
for (auto const& b : bs)
|
||||
s.append(buffer_cast<char const*>(b), buffer_size(b));
|
||||
s.append(static_cast<char const*>(b.data()), buffer_size(b));
|
||||
return parse(s, root);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <xrpl/json/json_forwards.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -159,9 +158,9 @@ public:
|
||||
using ArrayIndex = UInt;
|
||||
|
||||
static Value const null;
|
||||
static constexpr Int minInt = std::numeric_limits<Int>::min();
|
||||
static constexpr Int maxInt = std::numeric_limits<Int>::max();
|
||||
static constexpr UInt maxUInt = std::numeric_limits<UInt>::max();
|
||||
static Int const minInt;
|
||||
static Int const maxInt;
|
||||
static UInt const maxUInt;
|
||||
|
||||
private:
|
||||
class CZString
|
||||
@@ -264,10 +263,6 @@ public:
|
||||
bool
|
||||
asBool() const;
|
||||
|
||||
/** Correct absolute value from int or unsigned int */
|
||||
UInt
|
||||
asAbsUInt() const;
|
||||
|
||||
// TODO: What is the "empty()" method this docstring mentions?
|
||||
/** isNull() tests to see if this field is null. Don't use this method to
|
||||
test for emptiness: use empty(). */
|
||||
@@ -400,9 +395,6 @@ public:
|
||||
/// Return true if the object has a member named key.
|
||||
bool
|
||||
isMember(std::string const& key) const;
|
||||
/// Return true if the object has a member named key.
|
||||
bool
|
||||
isMember(StaticString const& key) const;
|
||||
|
||||
/// \brief Return a list of the member names.
|
||||
///
|
||||
|
||||
@@ -387,45 +387,6 @@ public:
|
||||
emptyDirDelete(Keylet const& directory);
|
||||
};
|
||||
|
||||
namespace directory {
|
||||
/** Helper functions for managing low-level directory operations.
|
||||
These are not part of the ApplyView interface.
|
||||
|
||||
Don't use them unless you really, really know what you're doing.
|
||||
Instead use dirAdd, dirInsert, etc.
|
||||
*/
|
||||
|
||||
std::uint64_t
|
||||
createRoot(
|
||||
ApplyView& view,
|
||||
Keylet const& directory,
|
||||
uint256 const& key,
|
||||
std::function<void(std::shared_ptr<SLE> const&)> const& describe);
|
||||
|
||||
auto
|
||||
findPreviousPage(ApplyView& view, Keylet const& directory, SLE::ref start);
|
||||
|
||||
std::uint64_t
|
||||
insertKey(
|
||||
ApplyView& view,
|
||||
SLE::ref node,
|
||||
std::uint64_t page,
|
||||
bool preserveOrder,
|
||||
STVector256& indexes,
|
||||
uint256 const& key);
|
||||
|
||||
std::optional<std::uint64_t>
|
||||
insertPage(
|
||||
ApplyView& view,
|
||||
std::uint64_t page,
|
||||
SLE::pointer node,
|
||||
std::uint64_t nextPage,
|
||||
SLE::ref next,
|
||||
uint256 const& key,
|
||||
Keylet const& directory,
|
||||
std::function<void(std::shared_ptr<SLE> const&)> const& describe);
|
||||
|
||||
} // namespace directory
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
@@ -243,80 +242,6 @@ isDeepFrozen(
|
||||
Currency const& currency,
|
||||
AccountID const& issuer);
|
||||
|
||||
[[nodiscard]] inline bool
|
||||
isDeepFrozen(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
Issue const& issue,
|
||||
int = 0 /*ignored*/)
|
||||
{
|
||||
return isDeepFrozen(view, account, issue.currency, issue.account);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool
|
||||
isDeepFrozen(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
MPTIssue const& mptIssue,
|
||||
int depth = 0)
|
||||
{
|
||||
// Unlike IOUs, frozen / locked MPTs are not allowed to send or receive
|
||||
// funds, so checking "deep frozen" is the same as checking "frozen".
|
||||
return isFrozen(view, account, mptIssue, depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* isFrozen check is recursive for MPT shares in a vault, descending to
|
||||
* assets in the vault, up to maxAssetCheckDepth recursion depth. This is
|
||||
* purely defensive, as we currently do not allow such vaults to be created.
|
||||
*/
|
||||
[[nodiscard]] inline bool
|
||||
isDeepFrozen(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
Asset const& asset,
|
||||
int depth = 0)
|
||||
{
|
||||
return std::visit(
|
||||
[&](auto const& issue) {
|
||||
return isDeepFrozen(view, account, issue, depth);
|
||||
},
|
||||
asset.value());
|
||||
}
|
||||
|
||||
[[nodiscard]] inline TER
|
||||
checkDeepFrozen(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
Issue const& issue)
|
||||
{
|
||||
return isDeepFrozen(view, account, issue) ? (TER)tecFROZEN
|
||||
: (TER)tesSUCCESS;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline TER
|
||||
checkDeepFrozen(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
MPTIssue const& mptIssue)
|
||||
{
|
||||
return isDeepFrozen(view, account, mptIssue) ? (TER)tecLOCKED
|
||||
: (TER)tesSUCCESS;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline TER
|
||||
checkDeepFrozen(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
Asset const& asset)
|
||||
{
|
||||
return std::visit(
|
||||
[&](auto const& issue) {
|
||||
return checkDeepFrozen(view, account, issue);
|
||||
},
|
||||
asset.value());
|
||||
}
|
||||
|
||||
[[nodiscard]] bool
|
||||
isLPTokenFrozen(
|
||||
ReadView const& view,
|
||||
@@ -362,49 +287,6 @@ accountHolds(
|
||||
AuthHandling zeroIfUnauthorized,
|
||||
beast::Journal j);
|
||||
|
||||
// Returns the amount an account can spend total.
|
||||
//
|
||||
// These functions use accountHolds, but unlike accountHolds:
|
||||
// * The account can go into debt.
|
||||
// * If the account is the asset issuer the only limit is defined by the asset /
|
||||
// issuance.
|
||||
//
|
||||
// <-- saAmount: amount of currency held by account. May be negative.
|
||||
[[nodiscard]] STAmount
|
||||
accountSpendable(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
Currency const& currency,
|
||||
AccountID const& issuer,
|
||||
FreezeHandling zeroIfFrozen,
|
||||
beast::Journal j);
|
||||
|
||||
[[nodiscard]] STAmount
|
||||
accountSpendable(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
Issue const& issue,
|
||||
FreezeHandling zeroIfFrozen,
|
||||
beast::Journal j);
|
||||
|
||||
[[nodiscard]] STAmount
|
||||
accountSpendable(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
MPTIssue const& mptIssue,
|
||||
FreezeHandling zeroIfFrozen,
|
||||
AuthHandling zeroIfUnauthorized,
|
||||
beast::Journal j);
|
||||
|
||||
[[nodiscard]] STAmount
|
||||
accountSpendable(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
Asset const& asset,
|
||||
FreezeHandling zeroIfFrozen,
|
||||
AuthHandling zeroIfUnauthorized,
|
||||
beast::Journal j);
|
||||
|
||||
// Returns the amount an account can spend of the currency type saDefault, or
|
||||
// returns saDefault if this account is the issuer of the currency in
|
||||
// question. Should be used in favor of accountHolds when questioning how much
|
||||
@@ -651,11 +533,7 @@ dirNext(
|
||||
describeOwnerDir(AccountID const& account);
|
||||
|
||||
[[nodiscard]] TER
|
||||
dirLink(
|
||||
ApplyView& view,
|
||||
AccountID const& owner,
|
||||
std::shared_ptr<SLE>& object,
|
||||
SF_UINT64 const& node = sfOwnerNode);
|
||||
dirLink(ApplyView& view, AccountID const& owner, std::shared_ptr<SLE>& object);
|
||||
|
||||
AccountID
|
||||
pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey);
|
||||
@@ -674,17 +552,14 @@ createPseudoAccount(
|
||||
uint256 const& pseudoOwnerKey,
|
||||
SField const& ownerField);
|
||||
|
||||
// Returns true iff sleAcct is a pseudo-account or specific
|
||||
// pseudo-accounts in pseudoFieldFilter.
|
||||
// Returns true iff sleAcct is a pseudo-account.
|
||||
//
|
||||
// Returns false if sleAcct is
|
||||
// * NOT a pseudo-account OR
|
||||
// * NOT a ltACCOUNT_ROOT OR
|
||||
// * null pointer
|
||||
[[nodiscard]] bool
|
||||
isPseudoAccount(
|
||||
std::shared_ptr<SLE const> sleAcct,
|
||||
std::set<SField const*> const& pseudoFieldFilter = {});
|
||||
isPseudoAccount(std::shared_ptr<SLE const> sleAcct);
|
||||
|
||||
// Returns the list of fields that define an ACCOUNT_ROOT as a pseudo-account if
|
||||
// set
|
||||
@@ -698,91 +573,14 @@ isPseudoAccount(
|
||||
getPseudoAccountFields();
|
||||
|
||||
[[nodiscard]] inline bool
|
||||
isPseudoAccount(
|
||||
ReadView const& view,
|
||||
AccountID const& accountId,
|
||||
std::set<SField const*> const& pseudoFieldFilter = {})
|
||||
isPseudoAccount(ReadView const& view, AccountID accountId)
|
||||
{
|
||||
return isPseudoAccount(
|
||||
view.read(keylet::account(accountId)), pseudoFieldFilter);
|
||||
return isPseudoAccount(view.read(keylet::account(accountId)));
|
||||
}
|
||||
|
||||
[[nodiscard]] TER
|
||||
canAddHolding(ReadView const& view, Asset const& asset);
|
||||
|
||||
/** Validates that the destination SLE and tag are valid
|
||||
|
||||
- Checks that the SLE is not null.
|
||||
- If the SLE requires a destination tag, checks that there is a tag.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkDestinationAndTag(SLE::const_ref toSle, bool hasDestinationTag);
|
||||
|
||||
/** Checks that can withdraw funds from an object to itself or a destination.
|
||||
*
|
||||
* The receiver may be either the submitting account (sfAccount) or a different
|
||||
* destination account (sfDestination).
|
||||
*
|
||||
* - Checks that the receiver account exists.
|
||||
* - If the receiver requires a destination tag, check that one exists, even
|
||||
* if withdrawing to self.
|
||||
* - If withdrawing to self, succeed.
|
||||
* - If not, checks if the receiver requires deposit authorization, and if
|
||||
* the sender has it.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
canWithdraw(
|
||||
AccountID const& from,
|
||||
ReadView const& view,
|
||||
AccountID const& to,
|
||||
SLE::const_ref toSle,
|
||||
bool hasDestinationTag);
|
||||
|
||||
/** Checks that can withdraw funds from an object to itself or a destination.
|
||||
*
|
||||
* The receiver may be either the submitting account (sfAccount) or a different
|
||||
* destination account (sfDestination).
|
||||
*
|
||||
* - Checks that the receiver account exists.
|
||||
* - If the receiver requires a destination tag, check that one exists, even
|
||||
* if withdrawing to self.
|
||||
* - If withdrawing to self, succeed.
|
||||
* - If not, checks if the receiver requires deposit authorization, and if
|
||||
* the sender has it.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
canWithdraw(
|
||||
AccountID const& from,
|
||||
ReadView const& view,
|
||||
AccountID const& to,
|
||||
bool hasDestinationTag);
|
||||
|
||||
/** Checks that can withdraw funds from an object to itself or a destination.
|
||||
*
|
||||
* The receiver may be either the submitting account (sfAccount) or a different
|
||||
* destination account (sfDestination).
|
||||
*
|
||||
* - Checks that the receiver account exists.
|
||||
* - If the receiver requires a destination tag, check that one exists, even
|
||||
* if withdrawing to self.
|
||||
* - If withdrawing to self, succeed.
|
||||
* - If not, checks if the receiver requires deposit authorization, and if
|
||||
* the sender has it.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
canWithdraw(ReadView const& view, STTx const& tx);
|
||||
|
||||
[[nodiscard]] TER
|
||||
doWithdraw(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& senderAcct,
|
||||
AccountID const& dstAcct,
|
||||
AccountID const& sourceAcct,
|
||||
XRPAmount priorBalance,
|
||||
STAmount const& amount,
|
||||
beast::Journal j);
|
||||
|
||||
/// Any transactors that call addEmptyHolding() in doApply must call
|
||||
/// canAddHolding() in preflight with the same View and Asset
|
||||
[[nodiscard]] TER
|
||||
@@ -952,22 +750,6 @@ accountSend(
|
||||
beast::Journal j,
|
||||
WaiveTransferFee waiveFee = WaiveTransferFee::No);
|
||||
|
||||
using MultiplePaymentDestinations = std::vector<std::pair<AccountID, Number>>;
|
||||
/** Like accountSend, except one account is sending multiple payments (with the
|
||||
* same asset!) simultaneously
|
||||
*
|
||||
* Calls static accountSendMultiIOU if saAmount represents Issue.
|
||||
* Calls static accountSendMultiMPT if saAmount represents MPTIssue.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
accountSendMulti(
|
||||
ApplyView& view,
|
||||
AccountID const& senderID,
|
||||
Asset const& asset,
|
||||
MultiplePaymentDestinations const& receivers,
|
||||
beast::Journal j,
|
||||
WaiveTransferFee waiveFee = WaiveTransferFee::No);
|
||||
|
||||
[[nodiscard]] TER
|
||||
issueIOU(
|
||||
ApplyView& view,
|
||||
@@ -1039,8 +821,7 @@ requireAuth(
|
||||
* purely defensive, as we currently do not allow such vaults to be created.
|
||||
*
|
||||
* If StrongAuth then return tecNO_AUTH if MPToken doesn't exist or
|
||||
* lsfMPTRequireAuth is set and MPToken is not authorized. Vault and LoanBroker
|
||||
* pseudo-accounts are implicitly authorized.
|
||||
* lsfMPTRequireAuth is set and MPToken is not authorized.
|
||||
*
|
||||
* If WeakAuth then return tecNO_AUTH if lsfMPTRequireAuth is set and MPToken
|
||||
* doesn't exist or is not authorized (explicitly or via credentials, if
|
||||
@@ -1113,26 +894,6 @@ canTransfer(
|
||||
AccountID const& from,
|
||||
AccountID const& to);
|
||||
|
||||
[[nodiscard]] TER
|
||||
canTransfer(
|
||||
ReadView const& view,
|
||||
Issue const& issue,
|
||||
AccountID const& from,
|
||||
AccountID const& to);
|
||||
|
||||
[[nodiscard]] TER inline canTransfer(
|
||||
ReadView const& view,
|
||||
Asset const& asset,
|
||||
AccountID const& from,
|
||||
AccountID const& to)
|
||||
{
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) -> TER {
|
||||
return canTransfer(view, issue, from, to);
|
||||
},
|
||||
asset.value());
|
||||
}
|
||||
|
||||
/** Deleter function prototype. Returns the status of the entry deletion
|
||||
* (if should not be skipped) and if the entry should be skipped. The status
|
||||
* is always tesSUCCESS if the entry should be skipped.
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
|
||||
public:
|
||||
AutoSocket(
|
||||
boost::asio::io_service& s,
|
||||
boost::asio::io_context& s,
|
||||
boost::asio::ssl::context& c,
|
||||
bool secureOnly,
|
||||
bool plainOnly)
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
mSocket = std::make_unique<ssl_socket>(s, c);
|
||||
}
|
||||
|
||||
AutoSocket(boost::asio::io_service& s, boost::asio::ssl::context& c)
|
||||
AutoSocket(boost::asio::io_context& s, boost::asio::ssl::context& c)
|
||||
: AutoSocket(s, c, false, false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <xrpl/basics/ByteUtilities.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
|
||||
#include <chrono>
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
|
||||
static void
|
||||
get(bool bSSL,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::io_context& io_context,
|
||||
std::deque<std::string> deqSites,
|
||||
unsigned short const port,
|
||||
std::string const& strPath,
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
|
||||
static void
|
||||
get(bool bSSL,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::io_context& io_context,
|
||||
std::string strSite,
|
||||
unsigned short const port,
|
||||
std::string const& strPath,
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
static void
|
||||
request(
|
||||
bool bSSL,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::io_context& io_context,
|
||||
std::string strSite,
|
||||
unsigned short const port,
|
||||
std::function<
|
||||
|
||||
@@ -153,7 +153,7 @@ public:
|
||||
{
|
||||
strm.set_verify_callback(
|
||||
std::bind(
|
||||
&rfc2818_verify,
|
||||
&rfc6125_verify,
|
||||
host,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2,
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief callback invoked for name verification - just passes through
|
||||
* to the asio rfc2818 implementation.
|
||||
* to the asio `host_name_verification` (rfc6125) implementation.
|
||||
*
|
||||
* @param domain hostname expected
|
||||
* @param preverified passed by implementation
|
||||
@@ -175,13 +175,13 @@ public:
|
||||
* @param j journal for logging
|
||||
*/
|
||||
static bool
|
||||
rfc2818_verify(
|
||||
rfc6125_verify(
|
||||
std::string const& domain,
|
||||
bool preverified,
|
||||
boost::asio::ssl::verify_context& ctx,
|
||||
beast::Journal j)
|
||||
{
|
||||
if (boost::asio::ssl::rfc2818_verification(domain)(preverified, ctx))
|
||||
if (boost::asio::ssl::host_name_verification(domain)(preverified, ctx))
|
||||
return true;
|
||||
|
||||
JLOG(j.warn()) << "Outbound SSL connection to " << domain
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_NODESTORE_BACKEND_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_BACKEND_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Types.h>
|
||||
#include <xrpl/nodestore/Types.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@@ -53,6 +53,14 @@ public:
|
||||
virtual std::string
|
||||
getName() = 0;
|
||||
|
||||
/** Get the block size for backends that support it
|
||||
*/
|
||||
virtual std::optional<std::size_t>
|
||||
getBlockSize() const
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/** Open the backend.
|
||||
@param createIfMissing Create the database files if necessary.
|
||||
This allows the caller to catch exceptions.
|
||||
@@ -20,13 +20,12 @@
|
||||
#ifndef RIPPLE_NODESTORE_DATABASE_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_DATABASE_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Backend.h>
|
||||
#include <xrpld/nodestore/NodeObject.h>
|
||||
#include <xrpld/nodestore/Scheduler.h>
|
||||
|
||||
#include <xrpl/basics/BasicConfig.h>
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/TaggedCache.ipp>
|
||||
#include <xrpl/nodestore/Backend.h>
|
||||
#include <xrpl/nodestore/NodeObject.h>
|
||||
#include <xrpl/nodestore/Scheduler.h>
|
||||
#include <xrpl/protocol/SystemParameters.h>
|
||||
|
||||
#include <condition_variable>
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_NODESTORE_DATABASEROTATING_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_DATABASEROTATING_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Database.h>
|
||||
#include <xrpl/nodestore/Database.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace NodeStore {
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_NODESTORE_DUMMYSCHEDULER_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_DUMMYSCHEDULER_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Scheduler.h>
|
||||
#include <xrpl/nodestore/Scheduler.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace NodeStore {
|
||||
@@ -20,11 +20,10 @@
|
||||
#ifndef RIPPLE_NODESTORE_FACTORY_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_FACTORY_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Backend.h>
|
||||
#include <xrpld/nodestore/Scheduler.h>
|
||||
|
||||
#include <xrpl/basics/BasicConfig.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/nodestore/Backend.h>
|
||||
#include <xrpl/nodestore/Scheduler.h>
|
||||
|
||||
#include <nudb/store.hpp>
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef RIPPLE_NODESTORE_MANAGER_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_MANAGER_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/DatabaseRotating.h>
|
||||
#include <xrpld/nodestore/Factory.h>
|
||||
#include <xrpl/nodestore/DatabaseRotating.h>
|
||||
#include <xrpl/nodestore/Factory.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_NODESTORE_SCHEDULER_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_SCHEDULER_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Task.h>
|
||||
#include <xrpl/nodestore/Task.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_NODESTORE_TYPES_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_TYPES_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/NodeObject.h>
|
||||
#include <xrpl/nodestore/NodeObject.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
#ifndef RIPPLE_NODESTORE_BATCHWRITER_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_BATCHWRITER_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Scheduler.h>
|
||||
#include <xrpld/nodestore/Task.h>
|
||||
#include <xrpld/nodestore/Types.h>
|
||||
#include <xrpl/nodestore/Scheduler.h>
|
||||
#include <xrpl/nodestore/Task.h>
|
||||
#include <xrpl/nodestore/Types.h>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
@@ -20,10 +20,9 @@
|
||||
#ifndef RIPPLE_NODESTORE_DATABASENODEIMP_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_DATABASENODEIMP_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Database.h>
|
||||
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/nodestore/Database.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace NodeStore {
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_NODESTORE_DATABASEROTATINGIMP_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_DATABASEROTATINGIMP_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/DatabaseRotating.h>
|
||||
#include <xrpl/nodestore/DatabaseRotating.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_NODESTORE_DECODEDBLOB_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_DECODEDBLOB_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/NodeObject.h>
|
||||
#include <xrpl/nodestore/NodeObject.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace NodeStore {
|
||||
@@ -20,9 +20,8 @@
|
||||
#ifndef RIPPLE_NODESTORE_ENCODEDBLOB_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_ENCODEDBLOB_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/NodeObject.h>
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/nodestore/NodeObject.h>
|
||||
|
||||
#include <boost/align/align_up.hpp>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_NODESTORE_MANAGERIMP_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_MANAGERIMP_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Manager.h>
|
||||
#include <xrpl/nodestore/Manager.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
static void
|
||||
missing_backend();
|
||||
|
||||
ManagerImp() = default;
|
||||
ManagerImp();
|
||||
|
||||
~ManagerImp() = default;
|
||||
|
||||
@@ -23,11 +23,10 @@
|
||||
// Disable lz4 deprecation warning due to incompatibility with clang attributes
|
||||
#define LZ4_DISABLE_DEPRECATE_WARNINGS
|
||||
|
||||
#include <xrpld/nodestore/NodeObject.h>
|
||||
#include <xrpld/nodestore/detail/varint.h>
|
||||
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
#include <xrpl/nodestore/NodeObject.h>
|
||||
#include <xrpl/nodestore/detail/varint.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
|
||||
#include <nudb/detail/field.hpp>
|
||||
@@ -20,6 +20,11 @@
|
||||
#ifndef RIPPLE_PROTOCOL_APIVERSION_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_APIVERSION_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/core/SemanticVersion.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
@@ -72,6 +77,77 @@ static_assert(apiMaximumSupportedVersion >= apiMinimumSupportedVersion);
|
||||
static_assert(apiBetaVersion >= apiMaximumSupportedVersion);
|
||||
static_assert(apiMaximumValidVersion >= apiMaximumSupportedVersion);
|
||||
|
||||
template <class JsonObject>
|
||||
void
|
||||
setVersion(JsonObject& parent, unsigned int apiVersion, bool betaEnabled)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
apiVersion != apiInvalidVersion,
|
||||
"ripple::RPC::setVersion : input is valid");
|
||||
auto& retObj = addObject(parent, jss::version);
|
||||
|
||||
if (apiVersion == apiVersionIfUnspecified)
|
||||
{
|
||||
// API version numbers used in API version 1
|
||||
static beast::SemanticVersion const firstVersion{"1.0.0"};
|
||||
static beast::SemanticVersion const goodVersion{"1.0.0"};
|
||||
static beast::SemanticVersion const lastVersion{"1.0.0"};
|
||||
|
||||
retObj[jss::first] = firstVersion.print();
|
||||
retObj[jss::good] = goodVersion.print();
|
||||
retObj[jss::last] = lastVersion.print();
|
||||
}
|
||||
else
|
||||
{
|
||||
retObj[jss::first] = apiMinimumSupportedVersion.value;
|
||||
retObj[jss::last] =
|
||||
betaEnabled ? apiBetaVersion : apiMaximumSupportedVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the api version number from the json value
|
||||
*
|
||||
* Note that APIInvalidVersion will be returned if
|
||||
* 1) the version number field has a wrong format
|
||||
* 2) the version number retrieved is out of the supported range
|
||||
* 3) the version number is unspecified and
|
||||
* APIVersionIfUnspecified is out of the supported range
|
||||
*
|
||||
* @param jv a Json value that may or may not specifies
|
||||
* the api version number
|
||||
* @param betaEnabled if the beta API version is enabled
|
||||
* @return the api version number
|
||||
*/
|
||||
inline unsigned int
|
||||
getAPIVersionNumber(Json::Value const& jv, bool betaEnabled)
|
||||
{
|
||||
static Json::Value const minVersion(RPC::apiMinimumSupportedVersion);
|
||||
Json::Value const maxVersion(
|
||||
betaEnabled ? RPC::apiBetaVersion : RPC::apiMaximumSupportedVersion);
|
||||
|
||||
if (jv.isObject())
|
||||
{
|
||||
if (jv.isMember(jss::api_version))
|
||||
{
|
||||
auto const specifiedVersion = jv[jss::api_version];
|
||||
if (!specifiedVersion.isInt() && !specifiedVersion.isUInt())
|
||||
{
|
||||
return RPC::apiInvalidVersion;
|
||||
}
|
||||
auto const specifiedVersionInt = specifiedVersion.asInt();
|
||||
if (specifiedVersionInt < minVersion ||
|
||||
specifiedVersionInt > maxVersion)
|
||||
{
|
||||
return RPC::apiInvalidVersion;
|
||||
}
|
||||
return specifiedVersionInt;
|
||||
}
|
||||
}
|
||||
|
||||
return RPC::apiVersionIfUnspecified;
|
||||
}
|
||||
|
||||
} // namespace RPC
|
||||
|
||||
template <unsigned minVer, unsigned maxVer, typename Fn, typename... Args>
|
||||
|
||||
@@ -100,27 +100,7 @@ public:
|
||||
bool
|
||||
native() const
|
||||
{
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
return issue.native();
|
||||
if constexpr (std::is_same_v<TIss, MPTIssue>)
|
||||
return false;
|
||||
},
|
||||
issue_);
|
||||
}
|
||||
|
||||
bool
|
||||
integral() const
|
||||
{
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
return issue.native();
|
||||
if constexpr (std::is_same_v<TIss, MPTIssue>)
|
||||
return true;
|
||||
},
|
||||
issue_);
|
||||
return holds<Issue>() && get<Issue>().native();
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
|
||||
180
include/xrpl/protocol/ConfidentialTransfer.h
Normal file
180
include/xrpl/protocol/ConfidentialTransfer.h
Normal file
@@ -0,0 +1,180 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2025 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_CONFIDENTIALTRANSFER_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_CONFIDENTIALTRANSFER_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/Rate.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/detail/secp256k1.h>
|
||||
|
||||
#include <secp256k1.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/**
|
||||
* @brief Generates a new secp256k1 key pair.
|
||||
*/
|
||||
SECP256K1_API int
|
||||
secp256k1_elgamal_generate_keypair(
|
||||
secp256k1_context const* ctx,
|
||||
unsigned char* privkey,
|
||||
secp256k1_pubkey* pubkey);
|
||||
|
||||
/**
|
||||
* @brief Encrypts a 64-bit amount using ElGamal.
|
||||
*/
|
||||
SECP256K1_API int
|
||||
secp256k1_elgamal_encrypt(
|
||||
secp256k1_context const* ctx,
|
||||
secp256k1_pubkey* c1,
|
||||
secp256k1_pubkey* c2,
|
||||
secp256k1_pubkey const* pubkey_Q,
|
||||
uint64_t amount,
|
||||
unsigned char const* blinding_factor);
|
||||
|
||||
/**
|
||||
* @brief Decrypts an ElGamal ciphertext to recover the amount.
|
||||
*/
|
||||
SECP256K1_API int
|
||||
secp256k1_elgamal_decrypt(
|
||||
secp256k1_context const* ctx,
|
||||
uint64_t* amount,
|
||||
secp256k1_pubkey const* c1,
|
||||
secp256k1_pubkey const* c2,
|
||||
unsigned char const* privkey);
|
||||
|
||||
/**
|
||||
* @brief Homomorphically adds two ElGamal ciphertexts.
|
||||
*/
|
||||
SECP256K1_API int
|
||||
secp256k1_elgamal_add(
|
||||
secp256k1_context const* ctx,
|
||||
secp256k1_pubkey* sum_c1,
|
||||
secp256k1_pubkey* sum_c2,
|
||||
secp256k1_pubkey const* a_c1,
|
||||
secp256k1_pubkey const* a_c2,
|
||||
secp256k1_pubkey const* b_c1,
|
||||
secp256k1_pubkey const* b_c2);
|
||||
|
||||
/**
|
||||
* @brief Homomorphically subtracts two ElGamal ciphertexts.
|
||||
*/
|
||||
SECP256K1_API int
|
||||
secp256k1_elgamal_subtract(
|
||||
secp256k1_context const* ctx,
|
||||
secp256k1_pubkey* diff_c1,
|
||||
secp256k1_pubkey* diff_c2,
|
||||
secp256k1_pubkey const* a_c1,
|
||||
secp256k1_pubkey const* a_c2,
|
||||
secp256k1_pubkey const* b_c1,
|
||||
secp256k1_pubkey const* b_c2);
|
||||
|
||||
/**
|
||||
* @brief Generates the canonical encrypted zero for a given MPT token instance.
|
||||
*
|
||||
* This ciphertext represents a zero balance for a specific account's holding
|
||||
* of a token defined by its MPTokenIssuanceID.
|
||||
*
|
||||
* @param[in] ctx A pointer to a valid secp256k1 context.
|
||||
* @param[out] enc_zero_c1 The C1 component of the canonical ciphertext.
|
||||
* @param[out] enc_zero_c2 The C2 component of the canonical ciphertext.
|
||||
* @param[in] pubkey The ElGamal public key of the account holder.
|
||||
* @param[in] account_id A pointer to the 20-byte AccountID.
|
||||
* @param[in] mpt_issuance_id A pointer to the 24-byte MPTokenIssuanceID.
|
||||
*
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
SECP256K1_API int
|
||||
generate_canonical_encrypted_zero(
|
||||
secp256k1_context const* ctx,
|
||||
secp256k1_pubkey* enc_zero_c1,
|
||||
secp256k1_pubkey* enc_zero_c2,
|
||||
secp256k1_pubkey const* pubkey,
|
||||
unsigned char const* account_id, // 20 bytes
|
||||
unsigned char const* mpt_issuance_id // 24 bytes
|
||||
);
|
||||
|
||||
// breaks a 66-byte encrypted amount into two 33-byte components
|
||||
// then parses each 33-byte component into 64-byte secp256k1_pubkey format
|
||||
bool
|
||||
makeEcPair(Slice const& buffer, secp256k1_pubkey& out1, secp256k1_pubkey& out2);
|
||||
|
||||
// serialize two secp256k1_pubkey components back into compressed 66-byte form
|
||||
bool
|
||||
serializeEcPair(
|
||||
secp256k1_pubkey const& in1,
|
||||
secp256k1_pubkey const& in2,
|
||||
Buffer& buffer);
|
||||
|
||||
/**
|
||||
* @brief Verifies that a buffer contains two valid, parsable EC public keys.
|
||||
* @param buffer The input buffer containing two concatenated components.
|
||||
* @return true if both components can be parsed successfully, false otherwise.
|
||||
*/
|
||||
bool
|
||||
isValidCiphertext(Slice const& buffer);
|
||||
|
||||
TER
|
||||
homomorphicAdd(Slice const& a, Slice const& b, Buffer& out);
|
||||
|
||||
TER
|
||||
homomorphicSubtract(Slice const& a, Slice const& b, Buffer& out);
|
||||
|
||||
TER
|
||||
proveEquality(
|
||||
Slice const& proof,
|
||||
Slice const& encAmt, // encrypted amount
|
||||
Slice const& pubkey,
|
||||
uint64_t const amount,
|
||||
uint256 const& txHash, // Transaction context data
|
||||
std::uint32_t const spendVersion);
|
||||
|
||||
Buffer
|
||||
encryptAmount(uint64_t amt, Slice const& pubKeySlice);
|
||||
|
||||
Buffer
|
||||
encryptCanonicalZeroAmount(
|
||||
Slice const& pubKeySlice,
|
||||
AccountID const& account,
|
||||
MPTID const& mptId);
|
||||
|
||||
TER
|
||||
verifyConfidentialSendProof(
|
||||
Slice const& proof,
|
||||
Slice const& encSenderBalance,
|
||||
Slice const& encSenderAmt,
|
||||
Slice const& encDestAmt,
|
||||
Slice const& encIssuerAmt,
|
||||
Slice const& senderPubKey,
|
||||
Slice const& destPubKey,
|
||||
Slice const& issuerPubKey,
|
||||
std::uint32_t const version,
|
||||
uint256 const& txHash);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
@@ -346,24 +346,6 @@ vault(uint256 const& vaultKey)
|
||||
return {ltVAULT, vaultKey};
|
||||
}
|
||||
|
||||
Keylet
|
||||
loanbroker(AccountID const& owner, std::uint32_t seq) noexcept;
|
||||
|
||||
inline Keylet
|
||||
loanbroker(uint256 const& key)
|
||||
{
|
||||
return {ltLOAN_BROKER, key};
|
||||
}
|
||||
|
||||
Keylet
|
||||
loan(uint256 const& loanBrokerID, std::uint32_t loanSeq) noexcept;
|
||||
|
||||
inline Keylet
|
||||
loan(uint256 const& key)
|
||||
{
|
||||
return {ltLOAN, key};
|
||||
}
|
||||
|
||||
Keylet
|
||||
permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept;
|
||||
|
||||
|
||||
@@ -187,6 +187,7 @@ enum LedgerSpecificFlags {
|
||||
lsfMPTCanTrade = 0x00000010,
|
||||
lsfMPTCanTransfer = 0x00000020,
|
||||
lsfMPTCanClawback = 0x00000040,
|
||||
lsfMPTNoConfidentialTransfer = 0x00000080,
|
||||
|
||||
lsmfMPTCanMutateCanLock = 0x00000002,
|
||||
lsmfMPTCanMutateRequireAuth = 0x00000004,
|
||||
@@ -205,11 +206,6 @@ enum LedgerSpecificFlags {
|
||||
|
||||
// ltVAULT
|
||||
lsfVaultPrivate = 0x00010000,
|
||||
|
||||
// ltLOAN
|
||||
lsfLoanDefault = 0x00010000,
|
||||
lsfLoanImpaired = 0x00020000,
|
||||
lsfLoanOverpayment = 0x00040000, // True, loan allows overpayments
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <xrpl/basics/ByteUtilities.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/protocol/Units.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@@ -85,140 +84,6 @@ std::size_t constexpr maxDeletableTokenOfferEntries = 500;
|
||||
*/
|
||||
std::uint16_t constexpr maxTransferFee = 50000;
|
||||
|
||||
/** There are 10,000 basis points (bips) in 100%.
|
||||
*
|
||||
* Basis points represent 0.01%.
|
||||
*
|
||||
* Given a value X, to find the amount for B bps,
|
||||
* use X * B / bipsPerUnity
|
||||
*
|
||||
* Example: If a loan broker has 999 XRP of debt, and must maintain 1,000 bps of
|
||||
* that debt as cover (10%), then the minimum cover amount is 999,000,000 drops
|
||||
* * 1000 / bipsPerUnity = 99,900,00 drops or 99.9 XRP.
|
||||
*
|
||||
* Given a percentage P, to find the number of bps that percentage represents,
|
||||
* use P * bipsPerUnity.
|
||||
*
|
||||
* Example: 50% is 0.50 * bipsPerUnity = 5,000 bps.
|
||||
*/
|
||||
Bips32 constexpr bipsPerUnity(100 * 100);
|
||||
static_assert(bipsPerUnity == Bips32{10'000});
|
||||
TenthBips32 constexpr tenthBipsPerUnity(bipsPerUnity.value() * 10);
|
||||
static_assert(tenthBipsPerUnity == TenthBips32(100'000));
|
||||
|
||||
constexpr Bips32
|
||||
percentageToBips(std::uint32_t percentage)
|
||||
{
|
||||
return Bips32(percentage * bipsPerUnity.value() / 100);
|
||||
}
|
||||
constexpr TenthBips32
|
||||
percentageToTenthBips(std::uint32_t percentage)
|
||||
{
|
||||
return TenthBips32(percentage * tenthBipsPerUnity.value() / 100);
|
||||
}
|
||||
template <typename T, class TBips>
|
||||
constexpr T
|
||||
bipsOfValue(T value, Bips<TBips> bips)
|
||||
{
|
||||
return value * bips.value() / bipsPerUnity.value();
|
||||
}
|
||||
template <typename T, class TBips>
|
||||
constexpr T
|
||||
tenthBipsOfValue(T value, TenthBips<TBips> bips)
|
||||
{
|
||||
return value * bips.value() / tenthBipsPerUnity.value();
|
||||
}
|
||||
|
||||
namespace Lending {
|
||||
/** The maximum management fee rate allowed by a loan broker in 1/10 bips.
|
||||
|
||||
Valid values are between 0 and 10% inclusive.
|
||||
*/
|
||||
TenthBips16 constexpr maxManagementFeeRate(
|
||||
unsafe_cast<std::uint16_t>(percentageToTenthBips(10).value()));
|
||||
static_assert(maxManagementFeeRate == TenthBips16(std::uint16_t(10'000u)));
|
||||
|
||||
/** The maximum coverage rate required of a loan broker in 1/10 bips.
|
||||
|
||||
Valid values are between 0 and 100% inclusive.
|
||||
*/
|
||||
TenthBips32 constexpr maxCoverRate = percentageToTenthBips(100);
|
||||
static_assert(maxCoverRate == TenthBips32(100'000u));
|
||||
|
||||
/** The maximum overpayment fee on a loan in 1/10 bips.
|
||||
*
|
||||
Valid values are between 0 and 100% inclusive.
|
||||
*/
|
||||
TenthBips32 constexpr maxOverpaymentFee = percentageToTenthBips(100);
|
||||
static_assert(maxOverpaymentFee == TenthBips32(100'000u));
|
||||
|
||||
/** Annualized interest rate of the Loan in 1/10 bips.
|
||||
*
|
||||
* Valid values are between 0 and 100% inclusive.
|
||||
*/
|
||||
TenthBips32 constexpr maxInterestRate = percentageToTenthBips(100);
|
||||
static_assert(maxInterestRate == TenthBips32(100'000u));
|
||||
|
||||
/** The maximum premium added to the interest rate for late payments on a loan
|
||||
* in 1/10 bips.
|
||||
*
|
||||
* Valid values are between 0 and 100% inclusive.
|
||||
*/
|
||||
TenthBips32 constexpr maxLateInterestRate = percentageToTenthBips(100);
|
||||
static_assert(maxLateInterestRate == TenthBips32(100'000u));
|
||||
|
||||
/** The maximum close interest rate charged for repaying a loan early in 1/10
|
||||
* bips.
|
||||
*
|
||||
* Valid values are between 0 and 100% inclusive.
|
||||
*/
|
||||
TenthBips32 constexpr maxCloseInterestRate = percentageToTenthBips(100);
|
||||
static_assert(maxCloseInterestRate == TenthBips32(100'000u));
|
||||
|
||||
/** The maximum overpayment interest rate charged on loan overpayments in 1/10
|
||||
* bips.
|
||||
*
|
||||
* Valid values are between 0 and 100% inclusive.
|
||||
*/
|
||||
TenthBips32 constexpr maxOverpaymentInterestRate = percentageToTenthBips(100);
|
||||
static_assert(maxOverpaymentInterestRate == TenthBips32(100'000u));
|
||||
|
||||
/** LoanPay transaction cost will be one base fee per X combined payments
|
||||
*
|
||||
* The number of payments is estimated based on the Amount paid and the Loan's
|
||||
* Fixed Payment size. Overpayments (indicated with the tfLoanOverpayment flag)
|
||||
* count as one more payment.
|
||||
*
|
||||
* This number was chosen arbitrarily, but should not be changed once released
|
||||
* without an amendment
|
||||
*/
|
||||
static constexpr int loanPaymentsPerFeeIncrement = 5;
|
||||
|
||||
/** Maximum number of combined payments that a LoanPay transaction will process
|
||||
*
|
||||
* This limit is enforced during the loan payment process, and thus is not
|
||||
* estimated. If the limit is hit, no further payments or overpayments will be
|
||||
* processed, no matter how much of the transation Amount is left, but the
|
||||
* transaction will succeed with the payments that have been processed up to
|
||||
* that point.
|
||||
*
|
||||
* This limit is independent of loanPaymentsPerFeeIncrement, so a transaction
|
||||
* could potentially be charged for many more payments than actually get
|
||||
* processed. Users should take care not to submit a transaction paying more
|
||||
* than loanMaximumPaymentsPerTransaction * Loan.PeriodicPayment. Because
|
||||
* overpayments are charged as a payment, if submitting
|
||||
* loanMaximumPaymentsPerTransaction * Loan.PeriodicPayment, users should not
|
||||
* set the tfLoanOverpayment flag.
|
||||
*
|
||||
* Even though they're independent, loanMaximumPaymentsPerTransaction should be
|
||||
* a multiple of loanPaymentsPerFeeIncrement.
|
||||
*
|
||||
* This number was chosen arbitrarily, but should not be changed once released
|
||||
* without an amendment
|
||||
*/
|
||||
static constexpr int loanMaximumPaymentsPerTransaction = 100;
|
||||
} // namespace Lending
|
||||
|
||||
/** The maximum length of a URI inside an NFT */
|
||||
std::size_t constexpr maxTokenURILength = 256;
|
||||
|
||||
@@ -316,6 +181,20 @@ std::size_t constexpr permissionMaxSize = 10;
|
||||
/** The maximum number of transactions that can be in a batch. */
|
||||
std::size_t constexpr maxBatchTxCount = 8;
|
||||
|
||||
/** EC ElGamal ciphertext length 33-byte */
|
||||
std::size_t constexpr ecGamalEncryptedLength = 33;
|
||||
|
||||
/** EC ElGamal ciphertext length: two 33-byte components concatenated */
|
||||
std::size_t constexpr ecGamalEncryptedTotalLength = 66;
|
||||
|
||||
/** Length of equality ZKProof */
|
||||
std::size_t constexpr ecEqualityProofLength = 98;
|
||||
|
||||
/** Length of EC public key */
|
||||
std::size_t constexpr ecPubKeyLength = 64;
|
||||
|
||||
/** Length of EC private key */
|
||||
std::size_t constexpr ecPrivKeyLength = 32;
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define RIPPLE_PROTOCOL_PUBLICKEY_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/beast/net/IPEndpoint.h>
|
||||
#include <xrpl/protocol/KeyType.h>
|
||||
#include <xrpl/protocol/STExchange.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
@@ -264,6 +265,24 @@ calcNodeID(PublicKey const&);
|
||||
AccountID
|
||||
calcAccountID(PublicKey const& pk);
|
||||
|
||||
inline std::string
|
||||
getFingerprint(
|
||||
beast::IP::Endpoint const& address,
|
||||
std::optional<PublicKey> const& publicKey = std::nullopt,
|
||||
std::optional<std::string> const& id = std::nullopt)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "IP Address: " << address;
|
||||
if (publicKey.has_value())
|
||||
{
|
||||
ss << ", Public Key: " << toBase58(TokenType::NodePublic, *publicKey);
|
||||
}
|
||||
if (id.has_value())
|
||||
{
|
||||
ss << ", Id: " << id.value();
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
} // namespace ripple
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -139,8 +139,8 @@ field_code(int id, int index)
|
||||
SFields are created at compile time.
|
||||
|
||||
Each SField, once constructed, lives until program termination, and there
|
||||
is only one instance per fieldType/fieldValue pair which serves the
|
||||
entire application.
|
||||
is only one instance per fieldType/fieldValue pair which serves the entire
|
||||
application.
|
||||
*/
|
||||
class SField
|
||||
{
|
||||
|
||||
@@ -66,18 +66,16 @@ public:
|
||||
static int const cMaxOffset = 80;
|
||||
|
||||
// Maximum native value supported by the code
|
||||
constexpr static std::uint64_t cMinValue = 1'000'000'000'000'000ull;
|
||||
static_assert(isPowerOfTen(cMinValue));
|
||||
constexpr static std::uint64_t cMaxValue = cMinValue * 10 - 1;
|
||||
static_assert(cMaxValue == 9'999'999'999'999'999ull);
|
||||
constexpr static std::uint64_t cMaxNative = 9'000'000'000'000'000'000ull;
|
||||
static std::uint64_t const cMinValue = 1000000000000000ull;
|
||||
static std::uint64_t const cMaxValue = 9999999999999999ull;
|
||||
static std::uint64_t const cMaxNative = 9000000000000000000ull;
|
||||
|
||||
// Max native value on network.
|
||||
constexpr static std::uint64_t cMaxNativeN = 100'000'000'000'000'000ull;
|
||||
constexpr static std::uint64_t cIssuedCurrency = 0x8'000'000'000'000'000ull;
|
||||
constexpr static std::uint64_t cPositive = 0x4'000'000'000'000'000ull;
|
||||
constexpr static std::uint64_t cMPToken = 0x2'000'000'000'000'000ull;
|
||||
constexpr static std::uint64_t cValueMask = ~(cPositive | cMPToken);
|
||||
static std::uint64_t const cMaxNativeN = 100000000000000000ull;
|
||||
static std::uint64_t const cIssuedCurrency = 0x8000000000000000ull;
|
||||
static std::uint64_t const cPositive = 0x4000000000000000ull;
|
||||
static std::uint64_t const cMPToken = 0x2000000000000000ull;
|
||||
static std::uint64_t const cValueMask = ~(cPositive | cMPToken);
|
||||
|
||||
static std::uint64_t const uRateOne;
|
||||
|
||||
@@ -176,9 +174,6 @@ public:
|
||||
int
|
||||
exponent() const noexcept;
|
||||
|
||||
bool
|
||||
integral() const noexcept;
|
||||
|
||||
bool
|
||||
native() const noexcept;
|
||||
|
||||
@@ -459,12 +454,6 @@ STAmount::exponent() const noexcept
|
||||
return mOffset;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STAmount::integral() const noexcept
|
||||
{
|
||||
return mAsset.integral();
|
||||
}
|
||||
|
||||
inline bool
|
||||
STAmount::native() const noexcept
|
||||
{
|
||||
@@ -583,7 +572,7 @@ STAmount::clear()
|
||||
{
|
||||
// The -100 is used to allow 0 to sort less than a small positive values
|
||||
// which have a negative exponent.
|
||||
mOffset = integral() ? 0 : -100;
|
||||
mOffset = native() ? 0 : -100;
|
||||
mValue = 0;
|
||||
mIsNegative = false;
|
||||
}
|
||||
@@ -706,53 +695,6 @@ divRoundStrict(
|
||||
std::uint64_t
|
||||
getRate(STAmount const& offerOut, STAmount const& offerIn);
|
||||
|
||||
/** Round an arbitrary precision Amount to the precision of an STAmount that has
|
||||
* a given exponent.
|
||||
*
|
||||
* This is used to ensure that calculations involving IOU amounts do not collect
|
||||
* dust beyond the precision of the reference value.
|
||||
*
|
||||
* @param value The value to be rounded
|
||||
* @param scale An exponent value to establish the precision limit of
|
||||
* `value`. Should be larger than `value.exponent()`.
|
||||
* @param rounding Optional Number rounding mode
|
||||
*
|
||||
*/
|
||||
STAmount
|
||||
roundToScale(
|
||||
STAmount const& value,
|
||||
std::int32_t scale,
|
||||
Number::rounding_mode rounding = Number::getround());
|
||||
|
||||
/** Round an arbitrary precision Number to the precision of a given Asset.
|
||||
*
|
||||
* This is used to ensure that calculations do not collect dust beyond the
|
||||
* precision of the reference value for IOUs, or fractional amounts for the
|
||||
* integral types XRP and MPT.
|
||||
*
|
||||
* @param asset The relevant asset
|
||||
* @param value The value to be rounded
|
||||
* @param scale Only relevant to IOU assets. An exponent value to establish the
|
||||
* precision limit of `value`. Should be larger than `value.exponent()`.
|
||||
* @param rounding Optional Number rounding mode
|
||||
*/
|
||||
template <AssetType A>
|
||||
Number
|
||||
roundToAsset(
|
||||
A const& asset,
|
||||
Number const& value,
|
||||
std::int32_t scale,
|
||||
Number::rounding_mode rounding = Number::getround())
|
||||
{
|
||||
NumberRoundModeGuard mg(rounding);
|
||||
STAmount const ret{asset, value};
|
||||
if (ret.integral())
|
||||
return ret;
|
||||
// Note that the ctor will round integral types (XRP, MPT) via canonicalize,
|
||||
// so no extra work is needed for those.
|
||||
return roundToScale(ret, scale);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline bool
|
||||
@@ -767,37 +709,6 @@ canAdd(STAmount const& amt1, STAmount const& amt2);
|
||||
bool
|
||||
canSubtract(STAmount const& amt1, STAmount const& amt2);
|
||||
|
||||
// Since `canonicalize` does not have access to a ledger, this is needed to put
|
||||
// the low-level routine stAmountCanonicalize on an amendment switch. Only
|
||||
// transactions need to use this switchover. Outside of a transaction it's safe
|
||||
// to unconditionally use the new behavior.
|
||||
|
||||
bool
|
||||
getSTAmountCanonicalizeSwitchover();
|
||||
|
||||
void
|
||||
setSTAmountCanonicalizeSwitchover(bool v);
|
||||
|
||||
/** RAII class to set and restore the STAmount canonicalize switchover.
|
||||
*/
|
||||
|
||||
class STAmountSO
|
||||
{
|
||||
public:
|
||||
explicit STAmountSO(bool v) : saved_(getSTAmountCanonicalizeSwitchover())
|
||||
{
|
||||
setSTAmountCanonicalizeSwitchover(v);
|
||||
}
|
||||
|
||||
~STAmountSO()
|
||||
{
|
||||
setSTAmountCanonicalizeSwitchover(saved_);
|
||||
}
|
||||
|
||||
private:
|
||||
bool saved_;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -501,8 +501,6 @@ public:
|
||||
value_type
|
||||
operator*() const;
|
||||
|
||||
/// Do not use operator->() unless the field is required, or you've checked
|
||||
/// that it's set.
|
||||
T const*
|
||||
operator->() const;
|
||||
|
||||
@@ -526,26 +524,7 @@ protected:
|
||||
// Constraint += and -= ValueProxy operators
|
||||
// to value types that support arithmetic operations
|
||||
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 = 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 = typename U::value_type>
|
||||
concept IsArithmeticST = !IsArithmeticValueUnit<U> && IsArithmeticNumber<Value>;
|
||||
template <typename U>
|
||||
concept IsArithmetic =
|
||||
IsArithmeticNumber<U> || IsArithmeticST<U> || IsArithmeticValueUnit<U>;
|
||||
|
||||
template <class T, class U>
|
||||
concept Addable = requires(T t, U u) { t = t + u; };
|
||||
template <typename T, typename U>
|
||||
concept IsArithmeticCompatible =
|
||||
IsArithmetic<typename T::value_type> && Addable<typename T::value_type, U>;
|
||||
concept IsArithmetic = std::is_arithmetic_v<U> || std::is_same_v<U, STAmount>;
|
||||
|
||||
template <class T>
|
||||
class STObject::ValueProxy : public Proxy<T>
|
||||
@@ -565,12 +544,10 @@ public:
|
||||
// Convenience operators for value types supporting
|
||||
// arithmetic operations
|
||||
template <IsArithmetic U>
|
||||
requires IsArithmeticCompatible<T, U>
|
||||
ValueProxy&
|
||||
operator+=(U const& u);
|
||||
|
||||
template <IsArithmetic U>
|
||||
requires IsArithmeticCompatible<T, U>
|
||||
ValueProxy&
|
||||
operator-=(U const& u);
|
||||
|
||||
@@ -760,8 +737,6 @@ STObject::Proxy<T>::operator*() const -> value_type
|
||||
return this->value();
|
||||
}
|
||||
|
||||
/// Do not use operator->() unless the field is required, or you've checked that
|
||||
/// it's set.
|
||||
template <class T>
|
||||
T const*
|
||||
STObject::Proxy<T>::operator->() const
|
||||
@@ -808,7 +783,6 @@ STObject::ValueProxy<T>::operator=(U&& u)
|
||||
|
||||
template <typename T>
|
||||
template <IsArithmetic U>
|
||||
requires IsArithmeticCompatible<T, U>
|
||||
STObject::ValueProxy<T>&
|
||||
STObject::ValueProxy<T>::operator+=(U const& u)
|
||||
{
|
||||
@@ -818,7 +792,6 @@ STObject::ValueProxy<T>::operator+=(U const& u)
|
||||
|
||||
template <class T>
|
||||
template <IsArithmetic U>
|
||||
requires IsArithmeticCompatible<T, U>
|
||||
STObject::ValueProxy<T>&
|
||||
STObject::ValueProxy<T>::operator-=(U const& u)
|
||||
{
|
||||
|
||||
@@ -73,14 +73,8 @@ static constexpr std::uint32_t XRP_LEDGER_EARLIEST_SEQ{32570u};
|
||||
* used in asserts and tests. */
|
||||
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_FEES{562177u};
|
||||
|
||||
/** The minimum amount of support an amendment should have.
|
||||
|
||||
@note This value is used by legacy code and will become obsolete
|
||||
once the fixAmendmentMajorityCalc amendment activates.
|
||||
*/
|
||||
constexpr std::ratio<204, 256> preFixAmendmentMajorityCalcThreshold;
|
||||
|
||||
constexpr std::ratio<80, 100> postFixAmendmentMajorityCalcThreshold;
|
||||
/** The minimum amount of support an amendment should have. */
|
||||
constexpr std::ratio<80, 100> amendmentMajorityCalcThreshold;
|
||||
|
||||
/** The minimum amount of time an amendment must hold a majority */
|
||||
constexpr std::chrono::seconds const defaultAmendmentMajorityTime = weeks{2};
|
||||
|
||||
@@ -141,6 +141,7 @@ enum TEMcodes : TERUnderlyingType {
|
||||
temARRAY_TOO_LARGE,
|
||||
temBAD_TRANSFER_FEE,
|
||||
temINVALID_INNER_BATCH,
|
||||
temBAD_CIPHERTEXT,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -225,8 +226,9 @@ enum TERcodes : TERUnderlyingType {
|
||||
terQUEUED, // Transaction is being held in TxQ until fee drops
|
||||
terPRE_TICKET, // Ticket is not yet in ledger but might be on its way
|
||||
terNO_AMM, // AMM doesn't exist for the asset pair
|
||||
terADDRESS_COLLISION, // Failed to allocate AccountID when trying to
|
||||
// create a pseudo-account
|
||||
terADDRESS_COLLISION, // Failed to allocate AccountID when trying to
|
||||
// create a pseudo-account
|
||||
terNO_DELEGATE_PERMISSION, // Delegate does not have permission
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -361,7 +363,11 @@ enum TECcodes : TERUnderlyingType {
|
||||
tecLIMIT_EXCEEDED = 195,
|
||||
tecPSEUDO_ACCOUNT = 196,
|
||||
tecPRECISION_LOSS = 197,
|
||||
// DEPRECATED: This error code tecNO_DELEGATE_PERMISSION is reserved for
|
||||
// backward compatibility with historical data on non-prod networks, can be
|
||||
// reclaimed after those networks reset.
|
||||
tecNO_DELEGATE_PERMISSION = 198,
|
||||
tecBAD_PROOF = 199
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -151,8 +151,9 @@ constexpr std::uint32_t const tfMPTCanEscrow = lsfMPTCanEscrow;
|
||||
constexpr std::uint32_t const tfMPTCanTrade = lsfMPTCanTrade;
|
||||
constexpr std::uint32_t const tfMPTCanTransfer = lsfMPTCanTransfer;
|
||||
constexpr std::uint32_t const tfMPTCanClawback = lsfMPTCanClawback;
|
||||
constexpr std::uint32_t const tfMPTNoConfidentialTransfer = lsfMPTNoConfidentialTransfer;
|
||||
constexpr std::uint32_t const tfMPTokenIssuanceCreateMask =
|
||||
~(tfUniversal | tfMPTCanLock | tfMPTRequireAuth | tfMPTCanEscrow | tfMPTCanTrade | tfMPTCanTransfer | tfMPTCanClawback);
|
||||
~(tfUniversal | tfMPTCanLock | tfMPTRequireAuth | tfMPTCanEscrow | tfMPTCanTrade | tfMPTCanTransfer | tfMPTCanClawback | tfMPTNoConfidentialTransfer);
|
||||
|
||||
// MPTokenIssuanceCreate MutableFlags:
|
||||
// Indicating specific fields or flags may be changed after issuance.
|
||||
@@ -285,32 +286,6 @@ constexpr std::uint32_t tfIndependent = 0x00080000;
|
||||
constexpr std::uint32_t const tfBatchMask =
|
||||
~(tfUniversal | tfAllOrNothing | tfOnlyOne | tfUntilFailure | tfIndependent) | tfInnerBatchTxn;
|
||||
|
||||
// LoanSet and LoanPay flags:
|
||||
// LoanSet: True, indicates the loan supports overpayments
|
||||
// LoanPay: True, indicates any excess in this payment can be used
|
||||
// as an overpayment. False, no overpayments will be taken.
|
||||
constexpr std::uint32_t const tfLoanOverpayment = 0x00010000;
|
||||
// LoanPay exclusive flags:
|
||||
// tfLoanFullPayment: True, indicates that the payment is an early
|
||||
// full payment. It must pay the entire loan including close
|
||||
// interest and fees, or it will fail. False: Not a full payment.
|
||||
constexpr std::uint32_t const tfLoanFullPayment = 0x00020000;
|
||||
// tfLoanLatePayment: True, indicates that the payment is late,
|
||||
// and includes late iterest and fees. If the loan is not late,
|
||||
// it will fail. False: not a late payment. If the current payment
|
||||
// is overdue, the transaction will fail.
|
||||
constexpr std::uint32_t const tfLoanLatePayment = 0x00040000;
|
||||
constexpr std::uint32_t const tfLoanSetMask = ~(tfUniversal |
|
||||
tfLoanOverpayment);
|
||||
constexpr std::uint32_t const tfLoanPayMask = ~(tfUniversal |
|
||||
tfLoanOverpayment | tfLoanFullPayment | tfLoanLatePayment);
|
||||
|
||||
// LoanManage flags:
|
||||
constexpr std::uint32_t const tfLoanDefault = 0x00010000;
|
||||
constexpr std::uint32_t const tfLoanImpair = 0x00020000;
|
||||
constexpr std::uint32_t const tfLoanUnimpair = 0x00040000;
|
||||
constexpr std::uint32_t const tfLoanManageMask = ~(tfUniversal | tfLoanDefault | tfLoanImpair | tfLoanUnimpair);
|
||||
|
||||
// clang-format on
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
@@ -33,51 +33,35 @@ namespace ripple {
|
||||
|
||||
class TxMeta
|
||||
{
|
||||
private:
|
||||
struct CtorHelper
|
||||
{
|
||||
explicit CtorHelper() = default;
|
||||
};
|
||||
template <class T>
|
||||
TxMeta(
|
||||
uint256 const& txID,
|
||||
std::uint32_t ledger,
|
||||
T const& data,
|
||||
CtorHelper);
|
||||
|
||||
public:
|
||||
TxMeta(
|
||||
uint256 const& transactionID,
|
||||
std::uint32_t ledger,
|
||||
std::optional<uint256> parentBatchId = std::nullopt);
|
||||
TxMeta(uint256 const& transactionID, std::uint32_t ledger);
|
||||
TxMeta(uint256 const& txID, std::uint32_t ledger, Blob const&);
|
||||
TxMeta(uint256 const& txID, std::uint32_t ledger, std::string const&);
|
||||
TxMeta(uint256 const& txID, std::uint32_t ledger, STObject const&);
|
||||
|
||||
uint256 const&
|
||||
getTxID() const
|
||||
{
|
||||
return mTransactionID;
|
||||
return transactionID_;
|
||||
}
|
||||
std::uint32_t
|
||||
getLgrSeq() const
|
||||
{
|
||||
return mLedger;
|
||||
return ledgerSeq_;
|
||||
}
|
||||
int
|
||||
getResult() const
|
||||
{
|
||||
return mResult;
|
||||
return result_;
|
||||
}
|
||||
TER
|
||||
getResultTER() const
|
||||
{
|
||||
return TER::fromInt(mResult);
|
||||
return TER::fromInt(result_);
|
||||
}
|
||||
std::uint32_t
|
||||
getIndex() const
|
||||
{
|
||||
return mIndex;
|
||||
return index_;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -104,66 +88,52 @@ public:
|
||||
STArray&
|
||||
getNodes()
|
||||
{
|
||||
return (mNodes);
|
||||
return nodes_;
|
||||
}
|
||||
STArray const&
|
||||
getNodes() const
|
||||
{
|
||||
return (mNodes);
|
||||
return nodes_;
|
||||
}
|
||||
|
||||
void
|
||||
setDeliveredAmount(STAmount const& delivered)
|
||||
setAdditionalFields(STObject const& obj)
|
||||
{
|
||||
mDelivered = delivered;
|
||||
if (obj.isFieldPresent(sfDeliveredAmount))
|
||||
deliveredAmount_ = obj.getFieldAmount(sfDeliveredAmount);
|
||||
|
||||
if (obj.isFieldPresent(sfParentBatchID))
|
||||
parentBatchID_ = obj.getFieldH256(sfParentBatchID);
|
||||
}
|
||||
|
||||
STAmount
|
||||
std::optional<STAmount> const&
|
||||
getDeliveredAmount() const
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
hasDeliveredAmount(),
|
||||
"ripple::TxMeta::getDeliveredAmount : non-null delivered amount");
|
||||
return *mDelivered;
|
||||
}
|
||||
|
||||
bool
|
||||
hasDeliveredAmount() const
|
||||
{
|
||||
return static_cast<bool>(mDelivered);
|
||||
return deliveredAmount_;
|
||||
}
|
||||
|
||||
void
|
||||
setParentBatchId(uint256 const& parentBatchId)
|
||||
setDeliveredAmount(std::optional<STAmount> const& amount)
|
||||
{
|
||||
mParentBatchId = parentBatchId;
|
||||
deliveredAmount_ = amount;
|
||||
}
|
||||
|
||||
uint256
|
||||
getParentBatchId() const
|
||||
void
|
||||
setParentBatchID(std::optional<uint256> const& id)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
hasParentBatchId(),
|
||||
"ripple::TxMeta::getParentBatchId : non-null batch id");
|
||||
return *mParentBatchId;
|
||||
}
|
||||
|
||||
bool
|
||||
hasParentBatchId() const
|
||||
{
|
||||
return static_cast<bool>(mParentBatchId);
|
||||
parentBatchID_ = id;
|
||||
}
|
||||
|
||||
private:
|
||||
uint256 mTransactionID;
|
||||
std::uint32_t mLedger;
|
||||
std::uint32_t mIndex;
|
||||
int mResult;
|
||||
uint256 transactionID_;
|
||||
std::uint32_t ledgerSeq_;
|
||||
std::uint32_t index_;
|
||||
int result_;
|
||||
|
||||
std::optional<STAmount> mDelivered;
|
||||
std::optional<uint256> mParentBatchId;
|
||||
std::optional<STAmount> deliveredAmount_;
|
||||
std::optional<uint256> parentBatchID_;
|
||||
|
||||
STArray mNodes;
|
||||
STArray nodes_;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
@@ -27,17 +27,15 @@
|
||||
#error "undefined macro: XRPL_RETIRE"
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
|
||||
XRPL_FEATURE(LendingProtocol, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(ConfidentialTransfer, 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::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (TokenEscrowV1, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (DelegateV1_1, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PriceOracleOrder, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (MPTDeliveredAmount, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (AMMClawbackRounding, Supported::yes, VoteBehavior::DefaultNo)
|
||||
@@ -47,7 +45,6 @@ XRPL_FIX (AMMv1_3, Supported::yes, VoteBehavior::DefaultNo
|
||||
XRPL_FEATURE(PermissionedDEX, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(Batch, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(SingleAssetVault, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionDelegation, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo)
|
||||
// Check flags in Credential transactions
|
||||
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultNo)
|
||||
@@ -81,45 +78,24 @@ XRPL_FIX (DisallowIncomingV1, Supported::yes, VoteBehavior::DefaultNo
|
||||
XRPL_FEATURE(XChainBridge, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(AMM, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(Clawback, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (ReducedOffersV1, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (NFTokenRemint, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (NonFungibleTokensV1_2, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (UniversalNumber, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(XRPFees, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DisallowIncoming, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(ImmediateOfferKilled, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (RemoveNFTokenAutoTrustLine, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (TrustLinesToSelf, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(NonFungibleTokensV1_1, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(ExpandedSignerList, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(CheckCashMakesTrustLine, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (RmSmallIncreasedQOffers, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (STAmountCanonicalize, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(FlowSortStrands, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(TicketBatch, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(NegativeUNL, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (AmendmentMajorityCalc, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(HardenedValidations, Supported::yes, VoteBehavior::DefaultYes)
|
||||
// fix1781: XRPEndpointSteps should be included in the circular payment check
|
||||
XRPL_FIX (1781, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(RequireFullyCanonicalSig, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (QualityUpperBound, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(DeletableAccounts, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (PayChanRecipientOwnerDir, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (CheckThreading, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (MasterKeyAsRegularKey, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (TakerDryOfferRemoval, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(MultiSignReserve, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (1578, Supported::yes, VoteBehavior::DefaultYes)
|
||||
// fix1515: Use liquidity from strands that consume max offers, but mark as dry
|
||||
XRPL_FIX (1515, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(DepositPreauth, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (1623, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (1543, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (1571, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(Checks, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(DepositAuth, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (1513, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(Flow, Supported::yes, VoteBehavior::DefaultYes)
|
||||
|
||||
// The following amendments are obsolete, but must remain supported
|
||||
@@ -133,30 +109,46 @@ XRPL_FEATURE(Flow, Supported::yes, VoteBehavior::DefaultYe
|
||||
//
|
||||
// If a feature remains obsolete for long enough that no clients are able
|
||||
// to vote for it, the feature can be removed (entirely?) from the code.
|
||||
XRPL_FIX (NFTokenNegOffer, Supported::yes, VoteBehavior::Obsolete)
|
||||
XRPL_FIX (NFTokenDirV1, Supported::yes, VoteBehavior::Obsolete)
|
||||
XRPL_FEATURE(NonFungibleTokensV1, Supported::yes, VoteBehavior::Obsolete)
|
||||
XRPL_FEATURE(CryptoConditionsSuite, Supported::yes, VoteBehavior::Obsolete)
|
||||
|
||||
// The following amendments have been active for at least two years. Their
|
||||
// pre-amendment code has been removed and the identifiers are deprecated.
|
||||
// All known amendments and amendments that may appear in a validated
|
||||
// ledger must be registered either here or above with the "active" amendments
|
||||
XRPL_RETIRE(MultiSign)
|
||||
XRPL_RETIRE(TrustSetAuth)
|
||||
XRPL_RETIRE(FeeEscalation)
|
||||
XRPL_RETIRE(PayChan)
|
||||
XRPL_RETIRE(CryptoConditions)
|
||||
XRPL_RETIRE(TickSize)
|
||||
XRPL_RETIRE(fix1368)
|
||||
XRPL_RETIRE(Escrow)
|
||||
XRPL_RETIRE(fix1373)
|
||||
XRPL_RETIRE(EnforceInvariants)
|
||||
XRPL_RETIRE(SortedDirectories)
|
||||
// All known amendments and amendments that may appear in a validated ledger
|
||||
// must be registered either here or above with the "active" amendments
|
||||
//
|
||||
// Please keep this list sorted alphabetically for convenience.
|
||||
XRPL_RETIRE(fix1201)
|
||||
XRPL_RETIRE(fix1368)
|
||||
XRPL_RETIRE(fix1373)
|
||||
XRPL_RETIRE(fix1512)
|
||||
XRPL_RETIRE(fix1513)
|
||||
XRPL_RETIRE(fix1515)
|
||||
XRPL_RETIRE(fix1523)
|
||||
XRPL_RETIRE(fix1528)
|
||||
XRPL_RETIRE(fix1543)
|
||||
XRPL_RETIRE(fix1571)
|
||||
XRPL_RETIRE(fix1578)
|
||||
XRPL_RETIRE(fix1623)
|
||||
XRPL_RETIRE(fix1781)
|
||||
XRPL_RETIRE(fixAmendmentMajorityCalc)
|
||||
XRPL_RETIRE(fixCheckThreading)
|
||||
XRPL_RETIRE(fixNonFungibleTokensV1_2)
|
||||
XRPL_RETIRE(fixNFTokenRemint)
|
||||
XRPL_RETIRE(fixMasterKeyAsRegularKey)
|
||||
XRPL_RETIRE(fixQualityUpperBound)
|
||||
XRPL_RETIRE(fixReducedOffersV1)
|
||||
XRPL_RETIRE(fixRmSmallIncreasedQOffers)
|
||||
XRPL_RETIRE(fixSTAmountCanonicalize)
|
||||
XRPL_RETIRE(fixTakerDryOfferRemoval)
|
||||
XRPL_RETIRE(CryptoConditions)
|
||||
XRPL_RETIRE(Escrow)
|
||||
XRPL_RETIRE(EnforceInvariants)
|
||||
XRPL_RETIRE(FeeEscalation)
|
||||
XRPL_RETIRE(FlowCross)
|
||||
|
||||
// clang-format on
|
||||
XRPL_RETIRE(ImmediateOfferKilled)
|
||||
XRPL_RETIRE(MultiSign)
|
||||
XRPL_RETIRE(NonFungibleTokensV1_1)
|
||||
XRPL_RETIRE(PayChan)
|
||||
XRPL_RETIRE(SortedDirectories)
|
||||
XRPL_RETIRE(TickSize)
|
||||
XRPL_RETIRE(TrustSetAuth)
|
||||
|
||||
@@ -168,7 +168,6 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
|
||||
{sfFirstNFTokenSequence, soeOPTIONAL},
|
||||
{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.
|
||||
@@ -417,6 +416,8 @@ LEDGER_ENTRY(ltMPTOKEN_ISSUANCE, 0x007e, MPTokenIssuance, mpt_issuance, ({
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
{sfDomainID, soeOPTIONAL},
|
||||
{sfMutableFlags, soeDEFAULT},
|
||||
{sfIssuerElGamalPublicKey, soeOPTIONAL},
|
||||
{sfConfidentialOutstandingAmount, soeDEFAULT},
|
||||
}))
|
||||
|
||||
/** A ledger object which tracks MPToken
|
||||
@@ -430,6 +431,11 @@ LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, mptoken, ({
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
{sfPreviousTxnID, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
{sfConfidentialBalanceInbox, soeOPTIONAL},
|
||||
{sfConfidentialBalanceSpending, soeOPTIONAL},
|
||||
{sfConfidentialBalanceVersion, soeDEFAULT},
|
||||
{sfIssuerEncryptedBalance, soeOPTIONAL},
|
||||
{sfHolderElGamalPublicKey, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** A ledger object which tracks Oracle
|
||||
@@ -499,10 +505,10 @@ LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
|
||||
{sfAccount, soeREQUIRED},
|
||||
{sfData, soeOPTIONAL},
|
||||
{sfAsset, soeREQUIRED},
|
||||
{sfAssetsTotal, soeDEFAULT},
|
||||
{sfAssetsAvailable, soeDEFAULT},
|
||||
{sfAssetsTotal, soeREQUIRED},
|
||||
{sfAssetsAvailable, soeREQUIRED},
|
||||
{sfAssetsMaximum, soeDEFAULT},
|
||||
{sfLossUnrealized, soeDEFAULT},
|
||||
{sfLossUnrealized, soeREQUIRED},
|
||||
{sfShareMPTID, soeREQUIRED},
|
||||
{sfWithdrawalPolicy, soeREQUIRED},
|
||||
{sfScale, soeDEFAULT},
|
||||
@@ -510,117 +516,5 @@ LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
|
||||
// no PermissionedDomainID ever (use MPTIssuance.sfDomainID)
|
||||
}))
|
||||
|
||||
/** Reserve 0x0084-0x0087 for future Vault-related objects. */
|
||||
|
||||
/** A ledger object representing a loan broker
|
||||
|
||||
\sa keylet::loanbroker
|
||||
*/
|
||||
LEDGER_ENTRY(ltLOAN_BROKER, 0x0088, LoanBroker, loan_broker, ({
|
||||
{sfPreviousTxnID, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
{sfSequence, soeREQUIRED},
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
{sfVaultNode, soeREQUIRED},
|
||||
{sfVaultID, soeREQUIRED},
|
||||
{sfAccount, soeREQUIRED},
|
||||
{sfOwner, soeREQUIRED},
|
||||
{sfLoanSequence, soeREQUIRED},
|
||||
{sfData, soeDEFAULT},
|
||||
{sfManagementFeeRate, soeDEFAULT},
|
||||
{sfOwnerCount, soeDEFAULT},
|
||||
{sfDebtTotal, soeDEFAULT},
|
||||
{sfDebtMaximum, soeDEFAULT},
|
||||
{sfCoverAvailable, soeDEFAULT},
|
||||
{sfCoverRateMinimum, soeDEFAULT},
|
||||
{sfCoverRateLiquidation, soeDEFAULT},
|
||||
}))
|
||||
|
||||
/** A ledger object representing a loan between a Borrower and a Loan Broker
|
||||
|
||||
\sa keylet::loan
|
||||
*/
|
||||
LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
|
||||
{sfPreviousTxnID, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
{sfLoanBrokerNode, soeREQUIRED},
|
||||
{sfLoanBrokerID, soeREQUIRED},
|
||||
{sfLoanSequence, soeREQUIRED},
|
||||
{sfBorrower, soeREQUIRED},
|
||||
{sfLoanOriginationFee, soeDEFAULT},
|
||||
{sfLoanServiceFee, soeDEFAULT},
|
||||
{sfLatePaymentFee, soeDEFAULT},
|
||||
{sfClosePaymentFee, soeDEFAULT},
|
||||
{sfOverpaymentFee, soeDEFAULT},
|
||||
{sfInterestRate, soeDEFAULT},
|
||||
{sfLateInterestRate, soeDEFAULT},
|
||||
{sfCloseInterestRate, soeDEFAULT},
|
||||
{sfOverpaymentInterestRate, soeDEFAULT},
|
||||
{sfStartDate, soeREQUIRED},
|
||||
{sfPaymentInterval, soeREQUIRED},
|
||||
{sfGracePeriod, soeDEFAULT},
|
||||
{sfPreviousPaymentDate, soeDEFAULT},
|
||||
{sfNextPaymentDueDate, soeDEFAULT},
|
||||
// The loan object tracks these values:
|
||||
//
|
||||
// - PaymentRemaining: The number of payments left in the loan. When it
|
||||
// reaches 0, the loan is paid off, and all other relevant values
|
||||
// must also be 0.
|
||||
//
|
||||
// - PeriodicPayment: The fixed, unrounded amount to be paid each
|
||||
// interval. Stored with as much precision as possible.
|
||||
// Payment transactions must round this value *UP*.
|
||||
//
|
||||
// - TotalValueOutstanding: The rounded total amount owed by the
|
||||
// borrower to the lender / vault.
|
||||
//
|
||||
// - PrincipalOutstanding: The rounded portion of the
|
||||
// TotalValueOutstanding that is from the principal borrowed.
|
||||
//
|
||||
// - ManagementFeeOutstanding: The rounded portion of the
|
||||
// TotalValueOutstanding that represents management fees
|
||||
// specifically owed to the broker based on the initial
|
||||
// loan parameters.
|
||||
//
|
||||
// There are additional values that can be computed from these:
|
||||
//
|
||||
// - InterestOutstanding = TotalValueOutstanding - PrincipalOutstanding
|
||||
// The total amount of interest still pending on the loan,
|
||||
// independent of management fees.
|
||||
//
|
||||
// - InterestOwedToVault = InterestOutstanding - ManagementFeeOutstanding
|
||||
// The amount of the total interest that is owed to the vault, and
|
||||
// will be sent to it as part of a payment.
|
||||
//
|
||||
// - TrueTotalLoanValue = PaymentRemaining * PeriodicPayment
|
||||
// The unrounded true total value of the loan.
|
||||
//
|
||||
// - TrueTotalPrincialOutstanding can be computed using the algorithm
|
||||
// in the ripple::detail::loanPrincipalFromPeriodicPayment function.
|
||||
//
|
||||
// - TrueTotalInterestOutstanding = TrueTotalLoanValue -
|
||||
// TrueTotalPrincipalOutstanding
|
||||
// The unrounded true total interest remaining.
|
||||
//
|
||||
// - TrueTotalManagementFeeOutstanding = TrueTotalInterestOutstanding *
|
||||
// LoanBroker.ManagementFeeRate
|
||||
// The unrounded true total fee still owed to the broker.
|
||||
//
|
||||
// Note the the "True" values may differ significantly from the tracked
|
||||
// rounded values.
|
||||
{sfPaymentRemaining, soeDEFAULT},
|
||||
{sfPeriodicPayment, soeREQUIRED},
|
||||
{sfPrincipalOutstanding, soeDEFAULT},
|
||||
{sfTotalValueOutstanding, soeDEFAULT},
|
||||
{sfManagementFeeOutstanding, soeDEFAULT},
|
||||
// Based on the computed total value at creation, used for
|
||||
// rounding calculated values so they are all on a
|
||||
// consistent scale - that is, they all have the same
|
||||
// number of digits after the decimal point (excluding
|
||||
// trailing zeros).
|
||||
{sfLoanScale, soeDEFAULT},
|
||||
}))
|
||||
|
||||
#undef EXPAND
|
||||
#undef LEDGER_ENTRY_DUPLICATE
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
#error "undefined macro: TYPED_SFIELD"
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
|
||||
// untyped
|
||||
UNTYPED_SFIELD(sfLedgerEntry, LEDGERENTRY, 257)
|
||||
UNTYPED_SFIELD(sfTransaction, TRANSACTION, 257)
|
||||
@@ -61,7 +59,6 @@ TYPED_SFIELD(sfHookEmitCount, UINT16, 18)
|
||||
TYPED_SFIELD(sfHookExecutionIndex, UINT16, 19)
|
||||
TYPED_SFIELD(sfHookApiVersion, UINT16, 20)
|
||||
TYPED_SFIELD(sfLedgerFixType, UINT16, 21)
|
||||
TYPED_SFIELD(sfManagementFeeRate, UINT16, 22) // 1/10 basis points (bips)
|
||||
|
||||
// 32-bit integers (common)
|
||||
TYPED_SFIELD(sfNetworkID, UINT32, 1)
|
||||
@@ -118,21 +115,7 @@ TYPED_SFIELD(sfFirstNFTokenSequence, UINT32, 50)
|
||||
TYPED_SFIELD(sfOracleDocumentID, UINT32, 51)
|
||||
TYPED_SFIELD(sfPermissionValue, UINT32, 52)
|
||||
TYPED_SFIELD(sfMutableFlags, UINT32, 53)
|
||||
TYPED_SFIELD(sfStartDate, UINT32, 54)
|
||||
TYPED_SFIELD(sfPaymentInterval, UINT32, 55)
|
||||
TYPED_SFIELD(sfGracePeriod, UINT32, 56)
|
||||
TYPED_SFIELD(sfPreviousPaymentDate, UINT32, 57)
|
||||
TYPED_SFIELD(sfNextPaymentDueDate, UINT32, 58)
|
||||
TYPED_SFIELD(sfPaymentRemaining, UINT32, 59)
|
||||
TYPED_SFIELD(sfPaymentTotal, UINT32, 60)
|
||||
TYPED_SFIELD(sfLoanSequence, UINT32, 61)
|
||||
TYPED_SFIELD(sfCoverRateMinimum, UINT32, 62) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfCoverRateLiquidation, UINT32, 63) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfOverpaymentFee, UINT32, 64) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfInterestRate, UINT32, 65) // 1/10 basis points (bips)
|
||||
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(sfConfidentialBalanceVersion, UINT32, 54)
|
||||
|
||||
// 64-bit integers (common)
|
||||
TYPED_SFIELD(sfIndexNext, UINT64, 1)
|
||||
@@ -164,8 +147,7 @@ TYPED_SFIELD(sfMPTAmount, UINT64, 26, SField::sMD_BaseTen|SFie
|
||||
TYPED_SFIELD(sfIssuerNode, UINT64, 27)
|
||||
TYPED_SFIELD(sfSubjectNode, UINT64, 28)
|
||||
TYPED_SFIELD(sfLockedAmount, UINT64, 29, SField::sMD_BaseTen|SField::sMD_Default)
|
||||
TYPED_SFIELD(sfVaultNode, UINT64, 30)
|
||||
TYPED_SFIELD(sfLoanBrokerNode, UINT64, 31)
|
||||
TYPED_SFIELD(sfConfidentialOutstandingAmount, UINT64, 30, SField::sMD_BaseTen|SField::sMD_Default)
|
||||
|
||||
// 128-bit
|
||||
TYPED_SFIELD(sfEmailHash, UINT128, 1)
|
||||
@@ -220,9 +202,6 @@ TYPED_SFIELD(sfDomainID, UINT256, 34)
|
||||
TYPED_SFIELD(sfVaultID, UINT256, 35,
|
||||
SField::sMD_PseudoAccount | SField::sMD_Default)
|
||||
TYPED_SFIELD(sfParentBatchID, UINT256, 36)
|
||||
TYPED_SFIELD(sfLoanBrokerID, UINT256, 37,
|
||||
SField::sMD_PseudoAccount | SField::sMD_Default)
|
||||
TYPED_SFIELD(sfLoanID, UINT256, 38)
|
||||
|
||||
// number (common)
|
||||
TYPED_SFIELD(sfNumber, NUMBER, 1)
|
||||
@@ -230,21 +209,12 @@ TYPED_SFIELD(sfAssetsAvailable, NUMBER, 2)
|
||||
TYPED_SFIELD(sfAssetsMaximum, NUMBER, 3)
|
||||
TYPED_SFIELD(sfAssetsTotal, NUMBER, 4)
|
||||
TYPED_SFIELD(sfLossUnrealized, NUMBER, 5)
|
||||
TYPED_SFIELD(sfDebtTotal, NUMBER, 6)
|
||||
TYPED_SFIELD(sfDebtMaximum, NUMBER, 7)
|
||||
TYPED_SFIELD(sfCoverAvailable, NUMBER, 8)
|
||||
TYPED_SFIELD(sfLoanOriginationFee, NUMBER, 9)
|
||||
TYPED_SFIELD(sfLoanServiceFee, NUMBER, 10)
|
||||
TYPED_SFIELD(sfLatePaymentFee, NUMBER, 11)
|
||||
TYPED_SFIELD(sfClosePaymentFee, NUMBER, 12)
|
||||
TYPED_SFIELD(sfPrincipalOutstanding, NUMBER, 13)
|
||||
TYPED_SFIELD(sfPrincipalRequested, NUMBER, 14)
|
||||
TYPED_SFIELD(sfTotalValueOutstanding, NUMBER, 15)
|
||||
TYPED_SFIELD(sfPeriodicPayment, NUMBER, 16)
|
||||
TYPED_SFIELD(sfManagementFeeOutstanding, NUMBER, 17)
|
||||
|
||||
// int32
|
||||
TYPED_SFIELD(sfLoanScale, INT32, 1)
|
||||
// NOTE: Do not use `sfDummyInt32`. It's so far the only use of INT32
|
||||
// in this file and has been defined here for test only.
|
||||
// TODO: Replace `sfDummyInt32` with actually useful field.
|
||||
TYPED_SFIELD(sfDummyInt32, INT32, 1) // for tests only
|
||||
|
||||
// currency amount (common)
|
||||
TYPED_SFIELD(sfAmount, AMOUNT, 1)
|
||||
@@ -316,6 +286,16 @@ TYPED_SFIELD(sfAssetClass, VL, 28)
|
||||
TYPED_SFIELD(sfProvider, VL, 29)
|
||||
TYPED_SFIELD(sfMPTokenMetadata, VL, 30)
|
||||
TYPED_SFIELD(sfCredentialType, VL, 31)
|
||||
TYPED_SFIELD(sfConfidentialBalanceInbox, VL, 32)
|
||||
TYPED_SFIELD(sfConfidentialBalanceSpending, VL, 33)
|
||||
TYPED_SFIELD(sfIssuerEncryptedBalance, VL, 34)
|
||||
TYPED_SFIELD(sfIssuerElGamalPublicKey, VL, 35)
|
||||
TYPED_SFIELD(sfHolderElGamalPublicKey, VL, 36)
|
||||
TYPED_SFIELD(sfZKProof, VL, 37)
|
||||
TYPED_SFIELD(sfHolderEncryptedAmount, VL, 38)
|
||||
TYPED_SFIELD(sfIssuerEncryptedAmount, VL, 39)
|
||||
TYPED_SFIELD(sfSenderEncryptedAmount, VL, 40)
|
||||
TYPED_SFIELD(sfDestinationEncryptedAmount, VL, 41)
|
||||
|
||||
// account (common)
|
||||
TYPED_SFIELD(sfAccount, ACCOUNT, 1)
|
||||
@@ -340,8 +320,6 @@ TYPED_SFIELD(sfAttestationRewardAccount, ACCOUNT, 21)
|
||||
TYPED_SFIELD(sfLockingChainDoor, ACCOUNT, 22)
|
||||
TYPED_SFIELD(sfIssuingChainDoor, ACCOUNT, 23)
|
||||
TYPED_SFIELD(sfSubject, ACCOUNT, 24)
|
||||
TYPED_SFIELD(sfBorrower, ACCOUNT, 25)
|
||||
TYPED_SFIELD(sfCounterparty, ACCOUNT, 26)
|
||||
|
||||
// vector of 256-bit
|
||||
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::sMD_Never)
|
||||
@@ -405,7 +383,6 @@ UNTYPED_SFIELD(sfCredential, OBJECT, 33)
|
||||
UNTYPED_SFIELD(sfRawTransaction, OBJECT, 34)
|
||||
UNTYPED_SFIELD(sfBatchSigner, OBJECT, 35)
|
||||
UNTYPED_SFIELD(sfBook, OBJECT, 36)
|
||||
UNTYPED_SFIELD(sfCounterpartySignature, OBJECT, 37, SField::sMD_Default, SField::notSigning)
|
||||
|
||||
// array of objects (common)
|
||||
// ARRAY/1 is reserved for end of array
|
||||
@@ -440,5 +417,3 @@ UNTYPED_SFIELD(sfAcceptedCredentials, ARRAY, 28)
|
||||
UNTYPED_SFIELD(sfPermissions, ARRAY, 29)
|
||||
UNTYPED_SFIELD(sfRawTransactions, ARRAY, 30)
|
||||
UNTYPED_SFIELD(sfBatchSigners, ARRAY, 31, SField::sMD_Default, SField::notSigning)
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -316,7 +316,7 @@ TRANSACTION(ttTRUST_SET, 20, TrustSet,
|
||||
#endif
|
||||
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
|
||||
Delegation::notDelegatable,
|
||||
uint256{},
|
||||
featureDeletableAccounts,
|
||||
mustDeleteAcct,
|
||||
({
|
||||
{sfDestination, soeREQUIRED},
|
||||
@@ -332,7 +332,7 @@ TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
|
||||
#endif
|
||||
TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint,
|
||||
Delegation::delegatable,
|
||||
featureNonFungibleTokensV1,
|
||||
uint256{},
|
||||
changeNFTCounts,
|
||||
({
|
||||
{sfNFTokenTaxon, soeREQUIRED},
|
||||
@@ -350,7 +350,7 @@ TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint,
|
||||
#endif
|
||||
TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn,
|
||||
Delegation::delegatable,
|
||||
featureNonFungibleTokensV1,
|
||||
uint256{},
|
||||
changeNFTCounts,
|
||||
({
|
||||
{sfNFTokenID, soeREQUIRED},
|
||||
@@ -363,7 +363,7 @@ TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn,
|
||||
#endif
|
||||
TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer,
|
||||
Delegation::delegatable,
|
||||
featureNonFungibleTokensV1,
|
||||
uint256{},
|
||||
noPriv,
|
||||
({
|
||||
{sfNFTokenID, soeREQUIRED},
|
||||
@@ -379,7 +379,7 @@ TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer,
|
||||
#endif
|
||||
TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer,
|
||||
Delegation::delegatable,
|
||||
featureNonFungibleTokensV1,
|
||||
uint256{},
|
||||
noPriv,
|
||||
({
|
||||
{sfNFTokenOffers, soeREQUIRED},
|
||||
@@ -391,7 +391,7 @@ TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer,
|
||||
#endif
|
||||
TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer,
|
||||
Delegation::delegatable,
|
||||
featureNonFungibleTokensV1,
|
||||
uint256{},
|
||||
noPriv,
|
||||
({
|
||||
{sfNFTokenBuyOffer, soeOPTIONAL},
|
||||
@@ -741,6 +741,7 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet,
|
||||
{sfMPTokenMetadata, soeOPTIONAL},
|
||||
{sfTransferFee, soeOPTIONAL},
|
||||
{sfMutableFlags, soeOPTIONAL},
|
||||
{sfIssuerElGamalPublicKey, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction type authorizes a MPToken instance */
|
||||
@@ -837,7 +838,7 @@ TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete,
|
||||
#endif
|
||||
TRANSACTION(ttDELEGATE_SET, 64, DelegateSet,
|
||||
Delegation::notDelegatable,
|
||||
featurePermissionDelegation,
|
||||
featurePermissionDelegationV1_1,
|
||||
noPriv,
|
||||
({
|
||||
{sfAuthorize, soeREQUIRED},
|
||||
@@ -944,137 +945,80 @@ TRANSACTION(ttBATCH, 71, Batch,
|
||||
{sfBatchSigners, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** Reserve 72-73 for future Vault-related transactions */
|
||||
|
||||
/** This transaction creates and updates a Loan Broker */
|
||||
/** This transaction type converts into confidential MPT balance. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpld/app/tx/detail/LoanBrokerSet.h>
|
||||
#include <xrpld/app/tx/detail/ConfidentialConvert.h>
|
||||
#endif
|
||||
TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet,
|
||||
TRANSACTION(ttCONFIDENTIAL_CONVERT, 72, ConfidentialConvert,
|
||||
Delegation::delegatable,
|
||||
featureLendingProtocol,
|
||||
createPseudoAcct | mayAuthorizeMPT, ({
|
||||
{sfVaultID, soeREQUIRED},
|
||||
{sfLoanBrokerID, soeOPTIONAL},
|
||||
{sfData, soeOPTIONAL},
|
||||
{sfManagementFeeRate, soeOPTIONAL},
|
||||
{sfDebtMaximum, soeOPTIONAL},
|
||||
{sfCoverRateMinimum, soeOPTIONAL},
|
||||
{sfCoverRateLiquidation, soeOPTIONAL},
|
||||
featureConfidentialTransfer,
|
||||
noPriv,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
{sfMPTAmount, soeREQUIRED},
|
||||
{sfHolderElGamalPublicKey, soeOPTIONAL},
|
||||
{sfHolderEncryptedAmount, soeREQUIRED},
|
||||
{sfIssuerEncryptedAmount, soeREQUIRED},
|
||||
{sfZKProof, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This transaction deletes a Loan Broker */
|
||||
/** This transaction type merges MPT inbox. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpld/app/tx/detail/LoanBrokerDelete.h>
|
||||
#include <xrpld/app/tx/detail/ConfidentialMergeInbox.h>
|
||||
#endif
|
||||
TRANSACTION(ttLOAN_BROKER_DELETE, 75, LoanBrokerDelete,
|
||||
TRANSACTION(ttCONFIDENTIAL_MERGE_INBOX, 73, ConfidentialMergeInbox,
|
||||
Delegation::delegatable,
|
||||
featureLendingProtocol,
|
||||
mustDeleteAcct | mayAuthorizeMPT, ({
|
||||
{sfLoanBrokerID, soeREQUIRED},
|
||||
featureConfidentialTransfer,
|
||||
noPriv,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This transaction deposits First Loss Capital into a Loan Broker */
|
||||
/** This transaction type converts back into public MPT balance. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpld/app/tx/detail/LoanBrokerCoverDeposit.h>
|
||||
#include <xrpld/app/tx/detail/ConfidentialConvertBack.h>
|
||||
#endif
|
||||
TRANSACTION(ttLOAN_BROKER_COVER_DEPOSIT, 76, LoanBrokerCoverDeposit,
|
||||
TRANSACTION(ttCONFIDENTIAL_CONVERT_BACK, 74, ConfidentialConvertBack,
|
||||
Delegation::delegatable,
|
||||
featureLendingProtocol,
|
||||
noPriv, ({
|
||||
{sfLoanBrokerID, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
featureConfidentialTransfer,
|
||||
noPriv,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
{sfMPTAmount, soeREQUIRED},
|
||||
{sfHolderEncryptedAmount, soeREQUIRED},
|
||||
{sfIssuerEncryptedAmount, soeREQUIRED},
|
||||
{sfZKProof, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This transaction withdraws First Loss Capital from a Loan Broker */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpld/app/tx/detail/LoanBrokerCoverWithdraw.h>
|
||||
#include <xrpld/app/tx/detail/ConfidentialSend.h>
|
||||
#endif
|
||||
TRANSACTION(ttLOAN_BROKER_COVER_WITHDRAW, 77, LoanBrokerCoverWithdraw,
|
||||
TRANSACTION(ttCONFIDENTIAL_SEND, 75, ConfidentialSend,
|
||||
Delegation::delegatable,
|
||||
featureLendingProtocol,
|
||||
mayAuthorizeMPT, ({
|
||||
{sfLoanBrokerID, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
{sfDestination, soeOPTIONAL},
|
||||
{sfDestinationTag, soeOPTIONAL},
|
||||
featureConfidentialTransfer,
|
||||
noPriv,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
{sfDestination, soeREQUIRED},
|
||||
{sfSenderEncryptedAmount, soeREQUIRED},
|
||||
{sfDestinationEncryptedAmount, soeREQUIRED},
|
||||
{sfIssuerEncryptedAmount, soeREQUIRED},
|
||||
{sfZKProof, soeREQUIRED},
|
||||
{sfCredentialIDs, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction claws back First Loss Capital from a Loan Broker to
|
||||
the issuer of the capital */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpld/app/tx/detail/LoanBrokerCoverClawback.h>
|
||||
#include <xrpld/app/tx/detail/ConfidentialClawback.h>
|
||||
#endif
|
||||
TRANSACTION(ttLOAN_BROKER_COVER_CLAWBACK, 78, LoanBrokerCoverClawback,
|
||||
TRANSACTION(ttCONFIDENTIAL_CLAWBACK, 76, ConfidentialClawback,
|
||||
Delegation::delegatable,
|
||||
featureLendingProtocol,
|
||||
noPriv, ({
|
||||
{sfLoanBrokerID, soeOPTIONAL},
|
||||
{sfAmount, soeOPTIONAL, soeMPTSupported},
|
||||
}))
|
||||
|
||||
/** This transaction creates a Loan */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpld/app/tx/detail/LoanSet.h>
|
||||
#endif
|
||||
TRANSACTION(ttLOAN_SET, 80, LoanSet,
|
||||
Delegation::delegatable,
|
||||
featureLendingProtocol,
|
||||
mayAuthorizeMPT | mustModifyVault, ({
|
||||
{sfLoanBrokerID, soeREQUIRED},
|
||||
{sfData, soeOPTIONAL},
|
||||
{sfCounterparty, soeOPTIONAL},
|
||||
{sfCounterpartySignature, soeOPTIONAL},
|
||||
{sfLoanOriginationFee, soeOPTIONAL},
|
||||
{sfLoanServiceFee, soeOPTIONAL},
|
||||
{sfLatePaymentFee, soeOPTIONAL},
|
||||
{sfClosePaymentFee, soeOPTIONAL},
|
||||
{sfOverpaymentFee, soeOPTIONAL},
|
||||
{sfInterestRate, soeOPTIONAL},
|
||||
{sfLateInterestRate, soeOPTIONAL},
|
||||
{sfCloseInterestRate, soeOPTIONAL},
|
||||
{sfOverpaymentInterestRate, soeOPTIONAL},
|
||||
{sfPrincipalRequested, soeREQUIRED},
|
||||
{sfPaymentTotal, soeOPTIONAL},
|
||||
{sfPaymentInterval, soeOPTIONAL},
|
||||
{sfGracePeriod, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction deletes an existing Loan */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpld/app/tx/detail/LoanDelete.h>
|
||||
#endif
|
||||
TRANSACTION(ttLOAN_DELETE, 81, LoanDelete,
|
||||
Delegation::delegatable,
|
||||
featureLendingProtocol,
|
||||
noPriv, ({
|
||||
{sfLoanID, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This transaction is used to change the delinquency status of an existing Loan */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpld/app/tx/detail/LoanManage.h>
|
||||
#endif
|
||||
TRANSACTION(ttLOAN_MANAGE, 82, LoanManage,
|
||||
Delegation::delegatable,
|
||||
featureLendingProtocol,
|
||||
// All of the LoanManage options will modify the vault, but the
|
||||
// transaction can succeed without options, essentially making it
|
||||
// a noop.
|
||||
mayModifyVault, ({
|
||||
{sfLoanID, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** The Borrower uses this transaction to make a Payment on the Loan. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpld/app/tx/detail/LoanPay.h>
|
||||
#endif
|
||||
TRANSACTION(ttLOAN_PAY, 84, LoanPay,
|
||||
Delegation::delegatable,
|
||||
featureLendingProtocol,
|
||||
mayAuthorizeMPT | mustModifyVault, ({
|
||||
{sfLoanID, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
featureConfidentialTransfer,
|
||||
noPriv,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
{sfHolder, soeREQUIRED},
|
||||
{sfMPTAmount, soeREQUIRED},
|
||||
{sfZKProof, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This system-generated transaction type is used to update the status of the various amendments.
|
||||
|
||||
@@ -59,8 +59,6 @@ JSS(BaseAsset); // in: Oracle
|
||||
JSS(BidMax); // in: AMM Bid
|
||||
JSS(BidMin); // in: AMM Bid
|
||||
JSS(ClearFlag); // field.
|
||||
JSS(Counterparty); // field.
|
||||
JSS(CounterpartySignature);// field.
|
||||
JSS(DeliverMax); // out: alias to Amount
|
||||
JSS(DeliverMin); // in: TransactionSign
|
||||
JSS(Destination); // in: TransactionSign; field.
|
||||
@@ -394,8 +392,6 @@ JSS(load_factor_local); // out: NetworkOPs
|
||||
JSS(load_factor_net); // out: NetworkOPs
|
||||
JSS(load_factor_server); // out: NetworkOPs
|
||||
JSS(load_fee); // out: LoadFeeTrackImp, NetworkOPs
|
||||
JSS(loan_broker_id); // in: LedgerEntry
|
||||
JSS(loan_seq); // in: LedgerEntry
|
||||
JSS(local); // out: resource/Logic.h
|
||||
JSS(local_txs); // out: GetCounts
|
||||
JSS(local_static_keys); // out: ValidatorList
|
||||
@@ -508,7 +504,6 @@ JSS(propose_seq); // out: LedgerPropose
|
||||
JSS(proposers); // out: NetworkOPs, LedgerConsensus
|
||||
JSS(protocol); // out: NetworkOPs, PeerImp
|
||||
JSS(proxied); // out: RPC ping
|
||||
JSS(pseudo_account); // out: AccountInfo
|
||||
JSS(pubkey_node); // out: NetworkOPs
|
||||
JSS(pubkey_publisher); // out: ValidatorList
|
||||
JSS(pubkey_validator); // out: NetworkOPs, ValidatorList
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define RIPPLE_RESOURCE_CONSUMER_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/resource/Charge.h>
|
||||
#include <xrpl/resource/Disposition.h>
|
||||
|
||||
@@ -87,6 +88,9 @@ public:
|
||||
Entry&
|
||||
entry();
|
||||
|
||||
void
|
||||
setPublicKey(PublicKey const& publicKey);
|
||||
|
||||
private:
|
||||
Logic* m_logic;
|
||||
Entry* m_entry;
|
||||
|
||||
@@ -53,7 +53,7 @@ struct Entry : public beast::List<Entry>::Node
|
||||
std::string
|
||||
to_string() const
|
||||
{
|
||||
return key->address.to_string();
|
||||
return getFingerprint(key->address, publicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,6 +82,9 @@ struct Entry : public beast::List<Entry>::Node
|
||||
return local_balance.add(charge, now) + remote_balance;
|
||||
}
|
||||
|
||||
// The public key of the peer
|
||||
std::optional<PublicKey> publicKey;
|
||||
|
||||
// Back pointer to the map key (bit of a hack here)
|
||||
Key const* key;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <xrpl/server/Port.h>
|
||||
#include <xrpl/server/detail/ServerImpl.h>
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -34,10 +34,10 @@ template <class Handler>
|
||||
std::unique_ptr<Server>
|
||||
make_Server(
|
||||
Handler& handler,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::io_context& io_context,
|
||||
beast::Journal journal)
|
||||
{
|
||||
return std::make_unique<ServerImpl<Handler>>(handler, io_service, journal);
|
||||
return std::make_unique<ServerImpl<Handler>>(handler, io_context, journal);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
@@ -88,9 +88,7 @@ public:
|
||||
++iter)
|
||||
{
|
||||
typename BufferSequence::value_type const& buffer(*iter);
|
||||
write(
|
||||
boost::asio::buffer_cast<void const*>(buffer),
|
||||
boost::asio::buffer_size(buffer));
|
||||
write(buffer.data(), boost::asio::buffer_size(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +102,7 @@ public:
|
||||
|
||||
/** Detach the session.
|
||||
This holds the session open so that the response can be sent
|
||||
asynchronously. Calls to io_service::run made by the server
|
||||
asynchronously. Calls to io_context::run made by the server
|
||||
will not return until all detached sessions are closed.
|
||||
*/
|
||||
virtual std::shared_ptr<Session>
|
||||
|
||||
@@ -24,11 +24,13 @@
|
||||
#include <xrpl/beast/net/IPAddressConversion.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/server/Session.h>
|
||||
#include <xrpl/server/detail/Spawn.h>
|
||||
#include <xrpl/server/detail/io_list.h>
|
||||
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/spawn.hpp>
|
||||
#include <boost/asio/ssl/stream.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
#include <boost/beast/core/stream_traits.hpp>
|
||||
#include <boost/beast/http/dynamic_body.hpp>
|
||||
@@ -215,8 +217,8 @@ BaseHTTPPeer<Handler, Impl>::BaseHTTPPeer(
|
||||
ConstBufferSequence const& buffers)
|
||||
: port_(port)
|
||||
, handler_(handler)
|
||||
, work_(executor)
|
||||
, strand_(executor)
|
||||
, work_(boost::asio::make_work_guard(executor))
|
||||
, strand_(boost::asio::make_strand(executor))
|
||||
, remote_address_(remote_address)
|
||||
, journal_(journal)
|
||||
{
|
||||
@@ -356,7 +358,7 @@ BaseHTTPPeer<Handler, Impl>::on_write(
|
||||
return;
|
||||
if (graceful_)
|
||||
return do_close();
|
||||
boost::asio::spawn(
|
||||
util::spawn(
|
||||
strand_,
|
||||
std::bind(
|
||||
&BaseHTTPPeer<Handler, Impl>::do_read,
|
||||
@@ -375,7 +377,7 @@ BaseHTTPPeer<Handler, Impl>::do_writer(
|
||||
{
|
||||
auto const p = impl().shared_from_this();
|
||||
resume = std::function<void(void)>([this, p, writer, keep_alive]() {
|
||||
boost::asio::spawn(
|
||||
util::spawn(
|
||||
strand_,
|
||||
std::bind(
|
||||
&BaseHTTPPeer<Handler, Impl>::do_writer,
|
||||
@@ -406,7 +408,7 @@ BaseHTTPPeer<Handler, Impl>::do_writer(
|
||||
if (!keep_alive)
|
||||
return do_close();
|
||||
|
||||
boost::asio::spawn(
|
||||
util::spawn(
|
||||
strand_,
|
||||
std::bind(
|
||||
&BaseHTTPPeer<Handler, Impl>::do_read,
|
||||
@@ -448,14 +450,14 @@ BaseHTTPPeer<Handler, Impl>::write(
|
||||
std::shared_ptr<Writer> const& writer,
|
||||
bool keep_alive)
|
||||
{
|
||||
boost::asio::spawn(bind_executor(
|
||||
util::spawn(
|
||||
strand_,
|
||||
std::bind(
|
||||
&BaseHTTPPeer<Handler, Impl>::do_writer,
|
||||
impl().shared_from_this(),
|
||||
writer,
|
||||
keep_alive,
|
||||
std::placeholders::_1)));
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
@@ -490,12 +492,12 @@ BaseHTTPPeer<Handler, Impl>::complete()
|
||||
}
|
||||
|
||||
// keep-alive
|
||||
boost::asio::spawn(bind_executor(
|
||||
util::spawn(
|
||||
strand_,
|
||||
std::bind(
|
||||
&BaseHTTPPeer<Handler, Impl>::do_read,
|
||||
impl().shared_from_this(),
|
||||
std::placeholders::_1)));
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
|
||||
@@ -91,8 +91,8 @@ BasePeer<Handler, Impl>::BasePeer(
|
||||
return "##" + std::to_string(++id) + " ";
|
||||
}())
|
||||
, j_(sink_)
|
||||
, work_(executor)
|
||||
, strand_(executor)
|
||||
, work_(boost::asio::make_work_guard(executor))
|
||||
, strand_(boost::asio::make_strand(executor))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <xrpl/server/detail/BasePeer.h>
|
||||
#include <xrpl/server/detail/LowestLayer.h>
|
||||
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/beast/core/multi_buffer.hpp>
|
||||
#include <boost/beast/http/message.hpp>
|
||||
#include <boost/beast/websocket.hpp>
|
||||
@@ -420,11 +421,17 @@ BaseWSPeer<Handler, Impl>::start_timer()
|
||||
// Max seconds without completing a message
|
||||
static constexpr std::chrono::seconds timeout{30};
|
||||
static constexpr std::chrono::seconds timeoutLocal{3};
|
||||
error_code ec;
|
||||
timer_.expires_from_now(
|
||||
remote_endpoint().address().is_loopback() ? timeoutLocal : timeout, ec);
|
||||
if (ec)
|
||||
return fail(ec, "start_timer");
|
||||
|
||||
try
|
||||
{
|
||||
timer_.expires_after(
|
||||
remote_endpoint().address().is_loopback() ? timeoutLocal : timeout);
|
||||
}
|
||||
catch (boost::system::system_error const& e)
|
||||
{
|
||||
return fail(e.code(), "start_timer");
|
||||
}
|
||||
|
||||
timer_.async_wait(bind_executor(
|
||||
strand_,
|
||||
std::bind(
|
||||
@@ -438,8 +445,14 @@ template <class Handler, class Impl>
|
||||
void
|
||||
BaseWSPeer<Handler, Impl>::cancel_timer()
|
||||
{
|
||||
error_code ec;
|
||||
timer_.cancel(ec);
|
||||
try
|
||||
{
|
||||
timer_.cancel();
|
||||
}
|
||||
catch (boost::system::system_error const&)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
template <class Handler, class Impl>
|
||||
|
||||
@@ -30,15 +30,29 @@
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/spawn.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/beast/core/detect_ssl.hpp>
|
||||
#include <boost/beast/core/multi_buffer.hpp>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <boost/predef.h>
|
||||
|
||||
#if !BOOST_OS_WINDOWS
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -69,7 +83,7 @@ private:
|
||||
stream_type stream_;
|
||||
socket_type& socket_;
|
||||
endpoint_type remote_address_;
|
||||
boost::asio::io_context::strand strand_;
|
||||
boost::asio::strand<boost::asio::io_context::executor_type> strand_;
|
||||
beast::Journal const j_;
|
||||
|
||||
public:
|
||||
@@ -95,13 +109,30 @@ private:
|
||||
Handler& handler_;
|
||||
boost::asio::io_context& ioc_;
|
||||
acceptor_type acceptor_;
|
||||
boost::asio::io_context::strand strand_;
|
||||
boost::asio::strand<boost::asio::io_context::executor_type> strand_;
|
||||
bool ssl_;
|
||||
bool plain_;
|
||||
static constexpr std::chrono::milliseconds INITIAL_ACCEPT_DELAY{50};
|
||||
static constexpr std::chrono::milliseconds MAX_ACCEPT_DELAY{2000};
|
||||
std::chrono::milliseconds accept_delay_{INITIAL_ACCEPT_DELAY};
|
||||
boost::asio::steady_timer backoff_timer_;
|
||||
static constexpr double FREE_FD_THRESHOLD = 0.70;
|
||||
|
||||
struct FDStats
|
||||
{
|
||||
std::uint64_t used{0};
|
||||
std::uint64_t limit{0};
|
||||
};
|
||||
|
||||
void
|
||||
reOpen();
|
||||
|
||||
std::optional<FDStats>
|
||||
query_fd_stats() const;
|
||||
|
||||
bool
|
||||
should_throttle_for_fds();
|
||||
|
||||
public:
|
||||
Door(
|
||||
Handler& handler,
|
||||
@@ -155,7 +186,7 @@ Door<Handler>::Detector::Detector(
|
||||
, stream_(std::move(stream))
|
||||
, socket_(stream_.socket())
|
||||
, remote_address_(remote_address)
|
||||
, strand_(ioc_)
|
||||
, strand_(boost::asio::make_strand(ioc_))
|
||||
, j_(j)
|
||||
{
|
||||
}
|
||||
@@ -164,7 +195,7 @@ template <class Handler>
|
||||
void
|
||||
Door<Handler>::Detector::run()
|
||||
{
|
||||
boost::asio::spawn(
|
||||
util::spawn(
|
||||
strand_,
|
||||
std::bind(
|
||||
&Detector::do_detect,
|
||||
@@ -269,7 +300,7 @@ Door<Handler>::reOpen()
|
||||
Throw<std::exception>();
|
||||
}
|
||||
|
||||
acceptor_.listen(boost::asio::socket_base::max_connections, ec);
|
||||
acceptor_.listen(boost::asio::socket_base::max_listen_connections, ec);
|
||||
if (ec)
|
||||
{
|
||||
JLOG(j_.error()) << "Listen on port '" << port_.name
|
||||
@@ -291,7 +322,7 @@ Door<Handler>::Door(
|
||||
, handler_(handler)
|
||||
, ioc_(io_context)
|
||||
, acceptor_(io_context)
|
||||
, strand_(io_context)
|
||||
, strand_(boost::asio::make_strand(io_context))
|
||||
, ssl_(
|
||||
port_.protocol.count("https") > 0 ||
|
||||
port_.protocol.count("wss") > 0 || port_.protocol.count("wss2") > 0 ||
|
||||
@@ -299,6 +330,7 @@ Door<Handler>::Door(
|
||||
, plain_(
|
||||
port_.protocol.count("http") > 0 || port_.protocol.count("ws") > 0 ||
|
||||
port_.protocol.count("ws2"))
|
||||
, backoff_timer_(io_context)
|
||||
{
|
||||
reOpen();
|
||||
}
|
||||
@@ -307,7 +339,7 @@ template <class Handler>
|
||||
void
|
||||
Door<Handler>::run()
|
||||
{
|
||||
boost::asio::spawn(
|
||||
util::spawn(
|
||||
strand_,
|
||||
std::bind(
|
||||
&Door<Handler>::do_accept,
|
||||
@@ -320,8 +352,10 @@ void
|
||||
Door<Handler>::close()
|
||||
{
|
||||
if (!strand_.running_in_this_thread())
|
||||
return strand_.post(
|
||||
return boost::asio::post(
|
||||
strand_,
|
||||
std::bind(&Door<Handler>::close, this->shared_from_this()));
|
||||
backoff_timer_.cancel();
|
||||
error_code ec;
|
||||
acceptor_.close(ec);
|
||||
}
|
||||
@@ -367,6 +401,17 @@ Door<Handler>::do_accept(boost::asio::yield_context do_yield)
|
||||
{
|
||||
while (acceptor_.is_open())
|
||||
{
|
||||
if (should_throttle_for_fds())
|
||||
{
|
||||
backoff_timer_.expires_after(accept_delay_);
|
||||
boost::system::error_code tec;
|
||||
backoff_timer_.async_wait(do_yield[tec]);
|
||||
accept_delay_ = std::min(accept_delay_ * 2, MAX_ACCEPT_DELAY);
|
||||
JLOG(j_.warn()) << "Throttling do_accept for "
|
||||
<< accept_delay_.count() << "ms.";
|
||||
continue;
|
||||
}
|
||||
|
||||
error_code ec;
|
||||
endpoint_type remote_address;
|
||||
stream_type stream(ioc_);
|
||||
@@ -376,15 +421,28 @@ Door<Handler>::do_accept(boost::asio::yield_context do_yield)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
break;
|
||||
JLOG(j_.error()) << "accept: " << ec.message();
|
||||
if (ec == boost::asio::error::no_descriptors)
|
||||
|
||||
if (ec == boost::asio::error::no_descriptors ||
|
||||
ec == boost::asio::error::no_buffer_space)
|
||||
{
|
||||
JLOG(j_.info()) << "re-opening acceptor";
|
||||
reOpen();
|
||||
JLOG(j_.warn()) << "accept: Too many open files. Pausing for "
|
||||
<< accept_delay_.count() << "ms.";
|
||||
|
||||
backoff_timer_.expires_after(accept_delay_);
|
||||
boost::system::error_code tec;
|
||||
backoff_timer_.async_wait(do_yield[tec]);
|
||||
|
||||
accept_delay_ = std::min(accept_delay_ * 2, MAX_ACCEPT_DELAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(j_.error()) << "accept error: " << ec.message();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
accept_delay_ = INITIAL_ACCEPT_DELAY;
|
||||
|
||||
if (ssl_ && plain_)
|
||||
{
|
||||
if (auto sp = ios().template emplace<Detector>(
|
||||
@@ -407,6 +465,60 @@ Door<Handler>::do_accept(boost::asio::yield_context do_yield)
|
||||
}
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
std::optional<typename Door<Handler>::FDStats>
|
||||
Door<Handler>::query_fd_stats() const
|
||||
{
|
||||
#if BOOST_OS_WINDOWS
|
||||
return std::nullopt;
|
||||
#else
|
||||
FDStats s;
|
||||
struct rlimit rl;
|
||||
if (getrlimit(RLIMIT_NOFILE, &rl) != 0 || rl.rlim_cur == RLIM_INFINITY)
|
||||
return std::nullopt;
|
||||
s.limit = static_cast<std::uint64_t>(rl.rlim_cur);
|
||||
#if BOOST_OS_LINUX
|
||||
constexpr char const* kFdDir = "/proc/self/fd";
|
||||
#else
|
||||
constexpr char const* kFdDir = "/dev/fd";
|
||||
#endif
|
||||
if (DIR* d = ::opendir(kFdDir))
|
||||
{
|
||||
std::uint64_t cnt = 0;
|
||||
while (::readdir(d) != nullptr)
|
||||
++cnt;
|
||||
::closedir(d);
|
||||
// readdir counts '.', '..', and the DIR* itself shows in the list
|
||||
s.used = (cnt >= 3) ? (cnt - 3) : 0;
|
||||
return s;
|
||||
}
|
||||
return std::nullopt;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
bool
|
||||
Door<Handler>::should_throttle_for_fds()
|
||||
{
|
||||
#if BOOST_OS_WINDOWS
|
||||
return false;
|
||||
#else
|
||||
auto const stats = query_fd_stats();
|
||||
if (!stats || stats->limit == 0)
|
||||
return false;
|
||||
|
||||
auto const& s = *stats;
|
||||
auto const free = (s.limit > s.used) ? (s.limit - s.used) : 0ull;
|
||||
double const free_ratio =
|
||||
static_cast<double>(free) / static_cast<double>(s.limit);
|
||||
if (free_ratio < FREE_FD_THRESHOLD)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -105,7 +105,7 @@ PlainHTTPPeer<Handler>::run()
|
||||
{
|
||||
if (!this->handler_.onAccept(this->session(), this->remote_address_))
|
||||
{
|
||||
boost::asio::spawn(
|
||||
util::spawn(
|
||||
this->strand_,
|
||||
std::bind(&PlainHTTPPeer::do_close, this->shared_from_this()));
|
||||
return;
|
||||
@@ -114,7 +114,7 @@ PlainHTTPPeer<Handler>::run()
|
||||
if (!socket_.is_open())
|
||||
return;
|
||||
|
||||
boost::asio::spawn(
|
||||
util::spawn(
|
||||
this->strand_,
|
||||
std::bind(
|
||||
&PlainHTTPPeer::do_read,
|
||||
|
||||
@@ -115,14 +115,14 @@ SSLHTTPPeer<Handler>::run()
|
||||
{
|
||||
if (!this->handler_.onAccept(this->session(), this->remote_address_))
|
||||
{
|
||||
boost::asio::spawn(
|
||||
util::spawn(
|
||||
this->strand_,
|
||||
std::bind(&SSLHTTPPeer::do_close, this->shared_from_this()));
|
||||
return;
|
||||
}
|
||||
if (!socket_.is_open())
|
||||
return;
|
||||
boost::asio::spawn(
|
||||
util::spawn(
|
||||
this->strand_,
|
||||
std::bind(
|
||||
&SSLHTTPPeer::do_handshake,
|
||||
@@ -164,7 +164,7 @@ SSLHTTPPeer<Handler>::do_handshake(yield_context do_yield)
|
||||
this->port().protocol.count("https") > 0;
|
||||
if (http)
|
||||
{
|
||||
boost::asio::spawn(
|
||||
util::spawn(
|
||||
this->strand_,
|
||||
std::bind(
|
||||
&SSLHTTPPeer::do_read,
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <xrpl/server/detail/io_list.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
@@ -85,9 +87,11 @@ private:
|
||||
|
||||
Handler& handler_;
|
||||
beast::Journal const j_;
|
||||
boost::asio::io_service& io_service_;
|
||||
boost::asio::io_service::strand strand_;
|
||||
std::optional<boost::asio::io_service::work> work_;
|
||||
boost::asio::io_context& io_context_;
|
||||
boost::asio::strand<boost::asio::io_context::executor_type> strand_;
|
||||
std::optional<boost::asio::executor_work_guard<
|
||||
boost::asio::io_context::executor_type>>
|
||||
work_;
|
||||
|
||||
std::mutex m_;
|
||||
std::vector<Port> ports_;
|
||||
@@ -100,7 +104,7 @@ private:
|
||||
public:
|
||||
ServerImpl(
|
||||
Handler& handler,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::io_context& io_context,
|
||||
beast::Journal journal);
|
||||
|
||||
~ServerImpl();
|
||||
@@ -123,10 +127,10 @@ public:
|
||||
return ios_;
|
||||
}
|
||||
|
||||
boost::asio::io_service&
|
||||
get_io_service()
|
||||
boost::asio::io_context&
|
||||
get_io_context()
|
||||
{
|
||||
return io_service_;
|
||||
return io_context_;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -140,13 +144,13 @@ private:
|
||||
template <class Handler>
|
||||
ServerImpl<Handler>::ServerImpl(
|
||||
Handler& handler,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::io_context& io_context,
|
||||
beast::Journal journal)
|
||||
: handler_(handler)
|
||||
, j_(journal)
|
||||
, io_service_(io_service)
|
||||
, strand_(io_service_)
|
||||
, work_(io_service_)
|
||||
, io_context_(io_context)
|
||||
, strand_(boost::asio::make_strand(io_context_))
|
||||
, work_(std::in_place, boost::asio::make_work_guard(io_context_))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -173,7 +177,7 @@ ServerImpl<Handler>::ports(std::vector<Port> const& ports)
|
||||
ports_.push_back(port);
|
||||
auto& internalPort = ports_.back();
|
||||
if (auto sp = ios_.emplace<Door<Handler>>(
|
||||
handler_, io_service_, internalPort, j_))
|
||||
handler_, io_context_, internalPort, j_))
|
||||
{
|
||||
list_.push_back(sp);
|
||||
|
||||
|
||||
108
include/xrpl/server/detail/Spawn.h
Normal file
108
include/xrpl/server/detail/Spawn.h
Normal file
@@ -0,0 +1,108 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright(c) 2025 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_SERVER_SPAWN_H_INCLUDED
|
||||
#define RIPPLE_SERVER_SPAWN_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
|
||||
#include <boost/asio/spawn.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
|
||||
#include <concepts>
|
||||
#include <type_traits>
|
||||
|
||||
namespace ripple::util {
|
||||
namespace impl {
|
||||
|
||||
template <typename T>
|
||||
concept IsStrand = std::same_as<
|
||||
std::decay_t<T>,
|
||||
boost::asio::strand<typename std::decay_t<T>::inner_executor_type>>;
|
||||
|
||||
/**
|
||||
* @brief A completion handler that restores `boost::asio::spawn`'s behaviour
|
||||
* from Boost 1.83
|
||||
*
|
||||
* This is intended to be passed as the third argument to `boost::asio::spawn`
|
||||
* so that exceptions are not ignored but propagated to `io_context.run()` call
|
||||
* site.
|
||||
*
|
||||
* @param ePtr The exception that was caught on the coroutine
|
||||
*/
|
||||
inline constexpr auto kPROPAGATE_EXCEPTIONS = [](std::exception_ptr ePtr) {
|
||||
if (ePtr)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::rethrow_exception(ePtr);
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
JLOG(debugLog().warn()) << "Spawn exception: " << e.what();
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
JLOG(debugLog().warn()) << "Spawn exception: Unknown";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
/**
|
||||
* @brief Spawns a coroutine using `boost::asio::spawn`
|
||||
*
|
||||
* @note This uses kPROPAGATE_EXCEPTIONS to force asio to propagate exceptions
|
||||
* through `io_context`
|
||||
* @note Since implicit strand was removed from boost::asio::spawn this helper
|
||||
* function adds the strand back
|
||||
*
|
||||
* @tparam Ctx The type of the context/strand
|
||||
* @tparam F The type of the function to execute
|
||||
* @param ctx The execution context
|
||||
* @param func The function to execute. Must return `void`
|
||||
*/
|
||||
template <typename Ctx, typename F>
|
||||
requires std::is_invocable_r_v<void, F, boost::asio::yield_context>
|
||||
void
|
||||
spawn(Ctx&& ctx, F&& func)
|
||||
{
|
||||
if constexpr (impl::IsStrand<Ctx>)
|
||||
{
|
||||
boost::asio::spawn(
|
||||
std::forward<Ctx>(ctx),
|
||||
std::forward<F>(func),
|
||||
impl::kPROPAGATE_EXCEPTIONS);
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::asio::spawn(
|
||||
boost::asio::make_strand(
|
||||
boost::asio::get_associated_executor(std::forward<Ctx>(ctx))),
|
||||
std::forward<F>(func),
|
||||
impl::kPROPAGATE_EXCEPTIONS);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ripple::util
|
||||
|
||||
#endif
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
May be called concurrently.
|
||||
|
||||
Preconditions:
|
||||
No call to io_service::run on any io_service
|
||||
No call to io_context::run on any io_context
|
||||
used by work objects associated with this io_list
|
||||
exists in the caller's call stack.
|
||||
*/
|
||||
|
||||
@@ -20,11 +20,10 @@
|
||||
#ifndef RIPPLE_SHAMAP_FAMILY_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_FAMILY_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Database.h>
|
||||
#include <xrpld/shamap/FullBelowCache.h>
|
||||
#include <xrpld/shamap/TreeNodeCache.h>
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/nodestore/Database.h>
|
||||
#include <xrpl/shamap/FullBelowCache.h>
|
||||
#include <xrpl/shamap/TreeNodeCache.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user