Skip to content

Move Gloas spec tests into their own packages - #17309

Open
kasey wants to merge 2 commits into
methodical-codegen-switchfrom
local-spectest-refactors
Open

Move Gloas spec tests into their own packages#17309
kasey wants to merge 2 commits into
methodical-codegen-switchfrom
local-spectest-refactors

Conversation

@kasey

@kasey kasey commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Move Gloas spec tests into their own packages

Part of the gloas-devnet-7 stacked series; based on methodical-codegen-switch, diff shown against it.

The mainnet and minimal spec test packages had accumulated a large flat set of gloas__* files sharing a single go_test target with every other fork. Because Bazel test targets are the unit of granularity, running any gloas spec test meant compiling and pulling in the fixtures for phase0 through fulu as well. This PR moves the gloas files into testing/spectest/mainnet/gloas and testing/spectest/minimal/gloas with their own targets, so gloas can be iterated on independently.

The second half of the PR is tooling for the situation this series is in: during devnet development the config values Prysm carries are ahead of the pinned consensus-spec-tests release, so fixtures often have to come from a locally built spec rather than a published tarball. Now spectest fixtures are merged upstream, but having the option to run from a local tarball instead of always trying to download from the http archive seemed like a useful capability to preserve in case we need to use fixtures like this again, or have a reason to generate our own fixtures locally.
tools/download_spectests.bzl gains two opt-in ways to source spec test data from disk. tools/ssztrace is added to make root mismatches against a fixture debuggable — it dumps the merkleization of an SSZ object so a disagreement can be localized to the field that diverged. A corresponding python tool can be found at kasey/ssz-tracer to generate merkleization traces from remerkleable, giving a developer or LLM assistant the baseline canonical trace to diff.

Key changes

Spec test package split

  • New testing/spectest/mainnet/gloas/BUILD.bazel and testing/spectest/minimal/gloas/BUILD.bazel, each with a go_default_test target carrying that preset's 42 gloas test files, data = ["@consensus_spec_tests//:test_data"], and only the //testing/spectest/shared/gloas/... dependencies. The minimal target keeps eth_network = "minimal" and the minimal tag; both keep the spectest tag, so existing --test_tag_filters=spectest invocations still pick them up.
  • The corresponding srcs and deps entries are removed from testing/spectest/mainnet/BUILD.bazel and testing/spectest/minimal/BUILD.bazel.
  • The moved *_test.go files change only their package clause (package mainnet / package minimalpackage gloas). Test function names, helper calls, and preset arguments are untouched.

Local spec test data (tools/download_spectests.bzl)

Two new mechanisms, both taking precedence over CONSENSUS_SPEC_TESTS_VERSION and requiring no network access. All paths must be absolute; a source may be a tarball or an already-unpacked directory tree.

  • CONSENSUS_SPEC_TESTS_DIR=/abs/dir — for each flavor (general, mainnet, minimal), _local_sources looks for <dir>/<flavor>.tar.gz, then <dir>/tests/<flavor>/, then <dir>/<flavor>/, in that order. Flavors that are absent are skipped, so supplying just mainnet is valid.
  • CONSENSUS_SPEC_TESTS_<FLAVOR>=/abs/path (GENERAL, MAINNET, MINIMAL) — points one flavor at an arbitrarily named tarball or directly at an unpacked flavor tree, and wins over the directory entry for that flavor.
  • _install_local normalizes each source to the tests/<flavor> layout the generated BUILD.bazel globs expect. Directories are symlinked (no large copy); tarballs are symlinked in as <flavor>.tar.gz, extracted to a staging dir, and then the detected internal prefix (tests/<flavor> or <flavor>) is symlinked into place.
  • Requesting local sources but finding nothing is a hard fail rather than a silent fall back to downloading.
  • All four variables are added to the repository rule's environ list.

Raw tarballs kept alongside extracted fixtures

  • The release path now calls repository_ctx.download followed by repository_ctx.extract instead of download_and_extract, keeping <flavor>.tar.gz in the repo. Still one download, still integrity-checked and repository-cache-eligible.
  • The generated BUILD.bazel gains exports_files(glob(["*.tar.gz"])) so rules that want the un-extracted archive can depend on @consensus_spec_tests//:<flavor>.tar.gz.

