mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
update test to new Block/State refactoring - credit to winsvega and chriseth
This commit is contained in:
parent
e0863fbd27
commit
4626890913
@ -25,6 +25,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <libethcore/EthashAux.h>
|
#include <libethcore/EthashAux.h>
|
||||||
#include <libethereum/Client.h>
|
#include <libethereum/Client.h>
|
||||||
|
#include <libevm/ExtVMFace.h>
|
||||||
#include <liblll/Compiler.h>
|
#include <liblll/Compiler.h>
|
||||||
#include <libevm/VMFactory.h>
|
#include <libevm/VMFactory.h>
|
||||||
#include "Stats.h"
|
#include "Stats.h"
|
||||||
@ -61,7 +62,7 @@ void connectClients(Client& c1, Client& c2)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void mine(State& s, BlockChain const& _bc)
|
void mine(Block& s, BlockChain const& _bc)
|
||||||
{
|
{
|
||||||
std::unique_ptr<SealEngineFace> sealer(Ethash::createSealEngine());
|
std::unique_ptr<SealEngineFace> sealer(Ethash::createSealEngine());
|
||||||
s.commitToSeal(_bc);
|
s.commitToSeal(_bc);
|
||||||
@ -94,21 +95,41 @@ struct MissingFields : virtual Exception {};
|
|||||||
|
|
||||||
bigint const c_max256plus1 = bigint(1) << 256;
|
bigint const c_max256plus1 = bigint(1) << 256;
|
||||||
|
|
||||||
ImportTest::ImportTest(json_spirit::mObject& _o, bool isFiller):
|
ImportTest::ImportTest(json_spirit::mObject& _o, bool isFiller, testType testTemplate):
|
||||||
m_statePre(OverlayDB(), eth::BaseState::Empty, Address(_o["env"].get_obj()["currentCoinbase"].get_str())),
|
m_statePre(OverlayDB(), eth::BaseState::Empty),
|
||||||
m_statePost(OverlayDB(), eth::BaseState::Empty, Address(_o["env"].get_obj()["currentCoinbase"].get_str())),
|
m_statePost(OverlayDB(), eth::BaseState::Empty),
|
||||||
m_environment(m_envInfo),
|
|
||||||
m_testObject(_o)
|
m_testObject(_o)
|
||||||
{
|
{
|
||||||
|
if (testTemplate == testType::StateTests)
|
||||||
|
{
|
||||||
importEnv(_o["env"].get_obj());
|
importEnv(_o["env"].get_obj());
|
||||||
importState(_o["pre"].get_obj(), m_statePre);
|
|
||||||
importTransaction(_o["transaction"].get_obj());
|
importTransaction(_o["transaction"].get_obj());
|
||||||
|
importState(_o["pre"].get_obj(), m_statePre);
|
||||||
if (!isFiller)
|
if (!isFiller)
|
||||||
{
|
{
|
||||||
|
if (_o.count("post"))
|
||||||
importState(_o["post"].get_obj(), m_statePost);
|
importState(_o["post"].get_obj(), m_statePost);
|
||||||
m_environment.sub.logs = importLog(_o["logs"].get_array());
|
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)
|
json_spirit::mObject& ImportTest::makeAllFieldsHex(json_spirit::mObject& _o)
|
||||||
@ -139,24 +160,25 @@ json_spirit::mObject& ImportTest::makeAllFieldsHex(json_spirit::mObject& _o)
|
|||||||
|
|
||||||
void ImportTest::importEnv(json_spirit::mObject& _o)
|
void ImportTest::importEnv(json_spirit::mObject& _o)
|
||||||
{
|
{
|
||||||
assert(_o.count("previousHash") > 0);
|
|
||||||
assert(_o.count("currentGasLimit") > 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("currentTimestamp") > 0);
|
||||||
assert(_o.count("currentCoinbase") > 0);
|
assert(_o.count("currentCoinbase") > 0);
|
||||||
assert(_o.count("currentNumber") > 0);
|
m_envInfo.setGasLimit(toInt(_o["currentGasLimit"]));
|
||||||
m_envInfo.setBeneficiary(Address(_o["currentCoinbase"].get_str()));
|
|
||||||
m_envInfo.setDifficulty(toInt(_o["currentDifficulty"]));
|
m_envInfo.setDifficulty(toInt(_o["currentDifficulty"]));
|
||||||
m_envInfo.setNumber(toInt(_o["currentNumber"]));
|
m_envInfo.setNumber(toInt(_o["currentNumber"]));
|
||||||
m_envInfo.setGasLimit(toInt(_o["currentGasLimit"]));
|
|
||||||
m_envInfo.setTimestamp(toInt(_o["currentTimestamp"]));
|
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
|
// 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)
|
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)
|
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) \
|
#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!");
|
CHECK(_statePost.addressInUse(a.first), "Filling Test: " << a.first << " missing expected address!");
|
||||||
if (_statePost.addressInUse(a.first))
|
if (_statePost.addressInUse(a.first))
|
||||||
{
|
{
|
||||||
ImportStateOptions addressOptions(true);
|
AccountMask addressOptions(true);
|
||||||
if(_expectedStateOptions.size())
|
if(_expectedStateOptions.size())
|
||||||
{
|
{
|
||||||
try
|
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((_stateExpect.balance(a.first) == _statePost.balance(a.first)),
|
||||||
"Check State: " << a.first << ": incorrect balance " << _statePost.balance(a.first) << ", expected " << _stateExpect.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((_stateExpect.transactionsFrom(a.first) == _statePost.transactionsFrom(a.first)),
|
||||||
"Check State: " << a.first << ": incorrect nonce " << _statePost.transactionsFrom(a.first) << ", expected " << _stateExpect.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);
|
unordered_map<u256, u256> stateStorage = _statePost.storage(a.first);
|
||||||
for (auto const& s: _stateExpect.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]));
|
"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((_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)) << "'");
|
"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
|
// export output
|
||||||
|
|
||||||
@ -292,21 +314,21 @@ void ImportTest::exportTest(bytes const& _output, State const& _statePost)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// export logs
|
// export logs
|
||||||
m_testObject["logs"] = exportLog(_statePost.pending().size() ? _statePost.log(0) : LogEntries());
|
m_testObject["logs"] = exportLog(m_logs);
|
||||||
|
|
||||||
// compare expected state with post state
|
// compare expected state with post state
|
||||||
if (m_testObject.count("expect") > 0)
|
if (m_testObject.count("expect") > 0)
|
||||||
{
|
{
|
||||||
stateOptionsMap stateMap;
|
eth::AccountMaskMap stateMap;
|
||||||
State expectState(OverlayDB(), eth::BaseState::Empty);
|
State expectState(OverlayDB(), eth::BaseState::Empty);
|
||||||
importState(m_testObject["expect"].get_obj(), expectState, stateMap);
|
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"));
|
m_testObject.erase(m_testObject.find("expect"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// export post state
|
// export post state
|
||||||
m_testObject["post"] = fillJsonWithState(_statePost);
|
m_testObject["post"] = fillJsonWithState(m_statePost);
|
||||||
m_testObject["postStateRoot"] = toHex(_statePost.rootHash().asBytes());
|
m_testObject["postStateRoot"] = toHex(m_statePost.rootHash().asBytes());
|
||||||
|
|
||||||
// export pre state
|
// export pre state
|
||||||
m_testObject["pre"] = fillJsonWithState(m_statePre);
|
m_testObject["pre"] = fillJsonWithState(m_statePre);
|
||||||
|
25
TestHelper.h
25
TestHelper.h
@ -32,6 +32,7 @@
|
|||||||
#include <libevm/ExtVMFace.h>
|
#include <libevm/ExtVMFace.h>
|
||||||
#include <libtestutils/Common.h>
|
#include <libtestutils/Common.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef NOBOOST
|
#ifdef NOBOOST
|
||||||
#define TBOOST_REQUIRE(arg) if(arg == false) throw dev::Exception();
|
#define TBOOST_REQUIRE(arg) if(arg == false) throw dev::Exception();
|
||||||
#define TBOOST_REQUIRE_EQUAL(arg1, arg2) if(arg1 != arg2) 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 mine(Client& c, int numBlocks);
|
||||||
void connectClients(Client& c1, Client& c2);
|
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);
|
void mine(Ethash::BlockHeader& _bi);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -122,11 +123,17 @@ namespace test
|
|||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
|
enum class testType
|
||||||
|
{
|
||||||
|
StateTests,
|
||||||
|
BlockChainTests,
|
||||||
|
Other
|
||||||
|
};
|
||||||
|
|
||||||
class ImportTest
|
class ImportTest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImportTest(json_spirit::mObject& _o): m_environment(m_envInfo), m_testObject(_o) {}
|
ImportTest(json_spirit::mObject& _o, bool isFiller, testType testTemplate = testType::StateTests);
|
||||||
ImportTest(json_spirit::mObject& _o, bool isFiller);
|
|
||||||
|
|
||||||
// imports
|
// imports
|
||||||
void importEnv(json_spirit::mObject& _o);
|
void importEnv(json_spirit::mObject& _o);
|
||||||
@ -135,14 +142,16 @@ public:
|
|||||||
void importTransaction(json_spirit::mObject& _o);
|
void importTransaction(json_spirit::mObject& _o);
|
||||||
static json_spirit::mObject& makeAllFieldsHex(json_spirit::mObject& _o);
|
static json_spirit::mObject& makeAllFieldsHex(json_spirit::mObject& _o);
|
||||||
|
|
||||||
void exportTest(bytes const& _output, eth::State const& _statePost);
|
bytes executeTest();
|
||||||
static void checkExpectedState(eth::State const& _stateExpect, eth::State const& _statePost, stateOptionsMap const _expectedStateOptions = stateOptionsMap(), WhenError _throw = WhenError::Throw);
|
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_statePre;
|
||||||
eth::State m_statePost;
|
eth::State m_statePost;
|
||||||
eth::EnvInfo m_envInfo;
|
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:
|
private:
|
||||||
json_spirit::mObject& m_testObject;
|
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 doBlockchainTests(json_spirit::mValue& _v, bool _fillin);
|
||||||
void doRlpTests(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)
|
void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs)
|
||||||
{
|
{
|
||||||
for (auto& resultPair : _resultAddrs)
|
for (auto& resultPair : _resultAddrs)
|
||||||
@ -207,7 +216,7 @@ void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs)
|
|||||||
TBOOST_ERROR("Missing result address " << resultAddr);
|
TBOOST_ERROR("Missing result address " << resultAddr);
|
||||||
}
|
}
|
||||||
TBOOST_CHECK((_expectedAddrs == _resultAddrs));
|
TBOOST_CHECK((_expectedAddrs == _resultAddrs));
|
||||||
}
|
}*/
|
||||||
|
|
||||||
class Options
|
class Options
|
||||||
{
|
{
|
||||||
|
@ -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
|
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);
|
callback(_json, client);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -545,7 +545,7 @@ BOOST_AUTO_TEST_CASE(multisig_value_transfer)
|
|||||||
// 4 owners, set required to 3
|
// 4 owners, set required to 3
|
||||||
BOOST_REQUIRE(callContractFunction("changeRequirement(uint256)", u256(3)) == encodeArgs());
|
BOOST_REQUIRE(callContractFunction("changeRequirement(uint256)", u256(3)) == encodeArgs());
|
||||||
// check that balance is and stays zero at destination address
|
// 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);
|
BOOST_CHECK_EQUAL(m_state.balance(Address(0x05)), 0);
|
||||||
m_sender = Address(0x12);
|
m_sender = Address(0x12);
|
||||||
BOOST_REQUIRE(callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00) == encodeArgs(opHash));
|
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());
|
BOOST_REQUIRE(callContractFunction("changeRequirement(uint256)", u256(3)) == encodeArgs());
|
||||||
// create a transaction
|
// create a transaction
|
||||||
Address deployer = m_sender;
|
Address deployer = m_sender;
|
||||||
h256 opHash("8f27f478ebcfaf28b0c354f4809ace8087000d668b89c8bc3b1b608bfdbe6654");
|
h256 opHash("6244b4fa93f73e09db0ae52750095ca0364a76b72bc01723c97011fcb876cc9e");
|
||||||
BOOST_CHECK_EQUAL(m_state.balance(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(m_state.balance(Address(0x05)), 0);
|
||||||
m_sender = Address(0x12);
|
m_sender = Address(0x12);
|
||||||
BOOST_REQUIRE(callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00) == encodeArgs(opHash));
|
BOOST_REQUIRE(callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00) == encodeArgs(opHash));
|
||||||
|
@ -1151,8 +1151,10 @@ BOOST_AUTO_TEST_CASE(blockchain)
|
|||||||
" blockNumber = block.number;\n"
|
" blockNumber = block.number;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
m_envInfo.setBeneficiary(Address(0x123));
|
||||||
|
m_envInfo.setNumber(7);
|
||||||
compileAndRun(sourceCode, 27);
|
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)
|
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)
|
BOOST_AUTO_TEST_CASE(now)
|
||||||
{
|
{
|
||||||
char const* sourceCode = "contract test {\n"
|
char const* sourceCode = "contract test {\n"
|
||||||
" function someInfo() returns (bool success) {\n"
|
" function someInfo() returns (bool equal, uint val) {\n"
|
||||||
" return block.timestamp == now && now > 0;\n"
|
" equal = block.timestamp == now;\n"
|
||||||
|
" val = now;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
m_envInfo.setTimestamp(9);
|
||||||
compileAndRun(sourceCode);
|
compileAndRun(sourceCode);
|
||||||
BOOST_CHECK(callContractFunction("someInfo()") == encodeArgs(true));
|
BOOST_CHECK(callContractFunction("someInfo()") == encodeArgs(true, 9));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(type_conversions_cleanup)
|
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_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)
|
BOOST_AUTO_TEST_CASE(string_as_mapping_key)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
|
@ -2149,23 +2149,6 @@ BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
|
|||||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
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()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,6 @@ public:
|
|||||||
ExecutionFramework()
|
ExecutionFramework()
|
||||||
{
|
{
|
||||||
g_logVerbosity = 0;
|
g_logVerbosity = 0;
|
||||||
m_state.resetCurrent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes const& compileAndRunWithoutCheck(
|
bytes const& compileAndRunWithoutCheck(
|
||||||
@ -185,7 +184,7 @@ protected:
|
|||||||
void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0)
|
void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0)
|
||||||
{
|
{
|
||||||
m_state.addBalance(m_sender, _value); // just in case
|
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;
|
eth::ExecutionResult res;
|
||||||
executive.setResultRecipient(res);
|
executive.setResultRecipient(res);
|
||||||
eth::Transaction t =
|
eth::Transaction t =
|
||||||
@ -226,6 +225,7 @@ protected:
|
|||||||
dev::solidity::CompilerStack m_compiler;
|
dev::solidity::CompilerStack m_compiler;
|
||||||
Address m_sender;
|
Address m_sender;
|
||||||
Address m_contractAddress;
|
Address m_contractAddress;
|
||||||
|
eth::EnvInfo m_envInfo;
|
||||||
eth::State m_state;
|
eth::State m_state;
|
||||||
u256 const m_gasPrice = 100 * eth::szabo;
|
u256 const m_gasPrice = 100 * eth::szabo;
|
||||||
u256 const m_gas = 100000000;
|
u256 const m_gas = 100000000;
|
||||||
|
Loading…
Reference in New Issue
Block a user