Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

EIP-712 canonical-type collection re-parses whole build infos

Abierto
#1,663 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 2 días

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
48/100
Tipo de issue
Refactorización
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
typescript
Área
performance

Línea de trabajo

Empieza en packages/hardhat/src/internal/builtin-plugins/solidity-test/eip712/index.ts y luego lee ast-walker.ts, canonicalize.ts y edr-artifacts.ts para entender el solapamiento entre el análisis y la carga de artefactos. Ejecuta el escenario documentado del profiler de pnpm para establecer la línea base antes de evaluar el caching, la recopilación en tiempo de compilación o el análisis compartido. Se considera terminado cuando los tipos canónicos y el comportamiento de las pruebas sean idénticos, y el coste repetido de parseJsonBytes se haya eliminado o reducido según las mediciones del profiling.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Hardhat's JS-side EIP-712 pipeline (builtin-plugins/solidity-test/eip712/) prepares the eip712CanonicalTypes config field for EDR. Its own logic costs milliseconds, but it parses entire build-info outputs — the AST-bearing JSON for all compiled sources — to extract a handful of struct definitions.

Measured in the Hardhat 3 + EDR profiling campaign on aave-v4's hardhat test solidity run, the only benchmark suite configuring EIP-712 types:

  • JS side: 1.35 s of parseJsonBytes under the collector — 1.21 s ≈ 37% of active JS ≈ 6% of wall
  • EDR side: ~1.1 s in its native EIP-712 collector on the same run
  • Combined: ~2.3 s ≈ 12% of that 19 s test run

Three structural inefficiencies: the parse is a superset (full ASTs, bytecode and metadata materialised for a few struct definitions); the result is recomputed on every test run even though build infos are immutable per build id; and the artifact loader may read the same build infos in the same run. Cost is zero when unconfigured — collection short-circuits on an empty include.

Direction

In order of likely payoff: cache the collected canonical types by build id plus EIP-712 config (build infos are content-addressed, so invalidation is trivial and warm runs pay ~0); or collect at compile time, where the output JSON is already in memory, storing a small artifact that test runs load instead of walking ASTs; or, if parsing must stay on the test path, share the parsed build info with the artifact loader rather than parsing twice.

Note: this collector is being moved to Rust (EDR feat/eip712-collector-crate-and-inline-config), including compile-time collection — so the remaining JS-side scope here may reduce to caching and shared parsing.

Implementation plan

# Stop re-parsing whole build infos in the EIP-712 canonical-type collector

## Problem

[Profiling Hardhat 3 e2e scenarios](https://app.notion.com/p/nomicfoundation/Runtime-Profiling-2026-08-05-3b3578cdeaf5808eafdff4e22ba425d0?source=copy_link) measures the JS-side EIP-712 canonical-type collection on aave-v4's `hardhat test solidity` run at 1.35 s of `parseJsonBytes` self-time under `collectEip712CanonicalTypes` — 1.21 s ≈ 37% of active JS ≈ **6% of wall**. EDR spends a further ~1.1 s in its native EIP-712 collector on the same run, so EIP-712 preparation totals ~2.3 s ≈ **12% of that 19 s test run**.

The collector's own logic costs milliseconds; the cost is the parsing. It is zero in scenarios that configure no EIP-712 types, since collection short-circuits on an empty `include`.

## Root cause

`packages/hardhat/src/internal/builtin-plugins/solidity-test/eip712/index.ts` — `collectEip712CanonicalTypes` parses **entire build-info output files** (`SolidityBuildInfoOutput`, the AST-bearing JSON for every compiled source) with `parseJsonBytes`, walks each source's AST (`ast-walker.ts`) and canonicalises struct definitions (`canonicalize.ts`). Three structural inefficiencies:

1. **Superset parsing** — the document carries full ASTs, bytecode and metadata for every source, while the collector needs only struct definitions and user-defined value types from selected sources. `JSON.parse` is all-or-nothing, so everything is materialised. A `bytesIncludesUtf8String` pre-filter exists; check what it actually filters out here.
2. **Recomputed every run** — build-info outputs are immutable per build id, yet canonical types are re-collected on every `hardhat test solidity` invocation.
3. **Duplicate parsing** — the artifact loading path may read the same build info in the same run; check `edr-artifacts.ts` (`BuildInfoAndOutput`) for overlap.

## Task

1. Reproduce the baseline (see Verification), and add a temporary timing log around `collectEip712CanonicalTypes` for aave-v4.
2. Evaluate, in order of likely payoff:
   - **Cache by build id**: persist the collected canonical types keyed by build id plus EIP-712 config, next to the build info or in the cache directory. Build infos are content-addressed, so invalidation is trivial, and warm test runs pay ~0.
   - **Collect at compile time**: compute the canonical types once at the end of compilation, where the output JSON is already in memory, and store them as a small artifact — test runs then load a tiny file instead of walking ASTs. Weigh the cost for users who never run EIP-712 Solidity tests; the config gate can decide.
   - **Cheaper extraction**, if parsing must stay on the test path: share the parsed build-info object with the artifact loader when both need it in one run, or extract only the `ast` subtrees of selected sources — worthwhile only if measurements justify the complexity.
3. Behaviour must be identical: same canonical type strings, same `include`/`exclude` semantics, same cross-file dependency inlining (non-selected sources still feed the dependency graph — see the doc comment in `index.ts`).
4. Extend the existing eip712 unit tests with cache-hit and invalidation cases if caching lands. Run `pnpm lint`, `pnpm build`, `pnpm test` in `packages/hardhat`.

## Verification (before/after)

Profile before and after with `pnpm profiler` (a bare `pnpm profiler` prints its usage; see `scripts/README.md`):

```bash
pnpm build
pnpm profiler --scenario ./end-to-end/aave-v4 \
  --prepare "cold compile" --command "test solidity" \
  --mode js --init --use-local
```

Expect: `parseJsonBytes` gone from the top functions of the `.cpuprofile` — on the second, cache-warm run if caching lands, or on every run if compile-time collection does. Test results must be identical, and so must the canonical types handed to EDR (assert against a baseline dump).
Lenguaje dominante
TypeScript
Estrellas
110
Forks
49
Merge medio
2 d 19 h
PR fusionados (30 d)
64

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de NomicFoundation/edr

Todos los issues de NomicFoundation/edr

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.