refactor(testing): collapse the two placeholder-proof branches (#1160) #788
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Production Test Vectors | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: prod-vectors-latest | |
| cancel-in-progress: true | |
| jobs: | |
| check: | |
| name: Check key availability | |
| runs-on: ubuntu-latest | |
| outputs: | |
| scheme-changed: ${{ steps.scheme-diff.outputs.changed }} | |
| cache-hit: ${{ steps.key-cache.outputs.cache-hit }} | |
| steps: | |
| - name: Checkout leanSpec | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 2 | |
| - name: Check if scheme changed | |
| id: scheme-diff | |
| run: | | |
| if git diff HEAD~1 --name-only | grep -qE '^src/lean_spec/subspecs/(xmss|poseidon1)/'; then | |
| echo "changed=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Check prod key cache | |
| id: key-cache | |
| uses: actions/cache/restore@v4 | |
| with: | |
| path: /tmp/prod-keys-probe | |
| key: prod-keys-${{ hashFiles('src/lean_spec/subspecs/xmss/**', 'src/lean_spec/subspecs/poseidon1/**') }} | |
| lookup-only: true | |
| keygen: | |
| name: Generate keys | |
| needs: check | |
| if: needs.check.outputs.cache-hit != 'true' && needs.check.outputs.scheme-changed == 'true' | |
| uses: ./.github/workflows/generate-keys.yml | |
| secrets: inherit | |
| fill: | |
| name: Fill production test fixtures | |
| needs: [check, keygen] | |
| # Trick to run even when keygen was skipped, but not on failure or cancel. | |
| if: always() && !failure() && !cancelled() | |
| runs-on: macos-latest | |
| steps: | |
| - name: Checkout leanSpec | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.14 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.14" | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: "pyproject.toml" | |
| - name: Install just | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: just | |
| - name: Restore prod key cache | |
| id: key-cache | |
| uses: actions/cache/restore@v4 | |
| with: | |
| path: packages/testing/src/consensus_testing/test_keys/prod_scheme | |
| key: prod-keys-${{ hashFiles('src/lean_spec/subspecs/xmss/**', 'src/lean_spec/subspecs/poseidon1/**') }} | |
| - name: Download keys | |
| if: steps.key-cache.outputs.cache-hit != 'true' | |
| run: uv run keys --download --scheme prod | |
| - name: Save key cache | |
| if: steps.key-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: packages/testing/src/consensus_testing/test_keys/prod_scheme | |
| key: prod-keys-${{ hashFiles('src/lean_spec/subspecs/xmss/**', 'src/lean_spec/subspecs/poseidon1/**') }} | |
| - name: Fill production test fixtures | |
| env: | |
| # Only the real_crypto smoke vectors run genuine production XMSS proofs. | |
| # Each proof parallelizes internally with rayon, so few heavy tasks dominate the run. | |
| # Two xdist workers overlap the heavy proofs and chew through the mocked backlog. | |
| # Leaving rayon unpinned lets each proof spread across cores instead of one thread. | |
| FILL_WORKERS: "2" | |
| run: just fill-ci --scheme=prod | |
| - name: Bundle keys with fixtures | |
| run: | | |
| mkdir -p fixtures/keys | |
| cp -r packages/testing/src/consensus_testing/test_keys/prod_scheme fixtures/keys/ | |
| - name: Create reproducible fixture archive | |
| run: | | |
| python - <<'PY' | |
| from __future__ import annotations | |
| import gzip | |
| import hashlib | |
| import tarfile | |
| from pathlib import Path | |
| archive_path = Path("fixtures-prod-scheme.tar.gz") | |
| checksum_path = Path("fixtures-prod-scheme.tar.gz.sha256") | |
| source_directory = Path("fixtures") | |
| fixed_modification_time = 1_577_836_800 | |
| if not source_directory.is_dir(): | |
| raise SystemExit("Expected fixtures/ to exist before archiving.") | |
| consensus_fixture_paths = sorted(source_directory.glob("consensus/**/*.json")) | |
| if not consensus_fixture_paths: | |
| raise SystemExit("No consensus fixture JSON files were generated.") | |
| source_paths = [source_directory, *sorted(source_directory.rglob("*"))] | |
| with archive_path.open("wb") as archive_file_handle: | |
| with gzip.GzipFile( | |
| filename="", | |
| mode="wb", | |
| fileobj=archive_file_handle, | |
| mtime=0, | |
| ) as gzip_file_handle: | |
| with tarfile.open( | |
| fileobj=gzip_file_handle, | |
| mode="w", | |
| format=tarfile.PAX_FORMAT, | |
| ) as tar_file_handle: | |
| for source_path in source_paths: | |
| tar_file_information = tar_file_handle.gettarinfo( | |
| source_path, | |
| arcname=source_path.as_posix(), | |
| ) | |
| tar_file_information.uid = 0 | |
| tar_file_information.gid = 0 | |
| tar_file_information.uname = "" | |
| tar_file_information.gname = "" | |
| tar_file_information.mtime = fixed_modification_time | |
| if tar_file_information.isfile(): | |
| with source_path.open("rb") as source_file_handle: | |
| tar_file_handle.addfile( | |
| tar_file_information, | |
| source_file_handle, | |
| ) | |
| else: | |
| tar_file_handle.addfile(tar_file_information) | |
| archive_digest = hashlib.sha256(archive_path.read_bytes()).hexdigest() | |
| checksum_path.write_text(f"{archive_digest} {archive_path.name}\n") | |
| with tarfile.open(archive_path, "r:gz") as archive_file_handle: | |
| archived_consensus_fixtures = [ | |
| archived_member.name | |
| for archived_member in archive_file_handle.getmembers() | |
| if archived_member.name.startswith("fixtures/consensus/") | |
| and archived_member.name.endswith(".json") | |
| ] | |
| if not archived_consensus_fixtures: | |
| raise SystemExit("Archive does not contain generated consensus fixtures.") | |
| PY | |
| - name: Upload fixture archive | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fixtures-prod-scheme | |
| path: | | |
| fixtures-prod-scheme.tar.gz | |
| fixtures-prod-scheme.tar.gz.sha256 | |
| if-no-files-found: error | |
| - name: Publish latest release | |
| run: | | |
| gh release delete latest --cleanup-tag --yes || true | |
| gh release create latest \ | |
| fixtures-prod-scheme.tar.gz \ | |
| fixtures-prod-scheme.tar.gz.sha256 \ | |
| --target "${{ github.sha }}" \ | |
| --title "Latest production fixtures" \ | |
| --notes "Auto-generated from leanSpec@${{ github.sha }}" | |
| env: | |
| GH_TOKEN: ${{ github.token }} |