aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TestHelper.cpp86
-rw-r--r--TestHelper.h27
-rw-r--r--TestUtils.cpp4
-rw-r--r--contracts/Wallet.cpp4
-rw-r--r--libsolidity/SolidityEndToEndTest.cpp37
-rw-r--r--libsolidity/SolidityNameAndTypeResolution.cpp17
-rw-r--r--libsolidity/solidityExecutionFramework.h4
7 files changed, 87 insertions, 92 deletions
diff --git a/TestHelper.cpp b/TestHelper.cpp
index e2c51a66..39977975 100644
--- a/TestHelper.cpp
+++ b/TestHelper.cpp
@@ -25,6 +25,7 @@
#include <chrono>
#include <libethcore/EthashAux.h>
#include <libethereum/Client.h>
+#include <libevm/ExtVMFace.h>
#include <liblll/Compiler.h>
#include <libevm/VMFactory.h>
#include "Stats.h"
@@ -61,7 +62,7 @@ void connectClients(Client& c1, Client& c2)
#endif
}
-void mine(State& s, BlockChain const& _bc)
+void mine(Block& s, BlockChain const& _bc)
{
std::unique_ptr<SealEngineFace> sealer(Ethash::createSealEngine());
s.commitToSeal(_bc);
@@ -94,23 +95,43 @@ struct MissingFields : virtual Exception {};
bigint const c_max256plus1 = bigint(1) << 256;
-ImportTest::ImportTest(json_spirit::mObject& _o, bool isFiller):
- m_statePre(OverlayDB(), eth::BaseState::Empty, Address(_o["env"].get_obj()["currentCoinbase"].get_str())),
- m_statePost(OverlayDB(), eth::BaseState::Empty, Address(_o["env"].get_obj()["currentCoinbase"].get_str())),
- m_environment(m_envInfo),
+ImportTest::ImportTest(json_spirit::mObject& _o, bool isFiller, testType testTemplate):
+ m_statePre(OverlayDB(), eth::BaseState::Empty),
+ m_statePost(OverlayDB(), eth::BaseState::Empty),
m_testObject(_o)
{
- importEnv(_o["env"].get_obj());
- importState(_o["pre"].get_obj(), m_statePre);
- importTransaction(_o["transaction"].get_obj());
-
- if (!isFiller)
+ if (testTemplate == testType::StateTests)
{
- importState(_o["post"].get_obj(), m_statePost);
- m_environment.sub.logs = importLog(_o["logs"].get_array());
+ importEnv(_o["env"].get_obj());
+ importTransaction(_o["transaction"].get_obj());
+ importState(_o["pre"].get_obj(), m_statePre);
+ if (!isFiller)
+ {
+ if (_o.count("post"))
+ importState(_o["post"].get_obj(), m_statePost);
+ else
+ importState(_o["postState"].get_obj(), m_statePost);
+ m_logsExpected = importLog(_o["logs"].get_array());
+ }
}
}
+//executes an imported transacton on preState
+bytes ImportTest::executeTest()
+{
+ ExecutionResult res;
+ eth::State tmpState = m_statePre;
+
+ std::pair<ExecutionResult, TransactionReceipt> execOut = m_statePre.execute(m_envInfo, m_transaction);
+ res = execOut.first;
+ m_logs = execOut.second.log();
+ m_statePre.commit();
+ m_statePost = m_statePre;
+ m_statePre = tmpState;
+
+ return res.output;
+}
+
json_spirit::mObject& ImportTest::makeAllFieldsHex(json_spirit::mObject& _o)
{
static const set<string> hashes {"bloom" , "coinbase", "hash", "mixHash", "parentHash", "receiptTrie",
@@ -139,24 +160,25 @@ json_spirit::mObject& ImportTest::makeAllFieldsHex(json_spirit::mObject& _o)
void ImportTest::importEnv(json_spirit::mObject& _o)
{
- assert(_o.count("previousHash") > 0);
assert(_o.count("currentGasLimit") > 0);
- assert(_o.count("currentDifficulty") > 0);
+ assert(_o.count("currentDifficulty") > 0);
+ assert(_o.count("currentNumber") > 0);
assert(_o.count("currentTimestamp") > 0);
assert(_o.count("currentCoinbase") > 0);
- assert(_o.count("currentNumber") > 0);
- m_envInfo.setBeneficiary(Address(_o["currentCoinbase"].get_str()));
+ m_envInfo.setGasLimit(toInt(_o["currentGasLimit"]));
m_envInfo.setDifficulty(toInt(_o["currentDifficulty"]));
m_envInfo.setNumber(toInt(_o["currentNumber"]));
- m_envInfo.setGasLimit(toInt(_o["currentGasLimit"]));
m_envInfo.setTimestamp(toInt(_o["currentTimestamp"]));
+ m_envInfo.setBeneficiary(Address(_o["currentCoinbase"].get_str()));
+ m_envInfo.setLastHashes( lastHashes( m_envInfo.number() ) );
}
// import state from not fully declared json_spirit::mObject, writing to _stateOptionsMap which fields were defined in json
void ImportTest::importState(json_spirit::mObject& _o, State& _state, AccountMaskMap& o_mask)
-{
- _state.populateFrom(jsonToAccountMap(json_spirit::write_string(_o, false), &o_mask));
+{
+ std::string jsondata = json_spirit::write_string((json_spirit::mValue)_o, false);
+ _state.populateFrom(jsonToAccountMap(jsondata, &o_mask));
}
void ImportTest::importState(json_spirit::mObject& _o, State& _state)
@@ -215,7 +237,7 @@ void ImportTest::importTransaction(json_spirit::mObject& _o)
}
}
-void ImportTest::checkExpectedState(State const& _stateExpect, State const& _statePost, stateOptionsMap const _expectedStateOptions, WhenError _throw)
+void ImportTest::compareStates(State const& _stateExpect, State const& _statePost, AccountMaskMap const _expectedStateOptions, WhenError _throw)
{
#define CHECK(a,b) \
{ \
@@ -230,7 +252,7 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta
CHECK(_statePost.addressInUse(a.first), "Filling Test: " << a.first << " missing expected address!");
if (_statePost.addressInUse(a.first))
{
- ImportStateOptions addressOptions(true);
+ AccountMask addressOptions(true);
if(_expectedStateOptions.size())
{
try
@@ -244,15 +266,15 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta
}
}
- if (addressOptions.m_bHasBalance)
+ if (addressOptions.hasBalance())
CHECK((_stateExpect.balance(a.first) == _statePost.balance(a.first)),
"Check State: " << a.first << ": incorrect balance " << _statePost.balance(a.first) << ", expected " << _stateExpect.balance(a.first));
- if (addressOptions.m_bHasNonce)
+ if (addressOptions.hasNonce())
CHECK((_stateExpect.transactionsFrom(a.first) == _statePost.transactionsFrom(a.first)),
"Check State: " << a.first << ": incorrect nonce " << _statePost.transactionsFrom(a.first) << ", expected " << _stateExpect.transactionsFrom(a.first));
- if (addressOptions.m_bHasStorage)
+ if (addressOptions.hasStorage())
{
unordered_map<u256, u256> stateStorage = _statePost.storage(a.first);
for (auto const& s: _stateExpect.storage(a.first))
@@ -266,14 +288,14 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta
"Check State: " << a.first << ": incorrect storage [" << s.first << "] = " << toHex(s.second) << ", expected [" << s.first << "] = " << toHex(stateStorage[s.first]));
}
- if (addressOptions.m_bHasCode)
+ if (addressOptions.hasCode())
CHECK((_stateExpect.code(a.first) == _statePost.code(a.first)),
"Check State: " << a.first << ": incorrect code '" << toHex(_statePost.code(a.first)) << "', expected '" << toHex(_stateExpect.code(a.first)) << "'");
}
}
}
-void ImportTest::exportTest(bytes const& _output, State const& _statePost)
+void ImportTest::exportTest(bytes const& _output)
{
// export output
@@ -291,22 +313,22 @@ void ImportTest::exportTest(bytes const& _output, State const& _statePost)
m_testObject.erase(m_testObject.find("expectOut"));
}
- // export logs
- m_testObject["logs"] = exportLog(_statePost.pending().size() ? _statePost.log(0) : LogEntries());
+ // export logs
+ m_testObject["logs"] = exportLog(m_logs);
// compare expected state with post state
if (m_testObject.count("expect") > 0)
{
- stateOptionsMap stateMap;
+ eth::AccountMaskMap stateMap;
State expectState(OverlayDB(), eth::BaseState::Empty);
importState(m_testObject["expect"].get_obj(), expectState, stateMap);
- checkExpectedState(expectState, _statePost, stateMap, Options::get().checkState ? WhenError::Throw : WhenError::DontThrow);
+ compareStates(expectState, m_statePost, stateMap, Options::get().checkState ? WhenError::Throw : WhenError::DontThrow);
m_testObject.erase(m_testObject.find("expect"));
}
// export post state
- m_testObject["post"] = fillJsonWithState(_statePost);
- m_testObject["postStateRoot"] = toHex(_statePost.rootHash().asBytes());
+ m_testObject["post"] = fillJsonWithState(m_statePost);
+ m_testObject["postStateRoot"] = toHex(m_statePost.rootHash().asBytes());
// export pre state
m_testObject["pre"] = fillJsonWithState(m_statePre);
diff --git a/TestHelper.h b/TestHelper.h
index 85e901b2..9d2625e1 100644
--- a/TestHelper.h
+++ b/TestHelper.h
@@ -32,6 +32,7 @@
#include <libevm/ExtVMFace.h>
#include <libtestutils/Common.h>
+
#ifdef NOBOOST
#define TBOOST_REQUIRE(arg) if(arg == false) throw dev::Exception();
#define TBOOST_REQUIRE_EQUAL(arg1, arg2) if(arg1 != arg2) throw dev::Exception();
@@ -62,7 +63,7 @@ class State;
void mine(Client& c, int numBlocks);
void connectClients(Client& c1, Client& c2);
-void mine(State& _s, BlockChain const& _bc);
+void mine(Block& _s, BlockChain const& _bc);
void mine(Ethash::BlockHeader& _bi);
}
@@ -122,11 +123,17 @@ namespace test
} \
while (0)
+enum class testType
+{
+ StateTests,
+ BlockChainTests,
+ Other
+};
+
class ImportTest
{
public:
- ImportTest(json_spirit::mObject& _o): m_environment(m_envInfo), m_testObject(_o) {}
- ImportTest(json_spirit::mObject& _o, bool isFiller);
+ ImportTest(json_spirit::mObject& _o, bool isFiller, testType testTemplate = testType::StateTests);
// imports
void importEnv(json_spirit::mObject& _o);
@@ -135,14 +142,16 @@ public:
void importTransaction(json_spirit::mObject& _o);
static json_spirit::mObject& makeAllFieldsHex(json_spirit::mObject& _o);
- void exportTest(bytes const& _output, eth::State const& _statePost);
- static void checkExpectedState(eth::State const& _stateExpect, eth::State const& _statePost, stateOptionsMap const _expectedStateOptions = stateOptionsMap(), WhenError _throw = WhenError::Throw);
+ bytes executeTest();
+ void exportTest(bytes const& _output);
+ static void compareStates(eth::State const& _stateExpect, eth::State const& _statePost, eth::AccountMaskMap const _expectedStateOptions = eth::AccountMaskMap(), WhenError _throw = WhenError::Throw);
eth::State m_statePre;
eth::State m_statePost;
eth::EnvInfo m_envInfo;
- eth::ExtVMFace m_environment;
- eth::Transaction m_transaction;
+ eth::Transaction m_transaction;
+ eth::LogEntries m_logs;
+ eth::LogEntries m_logsExpected;
private:
json_spirit::mObject& m_testObject;
@@ -196,7 +205,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin);
void doBlockchainTests(json_spirit::mValue& _v, bool _fillin);
void doRlpTests(json_spirit::mValue& v, bool _fillin);
-template<typename mapType>
+/*template<typename mapType>
void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs)
{
for (auto& resultPair : _resultAddrs)
@@ -207,7 +216,7 @@ void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs)
TBOOST_ERROR("Missing result address " << resultAddr);
}
TBOOST_CHECK((_expectedAddrs == _resultAddrs));
-}
+}*/
class Options
{
diff --git a/TestUtils.cpp b/TestUtils.cpp
index bd603a61..053ffa21 100644
--- a/TestUtils.cpp
+++ b/TestUtils.cpp
@@ -101,7 +101,9 @@ void ClientBaseFixture::enumerateClients(std::function<void(Json::Value const&,
{
enumerateBlockchains([&callback](Json::Value const& _json, BlockChain const& _bc, State _state) -> void
{
- FixedClient client(_bc, _state);
+ cerr << "void ClientBaseFixture::enumerateClients. FixedClient now accepts block not sate!" << endl;
+ _state.commit(); //unused variable. remove this line
+ FixedClient client(_bc, eth::Block {});
callback(_json, client);
});
}
diff --git a/contracts/Wallet.cpp b/contracts/Wallet.cpp
index 3c88afd9..5f9febd4 100644
--- a/contracts/Wallet.cpp
+++ b/contracts/Wallet.cpp
@@ -545,7 +545,7 @@ BOOST_AUTO_TEST_CASE(multisig_value_transfer)
// 4 owners, set required to 3
BOOST_REQUIRE(callContractFunction("changeRequirement(uint256)", u256(3)) == encodeArgs());
// check that balance is and stays zero at destination address
- h256 opHash("8f27f478ebcfaf28b0c354f4809ace8087000d668b89c8bc3b1b608bfdbe6654");
+ h256 opHash("6244b4fa93f73e09db0ae52750095ca0364a76b72bc01723c97011fcb876cc9e");
BOOST_CHECK_EQUAL(m_state.balance(Address(0x05)), 0);
m_sender = Address(0x12);
BOOST_REQUIRE(callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00) == encodeArgs(opHash));
@@ -596,7 +596,7 @@ BOOST_AUTO_TEST_CASE(revoke_transaction)
BOOST_REQUIRE(callContractFunction("changeRequirement(uint256)", u256(3)) == encodeArgs());
// create a transaction
Address deployer = m_sender;
- h256 opHash("8f27f478ebcfaf28b0c354f4809ace8087000d668b89c8bc3b1b608bfdbe6654");
+ h256 opHash("6244b4fa93f73e09db0ae52750095ca0364a76b72bc01723c97011fcb876cc9e");
BOOST_CHECK_EQUAL(m_state.balance(Address(0x05)), 0);
m_sender = Address(0x12);
BOOST_REQUIRE(callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00) == encodeArgs(opHash));
diff --git a/libsolidity/SolidityEndToEndTest.cpp b/libsolidity/SolidityEndToEndTest.cpp
index a10b4767..fdffed1e 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)
@@ -5099,31 +5103,6 @@ BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0)));
}
-BOOST_AUTO_TEST_CASE(string_bytes_conversion)
-{
- char const* sourceCode = R"(
- contract Test {
- string s;
- bytes b;
- function f(string _s, uint n) returns (byte) {
- b = bytes(_s);
- s = string(b);
- return bytes(s)[n];
- }
- function l() returns (uint) { return bytes(s).length; }
- }
- )";
- compileAndRun(sourceCode, 0, "Test");
- BOOST_CHECK(callContractFunction(
- "f(string,uint256)",
- u256(0x40),
- u256(2),
- u256(6),
- string("abcdef")
- ) == encodeArgs("c"));
- BOOST_CHECK(callContractFunction("l()") == encodeArgs(u256(6)));
-}
-
BOOST_AUTO_TEST_CASE(string_as_mapping_key)
{
char const* sourceCode = R"(
diff --git a/libsolidity/SolidityNameAndTypeResolution.cpp b/libsolidity/SolidityNameAndTypeResolution.cpp
index 6b116f25..cfc43df9 100644
--- a/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -2149,23 +2149,6 @@ BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
-BOOST_AUTO_TEST_CASE(string_bytes_conversion)
-{
- char const* text = R"(
- contract Test {
- string s;
- bytes b;
- function h(string _s) external { bytes(_s).length; }
- function i(string _s) internal { bytes(_s).length; }
- function j() internal { bytes(s).length; }
- function k(bytes _b) external { string(_b); }
- function l(bytes _b) internal { string(_b); }
- function m() internal { string(b); }
- }
- )";
- BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
-}
-
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/libsolidity/solidityExecutionFramework.h b/libsolidity/solidityExecutionFramework.h
index 58099235..c6686883 100644
--- a/libsolidity/solidityExecutionFramework.h
+++ b/libsolidity/solidityExecutionFramework.h
@@ -44,7 +44,6 @@ public:
ExecutionFramework()
{
g_logVerbosity = 0;
- m_state.resetCurrent();
}
bytes const& compileAndRunWithoutCheck(
@@ -185,7 +184,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::EnvInfo(), 0);
+ eth::Executive executive(m_state, m_envInfo, 0);
eth::ExecutionResult res;
executive.setResultRecipient(res);
eth::Transaction t =
@@ -226,6 +225,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;