Skip to content

Optional Echidna compatibility check as a Github Action#1039

Merged
blishko merged 20 commits intomainfrom
dev-echidna-compat-check
Mar 9, 2026
Merged

Optional Echidna compatibility check as a Github Action#1039
blishko merged 20 commits intomainfrom
dev-echidna-compat-check

Conversation

@gustavo-grieco
Copy link
Collaborator

@gustavo-grieco gustavo-grieco commented Feb 25, 2026

Description

The workflow is located at hevm/.github/workflows/echidna-compat.yml. It performs the following steps when a Pull Request is opened or updated in the hevm repository:

  1. Checkouts: It clones both the current hevm PR branch and the crytic/echidna master branch.
  2. Patching: It uses a Python script to safely modify echidna/stack.yaml, replacing the remote hevm git dependency with the local checkout (./hevm).
  3. Environment: It leverages Nix to obtain Stack and GHC, and ensure that hevm and echidna's C dependencies (like libsecp256k1 and libff) are correctly provided to the build environment.
  4. Compilation: It runs stack build --fast --test --no-run-tests to verify that echidna still compiles with the changes made in the hevm PR.

Optional Status: The job uses continue-on-error: true, which means it will act as a warning. If compatibility is broken, the PR will show a warning icon but won't be blocked (unless you specifically mark this check as required in GitHub settings). The job will also post a status update with a build log in case the build fails.

Checklist

  • tested locally
  • added automated tests
  • updated the docs
  • updated the changelog

@msooseth
Copy link
Collaborator

This would be really nice actually! So we know when we break Echidna :)

@elopez elopez force-pushed the dev-echidna-compat-check branch from 2bd2edd to 7ab28fd Compare February 25, 2026 18:15
@github-actions
Copy link

github-actions bot commented Feb 25, 2026

⚠️ Echidna build failed

Building Echidna
against this PR's hevm failed.

