Skip to content

Commit 6bbcf1f

Browse files
authored
Merge pull request #663 from ethereum/dev-windows-ci-fix
tests: run `evm` on its own directory
2 parents 54eb53a + 24ee110 commit 6bbcf1f

File tree

4 files changed

+53
-64
lines changed

4 files changed

+53
-64
lines changed

.github/workflows/build.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,6 @@ jobs:
228228
echo HEVM_SOLIDITY_REPO="$PWD/ethereum-solidity" >> "$GITHUB_ENV"
229229
echo HEVM_ETHEREUM_TESTS_REPO="$PWD/ethereum-tests" >> "$GITHUB_ENV"
230230
echo HEVM_FORGE_STD_REPO="$PWD/forge-std" >> "$GITHUB_ENV"
231-
# environment
232-
echo HEVM_SYSTEM_SHELL="$(which bash)" >> "$GITHUB_ENV"
233231
234232
- name: run tests
235233
run: |

test/EVM/Test/BlockchainTests.hs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import Data.Word (Word64)
3333
import System.Environment (lookupEnv, getEnv)
3434
import System.FilePath.Find qualified as Find
3535
import System.FilePath.Posix (makeRelative, (</>))
36+
import System.IO (hPutStr, hClose)
37+
import System.IO.Temp (withSystemTempFile)
3638
import System.Process (readProcessWithExitCode)
3739
import GHC.IO.Exception (ExitCode(ExitSuccess))
3840
import Witch (into, unsafeInto)
@@ -208,8 +210,10 @@ traceVsGeth fname name x = do
208210
putStrLn $ "evmtool stderr output:" <> show evmtoolStderr
209211
putStrLn $ "evmtool stdout output:" <> show evmtoolStdout
210212
hevm <- traceVMTest x
211-
liftIO $ writeFile "trace.jsonl" $ filterInfoLines evmtoolStderr
212-
decodedContents <- liftIO $ decodeTraceOutputHelper "trace.jsonl"
213+
decodedContents <- liftIO $ withSystemTempFile "trace.jsonl" $ \traceFile hdl -> do
214+
hPutStr hdl $ filterInfoLines evmtoolStderr
215+
hClose hdl
216+
decodeTraceOutputHelper traceFile
213217
let EVMToolTraceOutput ts _ = fromJust decodedContents
214218
liftIO $ putStrLn "Comparing traces."
215219
_ <- liftIO $ compareTraces hevm ts

test/EVM/Test/Tracing.hs

Lines changed: 45 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@ import Data.Aeson qualified as JSON
2323
import Data.ByteString (ByteString)
2424
import Data.ByteString qualified as BS
2525
import Data.ByteString.Char8 qualified as Char8
26-
import Data.Maybe (fromJust, fromMaybe, isJust, isNothing)
26+
import Data.Maybe (fromJust, isJust, isNothing)
2727
import Data.Map.Strict qualified as Map
2828
import Data.Text.IO qualified as T
2929
import Data.Vector qualified as Vector
3030
import Data.Word (Word8, Word64)
3131
import GHC.Generics (Generic)
3232
import GHC.IO.Exception (ExitCode(ExitSuccess))
3333
import Numeric (showHex)
34-
import Paths_hevm qualified as Paths
35-
import System.Directory (removeFile)
36-
import System.Environment (lookupEnv)
37-
import System.Process (readProcessWithExitCode)
34+
import System.Directory (removeDirectoryRecursive)
35+
import System.FilePath ((</>))
36+
import System.IO.Temp (getCanonicalTemporaryDirectory, createTempDirectory)
37+
import System.Process (readCreateProcessWithExitCode, proc, CreateProcess(..))
3838
import Test.QuickCheck (elements)
3939
import Test.QuickCheck.Instances.Text()
4040
import Test.QuickCheck.Instances.Natural()
@@ -308,8 +308,8 @@ getHEVMRet contr txData gaslimitExec = do
308308
let (txn, evmEnv, contrAlloc, fromAddress, toAddress, _) = evmSetup contr txData gaslimitExec
309309
runCodeWithTrace Nothing evmEnv contrAlloc txn (LitAddr fromAddress) (LitAddr toAddress)
310310

