Skip to content

fix(edr_solidity): resolve declaration-attributed locations in solx stack traces - #1553

Merged
nebasuke merged 1 commit into
feat/solx-stack-trace-provider-coveragefrom
fix/solx-declaration-attributed-inference
Jul 20, 2026
Merged

fix(edr_solidity): resolve declaration-attributed locations in solx stack traces#1553
nebasuke merged 1 commit into
feat/solx-stack-trace-provider-coveragefrom
fix/solx-declaration-attributed-inference

Conversation

@nebasuke

@nebasuke nebasuke commented Jul 10, 2026

Copy link
Copy Markdown
Member

Note: For now these are quick AI written fixes/tests to try and validate the solx trace integration.

Claude Summary

Fixes the two inference gaps found by #1552's provider-path tests (stacked: #1425#1552 ← this).

Root cause

solx attributes compiler-generated helper code — calldata decoding, shared revert builders — to the declaration of the enclosing function or contract in its DWARF line table, where solc leaves the same code unmapped in source maps. Two location-anchored inference paths broke on that difference:

  1. fails_right_after_call / is_call_failed_error compare every post-CALL step location to the call site by strict equality. Under solc, unmapped helper instructions are skipped; under solx, the same instructions carry declaration-level locations (whose range merely contains the statement), so the heuristics bailed and the revert degraded to OtherExecutionError at the contract-declaration line.
  2. Shared revert helpers flattened out of a modifier are attributed to the modified function's declaration line, so a modifier's failing require (line 415 in the scenarios fixture) was reported at the function signature (line 420). Diagnosis showed the statement's real line is present in the line table — on the message-building instructions executed just before the revert — so this is recoverable EDR-side.

Fix

Both fixes live in the solx strategy; SolcTraceStrategy is behavior-identical (strict equality kept, new parameter ignored).

  • New TraceStrategy::locations_equivalent(step, reference): solx treats a step location that contains the reference (declaration-level padding) as "still at the statement"; solc keeps ==. Used by is_last_location.
  • TraceStrategy::revert_source_reference now receives a lazy step_pcs thunk (same pattern as PanicHelperContext). When the reverting instruction sits on the function's declaration line, SolxTraceStrategy walks the executed steps back to the last statement-level location — the require's message-building code keeps its own line.

Effect (goldens flipped in solx_stack_trace.rs)

  • ReturndataSizeError now surfaces at the call site (LongTail.sol:47, ExpectsWord.callGet) for both the returndata-size mismatch and the typed call to a codeless account, replacing OtherExecutionError at the contract declaration. This is parity with the solc route: solc ≥ 0.8.10 emits no EXTCODESIZE probe for returndata-expecting calls either, so both routes classify the EOA case as a returndata failure. (A true NoncontractAccountCalledError would need a void-returning call scenario — future coverage.)
  • The multi-statement modifier revert reports the failing require's line (415) instead of the declaration line (420) — removing the provider-level twin of the sweep's pinned NestedModifierRevertTest divergence. The sweep golden for that scenario will need updating when the sweep next runs against a linked plugin (its pinned line should move accordingly).

Verification

  • solx_stack_trace.rs: 31/31 pass (the three flipped goldens broke in the improvement direction before the assertions were updated, everything else unchanged).
  • edr_solidity unit tests: 77/77; full edr_provider integration harness: 198/198.
  • solc behavior is guarded code-structurally (solc strategy unchanged) and by the hardhat-tests stack-trace corpus in CI.

No changeset: this is a pre-release fix to the solx DWARF feature introduced in #1425, covered by its changeset.

Also: the hardhat-tests CI failure on the feature branch

