mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-18 10:05:51 +00:00
Compare commits
82 Commits
bthomee/lo
...
ripple/con
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
5a89641d98 | ||
|
|
beefa248a6 | ||
|
|
e919a25ecb | ||
|
|
c3fdbc0430 |
27
.github/actions/build-deps/action.yml
vendored
27
.github/actions/build-deps/action.yml
vendored
@@ -4,20 +4,23 @@ description: "Install Conan dependencies, optionally forcing a rebuild of all de
|
||||
# Note that actions do not support 'type' and all inputs are strings, see
|
||||
# https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs.
|
||||
inputs:
|
||||
verbosity:
|
||||
description: "The build verbosity."
|
||||
required: false
|
||||
default: "verbose"
|
||||
build_dir:
|
||||
description: "The directory where to build."
|
||||
required: true
|
||||
build_type:
|
||||
description: 'The build type to use ("Debug", "Release").'
|
||||
required: true
|
||||
build_nproc:
|
||||
description: "The number of processors to use for building."
|
||||
required: true
|
||||
force_build:
|
||||
description: 'Force building of all dependencies ("true", "false").'
|
||||
required: false
|
||||
default: "false"
|
||||
log_verbosity:
|
||||
description: "The logging verbosity."
|
||||
required: false
|
||||
default: "verbose"
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
@@ -26,19 +29,21 @@ runs:
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_DIR: ${{ inputs.build_dir }}
|
||||
BUILD_NPROC: ${{ inputs.build_nproc }}
|
||||
BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }}
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
LOG_VERBOSITY: ${{ inputs.log_verbosity }}
|
||||
run: |
|
||||
echo 'Installing dependencies.'
|
||||
mkdir -p '${{ env.BUILD_DIR }}'
|
||||
cd '${{ env.BUILD_DIR }}'
|
||||
mkdir -p "${BUILD_DIR}"
|
||||
cd "${BUILD_DIR}"
|
||||
conan install \
|
||||
--output-folder . \
|
||||
--build=${{ env.BUILD_OPTION }} \
|
||||
--build="${BUILD_OPTION}" \
|
||||
--options:host='&:tests=True' \
|
||||
--options:host='&:xrpld=True' \
|
||||
--settings:all build_type='${{ env.BUILD_TYPE }}' \
|
||||
--conf:all tools.build:verbosity='${{ inputs.verbosity }}' \
|
||||
--conf:all tools.compilation:verbosity='${{ inputs.verbosity }}' \
|
||||
--conf:all tools.build:jobs=$(nproc) \
|
||||
--settings:all build_type="${BUILD_TYPE}" \
|
||||
--conf:all tools.build:jobs=${BUILD_NPROC} \
|
||||
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
|
||||
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
|
||||
..
|
||||
|
||||
4
.github/actions/setup-conan/action.yml
vendored
4
.github/actions/setup-conan/action.yml
vendored
@@ -39,8 +39,8 @@ runs:
|
||||
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
|
||||
CONAN_REMOTE_URL: ${{ inputs.conan_remote_url }}
|
||||
run: |
|
||||
echo "Adding Conan remote '${{ env.CONAN_REMOTE_NAME }}' at '${{ env.CONAN_REMOTE_URL }}'."
|
||||
conan remote add --index 0 --force '${{ env.CONAN_REMOTE_NAME }}' '${{ env.CONAN_REMOTE_URL }}'
|
||||
echo "Adding Conan remote '${CONAN_REMOTE_NAME}' at '${CONAN_REMOTE_URL}'."
|
||||
conan remote add --index 0 --force "${CONAN_REMOTE_NAME}" "${CONAN_REMOTE_URL}"
|
||||
|
||||
echo 'Listing Conan remotes.'
|
||||
conan remote list
|
||||
|
||||
@@ -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,18 +137,21 @@ 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
|
||||
tests.libxrpl > xrpl.basics
|
||||
tests.libxrpl > xrpl.json
|
||||
tests.libxrpl > xrpl.net
|
||||
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
|
||||
@@ -151,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
|
||||
@@ -171,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
|
||||
@@ -191,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
|
||||
|
||||
58
.github/scripts/strategy-matrix/linux.json
vendored
58
.github/scripts/strategy-matrix/linux.json
vendored
@@ -15,154 +15,168 @@
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "13",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "15",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "16",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "17",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "18",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "19",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "20",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "8",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "8",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "13",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "10",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "10",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "jammy",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "13",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "16",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "17",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "18",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "19",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "97ba375"
|
||||
}
|
||||
],
|
||||
"build_type": ["Debug", "Release"],
|
||||
|
||||
1
.github/workflows/on-pr.yml
vendored
1
.github/workflows/on-pr.yml
vendored
@@ -103,6 +103,7 @@ jobs:
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [linux, macos, windows]
|
||||
with:
|
||||
|
||||
8
.github/workflows/on-trigger.yml
vendored
8
.github/workflows/on-trigger.yml
vendored
@@ -50,7 +50,12 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
# When a PR is merged into the develop branch it will be assigned a unique
|
||||
# group identifier, so execution will continue even if another PR is merged
|
||||
# while it is still running. In all other cases the group identifier is shared
|
||||
# per branch, so that any in-progress runs are cancelled when a new commit is
|
||||
# pushed.
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
@@ -65,6 +70,7 @@ jobs:
|
||||
build-test:
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
fail-fast: ${{ github.event_name == 'merge_group' }}
|
||||
matrix:
|
||||
os: [linux, macos, windows]
|
||||
with:
|
||||
|
||||
2
.github/workflows/pre-commit.yml
vendored
2
.github/workflows/pre-commit.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
jobs:
|
||||
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
|
||||
run-hooks:
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@af1b0f0d764cda2e5435f5ac97b240d4bd4d95d3
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@34790936fae4c6c751f62ec8c06696f9c1a5753a
|
||||
with:
|
||||
runs_on: ubuntu-latest
|
||||
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-a8c7be1" }'
|
||||
|
||||
18
.github/workflows/publish-docs.yml
vendored
18
.github/workflows/publish-docs.yml
vendored
@@ -23,6 +23,7 @@ defaults:
|
||||
|
||||
env:
|
||||
BUILD_DIR: .build
|
||||
NPROC_SUBTRACT: 2
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
@@ -33,6 +34,13 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
|
||||
- name: Get number of processors
|
||||
uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
|
||||
id: nproc
|
||||
with:
|
||||
subtract: ${{ env.NPROC_SUBTRACT }}
|
||||
|
||||
- name: Check configuration
|
||||
run: |
|
||||
echo 'Checking path.'
|
||||
@@ -46,12 +54,16 @@ jobs:
|
||||
|
||||
echo 'Checking Doxygen version.'
|
||||
doxygen --version
|
||||
|
||||
- name: Build documentation
|
||||
env:
|
||||
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
|
||||
run: |
|
||||
mkdir -p ${{ env.BUILD_DIR }}
|
||||
cd ${{ env.BUILD_DIR }}
|
||||
mkdir -p "${BUILD_DIR}"
|
||||
cd "${BUILD_DIR}"
|
||||
cmake -Donly_docs=ON ..
|
||||
cmake --build . --target docs --parallel $(nproc)
|
||||
cmake --build . --target docs --parallel ${BUILD_NPROC}
|
||||
|
||||
- name: Publish documentation
|
||||
if: ${{ github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }}
|
||||
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
|
||||
|
||||
@@ -39,6 +39,12 @@ on:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
nproc_subtract:
|
||||
description: "The number of processors to subtract when calculating parallelism."
|
||||
required: false
|
||||
type: number
|
||||
default: 2
|
||||
|
||||
secrets:
|
||||
CODECOV_TOKEN:
|
||||
description: "The Codecov token to use for uploading coverage reports."
|
||||
@@ -55,6 +61,7 @@ jobs:
|
||||
runs_on: ${{ inputs.runs_on }}
|
||||
image: ${{ inputs.image }}
|
||||
config_name: ${{ inputs.config_name }}
|
||||
nproc_subtract: ${{ inputs.nproc_subtract }}
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@@ -67,3 +74,4 @@ jobs:
|
||||
runs_on: ${{ inputs.runs_on }}
|
||||
image: ${{ inputs.image }}
|
||||
config_name: ${{ inputs.config_name }}
|
||||
nproc_subtract: ${{ inputs.nproc_subtract }}
|
||||
|
||||
2
.github/workflows/reusable-build-test.yml
vendored
2
.github/workflows/reusable-build-test.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
||||
- generate-matrix
|
||||
uses: ./.github/workflows/reusable-build-test-config.yml
|
||||
strategy:
|
||||
fail-fast: false
|
||||
fail-fast: ${{ github.event_name == 'merge_group' }}
|
||||
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
|
||||
max-parallel: 10
|
||||
with:
|
||||
|
||||
49
.github/workflows/reusable-build.yml
vendored
49
.github/workflows/reusable-build.yml
vendored
@@ -34,6 +34,11 @@ on:
|
||||
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."
|
||||
@@ -48,6 +53,7 @@ jobs:
|
||||
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' }}
|
||||
@@ -57,13 +63,19 @@ jobs:
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5
|
||||
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
|
||||
|
||||
@@ -71,7 +83,11 @@ jobs:
|
||||
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
|
||||
@@ -83,33 +99,50 @@ jobs:
|
||||
cmake \
|
||||
-G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
|
||||
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||
${{ env.CMAKE_ARGS }} \
|
||||
-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 ${{ env.BUILD_TYPE }} \
|
||||
--parallel $(nproc) \
|
||||
--target ${{ env.CMAKE_TARGET }}
|
||||
--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: ${{ inputs.build_dir }}/${{ runner.os == 'Windows' && inputs.build_type || '' }}/rippled${{ runner.os == 'Windows' && '.exe' || '' }}
|
||||
path: ${{ env.BUILD_DIR }}/binaries/
|
||||
retention-days: 3
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload coverage report
|
||||
if: ${{ inputs.cmake_target == 'coverage' }}
|
||||
if: ${{ github.repository_owner == 'XRPLF' && inputs.cmake_target == 'coverage' }}
|
||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
|
||||
with:
|
||||
disable_search: true
|
||||
|
||||
10
.github/workflows/reusable-notify-clio.yml
vendored
10
.github/workflows/reusable-notify-clio.yml
vendored
@@ -51,7 +51,7 @@ jobs:
|
||||
run: |
|
||||
echo 'Generating user and channel.'
|
||||
echo "user=clio" >> "${GITHUB_OUTPUT}"
|
||||
echo "channel=pr_${{ env.PR_NUMBER }}" >> "${GITHUB_OUTPUT}"
|
||||
echo "channel=pr_${PR_NUMBER}" >> "${GITHUB_OUTPUT}"
|
||||
echo 'Extracting version.'
|
||||
echo "version=$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" >> "${GITHUB_OUTPUT}"
|
||||
- name: Calculate conan reference
|
||||
@@ -64,13 +64,15 @@ jobs:
|
||||
conan_remote_name: ${{ inputs.conan_remote_name }}
|
||||
conan_remote_url: ${{ inputs.conan_remote_url }}
|
||||
- name: Log into Conan remote
|
||||
run: conan remote login ${{ inputs.conan_remote_name }} "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}"
|
||||
env:
|
||||
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
|
||||
run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}"
|
||||
- name: Upload package
|
||||
env:
|
||||
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
|
||||
run: |
|
||||
conan export --user=${{ steps.generate.outputs.user }} --channel=${{ steps.generate.outputs.channel }} .
|
||||
conan upload --confirm --check --remote=${{ env.CONAN_REMOTE_NAME }} xrpl/${{ steps.conan_ref.outputs.conan_ref }}
|
||||
conan upload --confirm --check --remote="${CONAN_REMOTE_NAME}" xrpl/${{ steps.conan_ref.outputs.conan_ref }}
|
||||
outputs:
|
||||
conan_ref: ${{ steps.conan_ref.outputs.conan_ref }}
|
||||
|
||||
@@ -86,4 +88,4 @@ jobs:
|
||||
gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
/repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \
|
||||
-F "client_payload[conan_ref]=${{ needs.upload.outputs.conan_ref }}" \
|
||||
-F "client_payload[pr_url]=${{ env.PR_URL }}"
|
||||
-F "client_payload[pr_url]=${PR_URL}"
|
||||
|
||||
@@ -38,4 +38,4 @@ jobs:
|
||||
env:
|
||||
GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }}
|
||||
GENERATE_OPTION: ${{ inputs.strategy_matrix == 'all' && '--all' || '' }}
|
||||
run: ./generate.py ${{ env.GENERATE_OPTION }} ${{ env.GENERATE_CONFIG }} >> "${GITHUB_OUTPUT}"
|
||||
run: ./generate.py ${GENERATE_OPTION} ${GENERATE_CONFIG} >> "${GITHUB_OUTPUT}"
|
||||
|
||||
48
.github/workflows/reusable-test.yml
vendored
48
.github/workflows/reusable-test.yml
vendored
@@ -26,12 +26,28 @@ on:
|
||||
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:
|
||||
@@ -61,9 +77,35 @@ jobs:
|
||||
run: |
|
||||
./rippled --version | grep libvoidstar
|
||||
|
||||
- name: Test the binary
|
||||
- name: Run the embedded tests
|
||||
if: ${{ inputs.run_tests }}
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
|
||||
run: |
|
||||
./rippled --unittest --unittest-jobs $(nproc)
|
||||
ctest -j $(nproc) --output-on-failure
|
||||
./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
|
||||
|
||||
31
.github/workflows/upload-conan-deps.yml
vendored
31
.github/workflows/upload-conan-deps.yml
vendored
@@ -34,6 +34,7 @@ on:
|
||||
env:
|
||||
CONAN_REMOTE_NAME: xrplf
|
||||
CONAN_REMOTE_URL: https://conan.ripplex.io
|
||||
NPROC_SUBTRACT: 2
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -61,12 +62,23 @@ jobs:
|
||||
if: ${{ runner.os == 'macOS' }}
|
||||
uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
|
||||
|
||||
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5
|
||||
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: ${{ env.NPROC_SUBTRACT }}
|
||||
|
||||
- name: Setup Conan
|
||||
uses: ./.github/actions/setup-conan
|
||||
with:
|
||||
@@ -77,18 +89,19 @@ jobs:
|
||||
uses: ./.github/actions/build-deps
|
||||
with:
|
||||
build_dir: .build
|
||||
build_nproc: ${{ steps.nproc.outputs.nproc }}
|
||||
build_type: ${{ matrix.build_type }}
|
||||
force_build: ${{ github.event_name == 'schedule' || github.event.inputs.force_source_build == 'true' }}
|
||||
# The verbosity is set to "quiet" for Windows to avoid an excessive amount of logs, while it
|
||||
# is set to "verbose" otherwise to provide more information during the build process.
|
||||
verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
|
||||
# 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: Log into Conan remote
|
||||
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' }}
|
||||
run: conan remote login ${{ env.CONAN_REMOTE_NAME }} "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}"
|
||||
if: ${{ github.repository_owner == 'XRPLF' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
|
||||
run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}"
|
||||
|
||||
- name: Upload Conan packages
|
||||
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' && github.event_name != 'schedule' }}
|
||||
if: ${{ github.repository_owner == 'XRPLF' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
|
||||
env:
|
||||
FORCE_OPTION: ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }}
|
||||
run: conan upload "*" --remote='${{ env.CONAN_REMOTE_NAME }}' --confirm ${{ env.FORCE_OPTION }}
|
||||
run: conan upload "*" --remote="${CONAN_REMOTE_NAME}" --confirm ${FORCE_OPTION}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ 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)
|
||||
|
||||
@@ -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
|
||||
@@ -111,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
|
||||
@@ -136,6 +152,8 @@ target_link_modules(xrpl PUBLIC
|
||||
protocol
|
||||
resource
|
||||
server
|
||||
nodestore
|
||||
shamap
|
||||
net
|
||||
ledger
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,7 +7,7 @@ function(xrpl_add_test name)
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp"
|
||||
)
|
||||
add_executable(${target} EXCLUDE_FROM_ALL ${ARGN} ${sources})
|
||||
add_executable(${target} ${ARGN} ${sources})
|
||||
|
||||
isolate_headers(
|
||||
${target}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Global configuration for Conan. This is used to set the number of parallel
|
||||
# downloads, uploads, and build jobs.
|
||||
# downloads and uploads.
|
||||
core:non_interactive=True
|
||||
core.download:parallel={{ os.cpu_count() }}
|
||||
core.upload:parallel={{ os.cpu_count() }}
|
||||
tools.build:jobs={{ (os.cpu_count() * 4/5) | int }}
|
||||
|
||||
@@ -21,11 +21,11 @@ compiler.libcxx={{detect_api.detect_libcxx(compiler, version, compiler_exe)}}
|
||||
|
||||
[conf]
|
||||
{% if compiler == "clang" and compiler_version >= 19 %}
|
||||
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
|
||||
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
|
||||
{% endif %}
|
||||
{% if compiler == "apple-clang" and compiler_version >= 17 %}
|
||||
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
|
||||
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
|
||||
{% endif %}
|
||||
{% if compiler == "gcc" and compiler_version < 13 %}
|
||||
tools.build:cxxflags=['-Wno-restrict']
|
||||
tools.build:cxxflags+=['-Wno-restrict']
|
||||
{% endif %}
|
||||
|
||||
@@ -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>
|
||||
|
||||
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
|
||||
@@ -187,6 +187,7 @@ enum LedgerSpecificFlags {
|
||||
lsfMPTCanTrade = 0x00000010,
|
||||
lsfMPTCanTransfer = 0x00000020,
|
||||
lsfMPTCanClawback = 0x00000040,
|
||||
lsfMPTNoConfidentialTransfer = 0x00000080,
|
||||
|
||||
lsmfMPTCanMutateCanLock = 0x00000002,
|
||||
lsmfMPTCanMutateRequireAuth = 0x00000004,
|
||||
|
||||
@@ -55,7 +55,10 @@ std::size_t constexpr oversizeMetaDataCap = 5200;
|
||||
/** The maximum number of entries per directory page */
|
||||
std::size_t constexpr dirNodeMaxEntries = 32;
|
||||
|
||||
/** The maximum number of pages allowed in a directory */
|
||||
/** The maximum number of pages allowed in a directory
|
||||
|
||||
Made obsolete by fixDirectoryLimit amendment.
|
||||
*/
|
||||
std::uint64_t constexpr dirNodeMaxPages = 262144;
|
||||
|
||||
/** The maximum number of items in an NFT page */
|
||||
@@ -178,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
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -709,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
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -244,6 +244,9 @@ public:
|
||||
getFieldPathSet(SField const& field) const;
|
||||
STVector256 const&
|
||||
getFieldV256(SField const& field) const;
|
||||
// If not found, returns an object constructed with the given field
|
||||
STObject
|
||||
getFieldObject(SField const& field) const;
|
||||
STArray const&
|
||||
getFieldArray(SField const& field) const;
|
||||
STCurrency const&
|
||||
@@ -390,6 +393,8 @@ public:
|
||||
setFieldV256(SField const& field, STVector256 const& v);
|
||||
void
|
||||
setFieldArray(SField const& field, STArray const& v);
|
||||
void
|
||||
setFieldObject(SField const& field, STObject const& v);
|
||||
|
||||
template <class Tag>
|
||||
void
|
||||
|
||||
@@ -87,8 +87,14 @@ public:
|
||||
getFullText() const override;
|
||||
|
||||
// Outer transaction functions / signature functions.
|
||||
static Blob
|
||||
getSignature(STObject const& sigObject);
|
||||
|
||||
Blob
|
||||
getSignature() const;
|
||||
getSignature() const
|
||||
{
|
||||
return getSignature(*this);
|
||||
}
|
||||
|
||||
uint256
|
||||
getSigningHash() const;
|
||||
@@ -119,13 +125,20 @@ public:
|
||||
getJson(JsonOptions options, bool binary) const;
|
||||
|
||||
void
|
||||
sign(PublicKey const& publicKey, SecretKey const& secretKey);
|
||||
sign(
|
||||
PublicKey const& publicKey,
|
||||
SecretKey const& secretKey,
|
||||
std::optional<std::reference_wrapper<SField const>> signatureTarget =
|
||||
{});
|
||||
|
||||
/** Check the signature.
|
||||
@return `true` if valid signature. If invalid, the error message string.
|
||||
*/
|
||||
enum class RequireFullyCanonicalSig : bool { no, yes };
|
||||
|
||||
/** Check the signature.
|
||||
@param requireCanonicalSig If `true`, check that the signature is fully
|
||||
canonical. If `false`, only check that the signature is valid.
|
||||
@param rules The current ledger rules.
|
||||
@return `true` if valid signature. If invalid, the error message string.
|
||||
*/
|
||||
Expected<void, std::string>
|
||||
checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const& rules)
|
||||
const;
|
||||
@@ -150,17 +163,34 @@ public:
|
||||
char status,
|
||||
std::string const& escapedMetaData) const;
|
||||
|
||||
std::vector<uint256>
|
||||
std::vector<uint256> const&
|
||||
getBatchTransactionIDs() const;
|
||||
|
||||
private:
|
||||
/** Check the signature.
|
||||
@param requireCanonicalSig If `true`, check that the signature is fully
|
||||
canonical. If `false`, only check that the signature is valid.
|
||||
@param rules The current ledger rules.
|
||||
@param sigObject Reference to object that contains the signature fields.
|
||||
Will be *this more often than not.
|
||||
@return `true` if valid signature. If invalid, the error message string.
|
||||
*/
|
||||
Expected<void, std::string>
|
||||
checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const;
|
||||
checkSign(
|
||||
RequireFullyCanonicalSig requireCanonicalSig,
|
||||
Rules const& rules,
|
||||
STObject const& sigObject) const;
|
||||
|
||||
Expected<void, std::string>
|
||||
checkSingleSign(
|
||||
RequireFullyCanonicalSig requireCanonicalSig,
|
||||
STObject const& sigObject) const;
|
||||
|
||||
Expected<void, std::string>
|
||||
checkMultiSign(
|
||||
RequireFullyCanonicalSig requireCanonicalSig,
|
||||
Rules const& rules) const;
|
||||
Rules const& rules,
|
||||
STObject const& sigObject) const;
|
||||
|
||||
Expected<void, std::string>
|
||||
checkBatchSingleSign(
|
||||
@@ -179,7 +209,7 @@ private:
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
mutable std::vector<uint256> batch_txn_ids_;
|
||||
mutable std::vector<uint256> batchTxnIds_;
|
||||
};
|
||||
|
||||
bool
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -29,15 +29,15 @@
|
||||
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
// If you add an amendment here, then do not forget to increment `numFeatures`
|
||||
// in include/xrpl/protocol/Feature.h.
|
||||
|
||||
XRPL_FEATURE(ConfidentialTransfer, Supported::no, 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::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (MPTDeliveredAmount, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (AMMClawbackRounding, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(TokenEscrow, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (EnforceNFTokenTrustlineV2, Supported::yes, VoteBehavior::DefaultNo)
|
||||
@@ -45,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)
|
||||
@@ -79,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
|
||||
@@ -131,28 +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)
|
||||
XRPL_RETIRE(ImmediateOfferKilled)
|
||||
XRPL_RETIRE(MultiSign)
|
||||
XRPL_RETIRE(NonFungibleTokensV1_1)
|
||||
XRPL_RETIRE(PayChan)
|
||||
XRPL_RETIRE(SortedDirectories)
|
||||
XRPL_RETIRE(TickSize)
|
||||
XRPL_RETIRE(TrustSetAuth)
|
||||
|
||||
@@ -416,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
|
||||
@@ -429,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
|
||||
@@ -457,7 +464,7 @@ LEDGER_ENTRY(ltCREDENTIAL, 0x0081, Credential, credential, ({
|
||||
{sfExpiration, soeOPTIONAL},
|
||||
{sfURI, soeOPTIONAL},
|
||||
{sfIssuerNode, soeREQUIRED},
|
||||
{sfSubjectNode, soeREQUIRED},
|
||||
{sfSubjectNode, soeOPTIONAL},
|
||||
{sfPreviousTxnID, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
}))
|
||||
|
||||
@@ -115,6 +115,7 @@ TYPED_SFIELD(sfFirstNFTokenSequence, UINT32, 50)
|
||||
TYPED_SFIELD(sfOracleDocumentID, UINT32, 51)
|
||||
TYPED_SFIELD(sfPermissionValue, UINT32, 52)
|
||||
TYPED_SFIELD(sfMutableFlags, UINT32, 53)
|
||||
TYPED_SFIELD(sfConfidentialBalanceVersion, UINT32, 54)
|
||||
|
||||
// 64-bit integers (common)
|
||||
TYPED_SFIELD(sfIndexNext, UINT64, 1)
|
||||
@@ -146,6 +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(sfConfidentialOutstandingAmount, UINT64, 30, SField::sMD_BaseTen|SField::sMD_Default)
|
||||
|
||||
// 128-bit
|
||||
TYPED_SFIELD(sfEmailHash, UINT128, 1)
|
||||
@@ -284,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)
|
||||
|
||||
@@ -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},
|
||||
@@ -909,7 +910,7 @@ TRANSACTION(ttVAULT_DEPOSIT, 68, VaultDeposit,
|
||||
TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw,
|
||||
Delegation::delegatable,
|
||||
featureSingleAssetVault,
|
||||
mayDeleteMPT | mustModifyVault,
|
||||
mayDeleteMPT | mayAuthorizeMPT | mustModifyVault,
|
||||
({
|
||||
{sfVaultID, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
@@ -944,6 +945,82 @@ TRANSACTION(ttBATCH, 71, Batch,
|
||||
{sfBatchSigners, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction type converts into confidential MPT balance. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
#include <xrpld/app/tx/detail/ConfidentialConvert.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONFIDENTIAL_CONVERT, 72, ConfidentialConvert,
|
||||
Delegation::delegatable,
|
||||
featureConfidentialTransfer,
|
||||
noPriv,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
{sfMPTAmount, soeREQUIRED},
|
||||
{sfHolderElGamalPublicKey, soeOPTIONAL},
|
||||
{sfHolderEncryptedAmount, soeREQUIRED},
|
||||
{sfIssuerEncryptedAmount, soeREQUIRED},
|
||||
{sfZKProof, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This transaction type merges MPT inbox. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
#include <xrpld/app/tx/detail/ConfidentialMergeInbox.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONFIDENTIAL_MERGE_INBOX, 73, ConfidentialMergeInbox,
|
||||
Delegation::delegatable,
|
||||
featureConfidentialTransfer,
|
||||
noPriv,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This transaction type converts back into public MPT balance. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
#include <xrpld/app/tx/detail/ConfidentialConvertBack.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONFIDENTIAL_CONVERT_BACK, 74, ConfidentialConvertBack,
|
||||
Delegation::delegatable,
|
||||
featureConfidentialTransfer,
|
||||
noPriv,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
{sfMPTAmount, soeREQUIRED},
|
||||
{sfHolderEncryptedAmount, soeREQUIRED},
|
||||
{sfIssuerEncryptedAmount, soeREQUIRED},
|
||||
{sfZKProof, soeREQUIRED},
|
||||
}))
|
||||
|
||||
#if TRANSACTION_INCLUDE
|
||||
#include <xrpld/app/tx/detail/ConfidentialSend.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONFIDENTIAL_SEND, 75, ConfidentialSend,
|
||||
Delegation::delegatable,
|
||||
featureConfidentialTransfer,
|
||||
noPriv,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
{sfDestination, soeREQUIRED},
|
||||
{sfSenderEncryptedAmount, soeREQUIRED},
|
||||
{sfDestinationEncryptedAmount, soeREQUIRED},
|
||||
{sfIssuerEncryptedAmount, soeREQUIRED},
|
||||
{sfZKProof, soeREQUIRED},
|
||||
{sfCredentialIDs, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
#if TRANSACTION_INCLUDE
|
||||
#include <xrpld/app/tx/detail/ConfidentialClawback.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONFIDENTIAL_CLAWBACK, 76, ConfidentialClawback,
|
||||
Delegation::delegatable,
|
||||
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.
|
||||
|
||||
For details, see: https://xrpl.org/amendments.html
|
||||
|
||||
@@ -569,6 +569,7 @@ JSS(settle_delay); // out: AccountChannels
|
||||
JSS(severity); // in: LogLevel
|
||||
JSS(shares); // out: VaultInfo
|
||||
JSS(signature); // out: NetworkOPs, ChannelAuthorize
|
||||
JSS(signature_target); // in: TransactionSign
|
||||
JSS(signature_verified); // out: ChannelVerify
|
||||
JSS(signing_key); // out: NetworkOPs
|
||||
JSS(signing_keys); // out: 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;
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@ Door<Handler>::reOpen()
|
||||
if (ec)
|
||||
{
|
||||
JLOG(j_.error()) << "Open port '" << port_.name
|
||||
<< "' failed: " << ec.message();
|
||||
<< "' failed:" << ec.message();
|
||||
Throw<std::exception>();
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ Door<Handler>::reOpen()
|
||||
if (ec)
|
||||
{
|
||||
JLOG(j_.error()) << "Option for port '" << port_.name
|
||||
<< "' failed: " << ec.message();
|
||||
<< "' failed:" << ec.message();
|
||||
Throw<std::exception>();
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ Door<Handler>::reOpen()
|
||||
if (ec)
|
||||
{
|
||||
JLOG(j_.error()) << "Bind port '" << port_.name
|
||||
<< "' failed: " << ec.message();
|
||||
<< "' failed:" << ec.message();
|
||||
Throw<std::exception>();
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ Door<Handler>::reOpen()
|
||||
if (ec)
|
||||
{
|
||||
JLOG(j_.error()) << "Listen on port '" << port_.name
|
||||
<< "' failed: " << ec.message();
|
||||
<< "' failed:" << ec.message();
|
||||
Throw<std::exception>();
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -20,21 +20,19 @@
|
||||
#ifndef RIPPLE_SHAMAP_SHAMAP_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_SHAMAP_H_INCLUDED
|
||||
|
||||
#include <xrpld/nodestore/Database.h>
|
||||
#include <xrpld/nodestore/NodeObject.h>
|
||||
#include <xrpld/shamap/Family.h>
|
||||
#include <xrpld/shamap/SHAMapAddNode.h>
|
||||
#include <xrpld/shamap/SHAMapInnerNode.h>
|
||||
#include <xrpld/shamap/SHAMapItem.h>
|
||||
#include <xrpld/shamap/SHAMapLeafNode.h>
|
||||
#include <xrpld/shamap/SHAMapMissingNode.h>
|
||||
#include <xrpld/shamap/SHAMapTreeNode.h>
|
||||
#include <xrpld/shamap/TreeNodeCache.h>
|
||||
|
||||
#include <xrpl/basics/IntrusivePointer.h>
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/nodestore/Database.h>
|
||||
#include <xrpl/nodestore/NodeObject.h>
|
||||
#include <xrpl/shamap/Family.h>
|
||||
#include <xrpl/shamap/SHAMapAddNode.h>
|
||||
#include <xrpl/shamap/SHAMapInnerNode.h>
|
||||
#include <xrpl/shamap/SHAMapItem.h>
|
||||
#include <xrpl/shamap/SHAMapLeafNode.h>
|
||||
#include <xrpl/shamap/SHAMapMissingNode.h>
|
||||
#include <xrpl/shamap/SHAMapTreeNode.h>
|
||||
|
||||
#include <set>
|
||||
#include <stack>
|
||||
@@ -20,12 +20,11 @@
|
||||
#ifndef RIPPLE_SHAMAP_SHAMAPACCOUNTSTATELEAFNODE_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_SHAMAPACCOUNTSTATELEAFNODE_H_INCLUDED
|
||||
|
||||
#include <xrpld/shamap/SHAMapItem.h>
|
||||
#include <xrpld/shamap/SHAMapLeafNode.h>
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/shamap/SHAMapItem.h>
|
||||
#include <xrpl/shamap/SHAMapLeafNode.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -20,10 +20,9 @@
|
||||
#ifndef RIPPLE_SHAMAP_SHAMAPINNERNODE_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_SHAMAPINNERNODE_H_INCLUDED
|
||||
|
||||
#include <xrpld/shamap/SHAMapNodeID.h>
|
||||
#include <xrpld/shamap/detail/TaggedPointer.h>
|
||||
|
||||
#include <xrpl/basics/IntrusivePointer.h>
|
||||
#include <xrpl/shamap/SHAMapNodeID.h>
|
||||
#include <xrpl/shamap/detail/TaggedPointer.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef RIPPLE_SHAMAP_SHAMAPLEAFNODE_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_SHAMAPLEAFNODE_H_INCLUDED
|
||||
|
||||
#include <xrpld/shamap/SHAMapItem.h>
|
||||
#include <xrpld/shamap/SHAMapTreeNode.h>
|
||||
#include <xrpl/shamap/SHAMapItem.h>
|
||||
#include <xrpl/shamap/SHAMapTreeNode.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@@ -20,9 +20,8 @@
|
||||
#ifndef RIPPLE_SHAMAP_SHAMAPMISSINGNODE_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_SHAMAPMISSINGNODE_H_INCLUDED
|
||||
|
||||
#include <xrpld/shamap/SHAMapTreeNode.h>
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/shamap/SHAMapTreeNode.h>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <stdexcept>
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_SHAMAP_SHAMAPSYNCFILTER_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_SHAMAPSYNCFILTER_H_INCLUDED
|
||||
|
||||
#include <xrpld/shamap/SHAMapTreeNode.h>
|
||||
#include <xrpl/shamap/SHAMapTreeNode.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
@@ -20,13 +20,12 @@
|
||||
#ifndef RIPPLE_SHAMAP_SHAMAPTREENODE_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_SHAMAPTREENODE_H_INCLUDED
|
||||
|
||||
#include <xrpld/shamap/SHAMapItem.h>
|
||||
#include <xrpld/shamap/SHAMapNodeID.h>
|
||||
|
||||
#include <xrpl/basics/IntrusivePointer.h>
|
||||
#include <xrpl/basics/IntrusiveRefCounts.h>
|
||||
#include <xrpl/basics/SHAMapHash.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/shamap/SHAMapItem.h>
|
||||
#include <xrpl/shamap/SHAMapNodeID.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
@@ -20,12 +20,11 @@
|
||||
#ifndef RIPPLE_SHAMAP_SHAMAPTXLEAFNODE_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_SHAMAPTXLEAFNODE_H_INCLUDED
|
||||
|
||||
#include <xrpld/shamap/SHAMapItem.h>
|
||||
#include <xrpld/shamap/SHAMapLeafNode.h>
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/shamap/SHAMapItem.h>
|
||||
#include <xrpl/shamap/SHAMapLeafNode.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -20,12 +20,11 @@
|
||||
#ifndef RIPPLE_SHAMAP_SHAMAPLEAFTXPLUSMETANODE_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_SHAMAPLEAFTXPLUSMETANODE_H_INCLUDED
|
||||
|
||||
#include <xrpld/shamap/SHAMapItem.h>
|
||||
#include <xrpld/shamap/SHAMapLeafNode.h>
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/shamap/SHAMapItem.h>
|
||||
#include <xrpl/shamap/SHAMapLeafNode.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -20,10 +20,9 @@
|
||||
#ifndef RIPPLE_SHAMAP_TREENODECACHE_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_TREENODECACHE_H_INCLUDED
|
||||
|
||||
#include <xrpld/shamap/SHAMapTreeNode.h>
|
||||
|
||||
#include <xrpl/basics/IntrusivePointer.h>
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
#include <xrpl/shamap/SHAMapTreeNode.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -20,9 +20,8 @@
|
||||
#ifndef RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED
|
||||
#define RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED
|
||||
|
||||
#include <xrpld/shamap/SHAMapTreeNode.h>
|
||||
|
||||
#include <xrpl/basics/IntrusivePointer.h>
|
||||
#include <xrpl/shamap/SHAMapTreeNode.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
@@ -17,10 +17,9 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/shamap/SHAMapInnerNode.h>
|
||||
#include <xrpld/shamap/detail/TaggedPointer.h>
|
||||
|
||||
#include <xrpl/basics/ByteUtilities.h>
|
||||
#include <xrpl/shamap/SHAMapInnerNode.h>
|
||||
#include <xrpl/shamap/detail/TaggedPointer.h>
|
||||
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
@@ -126,10 +126,10 @@ ApplyStateTable::apply(
|
||||
std::optional<TxMeta> metadata;
|
||||
if (!to.open() || isDryRun)
|
||||
{
|
||||
TxMeta meta(tx.getTransactionID(), to.seq(), parentBatchId);
|
||||
TxMeta meta(tx.getTransactionID(), to.seq());
|
||||
|
||||
if (deliver)
|
||||
meta.setDeliveredAmount(*deliver);
|
||||
meta.setDeliveredAmount(deliver);
|
||||
meta.setParentBatchID(parentBatchId);
|
||||
|
||||
Mods newMod;
|
||||
for (auto& item : items_)
|
||||
@@ -682,12 +682,6 @@ ApplyStateTable::threadOwners(
|
||||
if (auto const optSleAcct{(*sle)[~sfAccount]})
|
||||
threadTx(base, meta, *optSleAcct, mods, j);
|
||||
|
||||
// Don't thread a check's sfDestination unless the amendment is
|
||||
// enabled
|
||||
if (ledgerType == ltCHECK &&
|
||||
!base.rules().enabled(fixCheckThreading))
|
||||
break;
|
||||
|
||||
// If sfDestination is present, thread to that account
|
||||
if (auto const optSleDest{(*sle)[~sfDestination]})
|
||||
threadTx(base, meta, *optSleDest, mods, j);
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
std::optional<std::uint64_t>
|
||||
@@ -91,8 +94,21 @@ ApplyView::dirAdd(
|
||||
return page;
|
||||
}
|
||||
|
||||
// We rely on modulo arithmetic of unsigned integers (guaranteed in
|
||||
// [basic.fundamental] paragraph 2) to detect page representation overflow.
|
||||
// For signed integers this would be UB, hence static_assert here.
|
||||
static_assert(std::is_unsigned_v<decltype(page)>);
|
||||
// Defensive check against breaking changes in compiler.
|
||||
static_assert([]<typename T>(std::type_identity<T>) constexpr -> T {
|
||||
T tmp = std::numeric_limits<T>::max();
|
||||
return ++tmp;
|
||||
}(std::type_identity<decltype(page)>{}) == 0);
|
||||
++page;
|
||||
// Check whether we're out of pages.
|
||||
if (++page >= dirNodeMaxPages)
|
||||
if (page == 0)
|
||||
return std::nullopt;
|
||||
if (!rules().enabled(fixDirectoryLimit) &&
|
||||
page >= dirNodeMaxPages) // Old pages limit
|
||||
return std::nullopt;
|
||||
|
||||
// We are about to create a new node; we'll link it to
|
||||
|
||||
@@ -504,7 +504,8 @@ accountHolds(
|
||||
// Only if auth check is needed, as it needs to do an additional read
|
||||
// operation. Note featureSingleAssetVault will affect error codes.
|
||||
if (zeroIfUnauthorized == ahZERO_IF_UNAUTHORIZED &&
|
||||
view.rules().enabled(featureSingleAssetVault))
|
||||
(view.rules().enabled(featureSingleAssetVault) ||
|
||||
view.rules().enabled(featureConfidentialTransfer)))
|
||||
{
|
||||
if (auto const err =
|
||||
requireAuth(view, mptIssue, account, AuthType::StrongAuth);
|
||||
@@ -1242,6 +1243,12 @@ addEmptyHolding(
|
||||
// If the line already exists, don't create it again.
|
||||
if (view.read(index))
|
||||
return tecDUPLICATE;
|
||||
|
||||
// Can the account cover the trust line reserve ?
|
||||
std::uint32_t const ownerCount = sleDst->at(sfOwnerCount);
|
||||
if (priorBalance < view.fees().accountReserve(ownerCount + 1))
|
||||
return tecNO_LINE_INSUF_RESERVE;
|
||||
|
||||
return trustCreate(
|
||||
view,
|
||||
high,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/detail/BatchWriter.h>
|
||||
#include <xrpl/nodestore/detail/BatchWriter.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace NodeStore {
|
||||
@@ -17,11 +17,10 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/Database.h>
|
||||
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/core/CurrentThreadName.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/nodestore/Database.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/detail/DatabaseNodeImp.h>
|
||||
#include <xrpl/nodestore/detail/DatabaseNodeImp.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace NodeStore {
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/detail/DatabaseRotatingImp.h>
|
||||
#include <xrpl/nodestore/detail/DatabaseRotatingImp.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace NodeStore {
|
||||
@@ -17,10 +17,9 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/detail/DecodedBlob.h>
|
||||
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/nodestore/detail/DecodedBlob.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/DummyScheduler.h>
|
||||
#include <xrpl/nodestore/DummyScheduler.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace NodeStore {
|
||||
@@ -17,8 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/detail/DatabaseNodeImp.h>
|
||||
#include <xrpld/nodestore/detail/ManagerImp.h>
|
||||
#include <xrpl/nodestore/detail/DatabaseNodeImp.h>
|
||||
#include <xrpl/nodestore/detail/ManagerImp.h>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
@@ -41,6 +41,27 @@ ManagerImp::missing_backend()
|
||||
"please see the rippled-example.cfg file!");
|
||||
}
|
||||
|
||||
// We shouldn't rely on global variables for lifetime management because their
|
||||
// lifetime is not well-defined. ManagerImp may get destroyed before the Factory
|
||||
// classes, and then, calling Manager::instance().erase() in the destructors of
|
||||
// the Factory classes is an undefined behaviour.
|
||||
void
|
||||
registerNuDBFactory(Manager& manager);
|
||||
void
|
||||
registerRocksDBFactory(Manager& manager);
|
||||
void
|
||||
registerNullFactory(Manager& manager);
|
||||
void
|
||||
registerMemoryFactory(Manager& manager);
|
||||
|
||||
ManagerImp::ManagerImp()
|
||||
{
|
||||
registerNuDBFactory(*this);
|
||||
registerRocksDBFactory(*this);
|
||||
registerNullFactory(*this);
|
||||
registerMemoryFactory(*this);
|
||||
}
|
||||
|
||||
std::unique_ptr<Backend>
|
||||
ManagerImp::make_Backend(
|
||||
Section const& parameters,
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/NodeObject.h>
|
||||
#include <xrpl/nodestore/NodeObject.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -17,10 +17,9 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/Factory.h>
|
||||
#include <xrpld/nodestore/Manager.h>
|
||||
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/nodestore/Factory.h>
|
||||
#include <xrpl/nodestore/Manager.h>
|
||||
|
||||
#include <boost/beast/core/string.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
@@ -46,10 +45,10 @@ class MemoryFactory : public Factory
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
std::map<std::string, MemoryDB, boost::beast::iless> map_;
|
||||
Manager& manager_;
|
||||
|
||||
public:
|
||||
MemoryFactory();
|
||||
~MemoryFactory() override;
|
||||
explicit MemoryFactory(Manager& manager);
|
||||
|
||||
std::string
|
||||
getName() const override;
|
||||
@@ -75,7 +74,14 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static MemoryFactory memoryFactory;
|
||||
MemoryFactory* memoryFactory = nullptr;
|
||||
|
||||
void
|
||||
registerMemoryFactory(Manager& manager)
|
||||
{
|
||||
static MemoryFactory instance{manager};
|
||||
memoryFactory = &instance;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -112,9 +118,9 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
open(bool createIfMissing) override
|
||||
open(bool) override
|
||||
{
|
||||
db_ = &memoryFactory.open(name_);
|
||||
db_ = &memoryFactory->open(name_);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -219,14 +225,9 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
MemoryFactory::MemoryFactory()
|
||||
MemoryFactory::MemoryFactory(Manager& manager) : manager_(manager)
|
||||
{
|
||||
Manager::instance().insert(*this);
|
||||
}
|
||||
|
||||
MemoryFactory::~MemoryFactory()
|
||||
{
|
||||
Manager::instance().erase(*this);
|
||||
manager_.insert(*this);
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -17,14 +17,14 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/Factory.h>
|
||||
#include <xrpld/nodestore/Manager.h>
|
||||
#include <xrpld/nodestore/detail/DecodedBlob.h>
|
||||
#include <xrpld/nodestore/detail/EncodedBlob.h>
|
||||
#include <xrpld/nodestore/detail/codec.h>
|
||||
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/beast/core/LexicalCast.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/nodestore/Factory.h>
|
||||
#include <xrpl/nodestore/Manager.h>
|
||||
#include <xrpl/nodestore/detail/DecodedBlob.h>
|
||||
#include <xrpl/nodestore/detail/EncodedBlob.h>
|
||||
#include <xrpl/nodestore/detail/codec.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
@@ -52,6 +52,7 @@ public:
|
||||
size_t const keyBytes_;
|
||||
std::size_t const burstSize_;
|
||||
std::string const name_;
|
||||
std::size_t const blockSize_;
|
||||
nudb::store db_;
|
||||
std::atomic<bool> deletePath_;
|
||||
Scheduler& scheduler_;
|
||||
@@ -66,6 +67,7 @@ public:
|
||||
, keyBytes_(keyBytes)
|
||||
, burstSize_(burstSize)
|
||||
, name_(get(keyValues, "path"))
|
||||
, blockSize_(parseBlockSize(name_, keyValues, journal))
|
||||
, deletePath_(false)
|
||||
, scheduler_(scheduler)
|
||||
{
|
||||
@@ -85,6 +87,7 @@ public:
|
||||
, keyBytes_(keyBytes)
|
||||
, burstSize_(burstSize)
|
||||
, name_(get(keyValues, "path"))
|
||||
, blockSize_(parseBlockSize(name_, keyValues, journal))
|
||||
, db_(context)
|
||||
, deletePath_(false)
|
||||
, scheduler_(scheduler)
|
||||
@@ -114,6 +117,12 @@ public:
|
||||
return name_;
|
||||
}
|
||||
|
||||
std::optional<std::size_t>
|
||||
getBlockSize() const override
|
||||
{
|
||||
return blockSize_;
|
||||
}
|
||||
|
||||
void
|
||||
open(bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt)
|
||||
override
|
||||
@@ -145,7 +154,7 @@ public:
|
||||
uid,
|
||||
salt,
|
||||
keyBytes_,
|
||||
nudb::block_size(kp),
|
||||
blockSize_,
|
||||
0.50,
|
||||
ec);
|
||||
if (ec == nudb::errc::file_exists)
|
||||
@@ -361,21 +370,69 @@ public:
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
private:
|
||||
static std::size_t
|
||||
parseBlockSize(
|
||||
std::string const& name,
|
||||
Section const& keyValues,
|
||||
beast::Journal journal)
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
auto const folder = path(name);
|
||||
auto const kp = (folder / "nudb.key").string();
|
||||
|
||||
std::size_t const defaultSize =
|
||||
nudb::block_size(kp); // Default 4K from NuDB
|
||||
std::size_t blockSize = defaultSize;
|
||||
std::string blockSizeStr;
|
||||
|
||||
if (!get_if_exists(keyValues, "nudb_block_size", blockSizeStr))
|
||||
{
|
||||
return blockSize; // Early return with default
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::size_t const parsedBlockSize =
|
||||
beast::lexicalCastThrow<std::size_t>(blockSizeStr);
|
||||
|
||||
// Validate: must be power of 2 between 4K and 32K
|
||||
if (parsedBlockSize < 4096 || parsedBlockSize > 32768 ||
|
||||
(parsedBlockSize & (parsedBlockSize - 1)) != 0)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "Invalid nudb_block_size: " << parsedBlockSize
|
||||
<< ". Must be power of 2 between 4096 and 32768.";
|
||||
Throw<std::runtime_error>(s.str());
|
||||
}
|
||||
|
||||
JLOG(journal.info())
|
||||
<< "Using custom NuDB block size: " << parsedBlockSize
|
||||
<< " bytes";
|
||||
return parsedBlockSize;
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "Invalid nudb_block_size value: " << blockSizeStr
|
||||
<< ". Error: " << e.what();
|
||||
Throw<std::runtime_error>(s.str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class NuDBFactory : public Factory
|
||||
{
|
||||
public:
|
||||
NuDBFactory()
|
||||
{
|
||||
Manager::instance().insert(*this);
|
||||
}
|
||||
private:
|
||||
Manager& manager_;
|
||||
|
||||
~NuDBFactory() override
|
||||
public:
|
||||
explicit NuDBFactory(Manager& manager) : manager_(manager)
|
||||
{
|
||||
Manager::instance().erase(*this);
|
||||
manager_.insert(*this);
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -410,7 +467,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static NuDBFactory nuDBFactory;
|
||||
void
|
||||
registerNuDBFactory(Manager& manager)
|
||||
{
|
||||
static NuDBFactory instance{manager};
|
||||
}
|
||||
|
||||
} // namespace NodeStore
|
||||
} // namespace ripple
|
||||
@@ -17,8 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/nodestore/Factory.h>
|
||||
#include <xrpld/nodestore/Manager.h>
|
||||
#include <xrpl/nodestore/Factory.h>
|
||||
#include <xrpl/nodestore/Manager.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -111,15 +111,13 @@ private:
|
||||
|
||||
class NullFactory : public Factory
|
||||
{
|
||||
public:
|
||||
NullFactory()
|
||||
{
|
||||
Manager::instance().insert(*this);
|
||||
}
|
||||
private:
|
||||
Manager& manager_;
|
||||
|
||||
~NullFactory() override
|
||||
public:
|
||||
explicit NullFactory(Manager& manager) : manager_(manager)
|
||||
{
|
||||
Manager::instance().erase(*this);
|
||||
manager_.insert(*this);
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -140,7 +138,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static NullFactory nullFactory;
|
||||
void
|
||||
registerNullFactory(Manager& manager)
|
||||
{
|
||||
static NullFactory instance{manager};
|
||||
}
|
||||
|
||||
} // namespace NodeStore
|
||||
} // namespace ripple
|
||||
@@ -17,20 +17,18 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpld/unity/rocksdb.h>
|
||||
#include <xrpl/basics/rocksdb.h>
|
||||
|
||||
#if RIPPLE_ROCKSDB_AVAILABLE
|
||||
#include <xrpld/core/Config.h> // VFALCO Bad dependency
|
||||
#include <xrpld/nodestore/Factory.h>
|
||||
#include <xrpld/nodestore/Manager.h>
|
||||
#include <xrpld/nodestore/detail/BatchWriter.h>
|
||||
#include <xrpld/nodestore/detail/DecodedBlob.h>
|
||||
#include <xrpld/nodestore/detail/EncodedBlob.h>
|
||||
|
||||
#include <xrpl/basics/ByteUtilities.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
#include <xrpl/beast/core/CurrentThreadName.h>
|
||||
#include <xrpl/nodestore/Factory.h>
|
||||
#include <xrpl/nodestore/Manager.h>
|
||||
#include <xrpl/nodestore/detail/BatchWriter.h>
|
||||
#include <xrpl/nodestore/detail/DecodedBlob.h>
|
||||
#include <xrpl/nodestore/detail/EncodedBlob.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
@@ -461,17 +459,15 @@ public:
|
||||
|
||||
class RocksDBFactory : public Factory
|
||||
{
|
||||
private:
|
||||
Manager& manager_;
|
||||
|
||||
public:
|
||||
RocksDBEnv m_env;
|
||||
|
||||
RocksDBFactory()
|
||||
RocksDBFactory(Manager& manager) : manager_(manager)
|
||||
{
|
||||
Manager::instance().insert(*this);
|
||||
}
|
||||
|
||||
~RocksDBFactory() override
|
||||
{
|
||||
Manager::instance().erase(*this);
|
||||
manager_.insert(*this);
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -493,7 +489,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static RocksDBFactory rocksDBFactory;
|
||||
void
|
||||
registerRocksDBFactory(Manager& manager)
|
||||
{
|
||||
static RocksDBFactory instance{manager};
|
||||
}
|
||||
|
||||
} // namespace NodeStore
|
||||
} // namespace ripple
|
||||
607
src/libxrpl/protocol/ConfidentialTransfer.cpp
Normal file
607
src/libxrpl/protocol/ConfidentialTransfer.cpp
Normal file
@@ -0,0 +1,607 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/protocol/ConfidentialTransfer.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
namespace ripple {
|
||||
int
|
||||
secp256k1_elgamal_generate_keypair(
|
||||
secp256k1_context const* ctx,
|
||||
unsigned char* privkey,
|
||||
secp256k1_pubkey* pubkey)
|
||||
{
|
||||
// 1. Generate 32 random bytes for the private key
|
||||
do
|
||||
{
|
||||
if (RAND_bytes(privkey, 32) != 1)
|
||||
{
|
||||
return 0; // Failure
|
||||
}
|
||||
// 2. Verify the random data is a valid private key.
|
||||
} while (secp256k1_ec_seckey_verify(ctx, privkey) != 1);
|
||||
|
||||
// 3. Create the corresponding public key.
|
||||
if (secp256k1_ec_pubkey_create(ctx, pubkey, privkey) != 1)
|
||||
{
|
||||
return 0; // Failure
|
||||
}
|
||||
|
||||
return 1; // Success
|
||||
}
|
||||
|
||||
// ... implementation of secp256k1_elgamal_encrypt ...
|
||||
|
||||
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)
|
||||
{
|
||||
secp256k1_pubkey S;
|
||||
|
||||
// First, calculate C1 = k * G
|
||||
if (secp256k1_ec_pubkey_create(ctx, c1, blinding_factor) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Next, calculate the shared secret S = k * Q
|
||||
S = *pubkey_Q;
|
||||
if (secp256k1_ec_pubkey_tweak_mul(ctx, &S, blinding_factor) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --- Handle the amount ---
|
||||
if (amount == 0)
|
||||
{
|
||||
// For amount = 0, C2 = S.
|
||||
*c2 = S;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For non-zero amounts, proceed as before.
|
||||
unsigned char amount_scalar[32] = {0};
|
||||
secp256k1_pubkey M;
|
||||
secp256k1_pubkey const* points_to_add[2];
|
||||
|
||||
// Convert amount to a 32-byte BIG-ENDIAN scalar.
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
amount_scalar[31 - i] = (amount >> (i * 8)) & 0xFF;
|
||||
}
|
||||
|
||||
// Calculate M = amount * G
|
||||
if (secp256k1_ec_pubkey_create(ctx, &M, amount_scalar) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate C2 = M + S
|
||||
points_to_add[0] = &M;
|
||||
points_to_add[1] = &S;
|
||||
if (secp256k1_ec_pubkey_combine(ctx, c2, points_to_add, 2) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1; // Success
|
||||
}
|
||||
|
||||
// ... implementation of secp256k1_elgamal_decrypt ...
|
||||
int
|
||||
secp256k1_elgamal_decrypt(
|
||||
secp256k1_context const* ctx,
|
||||
uint64_t* amount,
|
||||
secp256k1_pubkey const* c1,
|
||||
secp256k1_pubkey const* c2,
|
||||
unsigned char const* privkey)
|
||||
{
|
||||
secp256k1_pubkey S, M, G_point, current_M, next_M;
|
||||
secp256k1_pubkey const* points_to_add[2];
|
||||
unsigned char c2_bytes[33], s_bytes[33], m_bytes[33], current_m_bytes[33];
|
||||
size_t len;
|
||||
uint64_t i;
|
||||
|
||||
/* Create the scalar '1' in big-endian format */
|
||||
unsigned char one_scalar[32] = {0};
|
||||
one_scalar[31] = 1;
|
||||
|
||||
/* --- Executable Code --- */
|
||||
|
||||
// 1. Calculate S = privkey * C1
|
||||
S = *c1;
|
||||
if (secp256k1_ec_pubkey_tweak_mul(ctx, &S, privkey) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 2. Check for amount = 0 by comparing serialized points
|
||||
len = sizeof(c2_bytes);
|
||||
if (secp256k1_ec_pubkey_serialize(
|
||||
ctx, c2_bytes, &len, c2, SECP256K1_EC_COMPRESSED) != 1)
|
||||
return 0;
|
||||
len = sizeof(s_bytes);
|
||||
if (secp256k1_ec_pubkey_serialize(
|
||||
ctx, s_bytes, &len, &S, SECP256K1_EC_COMPRESSED) != 1)
|
||||
return 0;
|
||||
if (memcmp(c2_bytes, s_bytes, sizeof(c2_bytes)) == 0)
|
||||
{
|
||||
*amount = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 3. Recover M = C2 - S
|
||||
if (secp256k1_ec_pubkey_negate(ctx, &S) != 1)
|
||||
return 0;
|
||||
points_to_add[0] = c2;
|
||||
points_to_add[1] = &S;
|
||||
if (secp256k1_ec_pubkey_combine(ctx, &M, points_to_add, 2) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 4. Serialize M once for comparison in the loop
|
||||
len = sizeof(m_bytes);
|
||||
if (secp256k1_ec_pubkey_serialize(
|
||||
ctx, m_bytes, &len, &M, SECP256K1_EC_COMPRESSED) != 1)
|
||||
return 0;
|
||||
|
||||
// 5. Brute-force search loop
|
||||
if (secp256k1_ec_pubkey_create(ctx, &G_point, one_scalar) != 1)
|
||||
return 0;
|
||||
current_M = G_point;
|
||||
|
||||
for (i = 1; i <= 1000000; ++i)
|
||||
{
|
||||
len = sizeof(current_m_bytes);
|
||||
if (secp256k1_ec_pubkey_serialize(
|
||||
ctx,
|
||||
current_m_bytes,
|
||||
&len,
|
||||
¤t_M,
|
||||
SECP256K1_EC_COMPRESSED) != 1)
|
||||
return 0;
|
||||
if (memcmp(m_bytes, current_m_bytes, sizeof(m_bytes)) == 0)
|
||||
{
|
||||
*amount = i;
|
||||
return 1;
|
||||
}
|
||||
|
||||
points_to_add[0] = ¤t_M;
|
||||
points_to_add[1] = &G_point;
|
||||
if (secp256k1_ec_pubkey_combine(ctx, &next_M, points_to_add, 2) != 1)
|
||||
return 0;
|
||||
current_M = next_M;
|
||||
}
|
||||
|
||||
return 0; // Not found
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
secp256k1_pubkey const* c1_points[2] = {a_c1, b_c1};
|
||||
if (secp256k1_ec_pubkey_combine(ctx, sum_c1, c1_points, 2) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
secp256k1_pubkey const* c2_points[2] = {a_c2, b_c2};
|
||||
if (secp256k1_ec_pubkey_combine(ctx, sum_c2, c2_points, 2) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// To subtract, we add the negation: (A - B) is (A + (-B))
|
||||
// Make a local, modifiable copy of B's points.
|
||||
secp256k1_pubkey neg_b_c1 = *b_c1;
|
||||
secp256k1_pubkey neg_b_c2 = *b_c2;
|
||||
|
||||
// Negate the copies
|
||||
if (secp256k1_ec_pubkey_negate(ctx, &neg_b_c1) != 1 ||
|
||||
secp256k1_ec_pubkey_negate(ctx, &neg_b_c2) != 1)
|
||||
{
|
||||
return 0; // Negation failed
|
||||
}
|
||||
|
||||
// Now, add A and the negated copies of B
|
||||
secp256k1_pubkey const* c1_points[2] = {a_c1, &neg_b_c1};
|
||||
if (secp256k1_ec_pubkey_combine(ctx, diff_c1, c1_points, 2) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
secp256k1_pubkey const* c2_points[2] = {a_c2, &neg_b_c2};
|
||||
if (secp256k1_ec_pubkey_combine(ctx, diff_c2, c2_points, 2) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1; // Success
|
||||
}
|
||||
|
||||
// Helper function to concatenate data for hashing
|
||||
static void
|
||||
build_hash_input(
|
||||
unsigned char* output_buffer,
|
||||
size_t buffer_size,
|
||||
unsigned char const* account_id, // 20 bytes
|
||||
unsigned char const* mpt_issuance_id // 24 bytes
|
||||
)
|
||||
{
|
||||
char const* domain_separator = "EncZero";
|
||||
size_t domain_len = strlen(domain_separator);
|
||||
size_t offset = 0;
|
||||
|
||||
// Ensure buffer is large enough (should be checked by caller if necessary)
|
||||
// Size = strlen("EncZero") + 20 + 24 = 7 + 20 + 24 = 51 bytes
|
||||
|
||||
memcpy(output_buffer + offset, domain_separator, domain_len);
|
||||
offset += domain_len;
|
||||
|
||||
memcpy(output_buffer + offset, account_id, 20);
|
||||
offset += 20;
|
||||
|
||||
memcpy(output_buffer + offset, mpt_issuance_id, 24);
|
||||
// offset += 24; // Final size is offset + 24
|
||||
}
|
||||
|
||||
// The canonical encrypted zero
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
unsigned char deterministic_scalar[32];
|
||||
unsigned char hash_input[51]; // Size calculated above
|
||||
|
||||
/* 1. Create the input buffer for hashing */
|
||||
build_hash_input(
|
||||
hash_input, sizeof(hash_input), account_id, mpt_issuance_id);
|
||||
|
||||
/* 2. Hash the buffer to create the deterministic scalar 'r' */
|
||||
do
|
||||
{
|
||||
// Hash the concatenated bytes
|
||||
SHA256(hash_input, sizeof(hash_input), deterministic_scalar);
|
||||
|
||||
/* Note: If the hash output could be invalid (0 or >= n),
|
||||
* you might need to add a nonce/counter to hash_input
|
||||
* and re-hash in a loop until a valid scalar is produced. */
|
||||
} while (secp256k1_ec_seckey_verify(ctx, deterministic_scalar) != 1);
|
||||
|
||||
/* 3. Encrypt the amount 0 using the deterministic scalar */
|
||||
return secp256k1_elgamal_encrypt(
|
||||
ctx,
|
||||
enc_zero_c1,
|
||||
enc_zero_c2,
|
||||
pubkey,
|
||||
0, /* The amount is zero */
|
||||
deterministic_scalar);
|
||||
}
|
||||
|
||||
bool
|
||||
makeEcPair(Slice const& buffer, secp256k1_pubkey& out1, secp256k1_pubkey& out2)
|
||||
{
|
||||
auto parsePubKey = [](Slice const& slice, secp256k1_pubkey& out) {
|
||||
return secp256k1_ec_pubkey_parse(
|
||||
secp256k1Context(),
|
||||
&out,
|
||||
reinterpret_cast<unsigned char const*>(slice.data()),
|
||||
slice.length());
|
||||
};
|
||||
|
||||
Slice s1{buffer.data(), ecGamalEncryptedLength};
|
||||
Slice s2{buffer.data() + ecGamalEncryptedLength, ecGamalEncryptedLength};
|
||||
|
||||
int const ret1 = parsePubKey(s1, out1);
|
||||
int const ret2 = parsePubKey(s2, out2);
|
||||
|
||||
return ret1 == 1 && ret2 == 1;
|
||||
}
|
||||
|
||||
bool
|
||||
serializeEcPair(
|
||||
secp256k1_pubkey const& in1,
|
||||
secp256k1_pubkey const& in2,
|
||||
Buffer& buffer)
|
||||
{
|
||||
auto serializePubKey = [](secp256k1_pubkey const& pub, unsigned char* out) {
|
||||
size_t outLen = ecGamalEncryptedLength; // 33 bytes
|
||||
int const ret = secp256k1_ec_pubkey_serialize(
|
||||
secp256k1Context(), out, &outLen, &pub, SECP256K1_EC_COMPRESSED);
|
||||
return ret == 1 && outLen == ecGamalEncryptedLength;
|
||||
};
|
||||
|
||||
unsigned char* ptr = buffer.data();
|
||||
bool const res1 = serializePubKey(in1, ptr);
|
||||
bool const res2 = serializePubKey(in2, ptr + ecGamalEncryptedLength);
|
||||
|
||||
return res1 && res2;
|
||||
}
|
||||
|
||||
bool
|
||||
isValidCiphertext(Slice const& buffer)
|
||||
{
|
||||
// Local/temporary variables to pass to makeEcPair.
|
||||
// Their contents will be discarded when the function returns.
|
||||
secp256k1_pubkey key1;
|
||||
secp256k1_pubkey key2;
|
||||
|
||||
// Call makeEcPair and return its result.
|
||||
return makeEcPair(buffer, key1, key2);
|
||||
}
|
||||
|
||||
TER
|
||||
homomorphicAdd(Slice const& a, Slice const& b, Buffer& out)
|
||||
{
|
||||
if (a.length() != ecGamalEncryptedTotalLength ||
|
||||
b.length() != ecGamalEncryptedTotalLength)
|
||||
return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey aC1;
|
||||
secp256k1_pubkey aC2;
|
||||
secp256k1_pubkey bC1;
|
||||
secp256k1_pubkey bC2;
|
||||
|
||||
if (!makeEcPair(a, aC1, aC2) || !makeEcPair(b, bC1, bC2))
|
||||
return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey sumC1;
|
||||
secp256k1_pubkey sumC2;
|
||||
|
||||
if (secp256k1_elgamal_add(
|
||||
secp256k1Context(), &sumC1, &sumC2, &aC1, &aC2, &bC1, &bC2) != 1)
|
||||
return tecINTERNAL;
|
||||
|
||||
if (!serializeEcPair(sumC1, sumC2, out))
|
||||
return tecINTERNAL;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
homomorphicSubtract(Slice const& a, Slice const& b, Buffer& out)
|
||||
{
|
||||
if (a.length() != ecGamalEncryptedTotalLength ||
|
||||
b.length() != ecGamalEncryptedTotalLength)
|
||||
return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey aC1;
|
||||
secp256k1_pubkey aC2;
|
||||
secp256k1_pubkey bC1;
|
||||
secp256k1_pubkey bC2;
|
||||
|
||||
if (!makeEcPair(a, aC1, aC2) || !makeEcPair(b, bC1, bC2))
|
||||
return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey diffC1;
|
||||
secp256k1_pubkey diffC2;
|
||||
|
||||
if (secp256k1_elgamal_subtract(
|
||||
secp256k1Context(), &diffC1, &diffC2, &aC1, &aC2, &bC1, &bC2) != 1)
|
||||
return tecINTERNAL;
|
||||
|
||||
if (!serializeEcPair(diffC1, diffC2, out))
|
||||
return tecINTERNAL;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (proof.length() != ecEqualityProofLength)
|
||||
return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey c1;
|
||||
secp256k1_pubkey c2;
|
||||
|
||||
if (!makeEcPair(encAmt, c1, c2))
|
||||
return tecINTERNAL;
|
||||
|
||||
// todo: might need to change how its hashed
|
||||
Serializer s;
|
||||
s.addRaw(txHash.data(), txHash.bytes);
|
||||
s.add32(spendVersion);
|
||||
// auto const txContextId = s.getSHA512Half();
|
||||
|
||||
// todo: support equality
|
||||
// if (secp256k1_equality_verify(
|
||||
// secp256k1Context(),
|
||||
// reinterpret_cast<unsigned char const*>(proof.data()),
|
||||
// proof.length(), // Length of the proof byte array (98 bytes)
|
||||
// &c1,
|
||||
// &c2,
|
||||
// reinterpret_cast<unsigned char const*>(pubkey.data()),
|
||||
// amount,
|
||||
// txContextId.data(), // Transaction context data
|
||||
// txContextId.bytes // Length of context data
|
||||
// ) != 1)
|
||||
// return tecBAD_PROOF;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
Buffer
|
||||
encryptAmount(uint64_t amt, Slice const& pubKeySlice)
|
||||
{
|
||||
Buffer buf(ecGamalEncryptedTotalLength);
|
||||
|
||||
// Allocate ciphertext placeholders
|
||||
secp256k1_pubkey c1, c2;
|
||||
|
||||
// todo: might need to be updated using another RNG
|
||||
// Prepare a random blinding factor
|
||||
unsigned char blindingFactor[32];
|
||||
if (RAND_bytes(blindingFactor, 32) != 1)
|
||||
Throw<std::runtime_error>("Failed to generate random number");
|
||||
|
||||
secp256k1_pubkey pubKey;
|
||||
|
||||
std::memcpy(pubKey.data, pubKeySlice.data(), ecPubKeyLength);
|
||||
|
||||
// Encrypt the amount
|
||||
if (!secp256k1_elgamal_encrypt(
|
||||
secp256k1Context(), &c1, &c2, &pubKey, amt, blindingFactor))
|
||||
Throw<std::runtime_error>("Failed to encrypt amount");
|
||||
|
||||
// Serialize the ciphertext pair into the buffer
|
||||
if (!serializeEcPair(c1, c2, buf))
|
||||
Throw<std::runtime_error>(
|
||||
"Failed to serialize into 66 byte compressed format");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
Buffer
|
||||
encryptCanonicalZeroAmount(
|
||||
Slice const& pubKeySlice,
|
||||
AccountID const& account,
|
||||
MPTID const& mptId)
|
||||
{
|
||||
Buffer buf(ecGamalEncryptedTotalLength);
|
||||
|
||||
// Allocate ciphertext placeholders
|
||||
secp256k1_pubkey c1, c2;
|
||||
secp256k1_pubkey pubKey;
|
||||
|
||||
std::memcpy(pubKey.data, pubKeySlice.data(), ecPubKeyLength);
|
||||
|
||||
// Encrypt the amount
|
||||
if (!generate_canonical_encrypted_zero(
|
||||
secp256k1Context(),
|
||||
&c1,
|
||||
&c2,
|
||||
&pubKey,
|
||||
account.data(),
|
||||
mptId.data()))
|
||||
Throw<std::runtime_error>("Failed to encrypt amount");
|
||||
|
||||
// Serialize the ciphertext pair into the buffer
|
||||
if (!serializeEcPair(c1, c2, buf))
|
||||
Throw<std::runtime_error>(
|
||||
"Failed to serialize into 66 byte compressed format");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// if (proof.length() != ecConfidentialSendProofLength)
|
||||
// return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey balC1, balC2;
|
||||
if (!makeEcPair(encSenderBalance, balC1, balC2))
|
||||
return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey senderC1, senderC2;
|
||||
if (!makeEcPair(encSenderAmt, senderC1, senderC2))
|
||||
return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey destC1, destC2;
|
||||
if (!makeEcPair(encDestAmt, destC1, destC2))
|
||||
return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey issuerC1, issuerC2;
|
||||
if (!makeEcPair(encIssuerAmt, issuerC1, issuerC2))
|
||||
return tecINTERNAL;
|
||||
|
||||
Serializer s;
|
||||
s.addRaw(txHash.data(), txHash.bytes);
|
||||
s.add32(version);
|
||||
// auto const txContextId = s.getSHA512Half();
|
||||
|
||||
// todo: equality and range proof verification
|
||||
// if (secp256k1_equal_range_verify(
|
||||
// secp256k1Context(),
|
||||
// reinterpret_cast<unsigned char const*>(proof.data()),
|
||||
// proof.length(),
|
||||
// txContextId.data(),
|
||||
// &balC1,
|
||||
// &balC2,
|
||||
// &senderC1,
|
||||
// &senderC2,
|
||||
// reinterpret_cast<unsigned char const*>(senderPubKey.data()),
|
||||
// &destC1,
|
||||
// &destC2,
|
||||
// reinterpret_cast<unsigned char const*>(destPubKey.data()),
|
||||
// &issuerC1,
|
||||
// &issuerC2,
|
||||
// reinterpret_cast<unsigned char const*>(issuerPubKey.data()),
|
||||
// txContextId.data(),
|
||||
// txContextId.bytes) != 1)
|
||||
// return tecBAD_PROOF;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
@@ -174,21 +174,22 @@ Permission::isDelegatable(
|
||||
auto const txType = permissionToTxType(permissionValue);
|
||||
auto const it = delegatableTx_.find(txType);
|
||||
|
||||
if (rules.enabled(fixDelegateV1_1))
|
||||
{
|
||||
if (it == delegatableTx_.end())
|
||||
return false;
|
||||
if (it == delegatableTx_.end())
|
||||
return false;
|
||||
|
||||
auto const feature = getTxFeature(txType);
|
||||
auto const txFeaturesIt = txFeatureMap_.find(txType);
|
||||
XRPL_ASSERT(
|
||||
txFeaturesIt != txFeatureMap_.end(),
|
||||
"ripple::Permissions::isDelegatable : tx exists in txFeatureMap_");
|
||||
|
||||
// fixDelegateV1_1: Delegation is only allowed if the required amendment
|
||||
// for the transaction is enabled. For transactions that do not require
|
||||
// an amendment, delegation is always allowed.
|
||||
if (feature && !rules.enabled(*feature))
|
||||
return false;
|
||||
}
|
||||
// Delegation is only allowed if the required amendment for the transaction
|
||||
// is enabled. For transactions that do not require an amendment, delegation
|
||||
// is always allowed.
|
||||
if (txFeaturesIt->second != uint256{} &&
|
||||
!rules.enabled(txFeaturesIt->second))
|
||||
return false;
|
||||
|
||||
if (it != delegatableTx_.end() && it->second == Delegation::notDelegatable)
|
||||
if (it->second == Delegation::notDelegatable)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -131,17 +131,6 @@ Rules::enabled(uint256 const& feature) const
|
||||
{
|
||||
XRPL_ASSERT(impl_, "ripple::Rules::enabled : initialized");
|
||||
|
||||
// The functionality of the "NonFungibleTokensV1_1" amendment is
|
||||
// precisely the functionality of the following three amendments
|
||||
// so if their status is ever queried individually, we inject an
|
||||
// extra check here to simplify the checking elsewhere.
|
||||
if (feature == featureNonFungibleTokensV1 ||
|
||||
feature == fixNFTokenNegOffer || feature == fixNFTokenDirV1)
|
||||
{
|
||||
if (impl_->enabled(featureNonFungibleTokensV1_1))
|
||||
return true;
|
||||
}
|
||||
|
||||
return impl_->enabled(feature);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,29 +68,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace {
|
||||
|
||||
// Use a static inside a function to help prevent order-of-initialzation issues
|
||||
LocalValue<bool>&
|
||||
getStaticSTAmountCanonicalizeSwitchover()
|
||||
{
|
||||
static LocalValue<bool> r{true};
|
||||
return r;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool
|
||||
getSTAmountCanonicalizeSwitchover()
|
||||
{
|
||||
return *getStaticSTAmountCanonicalizeSwitchover();
|
||||
}
|
||||
|
||||
void
|
||||
setSTAmountCanonicalizeSwitchover(bool v)
|
||||
{
|
||||
*getStaticSTAmountCanonicalizeSwitchover() = v;
|
||||
}
|
||||
|
||||
static std::uint64_t const tenTo14 = 100000000000000ull;
|
||||
static std::uint64_t const tenTo14m1 = tenTo14 - 1;
|
||||
static std::uint64_t const tenTo17 = tenTo14 * 1000;
|
||||
@@ -884,18 +861,14 @@ STAmount::canonicalize()
|
||||
return;
|
||||
}
|
||||
|
||||
if (getSTAmountCanonicalizeSwitchover())
|
||||
{
|
||||
// log(cMaxNativeN, 10) == 17
|
||||
if (native() && mOffset > 17)
|
||||
Throw<std::runtime_error>(
|
||||
"Native currency amount out of range");
|
||||
// log(maxMPTokenAmount, 10) ~ 18.96
|
||||
if (mAsset.holds<MPTIssue>() && mOffset > 18)
|
||||
Throw<std::runtime_error>("MPT amount out of range");
|
||||
}
|
||||
// log(cMaxNativeN, 10) == 17
|
||||
if (native() && mOffset > 17)
|
||||
Throw<std::runtime_error>("Native currency amount out of range");
|
||||
// log(maxMPTokenAmount, 10) ~ 18.96
|
||||
if (mAsset.holds<MPTIssue>() && mOffset > 18)
|
||||
Throw<std::runtime_error>("MPT amount out of range");
|
||||
|
||||
if (getSTNumberSwitchover() && getSTAmountCanonicalizeSwitchover())
|
||||
if (getSTNumberSwitchover())
|
||||
{
|
||||
Number num(
|
||||
mIsNegative ? -mValue : mValue, mOffset, Number::unchecked{});
|
||||
@@ -919,16 +892,14 @@ STAmount::canonicalize()
|
||||
|
||||
while (mOffset > 0)
|
||||
{
|
||||
if (getSTAmountCanonicalizeSwitchover())
|
||||
{
|
||||
// N.B. do not move the overflow check to after the
|
||||
// multiplication
|
||||
if (native() && mValue > cMaxNativeN)
|
||||
Throw<std::runtime_error>(
|
||||
"Native currency amount out of range");
|
||||
else if (!native() && mValue > maxMPTokenAmount)
|
||||
Throw<std::runtime_error>("MPT amount out of range");
|
||||
}
|
||||
// N.B. do not move the overflow check to after the
|
||||
// multiplication
|
||||
if (native() && mValue > cMaxNativeN)
|
||||
Throw<std::runtime_error>(
|
||||
"Native currency amount out of range");
|
||||
else if (!native() && mValue > maxMPTokenAmount)
|
||||
Throw<std::runtime_error>("MPT amount out of range");
|
||||
|
||||
mValue *= 10;
|
||||
--mOffset;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user