Build log (last 200 lines)
xml-conduit                      >     To import instances alone, use: import Control.Monad.Trans.Resource()
xml-conduit                      >    |
xml-conduit                      > 82 | import           Control.Monad.Trans.Resource (MonadThrow, throwM)
xml-conduit                      >    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
xml-conduit                      > 
xml-conduit                      > /tmp/nix-shell-2451-0/stack-30e95803d52549c3/xml-conduit-1.9.1.4/src/Text/XML.hs:105:1: warning: [GHC-66111] [-Wunused-imports]
xml-conduit                      >     The import of ‘Control.Monad.Trans.Class’ is redundant
xml-conduit                      >       except perhaps to import instances from ‘Control.Monad.Trans.Class’
xml-conduit                      >     To import instances alone, use: import Control.Monad.Trans.Class()
xml-conduit                      >     |
xml-conduit                      > 105 | import           Control.Monad.Trans.Class    (lift)
xml-conduit                      >     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
xml-conduit                      > 
xml-conduit                      > /tmp/nix-shell-2451-0/stack-30e95803d52549c3/xml-conduit-1.9.1.4/src/Text/XML.hs:115:1: warning: [GHC-66111] [-Wunused-imports]
xml-conduit                      >     The import of ‘Data.Monoid’ is redundant
xml-conduit                      >       except perhaps to import instances from ‘Data.Monoid’
xml-conduit                      >     To import instances alone, use: import Data.Monoid()
xml-conduit                      >     |
xml-conduit                      > 115 | import           Data.Monoid                  (mappend, mempty)
xml-conduit                      >     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
mustache                         > [6 of 7] Compiling Text.Mustache.Compile
mustache                         > [7 of 7] Compiling Text.Mustache
xml-conduit                      > [7 of 7] Compiling Text.XML.Cursor
mustache                         > Preprocessing executable 'haskell-mustache' for mustache-2.4.3.1..
mustache                         > Building executable 'haskell-mustache' for mustache-2.4.3.1..
mustache                         > [1 of 1] Compiling Main
xml-conduit                      > copy/register
xml-conduit                      > Installing library in /home/runner/.stack/snapshots/x86_64-linux/1c8a30ef928030857b76b145f53fe7dee16e0d64f922c14b1899aa06fd6b3d77/9.8.4/lib/x86_64-linux-ghc-9.8.4/xml-conduit-1.9.1.4-GOwP44QynHv7R2VTmxumDR
xml-conduit                      > Registering library for xml-conduit-1.9.1.4..
mustache                         > [2 of 2] Linking .stack-work/dist/x86_64-linux/ghc-9.8.4/build/haskell-mustache/haskell-mustache
html-conduit                     > configure
html-conduit                     > Configuring html-conduit-1.3.2.2...
mustache                         > copy/register
mustache                         > Installing library in /home/runner/.stack/snapshots/x86_64-linux/1c8a30ef928030857b76b145f53fe7dee16e0d64f922c14b1899aa06fd6b3d77/9.8.4/lib/x86_64-linux-ghc-9.8.4/mustache-2.4.3.1-DGIWw3xg8H3DGyiI2ouchB
mustache                         > Installing executable haskell-mustache in /home/runner/.stack/snapshots/x86_64-linux/1c8a30ef928030857b76b145f53fe7dee16e0d64f922c14b1899aa06fd6b3d77/9.8.4/bin
html-conduit                     > build with ghc-9.8.4
html-conduit                     > Preprocessing library for html-conduit-1.3.2.2..
html-conduit                     > Building library for html-conduit-1.3.2.2..
mustache                         > Registering library for mustache-2.4.3.1..
html-conduit                     > [1 of 2] Compiling Text.HTML.TagStream
html-conduit                     > [2 of 2] Compiling Text.HTML.DOM
html-conduit                     > copy/register
html-conduit                     > Installing library in /home/runner/.stack/snapshots/x86_64-linux/1c8a30ef928030857b76b145f53fe7dee16e0d64f922c14b1899aa06fd6b3d77/9.8.4/lib/x86_64-linux-ghc-9.8.4/html-conduit-1.3.2.2-4xnBmX11kqNBY6HimGNQFZ
html-conduit                     > Registering library for html-conduit-1.3.2.2..
hevm                             > [ 5 of 32] Compiling EVM.Traversals
hevm                             > [ 6 of 32] Compiling EVM.SMT.Types
hevm                             > [ 7 of 32] Compiling EVM.SMT.SMTLIB
hevm                             > [ 8 of 32] Compiling EVM.RLP
hevm                             > [ 9 of 32] Compiling EVM.Expr
hevm                             > [10 of 32] Compiling EVM.Op
hevm                             > [11 of 32] Compiling EVM.Merge
hevm                             > [12 of 32] Compiling EVM.Keccak
hevm                             > [13 of 32] Compiling EVM.Concrete
hevm                             > [14 of 32] Compiling EVM.CSE
hevm                             > [15 of 32] Compiling EVM.Assembler
hevm                             > [16 of 32] Compiling EVM.ABI
hevm                             > [17 of 32] Compiling EVM.Solidity
hevm                             > [18 of 32] Compiling EVM.Sign
hevm                             > [19 of 32] Compiling EVM.Dapp
hevm                             > [20 of 32] Compiling EVM.CheatsTH
hevm                             > [21 of 32] Compiling EVM
hevm                             > [22 of 32] Compiling EVM.Format
hevm                             > [23 of 32] Compiling EVM.Transaction
hevm                             > [24 of 32] Compiling EVM.SMT
hevm                             > [25 of 32] Compiling EVM.Solvers
hevm                             > [26 of 32] Compiling EVM.Fetch
hevm                             > [27 of 32] Compiling EVM.Exec
hevm                             > [28 of 32] Compiling EVM.Stepper
hevm                             > [29 of 32] Compiling EVM.Tracing
hevm                             > [30 of 32] Compiling EVM.SymExec
hevm                             > [31 of 32] Compiling EVM.UnitTest
hevm                             > [32 of 32] Compiling Paths_hevm
hevm                             > Preprocessing executable 'hevm' for hevm-0.57.0..
hevm                             > Building executable 'hevm' for hevm-0.57.0..
hevm                             > [1 of 2] Compiling Paths_hevm
hevm                             > [2 of 2] Compiling Main
hevm                             > 
hevm                             > <no location info>: warning: [-Wmissed-extra-shared-lib]
hevm                             >     libz.so: cannot open shared object file: No such file or directory
hevm                             >     It's OK if you don't want to use symbols from it directly.
hevm                             >     (the package DLL is loaded by the system linker
hevm                             >      which manages dependencies by itself).
hevm                             > 
hevm                             > <no location info>: warning: [-Wmissed-extra-shared-lib]
hevm                             >     libsecp256k1.so: cannot open shared object file: No such file or directory
hevm                             >     It's OK if you don't want to use symbols from it directly.
hevm                             >     (the package DLL is loaded by the system linker
hevm                             >      which manages dependencies by itself).
hevm                             > 
hevm                             > <no location info>: warning: [-Wmissed-extra-shared-lib]
hevm                             >     libgmp.so: cannot open shared object file: No such file or directory
hevm                             >     It's OK if you don't want to use symbols from it directly.
hevm                             >     (the package DLL is loaded by the system linker
hevm                             >      which manages dependencies by itself).
hevm                             > [3 of 3] Linking .stack-work/dist/x86_64-linux/ghc-9.8.4/build/hevm/hevm
hevm                             > Preprocessing library 'test-utils' for hevm-0.57.0..
hevm                             > Building library 'test-utils' for hevm-0.57.0..
hevm                             > [1 of 3] Compiling EVM.Test.BlockchainTests
hevm                             > [2 of 3] Compiling Paths_hevm
hevm                             > [3 of 3] Compiling EVM.Test.Utils
hevm                             > copy/register
hevm                             > Installing library in /home/runner/work/hevm/hevm/echidna-src/.stack-work/install/x86_64-linux/1c8a30ef928030857b76b145f53fe7dee16e0d64f922c14b1899aa06fd6b3d77/9.8.4/lib/x86_64-linux-ghc-9.8.4/hevm-0.57.0-EFwX3gm4UfI4wJEAwh86zy
hevm                             > Installing executable hevm in /home/runner/work/hevm/hevm/echidna-src/.stack-work/install/x86_64-linux/1c8a30ef928030857b76b145f53fe7dee16e0d64f922c14b1899aa06fd6b3d77/9.8.4/bin
hevm                             > Installing internal library test-utils in /home/runner/work/hevm/hevm/echidna-src/.stack-work/install/x86_64-linux/1c8a30ef928030857b76b145f53fe7dee16e0d64f922c14b1899aa06fd6b3d77/9.8.4/lib/x86_64-linux-ghc-9.8.4/hevm-0.57.0-4NHparznO4bB05UDBj97qy-test-utils
hevm                             > Registering library for hevm-0.57.0..
hevm                             > Registering library 'test-utils' for hevm-0.57.0..
echidna                          > configure (lib + exe + test)
Configuring echidna-2.3.1...
echidna                          > build (lib + exe + test) with ghc-9.8.4
Preprocessing library for echidna-2.3.1..
Building library for echidna-2.3.1..
[ 1 of 49] Compiling Echidna.Mutator.Array
[ 2 of 49] Compiling Echidna.Onchain.Types
[ 3 of 49] Compiling Echidna.Onchain.Sourcify
[ 4 of 49] Compiling Echidna.Onchain.Etherscan
[ 5 of 49] Compiling Echidna.Orphans.JSON

