add the multi-abi config flag

pull/344/head
Will Song 5 years ago
parent e4b8c9d286
commit 0157f06e46
  1. 2
      examples/solidity/basic/default.yaml
  2. 1
      lib/Echidna/Config.hs
  3. 13
      lib/Echidna/Solidity.hs
  4. 2
      src/test/Spec.hs

@ -41,6 +41,8 @@ cryticArgs: []
quiet: false quiet: false
#initialize the blockchain with some data #initialize the blockchain with some data
initialize: null initialize: null
#whether ot not to use the multi-abi mode of testing
multi-abi: false
#checkAsserts checks assertions #checkAsserts checks assertions
checkAsserts: false checkAsserts: false
#dashboard determines if output is just text or an AFL-like display #dashboard determines if output is just text or an AFL-like display

@ -146,6 +146,7 @@ instance FromJSON EConfigWithUsage where
<*> v ..:? "solcLibs" ..!= [] <*> v ..:? "solcLibs" ..!= []
<*> v ..:? "quiet" ..!= False <*> v ..:? "quiet" ..!= False
<*> v ..:? "initialize" ..!= Nothing <*> v ..:? "initialize" ..!= Nothing
<*> v ..:? "multi-abi" ..!= False
<*> v ..:? "checkAsserts" ..!= False) <*> v ..:? "checkAsserts" ..!= False)
<*> tc <*> tc
<*> xc <*> xc

