From 7e145a3d1cb2a1e791a74628ba6b3234df7ce7c3 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 19 Jan 2015 15:34:15 +0100 Subject: [PATCH 1/3] Some addition to Solidity Execution Framework --- libsolidity/ExpressionCompiler.cpp | 4 +--- test/solidityExecutionFramework.h | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index b6a73a884..df90d0d9d 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -392,9 +392,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) m_context << eth::Instruction::COINBASE; else if (member == "timestamp") m_context << eth::Instruction::TIMESTAMP; -/* else if (member == "blockhash") - m_context << eth::Instruction::BLOCKHASH; -*/ else if (member == "difficulty") + else if (member == "difficulty") m_context << eth::Instruction::DIFFICULTY; else if (member == "number") m_context << eth::Instruction::NUMBER; diff --git a/test/solidityExecutionFramework.h b/test/solidityExecutionFramework.h index 8d3c7e77c..1160d046f 100644 --- a/test/solidityExecutionFramework.h +++ b/test/solidityExecutionFramework.h @@ -29,6 +29,7 @@ #include #include #include +#include "TestHelper.h" namespace dev { @@ -46,7 +47,20 @@ public: bytes const& compileAndRun(std::string const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "") { dev::solidity::CompilerStack compiler; - compiler.compile(_sourceCode, m_optimize); + try + { + compiler.compile(_sourceCode, m_optimize); + } + catch (const std::exception& e) + { + std::string const* extra = boost::get_error_info(e); + std::string msg = std::string("Parsing contract failed with: ") + + e.what() + std::string("\n"); + if (extra) + msg += *extra; + BOOST_FAIL(msg); + } + bytes code = compiler.getBytecode(_contractName); sendMessage(code, true, _value); BOOST_REQUIRE(!m_output.empty()); @@ -97,6 +111,7 @@ public: static bytes encode(char const* _value) { return encode(std::string(_value)); } static bytes encode(byte _value) { return bytes(31, 0) + bytes{_value}; } static bytes encode(u256 const& _value) { return toBigEndian(_value); } + static bytes encode(h256 const& _value) { return _value.asBytes(); } static bytes encode(bytes const& _value, bool _padLeft = true) { bytes padding = bytes((32 - _value.size() % 32) % 32, 0); @@ -114,6 +129,12 @@ public: return bytes(); } + eth::LastHashes setCurrentBlockNumber(u256 _currentBlockNumber) + { + m_lastHashes = dev::test::lastHashes(_currentBlockNumber); + return m_lastHashes; + } + private: template auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments) @@ -132,7 +153,7 @@ private: void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0) { m_state.addBalance(m_sender, _value); // just in case - eth::Executive executive(m_state, eth::LastHashes(), 0); + eth::Executive executive(m_state, m_lastHashes, 0); eth::Transaction t = _isCreation ? eth::Transaction(_value, m_gasPrice, m_gas, _data, 0, KeyPair::create().sec()) : eth::Transaction(_value, m_gasPrice, m_gas, m_contractAddress, _data, 0, KeyPair::create().sec()); bytes transactionRLP = t.rlp(); @@ -170,6 +191,7 @@ protected: u256 const m_gas = 1000000; bytes m_output; eth::LogEntries m_logs; + eth::LastHashes m_lastHashes; }; } From 3c22b7798260899c4a083f7c50c2651851ed8b54 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 19 Jan 2015 17:00:23 +0100 Subject: [PATCH 2/3] Adding blockhash test in Solidity ExpressionCompiler --- test/SolidityExpressionCompiler.cpp | 25 +++++++++++++++++++++++-- test/solidityExecutionFramework.h | 10 +--------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/test/SolidityExpressionCompiler.cpp b/test/SolidityExpressionCompiler.cpp index 579af5bb9..d50dc253e 100644 --- a/test/SolidityExpressionCompiler.cpp +++ b/test/SolidityExpressionCompiler.cpp @@ -86,13 +86,19 @@ Declaration const& resolveDeclaration(vector const& _namespacedName, } bytes compileFirstExpression(const string& _sourceCode, vector> _functions = {}, - vector> _localVariables = {}) + vector> _localVariables = {}, vector> _globalDeclarations = {}) { Parser parser; ASTPointer sourceUnit; BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared(CharStream(_sourceCode)))); - NameAndTypeResolver resolver({}); + + vector declarations; + declarations.reserve(_globalDeclarations.size() + 1); + for (ASTPointer const& variable: _globalDeclarations) + declarations.push_back(variable.get()); + NameAndTypeResolver resolver(declarations); resolver.registerDeclarations(*sourceUnit); + for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) { @@ -390,6 +396,21 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals) BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } +BOOST_AUTO_TEST_CASE(blockhash) +{ + char const* sourceCode = "contract test {\n" + " function f() {\n" + " block.blockhash(3);\n" + " }\n" + "}\n"; + bytes code = compileFirstExpression(sourceCode, {}, {}, + {make_shared("block", make_shared(MagicType::Kind::BLOCK))}); + + bytes expectation({byte(eth::Instruction::PUSH1), 0x03, + byte(eth::Instruction::BLOCKHASH)}); + BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/solidityExecutionFramework.h b/test/solidityExecutionFramework.h index 1160d046f..1aea61fec 100644 --- a/test/solidityExecutionFramework.h +++ b/test/solidityExecutionFramework.h @@ -29,7 +29,6 @@ #include #include #include -#include "TestHelper.h" namespace dev { @@ -129,12 +128,6 @@ public: return bytes(); } - eth::LastHashes setCurrentBlockNumber(u256 _currentBlockNumber) - { - m_lastHashes = dev::test::lastHashes(_currentBlockNumber); - return m_lastHashes; - } - private: template auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments) @@ -153,7 +146,7 @@ private: void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0) { m_state.addBalance(m_sender, _value); // just in case - eth::Executive executive(m_state, m_lastHashes, 0); + eth::Executive executive(m_state, eth::LastHashes(), 0); eth::Transaction t = _isCreation ? eth::Transaction(_value, m_gasPrice, m_gas, _data, 0, KeyPair::create().sec()) : eth::Transaction(_value, m_gasPrice, m_gas, m_contractAddress, _data, 0, KeyPair::create().sec()); bytes transactionRLP = t.rlp(); @@ -191,7 +184,6 @@ protected: u256 const m_gas = 1000000; bytes m_output; eth::LogEntries m_logs; - eth::LastHashes m_lastHashes; }; } From c3c2b1cf763aa3238059b36dc957d7d70b20e6c2 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 19 Jan 2015 18:58:09 +0100 Subject: [PATCH 3/3] Improved handling of exceptions in some Solidity Tests --- test/SolidityABIJSON.cpp | 8 ++------ test/SolidityNatspecJSON.cpp | 8 ++------ test/solidityExecutionFramework.h | 8 ++------ 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/test/SolidityABIJSON.cpp b/test/SolidityABIJSON.cpp index d553f576a..892b71f15 100644 --- a/test/SolidityABIJSON.cpp +++ b/test/SolidityABIJSON.cpp @@ -41,13 +41,9 @@ public: { m_compilerStack.parse(_code); } - catch (const std::exception& e) + catch(boost::exception const& _e) { - std::string const* extra = boost::get_error_info(e); - std::string msg = std::string("Parsing contract failed with: ") + - e.what() + std::string("\n"); - if (extra) - msg += *extra; + auto msg = std::string("Parsing contract failed with: ") + boost::diagnostic_information(_e); BOOST_FAIL(msg); } std::string generatedInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABI_INTERFACE); diff --git a/test/SolidityNatspecJSON.cpp b/test/SolidityNatspecJSON.cpp index d43aebc2b..5cec0444c 100644 --- a/test/SolidityNatspecJSON.cpp +++ b/test/SolidityNatspecJSON.cpp @@ -45,13 +45,9 @@ public: { m_compilerStack.parse(_code); } - catch (const std::exception& e) + catch(boost::exception const& _e) { - std::string const* extra = boost::get_error_info(e); - std::string msg = std::string("Parsing contract failed with: ") + - e.what() + std::string("\n"); - if (extra) - msg += *extra; + auto msg = std::string("Parsing contract failed with: ") + boost::diagnostic_information(_e); BOOST_FAIL(msg); } diff --git a/test/solidityExecutionFramework.h b/test/solidityExecutionFramework.h index 1aea61fec..271a594c4 100644 --- a/test/solidityExecutionFramework.h +++ b/test/solidityExecutionFramework.h @@ -50,13 +50,9 @@ public: { compiler.compile(_sourceCode, m_optimize); } - catch (const std::exception& e) + catch(boost::exception const& _e) { - std::string const* extra = boost::get_error_info(e); - std::string msg = std::string("Parsing contract failed with: ") + - e.what() + std::string("\n"); - if (extra) - msg += *extra; + auto msg = std::string("Compiling contract failed with: ") + boost::diagnostic_information(_e); BOOST_FAIL(msg); }