mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-23 23:30:54 +00:00
Compare commits
138 Commits
smart-escr
...
a1q123456/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9bd3dabf5 | ||
|
|
398e504b58 | ||
|
|
a6983f8bf3 | ||
|
|
4113b105a5 | ||
|
|
7442ff2dec | ||
|
|
666e77b22c | ||
|
|
8c12de6c56 | ||
|
|
b21fd86f6e | ||
|
|
f5f47f1cf5 | ||
|
|
ca39bff3c8 | ||
|
|
dd0edc19a0 | ||
|
|
820ca5b332 | ||
|
|
1b226c8b2e | ||
|
|
ca6121c5b3 | ||
|
|
c49789086a | ||
|
|
8336f0473f | ||
|
|
5337d028a2 | ||
|
|
43d842926a | ||
|
|
2adffaef72 | ||
|
|
bd87edfc75 | ||
|
|
d34aa37b3c | ||
|
|
a0074f83d3 | ||
|
|
028ccea7a1 | ||
|
|
df85d43d8a | ||
|
|
8e9b1791c5 | ||
|
|
946827b9bd | ||
|
|
91360c5126 | ||
|
|
af36890c11 | ||
|
|
1281c7a222 | ||
|
|
153b7839a7 | ||
|
|
26cc683ec1 | ||
|
|
6ca2fb84d4 | ||
|
|
a3147740f2 | ||
|
|
d43e5acaa7 | ||
|
|
c74724a719 | ||
|
|
0a572833ea | ||
|
|
639943123c | ||
|
|
909cc5bba9 | ||
|
|
6f5de9067a | ||
|
|
60291c3ed6 | ||
|
|
4173f7e499 | ||
|
|
9c292fbe4f | ||
|
|
b19c3c64f2 | ||
|
|
a0e1e578a0 | ||
|
|
07aa97fda4 | ||
|
|
4f8819565a | ||
|
|
6580b200db | ||
|
|
2967f1f0cc | ||
|
|
71e972cbed | ||
|
|
a24caaa6ea | ||
|
|
07b9c59b89 | ||
|
|
63d8772f69 | ||
|
|
94bccb3a5a | ||
|
|
0fb92c3194 | ||
|
|
798e889ec4 | ||
|
|
abf5511d07 | ||
|
|
a0e78b286f | ||
|
|
9859e5ceda | ||
|
|
00a178fb92 | ||
|
|
cb425647a4 | ||
|
|
5bf24c4045 | ||
|
|
8d7524f03b | ||
|
|
41d6bb5f73 | ||
|
|
39c8c293b3 | ||
|
|
54cfdda00b | ||
|
|
15d08770bf | ||
|
|
a75488e5ff | ||
|
|
c3ee602002 | ||
|
|
e0de716ee6 | ||
|
|
06488c1318 | ||
|
|
b8451ffa32 | ||
|
|
765babb20d | ||
|
|
97f35add2e | ||
|
|
8461ded0d8 | ||
|
|
d4c1359921 | ||
|
|
a88ba66fce | ||
|
|
4bd1d1ca2f | ||
|
|
0cce5a06d9 | ||
|
|
32a9cc4038 | ||
|
|
587505ef18 | ||
|
|
ecdd457f35 | ||
|
|
85e73cbd32 | ||
|
|
4eece4003d | ||
|
|
3ad6ce236e | ||
|
|
21cd615407 | ||
|
|
3c0659d26b | ||
|
|
532506541f | ||
|
|
8a5eded4f1 | ||
|
|
6ddad54985 | ||
|
|
ccb9db0bc7 | ||
|
|
24b6dad287 | ||
|
|
e290005db5 | ||
|
|
86832edc70 | ||
|
|
ff7fff2cf2 | ||
|
|
2db631c915 | ||
|
|
6c9c7f0555 | ||
|
|
9466ecb5c2 | ||
|
|
e0aa50c4be | ||
|
|
29120dfcbd | ||
|
|
20801d98ac | ||
|
|
b878818e80 | ||
|
|
6668b7e8d0 | ||
|
|
a5cc339d7b | ||
|
|
fecfc0cf3f | ||
|
|
ea0a6904f0 | ||
|
|
29d74142ae | ||
|
|
9afa1cf4d1 | ||
|
|
7908aec2ec | ||
|
|
4c0180b3db | ||
|
|
4acccfeda8 | ||
|
|
b89d75a2d5 | ||
|
|
1653f0c80f | ||
|
|
c50edf507c | ||
|
|
40cdf49d15 | ||
|
|
9cd531659a | ||
|
|
38c54c3f36 | ||
|
|
95e1ffea6e | ||
|
|
982bf36dd8 | ||
|
|
faca302adf | ||
|
|
6b3eaf091b | ||
|
|
68a765d929 | ||
|
|
033dca2f0e | ||
|
|
bf65e5fa7b | ||
|
|
90b2a68da8 | ||
|
|
06a9b1b617 | ||
|
|
7d3611df2a | ||
|
|
7877ee42a0 | ||
|
|
1dcaf4b54e | ||
|
|
5ab95748d4 | ||
|
|
4a9ee54c88 | ||
|
|
981c256933 | ||
|
|
a5af6b4e4a | ||
|
|
e1dae5f775 | ||
|
|
6c793edf72 | ||
|
|
d60955e2fc | ||
|
|
846369cbe7 | ||
|
|
d569f7db9e | ||
|
|
a12ab0496c |
@@ -75,6 +75,8 @@ Checks: "-*,
|
||||
# readability-static-accessed-through-instance, # this check is probably unnecessary. It makes the code less readable
|
||||
# ---
|
||||
|
||||
FormatStyle: file
|
||||
|
||||
CheckOptions:
|
||||
bugprone-unsafe-functions.ReportMoreUnsafeFunctions: true
|
||||
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
|
||||
@@ -83,6 +85,8 @@ CheckOptions:
|
||||
|
||||
readability-braces-around-statements.ShortStatementLines: 2
|
||||
readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
|
||||
readability-identifier-naming.NamespaceCase: lower_case
|
||||
readability-identifier-naming.InlineNamespaceCase: lower_case
|
||||
readability-identifier-naming.ClassCase: CamelCase
|
||||
readability-identifier-naming.StructCase: CamelCase
|
||||
readability-identifier-naming.UnionCase: CamelCase
|
||||
|
||||
@@ -7,6 +7,7 @@ ignorePaths:
|
||||
- cmake/**
|
||||
- LICENSE.md
|
||||
- .clang-tidy
|
||||
- nix/check-tools/*.txt # generated, and full of Nix store hashes
|
||||
language: en
|
||||
allowCompoundWords: true # TODO (#6334)
|
||||
ignoreRandomStrings: true
|
||||
@@ -30,7 +31,9 @@ ignoreRegExpList:
|
||||
- ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
- ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
overrides:
|
||||
- filename: "**/*_test.cpp" # all test files
|
||||
- filename:
|
||||
- "**/*_test.cpp" # legacy boost.test files
|
||||
- "src/tests/**/*.cpp" # gtest test files
|
||||
ignoreRegExpList:
|
||||
- /"[^"]*"/g # double-quoted strings
|
||||
- /'[^']*'/g # single-quoted strings
|
||||
@@ -66,6 +69,7 @@ words:
|
||||
- Buildx
|
||||
- canonicality
|
||||
- canonicalised
|
||||
- cctools
|
||||
- changespq
|
||||
- checkme
|
||||
- choco
|
||||
@@ -107,6 +111,7 @@ words:
|
||||
- disablerepo
|
||||
- distro
|
||||
- doxyfile
|
||||
- dsymutil
|
||||
- dxrpl
|
||||
- elgamal
|
||||
- enabled
|
||||
@@ -130,6 +135,7 @@ words:
|
||||
- godexsoft
|
||||
- gpgcheck
|
||||
- gpgkey
|
||||
- Hinnant
|
||||
- hotwallet
|
||||
- hwaddress
|
||||
- hwrap
|
||||
@@ -163,6 +169,8 @@ words:
|
||||
- llection
|
||||
- LOCALGOOD
|
||||
- logwstream
|
||||
- Lombrozo
|
||||
- lresolv
|
||||
- lseq
|
||||
- lsmf
|
||||
- ltype
|
||||
@@ -172,7 +180,6 @@ words:
|
||||
- MPTAMM
|
||||
- MPTDEX
|
||||
- Merkle
|
||||
- Metafuncton
|
||||
- misprediction
|
||||
- missingok
|
||||
- mptbalance
|
||||
@@ -200,6 +207,7 @@ words:
|
||||
- nftokens
|
||||
- nftpage
|
||||
- nikb
|
||||
- Nikolaos
|
||||
- nixfmt
|
||||
- nixos
|
||||
- nixpkgs
|
||||
@@ -216,6 +224,7 @@ words:
|
||||
- Nyffenegger
|
||||
- onlatest
|
||||
- ostr
|
||||
- otool
|
||||
- oxalica
|
||||
- pargs
|
||||
- partitioner
|
||||
@@ -245,11 +254,15 @@ words:
|
||||
- Raphson
|
||||
- rcflags
|
||||
- replayer
|
||||
- repodata
|
||||
- repomd
|
||||
- rerandomize
|
||||
- rerandomization
|
||||
- rerandomized
|
||||
- rerandomizes
|
||||
- rerere
|
||||
- retargeted
|
||||
- retargets
|
||||
- retriable
|
||||
- RIPD
|
||||
- ripdtop
|
||||
@@ -285,6 +298,7 @@ words:
|
||||
- sles
|
||||
- soci
|
||||
- socidb
|
||||
- Sonatype
|
||||
- sponsee
|
||||
- sponsees
|
||||
- SRPMS
|
||||
@@ -359,8 +373,10 @@ words:
|
||||
- wthread
|
||||
- xbridge
|
||||
- xchain
|
||||
- xcrun
|
||||
- ximinez
|
||||
- XMACRO
|
||||
- xored
|
||||
- xrpkuwait
|
||||
- xrpl
|
||||
- xrpld
|
||||
|
||||
6
.envrc
6
.envrc
@@ -1 +1,7 @@
|
||||
watch_file nix/*.nix
|
||||
|
||||
# The dev shell derivation includes all of conan/ (see nix/devshell.nix), so any
|
||||
# change in there has to invalidate direnv's cached environment.
|
||||
watch_dir conan
|
||||
|
||||
use flake
|
||||
|
||||
44
.github/actions/generate-version/action.yml
vendored
44
.github/actions/generate-version/action.yml
vendored
@@ -1,44 +0,0 @@
|
||||
name: Generate build version number
|
||||
description: "Generate build version number."
|
||||
|
||||
outputs:
|
||||
version:
|
||||
description: "The generated build version number."
|
||||
value: ${{ steps.version.outputs.version }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
# When a tag is pushed, the version is used as-is.
|
||||
- name: Generate version for tag event
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
shell: bash
|
||||
env:
|
||||
VERSION: ${{ github.ref_name }}
|
||||
run: echo "VERSION=${VERSION}" >>"${GITHUB_ENV}"
|
||||
|
||||
# When a tag is not pushed, then the version (e.g. 1.2.3-b0) is extracted
|
||||
# from the BuildInfo.cpp file and the shortened commit hash appended to it.
|
||||
# We use a plus sign instead of a hyphen because Conan recipe versions do
|
||||
# not support two hyphens.
|
||||
- name: Generate version for non-tag event
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'Extracting version from BuildInfo.cpp.'
|
||||
VERSION="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')"
|
||||
if [[ -z "${VERSION}" ]]; then
|
||||
echo 'Unable to extract version from BuildInfo.cpp.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 'Appending shortened commit hash to version.'
|
||||
SHA='${{ github.sha }}'
|
||||
VERSION="${VERSION}+${SHA:0:7}"
|
||||
|
||||
echo "VERSION=${VERSION}" >>"${GITHUB_ENV}"
|
||||
|
||||
- name: Output version
|
||||
id: version
|
||||
shell: bash
|
||||
run: echo "version=${VERSION}" >>"${GITHUB_OUTPUT}"
|
||||
90
.github/actions/release-info/action.yml
vendored
Normal file
90
.github/actions/release-info/action.yml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
name: Release info
|
||||
description: "Derive the version, release channel and package release number for this build."
|
||||
|
||||
outputs:
|
||||
version:
|
||||
description: "The build version number."
|
||||
value: ${{ steps.version.outputs.version }}
|
||||
channel:
|
||||
description: "The release channel this build belongs to."
|
||||
value: ${{ steps.channel.outputs.channel }}
|
||||
pkg_release:
|
||||
description: "The package release number: 1 for a tag, the run number otherwise."
|
||||
value: ${{ steps.pkg_release.outputs.pkg_release }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
# A tag names its own version. Anything else takes it from BuildInfo.cpp and
|
||||
# appends the commit hash as build metadata, joined with a plus sign because a
|
||||
# Conan version cannot contain two hyphens.
|
||||
- name: Determine version
|
||||
id: version
|
||||
shell: bash
|
||||
env:
|
||||
IS_TAG: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
REF_NAME: ${{ github.ref_name }}
|
||||
SHA: ${{ github.sha }}
|
||||
run: |
|
||||
if [[ "${IS_TAG}" == "true" ]]; then
|
||||
version="${REF_NAME}"
|
||||
else
|
||||
version="$(awk -F'"' '/versionString =/ { print $2 }' src/libxrpl/protocol/BuildInfo.cpp)"
|
||||
if [[ -z "${version}" ]]; then
|
||||
echo "Unable to read versionString from BuildInfo.cpp." >&2
|
||||
exit 1
|
||||
fi
|
||||
version="${version}+${SHA:0:7}"
|
||||
fi
|
||||
|
||||
echo "version=${version}" | tee -a "${GITHUB_OUTPUT}"
|
||||
|
||||
# Only a tag says how mature a build is: a push is a develop build whatever
|
||||
# its version, and a non-public codebase keeps its packages to itself.
|
||||
- name: Determine release channel
|
||||
id: channel
|
||||
shell: bash
|
||||
env:
|
||||
IS_TAG: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
REF_NAME: ${{ github.ref_name }}
|
||||
VISIBILITY: ${{ github.event.repository.visibility }}
|
||||
run: |
|
||||
pre_release=""
|
||||
if [[ "${REF_NAME}" == *-* ]]; then
|
||||
pre_release="${REF_NAME#*-}"
|
||||
fi
|
||||
|
||||
if [[ "${VISIBILITY}" != "public" ]]; then
|
||||
channel=private
|
||||
elif [[ "${IS_TAG}" != "true" ]]; then
|
||||
channel=develop
|
||||
elif [[ -z "${pre_release}" ]]; then
|
||||
channel=stable
|
||||
elif [[ "${pre_release}" =~ ^rc[0-9]+(\+.*)?$ ]]; then
|
||||
channel=unstable
|
||||
elif [[ "${pre_release}" =~ ^b(0|[1-9][0-9]*)(\+.*)?$ ]]; then
|
||||
channel=experimental
|
||||
else
|
||||
echo "Unsupported pre-release in tag '${REF_NAME}'. Use bN or rcN." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "channel=${channel}" | tee -a "${GITHUB_OUTPUT}"
|
||||
|
||||
# A tag is packaged once, so its release number is fixed at 1. Develop builds
|
||||
# repeat the same version, so the run number is what makes each push an
|
||||
# upgrade rather than a reinstall.
|
||||
- name: Determine package release
|
||||
id: pkg_release
|
||||
shell: bash
|
||||
env:
|
||||
IS_TAG: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
RUN_NUMBER: ${{ github.run_number }}
|
||||
run: |
|
||||
if [[ "${IS_TAG}" == "true" ]]; then
|
||||
pkg_release=1
|
||||
else
|
||||
pkg_release="${RUN_NUMBER}"
|
||||
fi
|
||||
|
||||
echo "pkg_release=${pkg_release}" | tee -a "${GITHUB_OUTPUT}"
|
||||
69
.github/actions/setup-nix-env/action.yml
vendored
Normal file
69
.github/actions/setup-nix-env/action.yml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
name: Setup Nix environment
|
||||
description: "Build the flake's CI environment and put its tools on PATH."
|
||||
|
||||
# The environment from nix/ci-env.nix, the same one the Linux CI images bake in
|
||||
# (see nix/docker). Exported onto PATH rather than entered with `nix develop`:
|
||||
# the composite actions below run plain `bash` and would escape a dev shell.
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
steps:
|
||||
- name: Build the CI environment
|
||||
id: build
|
||||
shell: bash
|
||||
env:
|
||||
# --out-link doubles as a GC root for the length of the job.
|
||||
OUT_LINK: ${{ runner.temp }}/xrpld-ci-env
|
||||
run: |
|
||||
# --extra-experimental-features: flakes may not be on in the runner's nix.conf.
|
||||
nix --extra-experimental-features "nix-command flakes" \
|
||||
build .#default --out-link "${OUT_LINK}" --print-build-logs
|
||||
echo "path=$(readlink -f "${OUT_LINK}")" >>"${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Export the environment
|
||||
shell: bash
|
||||
env:
|
||||
ENV_PATH: ${{ steps.build.outputs.path }}
|
||||
run: |
|
||||
echo "${ENV_PATH}/bin" >>"${GITHUB_PATH}"
|
||||
|
||||
# Already KEY=VALUE per line. See `darwinEnv` in nix/ci-env.nix.
|
||||
ENV_FILE="${ENV_PATH}/share/xrpld-ci-env/env"
|
||||
if [ -f "${ENV_FILE}" ]; then
|
||||
cat "${ENV_FILE}" >>"${GITHUB_ENV}"
|
||||
fi
|
||||
|
||||
# XrplSanity.cmake otherwise rejects a Nix compiler as one that leaked.
|
||||
echo "XRPL_DEVSHELL=ci-env" >>"${GITHUB_ENV}"
|
||||
|
||||
# Unlike the Linux nix images, macOS needs no SSL_CERT_FILE: it has its
|
||||
# own trust store, and pinning would break TLS to hosts relying on it.
|
||||
|
||||
# Workspace-local, so `cleanup-workspace` clears it, but not the
|
||||
# `.conan2` prepare-runner hands the system toolchain: that Conan is a
|
||||
# different version, and the two would migrate each other's cache.
|
||||
echo "CONAN_HOME=${{ github.workspace }}/.conan2-nix" >>"${GITHUB_ENV}"
|
||||
|
||||
# Config, profiles and remote, exactly as the dev shell sets them up on
|
||||
# entry; the `setup-conan` action is skipped for this toolchain.
|
||||
- name: Setup Conan
|
||||
shell: bash
|
||||
run: ./conan/init.sh
|
||||
|
||||
# `Check tools` runs later but swallows failures; a bad export would just
|
||||
# build with the system toolchain.
|
||||
- name: Verify the toolchain resolves into the Nix store
|
||||
shell: bash
|
||||
run: |
|
||||
for tool in clang clang++ cmake ninja conan; do
|
||||
path="$(command -v "${tool}" || true)"
|
||||
echo "${tool} -> ${path:-<not found>}"
|
||||
case "${path}" in
|
||||
/nix/store/*) ;;
|
||||
*)
|
||||
echo "::error::${tool} does not resolve into the Nix store"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
6
.github/dependabot.yml
vendored
6
.github/dependabot.yml
vendored
@@ -4,7 +4,7 @@ updates:
|
||||
directories:
|
||||
- /
|
||||
- .github/actions/build-deps/
|
||||
- .github/actions/generate-version/
|
||||
- .github/actions/release-info/
|
||||
- .github/actions/set-compiler-env/
|
||||
- .github/actions/setup-conan/
|
||||
schedule:
|
||||
@@ -15,3 +15,7 @@ updates:
|
||||
commit-message:
|
||||
prefix: "ci: [DEPENDABOT] "
|
||||
target-branch: develop
|
||||
groups:
|
||||
github-actions:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
18
.github/scripts/levelization/README.md
vendored
18
.github/scripts/levelization/README.md
vendored
@@ -40,18 +40,18 @@ listed later.
|
||||
| 04 | xrpl/protocol |
|
||||
| 05 | xrpl/core xrpl/resource xrpl/server |
|
||||
| 06 | xrpl/ledger xrpl/nodestore xrpl/net |
|
||||
| 07 | xrpl/shamap |
|
||||
| 07 | xrpl/shamap xrpl/consensus |
|
||||
|
||||
## xrpld Modules (Application Implementation)
|
||||
|
||||
| Level / Tier | Module(s) |
|
||||
| ------------ | -------------------------------- |
|
||||
| 05 | xrpld/conditions xrpld/consensus |
|
||||
| 06 | xrpld/core xrpld/peerfinder |
|
||||
| 07 | xrpld/shamap xrpld/overlay |
|
||||
| 08 | xrpld/app |
|
||||
| 09 | xrpld/rpc |
|
||||
| 10 | xrpld/perflog |
|
||||
| Level / Tier | Module(s) |
|
||||
| ------------ | --------------------------- |
|
||||
| 05 | xrpld/conditions |
|
||||
| 06 | xrpld/core xrpld/peerfinder |
|
||||
| 07 | xrpld/shamap xrpld/overlay |
|
||||
| 08 | xrpld/app |
|
||||
| 09 | xrpld/rpc |
|
||||
| 10 | xrpld/perflog |
|
||||
|
||||
## Test Modules
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
Loop: xrpld.app xrpld.overlay
|
||||
xrpld.app > xrpld.overlay
|
||||
|
||||
Loop: xrpld.app xrpld.peerfinder
|
||||
xrpld.peerfinder ~= xrpld.app
|
||||
|
||||
Loop: xrpld.app xrpld.rpc
|
||||
xrpld.rpc > xrpld.app
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ libxrpl.conditions > xrpl.basics
|
||||
libxrpl.conditions > xrpl.conditions
|
||||
libxrpl.config > xrpl.basics
|
||||
libxrpl.config > xrpl.config
|
||||
libxrpl.consensus > xrpl.basics
|
||||
libxrpl.consensus > xrpl.consensus
|
||||
libxrpl.core > xrpl.basics
|
||||
libxrpl.core > xrpl.core
|
||||
libxrpl.core > xrpl.json
|
||||
@@ -25,6 +27,9 @@ libxrpl.nodestore > xrpl.config
|
||||
libxrpl.nodestore > xrpl.json
|
||||
libxrpl.nodestore > xrpl.nodestore
|
||||
libxrpl.nodestore > xrpl.protocol
|
||||
libxrpl.peerfinder > xrpl.basics
|
||||
libxrpl.peerfinder > xrpl.peerfinder
|
||||
libxrpl.peerfinder > xrpl.protocol
|
||||
libxrpl.protocol > xrpl.basics
|
||||
libxrpl.protocol > xrpl.json
|
||||
libxrpl.protocol > xrpl.protocol
|
||||
@@ -60,9 +65,9 @@ test.app > test.jtx
|
||||
test.app > test.unit_test
|
||||
test.app > xrpl.basics
|
||||
test.app > xrpl.config
|
||||
test.app > xrpl.consensus
|
||||
test.app > xrpl.core
|
||||
test.app > xrpld.app
|
||||
test.app > xrpld.consensus
|
||||
test.app > xrpld.core
|
||||
test.app > xrpld.overlay
|
||||
test.app > xrpld.rpc
|
||||
@@ -83,12 +88,9 @@ test.basics > xrpl.protocol
|
||||
test.beast > xrpl.basics
|
||||
test.conditions > xrpl.basics
|
||||
test.conditions > xrpl.conditions
|
||||
test.consensus > test.csf
|
||||
test.consensus > test.jtx
|
||||
test.consensus > test.unit_test
|
||||
test.consensus > xrpl.basics
|
||||
test.consensus > xrpld.app
|
||||
test.consensus > xrpld.consensus
|
||||
test.consensus > xrpl.ledger
|
||||
test.consensus > xrpl.protocol
|
||||
test.consensus > xrpl.shamap
|
||||
@@ -103,10 +105,6 @@ test.core > xrpl.json
|
||||
test.core > xrpl.protocol
|
||||
test.core > xrpl.rdb
|
||||
test.core > xrpl.server
|
||||
test.csf > xrpl.basics
|
||||
test.csf > xrpld.consensus
|
||||
test.csf > xrpl.json
|
||||
test.csf > xrpl.ledger
|
||||
test.json > test.jtx
|
||||
test.json > xrpl.json
|
||||
test.jtx > test.unit_test
|
||||
@@ -132,12 +130,9 @@ test.ledger > xrpl.json
|
||||
test.ledger > xrpl.ledger
|
||||
test.ledger > xrpl.protocol
|
||||
test.nodestore > test.jtx
|
||||
test.nodestore > test.unit_test
|
||||
test.nodestore > xrpl.basics
|
||||
test.nodestore > xrpl.config
|
||||
test.nodestore > xrpld.core
|
||||
test.nodestore > xrpl.nodestore
|
||||
test.nodestore > xrpl.protocol
|
||||
test.nodestore > xrpl.rdb
|
||||
test.overlay > test.jtx
|
||||
test.overlay > test.unit_test
|
||||
@@ -146,19 +141,13 @@ test.overlay > xrpl.config
|
||||
test.overlay > xrpld.app
|
||||
test.overlay > xrpld.core
|
||||
test.overlay > xrpld.overlay
|
||||
test.overlay > xrpld.peerfinder
|
||||
test.overlay > xrpl.json
|
||||
test.overlay > xrpl.nodestore
|
||||
test.overlay > xrpl.peerfinder
|
||||
test.overlay > xrpl.protocol
|
||||
test.overlay > xrpl.resource
|
||||
test.overlay > xrpl.server
|
||||
test.overlay > xrpl.shamap
|
||||
test.peerfinder > test.beast
|
||||
test.peerfinder > test.unit_test
|
||||
test.peerfinder > xrpl.basics
|
||||
test.peerfinder > xrpld.core
|
||||
test.peerfinder > xrpld.peerfinder
|
||||
test.peerfinder > xrpl.protocol
|
||||
test.protocol > test.jtx
|
||||
test.protocol > test.unit_test
|
||||
test.protocol > xrpl.basics
|
||||
@@ -192,11 +181,13 @@ test.unit_test > xrpl.basics
|
||||
test.unit_test > xrpl.protocol
|
||||
tests.libxrpl > xrpl.basics
|
||||
tests.libxrpl > xrpl.config
|
||||
tests.libxrpl > xrpl.consensus
|
||||
tests.libxrpl > xrpl.core
|
||||
tests.libxrpl > xrpl.json
|
||||
tests.libxrpl > xrpl.ledger
|
||||
tests.libxrpl > xrpl.net
|
||||
tests.libxrpl > xrpl.nodestore
|
||||
tests.libxrpl > xrpl.peerfinder
|
||||
tests.libxrpl > xrpl.protocol
|
||||
tests.libxrpl > xrpl.protocol_autogen
|
||||
tests.libxrpl > xrpl.resource
|
||||
@@ -206,6 +197,10 @@ tests.libxrpl > xrpl.tx
|
||||
xrpl.conditions > xrpl.basics
|
||||
xrpl.conditions > xrpl.protocol
|
||||
xrpl.config > xrpl.basics
|
||||
xrpl.consensus > xrpl.basics
|
||||
xrpl.consensus > xrpl.json
|
||||
xrpl.consensus > xrpl.ledger
|
||||
xrpl.consensus > xrpl.protocol
|
||||
xrpl.core > xrpl.basics
|
||||
xrpl.core > xrpl.json
|
||||
xrpl.core > xrpl.protocol
|
||||
@@ -220,6 +215,8 @@ xrpl.nodestore > xrpl.basics
|
||||
xrpl.nodestore > xrpl.config
|
||||
xrpl.nodestore > xrpl.json
|
||||
xrpl.nodestore > xrpl.protocol
|
||||
xrpl.peerfinder > xrpl.basics
|
||||
xrpl.peerfinder > xrpl.protocol
|
||||
xrpl.protocol > xrpl.basics
|
||||
xrpl.protocol > xrpl.json
|
||||
xrpl.protocol_autogen > xrpl.json
|
||||
@@ -246,23 +243,20 @@ xrpl.tx > xrpl.protocol
|
||||
xrpld.app > test.unit_test
|
||||
xrpld.app > xrpl.basics
|
||||
xrpld.app > xrpl.config
|
||||
xrpld.app > xrpl.consensus
|
||||
xrpld.app > xrpl.core
|
||||
xrpld.app > xrpld.consensus
|
||||
xrpld.app > xrpld.core
|
||||
xrpld.app > xrpl.json
|
||||
xrpld.app > xrpl.ledger
|
||||
xrpld.app > xrpl.net
|
||||
xrpld.app > xrpl.nodestore
|
||||
xrpld.app > xrpl.peerfinder
|
||||
xrpld.app > xrpl.protocol
|
||||
xrpld.app > xrpl.rdb
|
||||
xrpld.app > xrpl.resource
|
||||
xrpld.app > xrpl.server
|
||||
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.config
|
||||
xrpld.core > xrpl.core
|
||||
@@ -271,21 +265,22 @@ xrpld.core > xrpl.protocol
|
||||
xrpld.core > xrpl.rdb
|
||||
xrpld.overlay > xrpl.basics
|
||||
xrpld.overlay > xrpl.config
|
||||
xrpld.overlay > xrpl.consensus
|
||||
xrpld.overlay > xrpl.core
|
||||
xrpld.overlay > xrpld.consensus
|
||||
xrpld.overlay > xrpld.core
|
||||
xrpld.overlay > xrpld.peerfinder
|
||||
xrpld.overlay > xrpl.json
|
||||
xrpld.overlay > xrpl.ledger
|
||||
xrpld.overlay > xrpl.peerfinder
|
||||
xrpld.overlay > xrpl.protocol
|
||||
xrpld.overlay > xrpl.resource
|
||||
xrpld.overlay > xrpl.server
|
||||
xrpld.overlay > xrpl.shamap
|
||||
xrpld.overlay > xrpl.tx
|
||||
xrpld.peerfinder > xrpl.basics
|
||||
xrpld.peerfinder > xrpl.config
|
||||
xrpld.peerfinder > xrpld.app
|
||||
xrpld.peerfinder > xrpld.core
|
||||
xrpld.peerfinder > xrpl.protocol
|
||||
xrpld.peerfinder > xrpl.peerfinder
|
||||
xrpld.peerfinder > xrpl.rdb
|
||||
xrpld.perflog > xrpl.basics
|
||||
xrpld.perflog > xrpl.config
|
||||
|
||||
3
.github/scripts/rename/namespace.sh
vendored
3
.github/scripts/rename/namespace.sh
vendored
@@ -46,9 +46,6 @@ for DIRECTORY in "${DIRECTORIES[@]}"; do
|
||||
done
|
||||
done
|
||||
|
||||
# Special case for NuDBFactory that has ripple twice in the test suite name.
|
||||
${SED_COMMAND} -i -E 's/(BEAST_DEFINE_TESTSUITE.+)ripple(.+)/\1xrpl\2/g' src/test/nodestore/NuDBFactory_test.cpp
|
||||
|
||||
DIRECTORY=$1
|
||||
find "${DIRECTORY}" -type f -name "*.md" | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
|
||||
31
.github/scripts/strategy-matrix/generate.py
vendored
31
.github/scripts/strategy-matrix/generate.py
vendored
@@ -33,6 +33,10 @@ def get_cmake_args(build_type: str, extra_args: str) -> str:
|
||||
# Every config must declare 'minimal'. Minimal configs form the reduced matrix
|
||||
# built for pull requests by default; the full matrix adds the rest. Packaging
|
||||
# configs declare it too, but packaging is gated in the workflow, not by it.
|
||||
#
|
||||
# Configs may also opt into 'benchmark' to smoke-run the benchmarks. Note that
|
||||
# the flag applies to every entry a config expands into, so only set it on
|
||||
# configs that expand to a single combination.
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
@@ -43,6 +47,7 @@ class LinuxConfig:
|
||||
build_type: list[str]
|
||||
arch: list[str]
|
||||
minimal: bool
|
||||
benchmark: bool = False # if true, smoke-run the benchmarks after testing
|
||||
sanitizers: list[str] = dataclasses.field(default_factory=list)
|
||||
suffix: str = ""
|
||||
extra_cmake_args: str = ""
|
||||
@@ -81,7 +86,11 @@ class PlatformConfig:
|
||||
build_type: list[str]
|
||||
minimal: bool
|
||||
build_only: bool = False # if true, skip tests (e.g. macos/Windows Debug)
|
||||
benchmark: bool = False # if true, smoke-run the benchmarks after testing
|
||||
extra_cmake_args: str = ""
|
||||
# "" is the runner's system compiler, "nix" the flake's CI environment.
|
||||
# macOS only: Linux always builds in a Nix image, Windows has no Nix.
|
||||
toolchain: str = ""
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if isinstance(self.build_type, str):
|
||||
@@ -125,18 +134,21 @@ class MatrixEntry:
|
||||
cmake_args: str
|
||||
cmake_target: str
|
||||
build_only: bool
|
||||
benchmark: bool
|
||||
build_type: str
|
||||
architecture: Architecture
|
||||
sanitizers: str
|
||||
image: str = "" # container image; empty for macOS/Windows (runs natively)
|
||||
compiler: str = "" # compiler name ("gcc" or "clang"); empty for macOS/Windows
|
||||
toolchain: str = "" # "nix" for the flake's CI environment; see PlatformConfig
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class PackagingEntry:
|
||||
"""One entry in the generated packaging strategy matrix."""
|
||||
|
||||
artifact_name: str
|
||||
xrpld_artifact_name: str
|
||||
validator_keys_artifact_name: str
|
||||
image: str
|
||||
distro: str # e.g. "debian" or "rhel"; drives package-format-specific steps
|
||||
|
||||
@@ -193,6 +205,7 @@ def expand_linux_matrix(linux: LinuxFile, minimal: bool) -> list[MatrixEntry]:
|
||||
cmake_args=get_cmake_args(build_type, cfg.extra_cmake_args),
|
||||
cmake_target="all",
|
||||
build_only=False,
|
||||
benchmark=cfg.benchmark,
|
||||
build_type=build_type,
|
||||
architecture=arch_info,
|
||||
sanitizers=sanitizer,
|
||||
@@ -206,18 +219,23 @@ def expand_linux_matrix(linux: LinuxFile, minimal: bool) -> list[MatrixEntry]:
|
||||
def expand_linux_packaging(linux: LinuxFile) -> list[PackagingEntry]:
|
||||
"""Generate the packaging matrix from a LinuxFile's package_configs section.
|
||||
|
||||
Packaging uses vanilla distro images (debian:bookworm, ubi9, …) instead of
|
||||
Packaging uses vanilla distro images (debian:bookworm, almalinux:9) instead of
|
||||
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 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():
|
||||
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",
|
||||
xrpld_artifact_name=f"xrpld-{config_name}",
|
||||
validator_keys_artifact_name=f"validator-keys-{config_name}",
|
||||
image=cfg.image,
|
||||
distro=distro,
|
||||
)
|
||||
@@ -239,15 +257,20 @@ def expand_platform_matrix(pf: PlatformFile, minimal: bool) -> list[MatrixEntry]
|
||||
if minimal and not cfg.minimal:
|
||||
continue
|
||||
for build_type in cfg.build_type:
|
||||
name = f"{platform_name}-{arch}-{build_type.lower()}"
|
||||
if cfg.toolchain:
|
||||
name += f"-{cfg.toolchain}"
|
||||
entries.append(
|
||||
MatrixEntry(
|
||||
config_name=f"{platform_name}-{arch}-{build_type.lower()}",
|
||||
config_name=name,
|
||||
cmake_args=get_cmake_args(build_type, cfg.extra_cmake_args),
|
||||
cmake_target="install" if is_windows else "all",
|
||||
build_only=cfg.build_only,
|
||||
benchmark=cfg.benchmark,
|
||||
build_type=build_type,
|
||||
architecture=Architecture(platform=pf.platform, runner=pf.runner),
|
||||
sanitizers="",
|
||||
toolchain=cfg.toolchain,
|
||||
)
|
||||
)
|
||||
return entries
|
||||
|
||||
32
.github/scripts/strategy-matrix/linux.json
vendored
32
.github/scripts/strategy-matrix/linux.json
vendored
@@ -1,13 +1,23 @@
|
||||
{
|
||||
"image_tag": "sha-3122de8",
|
||||
"image_tag": "sha-a0074f8",
|
||||
"configs": {
|
||||
"ubuntu": [
|
||||
{
|
||||
"compiler": ["gcc"],
|
||||
"build_type": ["Debug"],
|
||||
"arch": ["amd64"],
|
||||
"minimal": true,
|
||||
"suffix": "coverage",
|
||||
"extra_cmake_args": "-DUNIT_TEST_REFERENCE_FEE=500 -Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0"
|
||||
},
|
||||
{
|
||||
"compiler": ["clang"],
|
||||
"build_type": ["Release"],
|
||||
"arch": ["amd64"],
|
||||
"minimal": true
|
||||
"minimal": true,
|
||||
"benchmark": true
|
||||
},
|
||||
|
||||
{
|
||||
"compiler": ["gcc"],
|
||||
"build_type": ["Release"],
|
||||
@@ -29,14 +39,6 @@
|
||||
"sanitizers": ["address", "undefinedbehavior"]
|
||||
},
|
||||
|
||||
{
|
||||
"compiler": ["gcc"],
|
||||
"build_type": ["Debug"],
|
||||
"arch": ["amd64"],
|
||||
"minimal": true,
|
||||
"suffix": "coverage",
|
||||
"extra_cmake_args": "-DUNIT_TEST_REFERENCE_FEE=500 -Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0"
|
||||
},
|
||||
{
|
||||
"compiler": ["clang"],
|
||||
"build_type": ["Debug"],
|
||||
@@ -68,7 +70,8 @@
|
||||
"compiler": ["gcc"],
|
||||
"build_type": ["Release"],
|
||||
"arch": ["amd64"],
|
||||
"minimal": false
|
||||
"minimal": false,
|
||||
"extra_cmake_args": "-Dvalidator_keys=ON"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -77,7 +80,8 @@
|
||||
"compiler": ["gcc"],
|
||||
"build_type": ["Release"],
|
||||
"arch": ["amd64"],
|
||||
"minimal": false
|
||||
"minimal": false,
|
||||
"extra_cmake_args": "-Dvalidator_keys=ON"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -88,7 +92,7 @@
|
||||
"build_type": ["Release"],
|
||||
"arch": ["amd64"],
|
||||
"minimal": false,
|
||||
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-577d745"
|
||||
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-028ccea"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -98,7 +102,7 @@
|
||||
"build_type": ["Release"],
|
||||
"arch": ["amd64"],
|
||||
"minimal": false,
|
||||
"image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-577d745"
|
||||
"image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-028ccea"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
13
.github/scripts/strategy-matrix/macos.json
vendored
13
.github/scripts/strategy-matrix/macos.json
vendored
@@ -12,6 +12,19 @@
|
||||
"extra_cmake_args": "-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
|
||||
"build_only": true,
|
||||
"minimal": false
|
||||
},
|
||||
{
|
||||
"build_type": "Release",
|
||||
"extra_cmake_args": "-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
|
||||
"toolchain": "nix",
|
||||
"minimal": false
|
||||
},
|
||||
{
|
||||
"build_type": "Debug",
|
||||
"extra_cmake_args": "-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
|
||||
"toolchain": "nix",
|
||||
"build_only": true,
|
||||
"minimal": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
2
.github/workflows/build-nix-images.yml
vendored
2
.github/workflows/build-nix-images.yml
vendored
@@ -13,6 +13,7 @@ on:
|
||||
- "!nix/docker/README.md"
|
||||
- "!nix/devshell.nix"
|
||||
- "bin/check-tools.sh"
|
||||
- "bin/default-loader-path.sh"
|
||||
- "bin/install-sanitizer-libs.sh"
|
||||
pull_request:
|
||||
paths:
|
||||
@@ -24,6 +25,7 @@ on:
|
||||
- "!nix/docker/README.md"
|
||||
- "!nix/devshell.nix"
|
||||
- "bin/check-tools.sh"
|
||||
- "bin/default-loader-path.sh"
|
||||
- "bin/install-sanitizer-libs.sh"
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
3
.github/workflows/build-packaging-images.yml
vendored
3
.github/workflows/build-packaging-images.yml
vendored
@@ -36,8 +36,9 @@ jobs:
|
||||
distro:
|
||||
- name: debian
|
||||
base_image: debian:bookworm
|
||||
# AlmaLinux rather than UBI9, which does not ship rpm-sign.
|
||||
- name: rhel
|
||||
base_image: registry.access.redhat.com/ubi9/ubi:latest
|
||||
base_image: almalinux:9
|
||||
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@9e7e4e80af9e684c116b38369add8eea64451f32
|
||||
with:
|
||||
image_name: xrpld/packaging-${{ matrix.distro.name }}
|
||||
|
||||
2
.github/workflows/check-pr-description.yml
vendored
2
.github/workflows/check-pr-description.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Write PR body to file
|
||||
env:
|
||||
|
||||
114
.github/workflows/check-tools.yml
vendored
Normal file
114
.github/workflows/check-tools.yml
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
# Verifies the committed snapshots of `bin/check-tools.sh` output for each Nix
|
||||
# environment (see nix/check-tools/). If the environment changes — a new image
|
||||
# tag, an updated flake.lock, a different tool list — without the matching
|
||||
# snapshot being regenerated and committed, this workflow fails so the drift is
|
||||
# caught in review.
|
||||
#
|
||||
# To regenerate the snapshots, see nix/check-tools/README.md.
|
||||
name: Check tools
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/check-tools.yml"
|
||||
- ".github/scripts/strategy-matrix/linux.json"
|
||||
- "bin/check-tools.sh"
|
||||
- "nix/**"
|
||||
- "flake.nix"
|
||||
- "flake.lock"
|
||||
- "rust-toolchain.toml"
|
||||
push:
|
||||
branches:
|
||||
- "develop"
|
||||
paths:
|
||||
- ".github/workflows/check-tools.yml"
|
||||
- ".github/scripts/strategy-matrix/linux.json"
|
||||
- "bin/check-tools.sh"
|
||||
- "nix/**"
|
||||
- "flake.nix"
|
||||
- "flake.lock"
|
||||
- "rust-toolchain.toml"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
# The nix-nixos image tag is pinned alongside the build matrix in linux.json,
|
||||
# so snapshots are checked against the exact image CI builds against.
|
||||
linux-image-tag:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
tag: ${{ steps.tag.outputs.tag }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Read nix image tag
|
||||
id: tag
|
||||
run: echo "tag=$(jq -r .image_tag .github/scripts/strategy-matrix/linux.json)" >>"${GITHUB_OUTPUT}"
|
||||
|
||||
# One job for all environments; they differ only in whether the tools come
|
||||
# from the nix-nixos container (Linux) or `nix develop` (macOS).
|
||||
check-tools:
|
||||
needs: linux-image-tag
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- runner: ubuntu-latest
|
||||
snapshot: nix/check-tools/nix-ubuntu-amd64.txt
|
||||
nix_develop: false
|
||||
- runner: ubuntu-24.04-arm
|
||||
snapshot: nix/check-tools/nix-ubuntu-arm64.txt
|
||||
nix_develop: false
|
||||
- runner: macos-26-apple-clang-21
|
||||
snapshot: nix/check-tools/macos.txt
|
||||
nix_develop: true
|
||||
runs-on: ${{ matrix.runner }}
|
||||
# Linux runs inside the pinned nix-nixos image; macOS runs natively and uses
|
||||
# the flake's dev shell instead (see the run step below).
|
||||
container: ${{ !matrix.nix_develop && format('ghcr.io/xrplf/xrpld/nix-ubuntu:{0}', needs.linux-image-tag.outputs.tag) || null }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
- name: Regenerate snapshot
|
||||
env:
|
||||
CHECK_TOOLS_SKIP_CLONE: "1"
|
||||
# check-tools.sh skips some macOS tools when CI is set; the snapshots
|
||||
# capture the full `nix develop` environment, so unset it here.
|
||||
CI: ""
|
||||
run: |
|
||||
if [ "${{ matrix.nix_develop }}" = "true" ]; then
|
||||
# `nix develop` prints the dev-shell greeting first; keep only the
|
||||
# check-tools.sh output (from the "Detected OS:" line onward).
|
||||
nix --extra-experimental-features "nix-command flakes" develop \
|
||||
-c bash bin/check-tools.sh | sed -n '/^Detected OS:/,$p' >"${{ matrix.snapshot }}"
|
||||
else
|
||||
bash bin/check-tools.sh >"${{ matrix.snapshot }}"
|
||||
fi
|
||||
|
||||
- name: Verify snapshot is up to date
|
||||
run: |
|
||||
if ! git diff --exit-code -- "${{ matrix.snapshot }}"; then
|
||||
echo "::error::${{ matrix.snapshot }} is out of date. Regenerate it (see nix/check-tools/README.md) and commit the result."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Upload regenerated snapshot
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: check-tools-${{ runner.os }}-${{ runner.arch }}
|
||||
path: ${{ matrix.snapshot }}
|
||||
17
.github/workflows/on-pr.yml
vendored
17
.github/workflows/on-pr.yml
vendored
@@ -52,7 +52,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Determine changed files
|
||||
# This step checks whether any files have changed that should
|
||||
# cause the next jobs to run. We do it this way rather than
|
||||
@@ -77,11 +77,13 @@ jobs:
|
||||
|
||||
# Keep the paths below in sync with those in `on-trigger.yml`.
|
||||
.github/actions/build-deps/**
|
||||
.github/actions/generate-version/**
|
||||
.github/actions/release-info/**
|
||||
.github/actions/setup-conan/**
|
||||
.github/actions/setup-nix-env/**
|
||||
.github/scripts/strategy-matrix/**
|
||||
.github/workflows/reusable-build-test-config.yml
|
||||
.github/workflows/reusable-build-test.yml
|
||||
.github/workflows/reusable-check-autogen.yml
|
||||
.github/workflows/reusable-clang-tidy.yml
|
||||
.github/workflows/reusable-package.yml
|
||||
.github/workflows/reusable-strategy-matrix.yml
|
||||
@@ -89,7 +91,9 @@ jobs:
|
||||
.github/workflows/reusable-upload-recipe.yml
|
||||
.clang-tidy
|
||||
.codecov.yml
|
||||
bin/check-nix-store-refs.sh
|
||||
bin/check-tools.sh
|
||||
bin/default-loader-path.sh
|
||||
cfg/**
|
||||
cmake/**
|
||||
conan/**
|
||||
@@ -100,6 +104,9 @@ jobs:
|
||||
CMakeLists.txt
|
||||
conanfile.py
|
||||
conan.lock
|
||||
flake.lock
|
||||
flake.nix
|
||||
nix/**
|
||||
LICENSE.md
|
||||
package/**
|
||||
README.md
|
||||
@@ -125,6 +132,11 @@ jobs:
|
||||
outputs:
|
||||
go: ${{ steps.go.outputs.go == 'true' }}
|
||||
|
||||
check-autogen:
|
||||
needs: should-run
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
uses: ./.github/workflows/reusable-check-autogen.yml
|
||||
|
||||
check-levelization:
|
||||
needs: should-run
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
@@ -199,6 +211,7 @@ jobs:
|
||||
passed:
|
||||
if: failure() || cancelled()
|
||||
needs:
|
||||
- check-autogen
|
||||
- check-levelization
|
||||
- check-rename
|
||||
- clang-tidy
|
||||
|
||||
17
.github/workflows/on-tag.yml
vendored
17
.github/workflows/on-tag.yml
vendored
@@ -1,5 +1,9 @@
|
||||
# This workflow uploads the libxrpl recipe to the Conan remote and builds
|
||||
# release packages when a versioned tag is pushed.
|
||||
# When a versioned tag is pushed, this workflow:
|
||||
#
|
||||
# - uploads the libxrpl recipe to the Conan remote
|
||||
# - builds and tests the release binaries
|
||||
# - builds the DEB and RPM packages
|
||||
# - publishes those packages to the XRPLF package repositories
|
||||
name: Tag
|
||||
|
||||
on:
|
||||
@@ -24,7 +28,7 @@ jobs:
|
||||
remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }}
|
||||
|
||||
build-test:
|
||||
if: ${{ github.repository == 'XRPLF/rippled' }}
|
||||
if: ${{ github.repository_owner == 'XRPLF' }}
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
fail-fast: true
|
||||
@@ -37,6 +41,11 @@ jobs:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
package:
|
||||
if: ${{ github.repository == 'XRPLF/rippled' }}
|
||||
if: ${{ github.repository_owner == 'XRPLF' }}
|
||||
needs: build-test
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
with:
|
||||
publish: true
|
||||
secrets:
|
||||
remote_username: ${{ secrets.NEXUS_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }}
|
||||
|
||||
19
.github/workflows/on-trigger.yml
vendored
19
.github/workflows/on-trigger.yml
vendored
@@ -15,11 +15,13 @@ on:
|
||||
|
||||
# Keep the paths below in sync with those in `on-pr.yml`.
|
||||
- ".github/actions/build-deps/**"
|
||||
- ".github/actions/generate-version/**"
|
||||
- ".github/actions/release-info/**"
|
||||
- ".github/actions/setup-conan/**"
|
||||
- ".github/actions/setup-nix-env/**"
|
||||
- ".github/scripts/strategy-matrix/**"
|
||||
- ".github/workflows/reusable-build-test-config.yml"
|
||||
- ".github/workflows/reusable-build-test.yml"
|
||||
- ".github/workflows/reusable-check-autogen.yml"
|
||||
- ".github/workflows/reusable-clang-tidy.yml"
|
||||
- ".github/workflows/reusable-package.yml"
|
||||
- ".github/workflows/reusable-strategy-matrix.yml"
|
||||
@@ -27,7 +29,9 @@ on:
|
||||
- ".github/workflows/reusable-upload-recipe.yml"
|
||||
- ".clang-tidy"
|
||||
- ".codecov.yml"
|
||||
- "bin/check-nix-store-refs.sh"
|
||||
- "bin/check-tools.sh"
|
||||
- "bin/default-loader-path.sh"
|
||||
- "cfg/**"
|
||||
- "cmake/**"
|
||||
- "conan/**"
|
||||
@@ -38,6 +42,9 @@ on:
|
||||
- "CMakeLists.txt"
|
||||
- "conanfile.py"
|
||||
- "conan.lock"
|
||||
- "flake.lock"
|
||||
- "flake.nix"
|
||||
- "nix/**"
|
||||
- "LICENSE.md"
|
||||
- "package/**"
|
||||
- "README.md"
|
||||
@@ -66,6 +73,9 @@ defaults:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check-autogen:
|
||||
uses: ./.github/workflows/reusable-check-autogen.yml
|
||||
|
||||
clang-tidy:
|
||||
uses: ./.github/workflows/reusable-clang-tidy.yml
|
||||
permissions:
|
||||
@@ -103,3 +113,10 @@ jobs:
|
||||
package:
|
||||
needs: build-test
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
with:
|
||||
# Packages are built on every trigger; only develop pushes in XRPLF/rippled
|
||||
# publish them, matching upload-recipe above.
|
||||
publish: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' && github.ref == 'refs/heads/develop' }}
|
||||
secrets:
|
||||
remote_username: ${{ secrets.NEXUS_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }}
|
||||
|
||||
6
.github/workflows/publish-docs.yml
vendored
6
.github/workflows/publish-docs.yml
vendored
@@ -41,13 +41,13 @@ env:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3122de8
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-a0074f8
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@e4b6449d55a61c002d7c3fdfa6c20f721ede0606
|
||||
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
112
.github/workflows/reusable-build-test-config.yml
vendored
112
.github/workflows/reusable-build-test-config.yml
vendored
@@ -3,6 +3,12 @@ name: Build and test configuration
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
benchmark:
|
||||
description: "Whether to smoke-run the benchmarks after testing."
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
build_only:
|
||||
description: 'Whether to only build or to build and test the code ("true", "false").'
|
||||
required: true
|
||||
@@ -63,6 +69,12 @@ on:
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
toolchain:
|
||||
description: 'Where the toolchain comes from ("nix" to build the flake CI environment on the runner, empty for the system one). macOS only: Linux always builds in a Nix image, and Nix has no Windows support.'
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
secrets:
|
||||
CODECOV_TOKEN:
|
||||
description: "The Codecov token to use for uploading coverage reports."
|
||||
@@ -100,23 +112,32 @@ 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 != '' }}
|
||||
# The binaries reusable-package.yml consumes. A private repository skips
|
||||
# them except on a tag push, which is what produces its release packages.
|
||||
PACKAGING_ARTIFACTS_ENABLED: ${{ github.event.repository.visibility == 'public' || startsWith(github.ref, 'refs/tags/') }}
|
||||
steps:
|
||||
- name: Cleanup workspace (macOS and Windows)
|
||||
if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }}
|
||||
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@e4b6449d55a61c002d7c3fdfa6c20f721ede0606
|
||||
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
|
||||
with:
|
||||
enable_ccache: ${{ inputs.ccache_enabled }}
|
||||
|
||||
# Before any step that uses a build tool, composite actions included.
|
||||
- name: Setup Nix environment
|
||||
if: ${{ inputs.toolchain == 'nix' }}
|
||||
uses: ./.github/actions/setup-nix-env
|
||||
|
||||
- name: Set ccache log file
|
||||
if: ${{ inputs.ccache_enabled && runner.debug == '1' }}
|
||||
run: echo "CCACHE_LOGFILE=${{ runner.temp }}/ccache.log" >>"${GITHUB_ENV}"
|
||||
@@ -141,7 +162,9 @@ jobs:
|
||||
with:
|
||||
compiler: ${{ inputs.compiler }}
|
||||
|
||||
# `setup-nix-env` already did this for the Nix toolchain.
|
||||
- name: Setup Conan
|
||||
if: ${{ inputs.toolchain != 'nix' }}
|
||||
env:
|
||||
SANITIZERS: ${{ inputs.sanitizers }}
|
||||
uses: ./.github/actions/setup-conan
|
||||
@@ -170,9 +193,9 @@ jobs:
|
||||
..
|
||||
|
||||
# Export the sanitizer options before any instrumented binary runs. The
|
||||
# protocol code-gen and build steps below invoke instrumented dependency
|
||||
# tools (protoc, grpc), so setting UBSAN_OPTIONS here lets the UBSan
|
||||
# suppression list silence their diagnostics too, not just at test time.
|
||||
# build step below invokes instrumented dependency tools (protoc, grpc),
|
||||
# so setting UBSAN_OPTIONS here lets the UBSan suppression list silence
|
||||
# their diagnostics too, not just at test time.
|
||||
# GITHUB_WORKSPACE (not the github.workspace context) is used so the path
|
||||
# resolves correctly inside the container job.
|
||||
- name: Set sanitizer options
|
||||
@@ -190,32 +213,6 @@ jobs:
|
||||
echo "UBSAN_OPTIONS=include=${SUPP}/runtime-ubsan-options.txt:suppressions=${SUPP}/ubsan.supp" >>${GITHUB_ENV}
|
||||
echo "LSAN_OPTIONS=include=${SUPP}/runtime-lsan-options.txt:suppressions=${SUPP}/lsan.supp" >>${GITHUB_ENV}
|
||||
|
||||
- name: Check protocol autogen files are up-to-date
|
||||
working-directory: ${{ env.BUILD_DIR }}
|
||||
env:
|
||||
MESSAGE: |
|
||||
|
||||
The generated protocol wrapper classes are out of date.
|
||||
|
||||
This typically happens when the macro files or generator scripts
|
||||
have changed but the generated files were not regenerated.
|
||||
|
||||
To fix this:
|
||||
1. Run: cmake --build . --target setup_code_gen
|
||||
2. Run: cmake --build . --target code_gen
|
||||
3. Commit and push the regenerated files
|
||||
run: |
|
||||
set -e
|
||||
cmake --build . --target setup_code_gen
|
||||
cmake --build . --target code_gen
|
||||
DIFF=$(git -C .. status --porcelain -- include/xrpl/protocol_autogen src/tests/libxrpl/protocol_autogen)
|
||||
if [ -n "${DIFF}" ]; then
|
||||
echo "::error::Generated protocol files are out of date"
|
||||
git -C .. diff -- include/xrpl/protocol_autogen src/tests/libxrpl/protocol_autogen
|
||||
echo "${MESSAGE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build the binary
|
||||
working-directory: ${{ env.BUILD_DIR }}
|
||||
env:
|
||||
@@ -231,6 +228,24 @@ jobs:
|
||||
--target "${CMAKE_TARGET}" \
|
||||
2>&1 | tee "${GITHUB_WORKSPACE}/build.log"
|
||||
|
||||
# Nothing may reference the store, so whole trees are checked - the Conan
|
||||
# cache included, since what it holds is what gets uploaded and reused.
|
||||
- name: Check the build output for Nix store references (Nix toolchain)
|
||||
if: ${{ inputs.toolchain == 'nix' }}
|
||||
run: ./bin/check-nix-store-refs.sh "${BUILD_DIR}"
|
||||
|
||||
- name: Check the Conan cache for Nix store references (Nix toolchain)
|
||||
if: ${{ inputs.toolchain == 'nix' }}
|
||||
run: ./bin/check-nix-store-refs.sh "${CONAN_HOME}"
|
||||
|
||||
# Only what PatchNixBinary.cmake retargets: the toolchain in the Linux
|
||||
# images always references the store. Same condition it uses.
|
||||
- name: Check for Nix store references (Linux)
|
||||
if: ${{ runner.os == 'Linux' && env.SANITIZERS_ENABLED == 'false' }}
|
||||
run: |
|
||||
./bin/check-nix-store-refs.sh "${BUILD_DIR}/xrpld"
|
||||
./bin/check-nix-store-refs.sh "${BUILD_DIR}/xrpl_tests"
|
||||
|
||||
- name: Show ccache statistics
|
||||
if: ${{ inputs.ccache_enabled }}
|
||||
run: |
|
||||
@@ -241,7 +256,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Upload the binary (Linux)
|
||||
if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }}
|
||||
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && runner.os == 'Linux' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: xrpld-${{ inputs.config_name }}
|
||||
@@ -249,6 +264,22 @@ jobs:
|
||||
retention-days: 3
|
||||
if-no-files-found: error
|
||||
|
||||
- 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
|
||||
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && env.VALIDATOR_KEYS_ENABLED == 'true' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: validator-keys-${{ inputs.config_name }}
|
||||
path: |
|
||||
${{ env.BUILD_DIR }}/validator-keys
|
||||
${{ env.BUILD_DIR }}/validator-keys-LICENSE
|
||||
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
|
||||
@@ -266,7 +297,7 @@ jobs:
|
||||
./xrpld --definitions | python3 -m json.tool >server_definitions.json
|
||||
|
||||
- name: Upload server definitions
|
||||
if: ${{ github.event.repository.visibility == 'public' && inputs.config_name == 'debian-gcc-release-amd64' }}
|
||||
if: ${{ github.event.repository.visibility == 'public' && inputs.config_name == 'ubuntu-gcc-debug-amd64-coverage' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: server-definitions
|
||||
@@ -328,11 +359,14 @@ jobs:
|
||||
|
||||
# Smoke-run every benchmark module with a single repetition to confirm the
|
||||
# benchmarks still build and execute. This is a correctness check, not a
|
||||
# performance measurement, so it is skipped for instrumented builds
|
||||
# (sanitizers/coverage/voidstar), where it would be slow and meaningless,
|
||||
# and on Windows, where the `install` target does not build them.
|
||||
# performance measurement, so there is nothing to gain from repeating it
|
||||
# across configurations: it is opted into by a single config in the
|
||||
# strategy matrix (see the 'benchmark' flag in the JSON files), which
|
||||
# keeps it off instrumented builds (sanitizers/coverage/voidstar), where
|
||||
# it would be slow and meaningless, off Debug builds, where it is much
|
||||
# slower, and off Windows, where the `install` target does not build them.
|
||||
- name: Run the benchmarks
|
||||
if: ${{ !inputs.build_only && runner.os != 'Windows' && env.SANITIZERS_ENABLED == 'false' && env.COVERAGE_ENABLED != 'true' && env.VOIDSTAR_ENABLED != 'true' }}
|
||||
if: ${{ inputs.benchmark }}
|
||||
working-directory: ${{ env.BUILD_DIR }}
|
||||
run: |
|
||||
rc=0
|
||||
@@ -387,7 +421,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
|
||||
|
||||
2
.github/workflows/reusable-build-test.yml
vendored
2
.github/workflows/reusable-build-test.yml
vendored
@@ -40,6 +40,7 @@ jobs:
|
||||
fail-fast: ${{ github.event_name == 'merge_group' }}
|
||||
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
|
||||
with:
|
||||
benchmark: ${{ matrix.benchmark }}
|
||||
build_only: ${{ matrix.build_only }}
|
||||
build_type: ${{ matrix.build_type }}
|
||||
ccache_enabled: ${{ inputs.ccache_enabled }}
|
||||
@@ -50,5 +51,6 @@ jobs:
|
||||
config_name: ${{ matrix.config_name }}
|
||||
sanitizers: ${{ matrix.sanitizers }}
|
||||
compiler: ${{ matrix.compiler || '' }}
|
||||
toolchain: ${{ matrix.toolchain || '' }}
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
76
.github/workflows/reusable-check-autogen.yml
vendored
Normal file
76
.github/workflows/reusable-check-autogen.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# This workflow checks that the generated protocol wrapper classes are
|
||||
# up-to-date with the macro files and generator scripts they are produced from,
|
||||
# see more info in include/xrpl/protocol_autogen/README.md.
|
||||
name: Check autogen
|
||||
|
||||
# This workflow can only be triggered by other workflows.
|
||||
on: workflow_call
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-autogen
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
env:
|
||||
BUILD_DIR: build/codegen
|
||||
|
||||
jobs:
|
||||
autogen:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||
with:
|
||||
python-version: "3.13"
|
||||
|
||||
# Code generation is pure Python, so the standalone project below offers
|
||||
# the same targets as the main build without needing its dependencies or
|
||||
# a compiler, which keeps this job down to a few seconds.
|
||||
- name: Configure CMake
|
||||
run: cmake -S cmake/codegen -B "${BUILD_DIR}"
|
||||
|
||||
- name: Install code generation dependencies
|
||||
run: cmake --build "${BUILD_DIR}" --target setup_code_gen
|
||||
|
||||
- name: Generate code
|
||||
run: cmake --build "${BUILD_DIR}" --target code_gen
|
||||
|
||||
- name: Check for differences
|
||||
env:
|
||||
MESSAGE: |
|
||||
|
||||
The generated protocol wrapper classes are out of date.
|
||||
|
||||
This typically happens when the macro files or generator scripts
|
||||
have changed but the generated files were not regenerated.
|
||||
|
||||
Run the following from the repository root, then commit and push
|
||||
the regenerated files. This needs neither the dependencies nor a
|
||||
compiler. See include/xrpl/protocol_autogen/README.md for more info.
|
||||
|
||||
cmake -S cmake/codegen -B build/codegen
|
||||
cmake --build build/codegen --target setup_code_gen
|
||||
cmake --build build/codegen --target code_gen
|
||||
|
||||
In an already configured build directory, the 'setup_code_gen' and
|
||||
'code_gen' targets do the same thing.
|
||||
run: |
|
||||
# Record untracked files in the index without staging their contents,
|
||||
# so that classes generated for a newly added transaction or ledger
|
||||
# entry type show up in the diff below rather than silently as an
|
||||
# empty one.
|
||||
git add --intent-to-add .
|
||||
DIFF=$(git status --porcelain)
|
||||
if [ -n "${DIFF}" ]; then
|
||||
# Print the differences to give the contributor a hint about what to
|
||||
# expect when running code generation on their own machine.
|
||||
git diff
|
||||
echo "${MESSAGE}"
|
||||
exit 1
|
||||
fi
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Check levelization
|
||||
run: python .github/scripts/levelization/generate.py
|
||||
- name: Check for differences
|
||||
|
||||
2
.github/workflows/reusable-check-rename.yml
vendored
2
.github/workflows/reusable-check-rename.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Check definitions
|
||||
run: .github/scripts/rename/definitions.sh .
|
||||
- name: Check copyright notices
|
||||
|
||||
8
.github/workflows/reusable-clang-tidy.yml
vendored
8
.github/workflows/reusable-clang-tidy.yml
vendored
@@ -34,16 +34,16 @@ jobs:
|
||||
needs: [determine-files]
|
||||
if: ${{ needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.need_full_run == 'true' }}
|
||||
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
|
||||
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-3122de8"
|
||||
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-a0074f8"
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@e4b6449d55a61c002d7c3fdfa6c20f721ede0606
|
||||
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
@@ -95,7 +95,7 @@ jobs:
|
||||
TARGETS: ${{ needs.determine-files.outputs.need_full_run != 'true' && needs.determine-files.outputs.cpp_changed_files || 'include src tests' }}
|
||||
run: |
|
||||
set -o pipefail
|
||||
run-clang-tidy -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" -quiet -fix -allow-no-checks ${TARGETS} 2>&1 | tee "${OUTPUT_FILE}"
|
||||
run-clang-tidy -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" -quiet -fix -format -allow-no-checks ${TARGETS} 2>&1 | tee "${OUTPUT_FILE}"
|
||||
|
||||
- name: Print filtered clang-tidy errors
|
||||
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
|
||||
|
||||
71
.github/workflows/reusable-package.yml
vendored
71
.github/workflows/reusable-package.yml
vendored
@@ -1,17 +1,34 @@
|
||||
# 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 from the pre-built xrpld and validator-keys artifacts:
|
||||
#
|
||||
# - one job per distro, taken from "package_configs" in linux.json
|
||||
# - each job runs in that distro's container, which is what decides DEB or RPM
|
||||
# - with 'publish: true' a job also uploads what it built
|
||||
# (see package/publish_pkg.sh)
|
||||
#
|
||||
# Only linux/amd64 is supported; the runner is hardcoded in the job below.
|
||||
name: Package
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
pkg_release:
|
||||
description: "Package release number. Increment when repackaging the same executable."
|
||||
publish:
|
||||
description: "Whether to publish the packages after building them."
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
nexus_url:
|
||||
description: "The base URL of the Nexus instance hosting the deb and rpm repositories."
|
||||
required: false
|
||||
type: string
|
||||
default: "1"
|
||||
default: https://packages.xrplf.org
|
||||
|
||||
secrets:
|
||||
remote_username:
|
||||
description: "The username of a Nexus account with write access to the repositories."
|
||||
required: false
|
||||
remote_password:
|
||||
description: "The password or token for that Nexus account."
|
||||
required: false
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -27,7 +44,7 @@ jobs:
|
||||
matrix: ${{ steps.generate.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||
@@ -41,11 +58,11 @@ jobs:
|
||||
|
||||
package:
|
||||
needs: [generate-matrix]
|
||||
if: ${{ github.event.repository.visibility == 'public' }}
|
||||
if: ${{ github.event.repository.visibility == 'public' || startsWith(github.ref, 'refs/tags/') }}
|
||||
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"]
|
||||
@@ -54,28 +71,48 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Download pre-built binary
|
||||
- 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: 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: Determine release info
|
||||
id: release_info
|
||||
uses: ./.github/actions/release-info
|
||||
|
||||
- name: Build package
|
||||
env:
|
||||
PKG_RELEASE: ${{ inputs.pkg_release }}
|
||||
PKG_RELEASE: ${{ steps.release_info.outputs.pkg_release }}
|
||||
PKG_CHANNEL: ${{ steps.release_info.outputs.channel }}
|
||||
run: ./package/build_pkg.sh
|
||||
|
||||
- name: Upload package artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: ${{ matrix.artifact_name }}-pkg
|
||||
name: ${{ matrix.xrpld_artifact_name }}-pkg
|
||||
path: |
|
||||
${{ env.BUILD_DIR }}/debbuild/*.deb
|
||||
${{ env.BUILD_DIR }}/debbuild/*.ddeb
|
||||
${{ env.BUILD_DIR }}/rpmbuild/RPMS/**/*.rpm
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Publish package
|
||||
if: ${{ inputs.publish }}
|
||||
env:
|
||||
CHANNEL: ${{ steps.release_info.outputs.channel }}
|
||||
NEXUS_URL: ${{ inputs.nexus_url }}
|
||||
NEXUS_USERNAME: ${{ secrets.remote_username }}
|
||||
NEXUS_PASSWORD: ${{ secrets.remote_password }}
|
||||
run: ./package/publish_pkg.sh "${CHANNEL}" "${BUILD_DIR}"
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
matrix: ${{ steps.generate.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||
|
||||
16
.github/workflows/reusable-upload-recipe.yml
vendored
16
.github/workflows/reusable-upload-recipe.yml
vendored
@@ -40,18 +40,18 @@ defaults:
|
||||
jobs:
|
||||
upload:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-3122de8
|
||||
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-a0074f8
|
||||
env:
|
||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||
CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.remote_username }}
|
||||
CONAN_PASSWORD_XRPLF: ${{ secrets.remote_password }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Generate build version number
|
||||
id: version
|
||||
uses: ./.github/actions/generate-version
|
||||
- name: Determine release info
|
||||
id: release_info
|
||||
uses: ./.github/actions/release-info
|
||||
|
||||
- name: Set up Conan
|
||||
uses: ./.github/actions/setup-conan
|
||||
@@ -64,8 +64,8 @@ jobs:
|
||||
|
||||
- name: Upload Conan recipe (version)
|
||||
run: |
|
||||
conan export . --version=${{ steps.version.outputs.version }}
|
||||
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/${{ steps.version.outputs.version }}
|
||||
conan export . --version=${{ steps.release_info.outputs.version }}
|
||||
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/${{ steps.release_info.outputs.version }}
|
||||
|
||||
# When this workflow is triggered by a push event, it will always be when merging into the
|
||||
# 'develop' branch, see on-trigger.yml.
|
||||
@@ -92,4 +92,4 @@ jobs:
|
||||
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/release
|
||||
|
||||
outputs:
|
||||
ref: xrpl/${{ steps.version.outputs.version }}
|
||||
ref: xrpl/${{ steps.release_info.outputs.version }}
|
||||
|
||||
15
.github/workflows/upload-conan-deps.yml
vendored
15
.github/workflows/upload-conan-deps.yml
vendored
@@ -65,13 +65,18 @@ jobs:
|
||||
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@e4b6449d55a61c002d7c3fdfa6c20f721ede0606
|
||||
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
# Before any step that uses a build tool, composite actions included.
|
||||
- name: Setup Nix environment
|
||||
if: ${{ matrix.toolchain == 'nix' }}
|
||||
uses: ./.github/actions/setup-nix-env
|
||||
|
||||
- name: Print build environment
|
||||
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
|
||||
|
||||
@@ -87,7 +92,9 @@ jobs:
|
||||
with:
|
||||
compiler: ${{ matrix.compiler }}
|
||||
|
||||
# `setup-nix-env` already did this for the Nix toolchain.
|
||||
- name: Setup Conan
|
||||
if: ${{ matrix.toolchain != 'nix' }}
|
||||
env:
|
||||
SANITIZERS: ${{ matrix.sanitizers }}
|
||||
uses: ./.github/actions/setup-conan
|
||||
@@ -106,6 +113,10 @@ jobs:
|
||||
log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
|
||||
sanitizers: ${{ matrix.sanitizers }}
|
||||
|
||||
- name: Check the Conan cache for Nix store references (Nix toolchain)
|
||||
if: ${{ matrix.toolchain == 'nix' }}
|
||||
run: ./bin/check-nix-store-refs.sh "${CONAN_HOME}"
|
||||
|
||||
- name: Log into Conan remote
|
||||
if: ${{ github.repository == 'XRPLF/rippled' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
|
||||
run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.NEXUS_REMOTE_USERNAME }}" --password "${{ secrets.NEXUS_REMOTE_PASSWORD }}"
|
||||
|
||||
@@ -42,6 +42,7 @@ This section contains changes targeting a future version.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- `get_aggregate_price`: Duplicate entries in the `oracles` request array are now ignored. [#6586](https://github.com/XRPLF/rippled/pull/6586)
|
||||
- Peer Crawler: The `port` field in `overlay.active[]` now consistently returns an integer instead of a string for outbound peers. [#6318](https://github.com/XRPLF/rippled/pull/6318)
|
||||
- `ping`: The `ip` field is no longer returned as an empty string for proxied connections without a forwarded-for header. It is now omitted, consistent with the behavior for identified connections. [#6730](https://github.com/XRPLF/rippled/pull/6730)
|
||||
- gRPC `GetLedgerDiff`: Fixed error message that incorrectly said "base ledger not validated" when the desired ledger was not validated. [#6730](https://github.com/XRPLF/rippled/pull/6730)
|
||||
@@ -53,6 +54,8 @@ This section contains changes targeting a future version.
|
||||
- `submit`: The `fail_hard` field now returns an error if the value is not a boolean. [#6529](https://github.com/XRPLF/rippled/pull/6529)
|
||||
- `subscribe`: The `taker` field in the `books` array now returns `actMalformed` instead of `badIssuer` if the value is not a valid account. [#6529](https://github.com/XRPLF/rippled/pull/6529)
|
||||
- Fixed a bug in `Forwarded` HTTP header parsing where the extracted IP address could be incorrect when no comma or semicolon delimiter follows the address. This could cause the server to misidentify a client's IP address when operating behind a reverse proxy. [#6529](https://github.com/XRPLF/rippled/pull/6529)
|
||||
- `gateway_balances`: The `account` and `ident` fields now return an `invalidParams` error if the value is not a string, instead of an `internal` error. [#7655](https://github.com/XRPLF/rippled/pull/7655)
|
||||
- `account_lines`: The `peer` field now returns an error if the value is not a string. [#7728](https://github.com/XRPLF/rippled/pull/7728)
|
||||
|
||||
## XRP Ledger server version 3.1.0
|
||||
|
||||
|
||||
100
BUILD.md
100
BUILD.md
@@ -4,34 +4,14 @@
|
||||
|
||||
## Minimum Requirements
|
||||
|
||||
See [System Requirements](https://xrpl.org/system-requirements.html).
|
||||
For the hardware needed to run a node, see
|
||||
[System Requirements](https://xrpl.org/system-requirements.html).
|
||||
|
||||
Building xrpld generally requires Git, Python, Conan, CMake, and a C++
|
||||
compiler.
|
||||
|
||||
- [Python](https://www.python.org/downloads/)
|
||||
- [Conan](https://conan.io/downloads.html)
|
||||
- [CMake](https://cmake.org/download/)
|
||||
|
||||
You can verify that the required tools are installed and runnable with:
|
||||
|
||||
```bash
|
||||
./bin/check-tools.sh
|
||||
```
|
||||
|
||||
`xrpld` is written in the C++23 dialect. The [tested compiler versions][cpp23-support] are:
|
||||
|
||||
| Compiler | Version |
|
||||
| ----------- | --------------- |
|
||||
| GCC | 15.2 |
|
||||
| Clang | 22 |
|
||||
| Apple Clang | 21 |
|
||||
| MSVC | 19.44[^windows] |
|
||||
For the software needed to build xrpld, see the
|
||||
[environment setup guide](./docs/build/environment.md).
|
||||
|
||||
## Operating Systems
|
||||
|
||||
Please see the [environment setup guide](./docs/build/environment.md) for detailed instructions for all platforms.
|
||||
|
||||
### Linux
|
||||
|
||||
The Ubuntu Linux distribution has received the highest level of quality
|
||||
@@ -42,12 +22,13 @@ Our Linux CI tooling is distro-independent and uses a Nix-based environment, so
|
||||
### macOS
|
||||
|
||||
Many `xrpld` engineers use macOS for development.
|
||||
The minimum supported version is macOS 15 (Sequoia).
|
||||
CI testing is done in macOS 26 (Tahoe), but the build defaults `CMAKE_OSX_DEPLOYMENT_TARGET` to 15.
|
||||
|
||||
### Windows
|
||||
|
||||
Windows is used by some engineers for development only.
|
||||
|
||||
[^windows]: Windows is not recommended for production use.
|
||||
Windows is used by some engineers for development only, and is not recommended
|
||||
for production use.
|
||||
|
||||
## Steps
|
||||
|
||||
@@ -72,37 +53,25 @@ releases](https://github.com/XRPLF/rippled/releases).
|
||||
|
||||
### Set Up Conan
|
||||
|
||||
After you have a [C++ development environment](./docs/build/environment.md) ready with Git, Python,
|
||||
Conan, CMake, and a C++ compiler, you may need to set up your Conan profile.
|
||||
|
||||
These instructions assume a basic familiarity with Conan and CMake. If you are
|
||||
unfamiliar with Conan, then please read [this crash course](./docs/build/conan.md) or the official
|
||||
[Getting Started][conan-getting-started] walkthrough.
|
||||
|
||||
#### Profiles
|
||||
|
||||
We recommend that you install our Conan profiles:
|
||||
Once your [development environment](./docs/build/environment.md) is ready, set
|
||||
Conan up for this repository:
|
||||
|
||||
```bash
|
||||
conan config install conan/profiles/ -tf $(conan config home)/profiles/
|
||||
./conan/init.sh
|
||||
```
|
||||
|
||||
You can check your Conan profile by running:
|
||||
That installs our [`global.conf`](./conan/global.conf), our Conan
|
||||
[profiles](./conan/profiles), and the `xrplf` remote that hosts some of our
|
||||
dependencies. It honours `CONAN_HOME` and never deletes an existing Conan home,
|
||||
so it is safe to re-run — it only overwrites the files it manages.
|
||||
|
||||
```bash
|
||||
conan profile show
|
||||
```
|
||||
> [!TIP]
|
||||
> In the [Nix development shell](./docs/build/nix.md#conan-configuration) this is
|
||||
> already done for you: the script runs on entry.
|
||||
|
||||
If the default profile is not suitable for your environment, you can create a custom profile and pass it to Conan.
|
||||
More information on customizing Conan can be found in the [Advanced Conan configuration](./docs/build/advanced_conan.md).
|
||||
|
||||
#### Add xrplf remote
|
||||
|
||||
Run the following command to add the `xrplf` remote, which hosts some of our dependencies:
|
||||
|
||||
```bash
|
||||
conan remote add --index 0 --force xrplf https://conan.xrplf.org/repository/conan/
|
||||
```
|
||||
You can inspect the resulting profile with `conan profile show`. If it is not
|
||||
suitable for your environment, create a custom profile and pass it to Conan — see
|
||||
[Advanced Conan configuration](./docs/build/advanced_conan.md).
|
||||
|
||||
### Set Up Ccache
|
||||
|
||||
@@ -245,7 +214,17 @@ cmake --build . --target setup_code_gen # create venv and install dependencies
|
||||
cmake --build . --target code_gen # regenerate code
|
||||
```
|
||||
|
||||
The regenerated files should be committed alongside your changes.
|
||||
The same targets are also available as a standalone project, which does not
|
||||
need the dependencies to be configured first:
|
||||
|
||||
```
|
||||
cmake -S cmake/codegen -B build/codegen
|
||||
cmake --build build/codegen --target setup_code_gen
|
||||
cmake --build build/codegen --target code_gen
|
||||
```
|
||||
|
||||
The regenerated files should be committed alongside your changes. CI verifies
|
||||
that they are up-to-date.
|
||||
|
||||
## Coverage report
|
||||
|
||||
@@ -257,10 +236,14 @@ which is only enabled when the `coverage` option is set, e.g. with
|
||||
Prerequisites for the coverage report:
|
||||
|
||||
- [gcovr tool][gcovr] (can be installed e.g. with [pip][python-pip])
|
||||
- `gcov` for GCC (installed with the compiler by default) or
|
||||
- `llvm-cov` for Clang (installed with the compiler by default)
|
||||
- `gcov` for GCC or `llvm-cov` for Clang, usually installed with the compiler
|
||||
- `Debug` build type
|
||||
|
||||
> [!NOTE]
|
||||
> Clang coverage is not available in the [Nix development shell](./docs/build/nix.md#building-xrpld-in-the-nix-shell):
|
||||
> its `clang` shells do not ship `llvm-cov`. Use a `gcc` shell instead (`.#gcc`,
|
||||
> or `.#gcc-plain` on Linux), which provides a `gcov` matching its compiler.
|
||||
|
||||
A coverage report is created when the following steps are completed, in order:
|
||||
|
||||
1. `xrpld` binary built with instrumentation data, enabled by the `coverage`
|
||||
@@ -377,10 +360,14 @@ After any updates or changes to dependencies, you may need to do the following:
|
||||
4. [Regenerate lockfile](./docs/build/advanced_conan.md#conan-lockfile).
|
||||
5. Re-run [conan install](#build-and-test).
|
||||
|
||||
If you are using the Nix development shell, whether prebuilt Conan binaries apply
|
||||
depends on your platform — see
|
||||
[Prebuilt packages](./docs/build/nix.md#prebuilt-packages).
|
||||
|
||||
#### ERROR: Package not resolved
|
||||
|
||||
If you're seeing an error like `ERROR: Package 'snappy/1.1.10' not resolved: Unable to find 'snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1756234314.246' in remotes.`,
|
||||
please [add `xrplf` remote](#add-xrplf-remote) or re-run `conan export` for [patched recipes](./docs/build/advanced_conan.md#patched-recipes).
|
||||
please [set Conan up](#set-up-conan) so the `xrplf` remote is configured, or re-run `conan export` for [patched recipes](./docs/build/advanced_conan.md#patched-recipes).
|
||||
|
||||
### `protobuf/port_def.inc` file not found
|
||||
|
||||
@@ -400,7 +387,6 @@ For example, if you want to build Debug:
|
||||
1. For conan install, pass `--settings build_type=Debug`
|
||||
2. For cmake, pass `-DCMAKE_BUILD_TYPE=Debug`
|
||||
|
||||
[cpp23-support]: https://en.cppreference.com/w/cpp/compiler_support/23
|
||||
[conan-getting-started]: https://docs.conan.io/en/latest/getting_started.html
|
||||
[unity-build]: https://en.wikipedia.org/wiki/Unity_build
|
||||
[gcovr]: https://gcovr.com/en/stable/getting-started.html
|
||||
|
||||
@@ -13,6 +13,23 @@ if(DEFINED CMAKE_MODULE_PATH)
|
||||
endif()
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
# Must be set before project() because project() consumes it when configuring the compiler and SDK.
|
||||
# A user-provided -DCMAKE_OSX_DEPLOYMENT_TARGET still takes precedence.
|
||||
#
|
||||
# CMAKE_SYSTEM_NAME can't be used before project(), so CMAKE_HOST_SYSTEM_NAME is used instead.
|
||||
#
|
||||
# When CMAKE_OSX_DEPLOYMENT_TARGET is bumped to >=26.0, FastFloat dependency won't be needed anymore
|
||||
if(
|
||||
CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin"
|
||||
AND NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET
|
||||
)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET
|
||||
"15.0"
|
||||
CACHE STRING
|
||||
"Minimum macOS deployment version"
|
||||
)
|
||||
endif()
|
||||
|
||||
project(xrpl)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
@@ -87,6 +104,7 @@ include(deps/Boost)
|
||||
add_subdirectory(external/antithesis-sdk)
|
||||
find_package(date REQUIRED)
|
||||
find_package(ed25519 REQUIRED)
|
||||
find_package(FastFloat REQUIRED)
|
||||
find_package(gRPC REQUIRED)
|
||||
find_package(LibArchive REQUIRED)
|
||||
find_package(lz4 REQUIRED)
|
||||
@@ -102,6 +120,7 @@ target_link_libraries(
|
||||
xrpl_libs
|
||||
INTERFACE
|
||||
ed25519::ed25519
|
||||
FastFloat::fast_float
|
||||
lz4::lz4
|
||||
mpt-crypto::mpt-crypto
|
||||
OpenSSL::Crypto
|
||||
@@ -142,8 +161,10 @@ endif()
|
||||
include(XrplCore)
|
||||
include(XrplProtocolAutogen)
|
||||
include(XrplInstall)
|
||||
include(XrplPackaging)
|
||||
include(XrplValidatorKeys)
|
||||
# Must come after XrplValidatorKeys: the 'package' target depends on the
|
||||
# validator-keys target existing.
|
||||
include(XrplPackaging)
|
||||
|
||||
if(tests)
|
||||
include(CTest)
|
||||
|
||||
@@ -348,12 +348,14 @@ run-clang-tidy -p build -allow-no-checks 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:
|
||||
If you wish to automatically fix whatever clang-tidy finds _and_ is capable of fixing, add `-fix -format` to the above command:
|
||||
|
||||
```
|
||||
run-clang-tidy -p build -quiet -fix -allow-no-checks src tests
|
||||
run-clang-tidy -p build -quiet -fix -format -allow-no-checks src tests
|
||||
```
|
||||
|
||||
`-format` reformats the fixed code with [`.clang-format`](./.clang-format); without it the fixes are inserted in LLVM style and the `clang-format` hook rewrites them afterwards.
|
||||
|
||||
## Contracts and instrumentation
|
||||
|
||||
We are using [Antithesis](https://antithesis.com/) for continuous fuzzing,
|
||||
|
||||
111
bin/check-nix-store-refs.sh
Executable file
111
bin/check-nix-store-refs.sh
Executable file
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fail if a binary under <path> records a /nix/store path it resolves at run
|
||||
# time. See docs/build/nix.md#prebuilt-packages for why that matters.
|
||||
#
|
||||
# <path> is a file or a directory. macOS: nothing may reference the store, so
|
||||
# point it at whole trees. Linux: the toolchain always writes the store into
|
||||
# PT_INTERP and RUNPATH, so only at what cmake/PatchNixBinary.cmake retargets.
|
||||
#
|
||||
# Only Mach-O / ELF is inspected. Static archives hold store paths in debug info
|
||||
# alone; the scripts in a Conan cache are all git hook samples and autotools
|
||||
# scratch, 36 false positives to 0 real.
|
||||
#
|
||||
# Usage: bin/check-nix-store-refs.sh <path>
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "usage: $0 <path>" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ ! -e "$1" ]; then
|
||||
echo "$0: no such path: $1" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "$(uname -s)" in
|
||||
Darwin)
|
||||
format=Mach-O
|
||||
recorded_paths=macho_recorded_paths
|
||||
tool=otool
|
||||
;;
|
||||
Linux)
|
||||
format=ELF
|
||||
recorded_paths=elf_recorded_paths
|
||||
tool=readelf
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported OS - skipping the Nix store reference check."
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# `pipefail` would catch this too, but only as a bare nonzero exit.
|
||||
if ! command -v "${tool}" >/dev/null; then
|
||||
echo "$0: ${tool} not found; cannot inspect binaries" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Both list what the file records. `ldd` would answer what this machine resolves
|
||||
# now, which is wrong both ways: store paths for a correctly patched binary,
|
||||
# silence for a store RUNPATH that resolves nowhere.
|
||||
|
||||
# `name` covers LC_ID_DYLIB and LC_LOAD*_DYLIB, `path` covers LC_RPATH.
|
||||
macho_recorded_paths() {
|
||||
otool -l "$1" | sed -nE 's#^ *(name|path) ([^ ]*).*#\2#p'
|
||||
}
|
||||
|
||||
# RPATH and RUNPATH are colon-separated.
|
||||
elf_recorded_paths() {
|
||||
readelf -ldW "$1" |
|
||||
sed -nE \
|
||||
-e 's#.*program interpreter: ([^]]*)\].*#\1#p' \
|
||||
-e 's#.*\((RPATH|RUNPATH|NEEDED)\).*\[([^]]*)\].*#\2#p' |
|
||||
tr ':' '\n'
|
||||
}
|
||||
|
||||
checked=0
|
||||
skipped=0
|
||||
leaked=0
|
||||
|
||||
while IFS= read -r file; do
|
||||
case "$(file -b "${file}" 2>/dev/null)" in
|
||||
*"${format}"*) ;;
|
||||
*)
|
||||
skipped=$((skipped + 1))
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
checked=$((checked + 1))
|
||||
|
||||
# Filter after extracting, or a search path starting elsewhere ($ORIGIN)
|
||||
# hides the rest. `sed` not `grep`: grep calls "no matches" a failure, and
|
||||
# the `|| true` that would need masks a broken pipeline too.
|
||||
refs="$("${recorded_paths}" "${file}" | sed -n '\#^/nix/store/#p' | sort -u)"
|
||||
if [ -n "${refs}" ]; then
|
||||
leaked=$((leaked + 1))
|
||||
echo "::error file=${file}::references the Nix store at run time"
|
||||
echo "${file}"
|
||||
echo "${refs}" | sed 's/^/ /'
|
||||
fi
|
||||
done < <(find "$1" -type f \( -perm -u+x -o -name '*.dylib' -o -name '*.so*' \))
|
||||
|
||||
echo "$1: checked ${checked}, skipped ${skipped}, ${leaked} with Nix store references."
|
||||
|
||||
if [ "${leaked}" -ne 0 ]; then
|
||||
cat >&2 <<'EOF'
|
||||
|
||||
Fixes, in order of preference:
|
||||
- A Conan package built before this check existed: drop it
|
||||
(`conan remove '<name>/*'`) and rebuild.
|
||||
- A binary that should have been retargeted to the system loader: check that
|
||||
cmake/PatchNixBinary.cmake ran for it.
|
||||
- Link the macOS system library instead of the Nix one - see
|
||||
libresolvSystemStub in nix/darwin.nix.
|
||||
- No system library exists (libstdc++): link it statically.
|
||||
- None of the above: pin the toolchain into the package ID, following
|
||||
`user.package:libc_version` in conan/profiles/ci.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
@@ -15,10 +15,14 @@
|
||||
# - Windows: the core build tools only (CMake, Conan, Git, Python).
|
||||
# MSVC is expected to be provided separately and is not checked here.
|
||||
#
|
||||
# Some tools (clang-format, doxygen, gcovr, gh, git-cliff, gpg, pre-commit,
|
||||
# run-clang-tidy) are present in our Linux CI images and in local development
|
||||
# setups, but not in the macOS CI environment. They are checked everywhere
|
||||
# except when running in CI on macOS.
|
||||
# Some tools (clang-format, clang-tidy, doxygen, gcovr, gh, git-cliff, gpg,
|
||||
# pre-commit, run-clang-tidy) are present in our Linux CI images and in local
|
||||
# development setups, but not in the macOS CI environment. They are checked
|
||||
# everywhere except when running in CI on macOS.
|
||||
#
|
||||
# Tools that Nix also exposes under a version-suffixed name (`clang-tidy-22`,
|
||||
# `g++-15`, ...) are probed under both names: a suffixed name can break while
|
||||
# the plain one still works (see mkVersionedToolLinks in nix/packages.nix).
|
||||
#
|
||||
# Environment variables:
|
||||
# CI if set, skip the tools above when on macOS.
|
||||
@@ -26,12 +30,27 @@
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
# Version suffixes of the Nix tool links, tracking nix/packages.nix.
|
||||
gcc_version=15
|
||||
llvm_version=22
|
||||
|
||||
missing=()
|
||||
checked=0
|
||||
|
||||
# tool_path <name>
|
||||
# Fully resolved path of a tool, so the snapshots record which derivation
|
||||
# provides it. Prints nothing when it isn't on PATH.
|
||||
tool_path() {
|
||||
local path
|
||||
path="$(command -v "$1" 2>/dev/null)" || return 0
|
||||
readlink -f "${path}" 2>/dev/null || printf '%s' "${path}"
|
||||
}
|
||||
|
||||
# check <name> [probe-command...]
|
||||
# Runs the probe (default: "<name> --version") quietly. Records <name> as
|
||||
# missing if the command is not found or exits non-zero.
|
||||
# Runs the probe (default: "<name> --version"), capturing both stdout and
|
||||
# stderr, and prints three lines: the status and name, the first non-blank line
|
||||
# of the probe output (its version, or the error when it failed), and the tool's
|
||||
# resolved path. Records <name> as missing if it is not found or exits non-zero.
|
||||
check() {
|
||||
local name="$1"
|
||||
shift
|
||||
@@ -40,14 +59,18 @@ check() {
|
||||
probe=("${name}" --version)
|
||||
fi
|
||||
|
||||
echo "Checking ${name}..."
|
||||
checked=$((checked + 1))
|
||||
if "${probe[@]}" | head -n 1; then
|
||||
printf ' [ ok ] %s\n' "${name}"
|
||||
local output version path
|
||||
path="$(tool_path "${name}")"
|
||||
if output="$("${probe[@]}" 2>&1)"; then
|
||||
printf ' ✅ %s\n' "${name}"
|
||||
else
|
||||
printf ' [MISS] %s\n' "${name}"
|
||||
printf ' ❌ %s\n' "${name}"
|
||||
missing+=("${name}")
|
||||
fi
|
||||
version="$(printf '%s\n' "${output}" | grep -m1 '[^[:space:]]' || true)"
|
||||
printf ' %s\n' "${version:-(no output)}"
|
||||
printf ' %s\n' "${path:-(not found)}"
|
||||
}
|
||||
|
||||
case "$(uname -s)" in
|
||||
@@ -79,24 +102,35 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
|
||||
echo "Development tooling:"
|
||||
check ccache
|
||||
check clang
|
||||
check "clang-${llvm_version}"
|
||||
check clang++
|
||||
check "clang++-${llvm_version}"
|
||||
check ClangBuildAnalyzer
|
||||
check curl
|
||||
check file
|
||||
check less
|
||||
check make
|
||||
check netstat which netstat
|
||||
# net-tools netstat reports "net-tools X.Y"; macOS ships BSD netstat with no
|
||||
# version flag, so fall back to a presence marker there.
|
||||
check netstat sh -c 'command -v netstat >/dev/null && { netstat --version 2>&1 | grep -m1 -oE "net-tools [0-9.]+" || echo present; }'
|
||||
check ninja
|
||||
check perl
|
||||
check perl perl -e 'print "$^V\n"'
|
||||
check pkg-config
|
||||
check vim
|
||||
check zip
|
||||
check zip bash -c 'zip --version 2>&1 | grep -m1 -oE "Zip [0-9.]+"'
|
||||
|
||||
# These tools are present in our Linux CI images and in local development
|
||||
# setups, but not in the macOS CI environment. So check them everywhere
|
||||
# except when running in CI on macOS.
|
||||
if [ "${os}" = "linux" ] || [ -z "${CI:-}" ]; then
|
||||
check clang-apply-replacements
|
||||
check "clang-apply-replacements-${llvm_version}"
|
||||
check clang-format
|
||||
check "clang-format-${llvm_version}"
|
||||
# clang-tidy leads --version with the LLVM banner, not the version.
|
||||
tidy_probe="--version | grep -m1 -oE 'LLVM version [0-9.]+'"
|
||||
check clang-tidy sh -c "clang-tidy ${tidy_probe}"
|
||||
check "clang-tidy-${llvm_version}" sh -c "clang-tidy-${llvm_version} ${tidy_probe}"
|
||||
check dot
|
||||
check doxygen
|
||||
check gcovr
|
||||
@@ -107,6 +141,7 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
|
||||
# pre-commit, or its alternative implementation prek
|
||||
check pre-commit sh -c 'pre-commit --version || prek --version'
|
||||
check run-clang-tidy run-clang-tidy --help
|
||||
check "run-clang-tidy-${llvm_version}" "run-clang-tidy-${llvm_version}" --help
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -121,7 +156,7 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
|
||||
check cargo-audit cargo audit --version
|
||||
check cargo-llvm-cov cargo llvm-cov --version
|
||||
check cargo-nextest cargo nextest --version
|
||||
check clippy clippy-driver --version
|
||||
check clippy-driver
|
||||
check rust-analyzer
|
||||
check rustc
|
||||
check rustfmt
|
||||
@@ -133,7 +168,11 @@ if [ "${os}" = "linux" ]; then
|
||||
echo
|
||||
echo "GCC toolchain:"
|
||||
check gcc
|
||||
check "gcc-${gcc_version}"
|
||||
check g++
|
||||
check "g++-${gcc_version}"
|
||||
check cpp
|
||||
check "cpp-${gcc_version}"
|
||||
check gcov
|
||||
|
||||
echo
|
||||
@@ -158,9 +197,9 @@ else
|
||||
checked=$((checked + 1))
|
||||
tmp_clone="$(mktemp -d)"
|
||||
if git clone --depth 1 https://github.com/XRPLF/actions.git "${tmp_clone}/actions" >/dev/null 2>&1; then
|
||||
printf ' [ ok ] git clone over HTTPS\n'
|
||||
printf ' ✅ git clone over HTTPS\n'
|
||||
else
|
||||
printf ' [MISS] git clone over HTTPS\n'
|
||||
printf ' ❌ git clone over HTTPS\n'
|
||||
missing+=("git-https-clone")
|
||||
fi
|
||||
rm -rf "${tmp_clone}"
|
||||
@@ -168,9 +207,9 @@ fi
|
||||
|
||||
echo
|
||||
if [ "${#missing[@]}" -eq 0 ]; then
|
||||
echo "All ${checked} checked tools are present and runnable."
|
||||
echo "✅ All ${checked} checked tools are present and runnable."
|
||||
else
|
||||
echo "Missing or non-functional tools (${#missing[@]} of ${checked}):" >&2
|
||||
echo "❌ Missing or non-functional tools (${#missing[@]} of ${checked}):" >&2
|
||||
for tool in "${missing[@]}"; do
|
||||
echo " - ${tool}" >&2
|
||||
done
|
||||
|
||||
@@ -144,7 +144,11 @@ def main():
|
||||
+ files
|
||||
)
|
||||
canonicalize_fix_paths(Path(fixes_dir))
|
||||
applied = subprocess.run([clang_apply_replacements, fixes_dir])
|
||||
# `FormatStyle` in .clang-tidy does not reach this path,
|
||||
# so ask for the repository style here.
|
||||
applied = subprocess.run(
|
||||
[clang_apply_replacements, "--format", "--style=file", fixes_dir]
|
||||
)
|
||||
|
||||
return result.returncode or applied.returncode
|
||||
|
||||
|
||||
@@ -488,6 +488,17 @@
|
||||
# Must be a number between 100 and 1000, defaults to 250
|
||||
#
|
||||
#
|
||||
# [max_subscriptions_per_connection]
|
||||
#
|
||||
# Maximum number of account, real-time account, and account-history
|
||||
# subscriptions a single client connection may hold at once. Bounds the
|
||||
# per-connection state torn down when the connection disconnects. Book
|
||||
# subscriptions are tracked separately and are not counted here.
|
||||
#
|
||||
# Defaults to 100000 if not set; large enough for legitimate power users
|
||||
# such as block explorers.
|
||||
#
|
||||
#
|
||||
# [overlay]
|
||||
#
|
||||
# Controls settings related to the peer to peer overlay.
|
||||
@@ -538,6 +549,45 @@
|
||||
# only be used for local testing and debugging. Do not disable
|
||||
# on mainnet.
|
||||
#
|
||||
# max_untrusted_count = <number>
|
||||
#
|
||||
# The number of manifests the server keeps for validators it does not
|
||||
# list, and the number it sends and processes in a single peer protocol
|
||||
# message. Once the server holds this many, a manifest for a new
|
||||
# unlisted validator is rejected, so peer gossip cannot grow the cache
|
||||
# without end.
|
||||
#
|
||||
# This option can take any value between 50 and 1000, inclusive. If
|
||||
# the option is not present the server uses its built-in value.
|
||||
#
|
||||
# The current default (which is subject to change) is 300.
|
||||
#
|
||||
# max_trusted_count = <number>
|
||||
#
|
||||
# The number of manifests for listed validators to allow for when
|
||||
# sizing peer protocol messages. Manifests for listed validators are
|
||||
# never dropped, whether sending or receiving, because doing so would
|
||||
# delay a validator key change reaching this server. Set this above the
|
||||
# number of validators the server lists.
|
||||
#
|
||||
# Together the two counts above set the largest manifest message the
|
||||
# server accepts: bigger messages are discarded without reading them,
|
||||
# and without penalising the sender. Raising either means the server
|
||||
# accepts and sends bigger messages than a peer using the defaults, and
|
||||
# those peers will discard what this server sends. Lowering either below
|
||||
# what peers send makes this server discard their manifest messages,
|
||||
# which it does without recording anything.
|
||||
#
|
||||
# This option can take any value between 50 and 1000, inclusive. If
|
||||
# the option is not present the server uses its built-in value.
|
||||
#
|
||||
# The current default (which is subject to change) is 300.
|
||||
#
|
||||
# NOTE: These two options (max_untrusted_count and max_trusted_count)
|
||||
# are transitional. They exist to bound manifest-message size and cache
|
||||
# growth during the network upgrade. They may be removed in a future
|
||||
# release once the fleet has upgraded, and should not be relied upon as
|
||||
# stable configuration.
|
||||
#
|
||||
# [transaction_queue] EXPERIMENTAL
|
||||
#
|
||||
|
||||
@@ -29,6 +29,27 @@ if(CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
set(is_xcode TRUE)
|
||||
endif()
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Nix toolchain detection
|
||||
# --------------------------------------------------------------------
|
||||
# True when the C++ compiler resolves into the Nix store. CMAKE_CXX_COMPILER may
|
||||
# be referenced through a symlink outside the store (a Nix profile, a /usr/bin
|
||||
# alternative, ...), so resolve the real path before matching.
|
||||
set(is_nix_compiler FALSE)
|
||||
get_filename_component(_cxx_real "${CMAKE_CXX_COMPILER}" REALPATH)
|
||||
if(_cxx_real MATCHES "^/nix/store/")
|
||||
set(is_nix_compiler TRUE)
|
||||
endif()
|
||||
unset(_cxx_real)
|
||||
|
||||
# True inside the Nix CI Docker image, identified by the /nix/ci-env tree it
|
||||
# ships (see nix/docker/Dockerfile). The dev shell and bare systems don't have
|
||||
# it, so it distinguishes the CI image from other Nix-compiler environments.
|
||||
set(is_ci_image FALSE)
|
||||
if(EXISTS "/nix/ci-env/bin")
|
||||
set(is_ci_image TRUE)
|
||||
endif()
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Operating system detection
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
@@ -1,26 +1,38 @@
|
||||
#[===================================================================[
|
||||
Patch executables to run in non-Nix environments.
|
||||
|
||||
The Nix-based CI image links binaries against an ELF interpreter (loader)
|
||||
The Nix toolchain 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
|
||||
is skipped for sanitizer builds, whose runtime libraries are resolved through
|
||||
the rpath. Everywhere else `patch_nix_binary` is a no-op.
|
||||
This runs by default for Nix-toolchain builds (determined by whether the compiler resolves under /nix/store/).
|
||||
Those builds are where binaries get a Nix-store loader.
|
||||
It is opted out of by setting the XRPLD_NO_PATCH_NIX_BINARY environment variable —
|
||||
the plain Nix dev shells set it, since their binaries link a newer glibc
|
||||
and must not be retargeted to the system loader.
|
||||
|
||||
Non-Nix builds (a system compiler, already using the system loader) and sanitizer builds
|
||||
(runtime libraries resolved through the rpath) are skipped too.
|
||||
Everywhere else `patch_nix_binary` is a no-op.
|
||||
|
||||
The default loader is resolved by bin/default-loader-path.sh.
|
||||
#]===================================================================]
|
||||
|
||||
include_guard(GLOBAL)
|
||||
|
||||
include(CompilationEnv)
|
||||
|
||||
# Provided by the Nix-based CI image; prints the system default ELF loader path.
|
||||
set(_loader_path_script "/tmp/loader-path.sh")
|
||||
# Resolves the system default ELF loader path for the current architecture.
|
||||
set(_loader_path_script "${CMAKE_SOURCE_DIR}/bin/default-loader-path.sh")
|
||||
|
||||
if(is_linux AND NOT SANITIZERS_ENABLED AND EXISTS "${_loader_path_script}")
|
||||
if(
|
||||
is_linux
|
||||
AND NOT SANITIZERS_ENABLED
|
||||
AND is_nix_compiler
|
||||
AND NOT DEFINED ENV{XRPLD_NO_PATCH_NIX_BINARY}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND "${_loader_path_script}"
|
||||
OUTPUT_VARIABLE DEFAULT_LOADER_PATH
|
||||
@@ -41,13 +53,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 "$<TARGET_FILE:${target}>"
|
||||
COMMENT "Patching ${target}: set default loader, remove rpath"
|
||||
VERBATIM
|
||||
|
||||
set(patch_command
|
||||
"${PATCHELF_COMMAND}"
|
||||
--set-interpreter
|
||||
"${DEFAULT_LOADER_PATH}"
|
||||
--remove-rpath
|
||||
"$<TARGET_FILE:${target}>"
|
||||
)
|
||||
set(comment "Patching ${target}: set default loader, remove rpath")
|
||||
|
||||
# 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()
|
||||
endfunction()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
include_guard()
|
||||
|
||||
include(isolate_headers)
|
||||
|
||||
# Define a benchmark executable for the module `name`.
|
||||
|
||||
@@ -171,9 +171,8 @@ else()
|
||||
# Clang wrapper supplies those paths itself (via -nostdinc++), so at compile time the
|
||||
# flag is unused -> Clang errors under our -Werror. At link time the flag IS consumed
|
||||
# (it selects the C++ runtime), so we move it there instead of dropping it entirely.
|
||||
get_filename_component(_cxx_real "${CMAKE_CXX_COMPILER}" REALPATH)
|
||||
if(
|
||||
_cxx_real MATCHES "^/nix/store/"
|
||||
is_nix_compiler
|
||||
AND is_linux
|
||||
AND is_clang
|
||||
AND CMAKE_CXX_FLAGS MATCHES "stdlib=libstdc"
|
||||
@@ -267,10 +266,50 @@ elseif(use_lld)
|
||||
)
|
||||
if("${LD_VERSION}" MATCHES "LLD")
|
||||
target_link_libraries(common INTERFACE -fuse-ld=lld)
|
||||
# remembered for the linker flag probe below
|
||||
set(fuse_ld_flag "-fuse-ld=lld")
|
||||
endif()
|
||||
unset(LD_VERSION)
|
||||
endif()
|
||||
|
||||
# Linker warnings are errors where we control the toolchain and the dependencies: CI and the Nix dev shell.
|
||||
# On non-Nix macOS we suppress the deployment target warning: an old Conan profile may not pin os.version.
|
||||
# Only the new Apple linker understands the flag, so probe the actual linker (lld may be selected above).
|
||||
if(is_macos OR is_linux)
|
||||
if(is_ci OR is_nix_compiler)
|
||||
if(is_macos)
|
||||
set(fatal_warnings_flag "-Wl,-fatal_warnings")
|
||||
else()
|
||||
set(fatal_warnings_flag "-Wl,--fatal-warnings")
|
||||
endif()
|
||||
message(
|
||||
STATUS
|
||||
"Treating all linker warnings as errors (${fatal_warnings_flag})"
|
||||
)
|
||||
target_link_options(common INTERFACE "${fatal_warnings_flag}")
|
||||
unset(fatal_warnings_flag)
|
||||
elseif(is_macos)
|
||||
set(silence_flag "-Wl,-deployment_target_mismatches,suppress")
|
||||
set(probe_flags ${fuse_ld_flag} "${silence_flag}")
|
||||
include(CheckLinkerFlag)
|
||||
check_linker_flag(
|
||||
CXX
|
||||
"${probe_flags}"
|
||||
have_deployment_target_mismatches
|
||||
)
|
||||
if(have_deployment_target_mismatches)
|
||||
message(
|
||||
STATUS
|
||||
"Silencing macOS deployment target mismatch warnings (${silence_flag})"
|
||||
)
|
||||
target_link_options(common INTERFACE "${silence_flag}")
|
||||
endif()
|
||||
unset(probe_flags)
|
||||
unset(silence_flag)
|
||||
endif()
|
||||
endif()
|
||||
unset(fuse_ld_flag)
|
||||
|
||||
if(assert)
|
||||
foreach(var_ CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE)
|
||||
string(REGEX REPLACE "[-/]DNDEBUG" "" ${var_} "${${var_}}")
|
||||
|
||||
@@ -133,6 +133,12 @@ target_link_libraries(
|
||||
add_module(xrpl resource)
|
||||
target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol)
|
||||
|
||||
add_module(xrpl peerfinder)
|
||||
target_link_libraries(
|
||||
xrpl.libxrpl.peerfinder
|
||||
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.protocol
|
||||
)
|
||||
|
||||
# Level 08
|
||||
add_module(xrpl net)
|
||||
target_link_libraries(
|
||||
@@ -201,6 +207,16 @@ target_link_libraries(
|
||||
add_module(xrpl tx)
|
||||
target_link_libraries(xrpl.libxrpl.tx PUBLIC xrpl.libxrpl.ledger)
|
||||
|
||||
add_module(xrpl consensus)
|
||||
target_link_libraries(
|
||||
xrpl.libxrpl.consensus
|
||||
PUBLIC
|
||||
xrpl.libxrpl.basics
|
||||
xrpl.libxrpl.json
|
||||
xrpl.libxrpl.protocol
|
||||
xrpl.libxrpl.ledger
|
||||
)
|
||||
|
||||
add_library(xrpl.libxrpl)
|
||||
set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl)
|
||||
|
||||
@@ -220,6 +236,7 @@ target_link_modules(
|
||||
beast
|
||||
conditions
|
||||
config
|
||||
consensus
|
||||
core
|
||||
crypto
|
||||
git
|
||||
@@ -227,6 +244,7 @@ target_link_modules(
|
||||
ledger
|
||||
net
|
||||
nodestore
|
||||
peerfinder
|
||||
protocol
|
||||
protocol_autogen
|
||||
rdb
|
||||
|
||||
@@ -44,6 +44,7 @@ setup_target_for_coverage_gcovr(
|
||||
EXCLUDE
|
||||
"src/test"
|
||||
"src/tests"
|
||||
"src/benchmarks"
|
||||
"include/xrpl/beast/test"
|
||||
"include/xrpl/beast/unit_test"
|
||||
"${CMAKE_BINARY_DIR}/pb-xrpl.libpb"
|
||||
|
||||
@@ -25,6 +25,19 @@ if(NOT (RPMBUILD_EXECUTABLE OR DPKG_BUILDPACKAGE_EXECUTABLE))
|
||||
return()
|
||||
endif()
|
||||
|
||||
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 +50,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
|
||||
)
|
||||
|
||||
@@ -2,21 +2,22 @@
|
||||
Protocol Autogen - Code generation for protocol wrapper classes
|
||||
#]===================================================================]
|
||||
|
||||
# The repository root, derived from the location of this file rather than from
|
||||
# the including project, so that the targets below can also be offered on their
|
||||
# own by cmake/codegen/CMakeLists.txt.
|
||||
get_filename_component(XRPL_ROOT "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
|
||||
|
||||
set(CODEGEN_VENV_DIR
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/.venv"
|
||||
"${XRPL_ROOT}/.venv"
|
||||
CACHE PATH
|
||||
"Path to a Python virtual environment for code generation. A venv will be created here by setup_code_gen and used to run generation scripts."
|
||||
)
|
||||
|
||||
# Directory paths
|
||||
set(MACRO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl/protocol/detail")
|
||||
set(AUTOGEN_HEADER_DIR
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl/protocol_autogen"
|
||||
)
|
||||
set(AUTOGEN_TEST_DIR
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/tests/libxrpl/protocol_autogen"
|
||||
)
|
||||
set(SCRIPTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/scripts/codegen")
|
||||
set(MACRO_DIR "${XRPL_ROOT}/include/xrpl/protocol/detail")
|
||||
set(AUTOGEN_HEADER_DIR "${XRPL_ROOT}/include/xrpl/protocol_autogen")
|
||||
set(AUTOGEN_TEST_DIR "${XRPL_ROOT}/src/tests/libxrpl/protocol_autogen")
|
||||
set(SCRIPTS_DIR "${XRPL_ROOT}/cmake/scripts/codegen")
|
||||
|
||||
# Input macro files
|
||||
set(TRANSACTIONS_MACRO "${MACRO_DIR}/transactions.macro")
|
||||
@@ -114,14 +115,14 @@ if(CODEGEN_VENV_DIR)
|
||||
setup_code_gen
|
||||
COMMAND ${Python3_EXECUTABLE} -m venv "${CODEGEN_VENV_DIR}"
|
||||
COMMAND ${CODEGEN_PYTHON} -m pip install -r "${REQUIREMENTS_FILE}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
WORKING_DIRECTORY "${XRPL_ROOT}"
|
||||
COMMENT "Creating venv and installing code generation dependencies..."
|
||||
)
|
||||
else()
|
||||
add_custom_target(
|
||||
setup_code_gen
|
||||
COMMAND ${Python3_EXECUTABLE} -m pip install -r "${REQUIREMENTS_FILE}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
WORKING_DIRECTORY "${XRPL_ROOT}"
|
||||
COMMENT "Installing code generation dependencies..."
|
||||
)
|
||||
endif()
|
||||
@@ -139,8 +140,8 @@ add_custom_target(
|
||||
-DSFIELDS_MACRO=${SFIELDS_MACRO}
|
||||
-DAUTOGEN_HEADER_DIR=${AUTOGEN_HEADER_DIR}
|
||||
-DAUTOGEN_TEST_DIR=${AUTOGEN_TEST_DIR} -P
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/XrplProtocolAutogenRun.cmake"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/XrplProtocolAutogenRun.cmake"
|
||||
WORKING_DIRECTORY "${XRPL_ROOT}"
|
||||
COMMENT "Running protocol code generation..."
|
||||
SOURCES ${ALL_INPUT_FILES}
|
||||
)
|
||||
|
||||
@@ -36,6 +36,19 @@ elseif(is_gcc)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# A Nix compiler is only meant to be used from a managed environment: the xrpld
|
||||
# dev shell (which exports XRPL_DEVSHELL) or the CI image. Using one from a bare
|
||||
# shell usually means a leaked toolchain (picked up via PATH or a Conan profile)
|
||||
# and leads to confusing breakage, so fail early with guidance.
|
||||
if(is_nix_compiler AND NOT is_ci_image AND NOT DEFINED ENV{XRPL_DEVSHELL})
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"A Nix compiler (${CMAKE_CXX_COMPILER}) is being used outside the xrpld "
|
||||
"dev shell. Enter it with `nix develop` (see docs/build/nix.md) before "
|
||||
"configuring the build."
|
||||
)
|
||||
endif()
|
||||
|
||||
# check for in-source build and fail
|
||||
if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||
message(
|
||||
|
||||
@@ -5,22 +5,39 @@ 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}")
|
||||
# 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.
|
||||
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
|
||||
# as a subproject. Undo that, so validator_keys=ON really does build it.
|
||||
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
|
||||
)
|
||||
# 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()
|
||||
|
||||
21
cmake/codegen/CMakeLists.txt
Normal file
21
cmake/codegen/CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
#[===================================================================[
|
||||
Protocol Autogen - Standalone project
|
||||
|
||||
Exposes the 'setup_code_gen' and 'code_gen' targets on their own, without
|
||||
configuring the rest of xrpl. Code generation is pure Python, so this needs
|
||||
neither the dependencies nor a compiler, which makes it usable in CI and by
|
||||
contributors who only want to regenerate the protocol wrapper classes:
|
||||
|
||||
cmake -S cmake/codegen -B build/codegen
|
||||
cmake --build build/codegen --target setup_code_gen
|
||||
cmake --build build/codegen --target code_gen
|
||||
|
||||
The targets are identical to the ones offered by the top-level build, since
|
||||
both come from cmake/XrplProtocolAutogen.cmake.
|
||||
#]===================================================================]
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(xrpl_codegen LANGUAGES NONE)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/../XrplProtocolAutogen.cmake")
|
||||
@@ -12,7 +12,7 @@
|
||||
"protobuf/6.33.5#ff253ead763bd8d9904a52979cd21e81%1782392410.233933",
|
||||
"openssl/3.6.3#f806de8933e3bf6f01016c6a888cee2e%1783945160.863288",
|
||||
"nudb/2.0.9#11149c73f8f2baff9a0198fe25971fc7%1782392402.297166",
|
||||
"mpt-crypto/0.4.0-rc4#ffdba12f2332357f0d8b0ae944cfff52%1784138702.932355",
|
||||
"mpt-crypto/1.0.2#b313cef0c1a493eb970ad185b2e9bab7%1784285108.866483",
|
||||
"lz4/1.10.0#982d9b673900f665a1da109e09c17cab%1782392402.164188",
|
||||
"libiconv/1.17#9923bc6dc6f106646d6967e0039a5ada%1782392792.775744",
|
||||
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1782392402.420732",
|
||||
@@ -20,6 +20,7 @@
|
||||
"jemalloc/5.3.1#1fc58d55316041f10fbc1e8a2eae632a%1776700028.228",
|
||||
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1782392402.791979",
|
||||
"grpc/1.81.1#f729f6d75992d20f9c72828e9142d62f%1783945160.094135",
|
||||
"fast_float/8.2.10#f6f28d6bb22112078e7dbda611caf681%1782494504.298",
|
||||
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1782307148.15562",
|
||||
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1782392402.538492",
|
||||
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1782392402.681654",
|
||||
@@ -34,7 +35,7 @@
|
||||
"protobuf/6.33.5#ff253ead763bd8d9904a52979cd21e81%1782392410.233933",
|
||||
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1782395690.33162",
|
||||
"msys2/cci.latest#d22fe7b2808f5fd34d0a7923ace9c54f%1770657326.649",
|
||||
"m4/1.4.19#34c4bbc3eeebe98ca6edf2f52d602e7d%1777282960.259",
|
||||
"m4/1.4.19#1727f439cf74e83826ec96d0b4904eee%1784541921.659",
|
||||
"cmake/4.3.3#840cf00ea09777e05c2050a50a82c722%1782392418.696091",
|
||||
"b2/5.4.2#ffd6084a119587e70f11cd45d1a386e2%1782392402.624226",
|
||||
"automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56",
|
||||
|
||||
21
conan/init.sh
Executable file
21
conan/init.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# Install our Conan configuration, profiles and the xrplf remote into CONAN_HOME.
|
||||
# Safe to re-run; never deletes the Conan home.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONAN_DIR="$(conan config home)"
|
||||
|
||||
echo "Installing Conan configuration into ${CONAN_DIR}"
|
||||
conan config install "${SCRIPT_DIR}/global.conf"
|
||||
conan config install "${SCRIPT_DIR}/profiles" -tf "${CONAN_DIR}/profiles"
|
||||
# This script manages these files, so make them read-only - Conan does not
|
||||
# preserve the source mode. Only the files: the directories must stay writable
|
||||
# for `conan config install` to replace them.
|
||||
chmod a-w "${CONAN_DIR}/global.conf"
|
||||
find "${CONAN_DIR}/profiles" -type f -exec chmod a-w {} +
|
||||
|
||||
echo "Adding the xrplf Conan remote"
|
||||
# --index 0: our patched recipes must win over Conan Center.
|
||||
conan remote add --index 0 --force xrplf https://conan.xrplf.org/repository/conan/
|
||||
@@ -1,9 +1,13 @@
|
||||
{% set os = detect_api.detect_os() %}
|
||||
{% set arch = detect_api.detect_arch() %}
|
||||
{% set compiler, version, compiler_exe = detect_api.detect_default_compiler() %}
|
||||
{% set compiler_version = version %}
|
||||
{% if os == "Linux" %}
|
||||
{% set compiler_version = detect_api.default_compiler_version(compiler, version) %}
|
||||
{% if os == "Macos" %}
|
||||
{# Minimum macOS the dependencies target. #}
|
||||
{# Without this, Conan builds each dependency against the (possibly newer) host SDK, so the #}
|
||||
{# dependency objects target a newer macOS than the binary and the linker warns. #}
|
||||
{# Keep at or below CMAKE_OSX_DEPLOYMENT_TARGET in CMakeLists.txt. #}
|
||||
{% set min_macos_version = "15.0" %}
|
||||
{% endif %}
|
||||
|
||||
[settings]
|
||||
@@ -18,6 +22,9 @@ compiler.runtime=static
|
||||
{% else %}
|
||||
compiler.libcxx={{ detect_api.detect_libcxx(compiler, version, compiler_exe) }}
|
||||
{% endif %}
|
||||
{% if os == "Macos" %}
|
||||
os.version={{ min_macos_version }}
|
||||
{% endif %}
|
||||
|
||||
[conf]
|
||||
{# The Boost recipe builds with b2, which doesn't use Conan's toolchain files. #}
|
||||
@@ -41,3 +48,13 @@ tools.build:compiler_executables={'c':'{{ cc_exe }}','cpp':'{{ cxx_exe }}'}
|
||||
{# More info: https://docs.conan.io/2/reference/extensions/binary_compatibility.html #}
|
||||
user.package:cppstd_version=23
|
||||
tools.info.package_id:confs+=["user.package:cppstd_version"]
|
||||
|
||||
{% if os == "Macos" %}
|
||||
[buildenv]
|
||||
{# os.version adds -mmacosx-version-min to compiler command lines, #}
|
||||
{# but Boost.Context's b2 assembly (.S) rule ignores it, #}
|
||||
{# so those objects keep the host SDK version and still warn at link time. #}
|
||||
{# clang's assembler honors this env var regardless, pinning them. #}
|
||||
{# Scoped to boost/* since it is the only gap. #}
|
||||
boost/*:MACOSX_DEPLOYMENT_TARGET={{ min_macos_version }}
|
||||
{% endif %}
|
||||
|
||||
@@ -29,6 +29,7 @@ class Xrpl(ConanFile):
|
||||
|
||||
requires = [
|
||||
"ed25519/2015.03",
|
||||
"fast_float/8.2.10",
|
||||
"grpc/1.81.1",
|
||||
"libarchive/3.8.7",
|
||||
"nudb/2.0.9",
|
||||
@@ -138,7 +139,7 @@ class Xrpl(ConanFile):
|
||||
if self.options.jemalloc:
|
||||
self.requires("jemalloc/5.3.1")
|
||||
self.requires("lz4/1.10.0", force=True)
|
||||
self.requires("mpt-crypto/0.4.0-rc4", transitive_headers=True)
|
||||
self.requires("mpt-crypto/1.0.2", transitive_headers=True)
|
||||
self.requires("protobuf/6.33.5", force=True)
|
||||
if self.options.rocksdb:
|
||||
self.requires("rocksdb/10.5.1")
|
||||
@@ -211,6 +212,7 @@ class Xrpl(ConanFile):
|
||||
"boost::thread",
|
||||
"date::date",
|
||||
"ed25519::ed25519",
|
||||
"fast_float::fast_float",
|
||||
"grpc::grpc++",
|
||||
"libarchive::libarchive",
|
||||
"lz4::lz4",
|
||||
|
||||
Binary file not shown.
81
docs/build/environment.md
vendored
81
docs/build/environment.md
vendored
@@ -6,22 +6,52 @@ This document explains how to set one up.
|
||||
|
||||
## Tested compiler versions
|
||||
|
||||
`xrpld` is built in the **C++23** dialect by default.
|
||||
Make sure your toolchain is recent enough — the compiler versions currently tested in CI are:
|
||||
`xrpld` is built in the **C++23** dialect by default, so your toolchain has to
|
||||
support it — see [compiler support for C++23][cpp23-support].
|
||||
The versions currently tested in CI are:
|
||||
|
||||
| Compiler | Version |
|
||||
| ----------- | ------- |
|
||||
| GCC | 15.2 |
|
||||
| Clang | 22 |
|
||||
| Apple Clang | 17 |
|
||||
| MSVC | 19.44 |
|
||||
| Compiler | Version |
|
||||
| ----------- | ------------------ |
|
||||
| GCC | 15.2 |
|
||||
| Clang | 22 |
|
||||
| Apple Clang | 21 |
|
||||
| MSVC | Visual Studio 2026 |
|
||||
|
||||
LLVM tools (`clang-tidy` and `clang-format`) are also pinned to version 22.
|
||||
|
||||
### Older compilers
|
||||
|
||||
Older compilers may fail to build the latest `develop` code: the codebase now
|
||||
relies on C++23 features and has been adjusted for `clang-tidy`.
|
||||
If the latest code doesn't build for you, update your build toolchain first.
|
||||
|
||||
If updating isn't an option for you, we do accept pull requests that fix builds
|
||||
on older compilers, as long as the change is small and doesn't make the code
|
||||
harder to read. What we can't promise is that older compilers will keep working:
|
||||
only the versions in the table above are tested in CI, and we won't hold back
|
||||
the use of C++23 features or add invasive workarounds to keep an untested
|
||||
compiler building. Treat support for anything outside the table as best-effort.
|
||||
|
||||
## Required tools
|
||||
|
||||
Besides a compiler, building `xrpld` requires:
|
||||
|
||||
| Tool | Minimum version |
|
||||
| ------------------------------------------- | --------------- |
|
||||
| [Git](https://git-scm.com/downloads) | any recent |
|
||||
| [Python](https://www.python.org/downloads/) | 3.11 |
|
||||
| [Conan](https://conan.io/downloads.html) | 2.17 |
|
||||
| [CMake](https://cmake.org/download/) | 3.16 |
|
||||
|
||||
On Linux and macOS, the [Nix development shell](./nix.md) provides all of them
|
||||
(see below). On Windows they have to be installed manually.
|
||||
|
||||
Once they are in place, verify that everything is installed and runnable with:
|
||||
|
||||
```bash
|
||||
./bin/check-tools.sh
|
||||
```
|
||||
|
||||
## Linux and macOS
|
||||
|
||||
The **recommended way** to get a development environment on Linux and macOS is
|
||||
@@ -39,20 +69,15 @@ Clang. If you instead opt to use your system-wide Apple Clang (via
|
||||
below).
|
||||
|
||||
See [Using the Nix development shell](./nix.md) for installation and usage
|
||||
details, including how to select a different compiler.
|
||||
|
||||
> [!NOTE]
|
||||
> Using Nix is not mandatory. Any custom environment (Homebrew packages or
|
||||
> anything else) will continue to work, but then it is up to you to keep it in
|
||||
> sync with the environment used in CI. Nix unifies the development environment
|
||||
> for everyone and synchronizes updates, which is why we recommend it.
|
||||
details, including how to select a different compiler and why we recommend Nix
|
||||
over a hand-maintained environment.
|
||||
|
||||
### macOS: managing the Apple Clang version
|
||||
|
||||
If you use your system-wide Apple Clang on macOS (via `nix develop .#apple-clang`),
|
||||
the compiler version is whatever your installed Xcode (or Command Line Tools)
|
||||
provides. The following command should return a version greater than or equal to
|
||||
the [minimum required](#tested-compiler-versions):
|
||||
the [tested one](#tested-compiler-versions):
|
||||
|
||||
```bash
|
||||
clang --version
|
||||
@@ -89,23 +114,23 @@ building xrpld. You may want to install and pin a specific version of Xcode:
|
||||
Nix is not available on Windows, so the required tools have to be installed
|
||||
manually:
|
||||
|
||||
- [Visual Studio 2022](https://visualstudio.microsoft.com/) with the
|
||||
- [Visual Studio 2026](https://visualstudio.microsoft.com/) with the
|
||||
**"Desktop development with C++"** workload — this provides MSVC and the
|
||||
"x64 Native Tools Command Prompt".
|
||||
"x64 Native Tools Command Prompt". CI configures CMake with the
|
||||
`Visual Studio 18 2026` generator.
|
||||
- [Git for Windows](https://git-scm.com/download/win)
|
||||
- [Python 3.11](https://www.python.org/downloads/), or higher
|
||||
- [Conan 2.17](https://conan.io/downloads.html), or higher
|
||||
- [CMake 3.22](https://cmake.org/download/), or higher
|
||||
|
||||
> [!NOTE]
|
||||
> Windows is used for development only and is not recommended for production.
|
||||
- Python, Conan, and CMake, at the versions listed in
|
||||
[Required tools](#required-tools).
|
||||
|
||||
## 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. This project currently uses `clang-tidy` version 22.
|
||||
project. The version this project uses is listed in
|
||||
[Tested compiler versions](#tested-compiler-versions).
|
||||
|
||||
On Linux and macOS, the [Nix development shell](./nix.md) provides `clang-tidy`
|
||||
22 out of the box — run it via `run-clang-tidy`. No separate installation is
|
||||
needed.
|
||||
On Linux and macOS, the [Nix development shell](./nix.md) provides that exact
|
||||
version out of the box — run it via `run-clang-tidy`. No separate installation
|
||||
is needed.
|
||||
|
||||
[cpp23-support]: https://en.cppreference.com/w/cpp/compiler_support/23
|
||||
|
||||
138
docs/build/nix.md
vendored
138
docs/build/nix.md
vendored
@@ -7,7 +7,7 @@ This guide explains how to use Nix to set up a reproducible development environm
|
||||
## Benefits of Using Nix
|
||||
|
||||
- **Reproducible environment**: Everyone gets the same versions of tools and compilers
|
||||
- **Matches CI**: The Linux CI runs in Docker images built from this exact Nix environment
|
||||
- **Matches CI**: The Linux CI runs in Docker images built from this exact Nix environment, and CI builds some macOS configurations in it as well
|
||||
- **No system pollution**: Dependencies are isolated and don't affect your system packages
|
||||
- **Consistent compilers**: The GCC and Clang shells use the same versions as CI
|
||||
- **Quick setup**: Get started with a single command
|
||||
@@ -38,8 +38,10 @@ The first time you run this command, it will take a few minutes to download and
|
||||
|
||||
### Platform notes
|
||||
|
||||
- **Linux**: `nix develop` gives you a shell with all the tooling necessary to
|
||||
develop xrpld and with GCC 15.2 (also provided by Nix). There are no caveats.
|
||||
- **Linux**: `nix develop` gives you a shell with all the tooling necessary to develop xrpld
|
||||
and with the same GCC/glibc toolchain that Nix builds for CI.
|
||||
See [Choosing a different compiler](#choosing-a-different-compiler)
|
||||
for the custom-vs-plain toolchain trade-off.
|
||||
- **macOS**: `nix develop` gives you a full environment too, with Clang (and
|
||||
every other tool, including Conan) provided by Nix. To use your system-wide
|
||||
Apple Clang instead, enter `nix develop .#apple-clang`. Conan has no binary in
|
||||
@@ -63,8 +65,16 @@ The first time you run this command, it will take a few minutes to download and
|
||||
### Choosing a different compiler
|
||||
|
||||
A compiler can be chosen by providing its name with the `.#` prefix, e.g. `nix develop .#clang`.
|
||||
The `.#gcc` and `.#clang` shells provide the same GCC and Clang versions used in CI
|
||||
(pinned in [`nix/packages.nix`](../../nix/packages.nix)).
|
||||
|
||||
On Linux, `.#gcc` and `.#clang` provide the exact toolchain CI uses:
|
||||
the compiler (pinned in [`nix/packages.nix`](../../nix/packages.nix))
|
||||
rebuilt against the pinned custom glibc (see [`nix/linux.nix`](../../nix/linux.nix)).
|
||||
Building that toolchain the first time is slow unless it is fetched from a Nix binary cache.
|
||||
If you don't need the custom glibc, the Linux-only `.#gcc-plain` and `.#clang-plain`
|
||||
give you the stock nixpkgs compilers of the same versions.
|
||||
On macOS there is no custom glibc, so `.#gcc` and `.#clang` are already the plain nixpkgs toolchain,
|
||||
and the `-plain` variants do not exist.
|
||||
|
||||
Use `nix flake show` to see all the available development shells.
|
||||
|
||||
Use `nix develop .#no-compiler` to use the compiler from your system.
|
||||
@@ -72,14 +82,18 @@ Use `nix develop .#no-compiler` to use the compiler from your system.
|
||||
### Example Usage
|
||||
|
||||
```bash
|
||||
# Use GCC (same version as CI)
|
||||
# Use GCC — same toolchain as CI (custom glibc on Linux)
|
||||
nix develop .#gcc
|
||||
|
||||
# Use Clang (same version as CI)
|
||||
# Use Clang — same toolchain as CI (custom glibc on Linux)
|
||||
nix develop .#clang
|
||||
|
||||
# Use default for your platform
|
||||
nix develop
|
||||
|
||||
# Stock nixpkgs GCC/Clang, Linux only — skips the custom-glibc build, but does not match CI
|
||||
nix develop .#gcc-plain
|
||||
nix develop .#clang-plain
|
||||
```
|
||||
|
||||
### Using a different shell
|
||||
@@ -106,10 +120,102 @@ nix develop -c "$SHELL"
|
||||
>
|
||||
> If it doesn't, either adjust your shell configuration so it doesn't override `$PATH`, or use [direnv](#automatic-activation-with-direnv) (below), which loads the environment _after_ your shell config and so takes precedence regardless of the shell you use.
|
||||
|
||||
## Building xrpld with Nix
|
||||
## Building xrpld in the Nix shell
|
||||
|
||||
Once inside the Nix development shell, follow the standard [build instructions](../../BUILD.md#steps). The Nix shell provides all necessary tools (CMake, Ninja, Conan, etc.).
|
||||
|
||||
Coverage builds (`-Dcoverage=ON`) work in the `gcc` shell (and `gcc-plain` on Linux):
|
||||
each ships a `gcov` matching its compiler, since Nix's cc-wrapper does not expose one.
|
||||
The `clang` shells do not include `llvm-cov`, so use a `gcc` shell for coverage.
|
||||
|
||||
## Conan configuration
|
||||
|
||||
The shell runs [`conan/init.sh`](../../conan/init.sh) on entry, so
|
||||
[Set Up Conan](../../BUILD.md#set-up-conan) is already done for you. It installs
|
||||
into the shell's own Conan home: `CONAN_HOME=~/.conan2-nix`.
|
||||
|
||||
### Prebuilt packages
|
||||
|
||||
On **Linux**, the binaries on the `xrplf` remote are built in this same Nix
|
||||
environment — CI runs in Docker images that bundle the dev shell's toolchain (see
|
||||
[`nix/docker`](../../nix/docker)) — so `.#gcc` and `.#clang` can reuse them. The
|
||||
`-plain` shells do not match that toolchain's glibc, so binaries from the remote
|
||||
are not a reliable match there.
|
||||
|
||||
On **macOS**, CI also builds in this Nix environment, in Debug and Release (the
|
||||
`macos-arm64-*-nix` configurations — Debug because the profile defaults to it).
|
||||
The Nix build resolves to `compiler=clang`, so it gets its own package IDs,
|
||||
separate from the Apple Clang ones. The
|
||||
[dependency upload](../../.github/workflows/upload-conan-deps.yml) publishes them
|
||||
on pushes to `develop` and on manual runs — its nightly run rebuilds everything
|
||||
from source but uploads nothing — so once a set has been published `nix develop`
|
||||
can reuse it instead of compiling every dependency locally. These configurations
|
||||
run outside the reduced pull-request matrix, so label a PR `Full CI build` when it
|
||||
touches `flake.lock` or `nix/`.
|
||||
|
||||
To compile everything from source, add `--build '*'` to the `conan install`
|
||||
command.
|
||||
|
||||
### Why the nixpkgs revision is not part of the package ID
|
||||
|
||||
A Conan package ID records the compiler and its major version, but nothing about
|
||||
the nixpkgs revision the toolchain came from — and `flake.lock` moves far more
|
||||
often than the toolchain meaningfully changes, so folding it in would rebuild
|
||||
every dependency on every bump for nothing.
|
||||
|
||||
That is safe as long as no cached artifact resolves a `/nix/store` path at run
|
||||
time, because store paths change on every update and the old ones disappear with
|
||||
`nix-collect-garbage`. With the `clang` toolchain macOS CI and the dev shell use,
|
||||
they do not: it links against `/usr/lib/libc++` and `/usr/lib/libSystem`, and
|
||||
store paths reach the `.a` files only through debug info, which nothing resolves
|
||||
at link or run time.
|
||||
|
||||
> [!WARNING]
|
||||
> This does not hold for `nix develop .#gcc` on macOS. There is no system
|
||||
> libstdc++, so GCC links its own from the store and every binary keeps a
|
||||
> `/nix/store` reference. That shell is fine for tooling, but it is not a build
|
||||
> configuration CI covers, and no dependency binaries are published for it.
|
||||
|
||||
This is checked rather than assumed.
|
||||
[`bin/check-nix-store-refs.sh`](../../bin/check-nix-store-refs.sh) takes one file
|
||||
or directory and fails if a binary under it resolves a store path at run time.
|
||||
CI runs it over the build output and the Conan cache, and again in the upload job
|
||||
before anything is published. You can run it yourself:
|
||||
|
||||
```bash
|
||||
bin/check-nix-store-refs.sh build
|
||||
bin/check-nix-store-refs.sh ~/.conan2-nix
|
||||
```
|
||||
|
||||
It works on Linux too, but asserts something narrower there: the toolchain always
|
||||
writes the store into `PT_INTERP` and `RUNPATH`, and CI builds inside an image
|
||||
whose store is fixed for its lifetime, so that is fine. Only the binaries
|
||||
[`PatchNixBinary.cmake`](../../cmake/PatchNixBinary.cmake) retargets to the
|
||||
system loader have to be clean, and those are what CI checks:
|
||||
|
||||
```bash
|
||||
bin/check-nix-store-refs.sh build/xrpld
|
||||
```
|
||||
|
||||
### The libresolv stub
|
||||
|
||||
This is not hypothetical: `xrpld` used to be caught by it. The c-ares package
|
||||
tells the linker to pass `-lresolv`, and nixpkgs keeps `libresolv` out of the
|
||||
macOS SDK and ships it as an ordinary store dylib — so every Nix-built `xrpld`
|
||||
recorded a `/nix/store/…-libresolv-93/lib/libresolv.9.dylib` load command and
|
||||
stopped running once that path was collected. Nothing in the link uses a single
|
||||
symbol from it.
|
||||
|
||||
Both environments now put a stub on the linker search path
|
||||
(`libresolvSystemStub` in [`nix/darwin.nix`](../../nix/darwin.nix)): the
|
||||
same library with its install name set to `/usr/lib/libresolv.9.dylib`, which is
|
||||
exactly the load command the Apple Clang build records.
|
||||
|
||||
Package IDs did not change, so Conan keeps serving anything built before the
|
||||
stub landed. If a binary fails to start with `Library not loaded: /nix/store/…`,
|
||||
see [that entry](./nix_troubleshooting.md#library-not-loaded-nixstore-from-a-binary-that-used-to-work)
|
||||
in the troubleshooting guide.
|
||||
|
||||
## Automatic Activation with direnv
|
||||
|
||||
[direnv](https://direnv.net/) or [nix-direnv](https://github.com/nix-community/nix-direnv) can automatically activate the Nix development shell when you enter the repository directory.
|
||||
@@ -124,18 +230,18 @@ The repository already ships an `.envrc` at its root that activates the Nix flak
|
||||
> [!NOTE]
|
||||
> direnv only caches the `.direnv` directory (already listed in `.gitignore`); no other repository files are affected.
|
||||
|
||||
## Conan and Prebuilt Packages
|
||||
|
||||
Please note that there is no guarantee that binaries from conan cache will work when using nix. If you encounter any errors, please use `--build '*'` to force conan to compile everything from source:
|
||||
|
||||
```bash
|
||||
conan install .. --output-folder . --build '*' --settings build_type=Release
|
||||
```
|
||||
|
||||
## Updating `flake.lock` file
|
||||
|
||||
To update `flake.lock` to the latest revision use `nix flake update` command.
|
||||
|
||||
## Tooling snapshots
|
||||
|
||||
The tool versions in each Nix environment are recorded in
|
||||
[`nix/check-tools/`](../../nix/check-tools) and verified by CI. If you change the
|
||||
environment (bump the CI image tag, update `flake.lock`, or edit the tool list in
|
||||
`bin/check-tools.sh`), CI fails until you regenerate and commit the affected
|
||||
snapshot — see [`nix/check-tools/README.md`](../../nix/check-tools/README.md).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
See [Troubleshooting Nix problems](./nix_troubleshooting.md) for common issues,
|
||||
|
||||
160
docs/build/nix_troubleshooting.md
vendored
160
docs/build/nix_troubleshooting.md
vendored
@@ -3,6 +3,78 @@
|
||||
Common issues encountered when using the [Nix development shell](./nix.md), and
|
||||
how to resolve them.
|
||||
|
||||
## `command not found: nix` after a macOS update
|
||||
|
||||
If a shell suddenly can't find `nix` at all:
|
||||
|
||||
```
|
||||
$ nix develop
|
||||
zsh: command not found: nix
|
||||
```
|
||||
|
||||
then Nix is almost certainly still installed — only the shell hook that puts it
|
||||
on your `PATH` is gone. Confirm that first:
|
||||
|
||||
```bash
|
||||
ls -l /nix/var/nix/profiles/default/bin/nix
|
||||
```
|
||||
|
||||
If that exists, the installation is fine and this is purely a `PATH` problem.
|
||||
|
||||
### Why it happens
|
||||
|
||||
The installer does not touch your dotfiles. Instead it sources a setup script
|
||||
from the Nix store by editing **system-wide** rc files:
|
||||
|
||||
| Shell | File the installer edits |
|
||||
| ----- | ------------------------------------- |
|
||||
| bash | `/etc/bashrc`, `/etc/bash.bashrc` |
|
||||
| zsh | `/etc/zshrc` |
|
||||
| fish | `$__fish_sysconf_dir/conf.d/nix.fish` |
|
||||
|
||||
macOS manages `/etc/zshrc`, so an OS update can replace it with the vendor copy
|
||||
and silently drop the Nix block. `/etc/bashrc` and the fish file usually survive,
|
||||
which is why the breakage often shows up in zsh only. You can verify this by
|
||||
diffing against the backup the installer left behind:
|
||||
|
||||
```bash
|
||||
diff /etc/zshrc /etc/zshrc.backup-before-nix
|
||||
```
|
||||
|
||||
If they are identical, the Nix snippet was wiped. This is upstream issue
|
||||
[NixOS/nix#3616](https://github.com/NixOS/nix/issues/3616).
|
||||
|
||||
### Fix
|
||||
|
||||
To unblock the current shell:
|
||||
|
||||
```bash
|
||||
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
|
||||
```
|
||||
|
||||
For a permanent fix, add the snippet to your **user** rc file rather than
|
||||
restoring `/etc/zshrc` — user dotfiles are not clobbered by OS updates:
|
||||
|
||||
```bash
|
||||
cat >>~/.zshrc <<'EOF'
|
||||
|
||||
# Nix
|
||||
if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
|
||||
. '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
|
||||
fi
|
||||
# End Nix
|
||||
EOF
|
||||
```
|
||||
|
||||
The scripts guard against double-sourcing via `__ETC_PROFILE_NIX_SOURCED`, so
|
||||
this is safe even if a system-wide hook is later restored.
|
||||
|
||||
> [!NOTE]
|
||||
> `/etc/zshrc` and `~/.zshrc` are only read by **interactive** zsh. If the
|
||||
> snippet is present but `zsh -c '…'`, a script, or an IDE terminal still can't
|
||||
> find `nix`, that shell is non-interactive — put the snippet in `~/.zshenv`
|
||||
> instead.
|
||||
|
||||
## Git worktrees
|
||||
|
||||
If `nix develop` fails with an error like:
|
||||
@@ -59,3 +131,91 @@ once it picks up that rebuild, then re-run the `grep libgit2` check above to
|
||||
confirm it reports `1.9.4` or newer.
|
||||
|
||||
Until then, prefer the workarounds above.
|
||||
|
||||
## `wint_t` / `uint32_t` errors from the Nix libc++ headers
|
||||
|
||||
A build that mixes the Nix toolchain with the system SDK fails in libc++ itself,
|
||||
with errors that look nothing like your code:
|
||||
|
||||
```
|
||||
/nix/store/...-libcxx-.../include/c++/v1/cwchar:136:9: error: target of using declaration conflicts with declaration already in scope
|
||||
136 | using ::wint_t _LIBCPP_USING_IF_EXISTS;
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types/_wint_t.h:32:25: note: target of using declaration
|
||||
...
|
||||
error: use of undeclared identifier 'UINT32_C'
|
||||
```
|
||||
|
||||
The give-away is the second path: Nix's libc++ headers are being combined with
|
||||
the **Xcode Command Line Tools** SDK instead of the Nix one.
|
||||
|
||||
### Why it happens
|
||||
|
||||
`SDKROOT` and `DEVELOPER_DIR` are what point the toolchain at the Nix SDK, and
|
||||
they are not baked into the compiler — a dev shell gets them from the
|
||||
`apple-sdk` setup hook. CMake, finding neither, asks `xcrun`, which answers with
|
||||
the system SDK. Nix's `libc++` and Apple's headers then declare the same types
|
||||
twice.
|
||||
|
||||
### Fix
|
||||
|
||||
Run the build from inside the dev shell (`nix develop`), or from an environment
|
||||
that exports both variables. To confirm which SDK a configured build is using:
|
||||
|
||||
```bash
|
||||
grep -o '\-isysroot [^ ]*' build/compile_commands.json | sort -u
|
||||
```
|
||||
|
||||
It should print a `/nix/store/...-apple-sdk-*` path. If it prints
|
||||
`/Library/Developer/CommandLineTools/...`, re-configure from within the shell —
|
||||
CMake caches the sysroot, so an existing `build/` directory keeps the wrong one.
|
||||
|
||||
## `Library not loaded: /nix/store/…` from a binary that used to work
|
||||
|
||||
A binary stops starting after a `nix flake update`, or after
|
||||
`nix-collect-garbage` removes the paths the previous toolchain used:
|
||||
|
||||
```
|
||||
dyld[57271]: Library not loaded: /nix/store/…-libresolv-93/lib/libresolv.9.dylib
|
||||
```
|
||||
|
||||
[`bin/check-nix-store-refs.sh`](../../bin/check-nix-store-refs.sh) finds the same
|
||||
thing without having to run anything, and names the file:
|
||||
|
||||
```
|
||||
$ bin/check-nix-store-refs.sh ~/.conan2-nix
|
||||
::error file=/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig::references the Nix store at run time
|
||||
/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig
|
||||
/nix/store/p4lp3xq4imd1qzqh08x8vcq2zfhi7rca-libresolv-93/lib/libresolv.9.dylib
|
||||
/Users/you/.conan2-nix: checked 135, skipped 2495, 1 with Nix store references.
|
||||
```
|
||||
|
||||
Conan's cache folders are named after a truncated package name plus a hash, so
|
||||
ask Conan which package the offending one belongs to — pass the folder holding
|
||||
the hash, not the file itself:
|
||||
|
||||
```
|
||||
$ conan cache ref ~/.conan2-nix/p/b/c-area24ded30c388c
|
||||
c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650:dab5992496abe6d219defb7986ecbf367615a5e5#…
|
||||
```
|
||||
|
||||
### Why it happens
|
||||
|
||||
The binary records a store path that no longer exists. Nothing we build should:
|
||||
see [Prebuilt packages](./nix.md#prebuilt-packages) for why, and
|
||||
`libresolvSystemStub` in [`nix/darwin.nix`](../../nix/darwin.nix) for the one
|
||||
dependency that needed help to comply.
|
||||
|
||||
A Conan package ID does not encode the nixpkgs revision, so a package built
|
||||
before that stub existed stays in your local cache and keeps being reused. The
|
||||
dev shell is also what tends to produce one: it is a slightly _less_ isolated
|
||||
build environment than CI's, because `mkShell` puts every tool's headers and
|
||||
libraries on the compiler's search path — which is how c-ares found the Nix
|
||||
`libresolv` in the first place.
|
||||
|
||||
### Fix
|
||||
|
||||
Drop that package and let Conan refetch or rebuild it:
|
||||
|
||||
```bash
|
||||
conan remove 'c-ares/*'
|
||||
```
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/*!
|
||||
\page somestatechart Example state diagram
|
||||
|
||||
\startuml SomeState "my state diagram"
|
||||
scale 600 width
|
||||
|
||||
[*] -> State1
|
||||
State1 --> State2 : Succeeded
|
||||
State1 --> [*] : Aborted
|
||||
State2 --> State3 : Succeeded
|
||||
State2 --> [*] : Aborted
|
||||
state State3 {
|
||||
state "Accumulate Enough Data\nLong State Name" as long1
|
||||
long1 : Just a test
|
||||
[*] --> long1
|
||||
long1 --> long1 : New Data
|
||||
long1 --> ProcessData : Enough Data
|
||||
}
|
||||
State3 --> State3 : Failed
|
||||
State3 --> [*] : Succeeded / Save Result
|
||||
State3 --> [*] : Aborted
|
||||
|
||||
\enduml
|
||||
*/
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -13,6 +13,6 @@ namespace xrpl {
|
||||
* @throws runtime_error
|
||||
*/
|
||||
void
|
||||
extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const& dst);
|
||||
extractTarLz4(std::filesystem::path const& src, std::filesystem::path const& dst);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
@@ -156,6 +157,19 @@ public:
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Set every byte in the buffer to the given value.
|
||||
*
|
||||
* The size is unchanged, and this is a no-op on an empty buffer.
|
||||
*
|
||||
* @param value the byte to write to every position.
|
||||
*/
|
||||
void
|
||||
fill(std::uint8_t value) noexcept
|
||||
{
|
||||
std::fill_n(p_.get(), size_, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the buffer.
|
||||
* All memory is deallocated. The resulting size is 0.
|
||||
@@ -226,10 +240,4 @@ operator==(Buffer const& lhs, Buffer const& rhs) noexcept
|
||||
return std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(Buffer const& lhs, Buffer const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -1,24 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
std::string
|
||||
getFileContents(
|
||||
boost::system::error_code& ec,
|
||||
boost::filesystem::path const& sourcePath,
|
||||
std::error_code& ec,
|
||||
std::filesystem::path const& sourcePath,
|
||||
std::optional<std::size_t> maxSize = std::nullopt);
|
||||
|
||||
void
|
||||
writeFileContents(
|
||||
boost::system::error_code& ec,
|
||||
boost::filesystem::path const& destPath,
|
||||
std::error_code& ec,
|
||||
std::filesystem::path const& destPath,
|
||||
std::string const& contents);
|
||||
|
||||
/**
|
||||
* Generate a unique, non-existing path under @p base whose filename starts with
|
||||
* @p prefix and ends with a random hex suffix.
|
||||
*
|
||||
* Attempts up to @p maxAttempts paths. Throws `std::runtime_error` if a unique
|
||||
* path cannot be found or if the filesystem returns an error while checking for
|
||||
* existence.
|
||||
*/
|
||||
std::filesystem::path
|
||||
uniqueRandomPath(
|
||||
std::filesystem::path const& base,
|
||||
std::string const& prefix = "",
|
||||
std::size_t maxAttempts = 100);
|
||||
|
||||
/**
|
||||
* RAII temporary directory.
|
||||
*
|
||||
* The directory and all its contents are deleted when
|
||||
* the instance of `TempDir` is destroyed.
|
||||
*/
|
||||
class TempDir
|
||||
{
|
||||
std::filesystem::path path_;
|
||||
|
||||
public:
|
||||
#if !GENERATING_DOCS
|
||||
TempDir(TempDir const&) = delete;
|
||||
TempDir&
|
||||
operator=(TempDir const&) = delete;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Construct a temporary directory.
|
||||
*/
|
||||
TempDir();
|
||||
|
||||
/**
|
||||
* Destroy a temporary directory.
|
||||
*/
|
||||
~TempDir();
|
||||
|
||||
/**
|
||||
* Get the native path for the temporary directory.
|
||||
*/
|
||||
[[nodiscard]] std::string
|
||||
path() const;
|
||||
|
||||
/**
|
||||
* Get the native path for a file.
|
||||
*
|
||||
* The file does not need to exist.
|
||||
*/
|
||||
[[nodiscard]] std::string
|
||||
file(std::string const& name) const;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -96,9 +96,6 @@ public:
|
||||
SharedIntrusive&
|
||||
operator=(SharedIntrusive const& rhs);
|
||||
|
||||
bool
|
||||
operator!=(std::nullptr_t) const;
|
||||
|
||||
bool
|
||||
operator==(std::nullptr_t) const;
|
||||
|
||||
|
||||
@@ -111,13 +111,6 @@ SharedIntrusive<T>::operator=(SharedIntrusive<TT>&& rhs)
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool
|
||||
SharedIntrusive<T>::operator!=(std::nullptr_t) const
|
||||
{
|
||||
return this->get() != nullptr;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool
|
||||
SharedIntrusive<T>::operator==(std::nullptr_t) const
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
|
||||
#include <boost/beast/core/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -84,7 +84,7 @@ private:
|
||||
* @return `true` if the file was opened.
|
||||
*/
|
||||
bool
|
||||
open(boost::filesystem::path const& path);
|
||||
open(std::filesystem::path const& path);
|
||||
|
||||
/**
|
||||
* Close and re-open the system file associated with the log
|
||||
@@ -133,7 +133,7 @@ private:
|
||||
|
||||
private:
|
||||
std::unique_ptr<std::ofstream> stream_;
|
||||
boost::filesystem::path path_;
|
||||
std::filesystem::path path_;
|
||||
};
|
||||
|
||||
std::mutex mutable mutex_;
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
virtual ~Logs() = default;
|
||||
|
||||
bool
|
||||
open(boost::filesystem::path const& pathToLogFile);
|
||||
open(std::filesystem::path const& pathToLogFile);
|
||||
|
||||
beast::Journal::Sink&
|
||||
get(std::string const& name);
|
||||
|
||||
@@ -304,7 +304,7 @@ concept Integral64 = std::is_same_v<T, std::int64_t> || std::is_same_v<T, std::u
|
||||
* on-ledger are non-negative. This is due to implementation details of
|
||||
* several operations which use unsigned arithmetic internally. This is
|
||||
* sufficient to represent all valid XRP values (where the absolute value
|
||||
* can not exceed INITIAL_XRP: 10^17), and MPT values (where the absolute
|
||||
* can not exceed kInitialXRP: 10^17), and MPT values (where the absolute
|
||||
* value can not exceed maxMPTokenAmount: 2^63-1).
|
||||
*
|
||||
* ---- Mantissa Range Switching ----
|
||||
@@ -449,12 +449,6 @@ public:
|
||||
x.exponent_ == y.exponent_;
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator!=(Number const& x, Number const& y) noexcept
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator<(Number const& l, Number const& r) noexcept
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace xrpl {
|
||||
class Resolver
|
||||
{
|
||||
public:
|
||||
using HandlerType = std::function<void(std::string, std::vector<beast::IP::Endpoint>)>;
|
||||
using HandlerType = std::function<void(std::string, std::vector<beast::ip::Endpoint>)>;
|
||||
|
||||
virtual ~Resolver() = 0;
|
||||
|
||||
|
||||
@@ -85,12 +85,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator!=(SHAMapHash const& x, SHAMapHash const& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::size_t
|
||||
extract(SHAMapHash const& key)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
@@ -207,12 +208,6 @@ operator==(Slice const& lhs, Slice const& rhs) noexcept
|
||||
return std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(Slice const& lhs, Slice const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(Slice const& lhs, Slice const& rhs) noexcept
|
||||
{
|
||||
@@ -251,4 +246,11 @@ makeSlice(std::basic_string<char, Traits, Alloc> const& s)
|
||||
return Slice(s.data(), s.size());
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
Slice
|
||||
makeSlice(std::basic_string_view<char, Traits> s)
|
||||
{
|
||||
return Slice(s.data(), s.size());
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <xrpl/basics/Blob.h>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
#include <array>
|
||||
@@ -125,9 +124,31 @@ struct ParsedUrl
|
||||
bool
|
||||
parseUrl(ParsedUrl& pUrl, std::string const& strUrl);
|
||||
|
||||
/**
|
||||
* Remove leading and trailing ASCII whitespace.
|
||||
*
|
||||
* Whitespace is the fixed set " \t\n\v\f\r"; the current locale is not
|
||||
* consulted, so the result depends only on the input.
|
||||
*
|
||||
* @param str The string to trim.
|
||||
* @return @p str without leading or trailing whitespace.
|
||||
*/
|
||||
std::string
|
||||
trimWhitespace(std::string str);
|
||||
|
||||
/**
|
||||
* Fold ASCII upper case letters to lower case.
|
||||
*
|
||||
* Only 'A' through 'Z' are remapped; every other byte is left alone and the
|
||||
* current locale is not consulted, so the result depends only on the input.
|
||||
*
|
||||
* @param str The string to fold.
|
||||
* @return @p str with each ASCII upper case letter replaced by its lower case
|
||||
* equivalent.
|
||||
*/
|
||||
std::string
|
||||
toLower(std::string str);
|
||||
|
||||
std::optional<std::uint64_t>
|
||||
toUInt64(std::string const& s);
|
||||
|
||||
|
||||
@@ -41,6 +41,35 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
namespace base64 {
|
||||
|
||||
/**
|
||||
* Returns the maximum number of characters needed to base64-encode @p nBytes bytes.
|
||||
*
|
||||
* @param nBytes Number of input bytes.
|
||||
* @return Size of the encoded string, including padding.
|
||||
*/
|
||||
constexpr std::size_t
|
||||
encodedSize(std::size_t const nBytes)
|
||||
{
|
||||
return 4 * ((nBytes + 2) / 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of bytes a base64 string of @p numChars characters
|
||||
* decodes to.
|
||||
*
|
||||
* @param numChars Number of base64 characters.
|
||||
* @return Upper bound on the number of decoded bytes.
|
||||
*/
|
||||
constexpr std::size_t
|
||||
decodedSize(std::size_t const numChars)
|
||||
{
|
||||
return ((numChars / 4) * 3) + 2;
|
||||
}
|
||||
|
||||
} // namespace base64
|
||||
|
||||
std::string
|
||||
base64Encode(std::uint8_t const* data, std::size_t len);
|
||||
|
||||
|
||||
@@ -116,12 +116,6 @@ public:
|
||||
{
|
||||
return lhs.map == rhs.map && lhs.ait == rhs.ait && lhs.mit == rhs.mit;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(Iterator const& lhs, Iterator const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
struct ConstIterator
|
||||
@@ -189,12 +183,6 @@ public:
|
||||
{
|
||||
return lhs.map == rhs.map && lhs.ait == rhs.ait && lhs.mit == rhs.mit;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(ConstIterator const& lhs, ConstIterator const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
@@ -1038,25 +1038,6 @@ public:
|
||||
Compare,
|
||||
OtherAllocator> const& other) const;
|
||||
|
||||
template <
|
||||
bool OtherIsMulti,
|
||||
bool OtherIsMap,
|
||||
class OtherT,
|
||||
class OtherDuration,
|
||||
class OtherAllocator>
|
||||
bool
|
||||
operator!=(AgedOrderedContainer<
|
||||
OtherIsMulti,
|
||||
OtherIsMap,
|
||||
Key,
|
||||
OtherT,
|
||||
OtherDuration,
|
||||
Compare,
|
||||
OtherAllocator> const& other) const
|
||||
{
|
||||
return !(this->operator==(other));
|
||||
}
|
||||
|
||||
template <
|
||||
bool OtherIsMulti,
|
||||
bool OtherIsMap,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/container/detail/aged_associative_container.h>
|
||||
#include <xrpl/beast/container/detail/aged_container_iterator.h>
|
||||
#include <xrpl/beast/container/detail/empty_base_optimization.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/intrusive/unordered_set.hpp>
|
||||
@@ -1339,28 +1340,6 @@ public:
|
||||
OtherAllocator> const& other) const
|
||||
requires MaybeMulti;
|
||||
|
||||
template <
|
||||
bool OtherIsMulti,
|
||||
bool OtherIsMap,
|
||||
class OtherKey,
|
||||
class OtherT,
|
||||
class OtherDuration,
|
||||
class OtherHash,
|
||||
class OtherAllocator>
|
||||
bool
|
||||
operator!=(AgedUnorderedContainer<
|
||||
OtherIsMulti,
|
||||
OtherIsMap,
|
||||
OtherKey,
|
||||
OtherT,
|
||||
OtherDuration,
|
||||
OtherHash,
|
||||
KeyEqual,
|
||||
OtherAllocator> const& other) const
|
||||
{
|
||||
return !(this->operator==(other));
|
||||
}
|
||||
|
||||
private:
|
||||
bool
|
||||
wouldExceed(size_type additional) const
|
||||
|
||||
@@ -58,7 +58,7 @@ struct LexicalCast<Out, std::string_view>
|
||||
"beast::LexicalCast can only be used with integral types");
|
||||
|
||||
template <class Integral = Out>
|
||||
bool
|
||||
constexpr bool
|
||||
operator()(Integral& out, std::string_view in) const
|
||||
requires(std::is_integral_v<Integral> && !std::is_same_v<Integral, bool>)
|
||||
{
|
||||
@@ -110,7 +110,7 @@ struct LexicalCast<Out, boost::core::basic_string_view<char>>
|
||||
{
|
||||
explicit LexicalCast() = default;
|
||||
|
||||
bool
|
||||
constexpr bool
|
||||
operator()(Out& out, boost::core::basic_string_view<char> in) const
|
||||
{
|
||||
return LexicalCast<Out, std::string_view>()(out, in);
|
||||
@@ -123,7 +123,7 @@ struct LexicalCast<Out, std::string>
|
||||
{
|
||||
explicit LexicalCast() = default;
|
||||
|
||||
bool
|
||||
constexpr bool
|
||||
operator()(Out& out, std::string in) const
|
||||
{
|
||||
return LexicalCast<Out, std::string_view>()(out, in);
|
||||
@@ -136,7 +136,7 @@ struct LexicalCast<Out, char const*>
|
||||
{
|
||||
explicit LexicalCast() = default;
|
||||
|
||||
bool
|
||||
constexpr bool
|
||||
operator()(Out& out, char const* in) const
|
||||
{
|
||||
XRPL_ASSERT(in, "beast::detail::LexicalCast(char const*) : non-null input");
|
||||
@@ -151,7 +151,7 @@ struct LexicalCast<Out, char*>
|
||||
{
|
||||
explicit LexicalCast() = default;
|
||||
|
||||
bool
|
||||
constexpr bool
|
||||
operator()(Out& out, char* in) const
|
||||
{
|
||||
XRPL_ASSERT(in, "beast::detail::LexicalCast(char*) : non-null input");
|
||||
@@ -177,7 +177,7 @@ struct BadLexicalCast : public std::bad_cast
|
||||
* @return `false` if there was a parsing or range error
|
||||
*/
|
||||
template <class Out, class In>
|
||||
bool
|
||||
constexpr bool
|
||||
lexicalCastChecked(Out& out, In in)
|
||||
{
|
||||
return detail::LexicalCast<Out, In>()(out, in);
|
||||
@@ -191,7 +191,7 @@ lexicalCastChecked(Out& out, In in)
|
||||
* @return The new type.
|
||||
*/
|
||||
template <class Out, class In>
|
||||
Out
|
||||
constexpr Out
|
||||
lexicalCastThrow(In in)
|
||||
{
|
||||
if (Out out; lexicalCastChecked(out, in))
|
||||
@@ -207,7 +207,7 @@ lexicalCastThrow(In in)
|
||||
* @return The new type.
|
||||
*/
|
||||
template <class Out, class In>
|
||||
Out
|
||||
constexpr Out
|
||||
lexicalCast(In in, Out defaultValue = Out())
|
||||
{
|
||||
if (Out out; lexicalCastChecked(out, in))
|
||||
|
||||
@@ -82,13 +82,6 @@ public:
|
||||
return node_ == other.node_;
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
bool
|
||||
operator!=(ListIterator<M> const& other) const noexcept
|
||||
{
|
||||
return !((*this) == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const noexcept
|
||||
{
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace beast {
|
||||
class SemanticVersion
|
||||
{
|
||||
public:
|
||||
using identifier_list = std::vector<std::string>;
|
||||
using IdentifierList = std::vector<std::string>;
|
||||
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
int patchVersion;
|
||||
|
||||
identifier_list preReleaseIdentifiers;
|
||||
identifier_list metaData;
|
||||
IdentifierList preReleaseIdentifiers;
|
||||
IdentifierList metaData;
|
||||
|
||||
SemanticVersion();
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
* @param journal Destination for logging output.
|
||||
*/
|
||||
static std::shared_ptr<StatsDCollector>
|
||||
make(IP::Endpoint const& address, std::string const& prefix, Journal journal);
|
||||
make(ip::Endpoint const& address, std::string const& prefix, Journal journal);
|
||||
};
|
||||
|
||||
} // namespace beast::insight
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace beast {
|
||||
namespace IP {
|
||||
namespace ip {
|
||||
|
||||
using Address = boost::asio::ip::address;
|
||||
|
||||
@@ -73,13 +73,13 @@ isPublic(Address const& addr)
|
||||
return (addr.is_v4()) ? isPublic(addr.to_v4()) : isPublic(addr.to_v6());
|
||||
}
|
||||
|
||||
} // namespace IP
|
||||
} // namespace ip
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Hasher>
|
||||
void
|
||||
hash_append(Hasher& h, beast::IP::Address const& addr) noexcept
|
||||
hash_append(Hasher& h, beast::ip::Address const& addr) noexcept
|
||||
{
|
||||
using beast::hash_append;
|
||||
if (addr.is_v4())
|
||||
@@ -101,12 +101,12 @@ hash_append(Hasher& h, beast::IP::Address const& addr) noexcept
|
||||
|
||||
namespace boost {
|
||||
template <>
|
||||
struct hash<::beast::IP::Address>
|
||||
struct hash<::beast::ip::Address>
|
||||
{
|
||||
explicit hash() = default;
|
||||
|
||||
std::size_t
|
||||
operator()(::beast::IP::Address const& addr) const
|
||||
operator()(::beast::ip::Address const& addr) const
|
||||
{
|
||||
return ::beast::Uhash<>{}(addr);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace beast::IP {
|
||||
namespace beast::ip {
|
||||
|
||||
/**
|
||||
* Convert to Endpoint.
|
||||
@@ -32,7 +32,7 @@ toAsioAddress(Endpoint const& endpoint);
|
||||
boost::asio::ip::tcp::endpoint
|
||||
toAsioEndpoint(Endpoint const& endpoint);
|
||||
|
||||
} // namespace beast::IP
|
||||
} // namespace beast::ip
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -41,25 +41,25 @@ struct IPAddressConversion
|
||||
{
|
||||
explicit IPAddressConversion() = default;
|
||||
|
||||
static IP::Endpoint
|
||||
static ip::Endpoint
|
||||
fromAsio(boost::asio::ip::address const& address)
|
||||
{
|
||||
return IP::fromAsio(address);
|
||||
return ip::fromAsio(address);
|
||||
}
|
||||
static IP::Endpoint
|
||||
static ip::Endpoint
|
||||
fromAsio(boost::asio::ip::tcp::endpoint const& endpoint)
|
||||
{
|
||||
return IP::fromAsio(endpoint);
|
||||
return ip::fromAsio(endpoint);
|
||||
}
|
||||
static boost::asio::ip::address
|
||||
toAsioAddress(IP::Endpoint const& address)
|
||||
toAsioAddress(ip::Endpoint const& address)
|
||||
{
|
||||
return IP::toAsioAddress(address);
|
||||
return ip::toAsioAddress(address);
|
||||
}
|
||||
static boost::asio::ip::tcp::endpoint
|
||||
toAsioEndpoint(IP::Endpoint const& address)
|
||||
toAsioEndpoint(ip::Endpoint const& address)
|
||||
{
|
||||
return IP::toAsioEndpoint(address);
|
||||
return ip::toAsioEndpoint(address);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <boost/asio/ip/address_v4.hpp>
|
||||
|
||||
namespace beast::IP {
|
||||
namespace beast::ip {
|
||||
|
||||
using AddressV4 = boost::asio::ip::address_v4;
|
||||
|
||||
@@ -25,4 +25,4 @@ isPublic(AddressV4 const& addr);
|
||||
char
|
||||
getClass(AddressV4 const& address);
|
||||
|
||||
} // namespace beast::IP
|
||||
} // namespace beast::ip
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <boost/asio/ip/address_v6.hpp>
|
||||
|
||||
namespace beast::IP {
|
||||
namespace beast::ip {
|
||||
|
||||
using AddressV6 = boost::asio::ip::address_v6;
|
||||
|
||||
@@ -18,4 +18,4 @@ isPrivate(AddressV6 const& addr);
|
||||
bool
|
||||
isPublic(AddressV6 const& addr);
|
||||
|
||||
} // namespace beast::IP
|
||||
} // namespace beast::ip
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace beast::IP {
|
||||
namespace beast::ip {
|
||||
|
||||
using Port = std::uint16_t;
|
||||
|
||||
@@ -110,12 +110,6 @@ public:
|
||||
operator==(Endpoint const& lhs, Endpoint const& rhs);
|
||||
friend bool
|
||||
operator<(Endpoint const& lhs, Endpoint const& rhs);
|
||||
|
||||
friend bool
|
||||
operator!=(Endpoint const& lhs, Endpoint const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
friend bool
|
||||
operator>(Endpoint const& lhs, Endpoint const& rhs)
|
||||
{
|
||||
@@ -223,7 +217,7 @@ operator<<(OutputStream& os, Endpoint const& endpoint)
|
||||
std::istream&
|
||||
operator>>(std::istream& is, Endpoint& endpoint);
|
||||
|
||||
} // namespace beast::IP
|
||||
} // namespace beast::ip
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -232,12 +226,12 @@ namespace std {
|
||||
* std::hash support.
|
||||
*/
|
||||
template <>
|
||||
struct hash<::beast::IP::Endpoint>
|
||||
struct hash<::beast::ip::Endpoint>
|
||||
{
|
||||
hash() = default;
|
||||
|
||||
std::size_t
|
||||
operator()(::beast::IP::Endpoint const& endpoint) const
|
||||
operator()(::beast::ip::Endpoint const& endpoint) const
|
||||
{
|
||||
return ::beast::Uhash<>{}(endpoint);
|
||||
}
|
||||
@@ -249,12 +243,12 @@ namespace boost {
|
||||
* boost::hash support.
|
||||
*/
|
||||
template <>
|
||||
struct hash<::beast::IP::Endpoint>
|
||||
struct hash<::beast::ip::Endpoint>
|
||||
{
|
||||
hash() = default;
|
||||
|
||||
std::size_t
|
||||
operator()(::beast::IP::Endpoint const& endpoint) const
|
||||
operator()(::beast::ip::Endpoint const& endpoint) const
|
||||
{
|
||||
return ::beast::Uhash<>{}(endpoint);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace beast::rfc2616 {
|
||||
@@ -186,7 +187,7 @@ splitCommas(FwdIt first, FwdIt last)
|
||||
|
||||
template <class Result = std::vector<std::string>>
|
||||
Result
|
||||
splitCommas(boost::beast::string_view const& s)
|
||||
splitCommas(std::string_view s)
|
||||
{
|
||||
return splitCommas(s.begin(), s.end());
|
||||
}
|
||||
@@ -229,12 +230,6 @@ public:
|
||||
return other.it_ == it_ && other.end_ == end_ && other.value_.size() == value_.size();
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(ListIterator const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <xrpl/beast/unit_test/runner.h>
|
||||
#include <xrpl/beast/unit_test/suite_info.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -188,7 +187,7 @@ Reporter<Unused>::fmtdur(clock_type::duration const& d)
|
||||
using namespace std::chrono;
|
||||
auto const ms = duration_cast<milliseconds>(d);
|
||||
if (ms < seconds{1})
|
||||
return boost::lexical_cast<std::string>(ms.count()) + "ms";
|
||||
return std::to_string(ms.count()) + "ms";
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(1) << (ms.count() / 1000.) << "s";
|
||||
return ss.str();
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
|
||||
#include <xrpl/beast/unit_test/runner.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <exception>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
@@ -27,10 +26,10 @@ makeReason(String const& reason, char const* file, int line)
|
||||
std::string s(reason);
|
||||
if (!s.empty())
|
||||
s.append(": ");
|
||||
namespace fs = boost::filesystem;
|
||||
namespace fs = std::filesystem;
|
||||
s.append(fs::path{file}.filename().string());
|
||||
s.append("(");
|
||||
s.append(boost::lexical_cast<std::string>(line));
|
||||
s.append(std::to_string(line));
|
||||
s.append(")");
|
||||
return s;
|
||||
}
|
||||
@@ -295,6 +294,20 @@ public:
|
||||
return runner_->arg();
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Lets a suite compose other suites (e.g. an aggregator that reruns a
|
||||
* group of related suites under its own name) via `SuiteInfo::run`.
|
||||
*
|
||||
* @return The runner this suite is executing under.
|
||||
*/
|
||||
Runner&
|
||||
runner() const
|
||||
{
|
||||
return *runner_;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* DEPRECATED
|
||||
* @return `true` if the test condition indicates success(a false value)
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/**
|
||||
* RAII temporary directory.
|
||||
*
|
||||
* The directory and all its contents are deleted when
|
||||
* the instance of `temp_dir` is destroyed.
|
||||
*/
|
||||
class TempDir
|
||||
{
|
||||
boost::filesystem::path path_;
|
||||
|
||||
public:
|
||||
#if !GENERATING_DOCS
|
||||
TempDir(TempDir const&) = delete;
|
||||
TempDir&
|
||||
operator=(TempDir const&) = delete;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Construct a temporary directory.
|
||||
*/
|
||||
TempDir()
|
||||
{
|
||||
auto const dir = boost::filesystem::temp_directory_path();
|
||||
do
|
||||
{
|
||||
path_ = dir / boost::filesystem::unique_path();
|
||||
} while (boost::filesystem::exists(path_));
|
||||
boost::filesystem::create_directory(path_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a temporary directory.
|
||||
*/
|
||||
~TempDir()
|
||||
{
|
||||
// use non-throwing calls in the destructor
|
||||
boost::system::error_code ec;
|
||||
boost::filesystem::remove_all(path_, ec);
|
||||
// TODO: warn/notify if ec set ?
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the native path for the temporary directory
|
||||
*/
|
||||
[[nodiscard]] std::string
|
||||
path() const
|
||||
{
|
||||
return path_.string();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the native path for the a file.
|
||||
*
|
||||
* The file does not need to exist.
|
||||
*/
|
||||
[[nodiscard]] std::string
|
||||
file(std::string const& name) const
|
||||
{
|
||||
return (path_ / name).string();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
@@ -92,10 +92,4 @@ operator==(Condition const& lhs, Condition const& rhs)
|
||||
lhs.fingerprint == rhs.fingerprint;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(Condition const& lhs, Condition const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace xrpl::cryptoconditions
|
||||
|
||||
@@ -93,12 +93,6 @@ operator==(Fulfillment const& lhs, Fulfillment const& rhs)
|
||||
lhs.fingerprint() == rhs.fingerprint();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(Fulfillment const& lhs, Fulfillment const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given fulfillment and condition match
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <xrpl/basics/contract.h>
|
||||
|
||||
#include <boost/beast/core/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -25,6 +25,7 @@ struct Sections
|
||||
static constexpr auto kLedgerHistory = "ledger_history";
|
||||
static constexpr auto kLedgerReplay = "ledger_replay";
|
||||
static constexpr auto kLedgerTxTables = "ledger_tx_tables";
|
||||
static constexpr auto kMaxSubscriptionsPerConnection = "max_subscriptions_per_connection";
|
||||
static constexpr auto kMaxTransactions = "max_transactions";
|
||||
static constexpr auto kNetworkId = "network_id";
|
||||
static constexpr auto kNetworkQuorum = "network_quorum";
|
||||
@@ -118,7 +119,9 @@ struct Keys
|
||||
static constexpr auto kLogInterval = "log_interval";
|
||||
static constexpr auto kMaxDivergedTime = "max_diverged_time";
|
||||
static constexpr auto kMaxLedgerCountsToStore = "max_ledger_counts_to_store";
|
||||
static constexpr auto kMaxTrustedCount = "max_trusted_count";
|
||||
static constexpr auto kMaxUnknownTime = "max_unknown_time";
|
||||
static constexpr auto kMaxUntrustedCount = "max_untrusted_count";
|
||||
static constexpr auto kMaximumTxnInLedger = "maximum_txn_in_ledger";
|
||||
static constexpr auto kMaximumTxnPerAccount = "maximum_txn_per_account";
|
||||
static constexpr auto kMemoryLevel = "memory_level";
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace xrpl {
|
||||
|
||||
template <class TxID, class Sequence>
|
||||
class RCLCensorshipDetector
|
||||
class CensorshipDetector
|
||||
{
|
||||
public:
|
||||
struct TxIDSeq
|
||||
@@ -49,7 +49,7 @@ private:
|
||||
TxIDSeqVec tracker_;
|
||||
|
||||
public:
|
||||
RCLCensorshipDetector() = default;
|
||||
CensorshipDetector() = default;
|
||||
|
||||
/**
|
||||
* Add transactions being proposed for the current consensus round.
|
||||
@@ -1,15 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/consensus/ConsensusParms.h>
|
||||
#include <xrpld/consensus/ConsensusProposal.h>
|
||||
#include <xrpld/consensus/ConsensusTypes.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/clock/abstract_clock.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/consensus/ConsensusParms.h>
|
||||
#include <xrpl/consensus/ConsensusProposal.h>
|
||||
#include <xrpl/consensus/ConsensusTypes.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/json_writer.h>
|
||||
#include <xrpl/ledger/LedgerTiming.h>
|
||||
@@ -22,6 +21,7 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@@ -1580,7 +1580,13 @@ Consensus<Adaptor>::updateOurPositions(std::unique_ptr<std::stringstream> const&
|
||||
JLOG(j_.info()) << ss.str();
|
||||
CLOG(clog) << ss.str();
|
||||
|
||||
for (auto const& [t, v] : closeTimeVotes)
|
||||
// Walk the votes highest-time first so that, among close times tied
|
||||
// for the most votes, the earliest wins. The smaller value is the
|
||||
// safer choice: without close-time consensus this round, the winner
|
||||
// only updates our position for the next proposal, and a too-early
|
||||
// time is bounded below by the prior ledger's close time. Only the
|
||||
// tie-break changes; the bin with the most votes still wins.
|
||||
for (auto const& [t, v] : std::views::reverse(closeTimeVotes))
|
||||
{
|
||||
JLOG(j_.debug()) << "CCTime: seq "
|
||||
<< static_cast<std::uint32_t>(previousLedger_.seq()) + 1 << ": "
|
||||
@@ -1,15 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/consensus/ConsensusProposal.h>
|
||||
#include <xrpld/consensus/DisputedTx.h>
|
||||
|
||||
#include <xrpl/basics/UnorderedContainers.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/consensus/ConsensusProposal.h>
|
||||
#include <xrpl/consensus/DisputedTx.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -190,6 +191,75 @@ struct ConsensusCloseTimes
|
||||
NetClock::time_point self;
|
||||
};
|
||||
|
||||
/**
|
||||
* Offset of the network's close time relative to ours, using a weighted median.
|
||||
*
|
||||
* Treats the sample set as `{self x 1}` merged with `{t x w}` for each
|
||||
* `(t, w)` in `times.peers`, in time order, and returns `(median - self)`
|
||||
* in whole seconds. Uses the lower weighted median: the median is the
|
||||
* earliest time at which the running weight reaches half the total, so an
|
||||
* even total whose halfway point falls between two bins resolves to the
|
||||
* earlier bin.
|
||||
*
|
||||
* @param times Our own close time and the weighted close times of peers.
|
||||
* @return Weighted median of all close times minus our own, in whole seconds.
|
||||
*/
|
||||
inline std::chrono::seconds
|
||||
medianCloseOffset(ConsensusCloseTimes const& times)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
using time_point = NetClock::time_point;
|
||||
|
||||
std::int64_t totalWeight = 1;
|
||||
for (auto const& [_, w] : times.peers)
|
||||
totalWeight += w;
|
||||
|
||||
std::int64_t const halfWeight = (totalWeight + 1) / 2;
|
||||
|
||||
std::optional<time_point> median{};
|
||||
std::int64_t tally = 0;
|
||||
bool selfPlaced = false;
|
||||
|
||||
// Accumulate weight in time order; the first bin to reach halfWeight is
|
||||
// the (lower) weighted median. Returns true once that bin is found.
|
||||
auto step = [&](time_point t, std::int64_t w) {
|
||||
XRPL_ASSERT(tally < halfWeight, "xrpl::medianCloseOffset::step : median not yet found");
|
||||
tally += w;
|
||||
if (tally >= halfWeight)
|
||||
{
|
||||
median = t;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
for (auto const& [t, w] : times.peers)
|
||||
{
|
||||
if (!selfPlaced && times.self <= t)
|
||||
{
|
||||
selfPlaced = true;
|
||||
if (step(times.self, 1))
|
||||
break;
|
||||
}
|
||||
if (step(t, w))
|
||||
break;
|
||||
}
|
||||
if (!selfPlaced && !median)
|
||||
step(times.self, 1);
|
||||
|
||||
if (!median)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
UNREACHABLE("xrpl::medianCloseOffset : median not found");
|
||||
median = times.self;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
return duration_cast<seconds>(
|
||||
duration<std::int64_t>{median->time_since_epoch().count()} -
|
||||
duration<std::int64_t>{times.self.time_since_epoch().count()});
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we have or don't have a consensus
|
||||
*/
|
||||
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/consensus/ConsensusParms.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/consensus/ConsensusParms.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/json_writer.h>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user