@ -94,6 +94,7 @@ data SolConf = SolConf { _contractAddr :: Addr -- ^ Contract addr
, _solcLibs :: [String] -- ^ List of libraries to load, in order. , _solcLibs :: [String] -- ^ List of libraries to load, in order.
, _quiet :: Bool -- ^ Suppress @solc@ output, errors, and warnings , _quiet :: Bool -- ^ Suppress @solc@ output, errors, and warnings
, _initialize :: Maybe FilePath -- ^ Initialize world with Etheno txns , _initialize :: Maybe FilePath -- ^ Initialize world with Etheno txns
, _multiAbi :: Bool -- ^ Whether or not to use the multi-abi mode
, _checkAsserts :: Bool -- ^ Test if we can cause assertions to fail , _checkAsserts :: Bool -- ^ Test if we can cause assertions to fail
} }
makeLenses ''SolConf makeLenses ''SolConf
@ -128,7 +129,7 @@ contracts fp = let usual = ["--solc-disable-warnings", "--export-format", "solc"
concat <$> sequence (compileOne <$> fps) concat <$> sequence (compileOne <$> fps)
addresses :: (MonadReader x m, Has SolConf x) => m (NE.NonEmpty AbiValue) addresses :: (MonadReader x m, Has SolConf x) => m (NE.NonEmpty AbiValue)
addresses = view hasLens <&> \(SolConf ca d ads _ _ _ _ _ _ _ _ _) -> addresses = view hasLens <&> \(SolConf ca d ads _ _ _ _ _ _ _ _ _ _) ->
AbiAddress . fromIntegral <$> NE.nub (join ads [ca, d, 0x0]) AbiAddress . fromIntegral <$> NE.nub (join ads [ca, d, 0x0])
where join (first NE.:| rest) list = first NE.:| (rest ++ list) where join (first NE.:| rest) list = first NE.:| (rest ++ list)
@ -171,17 +172,17 @@ loadSpecified name cs = do
unless q . putStrLn $ "Analyzing contract: " <> c ^. contractName . unpacked unless q . putStrLn $ "Analyzing contract: " <> c ^. contractName . unpacked
-- Local variables -- Local variables
(SolConf ca d ads bala balc pref _ _ libs _ fp ch) <- view hasLens (SolConf ca d ads bala balc pref _ _ libs _ fp ma ch) <- view hasLens
-- generate the complete abi mapping -- generate the complete abi mapping
let abiOf :: SolcContract -> NE.NonEmpty SolSignature let abiOf :: SolcContract -> NE.NonEmpty SolSignature
abiOf cc = fallback NE.:| filter (not . isPrefixOf pref . fst) (elems (cc ^. abiMap) <&> \m -> (m ^. methodName, m ^.. methodInputs . traverse . _2)) abiOf cc = fallback NE.:| filter (not . isPrefixOf pref . fst) (elems (cc ^. abiMap) <&> \m -> (m ^. methodName, m ^.. methodInputs . traverse . _2))
abiMapping = M.fromList $ cs <&> \cc -> (cc ^. runtimeCode, abiOf cc) abiMapping = if ma then M.fromList $ cs <&> \cc -> (cc ^. runtimeCode, abiOf cc) else M.singleton (c ^. runtimeCode) (abiOf c)
bc = c ^. creationCode
let bc = c ^. creationCode
abi = liftM2 (,) (view methodName) (fmap snd . view methodInputs) <$> toList (c ^. abiMap) abi = liftM2 (,) (view methodName) (fmap snd . view methodInputs) <$> toList (c ^. abiMap)
con = view constructorInputs c con = view constructorInputs c
(tests, funs) = partition (isPrefixOf pref . fst) abi (tests, funs) = partition (isPrefixOf pref . fst) abi
-- Set up initial VM, either with chosen contract or Etheno initialization file -- Set up initial VM, either with chosen contract or Etheno initialization file
-- need to use snd to add to ABI dict -- need to use snd to add to ABI dict
blank' <- maybe (pure (vmForEthrunCreation bc)) (loadEthenoBatch (fst <$> tests)) fp blank' <- maybe (pure (vmForEthrunCreation bc)) (loadEthenoBatch (fst <$> tests)) fp
@ -228,7 +229,7 @@ loadWithCryticCompile fp name = contracts fp >>= loadSpecified name
-- for running a 'Campaign' against the tests found. -- for running a 'Campaign' against the tests found.
prepareForTest :: (MonadReader x m, Has SolConf x) prepareForTest :: (MonadReader x m, Has SolConf x)
=> (VM, NE.NonEmpty SolSignature, [Text], M.HashMap BS.ByteString (NE.NonEmpty SolSignature)) -> m (VM, World, [SolTest]) => (VM, NE.NonEmpty SolSignature, [Text], M.HashMap BS.ByteString (NE.NonEmpty SolSignature)) -> m (VM, World, [SolTest])
prepareForTest (v, a, ts, m) = view hasLens <&> \(SolConf _ _ s _ _ _ _ _ _ _ _ ch) -> prepareForTest (v, a, ts, m) = view hasLens <&> \(SolConf _ _ s _ _ _ _ _ _ _ _ _ ch) ->
(v, World s m, fmap Left (zip ts $ repeat r) ++ if ch then Right <$> drop 1 a' else []) where (v, World s m, fmap Left (zip ts $ repeat r) ++ if ch then Right <$> drop 1 a' else []) where
r = v ^. state . contract r = v ^. state . contract
a' = NE.toList a a' = NE.toList a

@ -196,7 +196,7 @@ integrationTests = testGroup "Solidity Integration Testing"
c <- set (sConf . quiet) True <$> maybe (pure testConfig) (fmap _econfig . parseConfig) cfg c <- set (sConf . quiet) True <$> maybe (pure testConfig) (fmap _econfig . parseConfig) cfg
res <- runContract fp (Just "Foo") c res <- runContract fp (Just "Foo") c
assertBool "echidna_test passed" $ solved "echidna_test" res assertBool "echidna_test passed" $ solved "echidna_test" res
, testContract' "basic/multi-abi.sol" (Just "B") Nothing , testContract' "basic/multi-abi.sol" (Just "B") (Just "basic/multi-abi.yaml")
[ ("echidna_test passed", solved "echidna_test") ] [ ("echidna_test passed", solved "echidna_test") ]
, testContract "abiv2/Ballot.sol" Nothing , testContract "abiv2/Ballot.sol" Nothing
[ ("echidna_test passed", solved "echidna_test") ] [ ("echidna_test passed", solved "echidna_test") ]

Loading…
Cancel
Save