<no location info>: warning: [-Wmissed-extra-shared-lib]
    libz.so: cannot open shared object file: No such file or directory
    It's OK if you don't want to use symbols from it directly.
    (the package DLL is loaded by the system linker
     which manages dependencies by itself).

<no location info>: warning: [-Wmissed-extra-shared-lib]
    libsecp256k1.so: cannot open shared object file: No such file or directory
    It's OK if you don't want to use symbols from it directly.
    (the package DLL is loaded by the system linker
     which manages dependencies by itself).

<no location info>: warning: [-Wmissed-extra-shared-lib]
    libgmp.so: cannot open shared object file: No such file or directory
    It's OK if you don't want to use symbols from it directly.
    (the package DLL is loaded by the system linker
     which manages dependencies by itself).
[ 6 of 49] Compiling Echidna.SymExec.Symbolic
[ 7 of 49] Compiling Echidna.SourceMapping
[ 8 of 49] Compiling Echidna.Events
[ 9 of 49] Compiling Echidna.Types
[10 of 49] Compiling Echidna.Types.Cache
[11 of 49] Compiling Echidna.Types.Random
[12 of 49] Compiling Echidna.Types.Signature
[13 of 49] Compiling Echidna.ABI
[14 of 49] Compiling Echidna.Types.Solidity
[15 of 49] Compiling Echidna.Types.Tx

