Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions .github/workflows/backward_compat_pr_change_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# On PR: when snapshot files are modified, generates a diff report between
# the base branch and the PR snapshots, then posts it as a PR comment.
# Helps reviewers understand what versioned types changed.
name: backward_compat_pr_change_report

on:
pull_request:
paths:
- 'utils/tfhe-lints/snapshots/lint_enum_snapshots_*.json'

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true

jobs:
change-report:
name: backward_compat_pr_change_report/change-report
runs-on: ubuntu-latest
permissions:
pull-requests: write # To send and modify message in the PR
steps:
- name: Checkout PR head
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: 'false'
path: head

- name: Checkout base branch
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: 'false'
ref: ${{ github.event.pull_request.base.sha }}
path: base

- name: Generate diff report
id: report
run: |
cd head && make backward_snapshot_report \
BASE_SNAPSHOT_DIR=../base/utils/tfhe-lints/snapshots \
HEAD_SNAPSHOT_DIR=utils/tfhe-lints/snapshots \
OUTPUT_FILE=../report.md

if [ -s ../report.md ]; then
echo "has_report=true" >> "$GITHUB_OUTPUT"
elif [ -f ../report.md ]; then
echo "has_report=false" >> "$GITHUB_OUTPUT"
else
echo "::error::report.md was not created — something went wrong"
exit 1
fi

- name: Find existing comment
id: find-comment
uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.1.0
with:
issue-number: ${{ github.event.pull_request.number }}
body-includes: '**Backward-compat snapshot:'

- name: Comment on PR
if: steps.report.outputs.has_report == 'true'
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body-path: report.md
edit-mode: replace
54 changes: 54 additions & 0 deletions .github/workflows/backward_compat_snapshot_consistency.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Generates snapshots from code and diffs against committed base files.
# Ensures snapshots are up to date on PRs and catches stale ones on main.
name: backward_compat_snapshot_consistency

env:
CARGO_TERM_COLOR: always
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
RUST_BACKTRACE: "full"
RUST_MIN_STACK: "8388608"
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACKIFY_MARKDOWN: true

on:
workflow_dispatch:
pull_request:
push:
branches:
- main

permissions:
contents: read

