From 4670c703ebaf396b7c1c611041e130bf6df70790 Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Wed, 29 Jul 2026 19:45:13 +0100 Subject: [PATCH 01/10] feat: Package validator-keys inside rippled --- .github/scripts/strategy-matrix/generate.py | 13 +++++- .github/scripts/strategy-matrix/linux.json | 6 ++- .../workflows/reusable-build-test-config.yml | 22 +++++++++ .github/workflows/reusable-package.yml | 20 ++++++--- CMakeLists.txt | 4 +- cmake/XrplPackaging.cmake | 16 ++++++- package/README.md | 45 ++++++++++++------- package/build_pkg.sh | 21 +++++++-- package/debian/control | 3 ++ package/debian/rules | 1 + package/rpm/xrpld.spec | 4 ++ 11 files changed, 122 insertions(+), 33 deletions(-) diff --git a/.github/scripts/strategy-matrix/generate.py b/.github/scripts/strategy-matrix/generate.py index c783f32fb78..08aa70149eb 100755 --- a/.github/scripts/strategy-matrix/generate.py +++ b/.github/scripts/strategy-matrix/generate.py @@ -136,7 +136,9 @@ class MatrixEntry: class PackagingEntry: """One entry in the generated packaging strategy matrix.""" - artifact_name: str + config_name: str # build config whose binaries are packaged + artifact_name: str # artifact holding the xrpld binary + validator_keys_artifact_name: str # artifact holding the validator-keys binary image: str distro: str # e.g. "debian" or "rhel"; drives package-format-specific steps @@ -210,14 +212,21 @@ def expand_linux_packaging(linux: LinuxFile) -> list[PackagingEntry]: the nix-based build images, because deb/rpm tooling (debhelper, rpm-build) is taken from the distro's archive rather than from nixpkgs. Each config entry carries its own 'image'. + + The binaries that go into a package (xrpld and validator-keys) are uploaded + as separate artifacts by the build job, both named after the build config, + so the packaging entry carries that config name as well. """ entries = [] for distro, configs in linux.package_configs.items(): for cfg in configs: for compiler, build_type in itertools.product(cfg.compiler, cfg.build_type): + config_name = f"{distro}-{compiler}-{build_type.lower()}-amd64" entries.append( PackagingEntry( - artifact_name=f"xrpld-{distro}-{compiler}-{build_type.lower()}-amd64", + config_name=config_name, + artifact_name=f"xrpld-{config_name}", + validator_keys_artifact_name=f"validator-keys-{config_name}", image=cfg.image, distro=distro, ) diff --git a/.github/scripts/strategy-matrix/linux.json b/.github/scripts/strategy-matrix/linux.json index 03ac1c6334c..62aead518ad 100644 --- a/.github/scripts/strategy-matrix/linux.json +++ b/.github/scripts/strategy-matrix/linux.json @@ -68,7 +68,8 @@ "compiler": ["gcc"], "build_type": ["Release"], "arch": ["amd64"], - "minimal": false + "minimal": false, + "extra_cmake_args": "-Dvalidator_keys=ON" } ], @@ -77,7 +78,8 @@ "compiler": ["gcc"], "build_type": ["Release"], "arch": ["amd64"], - "minimal": false + "minimal": false, + "extra_cmake_args": "-Dvalidator_keys=ON" } ] }, diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index b2327f67eaa..ce006b29a6d 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -247,6 +247,28 @@ jobs: retention-days: 3 if-no-files-found: error + # Only the configurations built with -Dvalidator_keys=ON produce this + # binary (see linux.json), so probe for it rather than keying the upload + # off a list of configuration names. + - name: Check for the validator-keys binary (Linux) + id: validator_keys + if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }} + run: | + if [ -x "${BUILD_DIR}/validator-keys" ]; then + echo "present=true" >>"${GITHUB_OUTPUT}" + else + echo "present=false" >>"${GITHUB_OUTPUT}" + fi + + - name: Upload the validator-keys binary (Linux) + if: ${{ steps.validator_keys.outputs.present == 'true' }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: validator-keys-${{ inputs.config_name }} + path: ${{ env.BUILD_DIR }}/validator-keys + retention-days: 3 + if-no-files-found: error + - name: Upload the test binary (Linux) if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/.github/workflows/reusable-package.yml b/.github/workflows/reusable-package.yml index 6feecbfb759..956f90966ba 100644 --- a/.github/workflows/reusable-package.yml +++ b/.github/workflows/reusable-package.yml @@ -1,7 +1,7 @@ -# Build Linux packages (DEB and RPM) from pre-built binary artifacts. -# Discovers which configurations to package from linux.json (configs in -# "package_configs") and fans out one job per distro. Only linux/amd64 is -# supported; the runner is hardcoded in the job below. +# Build Linux packages (DEB and RPM) from pre-built binary artifacts (xrpld and +# validator-keys). Discovers which configurations to package from linux.json +# (configs in "package_configs") and fans out one job per distro. Only +# linux/amd64 is supported; the runner is hardcoded in the job below. name: Package on: @@ -56,14 +56,20 @@ jobs: - name: Checkout repository uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - name: Download pre-built binary + - name: Download pre-built xrpld binary uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ matrix.artifact_name }} path: ${{ env.BUILD_DIR }} - - name: Make binary executable - run: chmod +x "${BUILD_DIR}/xrpld" + - name: Download pre-built validator-keys binary + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ${{ matrix.validator_keys_artifact_name }} + path: ${{ env.BUILD_DIR }} + + - name: Make binaries executable + run: chmod +x "${BUILD_DIR}/xrpld" "${BUILD_DIR}/validator-keys" - name: Build package env: diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e8befcc8f7..2c04aafb3de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,9 +137,11 @@ endif() include(XrplCore) include(XrplProtocolAutogen) +include(XrplValidatorKeys) include(XrplInstall) +# Must come after XrplValidatorKeys: the 'package' target depends on the +# validator-keys target existing. include(XrplPackaging) -include(XrplValidatorKeys) if(tests) include(CTest) diff --git a/cmake/XrplPackaging.cmake b/cmake/XrplPackaging.cmake index 8e3861925db..e58df6f4094 100644 --- a/cmake/XrplPackaging.cmake +++ b/cmake/XrplPackaging.cmake @@ -25,6 +25,20 @@ if(NOT (RPMBUILD_EXECUTABLE OR DPKG_BUILDPACKAGE_EXECUTABLE)) return() endif() +# The packages ship both binaries, so both targets must exist. +if(NOT TARGET xrpld) + message(STATUS "xrpld=ON is required; 'package' target not available") + return() +endif() + +if(NOT TARGET validator-keys) + message( + STATUS + "validator_keys=ON is required; 'package' target not available" + ) + return() +endif() + set(package_env SRC_DIR=${CMAKE_SOURCE_DIR} BUILD_DIR=${CMAKE_BINARY_DIR} @@ -37,7 +51,7 @@ add_custom_target( ${CMAKE_COMMAND} -E env ${package_env} ${CMAKE_SOURCE_DIR}/package/build_pkg.sh WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - DEPENDS xrpld + DEPENDS xrpld validator-keys COMMENT "Building Linux package (deb/rpm inferred from host tooling)" VERBATIM ) diff --git a/package/README.md b/package/README.md index 4b78106c4cb..ca2870cac42 100644 --- a/package/README.md +++ b/package/README.md @@ -1,6 +1,8 @@ # Linux Packaging -This directory contains all files needed to build RPM and Debian packages for `xrpld`. +This directory contains all files needed to build RPM and Debian packages for +`xrpld`. The packages also ship the `validator-keys` tool, so packaging requires +a build configured with `-Dvalidator_keys=ON`. ## Directory layout @@ -46,17 +48,24 @@ To print the full packaging matrix (artifact names and images) for the current Caller workflows (`on-pr.yml`, `on-tag.yml`, `on-trigger.yml`) call `reusable-package.yml`. That workflow generates its own packaging matrix from `package_configs` in `linux.json` (via `generate.py --packaging`) and fans out -one job per distro. Each job downloads the pre-built `xrpld` binary artifact and -runs in that distro's container, so the package format follows from the -container's package manager. The packaging script derives the package version -from the downloaded binary's `xrpld --version` output; no CMake configure or -build step is needed inside the packaging job. +one job per distro. Each job downloads the pre-built `xrpld` and `validator-keys` +binary artifacts and runs in that distro's container, so the package format +follows from the container's package manager. The packaging script derives the +package version from the downloaded binary's `xrpld --version` output; no CMake +configure or build step is needed inside the packaging job. + +The binaries come from the `debian` and `rhel` build configurations in +`linux.json`'s `configs` section, which pass `-Dvalidator_keys=ON` so that the +build job produces `validator-keys` next to `xrpld` and uploads it as the +`validator-keys-` artifact. The packaging entry for a distro names +both artifacts (`artifact_name` and `validator_keys_artifact_name`), so a +packaged configuration must keep `-Dvalidator_keys=ON`. ### Locally (mirrors CI) -With an `xrpld` binary already built at `build/xrpld`, run the packaging step -inside the same container CI uses. The image tag is derived from `linux.json` -so you don't need to hardcode a SHA. +With `xrpld` and `validator-keys` binaries already built at `build/xrpld` and +`build/validator-keys`, run the packaging step inside the same container CI uses. +The image tag is derived from `linux.json` so you don't need to hardcode a SHA. ```bash # From the repo root. Each distro's container image is the `image` field of its @@ -87,6 +96,7 @@ needed, but the host toolchain replaces the pinned CI image: ```bash cmake \ -Dxrpld=ON \ + -Dvalidator_keys=ON \ -Dpkg_release=1 \ -Dtests=OFF \ .. @@ -95,9 +105,11 @@ cmake --build . --target package # deb on Debian/Ubuntu, rpm on RHEL ``` The `cmake/XrplPackaging.cmake` module defines the `package` target only if at -least one of `rpmbuild` / `dpkg-buildpackage` is present; `build_pkg.sh` then -infers the package format from the host's package manager. The packaging script -installs to FHS-standard paths (`/usr/bin`, `/etc/xrpld`, etc.) regardless of +least one of `rpmbuild` / `dpkg-buildpackage` is present and both the `xrpld` and +`validator-keys` targets exist (`-Dxrpld=ON -Dvalidator_keys=ON`); the target +builds both binaries before packaging. `build_pkg.sh` then infers the package +format from the host's package manager. The packaging script installs to +FHS-standard paths (`/usr/bin`, `/etc/xrpld`, etc.) regardless of `CMAKE_INSTALL_PREFIX`. The package version is not a CMake input on this path: `build_pkg.sh` derives it @@ -156,13 +168,14 @@ CMake/CI integration. The CI workflow and the CMake `package` target both invoke and lets the script use defaults for the rest. 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, and invokes the platform build tool. +`stage_common()` to copy the `xrpld` and `validator-keys` binaries, config files, +and shared support files into the staging area, and invokes the platform build +tool. Both binaries must be present in `BUILD_DIR`; a missing one fails early. ### RPM 1. Creates the standard `rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}` tree inside the build directory. -2. Copies `xrpld.spec` and all shared source files (binary, configs, service files) into `SOURCES/`. +2. Copies `xrpld.spec` and all shared source files (binaries, configs, service files) into `SOURCES/`. 3. Runs `rpmbuild -bb`, passing the normalized package metadata version as the `pkg_version` RPM macro and `PKG_RELEASE` as the `pkg_release` RPM macro. The spec uses manual `install` commands to place files, disables `dwz`, and @@ -182,7 +195,7 @@ service restart. ### DEB 1. Creates a staging source tree at `debbuild/source/` inside the build directory. -2. Stages the binary, configs, `README.md`, and `LICENSE.md`. +2. Stages the binaries, configs, `README.md`, and `LICENSE.md`. 3. Copies `package/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` using `${pkg_version}-${PKG_RELEASE}`, diff --git a/package/build_pkg.sh b/package/build_pkg.sh index 3684fc096af..611ab0f9592 100755 --- a/package/build_pkg.sh +++ b/package/build_pkg.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -# Build an RPM or Debian package from a pre-built xrpld binary. +# Build an RPM or Debian package from the pre-built xrpld and validator-keys +# binaries. # # Flags override env vars; env vars override defaults. @@ -11,7 +12,9 @@ Usage: build_pkg.sh [options] Options (each can also be set via the env var shown): --src-dir DIR repo root [SRC_DIR; default: ${PWD}] - --build-dir DIR directory holding xrpld [BUILD_DIR; default: ${PWD}/build] + --build-dir DIR directory holding the + xrpld and validator-keys + binaries [BUILD_DIR; default: ${PWD}/build] --pkg-release N package release iteration [PKG_RELEASE; default: 1] --source-date-epoch SECS reproducibility timestamp [SOURCE_DATE_EPOCH; latest git ctime; fallback: current time] -h, --help show this help and exit @@ -69,7 +72,7 @@ SRC_DIR="$(cd "${SRC_DIR:-${PWD}}" && pwd)" BUILD_DIR="${BUILD_DIR:-${PWD}/build}" if [[ ! -d "${BUILD_DIR}" ]]; then echo "build_pkg.sh: build directory not found: ${BUILD_DIR}" >&2 - echo "Build xrpld before packaging, or set BUILD_DIR to the directory containing xrpld." >&2 + echo "Build xrpld before packaging, or set BUILD_DIR to the directory containing the binaries." >&2 exit 1 fi BUILD_DIR="$(cd "${BUILD_DIR}" && pwd)" @@ -81,6 +84,15 @@ if [[ ! -x "${xrpld_binary}" ]]; then exit 1 fi +# The packages ship validator-keys alongside xrpld, so it is required here too. +validator_keys_binary="${BUILD_DIR}/validator-keys" +if [[ ! -x "${validator_keys_binary}" ]]; then + echo "build_pkg.sh: expected executable validator-keys binary at ${validator_keys_binary}." >&2 + echo "Configure with -Dvalidator_keys=ON and build the validator-keys target before packaging," >&2 + echo "or set BUILD_DIR to the directory containing validator-keys." >&2 + exit 1 +fi + xrpld_version="$("${xrpld_binary}" --version | awk 'NR == 1 { print $3 }')" if [[ -z "${xrpld_version}" ]]; then @@ -150,7 +162,8 @@ stage_common() { local dest="$1" mkdir -p "${dest}" - cp "${BUILD_DIR}/xrpld" "${dest}/xrpld" + cp "${xrpld_binary}" "${dest}/xrpld" + cp "${validator_keys_binary}" "${dest}/validator-keys" cp "${SRC_DIR}/cfg/xrpld-example.cfg" "${dest}/xrpld.cfg" cp "${SRC_DIR}/cfg/validators-example.txt" "${dest}/validators.txt" cp "${SRC_DIR}/LICENSE.md" "${dest}/LICENSE.md" diff --git a/package/debian/control b/package/debian/control index 45d2acbbea5..5e506e7f56d 100644 --- a/package/debian/control +++ b/package/debian/control @@ -21,3 +21,6 @@ Description: XRP Ledger daemon Reference implementation of the XRP Ledger protocol. Participates in the peer-to-peer network, processes transactions, and maintains a local ledger copy. + . + This package also includes the validator-keys tool for validator key + management. diff --git a/package/debian/rules b/package/debian/rules index 16574bca3fd..8f880b81927 100644 --- a/package/debian/rules +++ b/package/debian/rules @@ -18,6 +18,7 @@ override_dh_installsysusers: override_dh_install: install -D -m 0755 xrpld debian/xrpld/usr/bin/xrpld + install -D -m 0755 validator-keys debian/xrpld/usr/bin/validator-keys install -D -m 0644 xrpld.cfg debian/xrpld/etc/xrpld/xrpld.cfg install -D -m 0644 validators.txt debian/xrpld/etc/xrpld/validators.txt diff --git a/package/rpm/xrpld.spec b/package/rpm/xrpld.spec index 61c2d61ec60..6d02fa6a8f1 100644 --- a/package/rpm/xrpld.spec +++ b/package/rpm/xrpld.spec @@ -32,6 +32,8 @@ BuildRequires: systemd-rpm-macros 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. +This package also includes the validator-keys tool for validator key +management. %prep : @@ -41,6 +43,7 @@ transactions, and maintains the ledger database. %install install -Dm0755 %{_sourcedir}/xrpld %{buildroot}%{_bindir}/%{name} +install -Dm0755 %{_sourcedir}/validator-keys %{buildroot}%{_bindir}/validator-keys install -Dm0644 %{_sourcedir}/xrpld.cfg %{buildroot}%{_sysconfdir}/%{name}/xrpld.cfg install -Dm0644 %{_sourcedir}/validators.txt %{buildroot}%{_sysconfdir}/%{name}/validators.txt @@ -85,6 +88,7 @@ systemd-tmpfiles --create %{_tmpfilesdir}/xrpld.conf || : %dir %{_sysconfdir}/%{name} %{_bindir}/%{name} +%{_bindir}/validator-keys %config(noreplace) %{_sysconfdir}/%{name}/xrpld.cfg %config(noreplace) %{_sysconfdir}/%{name}/validators.txt From 49eba618bb824eb518f20167c57509223108ff0f Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Wed, 29 Jul 2026 19:48:50 +0100 Subject: [PATCH 02/10] Do not exclude validator-keys from `all` target --- cmake/XrplValidatorKeys.cmake | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cmake/XrplValidatorKeys.cmake b/cmake/XrplValidatorKeys.cmake index 0e511b6a88b..9123fdf07a7 100644 --- a/cmake/XrplValidatorKeys.cmake +++ b/cmake/XrplValidatorKeys.cmake @@ -18,9 +18,16 @@ if(validator_keys) GIT_TAG "${current_branch}" ) FetchContent_MakeAvailable(validator_keys) + # The tool's own CMakeLists excludes the target from 'all' when it is built + # as a subproject. Undo that: the packages ship validator-keys, so a build + # configured with validator_keys=ON must produce it as part of the default + # target, next to xrpld. set_target_properties( validator-keys - PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + EXCLUDE_FROM_ALL OFF + EXCLUDE_FROM_DEFAULT_BUILD OFF ) install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() From bee8df9290799747a9548f6c015ca007495c2b30 Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Wed, 29 Jul 2026 20:09:55 +0100 Subject: [PATCH 03/10] Fix some stuff --- .gersemi/definitions.cmake | 3 +++ .github/scripts/strategy-matrix/generate.py | 4 +--- .../workflows/reusable-build-test-config.yml | 9 ++++++-- cmake/PatchNixBinary.cmake | 23 +++++++++++++++++++ cmake/XrplValidatorKeys.cmake | 18 +++++++++------ package/README.md | 9 +++++++- package/build_pkg.sh | 9 ++++++++ 7 files changed, 62 insertions(+), 13 deletions(-) diff --git a/.gersemi/definitions.cmake b/.gersemi/definitions.cmake index aa63076c8b9..d2a35c76b01 100644 --- a/.gersemi/definitions.cmake +++ b/.gersemi/definitions.cmake @@ -105,3 +105,6 @@ endfunction() function(patch_nix_binary target) endfunction() + +function(patch_nix_binary_in_other_dir target) +endfunction() diff --git a/.github/scripts/strategy-matrix/generate.py b/.github/scripts/strategy-matrix/generate.py index 08aa70149eb..339b39283c6 100755 --- a/.github/scripts/strategy-matrix/generate.py +++ b/.github/scripts/strategy-matrix/generate.py @@ -136,7 +136,6 @@ class MatrixEntry: class PackagingEntry: """One entry in the generated packaging strategy matrix.""" - config_name: str # build config whose binaries are packaged artifact_name: str # artifact holding the xrpld binary validator_keys_artifact_name: str # artifact holding the validator-keys binary image: str @@ -215,7 +214,7 @@ def expand_linux_packaging(linux: LinuxFile) -> list[PackagingEntry]: The binaries that go into a package (xrpld and validator-keys) are uploaded as separate artifacts by the build job, both named after the build config, - so the packaging entry carries that config name as well. + so each entry names both artifacts. """ entries = [] for distro, configs in linux.package_configs.items(): @@ -224,7 +223,6 @@ def expand_linux_packaging(linux: LinuxFile) -> list[PackagingEntry]: config_name = f"{distro}-{compiler}-{build_type.lower()}-amd64" entries.append( PackagingEntry( - config_name=config_name, artifact_name=f"xrpld-{config_name}", validator_keys_artifact_name=f"validator-keys-{config_name}", image=cfg.image, diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index ce006b29a6d..32f0f23e1e5 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -252,7 +252,7 @@ jobs: # off a list of configuration names. - name: Check for the validator-keys binary (Linux) id: validator_keys - if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }} + if: ${{ runner.os == 'Linux' }} run: | if [ -x "${BUILD_DIR}/validator-keys" ]; then echo "present=true" >>"${GITHUB_OUTPUT}" @@ -260,8 +260,13 @@ jobs: echo "present=false" >>"${GITHUB_OUTPUT}" fi - - name: Upload the validator-keys binary (Linux) + - name: Run the validator-keys tests (Linux) if: ${{ steps.validator_keys.outputs.present == 'true' }} + working-directory: ${{ env.BUILD_DIR }} + run: ./validator-keys --unittest + + - name: Upload the validator-keys binary (Linux) + if: ${{ github.event.repository.visibility == 'public' && steps.validator_keys.outputs.present == 'true' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: validator-keys-${{ inputs.config_name }} diff --git a/cmake/PatchNixBinary.cmake b/cmake/PatchNixBinary.cmake index 79ca0b150cd..6822c88f5cb 100644 --- a/cmake/PatchNixBinary.cmake +++ b/cmake/PatchNixBinary.cmake @@ -51,3 +51,26 @@ function(patch_nix_binary target) VERBATIM ) endfunction() + +#[===================================================================[ + Same as patch_nix_binary, for a target created in another directory, + such as a FetchContent subproject. add_custom_command(TARGET) only + works in the directory that defined the target, so drive patchelf from + a custom target that runs once the binary has been linked. patchelf is + idempotent, so re-running it on an up-to-date binary is harmless. +#]===================================================================] +function(patch_nix_binary_in_other_dir target) + if(NOT PATCH_NIX_BINARIES) + return() + endif() + add_custom_target( + ${target}-patch-nix + ALL + COMMAND + "${PATCHELF_COMMAND}" --set-interpreter "${DEFAULT_LOADER_PATH}" + --remove-rpath "$" + COMMENT "Patching ${target}: set default loader, remove rpath" + VERBATIM + ) + add_dependencies(${target}-patch-nix ${target}) +endfunction() diff --git a/cmake/XrplValidatorKeys.cmake b/cmake/XrplValidatorKeys.cmake index 9123fdf07a7..533cd369fbb 100644 --- a/cmake/XrplValidatorKeys.cmake +++ b/cmake/XrplValidatorKeys.cmake @@ -5,17 +5,16 @@ option( ) if(validator_keys) - git_branch(current_branch) - # default to tracking VK master branch unless we are on release - if(NOT (current_branch STREQUAL "release")) - set(current_branch "master") - endif() - message(STATUS "Tracking ValidatorKeys branch: ${current_branch}") + # Pinned to an exact commit, not a branch: the tool ships inside our + # packages, so the same xrpld version must always package the same + # validator-keys. Bump this deliberately. + set(validator_keys_commit "4c0fb75eec9601c711645998c904507e87e910ae") + message(STATUS "Using ValidatorKeys commit: ${validator_keys_commit}") FetchContent_Declare( validator_keys GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git - GIT_TAG "${current_branch}" + GIT_TAG "${validator_keys_commit}" ) FetchContent_MakeAvailable(validator_keys) # The tool's own CMakeLists excludes the target from 'all' when it is built @@ -29,5 +28,10 @@ if(validator_keys) EXCLUDE_FROM_ALL OFF EXCLUDE_FROM_DEFAULT_BUILD OFF ) + # Like xrpld, this binary leaves the Nix-based build image (we ship it in + # the deb/rpm), so it needs the system ELF loader instead of the one in the + # Nix store. Without this it cannot run on the target distro at all. The + # target belongs to the FetchContent subproject, hence the other_dir form. + patch_nix_binary_in_other_dir(validator-keys) install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() diff --git a/package/README.md b/package/README.md index ca2870cac42..79898e07832 100644 --- a/package/README.md +++ b/package/README.md @@ -61,6 +61,10 @@ build job produces `validator-keys` next to `xrpld` and uploads it as the both artifacts (`artifact_name` and `validator_keys_artifact_name`), so a packaged configuration must keep `-Dvalidator_keys=ON`. +`validator-keys` is fetched from an exact commit pinned in +[`cmake/XrplValidatorKeys.cmake`](../cmake/XrplValidatorKeys.cmake), so a given +`xrpld` version always packages the same tool; bump that commit deliberately. + ### Locally (mirrors CI) With `xrpld` and `validator-keys` binaries already built at `build/xrpld` and @@ -170,7 +174,10 @@ and lets the script use defaults for the rest. It resolves `SRC_DIR` and `BUILD_DIR` to absolute paths, then calls `stage_common()` to copy the `xrpld` and `validator-keys` binaries, config files, and shared support files into the staging area, and invokes the platform build -tool. Both binaries must be present in `BUILD_DIR`; a missing one fails early. +tool. Both binaries must be present in `BUILD_DIR` and must run in the packaging +environment; a missing or non-runnable one fails early. That runtime check is +what catches a binary still linked against the Nix store's ELF loader (see +`patch_nix_binary` in `cmake/PatchNixBinary.cmake`). ### RPM diff --git a/package/build_pkg.sh b/package/build_pkg.sh index 611ab0f9592..4c91bb47fe5 100755 --- a/package/build_pkg.sh +++ b/package/build_pkg.sh @@ -93,6 +93,15 @@ if [[ ! -x "${validator_keys_binary}" ]]; then exit 1 fi +# The binary must also *run* here. Packaging happens in a vanilla distro +# container, so this is what catches a binary still pointing at the Nix store's +# ELF loader (see patch_nix_binary in cmake/PatchNixBinary.cmake); xrpld is +# covered implicitly by the version query below. +if ! "${validator_keys_binary}" --version >/dev/null; then + echo "build_pkg.sh: ${validator_keys_binary} exists but does not run here." >&2 + exit 1 +fi + xrpld_version="$("${xrpld_binary}" --version | awk 'NR == 1 { print $3 }')" if [[ -z "${xrpld_version}" ]]; then From e46806e1071e659be4b757ec1bb0fd0e6860b2b9 Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Wed, 29 Jul 2026 20:21:17 +0100 Subject: [PATCH 04/10] One patch_nix_binary --- .gersemi/definitions.cmake | 3 -- cmake/PatchNixBinary.cmake | 66 ++++++++++++++++++----------------- cmake/XrplValidatorKeys.cmake | 5 ++- 3 files changed, 36 insertions(+), 38 deletions(-) diff --git a/.gersemi/definitions.cmake b/.gersemi/definitions.cmake index d2a35c76b01..aa63076c8b9 100644 --- a/.gersemi/definitions.cmake +++ b/.gersemi/definitions.cmake @@ -105,6 +105,3 @@ endfunction() function(patch_nix_binary target) endfunction() - -function(patch_nix_binary_in_other_dir target) -endfunction() diff --git a/cmake/PatchNixBinary.cmake b/cmake/PatchNixBinary.cmake index 6822c88f5cb..18d992305fa 100644 --- a/cmake/PatchNixBinary.cmake +++ b/cmake/PatchNixBinary.cmake @@ -3,9 +3,9 @@ The Nix-based CI image links binaries against an ELF interpreter (loader) that lives in the Nix store, so the resulting binaries don't run elsewhere - (including once installed from the .deb package). `patch_nix_binary` adds a - POST_BUILD step that resets the interpreter to the system default loader and - drops the rpath. + (including once installed from the .deb package). `patch_nix_binary` resets + the interpreter to the system default loader and drops the rpath, once the + binary has been linked. This is only active inside the Nix-based image, detected by the presence of /tmp/loader-path.sh (shipped by that image, resolves the default loader). It @@ -41,36 +41,38 @@ function(patch_nix_binary target) if(NOT PATCH_NIX_BINARIES) return() endif() - add_custom_command( - TARGET ${target} - POST_BUILD - COMMAND - "${PATCHELF_COMMAND}" --set-interpreter "${DEFAULT_LOADER_PATH}" - --remove-rpath "$" - COMMENT "Patching ${target}: set default loader, remove rpath" - VERBATIM + + set(patch_command + "${PATCHELF_COMMAND}" + --set-interpreter + "${DEFAULT_LOADER_PATH}" + --remove-rpath + "$" ) -endfunction() + set(comment "Patching ${target}: set default loader, remove rpath") -#[===================================================================[ - Same as patch_nix_binary, for a target created in another directory, - such as a FetchContent subproject. add_custom_command(TARGET) only - works in the directory that defined the target, so drive patchelf from - a custom target that runs once the binary has been linked. patchelf is - idempotent, so re-running it on an up-to-date binary is harmless. -#]===================================================================] -function(patch_nix_binary_in_other_dir target) - if(NOT PATCH_NIX_BINARIES) - return() + # POST_BUILD is the cheap way to do this: it runs only when the binary is + # relinked. It is also only available in the directory that defined the + # target, so for a target from elsewhere (e.g. a FetchContent subproject) + # fall back to a custom target that runs after the binary is linked. That + # one runs on every build, which is harmless because patchelf is idempotent. + get_target_property(target_source_dir ${target} SOURCE_DIR) + if("${target_source_dir}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND ${patch_command} + COMMENT "${comment}" + VERBATIM + ) + else() + add_custom_target( + ${target}-patch-nix + ALL + COMMAND ${patch_command} + COMMENT "${comment}" + VERBATIM + ) + add_dependencies(${target}-patch-nix ${target}) endif() - add_custom_target( - ${target}-patch-nix - ALL - COMMAND - "${PATCHELF_COMMAND}" --set-interpreter "${DEFAULT_LOADER_PATH}" - --remove-rpath "$" - COMMENT "Patching ${target}: set default loader, remove rpath" - VERBATIM - ) - add_dependencies(${target}-patch-nix ${target}) endfunction() diff --git a/cmake/XrplValidatorKeys.cmake b/cmake/XrplValidatorKeys.cmake index 533cd369fbb..a5564212186 100644 --- a/cmake/XrplValidatorKeys.cmake +++ b/cmake/XrplValidatorKeys.cmake @@ -30,8 +30,7 @@ if(validator_keys) ) # Like xrpld, this binary leaves the Nix-based build image (we ship it in # the deb/rpm), so it needs the system ELF loader instead of the one in the - # Nix store. Without this it cannot run on the target distro at all. The - # target belongs to the FetchContent subproject, hence the other_dir form. - patch_nix_binary_in_other_dir(validator-keys) + # Nix store. Without this it cannot run on the target distro at all. + patch_nix_binary(validator-keys) install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() From 78e30528848fc16af447ff4a3f66cd3c0ba7d730 Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Thu, 30 Jul 2026 13:42:37 +0100 Subject: [PATCH 05/10] Rename artifact name & remove useless comment --- .github/scripts/strategy-matrix/generate.py | 11 +++++------ .github/workflows/reusable-build-test-config.yml | 7 +++---- .github/workflows/reusable-package.yml | 6 +++--- cmake/XrplPackaging.cmake | 1 - cmake/XrplValidatorKeys.cmake | 9 +++------ package/README.md | 2 +- package/build_pkg.sh | 1 - 7 files changed, 15 insertions(+), 22 deletions(-) diff --git a/.github/scripts/strategy-matrix/generate.py b/.github/scripts/strategy-matrix/generate.py index 339b39283c6..b0a7b4b321d 100755 --- a/.github/scripts/strategy-matrix/generate.py +++ b/.github/scripts/strategy-matrix/generate.py @@ -136,8 +136,8 @@ class MatrixEntry: class PackagingEntry: """One entry in the generated packaging strategy matrix.""" - artifact_name: str # artifact holding the xrpld binary - validator_keys_artifact_name: str # artifact holding the validator-keys binary + xrpld_artifact_name: str + validator_keys_artifact_name: str image: str distro: str # e.g. "debian" or "rhel"; drives package-format-specific steps @@ -212,9 +212,8 @@ def expand_linux_packaging(linux: LinuxFile) -> list[PackagingEntry]: is taken from the distro's archive rather than from nixpkgs. Each config entry carries its own 'image'. - The binaries that go into a package (xrpld and validator-keys) are uploaded - as separate artifacts by the build job, both named after the build config, - so each entry names both artifacts. + The artifact names must match what the build job uploads: one artifact per + binary, each named after the build config. """ entries = [] for distro, configs in linux.package_configs.items(): @@ -223,7 +222,7 @@ def expand_linux_packaging(linux: LinuxFile) -> list[PackagingEntry]: config_name = f"{distro}-{compiler}-{build_type.lower()}-amd64" entries.append( PackagingEntry( - artifact_name=f"xrpld-{config_name}", + xrpld_artifact_name=f"xrpld-{config_name}", validator_keys_artifact_name=f"validator-keys-{config_name}", image=cfg.image, distro=distro, diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index 32f0f23e1e5..c5c1ef73b72 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -247,9 +247,8 @@ jobs: retention-days: 3 if-no-files-found: error - # Only the configurations built with -Dvalidator_keys=ON produce this - # binary (see linux.json), so probe for it rather than keying the upload - # off a list of configuration names. + # Only configurations built with -Dvalidator_keys=ON produce this binary, + # so probe for it instead of hardcoding which ones do. - name: Check for the validator-keys binary (Linux) id: validator_keys if: ${{ runner.os == 'Linux' }} @@ -393,7 +392,7 @@ jobs: --target coverage - name: Upload coverage report - if: ${{ github.repository == 'XRPLF/rippled' && !inputs.build_only && env.COVERAGE_ENABLED == 'true' }} + if: ${{ github.repository_owner == 'XRPLF' && !inputs.build_only && env.COVERAGE_ENABLED == 'true' }} uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: disable_search: true diff --git a/.github/workflows/reusable-package.yml b/.github/workflows/reusable-package.yml index 956f90966ba..0a0c96e7dd7 100644 --- a/.github/workflows/reusable-package.yml +++ b/.github/workflows/reusable-package.yml @@ -45,7 +45,7 @@ jobs: strategy: fail-fast: false matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} - name: "${{ matrix.artifact_name }}" + name: "${{ matrix.xrpld_artifact_name }}" permissions: contents: read runs-on: ["self-hosted", "Linux", "X64", "heavy"] @@ -59,7 +59,7 @@ jobs: - name: Download pre-built xrpld binary uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: ${{ matrix.artifact_name }} + name: ${{ matrix.xrpld_artifact_name }} path: ${{ env.BUILD_DIR }} - name: Download pre-built validator-keys binary @@ -79,7 +79,7 @@ jobs: - name: Upload package artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: ${{ matrix.artifact_name }}-pkg + name: ${{ matrix.xrpld_artifact_name }}-pkg path: | ${{ env.BUILD_DIR }}/debbuild/*.deb ${{ env.BUILD_DIR }}/debbuild/*.ddeb diff --git a/cmake/XrplPackaging.cmake b/cmake/XrplPackaging.cmake index e58df6f4094..bee7b15791b 100644 --- a/cmake/XrplPackaging.cmake +++ b/cmake/XrplPackaging.cmake @@ -25,7 +25,6 @@ if(NOT (RPMBUILD_EXECUTABLE OR DPKG_BUILDPACKAGE_EXECUTABLE)) return() endif() -# The packages ship both binaries, so both targets must exist. if(NOT TARGET xrpld) message(STATUS "xrpld=ON is required; 'package' target not available") return() diff --git a/cmake/XrplValidatorKeys.cmake b/cmake/XrplValidatorKeys.cmake index a5564212186..044b011369a 100644 --- a/cmake/XrplValidatorKeys.cmake +++ b/cmake/XrplValidatorKeys.cmake @@ -18,9 +18,7 @@ if(validator_keys) ) FetchContent_MakeAvailable(validator_keys) # The tool's own CMakeLists excludes the target from 'all' when it is built - # as a subproject. Undo that: the packages ship validator-keys, so a build - # configured with validator_keys=ON must produce it as part of the default - # target, next to xrpld. + # as a subproject. Undo that, so validator_keys=ON really does build it. set_target_properties( validator-keys PROPERTIES @@ -28,9 +26,8 @@ if(validator_keys) EXCLUDE_FROM_ALL OFF EXCLUDE_FROM_DEFAULT_BUILD OFF ) - # Like xrpld, this binary leaves the Nix-based build image (we ship it in - # the deb/rpm), so it needs the system ELF loader instead of the one in the - # Nix store. Without this it cannot run on the target distro at all. + # We ship this binary, so like xrpld it must not keep the Nix store's ELF + # loader, or it cannot run on the target distro at all. patch_nix_binary(validator-keys) install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() diff --git a/package/README.md b/package/README.md index 79898e07832..e816b66d499 100644 --- a/package/README.md +++ b/package/README.md @@ -58,7 +58,7 @@ The binaries come from the `debian` and `rhel` build configurations in `linux.json`'s `configs` section, which pass `-Dvalidator_keys=ON` so that the build job produces `validator-keys` next to `xrpld` and uploads it as the `validator-keys-` artifact. The packaging entry for a distro names -both artifacts (`artifact_name` and `validator_keys_artifact_name`), so a +both artifacts (`xrpld_artifact_name` and `validator_keys_artifact_name`), so a packaged configuration must keep `-Dvalidator_keys=ON`. `validator-keys` is fetched from an exact commit pinned in diff --git a/package/build_pkg.sh b/package/build_pkg.sh index 4c91bb47fe5..2c2575b540c 100755 --- a/package/build_pkg.sh +++ b/package/build_pkg.sh @@ -84,7 +84,6 @@ if [[ ! -x "${xrpld_binary}" ]]; then exit 1 fi -# The packages ship validator-keys alongside xrpld, so it is required here too. validator_keys_binary="${BUILD_DIR}/validator-keys" if [[ ! -x "${validator_keys_binary}" ]]; then echo "build_pkg.sh: expected executable validator-keys binary at ${validator_keys_binary}." >&2 From 0a0ec6ed259756719fb464a03a0d4da9a3d594ed Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Thu, 30 Jul 2026 13:50:14 +0100 Subject: [PATCH 06/10] Use VALIDATOR_KEYS_ENABLED env var to determine if val-keys is enabled --- .../workflows/reusable-build-test-config.yml | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index c5c1ef73b72..6b2d9648e4a 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -100,9 +100,10 @@ jobs: # header files are copied into separate directories by CMake, which will # otherwise result in cache misses. CCACHE_SLOPPINESS: include_file_ctime,include_file_mtime - # Determine if coverage and voidstar should be enabled. + # Determine if coverage, voidstar and validator-keys should be enabled. COVERAGE_ENABLED: ${{ contains(inputs.cmake_args, '-Dcoverage=ON') }} VOIDSTAR_ENABLED: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }} + VALIDATOR_KEYS_ENABLED: ${{ contains(inputs.cmake_args, '-Dvalidator_keys=ON') }} SANITIZERS_ENABLED: ${{ inputs.sanitizers != '' }} steps: - name: Cleanup workspace (macOS and Windows) @@ -247,25 +248,13 @@ jobs: retention-days: 3 if-no-files-found: error - # Only configurations built with -Dvalidator_keys=ON produce this binary, - # so probe for it instead of hardcoding which ones do. - - name: Check for the validator-keys binary (Linux) - id: validator_keys - if: ${{ runner.os == 'Linux' }} - run: | - if [ -x "${BUILD_DIR}/validator-keys" ]; then - echo "present=true" >>"${GITHUB_OUTPUT}" - else - echo "present=false" >>"${GITHUB_OUTPUT}" - fi - - - name: Run the validator-keys tests (Linux) - if: ${{ steps.validator_keys.outputs.present == 'true' }} + - name: Run the validator-keys tests + if: ${{ env.VALIDATOR_KEYS_ENABLED == 'true' }} working-directory: ${{ env.BUILD_DIR }} run: ./validator-keys --unittest - - name: Upload the validator-keys binary (Linux) - if: ${{ github.event.repository.visibility == 'public' && steps.validator_keys.outputs.present == 'true' }} + - name: Upload the validator-keys binary + if: ${{ github.event.repository.visibility == 'public' && env.VALIDATOR_KEYS_ENABLED == 'true' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: validator-keys-${{ inputs.config_name }} From 500997e5d0e19be51a17dd21d099b28e4d35a854 Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Thu, 30 Jul 2026 13:55:18 +0100 Subject: [PATCH 07/10] Report both binaries from one place --- package/build_pkg.sh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/package/build_pkg.sh b/package/build_pkg.sh index 2c2575b540c..af169108ce4 100755 --- a/package/build_pkg.sh +++ b/package/build_pkg.sh @@ -72,23 +72,25 @@ SRC_DIR="$(cd "${SRC_DIR:-${PWD}}" && pwd)" BUILD_DIR="${BUILD_DIR:-${PWD}/build}" if [[ ! -d "${BUILD_DIR}" ]]; then echo "build_pkg.sh: build directory not found: ${BUILD_DIR}" >&2 - echo "Build xrpld before packaging, or set BUILD_DIR to the directory containing the binaries." >&2 + echo "Build the binaries before packaging, or set BUILD_DIR to the directory containing them." >&2 exit 1 fi BUILD_DIR="$(cd "${BUILD_DIR}" && pwd)" xrpld_binary="${BUILD_DIR}/xrpld" -if [[ ! -x "${xrpld_binary}" ]]; then - echo "build_pkg.sh: expected executable xrpld binary at ${xrpld_binary}." >&2 - echo "Build xrpld before packaging, or set BUILD_DIR to the directory containing xrpld." >&2 - exit 1 -fi - validator_keys_binary="${BUILD_DIR}/validator-keys" -if [[ ! -x "${validator_keys_binary}" ]]; then - echo "build_pkg.sh: expected executable validator-keys binary at ${validator_keys_binary}." >&2 - echo "Configure with -Dvalidator_keys=ON and build the validator-keys target before packaging," >&2 - echo "or set BUILD_DIR to the directory containing validator-keys." >&2 + +# Report both binaries at once: they share a single BUILD_DIR, so telling the +# reader to point it at one of them in isolation is advice they cannot follow. +missing=() +[[ -x "${xrpld_binary}" ]] || missing+=(xrpld) +[[ -x "${validator_keys_binary}" ]] || missing+=(validator-keys) + +if [[ ${#missing[@]} -gt 0 ]]; then + echo "build_pkg.sh: missing or not executable in ${BUILD_DIR}: ${missing[*]}" >&2 + echo "Both binaries come from a single CMake build directory configured with" >&2 + echo "-Dxrpld=ON -Dvalidator_keys=ON. Build them, then point BUILD_DIR at that" >&2 + echo "directory." >&2 exit 1 fi From 52a2cbe91f3e47b1050284aa3eac8d7dfd74c75b Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Thu, 30 Jul 2026 14:01:27 +0100 Subject: [PATCH 08/10] Unify package descriptions --- package/debian/control | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package/debian/control b/package/debian/control index 5e506e7f56d..62e5d79ef1e 100644 --- a/package/debian/control +++ b/package/debian/control @@ -18,9 +18,8 @@ Depends: ${shlibs:Depends}, ${misc:Depends} Description: XRP Ledger daemon - Reference implementation of the XRP Ledger protocol. - Participates in the peer-to-peer network, processes transactions, - and maintains a local ledger copy. - . + 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. This package also includes the validator-keys tool for validator key management. From c07f2aec68435473490696ea27687fcd8c0d9741 Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Thu, 30 Jul 2026 14:47:32 +0100 Subject: [PATCH 09/10] Include GNUInstallDirs in XrplValidatorKeys directly --- CMakeLists.txt | 2 +- cmake/XrplValidatorKeys.cmake | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c04aafb3de..ac2bed1aa89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,8 +137,8 @@ endif() include(XrplCore) include(XrplProtocolAutogen) -include(XrplValidatorKeys) include(XrplInstall) +include(XrplValidatorKeys) # Must come after XrplValidatorKeys: the 'package' target depends on the # validator-keys target existing. include(XrplPackaging) diff --git a/cmake/XrplValidatorKeys.cmake b/cmake/XrplValidatorKeys.cmake index 044b011369a..64ed4e4c3a1 100644 --- a/cmake/XrplValidatorKeys.cmake +++ b/cmake/XrplValidatorKeys.cmake @@ -5,6 +5,10 @@ option( ) if(validator_keys) + # Own the install destination below rather than relying on another module + # having pulled this in first. + include(GNUInstallDirs) + # Pinned to an exact commit, not a branch: the tool ships inside our # packages, so the same xrpld version must always package the same # validator-keys. Bump this deliberately. From 0834ad84637eb4e9a637c07b4fa8fd5c833b16b9 Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Thu, 30 Jul 2026 15:02:42 +0100 Subject: [PATCH 10/10] Package validator-keys license file too --- .cspell.config.yaml | 3 +++ .../workflows/reusable-build-test-config.yml | 4 +++- cmake/XrplValidatorKeys.cmake | 6 ++++++ package/README.md | 3 ++- package/build_pkg.sh | 11 +++++++++++ package/debian/copyright | 19 +++++++++++++++++++ package/debian/xrpld.docs | 1 + package/rpm/xrpld.spec | 3 +++ 8 files changed, 48 insertions(+), 2 deletions(-) diff --git a/.cspell.config.yaml b/.cspell.config.yaml index 13da132b904..78ba979948f 100644 --- a/.cspell.config.yaml +++ b/.cspell.config.yaml @@ -130,6 +130,7 @@ words: - godexsoft - gpgcheck - gpgkey + - Hinnant - hotwallet - hwaddress - hwrap @@ -163,6 +164,7 @@ words: - llection - LOCALGOOD - logwstream + - Lombrozo - lseq - lsmf - ltype @@ -200,6 +202,7 @@ words: - nftokens - nftpage - nikb + - Nikolaos - nixfmt - nixos - nixpkgs diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index 6b2d9648e4a..60f11bed4b1 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -258,7 +258,9 @@ jobs: uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: validator-keys-${{ inputs.config_name }} - path: ${{ env.BUILD_DIR }}/validator-keys + path: | + ${{ env.BUILD_DIR }}/validator-keys + ${{ env.BUILD_DIR }}/validator-keys-LICENSE retention-days: 3 if-no-files-found: error diff --git a/cmake/XrplValidatorKeys.cmake b/cmake/XrplValidatorKeys.cmake index 64ed4e4c3a1..0acaed1a564 100644 --- a/cmake/XrplValidatorKeys.cmake +++ b/cmake/XrplValidatorKeys.cmake @@ -33,5 +33,11 @@ if(validator_keys) # We ship this binary, so like xrpld it must not keep the Nix store's ELF # loader, or it cannot run on the target distro at all. patch_nix_binary(validator-keys) + + configure_file( + "${validator_keys_SOURCE_DIR}/LICENSE" + "${CMAKE_BINARY_DIR}/validator-keys-LICENSE" + COPYONLY + ) install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() diff --git a/package/README.md b/package/README.md index e816b66d499..887509b60be 100644 --- a/package/README.md +++ b/package/README.md @@ -202,7 +202,8 @@ service restart. ### DEB 1. Creates a staging source tree at `debbuild/source/` inside the build directory. -2. Stages the binaries, configs, `README.md`, and `LICENSE.md`. +2. Stages the binaries, configs, `README.md`, `LICENSE.md`, and + `validator-keys-LICENSE`. 3. Copies `package/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` using `${pkg_version}-${PKG_RELEASE}`, diff --git a/package/build_pkg.sh b/package/build_pkg.sh index af169108ce4..d853bf95b74 100755 --- a/package/build_pkg.sh +++ b/package/build_pkg.sh @@ -94,6 +94,16 @@ if [[ ${#missing[@]} -gt 0 ]]; then exit 1 fi +# Shipping validator-keys means shipping its notice, so treat it as required +# rather than letting a package go out without the attribution. +validator_keys_license="${BUILD_DIR}/validator-keys-LICENSE" +if [[ ! -f "${validator_keys_license}" ]]; then + echo "build_pkg.sh: missing ${validator_keys_license}." >&2 + echo "cmake/XrplValidatorKeys.cmake copies it out of the fetched" >&2 + echo "validator-keys-tool source, so reconfigure with -Dvalidator_keys=ON." >&2 + exit 1 +fi + # The binary must also *run* here. Packaging happens in a vanilla distro # container, so this is what catches a binary still pointing at the Nix store's # ELF loader (see patch_nix_binary in cmake/PatchNixBinary.cmake); xrpld is @@ -174,6 +184,7 @@ stage_common() { cp "${xrpld_binary}" "${dest}/xrpld" cp "${validator_keys_binary}" "${dest}/validator-keys" + cp "${validator_keys_license}" "${dest}/validator-keys-LICENSE" cp "${SRC_DIR}/cfg/xrpld-example.cfg" "${dest}/xrpld.cfg" cp "${SRC_DIR}/cfg/validators-example.txt" "${dest}/validators.txt" cp "${SRC_DIR}/LICENSE.md" "${dest}/LICENSE.md" diff --git a/package/debian/copyright b/package/debian/copyright index ddaa719e3a2..2cf673854a1 100644 --- a/package/debian/copyright +++ b/package/debian/copyright @@ -4,6 +4,25 @@ Source: https://github.com/XRPLF/rippled Files: * Copyright: 2011-present, the XRP Ledger developers +License: ISC + +Files: validator-keys +Copyright: 2016, Ripple Labs Inc. + 2011, Arthur Britto, David Schwartz, Jed McCaleb, Vinnie Falco, Bob Way, + Eric Lombrozo, Nikolaos D. Bougalis, Howard Hinnant + 2013, Raw Material Software Ltd. + 2003-2011, Christopher M. Kohlhoff + 2009-2010, Satoshi Nakamoto + 2011, The Bitcoin developers + 2003-2005, Tom Wu +License: ISC +Comment: Built from https://github.com/ripple/validator-keys-tool at the commit + pinned in cmake/XrplValidatorKeys.cmake. Besides ISC-licensed code it + incorporates work under the Boost Software License 1.0 (ASIO), the MIT/X11 + license (Bitcoin) and Tom Wu's license, whose terms require its notice to be + retained intact. The complete upstream notice is therefore shipped verbatim as + /usr/share/doc/xrpld/validator-keys-LICENSE. + 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 diff --git a/package/debian/xrpld.docs b/package/debian/xrpld.docs index b43bf86b50f..77681ddc6e6 100644 --- a/package/debian/xrpld.docs +++ b/package/debian/xrpld.docs @@ -1 +1,2 @@ README.md +validator-keys-LICENSE diff --git a/package/rpm/xrpld.spec b/package/rpm/xrpld.spec index 6d02fa6a8f1..0e3ee2a9681 100644 --- a/package/rpm/xrpld.spec +++ b/package/rpm/xrpld.spec @@ -62,6 +62,8 @@ install -Dm0644 %{_sourcedir}/xrpld.logrotate %{buildroot}%{_sysconfdir}/lo # Docs install -Dm0644 %{_sourcedir}/LICENSE.md %{buildroot}%{_docdir}/%{name}/LICENSE.md install -Dm0644 %{_sourcedir}/README.md %{buildroot}%{_docdir}/%{name}/README.md +# Upstream notice for the bundled validator-keys tool. +install -Dm0644 %{_sourcedir}/validator-keys-LICENSE %{buildroot}%{_docdir}/%{name}/validator-keys-LICENSE # Legacy compatibility for pre-FHS package layouts. # TODO: remove after rippled fully deprecated. @@ -83,6 +85,7 @@ systemd-tmpfiles --create %{_tmpfilesdir}/xrpld.conf || : %files %license %{_docdir}/%{name}/LICENSE.md +%license %{_docdir}/%{name}/validator-keys-LICENSE %doc %{_docdir}/%{name}/README.md %dir %{_sysconfdir}/%{name}