methodical-ssz spec test generation

  • testing/spectest/methodical-spectest.yaml — the type relations config for methodical-ssz's spec test generator: each fork lists only the types it introduces or overrides (the generator inherits the rest from the most recent prior fork), with type_name for Prysm's fork-suffixed Go types and package: for the proto/engine/v1 execution-layer containers. Covers phase0 through gloas, including the gloas additions (ExecutionPayloadBid, PayloadAttestation*, Builder*, ExecutionPayloadEnvelope, ProposerPreferences, and the gloas variants of BeaconBlock/BeaconState/DataColumnSidecar).
  • testing/spectest/BUILD.bazel — an ssz_gen_spectest target (the rule already exists in tools/methodical.bzl from earlier in the series) that generates into testing/spectest/methodical, using @consensus_spec_tests//:mainnet.tar.gz as its fixture source. This is what the exports_files change above is for.
  • hack/update-go-spectest.sh — the generate-and-commit script, mirroring hack/update-go-ssz.sh. It builds every ssz_gen_spectest target, finds each generated package by its methodical_test.go marker, and mirrors the tree-artifact directory (test file plus testdata/) back into the source tree. Destinations are cleared first, since the tree artifact has no stable file list and stale fixtures would otherwise linger; copies are chmod u+w because Bazel outputs are read-only.

No generated output is committed in this PR — only the config, the target, and the script.

tools/ssztrace

A new go_binary that emits a merkleization trace for a gloas SSZ fixture, either as a flat generalized-index-to-root map or nested YAML, using Prysm's methodical-ssz-generated HashTreeRootWith and the tracer in github.com/OffchainLabs/methodical-ssz/ssz.

go run ./tools/ssztrace [-yaml] [-o out.yaml] <TypeName> <case_dir>
  • newObject in tools/ssztrace/main.go maps spec test folder names to Prysm types, mirroring testing/spectest/shared/gloas/ssz_static/ssz_static.go; only types with a generated methodical HTR are registered, and an unknown name is an error naming the function to extend.
  • <case_dir> is read for serialized.ssz_snappy and, if present, roots.yaml. The trace self-verifies against the value's generated HashTreeRoot internally; the fixture root is then cross-checked as a spec-version-skew signal only. A mismatch there prints a warning and still emits, because the trace is faithful to whatever the Go type computes.
  • Intended for cross-library bisection: diff the flat map against the Python/remerkleable tracer's output and take the highest generalized index whose root differs.