311-
getEVMToolRet :: OpContract -> ByteString -> Int -> IO (Maybe EVMToolResult)
312-
getEVMToolRet contr txData gaslimitExec = do
311+
getEVMToolRet :: FilePath -> OpContract -> ByteString -> Int -> IO (Maybe EVMToolResult)
312+
getEVMToolRet evmDir contr txData gaslimitExec = do
313313
let (txn, evmEnv, contrAlloc, fromAddress, toAddress, sk) = evmSetup contr txData gaslimitExec
314314
txs = [EVM.Transaction.sign sk txn]
315315
walletAlloc = EVMToolAlloc{ balance = 0x5ffd4878be161d74
@@ -318,24 +318,25 @@ getEVMToolRet contr txData gaslimitExec = do
318318
}
319319
alloc :: Map.Map Addr EVMToolAlloc
320320
alloc = Map.fromList ([ (fromAddress, walletAlloc), (toAddress, contrAlloc)])
321-
JSON.encodeFile "txs.json" txs
322-
JSON.encodeFile "alloc.json" alloc
323-
JSON.encodeFile "env.json" evmEnv
324-
(exitCode, evmtoolStdout, evmtoolStderr) <- readProcessWithExitCode "evm" [ "transition"
325-
, "--state.fork", "Cancun"
326-
, "--input.alloc" , "alloc.json"
327-
, "--input.env" , "env.json"
328-
, "--input.txs" , "txs.json"
329-
, "--output.alloc" , "alloc-out.json"
330-
, "--trace.returndata=true"
331-
, "--trace" , "trace.json"
332-
, "--output.result", "result.json"
333-
] ""
321+
JSON.encodeFile (evmDir </> "txs.json") txs
322+
JSON.encodeFile (evmDir </> "alloc.json") alloc
323+
JSON.encodeFile (evmDir </> "env.json") evmEnv
324+
let cmd = (proc "evm" [ "transition"
325+
, "--state.fork", "Cancun"
326+
, "--input.alloc", "alloc.json"
327+
, "--input.env", "env.json"
328+
, "--input.txs", "txs.json"
329+
, "--output.alloc", "alloc-out.json"
330+
, "--trace.returndata=true"
331+
, "--trace", "trace.json"
332+
, "--output.result", "result.json"
333+
]) { cwd = Just evmDir }
334+
(exitCode, evmtoolStdout, evmtoolStderr) <- readCreateProcessWithExitCode cmd ""
334335
when (exitCode /= ExitSuccess) $ do
335336
putStrLn $ "evmtool exited with code " <> show exitCode
336337
putStrLn $ "evmtool stderr output:" <> show evmtoolStderr
337338
putStrLn $ "evmtool stdout output:" <> show evmtoolStdout
338-
JSON.decodeFileStrict "result.json" :: IO (Maybe EVMToolResult)
339+
JSON.decodeFileStrict (evmDir </> "result.json") :: IO (Maybe EVMToolResult)
339340

340341
-- Compares traces of evmtool (from go-ethereum) and HEVM
341342
compareTraces :: [VMTrace] -> [EVMToolTrace] -> IO (Bool)
@@ -389,45 +390,34 @@ compareTraces hevmTrace evmTrace = go hevmTrace evmTrace
389390
putStrLn $ "Traces don't match. evmtool's trace is longer by:" <> (show b)
390391
pure False
391392

392-
getTraceFileName :: EVMToolResult -> String
393-
getTraceFileName evmtoolResult = traceFileName
393+
getTraceFileName :: FilePath -> EVMToolResult -> String
394+
getTraceFileName evmDir evmtoolResult = evmDir </> traceFileName
394395
where
395396
txName = ((evmtoolResult.receipts) !! 0).transactionHash
396397
traceFileName = "trace-0-" ++ txName ++ ".jsonl"
397398

398-
getTraceOutput :: Maybe EVMToolResult -> IO (Maybe EVMToolTraceOutput)
399-
getTraceOutput evmtoolResult =
399+
getTraceOutput :: FilePath -> Maybe EVMToolResult -> IO (Maybe EVMToolTraceOutput)
400+
getTraceOutput evmDir evmtoolResult =
400401
case evmtoolResult of
401402
Nothing -> pure Nothing
402403
Just res -> do
403-
let traceFileName = getTraceFileName res
404+
let traceFileName = getTraceFileName evmDir res
404405
decodeTraceOutputHelper traceFileName
405406

