diff options
author | chriseth <c@ethdev.com> | 2015-05-22 15:33:57 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-05-22 22:12:40 +0800 |
commit | ec76302b85b2715e19e02317d90ee4a6d63e8470 (patch) | |
tree | 371a7f5de2404bffe5901f52596bbab100dad75b /libsolidity | |
parent | ba2b77bb9a1bf6ec869adb14a7adbaa5117f1c36 (diff) | |
download | dexon-solidity-ec76302b85b2715e19e02317d90ee4a6d63e8470.tar.gz dexon-solidity-ec76302b85b2715e19e02317d90ee4a6d63e8470.tar.zst dexon-solidity-ec76302b85b2715e19e02317d90ee4a6d63e8470.zip |
Path gas meter.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/GasMeter.cpp | 70 |
1 files changed, 64 insertions, 6 deletions
diff --git a/libsolidity/GasMeter.cpp b/libsolidity/GasMeter.cpp index 43eb3f95..2508399f 100644 --- a/libsolidity/GasMeter.cpp +++ b/libsolidity/GasMeter.cpp @@ -23,6 +23,7 @@ #include <test/libsolidity/solidityExecutionFramework.h> #include <libevmasm/GasMeter.h> #include <libevmasm/KnownState.h> +#include <libevmasm/PathGasMeter.h> #include <libsolidity/AST.h> #include <libsolidity/StructuralGasEstimator.h> #include <libsolidity/SourceReferenceFormatter.h> @@ -57,20 +58,38 @@ public: ); } - void testCreationTimeGas(string const& _sourceCode, string const& _contractName = "") + void testCreationTimeGas(string const& _sourceCode) { compileAndRun(_sourceCode); auto state = make_shared<KnownState>(); - GasMeter meter(state); - GasMeter::GasConsumption gas; - for (AssemblyItem const& item: *m_compiler.getAssemblyItems(_contractName)) - gas += meter.estimateMax(item); - u256 bytecodeSize(m_compiler.getRuntimeBytecode(_contractName).size()); + PathGasMeter meter(*m_compiler.getAssemblyItems()); + GasMeter::GasConsumption gas = meter.estimateMax(0, state); + u256 bytecodeSize(m_compiler.getRuntimeBytecode().size()); gas += bytecodeSize * c_createDataGas; BOOST_REQUIRE(!gas.isInfinite); BOOST_CHECK(gas.value == m_gasUsed); } + void testRunTimeGas(std::string const& _sig, vector<bytes> _argumentVariants) + { + u256 gasUsed = 0; + FixedHash<4> hash(dev::sha3(_sig)); + for (bytes const& arguments: _argumentVariants) + { + sendMessage(hash.asBytes() + arguments, false, 0); + gasUsed = max(gasUsed, m_gasUsed); + } + + auto state = make_shared<KnownState>(); + //TODO modify state to include function hash in calldata + PathGasMeter meter(*m_compiler.getRuntimeAssemblyItems()); + GasMeter::GasConsumption gas = meter.estimateMax(0, state); + cout << "VM: " << gasUsed << endl; + cout << "est: " << gas << endl; + BOOST_REQUIRE(!gas.isInfinite); + BOOST_CHECK(gas.value == m_gasUsed); + } + protected: map<ASTNode const*, eth::GasMeter::GasConsumption> m_gasCosts; }; @@ -149,6 +168,45 @@ BOOST_AUTO_TEST_CASE(updating_store) testCreationTimeGas(sourceCode); } +BOOST_AUTO_TEST_CASE(branches) +{ + char const* sourceCode = R"( + contract test { + uint data; + uint data2; + function f(uint x) { + if (x > 7) + data2 = 1; + else + data = 1; + } + } + )"; + testCreationTimeGas(sourceCode); + testRunTimeGas("f(uint256)", vector<bytes>{encodeArgs(2), encodeArgs(8)}); +} + +BOOST_AUTO_TEST_CASE(function_calls) +{ + char const* sourceCode = R"( + contract test { + uint data; + uint data2; + function f(uint x) { + if (x > 7) + data2 = g(x**8) + 1; + else + data = 1; + } + function g(uint x) internal returns (uint) { + return data2; + } + } + )"; + testCreationTimeGas(sourceCode); + testRunTimeGas("f(uint256)", vector<bytes>{encodeArgs(2), encodeArgs(8)}); +} + BOOST_AUTO_TEST_SUITE_END() } |