/home/runner/work/hevm/hevm/echidna-src/lib/Echidna/Types/Tx.hs:238:13: warning: [GHC-62161] [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In a \case alternative:
        Patterns of type ‘VMResult Concrete’ not matched:
            VMFailure AssumeCheatFailed
    |
238 | getResult = \case
    |             ^^^^^...
[16 of 49] Compiling Echidna.Types.Test
[17 of 49] Compiling Echidna.Types.Coverage
[18 of 49] Compiling Echidna.Types.Campaign
[19 of 49] Compiling Echidna.Types.Corpus
[20 of 49] Compiling Echidna.Pretty
[21 of 49] Compiling Echidna.Output.Foundry
[22 of 49] Compiling Echidna.Types.Worker
[23 of 49] Compiling Echidna.Types.World
[24 of 49] Compiling Echidna.Utility
[25 of 49] Compiling Echidna.SourceAnalysis.Slither
[26 of 49] Compiling Echidna.Types.Config
[27 of 49] Compiling Echidna.Transaction
[28 of 49] Compiling Echidna.Mutator.Corpus
[29 of 49] Compiling Echidna.SymExec.Common

/home/runner/work/hevm/hevm/echidna-src/lib/Echidna/SymExec/Common.hs:19:69: error: [GHC-61689]
    Module ‘EVM.Solidity’ does not export ‘WarningData(..)’.
   |
19 | import EVM.Solidity (SolcContract(..), SourceCache(..), Method(..), WarningData(..))
   |                                                                     ^^^^^^^^^^^^^^^
[30 of 49] Compiling Echidna.Output.JSON
[31 of 49] Compiling Echidna.Output.Source
[32 of 49] Compiling Echidna.Onchain
[33 of 49] Compiling Echidna.Exec
[34 of 49] Compiling Echidna.Test
[35 of 49] Compiling Echidna.Config
[36 of 49] Compiling Echidna.Shrink
[37 of 49] Compiling Echidna.Deploy
[38 of 49] Compiling Echidna.Solidity
[39 of 49] Compiling Echidna.Worker
[40 of 49] Compiling Echidna.UI.Report
[43 of 49] Compiling Echidna.Server
[44 of 49] Compiling Echidna.Output.Corpus
[45 of 49] Compiling Echidna
[47 of 49] Compiling Paths_echidna
[48 of 49] Compiling Echidna.UI.Widgets
Completed 223 action(s).

Error: [S-7282]
       Stack failed to execute the build plan.
       
       While executing the build plan, Stack encountered the error:
       
       [S-7011]
       While building package echidna-2.3.1 (scroll up to its section to see the error) using:
       /home/runner/.stack/setup-exe-cache/x86_64-linux/Cabal-simple_O_vy6YIf_3.10.3.0_ghc-9.8.4 --verbose=1 --builddir=.stack-work/dist/x86_64-linux/ghc-9.8.4 build lib:echidna exe:echidna test:echidna-testsuite --ghc-options ""
       Process exited with code: ExitFailure 1 

The one from echidna just <<loop>>s
@gustavo-grieco
Copy link
Collaborator Author

Btw, it is expected that this fails as echidna fails with the latest hevm revision

@gustavo-grieco gustavo-grieco changed the title RFC: optional Echidna compatibility check as a Github Action Optional Echidna compatibility check as a Github Action Feb 25, 2026
@gustavo-grieco gustavo-grieco marked this pull request as ready for review February 25, 2026 21:04
@msooseth
Copy link
Collaborator

msooseth commented Mar 2, 2026

OH, it's good now? I'll review today :) Thanks!

