aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/SolidityEndToEndTest.cpp12
-rw-r--r--libsolidity/solidityExecutionFramework.h68
2 files changed, 74 insertions, 6 deletions
diff --git a/libsolidity/SolidityEndToEndTest.cpp b/libsolidity/SolidityEndToEndTest.cpp
index a10b4767..ae2fc6dc 100644
--- a/libsolidity/SolidityEndToEndTest.cpp
+++ b/libsolidity/SolidityEndToEndTest.cpp
@@ -1151,8 +1151,10 @@ BOOST_AUTO_TEST_CASE(blockchain)
" blockNumber = block.number;\n"
" }\n"
"}\n";
+ m_envInfo.setBeneficiary(Address(0x123));
+ m_envInfo.setNumber(7);
compileAndRun(sourceCode, 27);
- BOOST_CHECK(callContractFunctionWithValue("someInfo()", 28) == encodeArgs(28, 0, 1));
+ BOOST_CHECK(callContractFunctionWithValue("someInfo()", 28) == encodeArgs(28, 0x123, 7));
}
BOOST_AUTO_TEST_CASE(msg_sig)
@@ -1187,12 +1189,14 @@ BOOST_AUTO_TEST_CASE(msg_sig_after_internal_call_is_same)
BOOST_AUTO_TEST_CASE(now)
{
char const* sourceCode = "contract test {\n"
- " function someInfo() returns (bool success) {\n"
- " return block.timestamp == now && now > 0;\n"
+ " function someInfo() returns (bool equal, uint val) {\n"
+ " equal = block.timestamp == now;\n"
+ " val = now;\n"
" }\n"
"}\n";
+ m_envInfo.setTimestamp(9);
compileAndRun(sourceCode);
- BOOST_CHECK(callContractFunction("someInfo()") == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("someInfo()") == encodeArgs(true, 9));
}
BOOST_AUTO_TEST_CASE(type_conversions_cleanup)
diff --git a/libsolidity/solidityExecutionFramework.h b/libsolidity/solidityExecutionFramework.h
index e4c4087f..3f443720 100644
--- a/libsolidity/solidityExecutionFramework.h
+++ b/libsolidity/solidityExecutionFramework.h
@@ -25,6 +25,7 @@
#include <string>
#include <tuple>
#include "../TestHelper.h"
+#include <libethcore/ABI.h>
#include <libethereum/State.h>
#include <libethereum/Executive.h>
#include <libsolidity/CompilerStack.h>
@@ -44,7 +45,6 @@ public:
ExecutionFramework()
{
g_logVerbosity = 0;
- m_state.resetCurrent();
}
bytes const& compileAndRunWithoutCheck(
@@ -166,6 +166,69 @@ public:
return encodeArgs(u256(0x20), u256(_arg.size()), _arg);
}
+ class ContractInterface
+ {
+ public:
+ ContractInterface(ExecutionFramework& _framework): m_framework(_framework) {}
+
+ protected:
+ template <class... Args>
+ bytes const& call(std::string const& _sig, Args const&... _arguments)
+ {
+ auto const& ret = m_framework.callContractFunctionWithValue(_sig, m_nextValue, _arguments...);
+ m_nextValue = 0;
+ return ret;
+ }
+
+ void callString(std::string const& _name, std::string const& _arg)
+ {
+ BOOST_CHECK(call(_name + "(string)", u256(0x20), _arg.length(), _arg).empty());
+ }
+
+ void callStringAddress(std::string const& _name, std::string const& _arg1, u160 const& _arg2)
+ {
+ BOOST_CHECK(call(_name + "(string,address)", u256(0x40), _arg2, _arg1.length(), _arg1).empty());
+ }
+
+ void callStringAddressBool(std::string const& _name, std::string const& _arg1, u160 const& _arg2, bool _arg3)
+ {
+ BOOST_CHECK(call(_name + "(string,address,bool)", u256(0x60), _arg2, _arg3, _arg1.length(), _arg1).empty());
+ }
+
+ void callStringBytes32(std::string const& _name, std::string const& _arg1, h256 const& _arg2)
+ {
+ BOOST_CHECK(call(_name + "(string,bytes32)", u256(0x40), _arg2, _arg1.length(), _arg1).empty());
+ }
+
+ u160 callStringReturnsAddress(std::string const& _name, std::string const& _arg)
+ {
+ bytes const& ret = call(_name + "(string)", u256(0x20), _arg.length(), _arg);
+ BOOST_REQUIRE(ret.size() == 0x20);
+ BOOST_CHECK(std::count(ret.begin(), ret.begin() + 12, 0) == 12);
+ return eth::abiOut<u160>(ret);
+ }
+
+ std::string callAddressReturnsString(std::string const& _name, u160 const& _arg)
+ {
+ bytes const& ret = call(_name + "(address)", _arg);
+ BOOST_REQUIRE(ret.size() >= 0x20);
+ u256 len = eth::abiOut<u256>(ret);
+ BOOST_REQUIRE(ret.size() == (0x20 + len) / 32 * 32);
+ return std::string(ret.begin() + 0x20, ret.begin() + 0x20 + size_t(len));
+ }
+
+ h256 callStringReturnsBytes32(std::string const& _name, std::string const& _arg)
+ {
+ bytes const& ret = call(_name + "(string)", u256(0x20), _arg.length(), _arg);
+ BOOST_REQUIRE(ret.size() == 0x20);
+ return eth::abiOut<h256>(ret);
+ }
+
+ private:
+ u256 m_nextValue;
+ ExecutionFramework& m_framework;
+ };
+
private:
template <class CppFunction, class... Args>
auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
@@ -185,7 +248,7 @@ protected:
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_envInfo, 0);
eth::ExecutionResult res;
executive.setResultRecipient(res);
eth::Transaction t =
@@ -226,6 +289,7 @@ protected:
dev::solidity::CompilerStack m_compiler;
Address m_sender;
Address m_contractAddress;
+ eth::EnvInfo m_envInfo;
eth::State m_state;
u256 const m_gasPrice = 100 * eth::szabo;
u256 const m_gas = 100000000;