27 #include <boost/algorithm/string/trim.hpp> 45 std::this_thread::sleep_for(std::chrono::milliseconds(100));
57 c1.startNetwork(c1Port);
58 c2.startNetwork(c2Port);
59 c2.connect(
"127.0.0.1", c1Port);
97 case eth::Network::FrontierTest:
return "Frontier";
98 case eth::Network::HomesteadTest:
return "Homestead";
99 case eth::Network::EIP150Test:
return "EIP150";
100 case eth::Network::EIP158Test:
return "EIP158";
101 case eth::Network::MetropolisTest:
return "Metropolis";
102 default:
return "other";
110 return eth::Network::FrontierTest;
112 return eth::Network::HomesteadTest;
114 return eth::Network::EIP150Test;
116 return eth::Network::EIP158Test;
118 return eth::Network::MetropolisTest;
119 BOOST_ERROR(TestOutputHelper::testName() +
" network not found: " + _netname);
120 return eth::Network::FrontierTest;
147 bool mapEmpty = (_map.size() == 0);
151 if (_map.size() && _map.find(
a.first) == _map.end())
155 if (mapEmpty || _map.at(
a.first).hasBalance())
157 if (mapEmpty || _map.at(
a.first).hasNonce())
160 if (mapEmpty || _map.at(
a.first).hasStorage())
163 for (
auto const& s: _state.
storage(
a.first))
165 o[
"storage"] = store;
169 if (mapEmpty || _map.at(
a.first).hasCode())
179 if (_logs.size() == 0)
return ret;
185 for (
auto const& t: l.topics)
187 o[
"topics"] = topics;
203 default:
cwarn <<
"Bad type for scalar: " << _v.
type();
216 default:
cwarn <<
"Bad type for scalar: " << _v.
type();
223 return fromHex(_str.substr(0, 2) ==
"0x" ? _str.substr(2) : _str, WhenError::Throw);
232 for (
auto const& j: _o.at(
"data").get_array())
233 data.push_back(
toByte(j));
239 for (
auto& account: _o.count(
"alloc") ? _o[
"alloc"].get_obj() : _o.count(
"accounts") ? _o[
"accounts"].get_obj() : _o)
241 auto obj = account.second.get_obj();
244 string code = obj[
"code"].get_str();
247 account.second = obj;
255 if (_code.substr(0,2) ==
"0x" && _code.size() >= 2)
259 BOOST_ERROR(
"LLL compilation only supported on posix systems.");
263 boost::filesystem::path path(boost::filesystem::temp_directory_path() / boost::filesystem::unique_path());
264 string cmd = string(
"lllc ") + path.string();
267 FILE *fp = popen(cmd.c_str(),
"r");
269 BOOST_ERROR(
"Failed to run lllc");
270 if (fgets(input,
sizeof(input) - 1, fp) == NULL)
271 BOOST_ERROR(
"Reading empty file for lllc");
274 boost::filesystem::remove(path);
275 string result(input);
276 result =
"0x" + boost::trim_copy(result);
285 if (_o[
"code"].
get_str().find(
"0x") != 0)
292 for (
auto const& j: _o[
"code"].get_array())
293 code.push_back(
toByte(j));
301 for (
auto const& l: _a)
304 BOOST_REQUIRE(o.count(
"address") > 0);
305 BOOST_REQUIRE(o.count(
"topics") > 0);
306 BOOST_REQUIRE(o.count(
"data") > 0);
307 BOOST_REQUIRE(o.count(
"bloom") > 0);
310 for (
auto const& t: o[
"topics"].get_array())
311 log.topics.push_back(
h256(t.get_str()));
313 logEntries.push_back(log);
321 auto expectedOutput = _o[
"out"].get_str();
323 if (expectedOutput.find(
"#") == 0)
326 for (
auto const&
d: _o[
"out"].get_array())
328 BOOST_CHECK_MESSAGE(_output[j] ==
toInt(
d),
"Output byte [" << j <<
"] different!");
331 else if (expectedOutput.find(
"0x") == 0)
339 _expectedAddr = _expectedAddr;
340 for (
auto&& expectedStorePair : _expectedStore)
342 auto& expectedStoreKey = expectedStorePair.first;
343 auto resultStoreIt = _resultStore.find(expectedStoreKey);
344 if (resultStoreIt == _resultStore.end())
345 BOOST_ERROR(_expectedAddr <<
": missing store key " << expectedStoreKey);
348 auto& expectedStoreValue = expectedStorePair.second;
349 auto& resultStoreValue = resultStoreIt->second;
350 BOOST_CHECK_MESSAGE(expectedStoreValue == resultStoreValue, _expectedAddr <<
": store[" << expectedStoreKey <<
"] = " << resultStoreValue <<
", expected " << expectedStoreValue);
354 for (
auto&& resultStorePair: _resultStore)
356 if (!_expectedStore.count(resultStorePair.first))
357 BOOST_ERROR(_expectedAddr <<
": unexpected store key " << resultStorePair.first);
363 BOOST_REQUIRE_EQUAL(_resultLogs.size(), _expectedLogs.size());
365 for (
size_t i = 0; i < _resultLogs.size(); ++i)
375 BOOST_REQUIRE_EQUAL(_resultCallCreates.size(), _expectedCallCreates.size());
377 for (
size_t i = 0; i < _resultCallCreates.size(); ++i)
380 BOOST_CHECK(_resultCallCreates[i].receiveAddress() == _expectedCallCreates[i].receiveAddress());
381 BOOST_CHECK(_resultCallCreates[i].gas() == _expectedCallCreates[i].gas());
382 BOOST_CHECK(_resultCallCreates[i].value() == _expectedCallCreates[i].value());
388 if (!Options::get().singleTest)
391 if (Options::get().singleTestFile.empty() || Options::get().singleTestName.empty())
393 cnote <<
"Missing user test specification\nUsage: testeth --singletest <filename> <testname>\n";
397 auto& filename = Options::get().singleTestFile;
398 auto& testname = Options::get().singleTestName;
405 cnote <<
"Testing user defined test: " << filename;
408 BOOST_REQUIRE_MESSAGE(s.length() > 0,
"Contents of " + filename +
" is empty. ");
412 json_spirit::mObject::const_iterator pos = v.
get_obj().find(testname);
415 cnote <<
"Could not find test: " << testname <<
" in " << filename <<
"\n";
419 oSingleTest[pos->first] = pos->second;
422 doTests(v_singleTest, test::Options::get().filltests);
426 BOOST_ERROR(
"Failed Test with Exception: " << diagnostic_information(_e));
428 catch (std::exception
const& _e)
430 BOOST_ERROR(
"Failed Test with Exception: " << _e.what());
436 string testPath =
getTestPath() + _testPathAppendix;
437 string testFillerPath =
getTestPath() +
"/src/" + _fillerPathAppendix;
439 if (Options::get().stats)
440 Listener::registerListener(Stats::get());
443 if (_name.rfind(
"Filler.json") != std::string::npos)
444 name = _name.substr(0, _name.rfind(
"Filler.json"));
446 if (Options::get().filltests)
450 cnote <<
"Populating tests...";
452 boost::filesystem::path p(__FILE__);
454 string nameEnding = _addFillerSuffix ?
"Filler.json" :
".json";
455 string testfilename = testFillerPath +
"/" + name + nameEnding;
457 BOOST_REQUIRE_MESSAGE(s.length() > 0,
"Contents of " + testfilename +
" is empty.");
465 BOOST_ERROR(TestOutputHelper::testName() +
"Failed filling test with Exception: " << diagnostic_information(_e));
467 catch (std::exception
const& _e)
469 BOOST_ERROR(TestOutputHelper::testName() +
"Failed filling test with Exception: " << _e.what());
474 cnote <<
"TEST " << name <<
":";
477 BOOST_REQUIRE_MESSAGE(s.length() > 0,
"Contents of " + testPath +
"/" + name +
".json is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?");
479 Listener::notifySuiteStarted(name);
484 BOOST_ERROR(TestOutputHelper::testName() +
"Failed test with Exception: " << diagnostic_information(_e));
486 catch (std::exception
const& _e)
488 BOOST_ERROR(TestOutputHelper::testName() +
"Failed test with Exception: " << _e.what());
492 void copyFile(std::string
const& _source, std::string
const& _destination)
494 std::ifstream src(_source, std::ios::binary);
495 std::ofstream dst(_destination, std::ios::binary);
505 if (_tObj.count(
"nonce"))
506 rlpStream <<
bigint(_tObj.at(
"nonce").get_str());
508 if (_tObj.count(
"gasPrice"))
509 rlpStream <<
bigint(_tObj.at(
"gasPrice").get_str());
511 if (_tObj.count(
"gasLimit"))
512 rlpStream <<
bigint(_tObj.at(
"gasLimit").get_str());
514 if (_tObj.count(
"to"))
516 if (_tObj.at(
"to").get_str().empty())
522 if (_tObj.count(
"value"))
523 rlpStream <<
bigint(_tObj.at(
"value").get_str());
525 if (_tObj.count(
"data"))
528 if (_tObj.count(
"v"))
529 rlpStream <<
bigint(_tObj.at(
"v").get_str());
531 if (_tObj.count(
"r"))
532 rlpStream <<
bigint(_tObj.at(
"r").get_str());
534 if (_tObj.count(
"s"))
535 rlpStream <<
bigint(_tObj.at(
"s").get_str());
537 if (_tObj.count(
"extrafield"))
538 rlpStream <<
bigint(_tObj.at(
"extrafield").get_str());
547 for (
u256 i = 1; i <= 256 && i <= _currentBlockNumber; ++i)
553 h256 const& _parentHash,
554 h256 const& _sha3Uncles,
556 h256 const& _stateRoot,
557 h256 const& _transactionsRoot,
558 h256 const& _receiptsRoot,
560 u256 const& _difficulty,
562 u256 const& _gasLimit,
563 u256 const& _gasUsed,
564 u256 const& _timestamp,
565 bytes const& _extraData)
570 rlpStream << _parentHash << _sha3Uncles << _author << _stateRoot << _transactionsRoot << _receiptsRoot << _logBloom
571 << _difficulty << _number << _gasLimit << _gasUsed << _timestamp << _extraData <<
h256{} <<
Nonce{};
578 Ethash::setNonce(_header, _nonce);
579 Ethash::setMixHash(_header, _mixHash);
587 void Listener::registerListener(
Listener& _listener)
589 g_listener = &_listener;
592 void Listener::notifySuiteStarted(std::string
const& _name)
598 void Listener::notifyTestStarted(std::string
const& _name)
601 g_listener->testStarted(_name);
604 void Listener::notifyTestFinished(int64_t _gasUsed)
607 g_listener->testFinished(_gasUsed);
const Object & get_obj() const
u256 balance(Address const &_id) const
Get an account's balance.
std::string toCompactHex(u256 val, HexPrefix prefix=HexPrefix::DontAdd, unsigned _min=0)
void stopSealing() override
Stop sealing.
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)
#define function(a, b, c, d, k, s)
A modifiable reference to an existing object or vector in memory.
string netIdToString(eth::Network _netId)
BlockDetails details(h256 const &_hash) const
Get the familial details concerning a block (or the most recent mined if none given). Thread-safe.
bytes importData(json_spirit::mObject const &_o)
Allows observing test execution process.
Implements the blockchain database.
Fixture class for boost output when running testeth.
void checkOutput(bytesConstRef _output, json_spirit::mObject &_o)
void writeFile(std::string const &_file, bytesConstRef _data, bool _writeDeleteRename=false)
Write the given binary data into the given file, replacing the file if it pre-exists.
boost::multiprecision::number< boost::multiprecision::cpp_int_backend<>> bigint
bytes const & out() const
Read the byte stream.
virtual void generateSeal(BlockHeader const &_bi)=0
h160 Address
An Ethereum address: 20 bytes.
std::vector< Transaction > Transactions
Nice name for vector of Transaction.
boost::uint64_t get_uint64() const
void connectClients(Client &c1, Client &c2)
void commitToSeal(BlockChain const &_bc, bytes const &_extraData={})
Prepares the current state for mining.
std::hash for asio::adress
std::string contentsString(std::string const &_file)
Retrieve and returns the contents of the given file as a std::string.
int Add(word *C, const word *A, const word *B, size_t N)
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
json_spirit::mObject fillJsonWithState(State const &_state, eth::AccountMaskMap const &_map)
Model of an Ethereum state, essentially a facade for the trie.
bool contentsEqual(std::vector< mutable_value_type > const &_c) const
Class for handling testeth custom options.
SignatureStruct const & signature() const
json_spirit::mObject fillJsonWithTransaction(Transaction const &_txn)
void updateEthashSeal(dev::eth::BlockHeader &_header, h256 const &_mixHash, h64 const &_nonce)
void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs)
Active model of a block within the block chain.
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
std::vector< h256 > LastHashes
bool read_string(const String_type &s, Value_type &value)
Base class for all exceptions.
void userDefinedTest(std::function< void(json_spirit::mValue &, bool)> doTests)
mConfig::Array_type mArray
dev::eth::BlockHeader constructHeader(h256 const &_parentHash, h256 const &_sha3Uncles, Address const &_author, h256 const &_stateRoot, h256 const &_transactionsRoot, h256 const &_receiptsRoot, dev::eth::LogBloom const &_logBloom, u256 const &_difficulty, u256 const &_number, u256 const &_gasLimit, u256 const &_gasUsed, u256 const &_timestamp, bytes const &_extraData)
BlockChain const & blockChain() const
Get the object representing the current canonical blockchain.
byte toByte(json_spirit::mValue const &_v)
RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject const &_tObj)
virtual void onSealGenerated(std::function< void(bytes const &s)> const &_f)=0
json_spirit::mArray exportLog(eth::LogEntries _logs)
std::vector< byte > bytes
std::string getTestPath()
u256 storage(Address const &_contract, u256 const &_memory) const
Get the value of a storage position of an account.
u256 getNonce(Address const &_addr) const
Get the account nonce – the number of transactions it has sent.
Fixed-size raw-byte array container type, with an API optimised for storing hashes.
RLPStream & appendList(size_t _items)
Appends a list.
Main API hub for interfacing with Ethereum.
bytes const & data() const
std::unordered_map< Address, u256 > addresses() const
bytes asBytes(std::string const &_b)
Converts a string to a byte array containing the string's (byte) data.
bytes const & code(Address const &_addr) const
Get the code of an account.
const String_type & get_str() const
void checkStorage(map< u256, u256 > _expectedStore, map< u256, u256 > _resultStore, Address _expectedAddr)
bool sealBlock(bytes const &_header)
Pass in a properly sealed header matching this block.
void waitNot(N const &_v) const
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)
void copyFile(std::string const &_source, std::string const &_destination)
Encodes a transaction, ready to be exported to or freshly imported from RLP.
Temporary changes system's verbosity for specific function.
std::unordered_map< Address, AccountMask > AccountMaskMap
mConfig::Object_type mObject
int g_logVerbosity
The logging system's current verbosity.
void replaceLLLinState(json_spirit::mObject &_o)
Value_type::String_type write_string(const Value_type &value, bool pretty)
PlatformStyle::TableColorType type
#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.
string compileLLL(string const &_code)
void mine(BlockHeader &_bi, SealEngineFace *_sealer, bool _verify)
void executeTests(const string &_name, const string &_testPathAppendix, const string &_fillerPathAppendix, std::function< void(json_spirit::mValue &, bool)> doTests, bool _addFillerSuffix)
struct evm_uint160be address(struct evm_env *env)
bytes importByteArray(std::string const &_str)
void startSealing() override
Start sealing.
void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates)
virtual void suiteStarted(std::string const &)
std::string get_str(std::string::const_iterator begin, std::string::const_iterator end)
Class for writing to an RLP bytestream.
bytes contents(std::string const &_file)
Retrieve and returns the contents of the given file.
eth::Network stringToNetId(string const &_netname)
LogEntries importLog(json_spirit::mArray &_a)
std::string asString(bytes const &_b)
Converts byte array to a string containing the same (binary) data.
virtual void verify(Strictness _s, BlockHeader const &_bi, BlockHeader const &_parent=BlockHeader(), bytesConstRef _block=bytesConstRef()) const
Don't forget to call Super::verify when subclassing & overriding.
u256 toInt(json_spirit::mValue const &_v)
BlockHeader const & info() const
Get the header information on the present block.
std::vector< LogEntry > LogEntries
Helper functions to work with json::spirit and test files.
#define BOOST_CHECK(expr)
Address receiveAddress() const