From 5ab36afaed2372278904b838ba10e3c6d87d1c75 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 10 Feb 2015 12:15:44 +0100 Subject: [PATCH 1/6] fixed jsoncpp find_path --- SolidityABIJSON.cpp | 2 +- SolidityNatspecJSON.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SolidityABIJSON.cpp b/SolidityABIJSON.cpp index d600340eb..9cb7c9445 100644 --- a/SolidityABIJSON.cpp +++ b/SolidityABIJSON.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include namespace dev diff --git a/SolidityNatspecJSON.cpp b/SolidityNatspecJSON.cpp index 911820ddd..91d504e8c 100644 --- a/SolidityNatspecJSON.cpp +++ b/SolidityNatspecJSON.cpp @@ -21,7 +21,7 @@ */ #include -#include +#include #include #include #include From 8787413a86dee8f26077f086506f0010587cf350 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 10 Feb 2015 09:00:50 +0100 Subject: [PATCH 2/6] Tests and some code for msg.data. --- SolidityEndToEndTest.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index 8a21290cb..054b0c6a4 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -2254,6 +2254,31 @@ BOOST_AUTO_TEST_CASE(generic_call) BOOST_CHECK_EQUAL(m_state.balance(m_contractAddress), 50 - 2); } +BOOST_AUTO_TEST_CASE(storing_bytes) +{ + char const* sourceCode = R"( + contract C { + function save() { + savedData = msg.data; + } + function forward() { + this.call(savedData); + } + function clear() { + delete savedData; + } + function doubleIt(uint a) returns (uint b) { return a * 2; } + bytes savedData; + } + )"; + compileAndRun(sourceCode); + FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); + BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); + BOOST_CHECK(callContractFunction("forward()") == encodeArgs(14)); + BOOST_CHECK(callContractFunction("clear()") == bytes()); + BOOST_CHECK(callContractFunction("forward()") == bytes()); +} + BOOST_AUTO_TEST_SUITE_END() } From 6e0ade681d26bd9d9e44624516788beefce1df01 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 10 Feb 2015 14:57:01 +0100 Subject: [PATCH 3/6] Simple copy of bytes to storage. --- SolidityEndToEndTest.cpp | 67 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index 054b0c6a4..ecf7ba8a5 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -2254,7 +2254,26 @@ BOOST_AUTO_TEST_CASE(generic_call) BOOST_CHECK_EQUAL(m_state.balance(m_contractAddress), 50 - 2); } -BOOST_AUTO_TEST_CASE(storing_bytes) +BOOST_AUTO_TEST_CASE(store_bytes) +{ + // this test just checks that the copy loop does not mess up the stack + char const* sourceCode = R"( + contract C { + function save() returns (uint r) { + r = 23; + savedData = msg.data; + r = 24; + } + bytes savedData; + } + )"; + compileAndRun(sourceCode); + // empty copy loop + BOOST_CHECK(callContractFunction("save()") == encodeArgs(24)); + BOOST_CHECK(callContractFunction("save()", "abcdefg") == encodeArgs(24)); +} + +BOOST_AUTO_TEST_CASE(call_forward_bytes) { char const* sourceCode = R"( contract C { @@ -2267,16 +2286,56 @@ BOOST_AUTO_TEST_CASE(storing_bytes) function clear() { delete savedData; } - function doubleIt(uint a) returns (uint b) { return a * 2; } + function doubleIt(uint a) { val += a * 2; } bytes savedData; + uint public val; } )"; compileAndRun(sourceCode); FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); - BOOST_CHECK(callContractFunction("forward()") == encodeArgs(14)); - BOOST_CHECK(callContractFunction("clear()") == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(0)); BOOST_CHECK(callContractFunction("forward()") == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("clear()") == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("forward()") == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(14)); +} + +BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) +{ + char const* sourceCode = R"( + contract C { + function save() { + data1 = data2 = msg.data; + } + function forward(bool selector) { + if (selector) + { + this.call(data1); + delete data1; + } + else + { + this.call(data2); + delete data2; + } + } + function doubleIt(uint a) returns (uint b) { val += a * 2; } + bytes data1; + bytes data2; + uint public val; + } + )"; + compileAndRun(sourceCode); + FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); + BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(0)); + BOOST_CHECK(callContractFunction("forward(bool)", true) == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("forward(bool)", false) == bytes()); + BOOST_CHECK(callContractFunction("val()") == bytes(28)); } BOOST_AUTO_TEST_SUITE_END() From a5449d9b3e924943472bbf8c4e8eed9c88a687f0 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 10 Feb 2015 17:53:43 +0100 Subject: [PATCH 4/6] Dynamic copy to memory. --- SolidityEndToEndTest.cpp | 86 ++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index ecf7ba8a5..235e535d0 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -668,7 +668,7 @@ BOOST_AUTO_TEST_CASE(mapping_state) testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0)); testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1)); testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(2)); - // voting without vote right shourd be rejected + // voting without vote right should be rejected testSolidityAgainstCpp("vote(address,address)", vote, u160(0), u160(2)); testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0)); testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1)); @@ -2276,68 +2276,66 @@ BOOST_AUTO_TEST_CASE(store_bytes) BOOST_AUTO_TEST_CASE(call_forward_bytes) { char const* sourceCode = R"( - contract C { - function save() { - savedData = msg.data; - } - function forward() { - this.call(savedData); - } - function clear() { - delete savedData; - } - function doubleIt(uint a) { val += a * 2; } + contract receiver { + uint public received; + function receive(uint x) { received += x + 1; } + function() { received = 0x80; } + } + contract sender { + function sender() { rec = new receiver(); } + function() { savedData = msg.data; } + function forward() { rec.call(savedData); } + function clear() { delete savedData; } + function val() returns (uint) { return rec.received(); } + receiver rec; bytes savedData; - uint public val; } )"; - compileAndRun(sourceCode); - FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); - BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(0)); + compileAndRun(sourceCode, 0, "sender"); + BOOST_CHECK(callContractFunction("receive(uint256)", 7) == bytes()); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(0)); BOOST_CHECK(callContractFunction("forward()") == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("clear()") == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("forward()") == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(0x80)); } BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) { char const* sourceCode = R"( - contract C { - function save() { - data1 = data2 = msg.data; - } + contract receiver { + uint public received; + function receive(uint x) { received += x + 1; } + function() { received = 0x80; } + } + contract sender { + function sender() { rec = new receiver(); } + function() { savedData1 = savedData2 = msg.data; } function forward(bool selector) { - if (selector) - { - this.call(data1); - delete data1; - } - else - { - this.call(data2); - delete data2; - } + if (selector) { rec.call(savedData1); delete savedData1; } + else { rec.call(savedData2); delete savedData2; } } - function doubleIt(uint a) returns (uint b) { val += a * 2; } - bytes data1; - bytes data2; - uint public val; + function val() returns (uint) { return rec.received(); } + receiver rec; + bytes savedData1; + bytes savedData2; } )"; - compileAndRun(sourceCode); - FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); - BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(0)); + compileAndRun(sourceCode, 0, "sender"); + BOOST_CHECK(callContractFunction("receive(uint256)", 7) == bytes()); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(0)); BOOST_CHECK(callContractFunction("forward(bool)", true) == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(14)); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("forward(bool)", false) == bytes()); - BOOST_CHECK(callContractFunction("val()") == bytes(28)); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(16)); + BOOST_CHECK(callContractFunction("forward(bool)", true) == bytes()); + BOOST_CHECK(callContractFunction("val()") == encodeArgs(0x80)); } +// TODO test that "delete" also clears the values + BOOST_AUTO_TEST_SUITE_END() } From d089703254d9d8243522f94b6585eb2c4e99bd57 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 11 Feb 2015 14:32:46 +0100 Subject: [PATCH 5/6] Moved copy code to CompilerUtils. --- SolidityEndToEndTest.cpp | 69 ++++++++++++++++++++++++++++++------ solidityExecutionFramework.h | 2 +- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index 235e535d0..67d05d6e3 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -2284,8 +2284,8 @@ BOOST_AUTO_TEST_CASE(call_forward_bytes) contract sender { function sender() { rec = new receiver(); } function() { savedData = msg.data; } - function forward() { rec.call(savedData); } - function clear() { delete savedData; } + function forward() returns (bool) { rec.call(savedData); return true; } + function clear() returns (bool) { delete savedData; return true; } function val() returns (uint) { return rec.received(); } receiver rec; bytes savedData; @@ -2294,11 +2294,11 @@ BOOST_AUTO_TEST_CASE(call_forward_bytes) compileAndRun(sourceCode, 0, "sender"); BOOST_CHECK(callContractFunction("receive(uint256)", 7) == bytes()); BOOST_CHECK(callContractFunction("val()") == encodeArgs(0)); - BOOST_CHECK(callContractFunction("forward()") == bytes()); + BOOST_CHECK(callContractFunction("forward()") == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); - BOOST_CHECK(callContractFunction("clear()") == bytes()); + BOOST_CHECK(callContractFunction("clear()") == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); - BOOST_CHECK(callContractFunction("forward()") == bytes()); + BOOST_CHECK(callContractFunction("forward()") == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(0x80)); } @@ -2313,9 +2313,10 @@ BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) contract sender { function sender() { rec = new receiver(); } function() { savedData1 = savedData2 = msg.data; } - function forward(bool selector) { + function forward(bool selector) returns (bool) { if (selector) { rec.call(savedData1); delete savedData1; } else { rec.call(savedData2); delete savedData2; } + return true; } function val() returns (uint) { return rec.received(); } receiver rec; @@ -2326,15 +2327,63 @@ BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) compileAndRun(sourceCode, 0, "sender"); BOOST_CHECK(callContractFunction("receive(uint256)", 7) == bytes()); BOOST_CHECK(callContractFunction("val()") == encodeArgs(0)); - BOOST_CHECK(callContractFunction("forward(bool)", true) == bytes()); + BOOST_CHECK(callContractFunction("forward(bool)", true) == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(8)); - BOOST_CHECK(callContractFunction("forward(bool)", false) == bytes()); + BOOST_CHECK(callContractFunction("forward(bool)", false) == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(16)); - BOOST_CHECK(callContractFunction("forward(bool)", true) == bytes()); + BOOST_CHECK(callContractFunction("forward(bool)", true) == encodeArgs(true)); BOOST_CHECK(callContractFunction("val()") == encodeArgs(0x80)); } -// TODO test that "delete" also clears the values +BOOST_AUTO_TEST_CASE(delete_removes_bytes_data) +{ + char const* sourceCode = R"( + contract c { + function() { data = msg.data; } + function del() returns (bool) { delete data; return true; } + bytes data; + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("---", 7) == bytes()); + BOOST_CHECK(!m_state.storage(m_contractAddress).empty()); + BOOST_CHECK(callContractFunction("del()", 7) == encodeArgs(true)); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); +} + +BOOST_AUTO_TEST_CASE(copy_from_calldata_removes_bytes_data) +{ + char const* sourceCode = R"( + contract c { + function set() returns (bool) { data = msg.data; return true; } + function() { data = msg.data; } + bytes data; + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("set()", 1, 2, 3, 4, 5) == encodeArgs(true)); + BOOST_CHECK(!m_state.storage(m_contractAddress).empty()); + sendMessage(bytes(), false); + BOOST_CHECK(m_output == bytes()); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); +} + +BOOST_AUTO_TEST_CASE(copy_removes_bytes_data) +{ + char const* sourceCode = R"( + contract c { + function set() returns (bool) { data1 = msg.data; return true; } + function reset() returns (bool) { data1 = data2; return true; } + bytes data1; + bytes data2; + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("set()", 1, 2, 3, 4, 5) == encodeArgs(true)); + BOOST_CHECK(!m_state.storage(m_contractAddress).empty()); + BOOST_CHECK(callContractFunction("reset()") == encodeArgs(true)); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/solidityExecutionFramework.h b/solidityExecutionFramework.h index 5a6935365..4ef9bfdc8 100644 --- a/solidityExecutionFramework.h +++ b/solidityExecutionFramework.h @@ -139,6 +139,7 @@ private: return encode(_cppFunction(_arguments...)); } +protected: void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0) { m_state.addBalance(m_sender, _value); // just in case @@ -171,7 +172,6 @@ private: m_logs = executive.logs(); } -protected: bool m_optimize = false; bool m_addStandardSources = false; Address m_sender; From 6bbba2269010cde1fe524ea6d41f2fe985d727ff Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 12 Feb 2015 11:54:44 +0100 Subject: [PATCH 6/6] Another try in fixing windows build. --- SolidityEndToEndTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index 8a21290cb..1bfb55f66 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -963,7 +963,7 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors) compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("name()") == encodeArgs("Celina")); - BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::sha3(bytes{0x7b}))); + BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::sha3(bytes(1, 0x7b)))); BOOST_CHECK(callContractFunction("an_address()") == encodeArgs(toBigEndian(u160(0x1337)))); BOOST_CHECK(callContractFunction("super_secret_data()") == bytes()); } @@ -2203,7 +2203,7 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals) dev::sha3( toBigEndian(u256(10)) + bytes{0x0, 0xc} + - bytes{0x91}))); + bytes(1, 0x91)))); } BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) @@ -2227,7 +2227,7 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) dev::sha3( toBigEndian(u256(10)) + bytes{0x0, 0xc} + - bytes{0x91} + + bytes(1, 0x91) + bytes{0x66, 0x6f, 0x6f}))); }