23 #include <boost/filesystem.hpp> 36 FakeExtVM::FakeExtVM(
EnvInfo const& _envInfo,
unsigned _depth):
85 assert(_o.count(
"currentGasLimit") > 0);
86 assert(_o.count(
"currentDifficulty") > 0);
87 assert(_o.count(
"currentTimestamp") > 0);
88 assert(_o.count(
"currentCoinbase") > 0);
89 assert(_o.count(
"currentNumber") > 0);
90 auto gasLimit =
toInt(_o[
"currentGasLimit"]);
113 for (
auto const& s: get<2>(
a.second))
115 o[
"storage"] =
store;
125 for (
auto const& i: _object)
127 mObject o = i.second.get_obj();
129 assert(o.count(
"balance") > 0);
130 assert(o.count(
"nonce") > 0);
131 assert(o.count(
"storage") > 0);
132 assert(o.count(
"code") > 0);
135 get<0>(
a) =
toInt(o[
"balance"]);
136 get<1>(
a) =
toInt(o[
"nonce"]);
137 for (
auto const& j: o[
"storage"].get_obj())
161 assert(_o.count(
"address")> 0);
162 assert(_o.count(
"caller") > 0);
163 assert(_o.count(
"origin") > 0);
164 assert(_o.count(
"value") > 0);
165 assert(_o.count(
"data") > 0);
166 assert(_o.count(
"gasPrice") > 0);
167 assert(_o.count(
"gas") > 0);
196 o[
"destination"] = tx.isCreation() ?
"" :
toString(tx.receiveAddress());
207 for (
mValue& v: _callcreates)
209 auto tx = v.get_obj();
210 assert(tx.count(
"data") > 0);
211 assert(tx.count(
"value") > 0);
212 assert(tx.count(
"destination") > 0);
213 assert(tx.count(
"gasLimit") > 0);
214 Transaction t = tx[
"destination"].get_str().empty() ?
229 std::ostringstream o;
230 o << std::endl <<
" STACK" << std::endl;
231 for (
auto i: vm.
stack())
232 o << (
h256)i << std::endl;
234 o <<
" STORAGE" << std::endl;
237 o << std::showbase << std::hex << i.first <<
": " << i.second << std::endl;
249 for (
auto i: vm.
stack())
250 a_stack.push_back((
string)i);
252 o_step.push_back(
Pair(
"stack", a_stack ));
259 o_step.push_back(
Pair(
"memory", a_mem));
264 storage.push_back(
Pair( (
string)i.first , (
string)i.second));
267 o_step.push_back(
Pair(
"storage", storage));
268 o_step.push_back(
Pair(
"depth", to_string(ext.
depth)));
269 o_step.push_back(
Pair(
"gas", (
string)gas));
271 o_step.push_back(
Pair(
"step", steps ));
272 o_step.push_back(
Pair(
"pc", pc));
277 ofstream os(
"./stackTrace.json", ofstream::app);
284 namespace dev {
namespace test {
288 if (
string(boost::unit_test::framework::current_test_case().p_name) !=
"vmRandom")
293 string testname = i.first;
299 BOOST_REQUIRE_MESSAGE(o.count(
"env") > 0, testname +
"env not set!");
300 BOOST_REQUIRE_MESSAGE(o.count(
"pre") > 0, testname +
"pre not set!");
301 BOOST_REQUIRE_MESSAGE(o.count(
"exec") > 0, testname +
"exec not set!");
311 if (fev.
code.empty())
319 bool vmExceptionOccured =
false;
326 auto gas =
static_cast<int64_t
>(fev.
gas);
327 output = vm->exec(fev.
gas, fev, vmtrace);
328 gas -=
static_cast<int64_t
>(fev.
gas);
329 guard.setGasUsed(
gas);
334 cnote <<
" Safe VM Exception\n";
335 vmExceptionOccured =
true;
339 cnote <<
"VM did throw an exception: " << diagnostic_information(_e);
340 BOOST_ERROR(
"Failed VM Test with Exception: " << _e.
what());
342 catch (std::exception
const& _e)
344 cnote <<
"VM did throw an exception: " << _e.what();
345 BOOST_ERROR(
"Failed VM Test with Exception: " << _e.what());
352 vector<u256> keystoDelete;
353 for (
auto &s: get<2>(
a.second))
356 keystoDelete.push_back(s.first);
358 for (
auto const key: keystoDelete )
360 get<2>(
a.second).erase(key);
368 if (!vmExceptionOccured)
372 if (o.count(
"expect") > 0)
374 State postState(State::Null);
375 State expectState(State::Null);
380 o.erase(o.find(
"expect"));
387 if (o.count(
"expectOut") > 0)
389 std::string warning =
"Check State: Error! Unexpected output: " + o[
"out"].
get_str() +
" Expected: " + o[
"expectOut"].
get_str();
391 BOOST_CHECK_MESSAGE(o[
"out"].
get_str() == o[
"expectOut"].
get_str(), warning);
393 BOOST_WARN_MESSAGE(o[
"out"].
get_str() == o[
"expectOut"].
get_str(), warning);
395 o.erase(o.find(
"expectOut"));
404 if (o.count(
"post") > 0)
408 BOOST_REQUIRE(o.count(
"post") > 0);
409 BOOST_REQUIRE(o.count(
"callcreates") > 0);
410 BOOST_REQUIRE(o.count(
"out") > 0);
411 BOOST_REQUIRE(o.count(
"gas") > 0);
412 BOOST_REQUIRE(o.count(
"logs") > 0);
415 test.importState(o[
"post"].get_obj());
416 test.importCallCreates(o[
"callcreates"].get_array());
424 State postState(State::Null);
425 State expectState(State::Null);
447 BOOST_AUTO_TEST_SUITE(VMTests)
522 testPath +=
"/VMTests/RandomTests";
524 vector<boost::filesystem::path> testFiles;
525 boost::filesystem::directory_iterator iterator(testPath);
526 for(; iterator != boost::filesystem::directory_iterator(); ++iterator)
527 if (boost::filesystem::is_regular_file(iterator->path()) && iterator->path().extension() ==
".json")
528 testFiles.push_back(iterator->path());
533 for (
auto& path: testFiles)
537 cnote <<
"TEST " << path.filename();
540 BOOST_REQUIRE_MESSAGE(s.length() > 0,
"Content of " + path.string() +
" is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?");
547 BOOST_ERROR(
"Failed test with Exception: " << diagnostic_information(_e));
549 catch (std::exception
const& _e)
551 BOOST_ERROR(
"Failed test with Exception: " << _e.what());
const Object & get_obj() const
std::string toCompactHex(u256 val, HexPrefix prefix=HexPrefix::DontAdd, unsigned _min=0)
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
bytes importData(json_spirit::mObject const &_o)
static Options const & get(int argc=0, char **argv=0)
Get reference to options The first time used, options are parsed with argc, argv. ...
static dev::eth::EnvInfo importEnv(json_spirit::mObject &_o)
virtual u256 store(u256 _n) override
Read storage location.
h160 right160(h256 const &_t)
Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.
void checkOutput(bytesConstRef _output, json_spirit::mObject &_o)
static const int verbosity
boost::multiprecision::number< boost::multiprecision::cpp_int_backend<>> bigint
u256 value
Value (in Wei) that was passed to this address.
const char * what() const noexceptoverride
h160 Address
An Ethereum address: 20 bytes.
EnvInfo const & envInfo() const
Get the execution environment information.
std::hash for asio::adress
json_spirit::mObject exportExec()
assert(len-trim+(2 *lenIndices)<=WIDTH)
void importState(json_spirit::mObject &_object)
void setGasLimit(int64_t _v)
static std::unique_ptr< VMFace > create()
Creates a VM instance of global kind (controlled by setKind() function).
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
h256 codeHash
SHA3 hash of the executing code.
u256 const & number() const
Model of an Ethereum state, essentially a facade for the trie.
Config::Object_type Object
mConfig::Value_type mValue
std::vector< mutable_value_type > toVector() const
InstructionInfo instructionInfo(Instruction _inst)
Information on all the instructions.
void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs)
static int compareStates(eth::State const &_stateExpect, eth::State const &_statePost, eth::AccountMaskMap const _expectedStateOptions=eth::AccountMaskMap(), WhenError _throw=WhenError::Throw)
bool vmtrace
Create EVM execution tracer.
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
bool read_string(const String_type &s, Value_type &value)
void importCallCreates(json_spirit::mArray &_callcreates)
json_spirit::mObject exportEnv()
static void importState(json_spirit::mObject const &_o, eth::State &_state)
Base class for all exceptions.
Address caller
Address which sent the message (either equal to origin or a contract).
void userDefinedTest(std::function< void(json_spirit::mValue &, bool)> doTests)
mConfig::Array_type mArray
std::string name
The name of the instruction.
static void setMaxTests(int _count)
json_spirit::mObject exportState()
std::map< Address, std::tuple< u256, u256, std::map< u256, u256 >, bytes > > addresses
virtual boost::optional< eth::owning_bytes_ref > call(eth::CallParameters &) override
Make a new message call.
Test started/finished notification RAII helper.
json_spirit::mArray exportLog(eth::LogEntries _logs)
void setLastHashes(LastHashes &&_lh)
void setTimestamp(u256 const &_v)
std::vector< byte > bytes
std::string getTestPath()
std::vector< unsigned char > toBytes() const
bytes const & memory() const
Fixed-size raw-byte array container type, with an API optimised for storing hashes.
std::function< void(uint64_t, uint64_t, Instruction, bigint, bigint, bigint, VM *, ExtVMFace const *)> OnOpFunc
unsigned depth
Depth of the present call.
static void notifySuiteStarted(std::string const &_name)
void setNumber(u256 const &_v)
const String_type & get_str() const
eth::Transactions callcreates
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
bytes importCode(json_spirit::mObject &_o)
Encodes a transaction, ready to be exported to or freshly imported from RLP.
eth::OnOpFunc simpleTrace() const
std::unordered_map< Address, AccountMask > AccountMaskMap
Instruction
Virtual machine bytecode instruction.
mConfig::Object_type mObject
bytes rlpList()
Export a list of items in RLP format, returning a byte array.
int g_logVerbosity
The logging system's current verbosity.
u256 gasPrice
Price of gas (that we already paid).
void doVMTests(json_spirit::mValue &_v, bool _fillin)
Interface and null implementation of the class for specifying VM externalities.
BOOST_AUTO_TEST_CASE(rndCode)
Value_type::String_type write_string(const Value_type &value, bool pretty)
bytes code
Current code that is executing.
Address myAddress
Address associated with executing code (a contract, or contract-to-be).
Address origin
Original transactor.
PlatformStyle::TableColorType type
Reference to a slice of buffer that also owns the buffer.
#define BOOST_CHECK_EQUAL(v1, v2)
LastHashes lastHashes(u256 _currentBlockNumber)
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
#define BOOST_AUTO_TEST_SUITE_END()
void importExec(json_spirit::mObject &_o)
void setAuthor(Address const &_v)
SubState sub
Sub-band VM state (suicides, refund counter, logs).
std::string memDump(bytes const &_bytes, unsigned _width=8, bool _html=false)
Nicely renders the given bytes to a string, optionally as HTML.
void executeTests(const string &_name, const string &_testPathAppendix, const string &_fillerPathAppendix, std::function< void(json_spirit::mValue &, bool)> doTests, bool _addFillerSuffix)
json_spirit::mArray exportCallCreates()
bytesConstRef data
Current input data.
void setDifficulty(u256 const &_v)
void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates)
void reset(u256 _myBalance, u256 _myNonce, std::map< u256, u256 > const &_storage)
std::string get_str(std::string::const_iterator begin, std::string::const_iterator end)
void set(Address _a, u256 _myBalance, u256 _myNonce, std::map< u256, u256 > const &_storage, bytes const &_code)
bytes contents(std::string const &_file)
Retrieve and returns the contents of the given file.
LogEntries importLog(json_spirit::mArray &_a)
std::string asString(bytes const &_b)
Converts byte array to a string containing the same (binary) data.
u256 toInt(json_spirit::mValue const &_v)
virtual h160 create(u256 _endowment, u256 &io_gas, bytesConstRef _init, eth::OnOpFunc const &) override
Create a new (contract) account.
Logging class, iostream-like, that can be shifted to.
#define BOOST_CHECK(expr)
static void initTest(int _maxTests=1)
static bool passTest(json_spirit::mObject &_o, std::string &_testName)