mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move gas cost tests from command line tests to interactive gas cost tests.
This commit is contained in:
parent
6c9c54a657
commit
0a99519142
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <test/TestCase.h>
|
#include <test/TestCase.h>
|
||||||
#include <test/libsolidity/ASTJSONTest.h>
|
#include <test/libsolidity/ASTJSONTest.h>
|
||||||
|
#include <test/libsolidity/GasTest.h>
|
||||||
#include <test/libsolidity/SyntaxTest.h>
|
#include <test/libsolidity/SyntaxTest.h>
|
||||||
#include <test/libsolidity/SemanticTest.h>
|
#include <test/libsolidity/SemanticTest.h>
|
||||||
#include <test/libsolidity/SMTCheckerJSONTest.h>
|
#include <test/libsolidity/SMTCheckerJSONTest.h>
|
||||||
@ -58,7 +59,8 @@ Testsuite const g_interactiveTestsuites[] = {
|
|||||||
{"Semantic", "libsolidity", "semanticTests", false, true, &SemanticTest::create},
|
{"Semantic", "libsolidity", "semanticTests", false, true, &SemanticTest::create},
|
||||||
{"JSON AST", "libsolidity", "ASTJSON", false, false, &ASTJSONTest::create},
|
{"JSON AST", "libsolidity", "ASTJSON", false, false, &ASTJSONTest::create},
|
||||||
{"SMT Checker", "libsolidity", "smtCheckerTests", true, false, &SyntaxTest::create},
|
{"SMT Checker", "libsolidity", "smtCheckerTests", true, false, &SyntaxTest::create},
|
||||||
{"SMT Checker JSON", "libsolidity", "smtCheckerTestsJSON", true, false, &SMTCheckerTest::create}
|
{"SMT Checker JSON", "libsolidity", "smtCheckerTestsJSON", true, false, &SMTCheckerTest::create},
|
||||||
|
{"Gas Estimates", "libsolidity", "gasTests", false, false, &GasTest::create}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
--gas
|
|
@ -1,15 +0,0 @@
|
|||||||
pragma solidity >=0.0;
|
|
||||||
|
|
||||||
contract C {
|
|
||||||
function f() pure public {
|
|
||||||
require(false, "1234567890123456789012345678901");
|
|
||||||
require(false, "12345678901234567890123456789012");
|
|
||||||
require(false, "123456789012345678901234567890123");
|
|
||||||
require(false, "1234567890123456789012345678901234");
|
|
||||||
require(false, "12345678901234567890123456789012345");
|
|
||||||
require(false, "123456789012345678901234567890123456");
|
|
||||||
require(false, "123456789012345678901234567890121234567890123456789012345678901");
|
|
||||||
require(false, "1234567890123456789012345678901212345678901234567890123456789012");
|
|
||||||
require(false, "12345678901234567890123456789012123456789012345678901234567890123");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
|
|
||||||
======= data_storage/input.sol:C =======
|
|
||||||
Gas estimation:
|
|
||||||
construction:
|
|
||||||
294 + 255000 = 255294
|
|
||||||
external:
|
|
||||||
f(): 252
|
|
@ -1 +0,0 @@
|
|||||||
--gas
|
|
@ -1,3 +0,0 @@
|
|||||||
gas_test_abiv2/input.sol:2:1: Warning: Experimental features are turned on. Do not use experimental features on live deployments.
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
^-------------------------------^
|
|
@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
======= gas_test_abiv2/input.sol:C =======
|
|
||||||
Gas estimation:
|
|
||||||
construction:
|
|
||||||
1160 + 1119000 = 1120160
|
|
||||||
external:
|
|
||||||
a(): 530
|
|
||||||
b(uint256): infinite
|
|
||||||
f1(uint256): infinite
|
|
||||||
f2(uint256[],string[],uint16,address): infinite
|
|
||||||
f3(uint16[],string[],uint16,address): infinite
|
|
||||||
f4(uint32[],string[12],bytes[2][],address): infinite
|
|
||||||
f5(address[],string[],bytes,address): infinite
|
|
||||||
f6(uint256[30],string[],uint16,address): infinite
|
|
||||||
f7(uint256[31],string[20],address,address): infinite
|
|
||||||
f8(uint256[32],string[],uint32,address): infinite
|
|
@ -1 +0,0 @@
|
|||||||
--gas --optimize --optimize-yul
|
|
@ -1,4 +0,0 @@
|
|||||||
Warning: The Yul optimiser is still experimental. Do not use it in production unless correctness of generated code is verified with extensive tests.
|
|
||||||
gas_test_abiv2_optimize_yul/input.sol:2:1: Warning: Experimental features are turned on. Do not use experimental features on live deployments.
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
^-------------------------------^
|
|
@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
======= gas_test_abiv2_optimize_yul/input.sol:C =======
|
|
||||||
Gas estimation:
|
|
||||||
construction:
|
|
||||||
645 + 608800 = 609445
|
|
||||||
external:
|
|
||||||
a(): 429
|
|
||||||
b(uint256): 884
|
|
||||||
f1(uint256): 351
|
|
||||||
f2(uint256[],string[],uint16,address): infinite
|
|
||||||
f3(uint16[],string[],uint16,address): infinite
|
|
||||||
f4(uint32[],string[12],bytes[2][],address): infinite
|
|
||||||
f5(address[],string[],bytes,address): infinite
|
|
||||||
f6(uint256[30],string[],uint16,address): infinite
|
|
||||||
f7(uint256[31],string[20],address,address): infinite
|
|
||||||
f8(uint256[32],string[],uint32,address): infinite
|
|
@ -1 +0,0 @@
|
|||||||
--gas
|
|
@ -1,53 +0,0 @@
|
|||||||
|
|
||||||
======= gas_test_dispatch/input.sol:Large =======
|
|
||||||
Gas estimation:
|
|
||||||
construction:
|
|
||||||
670 + 635000 = 635670
|
|
||||||
external:
|
|
||||||
a(): 451
|
|
||||||
b(uint256): 846
|
|
||||||
f0(uint256): 427
|
|
||||||
f1(uint256): 40752
|
|
||||||
f2(uint256): 20693
|
|
||||||
f3(uint256): 20781
|
|
||||||
f4(uint256): 20759
|
|
||||||
f5(uint256): 20737
|
|
||||||
f6(uint256): 20760
|
|
||||||
f7(uint256): 20672
|
|
||||||
f8(uint256): 20672
|
|
||||||
f9(uint256): 20694
|
|
||||||
g0(uint256): 313
|
|
||||||
g1(uint256): 40707
|
|
||||||
g2(uint256): 20670
|
|
||||||
g3(uint256): 20758
|
|
||||||
g4(uint256): 20736
|
|
||||||
g5(uint256): 20692
|
|
||||||
g6(uint256): 20715
|
|
||||||
g7(uint256): 20714
|
|
||||||
g8(uint256): 20692
|
|
||||||
g9(uint256): 20649
|
|
||||||
|
|
||||||
======= gas_test_dispatch/input.sol:Medium =======
|
|
||||||
Gas estimation:
|
|
||||||
construction:
|
|
||||||
294 + 251200 = 251494
|
|
||||||
external:
|
|
||||||
a(): 428
|
|
||||||
b(uint256): 846
|
|
||||||
f1(uint256): 40663
|
|
||||||
f2(uint256): 20693
|
|
||||||
f3(uint256): 20737
|
|
||||||
g0(uint256): 313
|
|
||||||
g7(uint256): 20692
|
|
||||||
g8(uint256): 20670
|
|
||||||
g9(uint256): 20626
|
|
||||||
|
|
||||||
======= gas_test_dispatch/input.sol:Small =======
|
|
||||||
Gas estimation:
|
|
||||||
construction:
|
|
||||||
129 + 81800 = 81929
|
|
||||||
external:
|
|
||||||
fallback: 118
|
|
||||||
a(): 383
|
|
||||||
b(uint256): 802
|
|
||||||
f1(uint256): 40663
|
|
@ -1 +0,0 @@
|
|||||||
--optimize --optimize-runs 2 --gas
|
|
@ -1,53 +0,0 @@
|
|||||||
|
|
||||||
======= gas_test_dispatch_optimize/input.sol:Large =======
|
|
||||||
Gas estimation:
|
|
||||||
construction:
|
|
||||||
300 + 260000 = 260300
|
|
||||||
external:
|
|
||||||
a(): 398
|
|
||||||
b(uint256): 1105
|
|
||||||
f0(uint256): 334
|
|
||||||
f1(uint256): 40886
|
|
||||||
f2(uint256): 20952
|
|
||||||
f3(uint256): 21040
|
|
||||||
f4(uint256): 21018
|
|
||||||
f5(uint256): 20996
|
|
||||||
f6(uint256): 20908
|
|
||||||
f7(uint256): 20688
|
|
||||||
f8(uint256): 20820
|
|
||||||
f9(uint256): 20842
|
|
||||||
g0(uint256): 574
|
|
||||||
g1(uint256): 40598
|
|
||||||
g2(uint256): 20686
|
|
||||||
g3(uint256): 20774
|
|
||||||
g4(uint256): 20752
|
|
||||||
g5(uint256): 20840
|
|
||||||
g6(uint256): 20620
|
|
||||||
g7(uint256): 20730
|
|
||||||
g8(uint256): 20708
|
|
||||||
g9(uint256): 20554
|
|
||||||
|
|
||||||
======= gas_test_dispatch_optimize/input.sol:Medium =======
|
|
||||||
Gas estimation:
|
|
||||||
construction:
|
|
||||||
183 + 140400 = 140583
|
|
||||||
external:
|
|
||||||
a(): 398
|
|
||||||
b(uint256): 863
|
|
||||||
f1(uint256): 40666
|
|
||||||
f2(uint256): 20710
|
|
||||||
f3(uint256): 20754
|
|
||||||
g0(uint256): 332
|
|
||||||
g7(uint256): 20620
|
|
||||||
g8(uint256): 20598
|
|
||||||
g9(uint256): 20554
|
|
||||||
|
|
||||||
======= gas_test_dispatch_optimize/input.sol:Small =======
|
|
||||||
Gas estimation:
|
|
||||||
construction:
|
|
||||||
111 + 63600 = 63711
|
|
||||||
external:
|
|
||||||
fallback: 118
|
|
||||||
a(): 376
|
|
||||||
b(uint256): 753
|
|
||||||
f1(uint256): 40600
|
|
238
test/libsolidity/GasTest.cpp
Normal file
238
test/libsolidity/GasTest.cpp
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <test/libsolidity/GasTest.h>
|
||||||
|
#include <test/Options.h>
|
||||||
|
#include <libdevcore/CommonIO.h>
|
||||||
|
#include <libdevcore/JSON.h>
|
||||||
|
#include <liblangutil/SourceReferenceFormatterHuman.h>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
#include <boost/throw_exception.hpp>
|
||||||
|
#include <fstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
using namespace langutil;
|
||||||
|
using namespace dev::solidity;
|
||||||
|
using namespace dev::solidity::test;
|
||||||
|
using namespace dev;
|
||||||
|
using namespace std;
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
using namespace boost::unit_test;
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
u256 parseGasCost(string::iterator& _it, string::iterator _end)
|
||||||
|
{
|
||||||
|
if (_it == _end || !isdigit(*_it))
|
||||||
|
throw runtime_error("Invalid test expectation: expected gas cost.");
|
||||||
|
auto begin = _it;
|
||||||
|
while (_it != _end && isdigit(*_it))
|
||||||
|
++_it;
|
||||||
|
return u256(std::string(begin, _it));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GasTest::GasTest(string const& _filename)
|
||||||
|
{
|
||||||
|
ifstream file(_filename);
|
||||||
|
if (!file)
|
||||||
|
BOOST_THROW_EXCEPTION(runtime_error("Cannot open test contract: \"" + _filename + "\"."));
|
||||||
|
file.exceptions(ios::badbit);
|
||||||
|
|
||||||
|
m_source = parseSourceAndSettings(file);
|
||||||
|
|
||||||
|
if (m_settings.count("optimize"))
|
||||||
|
{
|
||||||
|
m_optimise = true;
|
||||||
|
m_validatedSettings["optimize"] = "true";
|
||||||
|
m_settings.erase("optimize");
|
||||||
|
}
|
||||||
|
if (m_settings.count("optimize-yul"))
|
||||||
|
{
|
||||||
|
m_optimiseYul = true;
|
||||||
|
m_validatedSettings["optimize-yul"] = "true";
|
||||||
|
m_settings.erase("optimize-yul");
|
||||||
|
}
|
||||||
|
if (m_settings.count("optimize-runs"))
|
||||||
|
{
|
||||||
|
m_optimiseRuns = stoul(m_settings["optimize-runs"]);
|
||||||
|
m_validatedSettings["optimize-runs"] = m_settings["optimize-runs"];
|
||||||
|
m_settings.erase("optimize-runs");
|
||||||
|
}
|
||||||
|
|
||||||
|
parseExpectations(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasTest::parseExpectations(std::istream& _stream)
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string>* currentKind = nullptr;
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
while (getline(_stream, line))
|
||||||
|
if (boost::starts_with(line, "// creation:"))
|
||||||
|
{
|
||||||
|
auto it = line.begin() + 12;
|
||||||
|
skipWhitespace(it, line.end());
|
||||||
|
m_creationCost.executionCost = parseGasCost(it, line.end());
|
||||||
|
skipWhitespace(it, line.end());
|
||||||
|
if (*it++ != '+')
|
||||||
|
BOOST_THROW_EXCEPTION(runtime_error("Invalid expectation: expected \"+\"-"));
|
||||||
|
skipWhitespace(it, line.end());
|
||||||
|
m_creationCost.codeDepositCost = parseGasCost(it, line.end());
|
||||||
|
skipWhitespace(it, line.end());
|
||||||
|
if (*it++ != '=')
|
||||||
|
BOOST_THROW_EXCEPTION(runtime_error("Invalid expectation: expected \"+\"-"));
|
||||||
|
skipWhitespace(it, line.end());
|
||||||
|
m_creationCost.totalCost = parseGasCost(it, line.end());
|
||||||
|
}
|
||||||
|
else if (line == "// external:")
|
||||||
|
currentKind = &m_externalFunctionCosts;
|
||||||
|
else if (line == "// internal:")
|
||||||
|
currentKind = &m_internalFunctionCosts;
|
||||||
|
else if (!currentKind)
|
||||||
|
BOOST_THROW_EXCEPTION(runtime_error("No function kind specified. Expected \"external:\" or \"internal:\"."));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!boost::starts_with(line, "// "))
|
||||||
|
BOOST_THROW_EXCEPTION(runtime_error("Invalid expectation: expected \"// \"."));
|
||||||
|
auto it = line.begin() + 3;
|
||||||
|
skipWhitespace(it, line.end());
|
||||||
|
auto functionNameBegin = it;
|
||||||
|
while (it != line.end() && *it != ':')
|
||||||
|
++it;
|
||||||
|
std::string functionName(functionNameBegin, it);
|
||||||
|
if (functionName == "fallback")
|
||||||
|
functionName.clear();
|
||||||
|
expect(it, line.end(), ':');
|
||||||
|
skipWhitespace(it, line.end());
|
||||||
|
if (it == line.end())
|
||||||
|
BOOST_THROW_EXCEPTION(runtime_error("Invalid expectation: expected gas cost."));
|
||||||
|
(*currentKind)[functionName] = std::string(it, line.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasTest::printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const
|
||||||
|
{
|
||||||
|
Json::Value estimates = compiler().gasEstimates(compiler().lastContractName());
|
||||||
|
_stream << _linePrefix
|
||||||
|
<< "creation: "
|
||||||
|
<< estimates["creation"]["executionCost"].asString()
|
||||||
|
<< " + "
|
||||||
|
<< estimates["creation"]["codeDepositCost"].asString()
|
||||||
|
<< " = "
|
||||||
|
<< estimates["creation"]["totalCost"].asString()
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
for (auto kind: {"external", "internal"})
|
||||||
|
if (estimates[kind])
|
||||||
|
{
|
||||||
|
_stream << _linePrefix << kind << ":" << std::endl;
|
||||||
|
for (auto it = estimates[kind].begin(); it != estimates[kind].end(); ++it)
|
||||||
|
{
|
||||||
|
_stream << _linePrefix << " ";
|
||||||
|
if (it.key().asString().empty())
|
||||||
|
_stream << "fallback";
|
||||||
|
else
|
||||||
|
_stream << it.key().asString();
|
||||||
|
_stream << ": " << it->asString() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GasTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
|
||||||
|
{
|
||||||
|
string const versionPragma = "pragma solidity >=0.0;\n";
|
||||||
|
compiler().reset();
|
||||||
|
OptimiserSettings settings = m_optimise ? OptimiserSettings::standard() : OptimiserSettings::minimal();
|
||||||
|
if (m_optimiseYul)
|
||||||
|
{
|
||||||
|
settings.runYulOptimiser = m_optimise;
|
||||||
|
settings.optimizeStackAllocation = m_optimise;
|
||||||
|
}
|
||||||
|
settings.expectedExecutionsPerDeployment = m_optimiseRuns;
|
||||||
|
compiler().setOptimiserSettings(settings);
|
||||||
|
compiler().setSources({{"", versionPragma + m_source}});
|
||||||
|
|
||||||
|
if (!compiler().parseAndAnalyze() || !compiler().compile())
|
||||||
|
{
|
||||||
|
SourceReferenceFormatterHuman formatter(cerr, _formatted);
|
||||||
|
for (auto const& error: compiler().errors())
|
||||||
|
formatter.printErrorInformation(*error);
|
||||||
|
BOOST_THROW_EXCEPTION(runtime_error("Test contract does not compile."));
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value estimates = compiler().gasEstimates(compiler().lastContractName());
|
||||||
|
|
||||||
|
|
||||||
|
auto creation = estimates["creation"];
|
||||||
|
bool success =
|
||||||
|
(creation["codeDepositCost"].asString() == toString(m_creationCost.codeDepositCost)) &&
|
||||||
|
(creation["executionCost"].asString() == toString(m_creationCost.executionCost)) &&
|
||||||
|
(creation["totalCost"].asString() == toString(m_creationCost.totalCost));
|
||||||
|
|
||||||
|
auto check = [&](map<string, string> const& _a, Json::Value const& _b) {
|
||||||
|
for (auto& entry: _a)
|
||||||
|
success &= _b[entry.first].asString() == entry.second;
|
||||||
|
};
|
||||||
|
check(m_internalFunctionCosts, estimates["internal"]);
|
||||||
|
check(m_externalFunctionCosts, estimates["external"]);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
_stream << _linePrefix << "Expected:" << std::endl;
|
||||||
|
_stream << _linePrefix
|
||||||
|
<< " creation: "
|
||||||
|
<< toString(m_creationCost.executionCost)
|
||||||
|
<< " + "
|
||||||
|
<< toString(m_creationCost.codeDepositCost)
|
||||||
|
<< " = "
|
||||||
|
<< toString(m_creationCost.totalCost)
|
||||||
|
<< std::endl;
|
||||||
|
auto printExpected = [&](std::string const& _kind, auto const& _expectations)
|
||||||
|
{
|
||||||
|
_stream << _linePrefix << " " << _kind << ":" << std::endl;
|
||||||
|
for (auto const& entry: _expectations)
|
||||||
|
_stream << _linePrefix
|
||||||
|
<< " "
|
||||||
|
<< (entry.first.empty() ? "fallback" : entry.first)
|
||||||
|
<< ": "
|
||||||
|
<< entry.second
|
||||||
|
<< std::endl;
|
||||||
|
};
|
||||||
|
if (!m_externalFunctionCosts.empty())
|
||||||
|
printExpected("external", m_externalFunctionCosts);
|
||||||
|
if (!m_internalFunctionCosts.empty())
|
||||||
|
printExpected("internal", m_internalFunctionCosts);
|
||||||
|
_stream << _linePrefix << "Obtained:" << std::endl;
|
||||||
|
printUpdatedExpectations(_stream, _linePrefix + " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasTest::printSource(ostream& _stream, string const& _linePrefix, bool) const
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::istringstream input(m_source);
|
||||||
|
while (getline(input, line))
|
||||||
|
_stream << _linePrefix << line << std::endl;
|
||||||
|
}
|
69
test/libsolidity/GasTest.h
Normal file
69
test/libsolidity/GasTest.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <test/libsolidity/AnalysisFramework.h>
|
||||||
|
#include <test/TestCase.h>
|
||||||
|
#include <liblangutil/Exceptions.h>
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
namespace solidity
|
||||||
|
{
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
|
||||||
|
class GasTest: AnalysisFramework, public TestCase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::unique_ptr<TestCase> create(Config const& _config)
|
||||||
|
{ return std::make_unique<GasTest>(_config.filename); }
|
||||||
|
GasTest(std::string const& _filename);
|
||||||
|
|
||||||
|
bool run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override;
|
||||||
|
|
||||||
|
void printSource(std::ostream &_stream, std::string const &_linePrefix = "", bool _formatted = false) const override;
|
||||||
|
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void parseExpectations(std::istream& _stream);
|
||||||
|
|
||||||
|
struct CreationCost
|
||||||
|
{
|
||||||
|
u256 executionCost{0};
|
||||||
|
u256 codeDepositCost{0};
|
||||||
|
u256 totalCost{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
bool m_optimise = false;
|
||||||
|
bool m_optimiseYul = false;
|
||||||
|
size_t m_optimiseRuns = 200;
|
||||||
|
std::string m_source;
|
||||||
|
CreationCost m_creationCost;
|
||||||
|
std::map<std::string, std::string> m_externalFunctionCosts;
|
||||||
|
std::map<std::string, std::string> m_internalFunctionCosts;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,3 @@
|
|||||||
pragma solidity >=0.0;
|
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
@ -13,3 +12,16 @@ contract C {
|
|||||||
function f7(uint[31] memory, string[20] memory, C, address) public returns (bytes[] memory, uint16[] memory) {}
|
function f7(uint[31] memory, string[20] memory, C, address) public returns (bytes[] memory, uint16[] memory) {}
|
||||||
function f8(uint[32] memory, string[] memory, uint32, address) public returns (uint[] memory, uint16[] memory) {}
|
function f8(uint[32] memory, string[] memory, uint32, address) public returns (uint[] memory, uint16[] memory) {}
|
||||||
}
|
}
|
||||||
|
// ----
|
||||||
|
// creation: 1160 + 1119000 = 1120160
|
||||||
|
// external:
|
||||||
|
// a(): 530
|
||||||
|
// b(uint256): infinite
|
||||||
|
// f1(uint256): infinite
|
||||||
|
// f2(uint256[],string[],uint16,address): infinite
|
||||||
|
// f3(uint16[],string[],uint16,address): infinite
|
||||||
|
// f4(uint32[],string[12],bytes[2][],address): infinite
|
||||||
|
// f5(address[],string[],bytes,address): infinite
|
||||||
|
// f6(uint256[30],string[],uint16,address): infinite
|
||||||
|
// f7(uint256[31],string[20],address,address): infinite
|
||||||
|
// f8(uint256[32],string[],uint32,address): infinite
|
@ -1,4 +1,3 @@
|
|||||||
pragma solidity >=0.0;
|
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
@ -13,3 +12,19 @@ contract C {
|
|||||||
function f7(uint[31] memory, string[20] memory, C, address) public returns (bytes[] memory, uint16[] memory) {}
|
function f7(uint[31] memory, string[20] memory, C, address) public returns (bytes[] memory, uint16[] memory) {}
|
||||||
function f8(uint[32] memory, string[] memory, uint32, address) public returns (uint[] memory, uint16[] memory) {}
|
function f8(uint[32] memory, string[] memory, uint32, address) public returns (uint[] memory, uint16[] memory) {}
|
||||||
}
|
}
|
||||||
|
// ====
|
||||||
|
// optimize: true
|
||||||
|
// optimize-yul: true
|
||||||
|
// ----
|
||||||
|
// creation: 645 + 608800 = 609445
|
||||||
|
// external:
|
||||||
|
// a(): 429
|
||||||
|
// b(uint256): 884
|
||||||
|
// f1(uint256): 351
|
||||||
|
// f2(uint256[],string[],uint16,address): infinite
|
||||||
|
// f3(uint16[],string[],uint16,address): infinite
|
||||||
|
// f4(uint32[],string[12],bytes[2][],address): infinite
|
||||||
|
// f5(address[],string[],bytes,address): infinite
|
||||||
|
// f6(uint256[30],string[],uint16,address): infinite
|
||||||
|
// f7(uint256[31],string[20],address,address): infinite
|
||||||
|
// f8(uint256[32],string[],uint32,address): infinite
|
17
test/libsolidity/gasTests/data_storage.sol
Normal file
17
test/libsolidity/gasTests/data_storage.sol
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
contract C {
|
||||||
|
function f() pure public {
|
||||||
|
require(false, "1234567890123456789012345678901");
|
||||||
|
require(false, "12345678901234567890123456789012");
|
||||||
|
require(false, "123456789012345678901234567890123");
|
||||||
|
require(false, "1234567890123456789012345678901234");
|
||||||
|
require(false, "12345678901234567890123456789012345");
|
||||||
|
require(false, "123456789012345678901234567890123456");
|
||||||
|
require(false, "123456789012345678901234567890121234567890123456789012345678901");
|
||||||
|
require(false, "1234567890123456789012345678901212345678901234567890123456789012");
|
||||||
|
require(false, "12345678901234567890123456789012123456789012345678901234567890123");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// creation: 294 + 255000 = 255294
|
||||||
|
// external:
|
||||||
|
// f(): 252
|
@ -1,5 +1,3 @@
|
|||||||
pragma solidity >=0.0;
|
|
||||||
|
|
||||||
contract Large {
|
contract Large {
|
||||||
uint public a;
|
uint public a;
|
||||||
uint[] public b;
|
uint[] public b;
|
||||||
@ -24,20 +22,28 @@ contract Large {
|
|||||||
function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }
|
function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }
|
||||||
function g0(uint x) public payable returns (uint) { require(x > 10); }
|
function g0(uint x) public payable returns (uint) { require(x > 10); }
|
||||||
}
|
}
|
||||||
contract Medium {
|
// ----
|
||||||
uint public a;
|
// creation: 670 + 635000 = 635670
|
||||||
uint[] public b;
|
// external:
|
||||||
function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }
|
// a(): 451
|
||||||
function f2(uint x) public returns (uint) { b[uint8(msg.data[1])] = x; }
|
// b(uint256): 846
|
||||||
function f3(uint x) public returns (uint) { b[uint8(msg.data[2])] = x; }
|
// f0(uint256): 427
|
||||||
function g7(uint x) public payable returns (uint) { b[uint8(msg.data[6])] = x; }
|
// f1(uint256): 40752
|
||||||
function g8(uint x) public payable returns (uint) { b[uint8(msg.data[7])] = x; }
|
// f2(uint256): 20693
|
||||||
function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }
|
// f3(uint256): 20781
|
||||||
function g0(uint x) public payable returns (uint) { require(x > 10); }
|
// f4(uint256): 20759
|
||||||
}
|
// f5(uint256): 20737
|
||||||
contract Small {
|
// f6(uint256): 20760
|
||||||
uint public a;
|
// f7(uint256): 20672
|
||||||
uint[] public b;
|
// f8(uint256): 20672
|
||||||
function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }
|
// f9(uint256): 20694
|
||||||
function () external payable {}
|
// g0(uint256): 313
|
||||||
}
|
// g1(uint256): 40707
|
||||||
|
// g2(uint256): 20670
|
||||||
|
// g3(uint256): 20758
|
||||||
|
// g4(uint256): 20736
|
||||||
|
// g5(uint256): 20692
|
||||||
|
// g6(uint256): 20715
|
||||||
|
// g7(uint256): 20714
|
||||||
|
// g8(uint256): 20692
|
||||||
|
// g9(uint256): 20649
|
@ -1,5 +1,3 @@
|
|||||||
pragma solidity >=0.0;
|
|
||||||
|
|
||||||
contract Large {
|
contract Large {
|
||||||
uint public a;
|
uint public a;
|
||||||
uint[] public b;
|
uint[] public b;
|
||||||
@ -24,20 +22,31 @@ contract Large {
|
|||||||
function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }
|
function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }
|
||||||
function g0(uint x) public payable returns (uint) { require(x > 10); }
|
function g0(uint x) public payable returns (uint) { require(x > 10); }
|
||||||
}
|
}
|
||||||
contract Medium {
|
// ====
|
||||||
uint public a;
|
// optimize: true
|
||||||
uint[] public b;
|
// optimize-runs: 2
|
||||||
function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }
|
// ----
|
||||||
function f2(uint x) public returns (uint) { b[uint8(msg.data[1])] = x; }
|
// creation: 300 + 260000 = 260300
|
||||||
function f3(uint x) public returns (uint) { b[uint8(msg.data[2])] = x; }
|
// external:
|
||||||
function g7(uint x) public payable returns (uint) { b[uint8(msg.data[6])] = x; }
|
// a(): 398
|
||||||
function g8(uint x) public payable returns (uint) { b[uint8(msg.data[7])] = x; }
|
// b(uint256): 1105
|
||||||
function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }
|
// f0(uint256): 334
|
||||||
function g0(uint x) public payable returns (uint) { require(x > 10); }
|
// f1(uint256): 40886
|
||||||
}
|
// f2(uint256): 20952
|
||||||
contract Small {
|
// f3(uint256): 21040
|
||||||
uint public a;
|
// f4(uint256): 21018
|
||||||
uint[] public b;
|
// f5(uint256): 20996
|
||||||
function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }
|
// f6(uint256): 20908
|
||||||
function () external payable {}
|
// f7(uint256): 20688
|
||||||
}
|
// f8(uint256): 20820
|
||||||
|
// f9(uint256): 20842
|
||||||
|
// g0(uint256): 574
|
||||||
|
// g1(uint256): 40598
|
||||||
|
// g2(uint256): 20686
|
||||||
|
// g3(uint256): 20774
|
||||||
|
// g4(uint256): 20752
|
||||||
|
// g5(uint256): 20840
|
||||||
|
// g6(uint256): 20620
|
||||||
|
// g7(uint256): 20730
|
||||||
|
// g8(uint256): 20708
|
||||||
|
// g9(uint256): 20554
|
23
test/libsolidity/gasTests/dispatch_medium.sol
Normal file
23
test/libsolidity/gasTests/dispatch_medium.sol
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
contract Medium {
|
||||||
|
uint public a;
|
||||||
|
uint[] public b;
|
||||||
|
function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }
|
||||||
|
function f2(uint x) public returns (uint) { b[uint8(msg.data[1])] = x; }
|
||||||
|
function f3(uint x) public returns (uint) { b[uint8(msg.data[2])] = x; }
|
||||||
|
function g7(uint x) public payable returns (uint) { b[uint8(msg.data[6])] = x; }
|
||||||
|
function g8(uint x) public payable returns (uint) { b[uint8(msg.data[7])] = x; }
|
||||||
|
function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }
|
||||||
|
function g0(uint x) public payable returns (uint) { require(x > 10); }
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// creation: 294 + 251200 = 251494
|
||||||
|
// external:
|
||||||
|
// a(): 428
|
||||||
|
// b(uint256): 846
|
||||||
|
// f1(uint256): 40663
|
||||||
|
// f2(uint256): 20693
|
||||||
|
// f3(uint256): 20737
|
||||||
|
// g0(uint256): 313
|
||||||
|
// g7(uint256): 20692
|
||||||
|
// g8(uint256): 20670
|
||||||
|
// g9(uint256): 20626
|
26
test/libsolidity/gasTests/dispatch_medium_optimised.sol
Normal file
26
test/libsolidity/gasTests/dispatch_medium_optimised.sol
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
contract Medium {
|
||||||
|
uint public a;
|
||||||
|
uint[] public b;
|
||||||
|
function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }
|
||||||
|
function f2(uint x) public returns (uint) { b[uint8(msg.data[1])] = x; }
|
||||||
|
function f3(uint x) public returns (uint) { b[uint8(msg.data[2])] = x; }
|
||||||
|
function g7(uint x) public payable returns (uint) { b[uint8(msg.data[6])] = x; }
|
||||||
|
function g8(uint x) public payable returns (uint) { b[uint8(msg.data[7])] = x; }
|
||||||
|
function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }
|
||||||
|
function g0(uint x) public payable returns (uint) { require(x > 10); }
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// optimize: true
|
||||||
|
// optimize-runs: 2
|
||||||
|
// ----
|
||||||
|
// creation: 183 + 140400 = 140583
|
||||||
|
// external:
|
||||||
|
// a(): 398
|
||||||
|
// b(uint256): 863
|
||||||
|
// f1(uint256): 40666
|
||||||
|
// f2(uint256): 20710
|
||||||
|
// f3(uint256): 20754
|
||||||
|
// g0(uint256): 332
|
||||||
|
// g7(uint256): 20620
|
||||||
|
// g8(uint256): 20598
|
||||||
|
// g9(uint256): 20554
|
13
test/libsolidity/gasTests/dispatch_small.sol
Normal file
13
test/libsolidity/gasTests/dispatch_small.sol
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
contract Small {
|
||||||
|
uint public a;
|
||||||
|
uint[] public b;
|
||||||
|
function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }
|
||||||
|
function () external payable {}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// creation: 129 + 81800 = 81929
|
||||||
|
// external:
|
||||||
|
// fallback: 118
|
||||||
|
// a(): 383
|
||||||
|
// b(uint256): 802
|
||||||
|
// f1(uint256): 40663
|
16
test/libsolidity/gasTests/dispatch_small_optimised.sol
Normal file
16
test/libsolidity/gasTests/dispatch_small_optimised.sol
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
contract Small {
|
||||||
|
uint public a;
|
||||||
|
uint[] public b;
|
||||||
|
function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }
|
||||||
|
function () external payable {}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// optimize: true
|
||||||
|
// optimize-runs: 2
|
||||||
|
// ----
|
||||||
|
// creation: 111 + 63600 = 63711
|
||||||
|
// external:
|
||||||
|
// fallback: 118
|
||||||
|
// a(): 376
|
||||||
|
// b(uint256): 753
|
||||||
|
// f1(uint256): 40600
|
@ -20,6 +20,7 @@ add_executable(isoltest
|
|||||||
../TestCase.cpp
|
../TestCase.cpp
|
||||||
../libsolidity/util/TestFileParser.cpp
|
../libsolidity/util/TestFileParser.cpp
|
||||||
../libsolidity/util/TestFunctionCall.cpp
|
../libsolidity/util/TestFunctionCall.cpp
|
||||||
|
../libsolidity/GasTest.cpp
|
||||||
../libsolidity/SyntaxTest.cpp
|
../libsolidity/SyntaxTest.cpp
|
||||||
../libsolidity/SemanticTest.cpp
|
../libsolidity/SemanticTest.cpp
|
||||||
../libsolidity/AnalysisFramework.cpp
|
../libsolidity/AnalysisFramework.cpp
|
||||||
|
Loading…
Reference in New Issue
Block a user