Second commit fixes the Error: missing field 'remainder' failures in the "Run Hardhat tests" job (seen on both #1425's and #1552's CI): the solx routing in add_compilation_result deserialized the compiler output into a struct with a literal remainder field, so every existing caller — HH2/HH3 pass a bare standard-JSON output — crashed on hardhat_addCompilationResult. Replaced with edr_solidity::artifacts::parse_compiler_output, which peeks an optional top-level compilerType field on the same value (mirroring the build-info path's PeekableCompilerType) and deserializes the whole output accordingly; absent/unknown → solc. Unit-tested against both fixture outputs. This commit is self-contained if it's preferred cherry-picked into #1425 directly, since it fixes that branch's red CI.

@nebasuke
nebasuke temporarily deployed to github-action-benchmark July 10, 2026 15:16 — with GitHub Actions Inactive
@changeset-bot

changeset-bot Bot commented Jul 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 905c238

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@nomicfoundation/edr Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@nebasuke
nebasuke temporarily deployed to github-action-benchmark July 10, 2026 15:21 — with GitHub Actions Inactive
@nebasuke
nebasuke temporarily deployed to github-action-benchmark July 10, 2026 15:21 — with GitHub Actions Inactive
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.85106% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.85%. Comparing base (dc3c75e) to head (905c238).
⚠️ Report is 1 commits behind head on feat/solx-stack-trace-provider-coverage.

Files with missing lines Patch % Lines
crates/edr_solidity/src/trace_strategy.rs 77.41% 2 Missing and 5 partials ⚠️
crates/edr_solidity/src/error_inferrer.rs 87.50% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@                             Coverage Diff                             @@
##           feat/solx-stack-trace-provider-coverage    #1553      +/-   ##
===========================================================================
- Coverage                                    79.86%   79.85%   -0.01%     
===========================================================================
  Files                                          452      452              
  Lines                                        78600    78642      +42     
  Branches                                     78600    78642      +42     
===========================================================================
+ Hits                                         62770    62803      +33     
- Misses                                       13666    13669       +3     
- Partials                                      2164     2170       +6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…tack traces

solx attributes compiler-generated helper code (calldata decoding, shared
revert builders) to the *declaration* of the enclosing function or
contract, where solc leaves such code unmapped. Two inference paths broke
on that difference:

1. fails_right_after_call / is_call_failed_error compared every post-CALL
   step location to the call site by strict equality, so declaration-level
   padding (whose range merely contains the statement) made the heuristics
   bail and reverts degraded to OtherExecutionError at the contract
   declaration line. New TraceStrategy::locations_equivalent treats a
   containing (declaration-level) location as "still at the statement"
   for solx; solc keeps strict equality.

2. A shared revert helper flattened out of a modifier is attributed to the
   modified function's declaration line. SolxTraceStrategy::
   revert_source_reference now walks the executed steps back from a
   declaration-line revert to the statement that led there (the require's
   message-building code keeps its own line), matching solc.

Provider-path effects (goldens flipped in solx_stack_trace.rs):
- ReturndataSizeError now surfaces at the call site for both a
  returndata-size mismatch and a typed call to a codeless account
  (parity with solc >= 0.8.10, which emits no EXTCODESIZE probe for
  returndata-expecting calls), replacing OtherExecutionError at the
  contract declaration.
- A multi-statement modifier revert reports the failing require's line
  (415) instead of the function declaration line (420), removing the
  provider-level twin of the sweep's NestedModifierRevertTest divergence.

The solc strategy is behavior-identical; edr_solidity unit tests (77) and
the edr_provider integration harness (198) pass.
@nebasuke
nebasuke force-pushed the feat/solx-stack-trace-provider-coverage branch from e7c64db to dc3c75e Compare July 20, 2026 14:47
@nebasuke
nebasuke force-pushed the fix/solx-declaration-attributed-inference branch from 9bcf71e to 905c238 Compare July 20, 2026 14:47
@nebasuke
nebasuke temporarily deployed to github-action-benchmark July 20, 2026 14:47 — with GitHub Actions Inactive
@nebasuke
nebasuke temporarily deployed to github-action-benchmark July 20, 2026 15:28 — with GitHub Actions Inactive
@nebasuke
nebasuke temporarily deployed to github-action-benchmark July 20, 2026 15:28 — with GitHub Actions Inactive
@nebasuke
nebasuke marked this pull request as ready for review July 20, 2026 15:46
@nebasuke
nebasuke merged commit e09dae7 into feat/solx-stack-trace-provider-coverage Jul 20, 2026
62 checks passed
@nebasuke
nebasuke deleted the fix/solx-declaration-attributed-inference branch July 20, 2026 15:47
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.

1 participant