406407
decodeTraceOutputHelper :: String -> IO (Maybe EVMToolTraceOutput)
407408
decodeTraceOutputHelper traceFileName = do
408-
convertPath <- Paths.getDataFileName "test/scripts/convert_trace_to_json.sh"
409-
maybeShellPath <- (fromMaybe "bash") <$> (lookupEnv "HEVM_SYSTEM_SHELL")
410-
let shellPath = if maybeShellPath == "" then "bash" else maybeShellPath
411-
(exitcode, stdout, stderr) <- readProcessWithExitCode shellPath [convertPath, traceFileName] ""
412-
case exitcode of
413-
ExitSuccess -> do
414-
-- putStrLn $ "Successfully converted trace to JSON: " <> (show stdout) <> " " <>
415-
-- (show stderr) <> " " <> (show exitcode) <> " " <> (show traceFileName)
416-
JSON.decodeFileStrict (traceFileName ++ ".json") :: IO (Maybe EVMToolTraceOutput)
417-
_ -> do
418-
putStrLn $ "Error converting trace! exit code:" <> (show exitcode)
419-
putStrLn $ "stdout: " <> (show stdout)
420-
putStrLn $ "stderr: " <> (show stderr)
421-
pure Nothing
422-
423-
deleteTraceOutputFiles :: Maybe EVMToolResult -> IO ()
424-
deleteTraceOutputFiles evmtoolResult =
425-
case evmtoolResult of
426-
Nothing -> pure ()
427-
Just res -> do
428-
let traceFileName = getTraceFileName res
429-
System.Directory.removeFile traceFileName
430-
System.Directory.removeFile (traceFileName ++ ".json")
409+
traceContents <- readFile traceFileName
410+
let traceLines = lines traceContents
411+
let (traces, outputLines) = splitAt (length traceLines - 1) traceLines
412+
let parsedTraces = map decodeString traces :: [Maybe EVMToolTrace]
413+
let parsedOutput = decodeString (outputLines !! 0) :: Maybe EVMToolOutput
414+
if all isJust parsedTraces && isJust parsedOutput then
415+
pure $ Just $ EVMToolTraceOutput (map fromJust parsedTraces) (fromJust parsedOutput)
416+
else
417+
pure Nothing
418+
where
419+
decodeString :: (JSON.FromJSON a) => String -> Maybe a
420+
decodeString = JSON.decodeStrict . Char8.pack
431421

432422
-- | Takes a runtime code and calls it with the provided calldata
433423
-- Uses evmtool's alloc and transaction to set up the VM correctly
@@ -875,9 +865,11 @@ tests = testGroup "contract-quickcheck-run"
875865

876866
checkTraceAndOutputs :: App m => OpContract -> Int -> ByteString -> m ()
877867
checkTraceAndOutputs contract gasLimit txData = do
878-
evmtoolResult <- liftIO $ getEVMToolRet contract txData gasLimit
868+
tmpDir <- liftIO getCanonicalTemporaryDirectory
869+
evmDir <- liftIO $ createTempDirectory tmpDir "evm-trace"
870+
evmtoolResult <- liftIO $ getEVMToolRet evmDir contract txData gasLimit
879871
hevmRun <- getHEVMRet contract txData gasLimit
880-
evmtoolTraceOutput <- fmap fromJust $ liftIO $ getTraceOutput evmtoolResult
872+
evmtoolTraceOutput <- fmap fromJust $ liftIO $ getTraceOutput evmDir evmtoolResult
881873
case hevmRun of
882874
(Right (expr, hevmTrace, hevmTraceResult)) -> liftIO $ do
883875
let
@@ -915,7 +907,7 @@ checkTraceAndOutputs contract gasLimit txData = do
915907
putStrLn $ "ret value computed via symb+conc : " <> (bsToHex (fromJust simplConcrExprRetval))
916908
assertEqual "Simplified, concretized expression must match evmtool's output." True False
917909
else do
918-
putStrLn $ "Name of trace file: " <> (getTraceFileName $ fromJust evmtoolResult)
910+
putStrLn $ "Name of trace file: " <> (getTraceFileName evmDir $ fromJust evmtoolResult)
919911
putStrLn $ "HEVM result :" <> (show hevmTraceResult)
920912
T.putStrLn $ "HEVM result: " <> (formatBinary $ bssToBs hevmTraceResult.out)
921913
T.putStrLn $ "evm result : " <> (formatBinary $ bssToBs evmtoolTraceOutput.output.output)
@@ -928,13 +920,7 @@ checkTraceAndOutputs contract gasLimit txData = do
928920
-- putStrLn $ "output by evmtool is: '" <> bsToHex evmtoolTraceOutput.toOutput.output <> "'"
929921
traceOK <- compareTraces hevmTrace (evmtoolTraceOutput.trace)
930922
assertEqual "Traces and gas must match" traceOK True
931-
liftIO $ do
932-
System.Directory.removeFile "txs.json"
933-
System.Directory.removeFile "alloc-out.json"
934-
System.Directory.removeFile "alloc.json"
935-
System.Directory.removeFile "result.json"
936-
System.Directory.removeFile "env.json"
937-
deleteTraceOutputFiles evmtoolResult
923+
liftIO $ removeDirectoryRecursive evmDir
938924

939925
-- GasLimitInt
940926
newtype GasLimitInt = GasLimitInt (Int)
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env bash
2+
set -euxo pipefail
23

3-
num=$(wc -l "$1" | cut -d " " -f 1)
4+
num=$(awk 'END{print NR}' "$1")
45
awk -v ll="$num" 'BEGIN {print "{\"trace\": [" } {if (NR!=ll) {print $0; if (NR!=ll-1) {print ","}} else {print "], \"output\":" $0}} END{print "}"}' "$1" > "$1.json"

0 commit comments

Comments
 (0)