Behavior and configuration notes

  • Test target paths change. Gloas spec tests no longer run as part of //testing/spectest/mainnet:go_default_test or //testing/spectest/minimal:go_default_test; they are //testing/spectest/mainnet/gloas:go_default_test and //testing/spectest/minimal/gloas:go_default_test. Anything that names those preset targets explicitly needs updating; tag-filtered and //... runs are unaffected.
  • Downloading is still the default. The local-source env vars are opt-in, and CI behavior is unchanged when none of them are set.
  • @consensus_spec_tests//:<flavor>.tar.gz only exists when the source is an actual tarball, not an unpacked directory, so the ssz_gen_spectest target cannot be built against a directory-sourced repo.
  • When only some flavors are supplied, scope the test target (e.g. //testing/spectest/mainnet/...) instead of //..., since the other flavors' filegroups resolve to empty globs.
  • Bazel keys the repository rule on the env var value, not file contents. Changing data at the same path requires bazel sync --configure or a different path to force a re-fetch.
  • testing/spectest/README.md documents all of the above; tools/download_spectests.bzl also picked up buildifier formatting churn in the pre-existing download paths.

Acknowledgements

  • I have read CONTRIBUTING.md.
  • I have included a uniquely named changelog fragment file.
  • I have added a description with sufficient context for reviewers to understand this PR.
  • I have tested that my changes work as expected and I added a testing plan to the PR description (if applicable).

Stack created with GitHub Stacks CLIGive Feedback 💬

@kasey
kasey requested a review from prestonvanloon as a code owner August 5, 2026 20:39
@kasey
kasey force-pushed the local-spectest-refactors branch from e6f59b0 to 0bb7aa1 Compare August 5, 2026 20:57
@kasey
kasey force-pushed the methodical-codegen-switch branch from c057083 to f23a915 Compare August 5, 2026 21:08
@kasey
kasey force-pushed the local-spectest-refactors branch 5 times, most recently from 5ef6291 to bc34380 Compare August 5, 2026 22:00
@kasey
kasey force-pushed the methodical-codegen-switch branch from ef2aa1f to f77fb7b Compare August 5, 2026 22:00
@kasey
kasey force-pushed the local-spectest-refactors branch from bc34380 to 66c0cfa Compare August 6, 2026 01:12
@kasey
kasey force-pushed the methodical-codegen-switch branch from f77fb7b to 76f1225 Compare August 6, 2026 01:12
@kasey
kasey force-pushed the local-spectest-refactors branch from 66c0cfa to e77427a Compare August 6, 2026 01:31
@kasey
kasey force-pushed the methodical-codegen-switch branch from 76f1225 to ae672ac Compare August 6, 2026 01:31
@kasey
kasey force-pushed the local-spectest-refactors branch 2 times, most recently from 159e1ac to 1b96281 Compare August 6, 2026 05:41
@kasey
kasey force-pushed the methodical-codegen-switch branch from 599d21c to 0150575 Compare August 6, 2026 05:49
@kasey
kasey force-pushed the local-spectest-refactors branch 2 times, most recently from 4a6e4ef to c592869 Compare August 6, 2026 13:27
@kasey
kasey force-pushed the methodical-codegen-switch branch from 0150575 to 1a01a0b Compare August 6, 2026 13:27
@kasey
kasey force-pushed the local-spectest-refactors branch from c592869 to 49ac6e9 Compare August 6, 2026 17:25
@kasey
kasey force-pushed the methodical-codegen-switch branch from 1a01a0b to 369252e Compare August 6, 2026 17:26

@terencechain terencechain left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we missed a few fields in testing/spectest/methodical-spectest.yaml

- name: DataColumnsByRootIdentifier
- name: SignedBeaconBlock
type_name: SignedBeaconBlockFulu
- fork: gloas

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we missing ExecutionRequestsExecutionRequestsGloas?
and how about the following?

BuilderDepositRequest
BuilderExitRequest
AttestationGloas
AttesterSlashingGloas
IndexedAttestationGloas
AggregateAttestationAndProofGloas,
SignedAggregateAttestationAndProofGloas


# Script to copy generated spectest packages from the bazel build folder back to
# the source tree (the "generate-and-commit" workflow, mirroring
# update-go-ssz.sh). Each ssz_gen_spectest target emits a tree-artifact

@nalepae nalepae Aug 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: update-go-ssz.sh does not exist any more.

Comment thread tools/ssztrace/main.go
// HashTreeRootWith and the tracer in github.com/OffchainLabs/methodical-ssz/ssz.
//
// It is the Go side of cross-library bisection: diff its flat map against the
// Python/remerkleable tracer's (ssz-tracer/trace_flat.py) and take the highest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where can this script be found?

bazel test //... --test_tag_filters=spectest --repo_env=CONSENSUS_SPEC_TESTS_VERSION=nightly-21422848633
```

## Using local spectest data

@nalepae nalepae Aug 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this PR, make test alreay had no equivalent to

bazel test //... --test_tag_filters=spectest --repo_env=CONSENSUS_SPEC_TESTS_VERSION=nightly

You can run the spectests only by using

make test mainnet-spectest minimal-spectest

but it's not possible to specify the equivalent of the --repo_env=CONSENSUS_SPEC_TESTS_VERSION value.

After this PR, this thing remains, and additionnaly, it's not possible to specify the equivalent of the --repo_env=CONSENSUS_SPEC_TESTS_DIR value.

These 2 things can be added in this current PR, or I can create a GH issue to track it, to be sure we implement this before totally remove Bazel.

@kasey
kasey force-pushed the methodical-codegen-switch branch from 369252e to 81c5678 Compare August 7, 2026 20:00
@kasey
kasey force-pushed the local-spectest-refactors branch from 49ac6e9 to 0d8a5ee Compare August 7, 2026 20:00
@kasey
kasey force-pushed the methodical-codegen-switch branch from 81c5678 to f464594 Compare August 11, 2026 14:29
@kasey
kasey force-pushed the local-spectest-refactors branch from 0d8a5ee to a10e16d Compare August 11, 2026 14:29
@kasey
kasey force-pushed the methodical-codegen-switch branch from f464594 to e29dde3 Compare August 11, 2026 19:34
@kasey
kasey force-pushed the local-spectest-refactors branch from a10e16d to 71436f8 Compare August 11, 2026 19:34
kasey added 2 commits August 12, 2026 15:31
The mainnet and minimal spec test packages had grown a large flat set of
gloas__* files sharing one BUILD target, so any gloas spec test run pulled
in every other fork's fixtures. Move them under mainnet/gloas and
minimal/gloas with their own targets.

download_spectests.bzl gains CONSENSUS_SPEC_TESTS_DIR and per-flavor
overrides so a working tree can be pointed at locally built spec test data,
which is what makes it practical to run against a nightly or unreleased
spec while devnet config values are ahead of the pinned release.

Adds ssztrace, which dumps the merkleization of an SSZ object so a root
mismatch against a fixture can be traced to the field that diverged.
@kasey
kasey force-pushed the local-spectest-refactors branch from 71436f8 to a676232 Compare August 12, 2026 20:32
@kasey
kasey force-pushed the methodical-codegen-switch branch from e29dde3 to 87e3a93 Compare August 12, 2026 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants