Skip to content

Commit

Permalink
Wrap fetch exceptions (#971)
Browse files Browse the repository at this point in the history
  • Loading branch information
arcz authored Mar 7, 2023
1 parent fef5dae commit d58a3b4
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions lib/Echidna/Exec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Echidna.Exec where

import Control.Lens
import Control.Monad (when)
import Control.Monad.Catch (MonadThrow(..))
import Control.Monad.Catch (MonadThrow(..), catchAll, SomeException)
import Control.Monad.State.Strict (MonadState(get, put), execState, runStateT, MonadIO(liftIO))
import Control.Monad.Reader (MonadReader, asks)
import Data.IORef (readIORef, atomicWriteIORef)
Expand Down Expand Up @@ -111,7 +111,7 @@ execTxWith l onErr executeTx tx = do
getRpcUrl >>= \case
Just rpcUrl -> do
rpcBlock <- getRpcBlock
ret <- liftIO $ EVM.Fetch.fetchContractFrom rpcBlock rpcUrl addr
ret <- liftIO $ safeFetchContractFrom rpcBlock rpcUrl addr
case ret of
-- TODO: fix hevm to not return an empty contract in case of an error
Just contract | contract._contractcode /= EVM.RuntimeCode (EVM.ConcreteRuntimeCode "") -> do
Expand Down Expand Up @@ -153,7 +153,7 @@ execTxWith l onErr executeTx tx = do
getRpcUrl >>= \case
Just rpcUrl -> do
rpcBlock <- getRpcBlock
ret <- liftIO $ EVM.Fetch.fetchSlotFrom rpcBlock rpcUrl addr slot
ret <- liftIO $ safeFetchSlotFrom rpcBlock rpcUrl addr slot
case ret of
Just value -> do
l %= execState (continuation value)
Expand Down Expand Up @@ -188,12 +188,25 @@ execTxWith l onErr executeTx tx = do
getRpcUrl = liftIO $ do
val <- lookupEnv "ECHIDNA_RPC_URL"
pure (Text.pack <$> val)

getRpcBlock = liftIO $ do
-- TODO: Is the latest block a good default? It makes fuzzing hard to
-- reproduce. Rethink this.
val <- lookupEnv "ECHIDNA_RPC_BLOCK"
pure $ maybe EVM.Fetch.Latest EVM.Fetch.BlockNumber (val >>= readMaybe)

-- TODO: temporary solution, handle errors gracefully
safeFetchContractFrom rpcBlock rpcUrl addr =
catchAll
(EVM.Fetch.fetchContractFrom rpcBlock rpcUrl addr)
(\(_e :: SomeException) -> pure $ Just emptyAccount)

-- TODO: temporary solution, handle errors gracefully
safeFetchSlotFrom rpcBlock rpcUrl addr slot =
catchAll
(EVM.Fetch.fetchSlotFrom rpcBlock rpcUrl addr slot)
(\(_e :: SomeException) -> pure $ Just 0)

-- | Handles reverts, failures and contract creations that might be the result
-- (`vmResult`) of executing transaction `tx`.
handleErrorsAndConstruction vmResult vmBeforeTx = case (vmResult, tx.call) of
Expand Down

0 comments on commit d58a3b4

Please sign in to comment.