aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryann300 <yann.levreau@gmail.com>2015-05-21 16:19:31 +0800
committeryann300 <yann.levreau@gmail.com>2015-05-21 16:19:31 +0800
commitba2b77bb9a1bf6ec869adb14a7adbaa5117f1c36 (patch)
tree59aa52393acbf73ff5708f688ea3eaddd0b33113
parent91dbf6397832b6825afdf7748416f7aa5126440d (diff)
parenta97a326ffe08e7304d4a0e0d2d879d3baef8bb20 (diff)
downloaddexon-solidity-ba2b77bb9a1bf6ec869adb14a7adbaa5117f1c36.tar.gz
dexon-solidity-ba2b77bb9a1bf6ec869adb14a7adbaa5117f1c36.tar.zst
dexon-solidity-ba2b77bb9a1bf6ec869adb14a7adbaa5117f1c36.zip
Merge remote-tracking branch 'up/develop' into bugFix
-rw-r--r--TestHelper.cpp9
-rw-r--r--libsolidity/GasMeter.cpp (renamed from GasMeter.cpp)60
-rw-r--r--libsolidity/SolidityEndToEndTest.cpp86
-rw-r--r--libsolidity/solidityExecutionFramework.h11
4 files changed, 159 insertions, 7 deletions
diff --git a/TestHelper.cpp b/TestHelper.cpp
index aada8304..476d1ecf 100644
--- a/TestHelper.cpp
+++ b/TestHelper.cpp
@@ -327,7 +327,8 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta
void ImportTest::exportTest(bytes const& _output, State const& _statePost)
{
// export output
- m_TestObject["out"] = toHex(_output, 2, HexPrefix::Add);
+
+ m_TestObject["out"] = _output.size() > 4096 ? "#" + toString(_output.size()) : toHex(_output, 2, HexPrefix::Add);
// export logs
m_TestObject["logs"] = exportLog(_statePost.pending().size() ? _statePost.log(0) : LogEntries());
@@ -489,7 +490,11 @@ LogEntries importLog(json_spirit::mArray& _a)
void checkOutput(bytes const& _output, json_spirit::mObject& _o)
{
int j = 0;
- if (_o["out"].type() == json_spirit::array_type)
+
+ if (_o["out"].get_str().find("#") == 0)
+ BOOST_CHECK((u256)_output.size() == toInt(_o["out"].get_str().substr(1)));
+
+ else if (_o["out"].type() == json_spirit::array_type)
for (auto const& d: _o["out"].get_array())
{
BOOST_CHECK_MESSAGE(_output[j] == toInt(d), "Output byte [" << j << "] different!");
diff --git a/GasMeter.cpp b/libsolidity/GasMeter.cpp
index 0ffe4171..43eb3f95 100644
--- a/GasMeter.cpp
+++ b/libsolidity/GasMeter.cpp
@@ -21,6 +21,8 @@
*/
#include <test/libsolidity/solidityExecutionFramework.h>
+#include <libevmasm/GasMeter.h>
+#include <libevmasm/KnownState.h>
#include <libsolidity/AST.h>
#include <libsolidity/StructuralGasEstimator.h>
#include <libsolidity/SourceReferenceFormatter.h>
@@ -55,8 +57,21 @@ public:
);
}
+ void testCreationTimeGas(string const& _sourceCode, string const& _contractName = "")
+ {
+ 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());
+ gas += bytecodeSize * c_createDataGas;
+ BOOST_REQUIRE(!gas.isInfinite);
+ BOOST_CHECK(gas.value == m_gasUsed);
+ }
+
protected:
- dev::solidity::CompilerStack m_compiler;
map<ASTNode const*, eth::GasMeter::GasConsumption> m_gasCosts;
};
@@ -91,6 +106,49 @@ BOOST_AUTO_TEST_CASE(non_overlapping_filtered_costs)
}
}
+BOOST_AUTO_TEST_CASE(simple_contract)
+{
+ // Tests a simple "deploy contract" code without constructor. The actual contract is not relevant.
+ char const* sourceCode = R"(
+ contract test {
+ bytes32 public shaValue;
+ function f(uint a) {
+ shaValue = sha3(a);
+ }
+ }
+ )";
+ testCreationTimeGas(sourceCode);
+}
+
+BOOST_AUTO_TEST_CASE(store_sha3)
+{
+ char const* sourceCode = R"(
+ contract test {
+ bytes32 public shaValue;
+ function test(uint a) {
+ shaValue = sha3(a);
+ }
+ }
+ )";
+ testCreationTimeGas(sourceCode);
+}
+
+BOOST_AUTO_TEST_CASE(updating_store)
+{
+ char const* sourceCode = R"(
+ contract test {
+ uint data;
+ uint data2;
+ function test() {
+ data = 1;
+ data = 2;
+ data2 = 0;
+ }
+ }
+ )";
+ testCreationTimeGas(sourceCode);
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/libsolidity/SolidityEndToEndTest.cpp b/libsolidity/SolidityEndToEndTest.cpp
index 90ce20d2..503615a5 100644
--- a/libsolidity/SolidityEndToEndTest.cpp
+++ b/libsolidity/SolidityEndToEndTest.cpp
@@ -4023,6 +4023,92 @@ BOOST_AUTO_TEST_CASE(overwriting_inheritance)
BOOST_CHECK(callContractFunction("checkOk()") == encodeArgs(6));
}
+BOOST_AUTO_TEST_CASE(struct_assign_reference_to_struct)
+{
+ char const* sourceCode = R"(
+ contract test {
+ struct testStruct
+ {
+ uint m_value;
+ }
+ testStruct data1;
+ testStruct data2;
+ testStruct data3;
+ function test()
+ {
+ data1.m_value = 2;
+ }
+ function assign() returns (uint ret_local, uint ret_global, uint ret_global3, uint ret_global1)
+ {
+ testStruct x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2
+ data2 = data1; // should copy data. data2.m_value == 2
+
+ ret_local = x.m_value; // = 2
+ ret_global = data2.m_value; // = 2
+
+ x.m_value = 3;
+ data3 = x; //should copy the data. data3.m_value == 3
+ ret_global3 = data3.m_value; // = 3
+ ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "test");
+ BOOST_CHECK(callContractFunction("assign()") == encodeArgs(2, 2, 3, 3));
+}
+
+BOOST_AUTO_TEST_CASE(struct_delete_member)
+{
+ char const* sourceCode = R"(
+ contract test {
+ struct testStruct
+ {
+ uint m_value;
+ }
+ testStruct data1;
+ function test()
+ {
+ data1.m_value = 2;
+ }
+ function deleteMember() returns (uint ret_value)
+ {
+ testStruct x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0
+ x.m_value = 4;
+ delete x.m_value;
+ ret_value = data1.m_value;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "test");
+ auto res = callContractFunction("deleteMember()");
+ BOOST_CHECK(callContractFunction("deleteMember()") == encodeArgs(0));
+}
+
+BOOST_AUTO_TEST_CASE(struct_delete_struct_in_mapping)
+{
+ char const* sourceCode = R"(
+ contract test {
+ struct testStruct
+ {
+ uint m_value;
+ }
+ mapping (uint => testStruct) campaigns;
+
+ function test()
+ {
+ campaigns[0].m_value = 2;
+ }
+ function deleteIt() returns (uint)
+ {
+ delete campaigns[0];
+ return campaigns[0].m_value;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "test");
+ auto res = callContractFunction("deleteIt()");
+ BOOST_CHECK(callContractFunction("deleteIt()") == encodeArgs(0));
+}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/libsolidity/solidityExecutionFramework.h b/libsolidity/solidityExecutionFramework.h
index f76465f2..fa25fb12 100644
--- a/libsolidity/solidityExecutionFramework.h
+++ b/libsolidity/solidityExecutionFramework.h
@@ -44,11 +44,11 @@ public:
bytes const& compileAndRun(std::string const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "")
{
- dev::solidity::CompilerStack compiler(m_addStandardSources);
- compiler.addSource("", _sourceCode);
- ETH_TEST_REQUIRE_NO_THROW(compiler.compile(m_optimize), "Compiling contract failed");
+ m_compiler.reset(false, m_addStandardSources);
+ m_compiler.addSource("", _sourceCode);
+ ETH_TEST_REQUIRE_NO_THROW(m_compiler.compile(m_optimize), "Compiling contract failed");
- bytes code = compiler.getBytecode(_contractName);
+ bytes code = m_compiler.getBytecode(_contractName);
sendMessage(code, true, _value);
BOOST_REQUIRE(!m_output.empty());
return m_output;
@@ -160,12 +160,14 @@ protected:
BOOST_REQUIRE(executive.go());
m_state.noteSending(m_sender);
executive.finalize();
+ m_gasUsed = executive.gasUsed();
m_output = executive.out().toVector();
m_logs = executive.logs();
}
bool m_optimize = false;
bool m_addStandardSources = false;
+ dev::solidity::CompilerStack m_compiler;
Address m_sender;
Address m_contractAddress;
eth::State m_state;
@@ -173,6 +175,7 @@ protected:
u256 const m_gas = 100000000;
bytes m_output;
eth::LogEntries m_logs;
+ u256 m_gasUsed;
};
}