@msooseth
Copy link
Collaborator

msooseth commented Mar 5, 2026

@blishko do you also wanna have a go at this? I'm actually OK with it -- it doesn't add anything to hevm, only adds another hook to build. Ultimately, I think it's fine as long as it doesn't break by accident, and only breaks if it really ought to break because we broke Echidna :D

Comment on lines +51 to +74
if 'extra-deps' in data:
new_deps = []
found_hevm = False
for dep in data['extra-deps']:
# Identify if this is the remote hevm dependency
is_hevm = (isinstance(dep, dict)
and 'git' in dep
and 'hevm' in dep['git'])
if is_hevm:
if not found_hevm:
new_deps.append('./hevm')
found_hevm = True
continue
if dep == './hevm':
found_hevm = True
new_deps.append(dep)
continue
new_deps.append(dep)

if not found_hevm:
# Insert hevm at the beginning of extra-deps
new_deps.insert(0, './hevm')

data['extra-deps'] = new_deps
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is this complicated logic needed?
Isn't the goal just to point echidna to the local hevm version? Isn't there a simpler way to do it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think there is a simpler way to do it using awk/sed but it won't be robust if we change some newlines/comments. Maybe @elopez has more ideas.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not just always prepend ./hevm to existing dependencies? Why all the checks?

Copy link
Collaborator

Choose a reason for hiding this comment

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

hevm is an existing dependency referenced via git, so then there would be two hevms listed potentially with the same version number. But I agree this script is too complicated for what it does. I simplified it a bunch on the latest commit.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Great, thanks! This version is much more understandable!

@blishko
Copy link
Collaborator

blishko commented Mar 5, 2026

Wouldn't it be better to just fail the workflow instead of marking it as successful and just posting a comment?
The comment can be difficult to spot. Failed workflow is spot immediately.

@gustavo-grieco
Copy link
Collaborator Author

@blishko this check is optional to avoid imposing a new burden to the hevm team. You can decide to fail the workflow in the future if you feel the ABI is stable enough.

@blishko
Copy link
Collaborator

blishko commented Mar 5, 2026

I would prefer the strong indication that this workflow is failing.
It is optional, true, so we can just decide to ignore the failure. But at least the failure will be visible.

@elopez
Copy link
Collaborator

elopez commented Mar 7, 2026

I removed the comment stuff now. The only con of just letting it fail is that whenever a breaking change is introduced to hevm, all commits, PRs, etc will then start to be marked with ❌ in the GitHub UI. That might make it hard to tell apart actual failures that need attention from the known compatibility breakage.

@blishko
Copy link
Collaborator

blishko commented Mar 8, 2026

Having the breakage be more visible is better in this case, but that is my personal opinion.
Let's try and if it is too distractive, we can go back to the PR comment.

@blishko
Copy link
Collaborator

blishko commented Mar 8, 2026

BTW, what was the reason for the current breakage? Do you plan to fix it in Echidna soon?

Copy link
Collaborator

@blishko blishko left a comment

Choose a reason for hiding this comment

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

LGMT!

@blishko
Copy link
Collaborator

blishko commented Mar 8, 2026

I think we can squash this to a single commit, no?

@gustavo-grieco
Copy link
Collaborator Author

Yes

@blishko blishko merged commit 436ef08 into main Mar 9, 2026
7 of 9 checks passed
@blishko blishko deleted the dev-echidna-compat-check branch March 9, 2026 12:21
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.

4 participants