diff --git a/Changelog.md b/Changelog.md index 3603d3151..7b64f950d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,6 +14,7 @@ Bugfixes: * Compiler interface: Fix a bug where source indexes could be inconsistent between Solidity compiled with different compilers (clang vs. gcc) or compiler settings. The bug was visible in AST and source mappings. + * Gas Estimator: Reflect the most recent fee schedule. * Type system: Contract inheriting from base with unimplemented constructor should be abstract. ### 0.4.10 (2017-03-15) diff --git a/appveyor.yml b/appveyor.yml index 8d9424f0e..22ec30a0d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -69,12 +69,8 @@ build_script: test_script: - cd %APPVEYOR_BUILD_FOLDER% - - cd deps\install\x64\eth - - ps: $ethProc = Start-Process eth.exe --test - - ps: Start-Sleep -s 100 - cd %APPVEYOR_BUILD_FOLDER%\build\test\%CONFIGURATION% - - copy "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\x86\Microsoft.VC140.CRT\msvc*.dll" . - - soltest.exe --show-progress -- --ipcpath \\.\pipe\geth.ipc + - soltest.exe --show-progress -- --no-ipc artifacts: - path: solidity-windows.zip diff --git a/libevmasm/EVMSchedule.h b/libevmasm/EVMSchedule.h index ce9003bdd..65d307ae9 100644 --- a/libevmasm/EVMSchedule.h +++ b/libevmasm/EVMSchedule.h @@ -34,7 +34,7 @@ struct EVMSchedule unsigned expByteGas = 10; unsigned sha3Gas = 30; unsigned sha3WordGas = 6; - unsigned sloadGas = 50; + unsigned sloadGas = 200; unsigned sstoreSetGas = 20000; unsigned sstoreResetGas = 5000; unsigned sstoreRefundGas = 15000; diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index a0adc35d5..f5fd00eab 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -149,6 +149,10 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ } break; } + case Instruction::SELFDESTRUCT: + gas = GasCosts::selfdestructGas; + gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists. + break; case Instruction::CREATE: if (_includeExternalCosts) // We assume that we do not know the target contract and thus, the consumption is infinite. @@ -232,6 +236,8 @@ unsigned GasMeter::runGas(Instruction _instruction) case Tier::High: return GasCosts::tier5Gas; case Tier::Ext: return GasCosts::tier6Gas; case Tier::Special: return GasCosts::tier7Gas; + case Tier::ExtCode: return GasCosts::extCodeGas; + case Tier::Balance: return GasCosts::balanceGas; default: break; } assertThrow(false, OptimizerException, "Invalid gas tier."); diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index 8ade838a2..3169ff2a8 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -44,11 +44,13 @@ namespace GasCosts static unsigned const tier5Gas = 10; static unsigned const tier6Gas = 20; static unsigned const tier7Gas = 0; + static unsigned const extCodeGas = 700; + static unsigned const balanceGas = 400; static unsigned const expGas = 10; - static unsigned const expByteGas = 10; + static unsigned const expByteGas = 50; static unsigned const sha3Gas = 30; static unsigned const sha3WordGas = 6; - static unsigned const sloadGas = 50; + static unsigned const sloadGas = 200; static unsigned const sstoreSetGas = 20000; static unsigned const sstoreResetGas = 5000; static unsigned const sstoreRefundGas = 15000; @@ -57,10 +59,11 @@ namespace GasCosts static unsigned const logDataGas = 8; static unsigned const logTopicGas = 375; static unsigned const createGas = 32000; - static unsigned const callGas = 40; + static unsigned const callGas = 700; static unsigned const callStipend = 2300; static unsigned const callValueTransferGas = 9000; static unsigned const callNewAccountGas = 25000; + static unsigned const selfdestructGas = 5000; static unsigned const selfdestructRefundGas = 24000; static unsigned const memoryGas = 3; static unsigned const quadCoeffDiv = 512; diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index de6630f30..5e92c6e66 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -191,7 +191,7 @@ static const std::map c_instructionInfo = { Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false, Tier::Low } }, { Instruction::SHA3, { "SHA3", 0, 2, 1, false, Tier::Special } }, { Instruction::ADDRESS, { "ADDRESS", 0, 0, 1, false, Tier::Base } }, - { Instruction::BALANCE, { "BALANCE", 0, 1, 1, false, Tier::Ext } }, + { Instruction::BALANCE, { "BALANCE", 0, 1, 1, false, Tier::Balance } }, { Instruction::ORIGIN, { "ORIGIN", 0, 0, 1, false, Tier::Base } }, { Instruction::CALLER, { "CALLER", 0, 0, 1, false, Tier::Base } }, { Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1, false, Tier::Base } }, @@ -201,8 +201,8 @@ static const std::map c_instructionInfo = { Instruction::CODESIZE, { "CODESIZE", 0, 0, 1, false, Tier::Base } }, { Instruction::CODECOPY, { "CODECOPY", 0, 3, 0, true, Tier::VeryLow } }, { Instruction::GASPRICE, { "GASPRICE", 0, 0, 1, false, Tier::Base } }, - { Instruction::EXTCODESIZE, { "EXTCODESIZE", 0, 1, 1, false, Tier::Ext } }, - { Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::Ext } }, + { Instruction::EXTCODESIZE, { "EXTCODESIZE", 0, 1, 1, false, Tier::ExtCode } }, + { Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::ExtCode } }, { Instruction::BLOCKHASH, { "BLOCKHASH", 0, 1, 1, false, Tier::Ext } }, { Instruction::COINBASE, { "COINBASE", 0, 0, 1, false, Tier::Base } }, { Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1, false, Tier::Base } }, @@ -297,7 +297,7 @@ static const std::map c_instructionInfo = { Instruction::DELEGATECALL, { "DELEGATECALL", 0, 6, 1, true, Tier::Special } }, { Instruction::REVERT, { "REVERT", 0, 2, 0, true, Tier::Zero } }, { Instruction::INVALID, { "INVALID", 0, 0, 0, true, Tier::Zero } }, - { Instruction::SELFDESTRUCT, { "SELFDESTRUCT", 0, 1, 0, true, Tier::Zero } } + { Instruction::SELFDESTRUCT, { "SELFDESTRUCT", 0, 1, 0, true, Tier::Special } } }; void dev::solidity::eachInstruction( diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index d79ec969e..192fe0903 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -237,6 +237,8 @@ enum class Tier : unsigned Mid, // 8, Mid High, // 10, Slow Ext, // 20, Ext + ExtCode, // 700, Extcode + Balance, // 400, Balance Special, // multiparam or otherwise special Invalid // Invalid. }; diff --git a/scripts/install_deps.bat b/scripts/install_deps.bat index bd68b07af..512a28dfa 100644 --- a/scripts/install_deps.bat +++ b/scripts/install_deps.bat @@ -59,4 +59,3 @@ REM Copyright (c) 2016 solidity contributors. REM --------------------------------------------------------------------------- cmake -P deps\install_deps.cmake -cmake -P scripts\install_eth.cmake diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh index 81cde14cc..24cf49d5d 100755 --- a/scripts/install_deps.sh +++ b/scripts/install_deps.sh @@ -314,12 +314,12 @@ case $(uname -s) in libboost-all-dev if [ "$CI" = true ]; then # Install 'eth', for use in the Solidity Tests-over-IPC. + # We will not use this 'eth', but its dependencies sudo add-apt-repository -y ppa:ethereum/ethereum sudo add-apt-repository -y ppa:ethereum/ethereum-dev sudo apt-get -y update sudo apt-get -y install eth fi - ;; #------------------------------------------------------------------------------ diff --git a/scripts/install_eth.cmake b/scripts/install_eth.cmake deleted file mode 100644 index 25f449e02..000000000 --- a/scripts/install_eth.cmake +++ /dev/null @@ -1,76 +0,0 @@ -#------------------------------------------------------------------------------ -# Cmake script for installing pre-requisite package eth for solidity. -# -# The aim of this script is to simply download and unpack eth binaries to the deps folder. -# -# The documentation for solidity is hosted at: -# -# http://solidity.readthedocs.io/ -# -# ------------------------------------------------------------------------------ -# This file is part of solidity. -# -# solidity is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# solidity is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with solidity. If not, see -# -# (c) 2016 solidity contributors. -#------------------------------------------------------------------------------ - -function(download URL DST_FILE STATUS) - set(TMP_FILE "${DST_FILE}.part") - - get_filename_component(FILE_NAME ${DST_FILE} NAME) - if (NOT EXISTS ${DST_FILE}) - message("Downloading ${FILE_NAME}") - file(DOWNLOAD ${URL} ${TMP_FILE} SHOW_PROGRESS STATUS DOWNLOAD_STATUS) - list(GET DOWNLOAD_STATUS 0 STATUS_CODE) - if (STATUS_CODE EQUAL 0) - file(RENAME ${TMP_FILE} ${DST_FILE}) - else() - file(REMOVE ${TMP_FILE}) - list(GET DOWNLOAD_STATUS 1 ERROR_MSG) - - message("ERROR! Downloading '${FILE_NAME}' failed.") - message(STATUS "URL: ${URL}") - message(STATUS "Error: ${STATUS_CODE} ${ERROR_MSG}") - set(STATUS FALSE PARENT_SCOPE) - return() - endif() - else() - message("Using cached ${FILE_NAME}") - endif() - set(STATUS TRUE PARENT_SCOPE) -endfunction(download) - -function(download_and_unpack PACKAGE_URL DST_DIR) - get_filename_component(FILE_NAME ${PACKAGE_URL} NAME) - - set(DST_FILE "${CACHE_DIR}/${FILE_NAME}") - set(TMP_FILE "${DST_FILE}.part") - - file(MAKE_DIRECTORY ${CACHE_DIR}) - file(MAKE_DIRECTORY ${DST_DIR}) - - download(${PACKAGE_URL} ${DST_FILE} STATUS) - - if (STATUS) - message("Unpacking ${FILE_NAME} to ${DST_DIR}") - execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${DST_FILE} - WORKING_DIRECTORY ${DST_DIR}) - endif() -endfunction(download_and_unpack) - -get_filename_component(ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) -set(CACHE_DIR "${ROOT_DIR}/deps/cache") -set(INSTALL_DIR "${ROOT_DIR}/deps/install/x64/eth") -download_and_unpack("https://github.com/bobsummerwill/cpp-ethereum/releases/download/develop-v1.3.0.401/cpp-ethereum-develop-windows.zip" ${INSTALL_DIR}) diff --git a/scripts/tests.sh b/scripts/tests.sh index d47edd28d..6b76c1545 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -42,8 +42,16 @@ test "${output//[[:blank:]]/}" = "3" # instead. This will go away soon. if [[ "$OSTYPE" == "darwin"* ]]; then ETH_PATH="$REPO_ROOT/eth" -else +elif [ -z $CI ]; then ETH_PATH="eth" +else + mkdir -p /tmp/test + wget -O /tmp/test/eth https://github.com/ethereum/cpp-ethereum/releases/download/solidityTester/eth + test "$(shasum /tmp/test/eth)" = "c132e8989229e4840831a4fb1a1d058b732a11d5 /tmp/test/eth" + sync + chmod +x /tmp/test/eth + sync # Otherwise we might get a "text file busy" error + ETH_PATH="/tmp/test/eth" fi # This trailing ampersand directs the shell to run the command in the background, diff --git a/test/RPCSession.cpp b/test/RPCSession.cpp index f8b364d1a..3ea3b1fe9 100644 --- a/test/RPCSession.cpp +++ b/test/RPCSession.cpp @@ -220,7 +220,10 @@ void RPCSession::test_setChainParams(vector const& _accounts) "accountStartNonce": "0x", "maximumExtraDataSize": "0x1000000", "blockReward": "0x", - "allowFutureBlocks": "1" + "allowFutureBlocks": "1", + "homsteadForkBlock": "0x00", + "EIP150ForkBlock": "0x00", + "EIP158ForkBlock": "0x00" }, "genesis": { "author": "0000000000000010000000000000000000000000", diff --git a/test/RPCSession.h b/test/RPCSession.h index b37cc3228..f3c3339a6 100644 --- a/test/RPCSession.h +++ b/test/RPCSession.h @@ -68,7 +68,7 @@ private: int m_socket; /// Socket read timeout in milliseconds. Needs to be large because the key generation routine /// might take long. - unsigned static constexpr m_readTimeOutMS = 15000; + unsigned static constexpr m_readTimeOutMS = 300000; char m_readBuf[512000]; }; #endif @@ -133,7 +133,7 @@ private: IPCSocket m_ipcSocket; size_t m_rpcSequence = 1; - unsigned m_maxMiningTime = 15000; // 15 seconds + unsigned m_maxMiningTime = 6000000; // 600 seconds unsigned m_sleepTime = 10; // 10 milliseconds unsigned m_successfulMineRuns = 0; diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 0c0857c91..094b59c60 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -43,8 +43,10 @@ Options::Options() optimize = true; else if (string(suite.argv[i]) == "--show-messages") showMessages = true; + else if (string(suite.argv[i]) == "--no-ipc") + disableIPC = true; - if (ipcPath.empty()) + if (!disableIPC && ipcPath.empty()) if (auto path = getenv("ETH_TEST_IPC")) ipcPath = path; } diff --git a/test/TestHelper.h b/test/TestHelper.h index 8f05eead6..3e74b54c5 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -108,6 +108,7 @@ struct Options: boost::noncopyable std::string ipcPath; bool showMessages = false; bool optimize = false; + bool disableIPC = false; static Options const& get(); diff --git a/test/boostTest.cpp b/test/boostTest.cpp index d1d35be3e..6fc1c925e 100644 --- a/test/boostTest.cpp +++ b/test/boostTest.cpp @@ -21,11 +21,9 @@ * Original code taken from boost sources. */ -#define BOOST_TEST_MODULE EthereumTests #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" - #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4535) // calling _set_se_translator requires /EHa @@ -36,3 +34,32 @@ #endif #pragma GCC diagnostic pop + +#include + +using namespace boost::unit_test; + +test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) +{ + master_test_suite_t& master = framework::master_test_suite(); + master.p_name.value = "SolidityTests"; + if (dev::test::Options::get().disableIPC) + { + for (auto suite: { + "SolidityAuctionRegistrar", + "SolidityFixedFeeRegistrar", + "SolidityWallet", + "LLLEndToEndTest", + "GasMeterTests", + "SolidityEndToEndTest", + "SolidityOptimizer" + }) + { + auto id = master.get(suite); + assert(id != INV_TEST_UNIT_ID); + master.remove(id); + } + } + + return 0; +} diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp index 0671fb150..f90cb1058 100644 --- a/test/libsolidity/GasMeter.cpp +++ b/test/libsolidity/GasMeter.cpp @@ -248,6 +248,51 @@ BOOST_AUTO_TEST_CASE(multiple_external_functions) testRunTimeGas("g(uint256)", vector{encodeArgs(2)}); } +BOOST_AUTO_TEST_CASE(exponent_size) +{ + char const* sourceCode = R"( + contract A { + function g(uint x) returns (uint) { + return x ** 0x100; + } + function h(uint x) returns (uint) { + return x ** 0x10000; + } + } + )"; + testCreationTimeGas(sourceCode); + testRunTimeGas("g(uint256)", vector{encodeArgs(2)}); + testRunTimeGas("h(uint256)", vector{encodeArgs(2)}); +} + +BOOST_AUTO_TEST_CASE(balance_gas) +{ + char const* sourceCode = R"( + contract A { + function lookup_balance(address a) returns (uint) { + return a.balance; + } + } + )"; + testCreationTimeGas(sourceCode); + testRunTimeGas("lookup_balance(address)", vector{encodeArgs(2), encodeArgs(100)}); +} + +BOOST_AUTO_TEST_CASE(extcodesize_gas) +{ + char const* sourceCode = R"( + contract A { + function f() returns (uint _s) { + assembly { + _s := extcodesize(0x30) + } + } + } + )"; + testCreationTimeGas(sourceCode); + testRunTimeGas("f()", vector{encodeArgs()}); +} + BOOST_AUTO_TEST_SUITE_END() }