jobs:
snapshot-consistency:
name: backward_compat_snapshot_consistency/snapshot-consistency
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.sha }}
cancel-in-progress: ${{ github.event_name != 'push' }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: 'false'

- name: Generate snapshots from current code
run: make backward_snapshot_head

- name: Check snapshot consistency
run: ./scripts/check_snapshot_consistency.sh

- name: Slack Notification
if: ${{ failure() || (cancelled() && github.event_name == 'push') }}
continue-on-error: true
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: >-
Backward compatibility snapshot consistency check: ${{ job.status }}.
Snapshots may be outdated — run `make backward_snapshot_base` and commit.
[See details](${{ env.ACTION_RUN_URL }})
3 changes: 2 additions & 1 deletion .linelint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ ignore:
- tfhe/web_wasm_parallel_tests/dist
- keys
- coverage
- utils/tfhe-lints/tests/*/main.stderr
- utils/tfhe-lints/**/main.stderr
- utils/tfhe-lints/**/*.json
- utils/tfhe-backward-compat-data/**/*.ron # ron files are autogenerated

rules:
Expand Down
30 changes: 17 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
[workspace]
resolver = "3"
members = [
"apps/test-vectors",
"backends/tfhe-cuda-backend",
"backends/tfhe-hpu-backend",
"backends/zk-cuda-backend",
"mockups/tfhe-hpu-mockup",
"tasks",
"tests",
"tfhe",
"tfhe-benchmark",
"tfhe-csprng",
"tfhe-fft",
"tfhe-ntt",
"tfhe-zk-pok",
"tasks",
"tfhe-csprng",
"backends/tfhe-cuda-backend",
"backends/zk-cuda-backend",
"backends/tfhe-hpu-backend",
"utils/tfhe-versionable",
"utils/tfhe-versionable-derive",
"utils/param_dedup",
"utils/tfhe-backward-compat-checker",
"utils/tfhe-backward-compat-data",
"utils/tfhe-backward-compat-data/crates/add_new_version",
"utils/param_dedup",
"utils/tfhe-versionable",
"utils/tfhe-versionable-derive",
"utils/wasm-par-mq",
"utils/wasm-par-mq/web_tests",
"utils/wasm-par-mq/examples/msm",
"tests",
"mockups/tfhe-hpu-mockup",
"apps/test-vectors",
"utils/wasm-par-mq/web_tests",
]

exclude = ["utils/tfhe-lints", "apps/trivium"]
Expand Down Expand Up @@ -74,7 +75,10 @@ lto = "off"
debug-assertions = false

[workspace.metadata.dylint]
libraries = [{ path = "utils/tfhe-lints" }]
libraries = [
{ path = "utils/tfhe-lints/lints" },
{ path = "utils/tfhe-lints/snapshot" },
]

[profile.debug_lto_off]
inherits = "dev"
Expand Down
36 changes: 10 additions & 26 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ ZIZMOR_VERSION=1.22.0
# copy paste the command in the terminal and change them if required without forgetting the flags
export RUSTFLAGS?=-C target-cpu=native

include utils/tfhe-lints/Makefile

ifeq ($(GEN_KEY_CACHE_MULTI_BIT_ONLY),TRUE)
MULTI_BIT_ONLY=--multi-bit-only
else
Expand Down Expand Up @@ -170,10 +172,6 @@ install_tarpaulin:
cargo install cargo-tarpaulin --locked || \
( echo "Unable to install cargo tarpaulin, unknown error." && exit 1 )

.PHONY: install_cargo_dylint # Install custom tfhe-rs lints
install_cargo_dylint:
cargo install --locked cargo-dylint dylint-link

.PHONY: install_cargo_audit # Check dependencies
install_cargo_audit:
cargo install --locked cargo-audit
Expand Down Expand Up @@ -537,12 +535,6 @@ clippy_versionable: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy --all-targets \
-p tfhe-versionable -- --no-deps -D warnings

.PHONY: clippy_tfhe_lints # Run clippy lints on tfhe-lints
clippy_tfhe_lints: install_cargo_dylint # the toolchain is selected with toolchain.toml
cd utils/tfhe-lints && \
rustup toolchain install && \
cargo clippy --all-targets -- --no-deps -D warnings

.PHONY: clippy_param_dedup # Run clippy lints on param_dedup tool
clippy_param_dedup: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy --all-targets \
Expand Down Expand Up @@ -608,19 +600,10 @@ check_rust_bindings_did_not_change:
( echo "Generated bindings have changed! Please run 'git add backends/tfhe-cuda-backend/src/bindings.rs' \
and commit the changes." && exit 1 )


.PHONY: tfhe_lints # Run custom tfhe-rs lints
tfhe_lints: install_cargo_dylint
RUSTFLAGS="$(RUSTFLAGS) -Dwarnings" cargo dylint --all -p tfhe --no-deps -- \
--features=boolean,shortint,integer,strings,zk-pok
RUSTFLAGS="$(RUSTFLAGS) -Dwarnings" cargo dylint --all -p tfhe-zk-pok --no-deps -- \
--features=experimental

.PHONY: audit_dependencies # Run cargo audit to check vulnerable dependencies
audit_dependencies: install_cargo_audit
cargo audit


.PHONY: build_core # Build core_crypto without experimental features
build_core:
RUSTFLAGS="$(RUSTFLAGS)" cargo build --profile $(CARGO_PROFILE) \
Expand Down Expand Up @@ -1241,12 +1224,6 @@ test_versionable:
RUSTFLAGS="$(RUSTFLAGS)" cargo test --profile $(CARGO_PROFILE) \
--all-targets -p tfhe-versionable

.PHONY: test_tfhe_lints # Run test on tfhe-lints
test_tfhe_lints: install_cargo_dylint
cd utils/tfhe-lints && \
rustup toolchain install && \
cargo test

# The backward compat data folder holds historical binary data but also rust code to generate and load them.
.PHONY: gen_backward_compat_data # Re-generate backward compatibility data
gen_backward_compat_data:
Expand Down Expand Up @@ -2367,4 +2344,11 @@ bench_ntt: install_rs_check_toolchain

.PHONY: help # Generate list of targets with descriptions
help:
@grep '^\.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1\t\2/' | expand -t30 | sort
@for f in Makefile $$(grep '^include ' Makefile | awk '{print $$2}'); do \
matches=$$(grep '^\.PHONY: .* #' "$$f" || true); \
if [ -n "$$matches" ]; then \
echo ""; \
echo "--- $$f ---"; \
echo "$$matches" | sed 's/\.PHONY: \(.*\) # \(.*\)/\1\t\2/' | expand -t30 | sort; \
fi \
done
51 changes: 51 additions & 0 deletions scripts/check_snapshot_consistency.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# Check that committed base snapshots match freshly generated head snapshots.
# Expects `make backward_snapshot_head` to have been run beforehand.
# Exits 1 if any mismatch is found.

set -euo pipefail

SNAPSHOT_DIR="utils/tfhe-lints/snapshots"

mismatch=0

head_count=$(find "${SNAPSHOT_DIR}/head" -name 'lint_enum_snapshots_*.json' | wc -l)
base_count=$(find "${SNAPSHOT_DIR}" -maxdepth 1 -name 'lint_enum_snapshots_*.json' | wc -l)

if [ "$head_count" -ne "$base_count" ]; then
echo "::error::File count mismatch: $base_count base file(s) vs $head_count head file(s)"
mismatch=1
fi

# Check each head file has a matching base file with identical content
for head_file in "${SNAPSHOT_DIR}"/head/lint_enum_snapshots_*.json; do
base_name=$(basename "$head_file")
base_file="${SNAPSHOT_DIR}/${base_name}"
if [ ! -f "$base_file" ]; then
echo "::error::Missing base snapshot: $base_file"
mismatch=1
continue
fi
if ! diff -q "$base_file" "$head_file" >/dev/null 2>&1; then
echo "::error::Snapshot mismatch: $base_name"
diff "$base_file" "$head_file" || true
mismatch=1
fi
done

# Check each base file has a matching head file
for base_file in "${SNAPSHOT_DIR}"/lint_enum_snapshots_*.json; do
base_name=$(basename "$base_file")
head_file="${SNAPSHOT_DIR}/head/${base_name}"
if [ ! -f "$head_file" ]; then
echo "::error::Stale base snapshot (no matching head): $base_file"
mismatch=1
fi
done

if [ "$mismatch" -ne 0 ]; then
echo "::error::Snapshots are inconsistent — run 'make backward_snapshot_base' and commit."
exit 1
fi

echo "All snapshots are consistent."
10 changes: 10 additions & 0 deletions utils/tfhe-backward-compat-checker/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "tfhe-backward-compat-checker"
version = "0.1.0"
edition = "2024"
rust-version.workspace = true

[dependencies]
clap = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = "1"
Loading
Loading