mirror of
https://github.com/XRPLF/rippled.git
synced 2026-03-28 15:42:29 +00:00
Compare commits
1 Commits
release-3.
...
legleux/li
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ef1811f63 |
@@ -90,7 +90,6 @@ test.core > xrpl.server
|
||||
test.csf > xrpl.basics
|
||||
test.csf > xrpld.consensus
|
||||
test.csf > xrpl.json
|
||||
test.csf > xrpl.ledger
|
||||
test.csf > xrpl.protocol
|
||||
test.json > test.jtx
|
||||
test.json > xrpl.json
|
||||
@@ -109,6 +108,7 @@ test.jtx > xrpl.tx
|
||||
test.ledger > test.jtx
|
||||
test.ledger > test.toplevel
|
||||
test.ledger > xrpl.basics
|
||||
test.ledger > xrpld.app
|
||||
test.ledger > xrpld.core
|
||||
test.ledger > xrpl.ledger
|
||||
test.ledger > xrpl.protocol
|
||||
@@ -125,7 +125,6 @@ test.overlay > xrpl.basics
|
||||
test.overlay > xrpld.app
|
||||
test.overlay > xrpld.overlay
|
||||
test.overlay > xrpld.peerfinder
|
||||
test.overlay > xrpl.ledger
|
||||
test.overlay > xrpl.nodestore
|
||||
test.overlay > xrpl.protocol
|
||||
test.overlay > xrpl.shamap
|
||||
@@ -235,7 +234,6 @@ xrpld.app > xrpl.shamap
|
||||
xrpld.app > xrpl.tx
|
||||
xrpld.consensus > xrpl.basics
|
||||
xrpld.consensus > xrpl.json
|
||||
xrpld.consensus > xrpl.ledger
|
||||
xrpld.consensus > xrpl.protocol
|
||||
xrpld.core > xrpl.basics
|
||||
xrpld.core > xrpl.core
|
||||
|
||||
14
.github/scripts/strategy-matrix/generate.py
vendored
14
.github/scripts/strategy-matrix/generate.py
vendored
@@ -99,14 +99,15 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
continue
|
||||
|
||||
# RHEL:
|
||||
# - 9 using GCC 12: Debug on linux/amd64.
|
||||
# - 9 using GCC 12: Debug and Release on linux/amd64
|
||||
# (Release is required for RPM packaging).
|
||||
# - 10 using Clang: Release on linux/amd64.
|
||||
if os["distro_name"] == "rhel":
|
||||
skip = True
|
||||
if os["distro_version"] == "9":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
|
||||
and build_type == "Debug"
|
||||
and build_type in ["Debug", "Release"]
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
@@ -121,7 +122,8 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
continue
|
||||
|
||||
# Ubuntu:
|
||||
# - Jammy using GCC 12: Debug on linux/arm64.
|
||||
# - Jammy using GCC 12: Debug on linux/arm64, Release on
|
||||
# linux/amd64 (Release is required for DEB packaging).
|
||||
# - Noble using GCC 14: Release on linux/amd64.
|
||||
# - Noble using Clang 18: Debug on linux/amd64.
|
||||
# - Noble using Clang 19: Release on linux/arm64.
|
||||
@@ -134,6 +136,12 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
and architecture["platform"] == "linux/arm64"
|
||||
):
|
||||
skip = False
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
|
||||
and build_type == "Release"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
elif os["distro_version"] == "noble":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-14"
|
||||
|
||||
25
.github/workflows/conflicting-pr.yml
vendored
25
.github/workflows/conflicting-pr.yml
vendored
@@ -1,25 +0,0 @@
|
||||
name: Label PRs with merge conflicts
|
||||
|
||||
on:
|
||||
# So that PRs touching the same files as the push are updated.
|
||||
push:
|
||||
# So that the `dirtyLabel` is removed if conflicts are resolved.
|
||||
# We recommend `pull_request_target` so that github secrets are available.
|
||||
# In `pull_request` we wouldn't be able to change labels of fork PRs.
|
||||
pull_request_target:
|
||||
types: [synchronize]
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check if PRs are dirty
|
||||
uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3
|
||||
with:
|
||||
dirtyLabel: "PR: has conflicts"
|
||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||
commentOnDirty: "This PR has conflicts, please resolve them in order for the PR to be reviewed."
|
||||
commentOnClean: "All conflicts have been resolved. Assigned reviewers can now start or resume their review."
|
||||
66
.github/workflows/manual-package.yml
vendored
Normal file
66
.github/workflows/manual-package.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
name: Manual Package Build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pkg_type:
|
||||
description: "Package type"
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- deb
|
||||
- rpm
|
||||
- both
|
||||
artifact_run_id:
|
||||
description: "Run ID to download binary artifact from (leave empty for latest on this branch)"
|
||||
required: false
|
||||
type: string
|
||||
version:
|
||||
description: "Version override (leave empty to auto-detect)"
|
||||
required: false
|
||||
type: string
|
||||
pkg_release:
|
||||
description: "Package release number (default: 1)"
|
||||
required: false
|
||||
type: string
|
||||
default: "1"
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
generate-version:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ inputs.version || steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
if: ${{ !inputs.version }}
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Generate version
|
||||
if: ${{ !inputs.version }}
|
||||
id: version
|
||||
uses: ./.github/actions/generate-version
|
||||
|
||||
package-deb:
|
||||
if: ${{ inputs.pkg_type == 'deb' || inputs.pkg_type == 'both' }}
|
||||
needs: generate-version
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
with:
|
||||
pkg_type: deb
|
||||
artifact_name: xrpld-ubuntu-jammy-gcc-12-amd64-release
|
||||
version: ${{ needs.generate-version.outputs.version }}
|
||||
pkg_release: ${{ inputs.pkg_release }}
|
||||
container_image: ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12
|
||||
|
||||
package-rpm:
|
||||
if: ${{ inputs.pkg_type == 'rpm' || inputs.pkg_type == 'both' }}
|
||||
needs: generate-version
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
with:
|
||||
pkg_type: rpm
|
||||
artifact_name: xrpld-rhel-9-gcc-12-amd64-release
|
||||
version: ${{ needs.generate-version.outputs.version }}
|
||||
pkg_release: ${{ inputs.pkg_release }}
|
||||
container_image: ghcr.io/xrplf/ci/rhel-9:gcc-12
|
||||
36
.github/workflows/on-pr.yml
vendored
36
.github/workflows/on-pr.yml
vendored
@@ -67,6 +67,7 @@ jobs:
|
||||
.github/workflows/reusable-build-test.yml
|
||||
.github/workflows/reusable-clang-tidy.yml
|
||||
.github/workflows/reusable-clang-tidy-files.yml
|
||||
.github/workflows/reusable-package.yml
|
||||
.github/workflows/reusable-strategy-matrix.yml
|
||||
.github/workflows/reusable-test.yml
|
||||
.github/workflows/reusable-upload-recipe.yml
|
||||
@@ -81,6 +82,8 @@ jobs:
|
||||
CMakeLists.txt
|
||||
conanfile.py
|
||||
conan.lock
|
||||
package/**
|
||||
|
||||
- name: Check whether to run
|
||||
# This step determines whether the rest of the workflow should
|
||||
# run. The rest of the workflow will run if this job runs AND at
|
||||
@@ -137,6 +140,39 @@ jobs:
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
generate-version:
|
||||
needs: should-run
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Generate version
|
||||
id: version
|
||||
uses: ./.github/actions/generate-version
|
||||
|
||||
package-deb:
|
||||
needs: [should-run, build-test, generate-version]
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
with:
|
||||
pkg_type: deb
|
||||
artifact_name: xrpld-ubuntu-jammy-gcc-12-amd64-release
|
||||
version: ${{ needs.generate-version.outputs.version }}
|
||||
container_image: ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12
|
||||
|
||||
package-rpm:
|
||||
needs: [should-run, build-test, generate-version]
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
with:
|
||||
pkg_type: rpm
|
||||
artifact_name: xrpld-rhel-9-gcc-12-amd64-release
|
||||
version: ${{ needs.generate-version.outputs.version }}
|
||||
container_image: ghcr.io/xrplf/ci/rhel-9:gcc-12
|
||||
|
||||
upload-recipe:
|
||||
needs:
|
||||
- should-run
|
||||
|
||||
50
.github/workflows/on-tag.yml
vendored
50
.github/workflows/on-tag.yml
vendored
@@ -1,5 +1,5 @@
|
||||
# This workflow uploads the libxrpl recipe to the Conan remote when a versioned
|
||||
# tag is pushed.
|
||||
# This workflow uploads the libxrpl recipe to the Conan remote and builds
|
||||
# release packages when a versioned tag is pushed.
|
||||
name: Tag
|
||||
|
||||
on:
|
||||
@@ -22,3 +22,49 @@ jobs:
|
||||
secrets:
|
||||
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
|
||||
|
||||
build-test:
|
||||
if: ${{ github.repository == 'XRPLF/rippled' }}
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [linux]
|
||||
with:
|
||||
ccache_enabled: false
|
||||
os: ${{ matrix.os }}
|
||||
strategy_matrix: minimal
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
generate-version:
|
||||
if: ${{ github.repository == 'XRPLF/rippled' }}
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Generate version
|
||||
id: version
|
||||
uses: ./.github/actions/generate-version
|
||||
|
||||
package-deb:
|
||||
needs: [build-test, generate-version]
|
||||
if: ${{ github.repository == 'XRPLF/rippled' }}
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
with:
|
||||
pkg_type: deb
|
||||
artifact_name: xrpld-ubuntu-jammy-gcc-12-amd64-release
|
||||
version: ${{ needs.generate-version.outputs.version }}
|
||||
container_image: ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12
|
||||
|
||||
package-rpm:
|
||||
needs: [build-test, generate-version]
|
||||
if: ${{ github.repository == 'XRPLF/rippled' }}
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
with:
|
||||
pkg_type: rpm
|
||||
artifact_name: xrpld-rhel-9-gcc-12-amd64-release
|
||||
version: ${{ needs.generate-version.outputs.version }}
|
||||
container_image: ghcr.io/xrplf/ci/rhel-9:gcc-12
|
||||
|
||||
33
.github/workflows/on-trigger.yml
vendored
33
.github/workflows/on-trigger.yml
vendored
@@ -38,6 +38,8 @@ on:
|
||||
- "CMakeLists.txt"
|
||||
- "conanfile.py"
|
||||
- "conan.lock"
|
||||
- "package/**"
|
||||
- ".github/workflows/reusable-package.yml"
|
||||
|
||||
# Run at 06:32 UTC on every day of the week from Monday through Friday. This
|
||||
# will force all dependencies to be rebuilt, which is useful to verify that
|
||||
@@ -77,7 +79,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: ${{ github.event_name == 'merge_group' }}
|
||||
matrix:
|
||||
os: [linux, macos, windows]
|
||||
os: [linux]
|
||||
with:
|
||||
# Enable ccache only for events targeting the XRPLF repository, since
|
||||
# other accounts will not have access to our remote cache storage.
|
||||
@@ -98,3 +100,32 @@ jobs:
|
||||
secrets:
|
||||
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
|
||||
|
||||
generate-version:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Generate version
|
||||
id: version
|
||||
uses: ./.github/actions/generate-version
|
||||
|
||||
package-deb:
|
||||
needs: [build-test, generate-version]
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
with:
|
||||
pkg_type: deb
|
||||
artifact_name: xrpld-ubuntu-jammy-gcc-12-amd64-release
|
||||
version: ${{ needs.generate-version.outputs.version }}
|
||||
container_image: ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12
|
||||
|
||||
package-rpm:
|
||||
needs: [build-test, generate-version]
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
with:
|
||||
pkg_type: rpm
|
||||
artifact_name: xrpld-rhel-9-gcc-12-amd64-release
|
||||
version: ${{ needs.generate-version.outputs.version }}
|
||||
container_image: ghcr.io/xrplf/ci/rhel-9:gcc-12
|
||||
|
||||
2
.github/workflows/reusable-clang-tidy.yml
vendored
2
.github/workflows/reusable-clang-tidy.yml
vendored
@@ -51,5 +51,5 @@ jobs:
|
||||
if: ${{ always() && !cancelled() && (!inputs.check_only_changed || needs.determine-files.outputs.any_cpp_changed == 'true' || needs.determine-files.outputs.clang_tidy_config_changed == 'true') }}
|
||||
uses: ./.github/workflows/reusable-clang-tidy-files.yml
|
||||
with:
|
||||
files: ${{ (needs.determine-files.outputs.clang_tidy_config_changed != 'true' && inputs.check_only_changed) && needs.determine-files.outputs.all_changed_files || '' }}
|
||||
files: ${{ needs.determine-files.outputs.clang_tidy_config_changed == 'true' && '' || (inputs.check_only_changed && needs.determine-files.outputs.all_changed_files || '') }}
|
||||
create_issue_on_failure: ${{ inputs.create_issue_on_failure }}
|
||||
|
||||
76
.github/workflows/reusable-package.yml
vendored
Normal file
76
.github/workflows/reusable-package.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# Build a Linux package (DEB or RPM) from a pre-built binary artifact.
|
||||
name: Package
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
pkg_type:
|
||||
description: "Package type to build: deb or rpm."
|
||||
required: true
|
||||
type: string
|
||||
artifact_name:
|
||||
description: "Name of the pre-built binary artifact to download."
|
||||
required: true
|
||||
type: string
|
||||
version:
|
||||
description: "Version string used for naming the output artifact."
|
||||
required: true
|
||||
type: string
|
||||
pkg_release:
|
||||
description: "Package release number. Increment when repackaging the same executable."
|
||||
required: false
|
||||
type: string
|
||||
default: "1"
|
||||
container_image:
|
||||
description: "Container image to use for packaging."
|
||||
required: true
|
||||
type: string
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
env:
|
||||
BUILD_DIR: build
|
||||
|
||||
jobs:
|
||||
package:
|
||||
name: ${{ inputs.pkg_type }} (${{ inputs.version }})
|
||||
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
|
||||
container: ${{ inputs.container_image }}
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Download pre-built binary
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.artifact_name }}
|
||||
path: ${{ env.BUILD_DIR }}
|
||||
|
||||
- name: Make binary executable
|
||||
run: chmod +x ${{ env.BUILD_DIR }}/xrpld
|
||||
|
||||
- name: Generate RPM spec from template
|
||||
if: ${{ inputs.pkg_type == 'rpm' }}
|
||||
run: |
|
||||
mkdir -p ${{ env.BUILD_DIR }}/package/rpm
|
||||
sed -e "s/@xrpld_version@/${{ inputs.version }}/" \
|
||||
-e "s/@pkg_release@/${{ inputs.pkg_release }}/" \
|
||||
package/rpm/xrpld.spec.in > ${{ env.BUILD_DIR }}/package/rpm/xrpld.spec
|
||||
|
||||
- name: Build package
|
||||
run: |
|
||||
./package/build_pkg.sh ${{ inputs.pkg_type }} . ${{ env.BUILD_DIR }} "${{ inputs.version }}" "${{ inputs.pkg_release }}"
|
||||
|
||||
- name: Upload package artifact
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: xrpld-${{ inputs.pkg_type }}-${{ inputs.version }}
|
||||
path: |
|
||||
${{ env.BUILD_DIR }}/debbuild/*.deb
|
||||
${{ env.BUILD_DIR }}/debbuild/*.ddeb
|
||||
${{ env.BUILD_DIR }}/rpmbuild/RPMS/**/*.rpm
|
||||
if-no-files-found: error
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -71,8 +71,6 @@ DerivedData
|
||||
/.zed/
|
||||
|
||||
# AI tools.
|
||||
/.agent
|
||||
/.agents
|
||||
/.augment
|
||||
/.claude
|
||||
/CLAUDE.md
|
||||
|
||||
77
BUILD.md
77
BUILD.md
@@ -125,9 +125,9 @@ default profile.
|
||||
|
||||
### Patched recipes
|
||||
|
||||
Occasionally, we need patched recipes or recipes not present in Conan Center.
|
||||
We maintain a fork of the Conan Center Index
|
||||
[here](https://github.com/XRPLF/conan-center-index/) containing the modified and newly added recipes.
|
||||
The recipes in Conan Center occasionally need to be patched for compatibility
|
||||
with the latest version of `xrpld`. We maintain a fork of the Conan Center
|
||||
[here](https://github.com/XRPLF/conan-center-index/) containing the patches.
|
||||
|
||||
To ensure our patched recipes are used, you must add our Conan remote at a
|
||||
higher index than the default Conan Center remote, so it is consulted first. You
|
||||
@@ -137,11 +137,19 @@ can do this by running:
|
||||
conan remote add --index 0 xrplf https://conan.ripplex.io
|
||||
```
|
||||
|
||||
Alternatively, you can pull our recipes from the repository and export them locally:
|
||||
Alternatively, you can pull the patched recipes into the repository and use them
|
||||
locally:
|
||||
|
||||
```bash
|
||||
# Extract the version number from the lockfile.
|
||||
function extract_version {
|
||||
version=$(cat conan.lock | sed -nE "s@.+${1}/(.+)#.+@\1@p" | head -n1)
|
||||
echo ${version}
|
||||
}
|
||||
|
||||
# Define which recipes to export.
|
||||
recipes=('abseil' 'ed25519' 'grpc' 'm4' 'mpt-crypto' 'nudb' 'openssl' 'secp256k1' 'snappy' 'soci' 'wasm-xrplf' 'wasmi')
|
||||
recipes=('ed25519' 'grpc' 'nudb' 'openssl' 'secp256k1' 'snappy' 'soci')
|
||||
folders=('all' 'all' 'all' '3.x.x' 'all' 'all' 'all')
|
||||
|
||||
# Selectively check out the recipes from our CCI fork.
|
||||
cd external
|
||||
@@ -150,19 +158,29 @@ cd conan-center-index
|
||||
git init
|
||||
git remote add origin git@github.com:XRPLF/conan-center-index.git
|
||||
git sparse-checkout init
|
||||
for recipe in "${recipes[@]}"; do
|
||||
echo "Checking out recipe '${recipe}'..."
|
||||
git sparse-checkout add recipes/${recipe}
|
||||
for ((index = 1; index <= ${#recipes[@]}; index++)); do
|
||||
recipe=${recipes[index]}
|
||||
folder=${folders[index]}
|
||||
echo "Checking out recipe '${recipe}' from folder '${folder}'..."
|
||||
git sparse-checkout add recipes/${recipe}/${folder}
|
||||
done
|
||||
git fetch origin master
|
||||
git checkout master
|
||||
cd ../..
|
||||
|
||||
./export_all.sh
|
||||
cd ../../
|
||||
# Export the recipes into the local cache.
|
||||
for ((index = 1; index <= ${#recipes[@]}; index++)); do
|
||||
recipe=${recipes[index]}
|
||||
folder=${folders[index]}
|
||||
version=$(extract_version ${recipe})
|
||||
echo "Exporting '${recipe}/${version}' from '${recipe}/${folder}'..."
|
||||
conan export --version $(extract_version ${recipe}) \
|
||||
external/conan-center-index/recipes/${recipe}/${folder}
|
||||
done
|
||||
```
|
||||
|
||||
In the case we switch to a newer version of a dependency that still requires a
|
||||
patch or add a new dependency, it will be necessary for you to pull in the changes and re-export the
|
||||
patch, it will be necessary for you to pull in the changes and re-export the
|
||||
updated dependencies with the newer version. However, if we switch to a newer
|
||||
version that no longer requires a patch, no action is required on your part, as
|
||||
the new recipe will be automatically pulled from the official Conan Center.
|
||||
@@ -171,8 +189,6 @@ the new recipe will be automatically pulled from the official Conan Center.
|
||||
> You might need to add `--lockfile=""` to your `conan install` command
|
||||
> to avoid automatic use of the existing `conan.lock` file when you run
|
||||
> `conan export` manually on your machine
|
||||
>
|
||||
> This is not recommended though, as you might end up using different revisions of recipes.
|
||||
|
||||
### Conan profile tweaks
|
||||
|
||||
@@ -188,14 +204,39 @@ Possible values are ['5.0', '5.1', '6.0', '6.1', '7.0', '7.3', '8.0', '8.1',
|
||||
Read "http://docs.conan.io/2/knowledge/faq.html#error-invalid-setting"
|
||||
```
|
||||
|
||||
you need to add your compiler to the list of compiler versions in
|
||||
`$(conan config home)/settings_user.yml`, by adding the required version number(s)
|
||||
you need to amend the list of compiler versions in
|
||||
`$(conan config home)/settings.yml`, by appending the required version number(s)
|
||||
to the `version` array specific for your compiler. For example:
|
||||
|
||||
```yaml
|
||||
compiler:
|
||||
apple-clang:
|
||||
version: ["17.0"]
|
||||
apple-clang:
|
||||
version:
|
||||
[
|
||||
"5.0",
|
||||
"5.1",
|
||||
"6.0",
|
||||
"6.1",
|
||||
"7.0",
|
||||
"7.3",
|
||||
"8.0",
|
||||
"8.1",
|
||||
"9.0",
|
||||
"9.1",
|
||||
"10.0",
|
||||
"11.0",
|
||||
"12.0",
|
||||
"13",
|
||||
"13.0",
|
||||
"13.1",
|
||||
"14",
|
||||
"14.0",
|
||||
"15",
|
||||
"15.0",
|
||||
"16",
|
||||
"16.0",
|
||||
"17",
|
||||
"17.0",
|
||||
]
|
||||
```
|
||||
|
||||
#### Multiple compilers
|
||||
|
||||
@@ -133,6 +133,7 @@ endif()
|
||||
|
||||
include(XrplCore)
|
||||
include(XrplInstall)
|
||||
include(XrplPackaging)
|
||||
include(XrplValidatorKeys)
|
||||
|
||||
if(tests)
|
||||
|
||||
@@ -259,10 +259,6 @@ There is a Continuous Integration job that runs clang-tidy on pull requests. The
|
||||
|
||||
This ensures that configuration changes don't introduce new warnings across the codebase.
|
||||
|
||||
### Installing clang-tidy
|
||||
|
||||
See the [environment setup guide](./docs/build/environment.md#clang-tidy) for platform-specific installation instructions.
|
||||
|
||||
### Running clang-tidy locally
|
||||
|
||||
Before running clang-tidy, you must build the project to generate required files (particularly protobuf headers). Refer to [`BUILD.md`](./BUILD.md) for build instructions.
|
||||
@@ -270,15 +266,10 @@ Before running clang-tidy, you must build the project to generate required files
|
||||
Then run clang-tidy on your local changes:
|
||||
|
||||
```
|
||||
run-clang-tidy -p build src include tests
|
||||
run-clang-tidy -p build src tests
|
||||
```
|
||||
|
||||
This will check all source files in the `src`, `include` and `tests` directories using the compile commands from your `build` directory.
|
||||
If you wish to automatically fix whatever clang-tidy finds _and_ is capable of fixing, add `-fix` to the above command:
|
||||
|
||||
```
|
||||
run-clang-tidy -p build -fix src include tests
|
||||
```
|
||||
This will check all source files in the `src` and `tests` directories using the compile commands from your `build` directory.
|
||||
|
||||
## Contracts and instrumentation
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2011, Arthur Britto, David Schwartz, Jed McCaleb, Vinnie Falco, Bob Way, Eric Lombrozo, Nikolaos D. Bougalis, Howard Hinnant.
|
||||
Copyright (c) 2012-present, the XRP Ledger developers.
|
||||
Copyright (c) 2012-2025, the XRP Ledger developers.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
||||
@@ -12,14 +12,14 @@ if(is_root_project AND TARGET xrpld)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_SOURCE_DIR}/cfg/xrpld-example.cfg"
|
||||
DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/xrpld"
|
||||
DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}"
|
||||
RENAME xrpld.cfg
|
||||
COMPONENT runtime
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_SOURCE_DIR}/cfg/validators-example.txt"
|
||||
DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/xrpld"
|
||||
DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}"
|
||||
RENAME validators.txt
|
||||
COMPONENT runtime
|
||||
)
|
||||
|
||||
147
cmake/XrplPackaging.cmake
Normal file
147
cmake/XrplPackaging.cmake
Normal file
@@ -0,0 +1,147 @@
|
||||
#[===================================================================[
|
||||
Linux packaging support: RPM and Debian targets + install tests
|
||||
#]===================================================================]
|
||||
|
||||
if(NOT CMAKE_INSTALL_PREFIX STREQUAL "/opt/xrpld")
|
||||
message(
|
||||
STATUS
|
||||
"Packaging targets require -DCMAKE_INSTALL_PREFIX=/opt/xrpld "
|
||||
"(current: '${CMAKE_INSTALL_PREFIX}'); skipping."
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Generate the RPM spec from template (substitutes @xrpld_version@, @pkg_release@).
|
||||
if(NOT DEFINED pkg_release)
|
||||
set(pkg_release 1)
|
||||
endif()
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/package/rpm/xrpld.spec.in
|
||||
${CMAKE_BINARY_DIR}/package/rpm/xrpld.spec
|
||||
@ONLY
|
||||
)
|
||||
|
||||
find_program(RPMBUILD_EXECUTABLE rpmbuild)
|
||||
if(RPMBUILD_EXECUTABLE)
|
||||
add_custom_target(
|
||||
package-rpm
|
||||
COMMAND
|
||||
${CMAKE_SOURCE_DIR}/package/build_pkg.sh rpm ${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Building RPM package"
|
||||
VERBATIM
|
||||
)
|
||||
else()
|
||||
message(STATUS "rpmbuild not found; 'package-rpm' target not available")
|
||||
endif()
|
||||
|
||||
find_program(DPKG_BUILDPACKAGE_EXECUTABLE dpkg-buildpackage)
|
||||
if(DPKG_BUILDPACKAGE_EXECUTABLE)
|
||||
add_custom_target(
|
||||
package-deb
|
||||
COMMAND
|
||||
${CMAKE_SOURCE_DIR}/package/build_pkg.sh deb ${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_BINARY_DIR} ${xrpld_version}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Building Debian package"
|
||||
VERBATIM
|
||||
)
|
||||
else()
|
||||
message(
|
||||
STATUS
|
||||
"dpkg-buildpackage not found; 'package-deb' target not available"
|
||||
)
|
||||
endif()
|
||||
|
||||
#[===================================================================[
|
||||
CTest fixtures for package install verification (requires docker)
|
||||
#]===================================================================]
|
||||
|
||||
find_program(DOCKER_EXECUTABLE docker)
|
||||
if(NOT DOCKER_EXECUTABLE)
|
||||
message(STATUS "docker not found; package install tests not available")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(DEB_TEST_IMAGE "geerlingguy/docker-ubuntu2204-ansible:latest")
|
||||
set(RPM_TEST_IMAGE "geerlingguy/docker-rockylinux9-ansible:latest")
|
||||
|
||||
foreach(PKG deb rpm)
|
||||
if(PKG STREQUAL "deb")
|
||||
set(IMAGE ${DEB_TEST_IMAGE})
|
||||
else()
|
||||
set(IMAGE ${RPM_TEST_IMAGE})
|
||||
endif()
|
||||
|
||||
# Fixture: start container
|
||||
add_test(
|
||||
NAME ${PKG}_container_start
|
||||
COMMAND
|
||||
sh -c
|
||||
"docker rm -f xrpld_${PKG}_install_test 2>/dev/null || true && \
|
||||
docker run --rm -d \
|
||||
--name xrpld_${PKG}_install_test \
|
||||
--memory=45g --memory-swap=45g \
|
||||
--privileged \
|
||||
--cgroupns host \
|
||||
--volume '${CMAKE_SOURCE_DIR}:/root:ro' \
|
||||
--volume /sys/fs/cgroup:/sys/fs/cgroup:rw \
|
||||
--tmpfs /tmp --tmpfs /run --tmpfs /run/lock \
|
||||
${IMAGE} \
|
||||
/usr/sbin/init"
|
||||
)
|
||||
set_tests_properties(
|
||||
${PKG}_container_start
|
||||
PROPERTIES FIXTURES_SETUP ${PKG}_container LABELS packaging
|
||||
)
|
||||
|
||||
# Fixture: stop container
|
||||
# On CI: always stop. Locally: leave running on failure for diagnosis.
|
||||
add_test(
|
||||
NAME ${PKG}_container_stop
|
||||
COMMAND
|
||||
sh -c
|
||||
"if [ -n \"$CI\" ] || ! docker exec xrpld_${PKG}_install_test test -f /tmp/test_failed 2>/dev/null; then \
|
||||
docker rm -f xrpld_${PKG}_install_test; \
|
||||
else \
|
||||
echo 'Tests failed — leaving xrpld_${PKG}_install_test running for diagnosis'; \
|
||||
echo 'Clean up with: docker rm -f xrpld_${PKG}_install_test'; \
|
||||
fi"
|
||||
)
|
||||
set_tests_properties(
|
||||
${PKG}_container_stop
|
||||
PROPERTIES FIXTURES_CLEANUP ${PKG}_container LABELS packaging
|
||||
)
|
||||
|
||||
# Install package and run smoke test
|
||||
add_test(
|
||||
NAME ${PKG}_install
|
||||
COMMAND
|
||||
docker exec -w /root xrpld_${PKG}_install_test bash
|
||||
/root/package/test/smoketest.sh local
|
||||
)
|
||||
set_tests_properties(
|
||||
${PKG}_install
|
||||
PROPERTIES
|
||||
FIXTURES_REQUIRED ${PKG}_container
|
||||
FIXTURES_SETUP ${PKG}_installed
|
||||
LABELS packaging
|
||||
TIMEOUT 600
|
||||
)
|
||||
|
||||
# Validate install paths and compat symlinks
|
||||
add_test(
|
||||
NAME ${PKG}_install_paths
|
||||
COMMAND
|
||||
docker exec -w /root xrpld_${PKG}_install_test sh
|
||||
/root/package/test/check_install_paths.sh
|
||||
)
|
||||
set_tests_properties(
|
||||
${PKG}_install_paths
|
||||
PROPERTIES
|
||||
FIXTURES_REQUIRED "${PKG}_container;${PKG}_installed"
|
||||
LABELS packaging
|
||||
TIMEOUT 60
|
||||
)
|
||||
endforeach()
|
||||
@@ -140,28 +140,6 @@ function(setup_protocol_autogen)
|
||||
)
|
||||
endif()
|
||||
|
||||
# Check pip index URL configuration
|
||||
execute_process(
|
||||
COMMAND ${VENV_PIP} config get global.index-url
|
||||
OUTPUT_VARIABLE PIP_INDEX_URL
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET
|
||||
)
|
||||
|
||||
# Default PyPI URL
|
||||
set(DEFAULT_PIP_INDEX "https://pypi.org/simple")
|
||||
|
||||
# Show warning if using non-default index
|
||||
if(PIP_INDEX_URL AND NOT PIP_INDEX_URL STREQUAL "")
|
||||
if(NOT PIP_INDEX_URL STREQUAL DEFAULT_PIP_INDEX)
|
||||
message(
|
||||
WARNING
|
||||
"Private pip index URL detected: ${PIP_INDEX_URL}\n"
|
||||
"You may need to connect to VPN to access this URL."
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "Installing Python dependencies...")
|
||||
execute_process(
|
||||
COMMAND ${VENV_PIP} install --upgrade pip
|
||||
|
||||
45
conan.lock
45
conan.lock
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"version": "0.5",
|
||||
"requires": [
|
||||
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809",
|
||||
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075",
|
||||
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
|
||||
"sqlite3/3.51.0#66aa11eabd0e34954c5c1c061ad44abe%1763899256.358",
|
||||
"soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231",
|
||||
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1765850149.926",
|
||||
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1765850149.46",
|
||||
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",
|
||||
"secp256k1/0.7.1#481881709eb0bdd0185a12b912bbe8ad%1770910500.329",
|
||||
"secp256k1/0.7.1#3a61e95e220062ef32c48d019e9c81f7%1770306721.686",
|
||||
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1765850186.86",
|
||||
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1774398111.888",
|
||||
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1773224203.27",
|
||||
"openssl/3.6.1#e6399de266349245a4542fc5f6c71552%1774458290.139",
|
||||
"re2/20230301#ca3b241baec15bd31ea9187150e0b333%1765850148.103",
|
||||
"protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1765850161.038",
|
||||
"openssl/3.5.5#05a4ac5b7323f7a329b2db1391d9941f%1769599205.414",
|
||||
"nudb/2.0.9#0432758a24204da08fee953ec9ea03cb%1769436073.32",
|
||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914",
|
||||
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492",
|
||||
@@ -18,26 +18,27 @@
|
||||
"libarchive/3.8.1#ffee18995c706e02bf96e7a2f7042e0d%1765850144.736",
|
||||
"jemalloc/5.3.0#e951da9cf599e956cebc117880d2d9f8%1729241615.244",
|
||||
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152",
|
||||
"grpc/1.78.1#b1a9e74b145cc471bed4dc64dc6eb2c1%1772623605.068",
|
||||
"grpc/1.72.0#f244a57bff01e708c55a1100b12e1589%1765850193.734",
|
||||
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1765850143.772",
|
||||
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772",
|
||||
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1774439234.681",
|
||||
"c-ares/1.34.5#5581c2b62a608b40bb85d965ab3ec7c8%1765850144.336",
|
||||
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1765850143.837",
|
||||
"boost/1.90.0#d5e8defe7355494953be18524a7f135b%1769454080.269",
|
||||
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196"
|
||||
"abseil/20250127.0#99262a368bd01c0ccca8790dfced9719%1766517936.993"
|
||||
],
|
||||
"build_requires": [
|
||||
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809",
|
||||
"strawberryperl/5.32.1.1#8d114504d172cfea8ea1662d09b6333e%1774447376.964",
|
||||
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1773224203.27",
|
||||
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075",
|
||||
"strawberryperl/5.32.1.1#707032463aa0620fa17ec0d887f5fe41%1765850165.196",
|
||||
"protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1765850161.038",
|
||||
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1765850144.707",
|
||||
"msys2/cci.latest#d22fe7b2808f5fd34d0a7923ace9c54f%1770657326.649",
|
||||
"m4/1.4.19#5d7a4994e5875d76faf7acf3ed056036%1774365463.87",
|
||||
"cmake/4.3.0#b939a42e98f593fb34d3a8c5cc860359%1774439249.183",
|
||||
"b2/5.4.2#ffd6084a119587e70f11cd45d1a386e2%1774439233.447",
|
||||
"msys2/cci.latest#eea83308ad7e9023f7318c60d5a9e6cb%1770199879.083",
|
||||
"m4/1.4.19#70dc8bbb33e981d119d2acc0175cf381%1763158052.846",
|
||||
"cmake/4.2.0#ae0a44f44a1ef9ab68fd4b3e9a1f8671%1765850153.937",
|
||||
"cmake/3.31.10#313d16a1aa16bbdb2ca0792467214b76%1765850153.479",
|
||||
"b2/5.3.3#107c15377719889654eb9a162a673975%1765850144.355",
|
||||
"automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56",
|
||||
"autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86",
|
||||
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196"
|
||||
"abseil/20250127.0#99262a368bd01c0ccca8790dfced9719%1766517936.993"
|
||||
],
|
||||
"python_requires": [],
|
||||
"overrides": {
|
||||
@@ -45,14 +46,14 @@
|
||||
null,
|
||||
"boost/1.90.0"
|
||||
],
|
||||
"protobuf/[>=5.27.0 <7]": [
|
||||
"protobuf/6.33.5"
|
||||
"protobuf/5.27.0": [
|
||||
"protobuf/6.32.1"
|
||||
],
|
||||
"lz4/1.9.4": [
|
||||
"lz4/1.10.0"
|
||||
],
|
||||
"sqlite3/[>=3.44 <4]": [
|
||||
"sqlite3/3.51.0"
|
||||
"sqlite3/3.44.2": [
|
||||
"sqlite3/3.49.1"
|
||||
],
|
||||
"boost/1.83.0": [
|
||||
"boost/1.90.0"
|
||||
|
||||
23
conanfile.py
23
conanfile.py
@@ -1,9 +1,10 @@
|
||||
import os
|
||||
import re
|
||||
import os
|
||||
|
||||
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
|
||||
|
||||
from conan import ConanFile
|
||||
from conan import __version__ as conan_version
|
||||
|
||||
|
||||
class Xrpl(ConanFile):
|
||||
@@ -29,10 +30,10 @@ class Xrpl(ConanFile):
|
||||
|
||||
requires = [
|
||||
"ed25519/2015.03",
|
||||
"grpc/1.78.1",
|
||||
"grpc/1.72.0",
|
||||
"libarchive/3.8.1",
|
||||
"nudb/2.0.9",
|
||||
"openssl/3.6.1",
|
||||
"openssl/3.5.5",
|
||||
"secp256k1/0.7.1",
|
||||
"soci/4.0.3",
|
||||
"zlib/1.3.1",
|
||||
@@ -43,7 +44,7 @@ class Xrpl(ConanFile):
|
||||
]
|
||||
|
||||
tool_requires = [
|
||||
"protobuf/6.33.5",
|
||||
"protobuf/6.32.1",
|
||||
]
|
||||
|
||||
default_options = {
|
||||
@@ -136,16 +137,20 @@ class Xrpl(ConanFile):
|
||||
self.default_options["fPIC"] = False
|
||||
|
||||
def requirements(self):
|
||||
self.requires("boost/1.90.0", force=True, transitive_headers=True)
|
||||
self.requires("date/3.0.4", transitive_headers=True)
|
||||
# Conan 2 requires transitive headers to be specified
|
||||
transitive_headers_opt = (
|
||||
{"transitive_headers": True} if conan_version.split(".")[0] == "2" else {}
|
||||
)
|
||||
self.requires("boost/1.90.0", force=True, **transitive_headers_opt)
|
||||
self.requires("date/3.0.4", **transitive_headers_opt)
|
||||
self.requires("lz4/1.10.0", force=True)
|
||||
self.requires("protobuf/6.33.5", force=True)
|
||||
self.requires("sqlite3/3.51.0", force=True)
|
||||
self.requires("protobuf/6.32.1", force=True)
|
||||
self.requires("sqlite3/3.49.1", force=True)
|
||||
if self.options.jemalloc:
|
||||
self.requires("jemalloc/5.3.0")
|
||||
if self.options.rocksdb:
|
||||
self.requires("rocksdb/10.5.1")
|
||||
self.requires("xxhash/0.8.3", transitive_headers=True)
|
||||
self.requires("xxhash/0.8.3", **transitive_headers_opt)
|
||||
|
||||
exports_sources = (
|
||||
"CMakeLists.txt",
|
||||
|
||||
@@ -93,11 +93,14 @@ words:
|
||||
- desync
|
||||
- desynced
|
||||
- determ
|
||||
- disablerepo
|
||||
- distro
|
||||
- doxyfile
|
||||
- dxrpl
|
||||
- enablerepo
|
||||
- endmacro
|
||||
- exceptioned
|
||||
- EXPECT_STREQ
|
||||
- Falco
|
||||
- fcontext
|
||||
- finalizers
|
||||
@@ -151,6 +154,7 @@ words:
|
||||
- Merkle
|
||||
- Metafuncton
|
||||
- misprediction
|
||||
- missingok
|
||||
- mptbalance
|
||||
- MPTDEX
|
||||
- mptflags
|
||||
@@ -181,7 +185,9 @@ words:
|
||||
- NOLINT
|
||||
- NOLINTNEXTLINE
|
||||
- nonxrp
|
||||
- noreplace
|
||||
- noripple
|
||||
- notifempty
|
||||
- nudb
|
||||
- nullptr
|
||||
- nunl
|
||||
@@ -201,6 +207,7 @@ words:
|
||||
- preauthorize
|
||||
- preauthorizes
|
||||
- preclaim
|
||||
- preun
|
||||
- protobuf
|
||||
- protos
|
||||
- ptrs
|
||||
@@ -235,12 +242,14 @@ words:
|
||||
- sfields
|
||||
- shamap
|
||||
- shamapitem
|
||||
- shlibs
|
||||
- sidechain
|
||||
- SIGGOOD
|
||||
- sle
|
||||
- sles
|
||||
- soci
|
||||
- socidb
|
||||
- SRPMS
|
||||
- sslws
|
||||
- statsd
|
||||
- STATSDCOLLECTOR
|
||||
@@ -268,8 +277,8 @@ words:
|
||||
- txn
|
||||
- txns
|
||||
- txs
|
||||
- UBSAN
|
||||
- ubsan
|
||||
- UBSAN
|
||||
- umant
|
||||
- unacquired
|
||||
- unambiguity
|
||||
@@ -297,7 +306,6 @@ words:
|
||||
- venv
|
||||
- vfalco
|
||||
- vinnie
|
||||
- wasmi
|
||||
- wextra
|
||||
- wptr
|
||||
- writeme
|
||||
@@ -306,7 +314,6 @@ words:
|
||||
- xbridge
|
||||
- xchain
|
||||
- ximinez
|
||||
- EXPECT_STREQ
|
||||
- XMACRO
|
||||
- xrpkuwait
|
||||
- xrpl
|
||||
|
||||
29
docs/build/environment.md
vendored
29
docs/build/environment.md
vendored
@@ -109,32 +109,3 @@ Install CMake with Homebrew too:
|
||||
```
|
||||
brew install cmake
|
||||
```
|
||||
|
||||
## Clang-tidy
|
||||
|
||||
Clang-tidy is required to run static analysis checks locally (see [CONTRIBUTING.md](../../CONTRIBUTING.md)).
|
||||
It is not required to build the project. Currently this project uses clang-tidy version 21.
|
||||
|
||||
### Linux
|
||||
|
||||
LLVM 21 is not available in the default Debian 12 (Bookworm) repositories.
|
||||
Install it using the official LLVM apt installer:
|
||||
|
||||
```
|
||||
wget https://apt.llvm.org/llvm.sh
|
||||
chmod +x llvm.sh
|
||||
sudo ./llvm.sh 21
|
||||
sudo apt install --yes clang-tidy-21
|
||||
```
|
||||
|
||||
Then use `run-clang-tidy-21` when running clang-tidy locally.
|
||||
|
||||
### macOS
|
||||
|
||||
Install LLVM 21 via Homebrew:
|
||||
|
||||
```
|
||||
brew install llvm@21
|
||||
```
|
||||
|
||||
Then use `run-clang-tidy` from the LLVM 21 Homebrew prefix when running clang-tidy locally.
|
||||
|
||||
@@ -45,7 +45,7 @@ class NetworkIDService;
|
||||
class OpenLedger;
|
||||
class OrderBookDB;
|
||||
class Overlay;
|
||||
class PathRequestManager;
|
||||
class PathRequests;
|
||||
class PeerReservationTable;
|
||||
class PendingSaves;
|
||||
class RelationalDatabase;
|
||||
@@ -195,8 +195,8 @@ public:
|
||||
virtual TxQ&
|
||||
getTxQ() = 0;
|
||||
|
||||
virtual PathRequestManager&
|
||||
getPathRequestManager() = 0;
|
||||
virtual PathRequests&
|
||||
getPathRequests() = 0;
|
||||
|
||||
// Server services
|
||||
virtual ServerHandler&
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Deprecated constant for backwards compatibility with pre-XRPFees amendment.
|
||||
// This was the reference fee units used in the old fee calculation.
|
||||
inline constexpr std::uint32_t FEE_UNITS_DEPRECATED = 10;
|
||||
|
||||
/** Reflects the fee settings for a particular ledger.
|
||||
|
||||
The fees are always the same for any transactions applied
|
||||
@@ -15,25 +11,15 @@ inline constexpr std::uint32_t FEE_UNITS_DEPRECATED = 10;
|
||||
*/
|
||||
struct Fees
|
||||
{
|
||||
/** @brief Cost of a reference transaction in drops. */
|
||||
XRPAmount base{0};
|
||||
|
||||
/** @brief Minimum XRP an account must hold to exist on the ledger. */
|
||||
XRPAmount reserve{0};
|
||||
|
||||
/** @brief Additional XRP reserve required per owned ledger object. */
|
||||
XRPAmount increment{0};
|
||||
XRPAmount base{0}; // Reference tx cost (drops)
|
||||
XRPAmount reserve{0}; // Reserve base (drops)
|
||||
XRPAmount increment{0}; // Reserve increment (drops)
|
||||
|
||||
explicit Fees() = default;
|
||||
Fees(Fees const&) = default;
|
||||
Fees&
|
||||
operator=(Fees const&) = default;
|
||||
|
||||
Fees(XRPAmount base_, XRPAmount reserve_, XRPAmount increment_)
|
||||
: base(base_), reserve(reserve_), increment(increment_)
|
||||
{
|
||||
}
|
||||
|
||||
/** Returns the account reserve given the owner count, in drops.
|
||||
|
||||
The reserve is calculated as the reserve base plus
|
||||
|
||||
@@ -72,8 +72,4 @@ deserializeHeader(Slice data, bool hasHash = false);
|
||||
LedgerHeader
|
||||
deserializePrefixedHeader(Slice data, bool hasHash = false);
|
||||
|
||||
/** Calculate the hash of a ledger header. */
|
||||
uint256
|
||||
calculateLedgerHash(LedgerHeader const& info);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
|
||||
XRPL_FIX (Security3_1_3, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PermissionedDomainInvariant, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (ExpiredNFTokenOfferRemoval, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (BatchInnerSigs, Supported::no, VoteBehavior::DefaultNo)
|
||||
|
||||
118
package/README.md
Normal file
118
package/README.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# Linux Packaging
|
||||
|
||||
This directory contains all files needed to build RPM and Debian packages for `xrpld`.
|
||||
|
||||
## Directory layout
|
||||
|
||||
```
|
||||
package/
|
||||
build_pkg.sh Staging and build script (called by CMake targets and CI)
|
||||
rpm/
|
||||
xrpld.spec.in RPM spec template (substitutes @xrpld_version@, @pkg_release@)
|
||||
deb/
|
||||
debian/ Debian control files (control, rules, install, links, conffiles, ...)
|
||||
shared/
|
||||
xrpld.service systemd unit file (used by both RPM and DEB)
|
||||
xrpld.sysusers sysusers.d config (used by both RPM and DEB)
|
||||
xrpld.tmpfiles tmpfiles.d config (used by both RPM and DEB)
|
||||
xrpld.logrotate logrotate config (installed to /opt/xrpld/bin/, user activates)
|
||||
update-xrpld.sh auto-update script (installed to /opt/xrpld/bin/)
|
||||
update-xrpld-cron cron entry for auto-update (installed to /opt/xrpld/bin/)
|
||||
test/
|
||||
smoketest.sh Package install smoke test
|
||||
check_install_paths.sh Verify install paths and compat symlinks
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
| Package type | Container | Tool required |
|
||||
| ------------ | -------------------------------------- | --------------------------------------------------------------- |
|
||||
| RPM | `ghcr.io/xrplf/ci/rhel-9:gcc-12` | `rpmbuild` |
|
||||
| DEB | `ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12` | `dpkg-buildpackage`, `debhelper (>= 13)`, `dh-sequence-systemd` |
|
||||
|
||||
## Building packages
|
||||
|
||||
### Via CI (recommended)
|
||||
|
||||
The `reusable-package.yml` workflow downloads a pre-built `xrpld` binary artifact
|
||||
and calls `build_pkg.sh` directly. No CMake configure or build step is needed in
|
||||
the packaging job.
|
||||
|
||||
### Via CMake (local development)
|
||||
|
||||
Configure with the required install prefix, then invoke the target:
|
||||
|
||||
```bash
|
||||
cmake \
|
||||
-DCMAKE_INSTALL_PREFIX=/opt/xrpld \
|
||||
-Dxrpld=ON \
|
||||
-Dtests=OFF \
|
||||
..
|
||||
|
||||
# RPM (in RHEL container):
|
||||
cmake --build . --target package-rpm
|
||||
|
||||
# DEB (in Debian/Ubuntu container):
|
||||
cmake --build . --target package-deb
|
||||
```
|
||||
|
||||
The `cmake/XrplPackaging.cmake` module gates each target on whether the required
|
||||
tool (`rpmbuild` / `dpkg-buildpackage`) is present at configure time, so
|
||||
configuring on a host that lacks one simply omits the corresponding target.
|
||||
|
||||
`CMAKE_INSTALL_PREFIX` must be `/opt/xrpld`; if it is not, both targets are
|
||||
skipped with a `STATUS` message.
|
||||
|
||||
## How `build_pkg.sh` works
|
||||
|
||||
`build_pkg.sh <pkg_type> <src_dir> <build_dir> [version] [pkg_release]` stages
|
||||
all files and invokes the platform build tool. It resolves `src_dir` and
|
||||
`build_dir` to absolute paths, then calls `stage_common()` to copy the binary,
|
||||
config files, and shared support files into the staging area.
|
||||
|
||||
### RPM
|
||||
|
||||
1. Creates the standard `rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}` tree inside the build directory.
|
||||
2. Copies the generated `xrpld.spec` and all source files (binary, configs, service files) into `SOURCES/`.
|
||||
3. Runs `rpmbuild -bb`. The spec uses manual `install` commands to place files.
|
||||
4. Output: `rpmbuild/RPMS/x86_64/xrpld-*.rpm`
|
||||
|
||||
### DEB
|
||||
|
||||
1. Creates a staging source tree at `debbuild/source/` inside the build directory.
|
||||
2. Stages the binary, configs, `README.md`, and `LICENSE.md`.
|
||||
3. Copies `package/deb/debian/` control files into `debbuild/source/debian/`.
|
||||
4. Copies shared service/sysusers/tmpfiles into `debian/` where `dh_installsystemd`, `dh_installsysusers`, and `dh_installtmpfiles` pick them up automatically.
|
||||
5. Generates a minimal `debian/changelog` (pre-release versions use `~` instead of `-`).
|
||||
6. Runs `dpkg-buildpackage -b --no-sign`. `debian/rules` uses manual `install` commands.
|
||||
7. Output: `debbuild/*.deb` and `debbuild/*.ddeb` (dbgsym package)
|
||||
|
||||
## Post-build verification
|
||||
|
||||
```bash
|
||||
# DEB
|
||||
dpkg-deb -c debbuild/*.deb | grep -E 'systemd|sysusers|tmpfiles'
|
||||
lintian -I debbuild/*.deb
|
||||
|
||||
# RPM
|
||||
rpm -qlp rpmbuild/RPMS/x86_64/*.rpm
|
||||
```
|
||||
|
||||
## Reproducibility
|
||||
|
||||
The following environment variables improve build reproducibility. They are not
|
||||
set automatically by `build_pkg.sh`; set them manually if needed:
|
||||
|
||||
```bash
|
||||
export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
|
||||
export TZ=UTC
|
||||
export LC_ALL=C.UTF-8
|
||||
export GZIP=-n
|
||||
export DEB_BUILD_OPTIONS="noautodbgsym reproducible=+fixfilepath"
|
||||
```
|
||||
|
||||
## TODO
|
||||
|
||||
- Port debsigs signing instructions and integrate into CI.
|
||||
- Port RPM GPG signing setup (key import + `%{?_gpg_sign}` in spec).
|
||||
- Introduce a virtual package for key rotation.
|
||||
91
package/build_pkg.sh
Executable file
91
package/build_pkg.sh
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build an RPM or Debian package from a pre-built xrpld binary.
|
||||
#
|
||||
# Usage: build_pkg.sh <pkg_type> <src_dir> <build_dir> [version] [pkg_release]
|
||||
# pkg_type : rpm | deb
|
||||
# src_dir : path to repository root
|
||||
# build_dir : directory containing the pre-built xrpld binary
|
||||
# version : package version string (e.g. 2.4.0-b1)
|
||||
# pkg_release : package release number (default: 1)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PKG_TYPE="${1:?pkg_type required}"
|
||||
SRC_DIR="$(cd "${2:?src_dir required}" && pwd)"
|
||||
BUILD_DIR="$(cd "${3:?build_dir required}" && pwd)"
|
||||
VERSION="${4:-1.0.0}"
|
||||
PKG_RELEASE="${5:-1}"
|
||||
|
||||
SHARED="${SRC_DIR}/package/shared"
|
||||
|
||||
# Stage files common to both package types into a target directory.
|
||||
stage_common() {
|
||||
local dest="$1"
|
||||
cp "${BUILD_DIR}/xrpld" "${dest}/xrpld"
|
||||
cp "${SRC_DIR}/cfg/xrpld-example.cfg" "${dest}/xrpld.cfg"
|
||||
cp "${SRC_DIR}/cfg/validators-example.txt" "${dest}/validators.txt"
|
||||
cp "${SHARED}/xrpld.logrotate" "${dest}/xrpld.logrotate"
|
||||
cp "${SHARED}/update-xrpld.sh" "${dest}/update-xrpld.sh"
|
||||
cp "${SHARED}/update-xrpld-cron" "${dest}/update-xrpld-cron"
|
||||
}
|
||||
|
||||
build_rpm() {
|
||||
local topdir="${BUILD_DIR}/rpmbuild"
|
||||
mkdir -p "${topdir}"/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
|
||||
|
||||
cp "${BUILD_DIR}/package/rpm/xrpld.spec" "${topdir}/SPECS/xrpld.spec"
|
||||
|
||||
stage_common "${topdir}/SOURCES"
|
||||
cp "${SHARED}/xrpld.service" "${topdir}/SOURCES/xrpld.service"
|
||||
cp "${SHARED}/xrpld.sysusers" "${topdir}/SOURCES/xrpld.sysusers"
|
||||
cp "${SHARED}/xrpld.tmpfiles" "${topdir}/SOURCES/xrpld.tmpfiles"
|
||||
|
||||
set -x
|
||||
rpmbuild -bb \
|
||||
--define "_topdir ${topdir}" \
|
||||
"${topdir}/SPECS/xrpld.spec"
|
||||
}
|
||||
|
||||
build_deb() {
|
||||
local staging="${BUILD_DIR}/debbuild/source"
|
||||
rm -rf "${staging}"
|
||||
mkdir -p "${staging}"
|
||||
|
||||
stage_common "${staging}"
|
||||
cp "${SRC_DIR}/README.md" "${staging}/"
|
||||
cp "${SRC_DIR}/LICENSE.md" "${staging}/"
|
||||
|
||||
# debian/ control files
|
||||
cp -r "${SRC_DIR}/package/deb/debian" "${staging}/debian"
|
||||
|
||||
# Shared support files for dh_installsystemd / sysusers / tmpfiles
|
||||
cp "${SHARED}/xrpld.service" "${staging}/debian/xrpld.service"
|
||||
cp "${SHARED}/xrpld.sysusers" "${staging}/debian/xrpld.sysusers"
|
||||
cp "${SHARED}/xrpld.tmpfiles" "${staging}/debian/xrpld.tmpfiles"
|
||||
|
||||
# Generate debian/changelog (pre-release versions use ~ instead of -).
|
||||
local deb_version="${VERSION//-/\~}"
|
||||
# TODO: Add facility for generating the changelog
|
||||
cat > "${staging}/debian/changelog" <<EOF
|
||||
xrpld (${deb_version}-${PKG_RELEASE}) unstable; urgency=medium
|
||||
|
||||
* Release ${VERSION}.
|
||||
|
||||
-- XRPL Foundation <contact@xrplf.org> $(LC_ALL=C date -u -R)
|
||||
EOF
|
||||
|
||||
chmod +x "${staging}/debian/rules"
|
||||
|
||||
set -x
|
||||
cd "${staging}"
|
||||
dpkg-buildpackage -b --no-sign -d
|
||||
}
|
||||
|
||||
case "${PKG_TYPE}" in
|
||||
rpm) build_rpm ;;
|
||||
deb) build_deb ;;
|
||||
*)
|
||||
echo "Unknown package type: ${PKG_TYPE}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
33
package/deb/debian/control
Normal file
33
package/deb/debian/control
Normal file
@@ -0,0 +1,33 @@
|
||||
Source: xrpld
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: XRPL Foundation <contact@xrpl.org>
|
||||
Rules-Requires-Root: no
|
||||
Build-Depends:
|
||||
debhelper-compat (= 13),
|
||||
Standards-Version: 4.7.0
|
||||
Homepage: https://github.com/XRPLF/rippled
|
||||
Vcs-Git: https://github.com/XRPLF/rippled.git
|
||||
Vcs-Browser: https://github.com/XRPLF/rippled
|
||||
|
||||
Package: xrpld
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: any
|
||||
Depends:
|
||||
${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Description: XRP Ledger daemon
|
||||
xrpld is the reference implementation of the XRP Ledger protocol.
|
||||
It participates in the peer-to-peer XRP Ledger network, processes
|
||||
transactions, and maintains the ledger database.
|
||||
|
||||
Package: rippled
|
||||
Architecture: all
|
||||
Section: oldlibs
|
||||
Priority: optional
|
||||
Depends: xrpld, ${misc:Depends}
|
||||
Description: transitional package - use xrpld
|
||||
The rippled package has been renamed to xrpld. This transitional
|
||||
package ensures a smooth upgrade and can be safely removed after
|
||||
xrpld is installed.
|
||||
20
package/deb/debian/copyright
Normal file
20
package/deb/debian/copyright
Normal file
@@ -0,0 +1,20 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: rippled
|
||||
Source: https://github.com/XRPLF/rippled
|
||||
|
||||
Files: *
|
||||
Copyright: 2012-2025 Ripple Labs Inc.
|
||||
License: ISC
|
||||
|
||||
License: ISC
|
||||
Permission to use, copy, modify, and 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.
|
||||
37
package/deb/debian/rules
Normal file
37
package/deb/debian/rules
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
export DH_VERBOSE = 1
|
||||
export DH_OPTIONS = -v
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_configure override_dh_auto_build override_dh_auto_test:
|
||||
@:
|
||||
|
||||
override_dh_auto_install:
|
||||
install -Dm0755 xrpld debian/tmp/opt/xrpld/bin/xrpld
|
||||
install -Dm0644 xrpld.cfg debian/tmp/opt/xrpld/etc/xrpld.cfg
|
||||
install -Dm0644 validators.txt debian/tmp/opt/xrpld/etc/validators.txt
|
||||
install -Dm0644 xrpld.logrotate debian/tmp/opt/xrpld/bin/xrpld.logrotate
|
||||
install -Dm0755 update-xrpld.sh debian/tmp/opt/xrpld/bin/update-xrpld.sh
|
||||
install -Dm0644 update-xrpld-cron debian/tmp/opt/xrpld/bin/update-xrpld-cron
|
||||
install -Dm0644 README.md debian/tmp/usr/share/doc/xrpld/README.md
|
||||
install -Dm0644 LICENSE.md debian/tmp/usr/share/doc/xrpld/LICENSE.md
|
||||
|
||||
override_dh_installsystemd:
|
||||
dh_installsystemd
|
||||
# see if this still works
|
||||
# dh_installsystemd --no-start
|
||||
|
||||
override_dh_installsysusers:
|
||||
dh_installsysusers
|
||||
|
||||
override_dh_installtmpfiles:
|
||||
dh_installtmpfiles
|
||||
|
||||
override_dh_install:
|
||||
dh_install
|
||||
|
||||
override_dh_dwz:
|
||||
@:
|
||||
1
package/deb/debian/source/format
Normal file
1
package/deb/debian/source/format
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
2
package/deb/debian/xrpld.conffiles
Normal file
2
package/deb/debian/xrpld.conffiles
Normal file
@@ -0,0 +1,2 @@
|
||||
/opt/xrpld/etc/xrpld.cfg
|
||||
/opt/xrpld/etc/validators.txt
|
||||
10
package/deb/debian/xrpld.install
Normal file
10
package/deb/debian/xrpld.install
Normal file
@@ -0,0 +1,10 @@
|
||||
opt/xrpld/bin/xrpld
|
||||
opt/xrpld/bin/xrpld.logrotate
|
||||
opt/xrpld/bin/update-xrpld.sh
|
||||
opt/xrpld/bin/update-xrpld-cron
|
||||
|
||||
opt/xrpld/etc/xrpld.cfg
|
||||
opt/xrpld/etc/validators.txt
|
||||
|
||||
usr/share/doc/xrpld/README.md
|
||||
usr/share/doc/xrpld/LICENSE.md
|
||||
13
package/deb/debian/xrpld.links
Normal file
13
package/deb/debian/xrpld.links
Normal file
@@ -0,0 +1,13 @@
|
||||
opt/xrpld/etc etc/opt/xrpld
|
||||
|
||||
opt/xrpld/bin/xrpld usr/bin/xrpld
|
||||
|
||||
## remove when "rippled" deprecated
|
||||
opt/xrpld/bin/xrpld opt/xrpld/bin/rippled
|
||||
opt/xrpld/bin/xrpld usr/bin/rippled
|
||||
opt/xrpld/bin/xrpld usr/local/bin/rippled
|
||||
opt/xrpld/etc/xrpld.cfg opt/xrpld/etc/rippled.cfg
|
||||
var/log/xrpld var/log/rippled
|
||||
var/lib/xrpld var/lib/rippled
|
||||
opt/xrpld opt/ripple
|
||||
etc/opt/xrpld etc/opt/ripple
|
||||
113
package/rpm/xrpld.spec.in
Normal file
113
package/rpm/xrpld.spec.in
Normal file
@@ -0,0 +1,113 @@
|
||||
%global xrpld_version @xrpld_version@
|
||||
%global pkg_release @pkg_release@
|
||||
%global _opt_prefix /opt/xrpld
|
||||
%global ver_base %(v=%{xrpld_version}; echo ${v%%-*})
|
||||
%global _has_dash %(v=%{xrpld_version}; [ "${v#*-}" != "$v" ] && echo 1 || echo 0)
|
||||
%if 0%{?_has_dash}
|
||||
%global ver_suffix %(v=%{xrpld_version}; printf %s "${v#*-}")
|
||||
%endif
|
||||
Name: xrpld
|
||||
Version: %{ver_base}
|
||||
Release: %{?ver_suffix:0.%{ver_suffix}.}%{pkg_release}%{?dist}
|
||||
Summary: XRP Ledger daemon
|
||||
|
||||
License: ISC
|
||||
URL: https://github.com/XRPLF/rippled
|
||||
|
||||
Source0: xrpld
|
||||
Source1: xrpld.cfg
|
||||
Source2: validators.txt
|
||||
Source3: xrpld.service
|
||||
Source4: xrpld.sysusers
|
||||
Source5: xrpld.tmpfiles
|
||||
Source6: xrpld.logrotate
|
||||
Source7: update-xrpld.sh
|
||||
Source8: update-xrpld-cron
|
||||
|
||||
BuildArch: x86_64
|
||||
BuildRequires: systemd-rpm-macros
|
||||
|
||||
%undefine _debugsource_packages
|
||||
%debug_package
|
||||
|
||||
%{?systemd_requires}
|
||||
%{?sysusers_requires_compat}
|
||||
|
||||
%description
|
||||
xrpld is the reference implementation of the XRP Ledger protocol. It
|
||||
participates in the peer-to-peer XRP Ledger network, processes
|
||||
transactions, and maintains the ledger database.
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
|
||||
# Suppress debugsource subpackage — no source files in the build tree.
|
||||
touch %{_builddir}/debugsourcefiles.list
|
||||
|
||||
# Install binary and config files.
|
||||
install -Dm0755 %{SOURCE0} %{buildroot}%{_opt_prefix}/bin/xrpld
|
||||
install -Dm0644 %{SOURCE1} %{buildroot}%{_opt_prefix}/etc/xrpld.cfg
|
||||
install -Dm0644 %{SOURCE2} %{buildroot}%{_opt_prefix}/etc/validators.txt
|
||||
|
||||
# Compatibility symlinks (matches debian/xrpld.links).
|
||||
mkdir -p %{buildroot}/etc/opt %{buildroot}/usr/bin %{buildroot}/usr/local/bin \
|
||||
%{buildroot}/var/log %{buildroot}/var/lib
|
||||
ln -s %{_opt_prefix}/etc %{buildroot}/etc/opt/xrpld
|
||||
ln -s %{_opt_prefix}/bin/xrpld %{buildroot}/usr/bin/xrpld
|
||||
|
||||
## remove when "rippled" deprecated
|
||||
ln -s xrpld %{buildroot}%{_opt_prefix}/bin/rippled
|
||||
ln -s %{_opt_prefix}/bin/xrpld %{buildroot}/usr/bin/rippled
|
||||
ln -s %{_opt_prefix}/bin/xrpld %{buildroot}/usr/local/bin/rippled
|
||||
ln -s xrpld.cfg %{buildroot}%{_opt_prefix}/etc/rippled.cfg
|
||||
ln -s %{_opt_prefix} %{buildroot}/opt/ripple
|
||||
ln -s /etc/opt/xrpld %{buildroot}/etc/opt/ripple
|
||||
ln -s xrpld %{buildroot}/var/log/rippled
|
||||
ln -s xrpld %{buildroot}/var/lib/rippled
|
||||
|
||||
# Install systemd/sysusers/tmpfiles support files.
|
||||
install -Dm0644 %{SOURCE3} %{buildroot}%{_unitdir}/xrpld.service
|
||||
install -Dm0644 %{SOURCE4} %{buildroot}%{_sysusersdir}/xrpld.conf
|
||||
install -Dm0644 %{SOURCE5} %{buildroot}%{_tmpfilesdir}/xrpld.conf
|
||||
install -Dm0644 %{SOURCE6} %{buildroot}%{_opt_prefix}/bin/xrpld.logrotate
|
||||
install -Dm0755 %{SOURCE7} %{buildroot}%{_opt_prefix}/bin/update-xrpld.sh
|
||||
install -Dm0644 %{SOURCE8} %{buildroot}%{_opt_prefix}/bin/update-xrpld-cron
|
||||
|
||||
%pre
|
||||
%sysusers_create_compat %{SOURCE4}
|
||||
|
||||
%post
|
||||
%systemd_post xrpld.service
|
||||
|
||||
%preun
|
||||
%systemd_preun xrpld.service
|
||||
|
||||
%postun
|
||||
%systemd_postun_with_restart xrpld.service
|
||||
|
||||
%files
|
||||
%dir %{_opt_prefix}
|
||||
%dir %{_opt_prefix}/bin
|
||||
%{_opt_prefix}/bin/xrpld
|
||||
%{_opt_prefix}/bin/xrpld.logrotate
|
||||
%{_opt_prefix}/bin/update-xrpld.sh
|
||||
%{_opt_prefix}/bin/update-xrpld-cron
|
||||
%{_opt_prefix}/bin/rippled
|
||||
/usr/bin/xrpld
|
||||
/usr/bin/rippled
|
||||
/usr/local/bin/rippled
|
||||
%dir %{_opt_prefix}/etc
|
||||
%config(noreplace) %{_opt_prefix}/etc/xrpld.cfg
|
||||
%config(noreplace) %{_opt_prefix}/etc/validators.txt
|
||||
%{_opt_prefix}/etc/rippled.cfg
|
||||
/etc/opt/xrpld
|
||||
/etc/opt/ripple
|
||||
/opt/ripple
|
||||
%{_unitdir}/xrpld.service
|
||||
%{_sysusersdir}/xrpld.conf
|
||||
%{_tmpfilesdir}/xrpld.conf
|
||||
/var/log/rippled
|
||||
/var/lib/rippled
|
||||
%ghost %dir /var/opt/ripple
|
||||
%ghost %dir /var/opt/ripple/lib
|
||||
%ghost %dir /var/opt/ripple/log
|
||||
9
package/shared/update-xrpld-cron
Normal file
9
package/shared/update-xrpld-cron
Normal file
@@ -0,0 +1,9 @@
|
||||
# For automatic updates, symlink this file to /etc/cron.d/
|
||||
# Do not remove the newline at the end of this cron script
|
||||
|
||||
# bash required for use of RANDOM below.
|
||||
SHELL=/bin/bash
|
||||
PATH=/sbin;/bin;/usr/sbin;/usr/bin
|
||||
|
||||
# invoke check/update script with random delay up to 59 mins
|
||||
0 * * * * root sleep $((RANDOM*3540/32768)) && /opt/xrpld/bin/update-xrpld.sh
|
||||
64
package/shared/update-xrpld.sh
Executable file
64
package/shared/update-xrpld.sh
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# auto-update script for xrpld daemon
|
||||
|
||||
# Check for sudo/root permissions
|
||||
if [[ $(id -u) -ne 0 ]] ; then
|
||||
echo "This update script must be run as root or sudo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LOCKDIR=/tmp/xrpld-update.lock
|
||||
UPDATELOG=/var/log/xrpld/update.log
|
||||
|
||||
function cleanup {
|
||||
# If this directory isn't removed, future updates will fail.
|
||||
rmdir $LOCKDIR
|
||||
}
|
||||
|
||||
# Use mkdir to check if process is already running. mkdir is atomic, as against file create.
|
||||
if ! mkdir $LOCKDIR 2>/dev/null; then
|
||||
echo $(date -u) "lockdir exists - won't proceed." >> $UPDATELOG
|
||||
exit 1
|
||||
fi
|
||||
trap cleanup EXIT
|
||||
|
||||
source /etc/os-release
|
||||
can_update=false
|
||||
|
||||
if [[ "$ID" == "ubuntu" || "$ID" == "debian" ]] ; then
|
||||
# Silent update
|
||||
apt-get update -qq
|
||||
|
||||
# The next line is an "awk"ward way to check if the package needs to be updated.
|
||||
XRPLD=$(apt-get install -s --only-upgrade xrpld | awk '/^Inst/ { print $2 }')
|
||||
test "$XRPLD" == "xrpld" && can_update=true
|
||||
|
||||
function apply_update {
|
||||
apt-get install xrpld -qq
|
||||
}
|
||||
elif [[ "$ID" == "fedora" || "$ID" == "centos" || "$ID" == "rhel" || "$ID" == "scientific" ]] ; then
|
||||
RIPPLE_REPO=${RIPPLE_REPO-stable}
|
||||
yum --disablerepo=* --enablerepo=ripple-$RIPPLE_REPO clean expire-cache
|
||||
|
||||
yum check-update -q --enablerepo=ripple-$RIPPLE_REPO xrpld || can_update=true
|
||||
|
||||
function apply_update {
|
||||
yum update -y --enablerepo=ripple-$RIPPLE_REPO xrpld
|
||||
}
|
||||
else
|
||||
echo "unrecognized distro!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Do the actual update and restart the service after reloading systemctl daemon.
|
||||
if [ "$can_update" = true ] ; then
|
||||
exec 3>&1 1>>${UPDATELOG} 2>&1
|
||||
set -e
|
||||
apply_update
|
||||
systemctl daemon-reload
|
||||
systemctl restart xrpld.service
|
||||
echo $(date -u) "xrpld daemon updated."
|
||||
else
|
||||
echo $(date -u) "no updates available" >> $UPDATELOG
|
||||
fi
|
||||
15
package/shared/xrpld.logrotate
Normal file
15
package/shared/xrpld.logrotate
Normal file
@@ -0,0 +1,15 @@
|
||||
/var/log/xrpld/*.log {
|
||||
daily
|
||||
minsize 200M
|
||||
rotate 7
|
||||
nocreate
|
||||
missingok
|
||||
notifempty
|
||||
compress
|
||||
compresscmd /usr/bin/nice
|
||||
compressoptions -n19 ionice -c3 gzip
|
||||
compressext .gz
|
||||
postrotate
|
||||
/opt/xrpld/bin/xrpld --conf /etc/opt/xrpld/xrpld.cfg logrotate
|
||||
endscript
|
||||
}
|
||||
15
package/shared/xrpld.service
Normal file
15
package/shared/xrpld.service
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=XRP Ledger Daemon
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/opt/xrpld/bin/xrpld --net --silent --conf /etc/opt/xrpld/xrpld.cfg
|
||||
Restart=on-failure
|
||||
User=xrpld
|
||||
Group=xrpld
|
||||
LimitNOFILE=65536
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
1
package/shared/xrpld.sysusers
Normal file
1
package/shared/xrpld.sysusers
Normal file
@@ -0,0 +1 @@
|
||||
u xrpld - "XRP Ledger daemon" /var/lib/xrpld /sbin/nologin
|
||||
2
package/shared/xrpld.tmpfiles
Normal file
2
package/shared/xrpld.tmpfiles
Normal file
@@ -0,0 +1,2 @@
|
||||
d /var/opt/ripple/lib 0750 xrpld xrpld -
|
||||
d /var/opt/ripple/log 0750 xrpld xrpld -
|
||||
50
package/test/check_install_paths.sh
Executable file
50
package/test/check_install_paths.sh
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env sh
|
||||
# Validate installed paths and compat symlinks for xrpld packages.
|
||||
|
||||
set -e
|
||||
set -x
|
||||
trap 'test $? -ne 0 && touch /tmp/test_failed' EXIT
|
||||
|
||||
check() { test $1 "$2" || { echo "FAIL: $1 $2"; exit 1; }; }
|
||||
check_resolves_to() {
|
||||
actual=$(readlink -f "$1")
|
||||
[ "$actual" = "$2" ] || { echo "FAIL: $1 resolves to $actual, expected $2"; exit 1; }
|
||||
}
|
||||
|
||||
# var dirs (compat symlinks)
|
||||
check -L /var/log/rippled
|
||||
check -L /var/lib/rippled
|
||||
|
||||
# compat directory symlinks — existence and resolved target
|
||||
check -L /opt/ripple
|
||||
check_resolves_to /opt/ripple /opt/xrpld
|
||||
|
||||
check -L /etc/opt/xrpld
|
||||
check_resolves_to /etc/opt/xrpld /opt/xrpld/etc
|
||||
|
||||
check -L /etc/opt/ripple
|
||||
check_resolves_to /etc/opt/ripple /opt/xrpld/etc
|
||||
|
||||
# config accessible via all expected paths
|
||||
check -f /opt/xrpld/etc/xrpld.cfg
|
||||
check -f /opt/xrpld/etc/rippled.cfg
|
||||
check -f /etc/opt/xrpld/xrpld.cfg
|
||||
check -f /etc/opt/xrpld/rippled.cfg
|
||||
check -f /etc/opt/ripple/xrpld.cfg
|
||||
check -f /etc/opt/ripple/rippled.cfg
|
||||
|
||||
if systemctl is-system-running >/dev/null 2>&1; then
|
||||
# service file sanity check
|
||||
SERVICE=$(systemctl cat xrpld)
|
||||
echo "$SERVICE" | grep -q 'ExecStart=/opt/xrpld/bin/xrpld' || { echo "FAIL: ExecStart wrong"; echo "$SERVICE"; exit 1; }
|
||||
echo "$SERVICE" | grep -q 'User=xrpld' || { echo "FAIL: User not xrpld"; echo "$SERVICE"; exit 1; }
|
||||
fi
|
||||
|
||||
# binary accessible via all expected paths
|
||||
/opt/xrpld/bin/xrpld --version
|
||||
/opt/xrpld/bin/rippled --version
|
||||
/opt/ripple/bin/xrpld --version
|
||||
/opt/ripple/bin/rippled --version
|
||||
/usr/bin/xrpld --version
|
||||
/usr/bin/rippled --version
|
||||
/usr/local/bin/rippled --version
|
||||
76
package/test/smoketest.sh
Executable file
76
package/test/smoketest.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
# Install a locally-built package and run basic verification.
|
||||
#
|
||||
# Usage: smoketest.sh local
|
||||
# Expects packages in build/{dpkg,rpm}/packages/ or build/debbuild/ / build/rpmbuild/RPMS/
|
||||
|
||||
set -x
|
||||
trap 'test $? -ne 0 && touch /tmp/test_failed' EXIT
|
||||
|
||||
install_from=$1
|
||||
|
||||
. /etc/os-release
|
||||
case ${ID} in
|
||||
ubuntu|debian)
|
||||
pkgtype="dpkg"
|
||||
;;
|
||||
fedora|centos|rhel|rocky|almalinux)
|
||||
pkgtype="rpm"
|
||||
;;
|
||||
*)
|
||||
echo "unrecognized distro!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "${install_from}" != "local" ]; then
|
||||
echo "only 'local' install mode is supported"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install the package
|
||||
if [ "${pkgtype}" = "dpkg" ] ; then
|
||||
apt-get -y update
|
||||
# Find .deb files — check both possible output locations
|
||||
debs=$(find build/debbuild/ build/dpkg/packages/ -name '*.deb' ! -name '*dbgsym*' 2>/dev/null | head -5)
|
||||
if [ -z "$debs" ]; then
|
||||
echo "No .deb files found"
|
||||
exit 1
|
||||
fi
|
||||
dpkg --no-debsig -i $debs || apt-get -y install -f
|
||||
elif [ "${pkgtype}" = "rpm" ] ; then
|
||||
# Find .rpm files — check both possible output locations
|
||||
rpms=$(find build/rpmbuild/RPMS/ build/rpm/packages/ -name '*.rpm' \
|
||||
! -name '*debug*' ! -name '*devel*' ! -name '*.src.rpm' 2>/dev/null | head -5)
|
||||
if [ -z "$rpms" ]; then
|
||||
echo "No .rpm files found"
|
||||
exit 1
|
||||
fi
|
||||
rpm -i $rpms
|
||||
fi
|
||||
|
||||
# Verify installed version
|
||||
VERSION_OUTPUT=$(/opt/xrpld/bin/xrpld --version)
|
||||
INSTALLED=$(echo "$VERSION_OUTPUT" | head -1 | awk '{print $NF}')
|
||||
echo "Installed version: ${INSTALLED}"
|
||||
|
||||
# Run unit tests
|
||||
if [ -n "${CI:-}" ]; then
|
||||
unittest_jobs=$(nproc)
|
||||
else
|
||||
unittest_jobs=16
|
||||
fi
|
||||
|
||||
cd /tmp
|
||||
/opt/xrpld/bin/xrpld --unittest --unittest-jobs ${unittest_jobs} > /tmp/unittest_results || true
|
||||
cd -
|
||||
|
||||
num_failures=$(tail /tmp/unittest_results -n1 | grep -oP '\d+(?= failures)')
|
||||
if [ "${num_failures:-0}" -ne 0 ]; then
|
||||
echo "$num_failures unit test(s) failed:"
|
||||
grep 'failed:' /tmp/unittest_results
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Compat path checks
|
||||
"$(dirname "${BASH_SOURCE[0]}")/check_install_paths.sh"
|
||||
@@ -433,7 +433,8 @@ doWithdraw(
|
||||
j) < amount)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(j.error()) << "doWithdraw: negative balance of broker cover assets.";
|
||||
JLOG(j.error()) << "LoanBrokerCoverWithdraw: negative balance of "
|
||||
"broker cover assets.";
|
||||
return tefINTERNAL;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ forEachItem(
|
||||
for (auto const& key : sle->getFieldV256(sfIndexes))
|
||||
f(view.read(keylet::child(key)));
|
||||
auto const next = sle->getFieldU64(sfIndexNext);
|
||||
if (next == 0u)
|
||||
if (!next)
|
||||
return;
|
||||
pos = keylet::page(root, next);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
//
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
@@ -13,6 +12,21 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Forward declarations for functions that remain in View.h/cpp
|
||||
bool
|
||||
isVaultPseudoAccountFrozen(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
MPTIssue const& mptShare,
|
||||
int depth);
|
||||
|
||||
[[nodiscard]] TER
|
||||
dirLink(
|
||||
ApplyView& view,
|
||||
AccountID const& owner,
|
||||
std::shared_ptr<SLE>& object,
|
||||
SF_UINT64 const& node = sfOwnerNode);
|
||||
|
||||
bool
|
||||
isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue)
|
||||
{
|
||||
@@ -69,7 +83,7 @@ transferRate(ReadView const& view, MPTID const& issuanceID)
|
||||
// which represents 50% of 1,000,000,000
|
||||
if (auto const sle = view.read(keylet::mptIssuance(issuanceID));
|
||||
sle && sle->isFieldPresent(sfTransferFee))
|
||||
return Rate{1'000'000'000u + (10'000 * sle->getFieldU16(sfTransferFee))};
|
||||
return Rate{1'000'000'000u + 10'000 * sle->getFieldU16(sfTransferFee)};
|
||||
|
||||
return parityRate;
|
||||
}
|
||||
@@ -135,7 +149,7 @@ authorizeMPToken(
|
||||
// When a holder wants to unauthorize/delete a MPT, the ledger must
|
||||
// - delete mptokenKey from owner directory
|
||||
// - delete the MPToken
|
||||
if ((flags & tfMPTUnauthorize) != 0)
|
||||
if (flags & tfMPTUnauthorize)
|
||||
{
|
||||
auto const mptokenKey = keylet::mptoken(mptIssuanceID, account);
|
||||
auto const sleMpt = view.peek(mptokenKey);
|
||||
@@ -215,7 +229,7 @@ authorizeMPToken(
|
||||
|
||||
// Issuer wants to unauthorize the holder, unset lsfMPTAuthorized on
|
||||
// their MPToken
|
||||
if ((flags & tfMPTUnauthorize) != 0)
|
||||
if (flags & tfMPTUnauthorize)
|
||||
{
|
||||
flagsOut &= ~lsfMPTAuthorized;
|
||||
}
|
||||
@@ -476,7 +490,7 @@ canTransfer(
|
||||
if (!sleIssuance)
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
if (!sleIssuance->isFlag(lsfMPTCanTransfer))
|
||||
if (!(sleIssuance->getFieldU32(sfFlags) & lsfMPTCanTransfer))
|
||||
{
|
||||
if (from != (*sleIssuance)[sfIssuer] && to != (*sleIssuance)[sfIssuer])
|
||||
return TER{tecNO_AUTH};
|
||||
|
||||
@@ -224,10 +224,10 @@ trustCreate(
|
||||
bSetHigh ? sfLowLimit : sfHighLimit,
|
||||
STAmount(Issue{saBalance.getCurrency(), bSetDst ? uSrcAccountID : uDstAccountID}));
|
||||
|
||||
if (uQualityIn != 0u)
|
||||
if (uQualityIn)
|
||||
sleRippleState->setFieldU32(bSetHigh ? sfHighQualityIn : sfLowQualityIn, uQualityIn);
|
||||
|
||||
if (uQualityOut != 0u)
|
||||
if (uQualityOut)
|
||||
sleRippleState->setFieldU32(bSetHigh ? sfHighQualityOut : sfLowQualityOut, uQualityOut);
|
||||
|
||||
std::uint32_t uFlags = bSetHigh ? lsfHighReserve : lsfLowReserve;
|
||||
@@ -327,16 +327,16 @@ updateTrustLine(
|
||||
// Sender balance was positive.
|
||||
&& after <= beast::zero
|
||||
// Sender is zero or negative.
|
||||
&& ((flags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) != 0u)
|
||||
&& (flags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve))
|
||||
// Sender reserve is set.
|
||||
&& static_cast<bool>(flags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) !=
|
||||
static_cast<bool>(sle->getFlags() & lsfDefaultRipple) &&
|
||||
((flags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) == 0u) &&
|
||||
!(flags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) &&
|
||||
!state->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit)
|
||||
// Sender trust limit is 0.
|
||||
&& (state->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn) == 0u)
|
||||
&& !state->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn)
|
||||
// Sender quality in is 0.
|
||||
&& (state->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut) == 0u))
|
||||
&& !state->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut))
|
||||
// Sender quality out is 0.
|
||||
{
|
||||
// VFALCO Where is the line being deleted?
|
||||
@@ -348,7 +348,7 @@ updateTrustLine(
|
||||
|
||||
// Balance is zero, receiver reserve is clear.
|
||||
if (!after // Balance is zero.
|
||||
&& ((flags & (bSenderHigh ? lsfLowReserve : lsfHighReserve)) == 0u))
|
||||
&& !(flags & (bSenderHigh ? lsfLowReserve : lsfHighReserve)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -539,12 +539,11 @@ requireAuth(ReadView const& view, Issue const& issue, AccountID const& account,
|
||||
// If this is a weak or legacy check, or if the account has a line, fail if
|
||||
// auth is required and not set on the line
|
||||
if (auto const issuerAccount = view.read(keylet::account(issue.account));
|
||||
issuerAccount && (((*issuerAccount)[sfFlags] & lsfRequireAuth) != 0u))
|
||||
issuerAccount && (*issuerAccount)[sfFlags] & lsfRequireAuth)
|
||||
{
|
||||
if (trustLine)
|
||||
{
|
||||
return (((*trustLine)[sfFlags] &
|
||||
((account > issue.account) ? lsfLowAuth : lsfHighAuth)) != 0u)
|
||||
return ((*trustLine)[sfFlags] & ((account > issue.account) ? lsfLowAuth : lsfHighAuth))
|
||||
? tesSUCCESS
|
||||
: TER{tecNO_AUTH};
|
||||
}
|
||||
@@ -576,7 +575,7 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc
|
||||
bool const issuerHigh = issuerId > account;
|
||||
return line->isFlag(issuerHigh ? lsfHighNoRipple : lsfLowNoRipple);
|
||||
}
|
||||
return !sleIssuer->isFlag(lsfDefaultRipple);
|
||||
return sleIssuer->isFlag(lsfDefaultRipple) == false;
|
||||
};
|
||||
|
||||
// Fail if rippling disabled on both trust lines
|
||||
@@ -749,7 +748,7 @@ deleteAMMTrustLine(
|
||||
}
|
||||
|
||||
auto const uFlags = !ammLow ? lsfLowReserve : lsfHighReserve;
|
||||
if ((sleState->getFlags() & uFlags) == 0u)
|
||||
if (!(sleState->getFlags() & uFlags))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
adjustOwnerCount(view, !ammLow ? sleLow : sleHigh, -1, j);
|
||||
|
||||
@@ -570,18 +570,17 @@ rippleCreditIOU(
|
||||
// Sender balance was positive.
|
||||
&& saBalance <= beast::zero
|
||||
// Sender is zero or negative.
|
||||
&& ((uFlags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) != 0u)
|
||||
&& (uFlags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve))
|
||||
// Sender reserve is set.
|
||||
&& static_cast<bool>(uFlags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) !=
|
||||
static_cast<bool>(
|
||||
view.read(keylet::account(uSenderID))->getFlags() & lsfDefaultRipple) &&
|
||||
((uFlags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) == 0u) &&
|
||||
!(uFlags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) &&
|
||||
!sleRippleState->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit)
|
||||
// Sender trust limit is 0.
|
||||
&& (sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn) == 0u)
|
||||
&& !sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn)
|
||||
// Sender quality in is 0.
|
||||
&&
|
||||
(sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut) == 0u))
|
||||
&& !sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut))
|
||||
// Sender quality out is 0.
|
||||
{
|
||||
// Clear the reserve of the sender, possibly delete the line!
|
||||
@@ -593,7 +592,7 @@ rippleCreditIOU(
|
||||
|
||||
// Balance is zero, receiver reserve is clear.
|
||||
bDelete = !saBalance // Balance is zero.
|
||||
&& ((uFlags & (bSenderHigh ? lsfLowReserve : lsfHighReserve)) == 0u);
|
||||
&& !(uFlags & (bSenderHigh ? lsfLowReserve : lsfHighReserve));
|
||||
// Receiver reserve is clear.
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ sharesToAssetsWithdraw(
|
||||
std::shared_ptr<SLE const> const& issuance,
|
||||
STAmount const& shares)
|
||||
{
|
||||
XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsWithdraw : non-negative shares");
|
||||
XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares");
|
||||
XRPL_ASSERT(
|
||||
shares.asset() == vault->at(sfShareMPTID),
|
||||
"xrpl::sharesToAssetsWithdraw : shares and vault match");
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace {
|
||||
// and follow the format described at http://semver.org/
|
||||
//------------------------------------------------------------------------------
|
||||
// clang-format off
|
||||
char const* const versionString = "3.2.0-b1"
|
||||
char const* const versionString = "3.2.0-b0"
|
||||
// clang-format on
|
||||
;
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/LedgerHeader.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -53,21 +51,4 @@ deserializePrefixedHeader(Slice data, bool hasHash)
|
||||
return deserializeHeader(data + 4, hasHash);
|
||||
}
|
||||
|
||||
uint256
|
||||
calculateLedgerHash(LedgerHeader const& info)
|
||||
{
|
||||
// VFALCO This has to match addRaw in View.h.
|
||||
return sha512Half(
|
||||
HashPrefix::ledgerMaster,
|
||||
std::uint32_t(info.seq),
|
||||
std::uint64_t(info.drops.drops()),
|
||||
info.parentHash,
|
||||
info.txHash,
|
||||
info.accountHash,
|
||||
std::uint32_t(info.parentCloseTime.time_since_epoch().count()),
|
||||
std::uint32_t(info.closeTime.time_since_epoch().count()),
|
||||
std::uint8_t(info.closeTimeResolution.count()),
|
||||
std::uint8_t(info.closeFlags));
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -12,6 +12,8 @@ namespace xrpl {
|
||||
Expected<std::vector<SignerEntries::SignerEntry>, NotTEC>
|
||||
SignerEntries::deserialize(STObject const& obj, beast::Journal journal, std::string_view annotation)
|
||||
{
|
||||
std::pair<std::vector<SignerEntry>, NotTEC> s;
|
||||
|
||||
if (!obj.isFieldPresent(sfSignerEntries))
|
||||
{
|
||||
JLOG(journal.trace()) << "Malformed " << annotation << ": Need signer entry array.";
|
||||
|
||||
@@ -677,7 +677,8 @@ Transactor::checkSign(
|
||||
}
|
||||
|
||||
// Look up the account.
|
||||
auto const idSigner = calcAccountID(PublicKey(makeSlice(pkSigner)));
|
||||
auto const idSigner =
|
||||
pkSigner.empty() ? idAccount : calcAccountID(PublicKey(makeSlice(pkSigner)));
|
||||
auto const sleAccount = view.read(keylet::account(idAccount));
|
||||
if (!sleAccount)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
@@ -100,6 +100,8 @@ PermissionedDomainSet::doApply()
|
||||
Keylet const pdKeylet =
|
||||
keylet::permissionedDomain(account_, ctx_.tx.getFieldU32(sfSequence));
|
||||
auto slePd = std::make_shared<SLE>(pdKeylet);
|
||||
if (!slePd)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
slePd->setAccountID(sfOwner, account_);
|
||||
slePd->setFieldU32(sfSequence, ctx_.tx.getFieldU32(sfSequence));
|
||||
|
||||
@@ -55,7 +55,7 @@ VaultDelete::preclaim(PreclaimContext const& ctx)
|
||||
if (!sleMPT)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(ctx.j.error()) << "VaultDelete: missing issuance of vault shares.";
|
||||
JLOG(ctx.j.error()) << "VaultDeposit: missing issuance of vault shares.";
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
@@ -63,7 +63,7 @@ VaultDelete::preclaim(PreclaimContext const& ctx)
|
||||
if (sleMPT->at(sfIssuer) != vault->getAccountID(sfAccount))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(ctx.j.error()) << "VaultDelete: invalid owner of vault shares.";
|
||||
JLOG(ctx.j.error()) << "VaultDeposit: invalid owner of vault shares.";
|
||||
return tecNO_PERMISSION;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
@@ -200,6 +200,8 @@ VaultDelete::doApply()
|
||||
// Destroy the vault.
|
||||
view().erase(vault);
|
||||
|
||||
associateAsset(*vault, asset);
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
#include <test/jtx/amount.h>
|
||||
#include <test/jtx/sendmax.h>
|
||||
|
||||
#include <xrpld/app/paths/AMMOffer.h>
|
||||
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/tx/paths/AMMOffer.h>
|
||||
#include <xrpl/tx/paths/Flow.h>
|
||||
#include <xrpl/tx/paths/detail/StrandFlow.h>
|
||||
#include <xrpl/tx/transactors/dex/AMMContext.h>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <test/jtx.h>
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/misc/FeeVote.h>
|
||||
|
||||
#include <xrpl/basics/BasicConfig.h>
|
||||
@@ -250,8 +251,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
jtx::Env env(*this, jtx::testable_amendments() - featureXRPFees);
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
env.app().config(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
|
||||
@@ -280,8 +280,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
jtx::Env env(*this, jtx::testable_amendments() | featureXRPFees);
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
env.app().config(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
|
||||
@@ -313,8 +312,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
jtx::Env env(*this, jtx::testable_amendments() - featureXRPFees);
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
env.app().config(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
|
||||
@@ -335,8 +333,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
jtx::Env env(*this, jtx::testable_amendments() | featureXRPFees);
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
env.app().config(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
|
||||
@@ -361,11 +358,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
|
||||
jtx::Env env(*this, jtx::testable_amendments());
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, env.app().config(), std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
|
||||
// Create the next ledger to apply transaction to
|
||||
ledger = std::make_shared<Ledger>(*ledger, env.app().timeKeeper().closeTime());
|
||||
@@ -400,11 +393,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
|
||||
jtx::Env env(*this, jtx::testable_amendments() | featureXRPFees);
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, env.app().config(), std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
|
||||
ledger = std::make_shared<Ledger>(*ledger, env.app().timeKeeper().closeTime());
|
||||
|
||||
@@ -448,11 +437,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
|
||||
jtx::Env env(*this, jtx::testable_amendments() | featureXRPFees);
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, env.app().config(), std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
|
||||
ledger = std::make_shared<Ledger>(*ledger, env.app().timeKeeper().closeTime());
|
||||
|
||||
@@ -479,11 +464,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
|
||||
jtx::Env env(*this, jtx::testable_amendments() | featureXRPFees);
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, env.app().config(), std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
|
||||
ledger = std::make_shared<Ledger>(*ledger, env.app().timeKeeper().closeTime());
|
||||
|
||||
@@ -525,11 +506,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
|
||||
jtx::Env env(*this, jtx::testable_amendments() | featureXRPFees);
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, env.app().config(), std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
|
||||
ledger = std::make_shared<Ledger>(*ledger, env.app().timeKeeper().closeTime());
|
||||
|
||||
@@ -567,8 +544,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
env.app().config(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
|
||||
@@ -597,8 +573,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
env.app().config(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
|
||||
@@ -641,11 +616,7 @@ class FeeVote_test : public beast::unit_test::suite
|
||||
|
||||
auto feeVote = make_FeeVote(setup, env.app().journal("FeeVote"));
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, env.app().config(), std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
|
||||
// doVoting requires a flag ledger (every 256th ledger)
|
||||
// We need to create a ledger at sequence 256 to make it a flag ledger
|
||||
|
||||
@@ -38,8 +38,7 @@ public:
|
||||
assert(!stx);
|
||||
return std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
env.app().config(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include <test/jtx.h>
|
||||
|
||||
#include <xrpld/app/consensus/RCLValidations.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
|
||||
namespace xrpl {
|
||||
namespace test {
|
||||
@@ -57,11 +57,7 @@ class RCLValidations_test : public beast::unit_test::suite
|
||||
jtx::Env env(*this);
|
||||
Config config;
|
||||
auto prev = std::make_shared<Ledger const>(
|
||||
create_genesis,
|
||||
Rules{config.features},
|
||||
config.FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, config, std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
history.push_back(prev);
|
||||
for (auto i = 0; i < ((2 * maxAncestors) + 1); ++i)
|
||||
{
|
||||
@@ -223,11 +219,7 @@ class RCLValidations_test : public beast::unit_test::suite
|
||||
auto& j = env.journal;
|
||||
Config config;
|
||||
auto prev = std::make_shared<Ledger const>(
|
||||
create_genesis,
|
||||
Rules{config.features},
|
||||
config.FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, config, std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
history.push_back(prev);
|
||||
for (auto i = 0; i < (maxAncestors + 10); ++i)
|
||||
{
|
||||
|
||||
@@ -45,11 +45,7 @@ struct Regression_test : public beast::unit_test::suite
|
||||
// be reproduced against an open ledger. Make a local
|
||||
// closed ledger and work with it directly.
|
||||
auto closed = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, env.app().config(), std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
auto expectedDrops = INITIAL_XRP;
|
||||
BEAST_EXPECT(closed->header().drops == expectedDrops);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class io_latency_probe_test : public beast::unit_test::suite, public beast::test
|
||||
bool done = false;
|
||||
boost::system::error_code wait_err;
|
||||
|
||||
while (--num_samples > 0u)
|
||||
while (--num_samples)
|
||||
{
|
||||
auto const start{MeasureClock::now()};
|
||||
done = false;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <xrpld/consensus/LedgerTiming.h>
|
||||
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/ledger/LedgerTiming.h>
|
||||
|
||||
namespace xrpl {
|
||||
namespace test {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <test/jtx.h>
|
||||
|
||||
#include <xrpld/app/consensus/RCLValidations.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/misc/NegativeUNLVote.h>
|
||||
#include <xrpld/app/misc/ValidatorList.h>
|
||||
|
||||
@@ -210,11 +211,7 @@ class NegativeUNL_test : public beast::unit_test::suite
|
||||
std::vector<PublicKey> publicKeys = createPublicKeys(3);
|
||||
// genesis ledger
|
||||
auto l = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, env.app().config(), std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
|
||||
// Record the public keys and ledger sequences of expected negative UNL
|
||||
// validators when we build the ledger history
|
||||
@@ -546,8 +543,7 @@ struct NetworkHistory
|
||||
static uint256 fake_amendment; // So we have different genesis ledgers
|
||||
auto l = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
env.app().config(),
|
||||
std::vector<uint256>{fake_amendment++},
|
||||
env.app().getNodeFamily());
|
||||
history.push_back(l);
|
||||
@@ -1674,11 +1670,7 @@ class NegativeUNLVoteFilterValidations_test : public beast::unit_test::suite
|
||||
testcase("Filter Validations");
|
||||
jtx::Env env(*this);
|
||||
auto l = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{env.app().config().features},
|
||||
env.app().config().FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, env.app().config(), std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
|
||||
auto createSTVal = [&](std::pair<PublicKey, SecretKey> const& keys) {
|
||||
return std::make_shared<STValidation>(
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
#include <test/csf/Tx.h>
|
||||
|
||||
#include <xrpld/consensus/LedgerTiming.h>
|
||||
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/basics/comparators.h>
|
||||
#include <xrpl/basics/tagged_integer.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/ledger/LedgerTiming.h>
|
||||
|
||||
#include <boost/bimap/bimap.hpp>
|
||||
|
||||
|
||||
@@ -11,17 +11,17 @@
|
||||
#include <test/jtx/vault.h>
|
||||
#include <test/unit_test/SuiteJournal.h>
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/OpenLedger.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/paths/Pathfinder.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/rpc/detail/Pathfinder.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/protocol/ApiVersion.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <test/jtx/paths.h>
|
||||
|
||||
#include <xrpld/rpc/detail/Pathfinder.h>
|
||||
#include <xrpld/app/paths/Pathfinder.h>
|
||||
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
#include <test/jtx/Account.h>
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <xrpld/app/ledger/PendingSaves.h>
|
||||
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/ledger/PendingSaves.h>
|
||||
|
||||
namespace xrpl {
|
||||
namespace test {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include <test/jtx/Env.h>
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -17,11 +18,7 @@ class SkipList_test : public beast::unit_test::suite
|
||||
{
|
||||
Config config;
|
||||
auto prev = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{config.features},
|
||||
config.FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, config, std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
history.push_back(prev);
|
||||
for (auto i = 0; i < 1023; ++i)
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <test/jtx.h>
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/core/ConfigSections.h>
|
||||
|
||||
#include <xrpl/ledger/ApplyViewImpl.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/Sandbox.h>
|
||||
@@ -116,11 +116,7 @@ class View_test : public beast::unit_test::suite
|
||||
Env env(*this);
|
||||
Config config;
|
||||
std::shared_ptr<Ledger const> const genesis = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{config.features},
|
||||
config.FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, config, std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
auto const ledger = std::make_shared<Ledger>(*genesis, env.app().timeKeeper().closeTime());
|
||||
wipe(*ledger);
|
||||
ReadView& v = *ledger;
|
||||
@@ -383,11 +379,7 @@ class View_test : public beast::unit_test::suite
|
||||
Env env(*this);
|
||||
Config config;
|
||||
std::shared_ptr<Ledger const> const genesis = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{config.features},
|
||||
config.FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, config, std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
auto const ledger = std::make_shared<Ledger>(*genesis, env.app().timeKeeper().closeTime());
|
||||
|
||||
auto setup = [&ledger](std::vector<int> const& vec) {
|
||||
@@ -591,11 +583,7 @@ class View_test : public beast::unit_test::suite
|
||||
Env env(*this);
|
||||
Config config;
|
||||
std::shared_ptr<Ledger const> const genesis = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{config.features},
|
||||
config.FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, config, std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
auto const ledger = std::make_shared<Ledger>(*genesis, env.app().timeKeeper().closeTime());
|
||||
auto setup123 = [&ledger, this]() {
|
||||
// erase middle element
|
||||
@@ -941,11 +929,7 @@ class View_test : public beast::unit_test::suite
|
||||
Env env(*this);
|
||||
Config config;
|
||||
std::shared_ptr<Ledger const> const genesis = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{config.features},
|
||||
config.FEES.toFees(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
create_genesis, config, std::vector<uint256>{}, env.app().getNodeFamily());
|
||||
auto const ledger =
|
||||
std::make_shared<Ledger>(*genesis, env.app().timeKeeper().closeTime());
|
||||
wipe(*ledger);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <test/jtx/amount.h>
|
||||
#include <test/jtx/pay.h>
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/LedgerMaster.h>
|
||||
#include <xrpld/overlay/Compression.h>
|
||||
#include <xrpld/overlay/Message.h>
|
||||
@@ -14,7 +15,6 @@
|
||||
#include <xrpl/basics/random.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/protocol/SecretKey.h>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpld/app/ledger/BuildLedger.h>
|
||||
#include <xrpld/app/ledger/InboundLedgers.h>
|
||||
#include <xrpld/app/ledger/InboundTransactions.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/LedgerMaster.h>
|
||||
#include <xrpld/app/ledger/LocalTxs.h>
|
||||
#include <xrpld/app/ledger/OpenLedger.h>
|
||||
@@ -10,6 +11,7 @@
|
||||
#include <xrpld/app/misc/TxQ.h>
|
||||
#include <xrpld/app/misc/ValidatorKeys.h>
|
||||
#include <xrpld/app/misc/ValidatorList.h>
|
||||
#include <xrpld/consensus/LedgerTiming.h>
|
||||
#include <xrpld/overlay/Overlay.h>
|
||||
#include <xrpld/overlay/predicates.h>
|
||||
|
||||
@@ -18,8 +20,6 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/HashRouter.h>
|
||||
#include <xrpl/ledger/AmendmentTable.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/ledger/LedgerTiming.h>
|
||||
#include <xrpl/protocol/BuildInfo.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/LedgerToJson.h>
|
||||
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/RippleLedgerHash.h>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/consensus/Validations.h>
|
||||
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/RippleLedgerHash.h>
|
||||
#include <xrpl/protocol/STValidation.h>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/detail/TimeoutCounter.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/overlay/PeerSet.h>
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
#include <xrpld/app/ledger/InboundLedgers.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/LedgerToJson.h>
|
||||
#include <xrpld/app/ledger/PendingSaves.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/consensus/LedgerTiming.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/HashRouter.h>
|
||||
#include <xrpl/core/JobQueue.h>
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/ledger/LedgerTiming.h>
|
||||
#include <xrpl/nodestore/Database.h>
|
||||
#include <xrpl/nodestore/detail/DatabaseNodeImp.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -11,6 +21,7 @@
|
||||
#include <xrpl/protocol/SecretKey.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -19,6 +30,23 @@ namespace xrpl {
|
||||
|
||||
create_genesis_t const create_genesis{};
|
||||
|
||||
uint256
|
||||
calculateLedgerHash(LedgerHeader const& info)
|
||||
{
|
||||
// VFALCO This has to match addRaw in View.h.
|
||||
return sha512Half(
|
||||
HashPrefix::ledgerMaster,
|
||||
std::uint32_t(info.seq),
|
||||
std::uint64_t(info.drops.drops()),
|
||||
info.parentHash,
|
||||
info.txHash,
|
||||
info.accountHash,
|
||||
std::uint32_t(info.parentCloseTime.time_since_epoch().count()),
|
||||
std::uint32_t(info.closeTime.time_since_epoch().count()),
|
||||
std::uint8_t(info.closeTimeResolution.count()),
|
||||
std::uint8_t(info.closeFlags));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class Ledger::sles_iter_impl : public sles_type::iter_base
|
||||
@@ -110,8 +138,8 @@ public:
|
||||
{
|
||||
auto const& item = *iter_;
|
||||
if (metadata_)
|
||||
return Ledger::deserializeTxPlusMeta(item);
|
||||
return {Ledger::deserializeTx(item), nullptr};
|
||||
return deserializeTxPlusMeta(item);
|
||||
return {deserializeTx(item), nullptr};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -119,15 +147,13 @@ public:
|
||||
|
||||
Ledger::Ledger(
|
||||
create_genesis_t,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
Config const& config,
|
||||
std::vector<uint256> const& amendments,
|
||||
Family& family)
|
||||
: mImmutable(false)
|
||||
, txMap_(SHAMapType::TRANSACTION, family)
|
||||
, stateMap_(SHAMapType::STATE, family)
|
||||
, fees_(fees)
|
||||
, rules_(rules)
|
||||
, rules_{config.features}
|
||||
, j_(beast::Journal(beast::Journal::getNullSink()))
|
||||
{
|
||||
header_.seq = 1;
|
||||
@@ -156,19 +182,19 @@ Ledger::Ledger(
|
||||
// Whether featureXRPFees is supported will depend on startup options.
|
||||
if (std::find(amendments.begin(), amendments.end(), featureXRPFees) != amendments.end())
|
||||
{
|
||||
sle->at(sfBaseFeeDrops) = fees.base;
|
||||
sle->at(sfReserveBaseDrops) = fees.reserve;
|
||||
sle->at(sfReserveIncrementDrops) = fees.increment;
|
||||
sle->at(sfBaseFeeDrops) = config.FEES.reference_fee;
|
||||
sle->at(sfReserveBaseDrops) = config.FEES.account_reserve;
|
||||
sle->at(sfReserveIncrementDrops) = config.FEES.owner_reserve;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto const f = fees.base.dropsAs<std::uint64_t>())
|
||||
if (auto const f = config.FEES.reference_fee.dropsAs<std::uint64_t>())
|
||||
sle->at(sfBaseFee) = *f;
|
||||
if (auto const f = fees.reserve.dropsAs<std::uint32_t>())
|
||||
if (auto const f = config.FEES.account_reserve.dropsAs<std::uint32_t>())
|
||||
sle->at(sfReserveBase) = *f;
|
||||
if (auto const f = fees.increment.dropsAs<std::uint32_t>())
|
||||
if (auto const f = config.FEES.owner_reserve.dropsAs<std::uint32_t>())
|
||||
sle->at(sfReserveIncrement) = *f;
|
||||
sle->at(sfReferenceFeeUnits) = FEE_UNITS_DEPRECATED;
|
||||
sle->at(sfReferenceFeeUnits) = Config::FEE_UNITS_DEPRECATED;
|
||||
}
|
||||
rawInsert(sle);
|
||||
}
|
||||
@@ -181,15 +207,13 @@ Ledger::Ledger(
|
||||
LedgerHeader const& info,
|
||||
bool& loaded,
|
||||
bool acquire,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
Config const& config,
|
||||
Family& family,
|
||||
beast::Journal j)
|
||||
: mImmutable(true)
|
||||
, txMap_(SHAMapType::TRANSACTION, info.txHash, family)
|
||||
, stateMap_(SHAMapType::STATE, info.accountHash, family)
|
||||
, fees_(fees)
|
||||
, rules_(rules)
|
||||
, rules_(config.features)
|
||||
, header_(info)
|
||||
, j_(j)
|
||||
{
|
||||
@@ -211,6 +235,7 @@ Ledger::Ledger(
|
||||
txMap_.setImmutable();
|
||||
stateMap_.setImmutable();
|
||||
|
||||
defaultFees(config);
|
||||
if (!setup())
|
||||
loaded = false;
|
||||
|
||||
@@ -250,11 +275,11 @@ Ledger::Ledger(Ledger const& prevLedger, NetClock::time_point closeTime)
|
||||
}
|
||||
}
|
||||
|
||||
Ledger::Ledger(LedgerHeader const& info, Rules const& rules, Family& family)
|
||||
Ledger::Ledger(LedgerHeader const& info, Config const& config, Family& family)
|
||||
: mImmutable(true)
|
||||
, txMap_(SHAMapType::TRANSACTION, info.txHash, family)
|
||||
, stateMap_(SHAMapType::STATE, info.accountHash, family)
|
||||
, rules_(rules)
|
||||
, rules_{config.features}
|
||||
, header_(info)
|
||||
, j_(beast::Journal(beast::Journal::getNullSink()))
|
||||
{
|
||||
@@ -264,19 +289,18 @@ Ledger::Ledger(LedgerHeader const& info, Rules const& rules, Family& family)
|
||||
Ledger::Ledger(
|
||||
std::uint32_t ledgerSeq,
|
||||
NetClock::time_point closeTime,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
Config const& config,
|
||||
Family& family)
|
||||
: mImmutable(false)
|
||||
, txMap_(SHAMapType::TRANSACTION, family)
|
||||
, stateMap_(SHAMapType::STATE, family)
|
||||
, fees_(fees)
|
||||
, rules_(rules)
|
||||
, rules_{config.features}
|
||||
, j_(beast::Journal(beast::Journal::getNullSink()))
|
||||
{
|
||||
header_.seq = ledgerSeq;
|
||||
header_.closeTime = closeTime;
|
||||
header_.closeTimeResolution = ledgerDefaultTimeResolution;
|
||||
defaultFees(config);
|
||||
setup();
|
||||
}
|
||||
|
||||
@@ -326,14 +350,14 @@ Ledger::addSLE(SLE const& sle)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::shared_ptr<STTx const>
|
||||
Ledger::deserializeTx(SHAMapItem const& item)
|
||||
deserializeTx(SHAMapItem const& item)
|
||||
{
|
||||
SerialIter sit(item.slice());
|
||||
return std::make_shared<STTx const>(sit);
|
||||
}
|
||||
|
||||
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>
|
||||
Ledger::deserializeTxPlusMeta(SHAMapItem const& item)
|
||||
deserializeTxPlusMeta(SHAMapItem const& item)
|
||||
{
|
||||
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>> result;
|
||||
SerialIter sit(item.slice());
|
||||
@@ -612,6 +636,20 @@ Ledger::setup()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
Ledger::defaultFees(Config const& config)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
fees_.base == 0 && fees_.reserve == 0 && fees_.increment == 0,
|
||||
"xrpl::Ledger::defaultFees : zero fees");
|
||||
if (fees_.base == 0)
|
||||
fees_.base = config.FEES.reference_fee;
|
||||
if (fees_.reserve == 0)
|
||||
fees_.reserve = config.FEES.account_reserve;
|
||||
if (fees_.increment == 0)
|
||||
fees_.increment = config.FEES.owner_reserve;
|
||||
}
|
||||
|
||||
std::shared_ptr<SLE>
|
||||
Ledger::peek(Keylet const& k) const
|
||||
{
|
||||
@@ -778,17 +816,27 @@ Ledger::walkLedger(beast::Journal j, bool parallel) const
|
||||
}
|
||||
|
||||
bool
|
||||
Ledger::isSensible() const
|
||||
Ledger::assertSensible(beast::Journal ledgerJ) const
|
||||
{
|
||||
if (header_.hash.isZero())
|
||||
return false;
|
||||
if (header_.accountHash.isZero())
|
||||
return false;
|
||||
if (header_.accountHash != stateMap_.getHash().as_uint256())
|
||||
return false;
|
||||
if (header_.txHash != txMap_.getHash().as_uint256())
|
||||
return false;
|
||||
return true;
|
||||
if (header_.hash.isNonZero() && header_.accountHash.isNonZero() &&
|
||||
(header_.accountHash == stateMap_.getHash().as_uint256()) &&
|
||||
(header_.txHash == txMap_.getHash().as_uint256()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
Json::Value j = getJson({*this, {}});
|
||||
|
||||
j[jss::accountTreeHash] = to_string(header_.accountHash);
|
||||
j[jss::transTreeHash] = to_string(header_.txHash);
|
||||
|
||||
JLOG(ledgerJ.fatal()) << "ledger is not sensible" << j;
|
||||
|
||||
UNREACHABLE("xrpl::Ledger::assertSensible : ledger is not sensible");
|
||||
|
||||
return false;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
// update the skip list with the information from our previous ledger
|
||||
@@ -877,6 +925,76 @@ Ledger::isVotingLedger() const
|
||||
return ::xrpl::isVotingLedger(header_.seq + 1);
|
||||
}
|
||||
|
||||
static bool
|
||||
saveValidatedLedger(Application& app, std::shared_ptr<Ledger const> const& ledger, bool current)
|
||||
{
|
||||
auto j = app.journal("Ledger");
|
||||
auto seq = ledger->header().seq;
|
||||
if (!app.pendingSaves().startWork(seq))
|
||||
{
|
||||
// The save was completed synchronously
|
||||
JLOG(j.debug()) << "Save aborted";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& db = app.getRelationalDatabase();
|
||||
|
||||
auto const res = db.saveValidatedLedger(ledger, current);
|
||||
|
||||
// Clients can now trust the database for
|
||||
// information about this ledger sequence.
|
||||
app.pendingSaves().finishWork(seq);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Save, or arrange to save, a fully-validated ledger
|
||||
Returns false on error
|
||||
*/
|
||||
bool
|
||||
pendSaveValidated(
|
||||
Application& app,
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
bool isSynchronous,
|
||||
bool isCurrent)
|
||||
{
|
||||
if (!app.getHashRouter().setFlags(ledger->header().hash, HashRouterFlags::SAVED))
|
||||
{
|
||||
// We have tried to save this ledger recently
|
||||
auto stream = app.journal("Ledger").debug();
|
||||
JLOG(stream) << "Double pend save for " << ledger->header().seq;
|
||||
|
||||
if (!isSynchronous || !app.pendingSaves().pending(ledger->header().seq))
|
||||
{
|
||||
// Either we don't need it to be finished
|
||||
// or it is finished
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
XRPL_ASSERT(ledger->isImmutable(), "xrpl::pendSaveValidated : immutable ledger");
|
||||
|
||||
if (!app.pendingSaves().shouldWork(ledger->header().seq, isSynchronous))
|
||||
{
|
||||
auto stream = app.journal("Ledger").debug();
|
||||
JLOG(stream) << "Pend save with seq in pending saves " << ledger->header().seq;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// See if we can use the JobQueue.
|
||||
if (!isSynchronous &&
|
||||
app.getJobQueue().addJob(
|
||||
isCurrent ? jtPUBLEDGER : jtPUBOLDLEDGER,
|
||||
std::to_string(ledger->seq()),
|
||||
[&app, ledger, isCurrent]() { saveValidatedLedger(app, ledger, isCurrent); }))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// The JobQueue won't do the Job. Do the save synchronously.
|
||||
return saveValidatedLedger(app, ledger, isCurrent);
|
||||
}
|
||||
|
||||
void
|
||||
Ledger::unshare() const
|
||||
{
|
||||
@@ -890,5 +1008,84 @@ Ledger::invariants() const
|
||||
stateMap_.invariants();
|
||||
txMap_.invariants();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Make ledger using info loaded from database.
|
||||
*
|
||||
* @param LedgerHeader: Ledger information.
|
||||
* @param app: Link to the Application.
|
||||
* @param acquire: Acquire the ledger if not found locally.
|
||||
* @return Shared pointer to the ledger.
|
||||
*/
|
||||
std::shared_ptr<Ledger>
|
||||
loadLedgerHelper(LedgerHeader const& info, Application& app, bool acquire)
|
||||
{
|
||||
bool loaded = false;
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
info, loaded, acquire, app.config(), app.getNodeFamily(), app.journal("Ledger"));
|
||||
|
||||
if (!loaded)
|
||||
ledger.reset();
|
||||
|
||||
return ledger;
|
||||
}
|
||||
|
||||
static void
|
||||
finishLoadByIndexOrHash(
|
||||
std::shared_ptr<Ledger> const& ledger,
|
||||
Config const& config,
|
||||
beast::Journal j)
|
||||
{
|
||||
if (!ledger)
|
||||
return;
|
||||
|
||||
XRPL_ASSERT(
|
||||
ledger->header().seq < XRP_LEDGER_EARLIEST_FEES || ledger->read(keylet::fees()),
|
||||
"xrpl::finishLoadByIndexOrHash : valid ledger fees");
|
||||
ledger->setImmutable();
|
||||
|
||||
JLOG(j.trace()) << "Loaded ledger: " << to_string(ledger->header().hash);
|
||||
|
||||
ledger->setFull();
|
||||
}
|
||||
|
||||
std::tuple<std::shared_ptr<Ledger>, std::uint32_t, uint256>
|
||||
getLatestLedger(Application& app)
|
||||
{
|
||||
std::optional<LedgerHeader> const info = app.getRelationalDatabase().getNewestLedgerInfo();
|
||||
if (!info)
|
||||
return {std::shared_ptr<Ledger>(), {}, {}};
|
||||
return {loadLedgerHelper(*info, app, true), info->seq, info->hash};
|
||||
}
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
loadByIndex(std::uint32_t ledgerIndex, Application& app, bool acquire)
|
||||
{
|
||||
if (std::optional<LedgerHeader> info =
|
||||
app.getRelationalDatabase().getLedgerInfoByIndex(ledgerIndex))
|
||||
{
|
||||
std::shared_ptr<Ledger> ledger = loadLedgerHelper(*info, app, acquire);
|
||||
finishLoadByIndexOrHash(ledger, app.config(), app.journal("Ledger"));
|
||||
return ledger;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
loadByHash(uint256 const& ledgerHash, Application& app, bool acquire)
|
||||
{
|
||||
if (std::optional<LedgerHeader> info =
|
||||
app.getRelationalDatabase().getLedgerInfoByHash(ledgerHash))
|
||||
{
|
||||
std::shared_ptr<Ledger> ledger = loadLedgerHelper(*info, app, acquire);
|
||||
finishLoadByIndexOrHash(ledger, app.config(), app.journal("Ledger"));
|
||||
XRPL_ASSERT(
|
||||
!ledger || ledger->header().hash == ledgerHash,
|
||||
"xrpl::loadByHash : ledger hash match if loaded");
|
||||
return ledger;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,12 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/TimeKeeper.h>
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/CachedView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/protocol/Fees.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/TxMeta.h>
|
||||
@@ -14,7 +15,7 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class ServiceRegistry;
|
||||
class Application;
|
||||
class Job;
|
||||
class TransactionMaster;
|
||||
|
||||
@@ -82,26 +83,21 @@ public:
|
||||
*/
|
||||
Ledger(
|
||||
create_genesis_t,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
Config const& config,
|
||||
std::vector<uint256> const& amendments,
|
||||
Family& family);
|
||||
|
||||
Ledger(LedgerHeader const& info, Rules const& rules, Family& family);
|
||||
Ledger(LedgerHeader const& info, Config const& config, Family& family);
|
||||
|
||||
/** Used for ledgers loaded from JSON files
|
||||
|
||||
@param acquire If true, acquires the ledger if not found locally
|
||||
|
||||
@note The fees parameter provides default values, but setup() may
|
||||
override them from the ledger state if fee-related SLEs exist.
|
||||
*/
|
||||
Ledger(
|
||||
LedgerHeader const& info,
|
||||
bool& loaded,
|
||||
bool acquire,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
Config const& config,
|
||||
Family& family,
|
||||
beast::Journal j);
|
||||
|
||||
@@ -117,8 +113,7 @@ public:
|
||||
Ledger(
|
||||
std::uint32_t ledgerSeq,
|
||||
NetClock::time_point closeTime,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
Config const& config,
|
||||
Family& family);
|
||||
|
||||
~Ledger() = default;
|
||||
@@ -327,7 +322,7 @@ public:
|
||||
walkLedger(beast::Journal j, bool parallel = false) const;
|
||||
|
||||
bool
|
||||
isSensible() const;
|
||||
assertSensible(beast::Journal ledgerJ) const;
|
||||
|
||||
void
|
||||
invariants() const;
|
||||
@@ -384,26 +379,8 @@ private:
|
||||
bool
|
||||
setup();
|
||||
|
||||
/** @brief Deserialize a SHAMapItem containing a single STTx.
|
||||
*
|
||||
* @param item The SHAMapItem to deserialize.
|
||||
* @return A shared pointer to the deserialized transaction.
|
||||
* @throw May throw on deserialization error.
|
||||
*/
|
||||
static std::shared_ptr<STTx const>
|
||||
deserializeTx(SHAMapItem const& item);
|
||||
|
||||
/** @brief Deserialize a SHAMapItem containing STTx + STObject metadata.
|
||||
*
|
||||
* The SHAMapItem must contain two variable length serialization objects.
|
||||
*
|
||||
* @param item The SHAMapItem to deserialize.
|
||||
* @return A pair containing shared pointers to the deserialized transaction
|
||||
* and metadata.
|
||||
* @throw May throw on deserialization error.
|
||||
*/
|
||||
static std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>
|
||||
deserializeTxPlusMeta(SHAMapItem const& item);
|
||||
void
|
||||
defaultFees(Config const& config);
|
||||
|
||||
bool mImmutable;
|
||||
|
||||
@@ -425,4 +402,54 @@ private:
|
||||
/** A ledger wrapped in a CachedView. */
|
||||
using CachedLedger = CachedView<Ledger>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// API
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
extern bool
|
||||
pendSaveValidated(
|
||||
Application& app,
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
bool isSynchronous,
|
||||
bool isCurrent);
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
loadLedgerHelper(LedgerHeader const& sinfo, Application& app, bool acquire);
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
loadByIndex(std::uint32_t ledgerIndex, Application& app, bool acquire = true);
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
loadByHash(uint256 const& ledgerHash, Application& app, bool acquire = true);
|
||||
|
||||
// Fetch the ledger with the highest sequence contained in the database
|
||||
extern std::tuple<std::shared_ptr<Ledger>, std::uint32_t, uint256>
|
||||
getLatestLedger(Application& app);
|
||||
|
||||
/** Deserialize a SHAMapItem containing a single STTx
|
||||
|
||||
Throw:
|
||||
|
||||
May throw on deserializaton error
|
||||
*/
|
||||
std::shared_ptr<STTx const>
|
||||
deserializeTx(SHAMapItem const& item);
|
||||
|
||||
/** Deserialize a SHAMapItem containing STTx + STObject metadata
|
||||
|
||||
The SHAMap must contain two variable length
|
||||
serialization objects.
|
||||
|
||||
Throw:
|
||||
|
||||
May throw on deserializaton error
|
||||
*/
|
||||
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>
|
||||
deserializeTxPlusMeta(SHAMapItem const& item);
|
||||
|
||||
uint256
|
||||
calculateLedgerHash(LedgerHeader const& info);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,7 +1,5 @@
|
||||
#include <xrpld/app/ledger/LedgerHistory.h>
|
||||
#include <xrpld/app/ledger/LedgerPersistence.h>
|
||||
#include <xrpld/app/ledger/LedgerToJson.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
@@ -75,9 +73,7 @@ LedgerHistory::getLedgerBySeq(LedgerIndex index)
|
||||
}
|
||||
}
|
||||
|
||||
Rules const rules{app_.config().features};
|
||||
Fees const fees = app_.config().FEES.toFees();
|
||||
std::shared_ptr<Ledger const> ret = loadByIndex(index, rules, fees, app_);
|
||||
std::shared_ptr<Ledger const> ret = loadByIndex(index, app_);
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
@@ -115,9 +111,7 @@ LedgerHistory::getLedgerByHash(LedgerHash const& hash)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Rules const rules{app_.config().features};
|
||||
Fees const fees = app_.config().FEES.toFees();
|
||||
ret = loadByHash(hash, rules, fees, app_);
|
||||
ret = loadByHash(hash, app_);
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
|
||||
#include <xrpl/beast/insight/Collector.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/protocol/RippleLedgerHash.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
@@ -2,18 +2,17 @@
|
||||
|
||||
#include <xrpld/app/ledger/AbstractFetchPackContainer.h>
|
||||
#include <xrpld/app/ledger/InboundLedgers.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/LedgerHistory.h>
|
||||
#include <xrpld/app/ledger/LedgerHolder.h>
|
||||
#include <xrpld/app/ledger/LedgerReplay.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/core/TimeKeeper.h>
|
||||
#include <xrpld/app/misc/CanonicalTXSet.h>
|
||||
|
||||
#include <xrpl/basics/RangeSet.h>
|
||||
#include <xrpl/basics/UptimeClock.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/insight/Collector.h>
|
||||
#include <xrpl/ledger/CanonicalTXSet.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/RippleLedgerHash.h>
|
||||
#include <xrpl/protocol/messages.h>
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class ServiceRegistry;
|
||||
struct Fees;
|
||||
|
||||
/** Save, or arrange to save, a fully-validated ledger.
|
||||
|
||||
@param registry The service registry providing access to required services.
|
||||
@param ledger The fully-validated ledger to save.
|
||||
@param isSynchronous If true, wait for the save to complete.
|
||||
@param isCurrent If true, the ledger is the current validated ledger.
|
||||
|
||||
@return false on error.
|
||||
*/
|
||||
bool
|
||||
pendSaveValidated(
|
||||
ServiceRegistry& registry,
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
bool isSynchronous,
|
||||
bool isCurrent);
|
||||
|
||||
/** Make ledger using info loaded from database.
|
||||
|
||||
@param info Ledger information.
|
||||
@param rules Rules to use (may be overwritten by setup()).
|
||||
@param fees Fees to use (may be overwritten by setup()).
|
||||
@param registry Service registry for dependency injection.
|
||||
@param acquire Acquire the ledger if not found locally.
|
||||
@return Shared pointer to the ledger.
|
||||
*/
|
||||
std::shared_ptr<Ledger>
|
||||
loadLedgerHelper(
|
||||
LedgerHeader const& info,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
ServiceRegistry& registry,
|
||||
bool acquire);
|
||||
|
||||
/** Load a ledger by its sequence number.
|
||||
|
||||
@param ledgerIndex The sequence number of the ledger to load.
|
||||
@param rules Rules to use (may be overwritten by setup()).
|
||||
@param fees Fees to use (may be overwritten by setup()).
|
||||
@param registry Service registry for dependency injection.
|
||||
@param acquire Acquire the ledger if not found locally.
|
||||
@return Shared pointer to the ledger, or nullptr if not found.
|
||||
*/
|
||||
std::shared_ptr<Ledger>
|
||||
loadByIndex(
|
||||
std::uint32_t ledgerIndex,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
ServiceRegistry& registry,
|
||||
bool acquire = true);
|
||||
|
||||
/** Load a ledger by its hash.
|
||||
|
||||
@param ledgerHash The hash of the ledger to load.
|
||||
@param rules Rules to use (may be overwritten by setup()).
|
||||
@param fees Fees to use (may be overwritten by setup()).
|
||||
@param registry Service registry for dependency injection.
|
||||
@param acquire Acquire the ledger if not found locally.
|
||||
@return Shared pointer to the ledger, or nullptr if not found.
|
||||
*/
|
||||
std::shared_ptr<Ledger>
|
||||
loadByHash(
|
||||
uint256 const& ledgerHash,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
ServiceRegistry& registry,
|
||||
bool acquire = true);
|
||||
|
||||
/** Fetch the ledger with the highest sequence contained in the database.
|
||||
|
||||
@param rules Rules to use (may be overwritten by setup()).
|
||||
@param fees Fees to use (may be overwritten by setup()).
|
||||
@param registry Service registry for dependency injection.
|
||||
@return Tuple of (ledger, sequence, hash), or empty if not found.
|
||||
*/
|
||||
std::tuple<std::shared_ptr<Ledger>, std::uint32_t, uint256>
|
||||
getLatestLedger(Rules const& rules, Fees const& fees, ServiceRegistry& registry);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/LedgerMaster.h>
|
||||
#include <xrpld/app/misc/TxQ.h>
|
||||
#include <xrpld/rpc/Context.h>
|
||||
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/protocol/serialize.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/ledger/CanonicalTXSet.h>
|
||||
#include <xrpld/app/misc/CanonicalTXSet.h>
|
||||
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/misc/CanonicalTXSet.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
@@ -7,8 +9,6 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/CachedSLEs.h>
|
||||
#include <xrpl/ledger/CanonicalTXSet.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include <xrpld/app/ledger/BuildLedger.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/LedgerReplay.h>
|
||||
#include <xrpld/app/ledger/OpenLedger.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/misc/CanonicalTXSet.h>
|
||||
|
||||
#include <xrpl/ledger/CanonicalTXSet.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/tx/apply.h>
|
||||
|
||||
|
||||
@@ -224,9 +224,8 @@ InboundLedger::tryDB(NodeStore::Database& srcDB)
|
||||
{
|
||||
auto makeLedger = [&, this](Blob const& data) {
|
||||
JLOG(journal_.trace()) << "Ledger header found in fetch pack";
|
||||
Rules const rules{app_.config().features};
|
||||
mLedger = std::make_shared<Ledger>(
|
||||
deserializePrefixedHeader(makeSlice(data)), rules, app_.getNodeFamily());
|
||||
deserializePrefixedHeader(makeSlice(data)), app_.config(), app_.getNodeFamily());
|
||||
if (mLedger->header().hash != hash_ || (mSeq != 0 && mSeq != mLedger->header().seq))
|
||||
{
|
||||
// We know for a fact the ledger can never be acquired
|
||||
@@ -778,8 +777,7 @@ InboundLedger::takeHeader(std::string const& data)
|
||||
return true;
|
||||
|
||||
auto* f = &app_.getNodeFamily();
|
||||
Rules const rules{app_.config().features};
|
||||
mLedger = std::make_shared<Ledger>(deserializeHeader(makeSlice(data)), rules, *f);
|
||||
mLedger = std::make_shared<Ledger>(deserializeHeader(makeSlice(data)), app_.config(), *f);
|
||||
if (mLedger->header().hash != hash_ || (mSeq != 0 && mSeq != mLedger->header().seq))
|
||||
{
|
||||
JLOG(journal_.warn()) << "Acquire hash mismatch: " << mLedger->header().hash
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include <xrpld/app/ledger/InboundLedgers.h>
|
||||
#include <xrpld/app/ledger/LedgerCleaner.h>
|
||||
#include <xrpld/app/ledger/LedgerMaster.h>
|
||||
#include <xrpld/app/ledger/LedgerPersistence.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
|
||||
#include <xrpl/beast/core/CurrentThreadName.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
@@ -263,9 +261,7 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
Rules const rules{app_.config().features};
|
||||
Fees const fees = app_.config().FEES.toFees();
|
||||
auto const dbLedger = loadByIndex(ledgerIndex, rules, fees, app_);
|
||||
auto dbLedger = loadByIndex(ledgerIndex, app_);
|
||||
if (!dbLedger || (dbLedger->header().hash != ledgerHash) ||
|
||||
(dbLedger->header().parentHash != nodeLedger->header().parentHash))
|
||||
{
|
||||
|
||||
@@ -124,8 +124,7 @@ LedgerDeltaAcquire::processData(
|
||||
if (info.seq == ledgerSeq_)
|
||||
{
|
||||
// create a temporary ledger for building a LedgerReplay object later
|
||||
Rules const rules{app_.config().features};
|
||||
replayTemp_ = std::make_shared<Ledger>(info, rules, app_.getNodeFamily());
|
||||
replayTemp_ = std::make_shared<Ledger>(info, app_.config(), app_.getNodeFamily());
|
||||
if (replayTemp_)
|
||||
{
|
||||
complete_ = true;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/ledger/InboundLedger.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/detail/TimeoutCounter.h>
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
#include <xrpld/app/consensus/RCLValidations.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/LedgerMaster.h>
|
||||
#include <xrpld/app/ledger/LedgerPersistence.h>
|
||||
#include <xrpld/app/ledger/LedgerReplayer.h>
|
||||
#include <xrpld/app/ledger/OpenLedger.h>
|
||||
#include <xrpld/app/ledger/PendingSaves.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/misc/SHAMapStore.h>
|
||||
#include <xrpld/app/misc/Transaction.h>
|
||||
#include <xrpld/app/misc/TxQ.h>
|
||||
#include <xrpld/app/misc/ValidatorList.h>
|
||||
#include <xrpld/app/paths/PathRequests.h>
|
||||
#include <xrpld/core/TimeKeeper.h>
|
||||
#include <xrpld/overlay/Overlay.h>
|
||||
#include <xrpld/overlay/Peer.h>
|
||||
#include <xrpld/rpc/detail/PathRequestManager.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/MathUtilities.h>
|
||||
@@ -21,9 +22,7 @@
|
||||
#include <xrpl/basics/scope.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/AmendmentTable.h>
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/ledger/OrderBookDB.h>
|
||||
#include <xrpl/ledger/PendingSaves.h>
|
||||
#include <xrpl/protocol/BuildInfo.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
@@ -1390,7 +1389,7 @@ LedgerMaster::updatePaths()
|
||||
|
||||
try
|
||||
{
|
||||
auto& pathRequests = app_.getPathRequestManager();
|
||||
auto& pathRequests = app_.getPathRequests();
|
||||
{
|
||||
std::lock_guard ml(m_mutex);
|
||||
if (!pathRequests.requestsPending())
|
||||
@@ -1472,7 +1471,7 @@ LedgerMaster::newOrderBookDB()
|
||||
bool
|
||||
LedgerMaster::newPFWork(char const* name, std::unique_lock<std::recursive_mutex>&)
|
||||
{
|
||||
if (!app_.isStopping() && mPathFindThread < 2 && app_.getPathRequestManager().requestsPending())
|
||||
if (!app_.isStopping() && mPathFindThread < 2 && app_.getPathRequests().requestsPending())
|
||||
{
|
||||
JLOG(m_journal.debug()) << "newPFWork: Creating job. path find threads: "
|
||||
<< mPathFindThread;
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
#include <xrpld/app/ledger/LedgerPersistence.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/HashRouter.h>
|
||||
#include <xrpl/core/JobQueue.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/PendingSaves.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
static bool
|
||||
saveValidatedLedger(
|
||||
ServiceRegistry& registry,
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
bool current)
|
||||
{
|
||||
auto j = registry.journal("Ledger");
|
||||
auto seq = ledger->header().seq;
|
||||
if (!registry.pendingSaves().startWork(seq))
|
||||
{
|
||||
// The save was completed synchronously
|
||||
JLOG(j.debug()) << "Save aborted";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& db = registry.getRelationalDatabase();
|
||||
|
||||
auto const res = db.saveValidatedLedger(ledger, current);
|
||||
|
||||
// Clients can now trust the database for
|
||||
// information about this ledger sequence.
|
||||
registry.pendingSaves().finishWork(seq);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
pendSaveValidated(
|
||||
ServiceRegistry& registry,
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
bool isSynchronous,
|
||||
bool isCurrent)
|
||||
{
|
||||
if (!registry.getHashRouter().setFlags(ledger->header().hash, HashRouterFlags::SAVED))
|
||||
{
|
||||
// We have tried to save this ledger recently
|
||||
auto stream = registry.journal("Ledger").debug();
|
||||
JLOG(stream) << "Double pend save for " << ledger->header().seq;
|
||||
|
||||
if (!isSynchronous || !registry.pendingSaves().pending(ledger->header().seq))
|
||||
{
|
||||
// Either we don't need it to be finished
|
||||
// or it is finished
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
XRPL_ASSERT(ledger->isImmutable(), "xrpl::pendSaveValidated : immutable ledger");
|
||||
|
||||
if (!registry.pendingSaves().shouldWork(ledger->header().seq, isSynchronous))
|
||||
{
|
||||
auto stream = registry.journal("Ledger").debug();
|
||||
JLOG(stream) << "Pend save with seq in pending saves " << ledger->header().seq;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// See if we can use the JobQueue.
|
||||
if (!isSynchronous &&
|
||||
registry.getJobQueue().addJob(
|
||||
isCurrent ? jtPUBLEDGER : jtPUBOLDLEDGER,
|
||||
std::to_string(ledger->seq()),
|
||||
[®istry, ledger, isCurrent]() { saveValidatedLedger(registry, ledger, isCurrent); }))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// The JobQueue won't do the Job. Do the save synchronously.
|
||||
return saveValidatedLedger(registry, ledger, isCurrent);
|
||||
}
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
loadLedgerHelper(
|
||||
LedgerHeader const& info,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
ServiceRegistry& registry,
|
||||
bool acquire)
|
||||
{
|
||||
bool loaded = false;
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
info, loaded, acquire, rules, fees, registry.getNodeFamily(), registry.journal("Ledger"));
|
||||
|
||||
if (!loaded)
|
||||
ledger.reset();
|
||||
|
||||
return ledger;
|
||||
}
|
||||
|
||||
static void
|
||||
finishLoadByIndexOrHash(std::shared_ptr<Ledger> const& ledger, beast::Journal j)
|
||||
{
|
||||
if (!ledger)
|
||||
return;
|
||||
|
||||
XRPL_ASSERT(
|
||||
ledger->header().seq < XRP_LEDGER_EARLIEST_FEES || ledger->read(keylet::fees()),
|
||||
"xrpl::finishLoadByIndexOrHash : valid ledger fees");
|
||||
ledger->setImmutable();
|
||||
|
||||
JLOG(j.trace()) << "Loaded ledger: " << to_string(ledger->header().hash);
|
||||
|
||||
ledger->setFull();
|
||||
}
|
||||
|
||||
std::tuple<std::shared_ptr<Ledger>, std::uint32_t, uint256>
|
||||
getLatestLedger(Rules const& rules, Fees const& fees, ServiceRegistry& registry)
|
||||
{
|
||||
std::optional<LedgerHeader> const info = registry.getRelationalDatabase().getNewestLedgerInfo();
|
||||
if (!info)
|
||||
return {std::shared_ptr<Ledger>(), {}, {}};
|
||||
return {loadLedgerHelper(*info, rules, fees, registry, true), info->seq, info->hash};
|
||||
}
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
loadByIndex(
|
||||
std::uint32_t ledgerIndex,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
ServiceRegistry& registry,
|
||||
bool acquire)
|
||||
{
|
||||
if (std::optional<LedgerHeader> info =
|
||||
registry.getRelationalDatabase().getLedgerInfoByIndex(ledgerIndex))
|
||||
{
|
||||
std::shared_ptr<Ledger> ledger = loadLedgerHelper(*info, rules, fees, registry, acquire);
|
||||
finishLoadByIndexOrHash(ledger, registry.journal("Ledger"));
|
||||
return ledger;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
loadByHash(
|
||||
uint256 const& ledgerHash,
|
||||
Rules const& rules,
|
||||
Fees const& fees,
|
||||
ServiceRegistry& registry,
|
||||
bool acquire)
|
||||
{
|
||||
if (std::optional<LedgerHeader> info =
|
||||
registry.getRelationalDatabase().getLedgerInfoByHash(ledgerHash))
|
||||
{
|
||||
std::shared_ptr<Ledger> ledger = loadLedgerHelper(*info, rules, fees, registry, acquire);
|
||||
finishLoadByIndexOrHash(ledger, registry.journal("Ledger"));
|
||||
XRPL_ASSERT(
|
||||
!ledger || ledger->header().hash == ledgerHash,
|
||||
"xrpl::loadByHash : ledger hash match if loaded");
|
||||
return ledger;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/LedgerReplay.h>
|
||||
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
LedgerReplay::LedgerReplay(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/LocalTxs.h>
|
||||
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <xrpld/app/ledger/OpenLedger.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/misc/TxQ.h>
|
||||
#include <xrpld/core/TimeKeeper.h>
|
||||
#include <xrpld/overlay/Message.h>
|
||||
#include <xrpld/overlay/Overlay.h>
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/ledger/InboundLedger.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/ledger/detail/TimeoutCounter.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
|
||||
#include <xrpl/ledger/Ledger.h>
|
||||
#include <xrpl/shamap/SHAMap.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#include <xrpld/app/ledger/InboundTransactions.h>
|
||||
#include <xrpld/app/ledger/LedgerCleaner.h>
|
||||
#include <xrpld/app/ledger/LedgerMaster.h>
|
||||
#include <xrpld/app/ledger/LedgerPersistence.h>
|
||||
#include <xrpld/app/ledger/LedgerReplayer.h>
|
||||
#include <xrpld/app/ledger/LedgerToJson.h>
|
||||
#include <xrpld/app/ledger/OpenLedger.h>
|
||||
#include <xrpld/app/ledger/OrderBookDBImpl.h>
|
||||
#include <xrpld/app/ledger/PendingSaves.h>
|
||||
#include <xrpld/app/ledger/TransactionMaster.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/main/BasicApp.h>
|
||||
@@ -21,13 +21,13 @@
|
||||
#include <xrpld/app/misc/ValidatorSite.h>
|
||||
#include <xrpld/app/misc/make_NetworkOPs.h>
|
||||
#include <xrpld/app/misc/setup_HashRouter.h>
|
||||
#include <xrpld/app/paths/PathRequests.h>
|
||||
#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
|
||||
#include <xrpld/core/ConfigSections.h>
|
||||
#include <xrpld/core/NetworkIDServiceImpl.h>
|
||||
#include <xrpld/overlay/Cluster.h>
|
||||
#include <xrpld/overlay/PeerSet.h>
|
||||
#include <xrpld/overlay/make_Overlay.h>
|
||||
#include <xrpld/rpc/detail/PathRequestManager.h>
|
||||
#include <xrpld/shamap/NodeFamily.h>
|
||||
|
||||
#include <xrpl/basics/ByteUtilities.h>
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <xrpl/crypto/csprng.h>
|
||||
#include <xrpl/json/json_reader.h>
|
||||
#include <xrpl/ledger/AmendmentTable.h>
|
||||
#include <xrpl/ledger/PendingSaves.h>
|
||||
#include <xrpl/nodestore/DummyScheduler.h>
|
||||
#include <xrpl/protocol/ApiVersion.h>
|
||||
#include <xrpl/protocol/BuildInfo.h>
|
||||
@@ -171,7 +170,7 @@ public:
|
||||
std::unique_ptr<NodeStore::Database> m_nodeStore;
|
||||
NodeFamily nodeFamily_;
|
||||
std::unique_ptr<OrderBookDB> m_orderBookDB;
|
||||
std::unique_ptr<PathRequestManager> m_pathRequestManager;
|
||||
std::unique_ptr<PathRequests> m_pathRequests;
|
||||
std::unique_ptr<LedgerMaster> m_ledgerMaster;
|
||||
std::unique_ptr<LedgerCleaner> ledgerCleaner_;
|
||||
std::unique_ptr<InboundLedgers> m_inboundLedgers;
|
||||
@@ -331,8 +330,8 @@ public:
|
||||
|
||||
, m_orderBookDB(make_OrderBookDB(*this, {config_->PATH_SEARCH_MAX, config_->standalone()}))
|
||||
|
||||
, m_pathRequestManager(
|
||||
std::make_unique<PathRequestManager>(
|
||||
, m_pathRequests(
|
||||
std::make_unique<PathRequests>(
|
||||
*this,
|
||||
logs_->journal("PathRequest"),
|
||||
m_collectorManager->collector()))
|
||||
@@ -661,10 +660,10 @@ public:
|
||||
return *m_orderBookDB;
|
||||
}
|
||||
|
||||
PathRequestManager&
|
||||
getPathRequestManager() override
|
||||
PathRequests&
|
||||
getPathRequests() override
|
||||
{
|
||||
return *m_pathRequestManager;
|
||||
return *m_pathRequests;
|
||||
}
|
||||
|
||||
CachedSLEs&
|
||||
@@ -1640,12 +1639,8 @@ ApplicationImp::startGenesisLedger()
|
||||
? m_amendmentTable->getDesired()
|
||||
: std::vector<uint256>{};
|
||||
|
||||
std::shared_ptr<Ledger> const genesis = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
Rules{config_->features},
|
||||
config_->FEES.toFees(),
|
||||
initialAmendments,
|
||||
nodeFamily_);
|
||||
std::shared_ptr<Ledger> const genesis =
|
||||
std::make_shared<Ledger>(create_genesis, *config_, initialAmendments, nodeFamily_);
|
||||
m_ledgerMaster->storeLedger(genesis);
|
||||
|
||||
auto const next = std::make_shared<Ledger>(*genesis, timeKeeper().closeTime());
|
||||
@@ -1666,8 +1661,7 @@ ApplicationImp::getLastFullLedger()
|
||||
|
||||
try
|
||||
{
|
||||
auto const [ledger, seq, hash] =
|
||||
getLatestLedger(Rules{config_->features}, config_->FEES.toFees(), *this);
|
||||
auto const [ledger, seq, hash] = getLatestLedger(*this);
|
||||
|
||||
if (!ledger)
|
||||
return ledger;
|
||||
@@ -1778,8 +1772,7 @@ ApplicationImp::loadLedgerFromFile(std::string const& name)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto loadLedger = std::make_shared<Ledger>(
|
||||
seq, closeTime, Rules{config_->features}, config_->FEES.toFees(), nodeFamily_);
|
||||
auto loadLedger = std::make_shared<Ledger>(seq, closeTime, *config_, nodeFamily_);
|
||||
loadLedger->setTotalDrops(totalDrops);
|
||||
|
||||
for (Json::UInt index = 0; index < ledger.get().size(); ++index)
|
||||
@@ -1859,8 +1852,7 @@ ApplicationImp::loadOldLedger(
|
||||
|
||||
if (hash.parseHex(ledgerID))
|
||||
{
|
||||
loadLedger =
|
||||
loadByHash(hash, Rules{config_->features}, config_->FEES.toFees(), *this);
|
||||
loadLedger = loadByHash(hash, *this);
|
||||
|
||||
if (!loadLedger)
|
||||
{
|
||||
@@ -1887,10 +1879,7 @@ ApplicationImp::loadOldLedger(
|
||||
std::uint32_t index = 0;
|
||||
|
||||
if (beast::lexicalCastChecked(index, ledgerID))
|
||||
{
|
||||
loadLedger =
|
||||
loadByIndex(index, Rules{config_->features}, config_->FEES.toFees(), *this);
|
||||
}
|
||||
loadLedger = loadByIndex(index, *this);
|
||||
}
|
||||
|
||||
if (!loadLedger)
|
||||
@@ -1905,11 +1894,7 @@ ApplicationImp::loadOldLedger(
|
||||
|
||||
JLOG(m_journal.info()) << "Loading parent ledger";
|
||||
|
||||
loadLedger = loadByHash(
|
||||
replayLedger->header().parentHash,
|
||||
Rules{config_->features},
|
||||
config_->FEES.toFees(),
|
||||
*this);
|
||||
loadLedger = loadByHash(replayLedger->header().parentHash, *this);
|
||||
if (!loadLedger)
|
||||
{
|
||||
JLOG(m_journal.info()) << "Loading parent ledger from node store";
|
||||
@@ -1978,13 +1963,10 @@ ApplicationImp::loadOldLedger(
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
if (!loadLedger->isSensible())
|
||||
if (!loadLedger->assertSensible(journal("Ledger")))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
Json::Value j = getJson({*loadLedger, {}});
|
||||
j[jss::accountTreeHash] = to_string(loadLedger->header().accountHash);
|
||||
j[jss::transTreeHash] = to_string(loadLedger->header().txHash);
|
||||
JLOG(m_journal.fatal()) << "Ledger is not sensible: " << j;
|
||||
JLOG(m_journal.fatal()) << "Ledger is not sensible.";
|
||||
UNREACHABLE(
|
||||
"xrpl::ApplicationImp::loadOldLedger : ledger is not "
|
||||
"sensible");
|
||||
|
||||
@@ -66,7 +66,7 @@ class NetworkOPs;
|
||||
class OpenLedger;
|
||||
class OrderBookDB;
|
||||
class Overlay;
|
||||
class PathRequestManager;
|
||||
class PathRequests;
|
||||
class PendingSaves;
|
||||
class PublicKey;
|
||||
class ServerHandler;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <xrpl/ledger/CanonicalTXSet.h>
|
||||
#include <xrpld/app/misc/CanonicalTXSet.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user