1 /* 2 This file is part of solidity. 3 4 solidity is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 solidity is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with solidity. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 // SPDX-License-Identifier: GPL-3.0 18 19 #pragma once 20 21 #include <test/EVMHost.h> 22 23 #include <libsolidity/interface/CompilerStack.h> 24 25 #include <libyul/AssemblyStack.h> 26 27 #include <libsolutil/Keccak256.h> 28 29 #include <evmone/evmone.h> 30 31 namespace solidity::test::fuzzer 32 { 33 struct CompilerOutput 34 { 35 /// EVM bytecode returned by compiler 36 solidity::bytes byteCode; 37 /// Method identifiers in a contract 38 Json::Value methodIdentifiersInContract; 39 }; 40 41 struct CompilerInput 42 { 43 CompilerInput( 44 langutil::EVMVersion _evmVersion, 45 StringMap const& _sourceCode, 46 std::string const& _contractName, 47 frontend::OptimiserSettings _optimiserSettings, 48 std::map<std::string, solidity::util::h160> _libraryAddresses, 49 bool _debugFailure = false, 50 bool _viaIR = false 51 ): evmVersionCompilerInput52 evmVersion(_evmVersion), 53 sourceCode(_sourceCode), 54 contractName(_contractName), 55 optimiserSettings(_optimiserSettings), 56 libraryAddresses(_libraryAddresses), 57 debugFailure(_debugFailure), 58 viaIR(_viaIR) 59 {} 60 /// EVM target version 61 langutil::EVMVersion evmVersion; 62 /// Source code to be compiled 63 StringMap const& sourceCode; 64 /// Contract name without a colon prefix 65 std::string contractName; 66 /// Optimiser setting to be used during compilation 67 frontend::OptimiserSettings optimiserSettings; 68 /// Information on which library is deployed where 69 std::map<std::string, solidity::util::h160> libraryAddresses; 70 /// Flag used for debugging 71 bool debugFailure; 72 /// Flag to enable new code generator. 73 bool viaIR; 74 }; 75 76 class SolidityCompilationFramework 77 { 78 public: SolidityCompilationFramework(CompilerInput _input)79 SolidityCompilationFramework(CompilerInput _input): m_compilerInput(_input) 80 {} 81 /// Sets contract name to @param _contractName. contractName(std::string const & _contractName)82 void contractName(std::string const& _contractName) 83 { 84 m_compilerInput.contractName = _contractName; 85 } 86 /// Sets library addresses to @param _libraryAddresses. libraryAddresses(std::map<std::string,solidity::util::h160> _libraryAddresses)87 void libraryAddresses(std::map<std::string, solidity::util::h160> _libraryAddresses) 88 { 89 m_compilerInput.libraryAddresses = std::move(_libraryAddresses); 90 } 91 /// @returns method identifiers in contract called @param _contractName. methodIdentifiers(std::string const & _contractName)92 Json::Value methodIdentifiers(std::string const& _contractName) 93 { 94 return m_compiler.methodIdentifiers(_contractName); 95 } 96 /// @returns Compilation output comprising EVM bytecode and list of 97 /// method identifiers in contract if compilation is successful, 98 /// null value otherwise. 99 std::optional<CompilerOutput> compileContract(); 100 private: 101 frontend::CompilerStack m_compiler; 102 CompilerInput m_compilerInput; 103 }; 104 105 class EvmoneUtility 106 { 107 public: EvmoneUtility(solidity::test::EVMHost & _evmHost,CompilerInput _compilerInput,std::string const & _contractName,std::string const & _libraryName,std::string const & _methodName)108 EvmoneUtility( 109 solidity::test::EVMHost& _evmHost, 110 CompilerInput _compilerInput, 111 std::string const& _contractName, 112 std::string const& _libraryName, 113 std::string const& _methodName 114 ): 115 m_evmHost(_evmHost), 116 m_compilationFramework(_compilerInput), 117 m_contractName(_contractName), 118 m_libraryName(_libraryName), 119 m_methodName(_methodName) 120 {} 121 /// @returns the result returned by the EVM host on compiling, deploying, 122 /// and executing test configuration. 123 /// @param _isabelleData contains encoding data to be passed to the 124 /// isabelle test entry point. 125 std::optional<evmc::result> compileDeployAndExecute(std::string _isabelleData = {}); 126 /// Compares the contents of the memory address pointed to 127 /// by `_result` of `_length` bytes to u256 zero. 128 /// @returns true if `_result` is zero, false 129 /// otherwise. 130 static bool zeroWord(uint8_t const* _result, size_t _length); 131 /// @returns an evmc_message with all of its fields zero 132 /// initialized except gas and input fields. 133 /// The gas field is set to the maximum permissible value so that we 134 /// don't run into out of gas errors. The input field is copied from 135 /// @param _input. 136 static evmc_message initializeMessage(bytes const& _input); 137 private: 138 /// @returns the result of the execution of the function whose 139 /// keccak256 hash is @param _functionHash that is deployed at 140 /// @param _deployedAddress in @param _hostContext. 141 evmc::result executeContract( 142 bytes const& _functionHash, 143 evmc_address _deployedAddress 144 ); 145 /// @returns the result of deployment of @param _code on @param _hostContext. 146 evmc::result deployContract(bytes const& _code); 147 /// Deploys and executes EVM byte code in @param _byteCode on 148 /// EVM Host referenced by @param _hostContext. Input passed 149 /// to execution context is @param _hexEncodedInput. 150 /// @returns result returning by @param _hostContext. 151 evmc::result deployAndExecute( 152 bytes const& _byteCode, 153 std::string const& _hexEncodedInput 154 ); 155 /// Compiles contract named @param _contractName present in 156 /// @param _sourceCode, optionally using a precompiled library 157 /// specified via a library mapping and an optimisation setting. 158 /// @returns a pair containing the generated byte code and method 159 /// identifiers for methods in @param _contractName. 160 std::optional<CompilerOutput> compileContract(); 161 162 /// EVM Host implementation 163 solidity::test::EVMHost& m_evmHost; 164 /// Solidity compilation framework 165 SolidityCompilationFramework m_compilationFramework; 166 /// Contract name 167 std::string m_contractName; 168 /// Library name 169 std::string m_libraryName; 170 /// Method name 171 std::string m_methodName; 172 }; 173 174 } 175