-
Notifications
You must be signed in to change notification settings - Fork 373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Source coverage printing after fuzzing campaign #516
Conversation
lib/Echidna.hs
Outdated
@@ -39,14 +40,14 @@ import qualified Data.List.NonEmpty as NE | |||
-- * A list of transaction sequences to initialize the corpus | |||
prepareContract :: (MonadCatch m, MonadRandom m, MonadReader x m, MonadIO m, MonadFail m, | |||
Has TxConf x, Has SolConf x) | |||
=> EConfig -> NE.NonEmpty FilePath -> Maybe String -> Seed -> m (VM, World, [SolTest], Maybe GenDict, [[Tx]]) | |||
=> EConfig -> NE.NonEmpty FilePath -> Maybe String -> Seed -> m (VM, SourceCache, [SolcContract], World, [SolTest], Maybe GenDict, [[Tx]]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe prepareContract
should take [SolcContract]
provided by prior calling of Echidna.Solidity.contracts
as an argument rather than FilePath
s?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean exactly?
lib/Echidna/Campaign.hs
Outdated
@@ -161,7 +161,7 @@ execTxOptC t = do | |||
res <- execTxWith vmExcept (usingCoverage $ pointCoverage cov) t | |||
let vmr = getResult $ fst res | |||
-- Update the coverage map with the proper binary according to the vm result | |||
cov %= mapWithKey (\_ s -> DS.map (set _2 vmr) s) | |||
cov %= mapWithKey (\_ s -> DS.map (\(i, j, _) -> (i, j, vmr)) s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set _3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
lib/Echidna/Exec.hs
Outdated
|
||
-- | Capture the current PC and bytecode (without metadata). This should identify instructions uniquely. | ||
pointCoverage :: (MonadState x m, Has VM x) => Lens' x CoverageMap -> m () | ||
pointCoverage l = do | ||
v <- use hasLens | ||
l %= M.insertWith (const . S.insert $ (v ^. state . pc, Success)) | ||
l %= M.insertWith (const . S.insert $ ( v ^. state . pc, fromJust $ vmOpIx v, Success)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rogue space
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
lib/Echidna/Output/JSON.hs
Outdated
@@ -22,7 +22,7 @@ data Campaign = Campaign | |||
, _error :: Maybe String | |||
, _tests :: [Test] | |||
, seed :: Int | |||
, coverage :: Map String [(Int, TxResult)] | |||
, coverage :: Map String [(Int, Int, TxResult)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use your new types?
lib/Echidna/Output/Source.hs
Outdated
@@ -0,0 +1,122 @@ | |||
{-# LANGUAGE DataKinds #-} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DataKinds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
|
||
-- | Mark one particular line, from a list of lines, keeping the order of them | ||
markLine :: Int -> TxResult -> FilePathText -> [(FilePathText, Text)] -> [(FilePathText, Text)] | ||
markLine n r cf ls = case splitAt (n-1) ls of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's make this multiline and indent a bit less
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think now it is better
lib/Echidna/Output/Corpus.hs
Outdated
|
||
import Echidna.Types.Tx | ||
|
||
listDirectory :: FilePath -> IO [FilePath] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe move these directory functions to a util module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
lib/Echidna/Output/Source.hs
Outdated
|
||
type FilePathText = Text | ||
|
||
saveCoveredCode :: Maybe FilePath -> SourceCache -> [SolcContract] -> CoverageMap -> IO () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe rename this to saveCoverage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@@ -73,7 +73,7 @@ runContract :: FilePath -> Maybe ContractName -> EConfig -> IO Campaign | |||
runContract f c cfg = | |||
flip runReaderT cfg $ do | |||
g <- getRandom | |||
(v, w, ts, d, txs) <- prepareContract cfg (f :| []) c g | |||
(v, _, _, w, ts, d, txs) <- prepareContract cfg (f :| []) c g | |||
-- start ui and run tests | |||
campaign (pure ()) v w ts d txs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now that we have a bunch of things from prepareContract
can we make a custom type for prepareContract
and campaign
and ui
to ingest the custom type instead of adding a new parameter every time? feel free to make an issue and refactor in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a new issue to track down this.
lib/Echidna/Types/Signature.hs
Outdated
import Data.List.NonEmpty (NonEmpty) | ||
import Data.ByteString (ByteString) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alphabetize these imports
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/Echidna/Transaction.hs
Outdated
import Control.Monad.Random.Strict (MonadRandom, getRandomR, uniform) | ||
import Control.Monad.Reader.Class (MonadReader) | ||
import Control.Monad.State.Strict (MonadState, State, runState, get, put) | ||
import Data.Aeson (ToJSON(..), decodeStrict, encodeFile) | ||
import Control.Monad (join, liftM2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alphabetize imports
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
This PR allows Echidna to use source information from hevm to print which lines were covered during a fuzzing campaign. There is no need to configure anything, the source information is included in the crytic-compile output. The user should only enable coverage and
corpusDir
. However, the user must update to crytic-compile 0.1.10 (or newer) to make sure the source files are properly sorted when compiling.The directly structure for the corpus directly was slight changed. For instance, after running
flags.sol
, the corpus directory will looks like this:where the
covered.txt
file looks like this:Constructors (#539) and echidna properties are not counting coverage. This should be fixed in another PR.
Each reachable line will have zero or more 'markers', signaling if how the sequence of transactions ended when covering that line. So far, we have support for the following markers:
*
for sequences ended with a return.r
for sequences ended with a revert.o
for sequences ended with an out-of-gas error.e
for every other type of error (e.g. self-destruction, insufficient balance, etc).It also introduced a small refactoring to move the corpus functions into a separated module inside
Output
.