diff options
Diffstat (limited to 'test/TestHelper.cpp')
-rw-r--r-- | test/TestHelper.cpp | 833 |
1 files changed, 0 insertions, 833 deletions
diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index e7633c5e..79242f83 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -21,846 +21,13 @@ #include "TestHelper.h" -#include <thread> -#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" - using namespace std; -using namespace dev::eth; namespace dev { -namespace eth -{ - -void mine(Client& c, int numBlocks) -{ - auto startBlock = c.blockChain().details().number; - - c.startMining(); - while(c.blockChain().details().number < startBlock + numBlocks) - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - c.stopMining(); -} - -void connectClients(Client& c1, Client& c2) -{ - (void)c1; - (void)c2; - // TODO: Move to WebThree. eth::Client no longer handles networking. -#if 0 - short c1Port = 20000; - short c2Port = 21000; - c1.startNetwork(c1Port); - c2.startNetwork(c2Port); - c2.connect("127.0.0.1", c1Port); -#endif -} - -void mine(Block& s, BlockChain const& _bc) -{ - std::unique_ptr<SealEngineFace> sealer(Ethash::createSealEngine()); - s.commitToSeal(_bc); - Notified<bytes> sealed; - sealer->onSealGenerated([&](bytes const& sealedHeader){ sealed = sealedHeader; }); - sealer->generateSeal(s.info()); - sealed.waitNot({}); - sealer.reset(); - s.sealBlock(sealed); -} - -void mine(Ethash::BlockHeader& _bi) -{ - std::unique_ptr<SealEngineFace> sealer(Ethash::createSealEngine()); - Notified<bytes> sealed; - sealer->onSealGenerated([&](bytes const& sealedHeader){ sealed = sealedHeader; }); - sealer->generateSeal(_bi); - sealed.waitNot({}); - sealer.reset(); - _bi = Ethash::BlockHeader(sealed, CheckNothing, h256{}, HeaderData); -} - -} - namespace test { -struct ValueTooLarge: virtual Exception {}; -struct MissingFields : virtual Exception {}; - -bigint const c_max256plus1 = bigint(1) << 256; - -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) -{ - if (testTemplate == testType::StateTests) - { - 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; - try - { - std::pair<ExecutionResult, TransactionReceipt> execOut = m_statePre.execute(m_envInfo, m_transaction); - res = execOut.first; - m_logs = execOut.second.log(); - } - catch (Exception const& _e) - { - cnote << "Exception: " << diagnostic_information(_e); - } - catch (std::exception const& _e) - { - cnote << "state execution exception: " << _e.what(); - } - - 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", - "stateRoot", "transactionsTrie", "uncleHash", "currentCoinbase", - "previousHash", "to", "address", "caller", "origin", "secretKey", "data"}; - - for (auto& i: _o) - { - std::string key = i.first; - if (hashes.count(key)) - continue; - - std::string str; - json_spirit::mValue value = i.second; - - if (value.type() == json_spirit::int_type) - str = toString(value.get_int()); - else if (value.type() == json_spirit::str_type) - str = value.get_str(); - else continue; - - _o[key] = (str.substr(0, 2) == "0x") ? str : toCompactHex(toInt(str), HexPrefix::Add, 1); - } - return _o; -} - -void ImportTest::importEnv(json_spirit::mObject& _o) -{ - assert(_o.count("currentGasLimit") > 0); - assert(_o.count("currentDifficulty") > 0); - assert(_o.count("currentNumber") > 0); - assert(_o.count("currentTimestamp") > 0); - assert(_o.count("currentCoinbase") > 0); - m_envInfo.setGasLimit(toInt(_o["currentGasLimit"])); - m_envInfo.setDifficulty(toInt(_o["currentDifficulty"])); - m_envInfo.setNumber(toInt(_o["currentNumber"])); - 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) -{ - 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) -{ - AccountMaskMap mask; - importState(_o, _state, mask); - for (auto const& i: mask) - //check that every parameter was declared in state object - if (!i.second.allSet()) - BOOST_THROW_EXCEPTION(MissingFields() << errinfo_comment("Import State: Missing state fields!")); -} - -void ImportTest::importTransaction (json_spirit::mObject const& _o, eth::Transaction& o_tr) -{ - if (_o.count("secretKey") > 0) - { - assert(_o.count("nonce") > 0); - assert(_o.count("gasPrice") > 0); - assert(_o.count("gasLimit") > 0); - assert(_o.count("to") > 0); - assert(_o.count("value") > 0); - assert(_o.count("data") > 0); - - if (bigint(_o.at("nonce").get_str()) >= c_max256plus1) - BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); - if (bigint(_o.at("gasPrice").get_str()) >= c_max256plus1) - BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") ); - if (bigint(_o.at("gasLimit").get_str()) >= c_max256plus1) - BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") ); - if (bigint(_o.at("value").get_str()) >= c_max256plus1) - BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'value' is equal or greater than 2**256") ); - - o_tr = _o.at("to").get_str().empty() ? - Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), importData(_o), toInt(_o.at("nonce")), Secret(_o.at("secretKey").get_str())) : - Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), Address(_o.at("to").get_str()), importData(_o), toInt(_o.at("nonce")), Secret(_o.at("secretKey").get_str())); - } - else - { - RLPStream transactionRLPStream = createRLPStreamFromTransactionFields(_o); - RLP transactionRLP(transactionRLPStream.out()); - try - { - o_tr = Transaction(transactionRLP.data(), CheckTransaction::Everything); - } - catch (InvalidSignature) - { - // create unsigned transaction - o_tr = _o.at("to").get_str().empty() ? - Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), importData(_o), toInt(_o.at("nonce"))) : - Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), Address(_o.at("to").get_str()), importData(_o), toInt(_o.at("nonce"))); - } - catch (Exception& _e) - { - cnote << "invalid transaction" << boost::diagnostic_information(_e); - } - } -} - -void ImportTest::importTransaction(json_spirit::mObject const& o_tr) -{ - importTransaction(o_tr, m_transaction); -} - -int ImportTest::compareStates(State const& _stateExpect, State const& _statePost, AccountMaskMap const _expectedStateOptions, WhenError _throw) -{ - #define CHECK(a,b) \ - { \ - if (_throw == WhenError::Throw) \ - { \ - TBOOST_CHECK_MESSAGE(a, b); \ - if (!a) \ - return 1; \ - } \ - else \ - {TBOOST_WARN_MESSAGE(a,b);} \ - } - - for (auto const& a: _stateExpect.addresses()) - { - CHECK(_statePost.addressInUse(a.first), "Check State: " << a.first << " missing expected address!"); - if (_statePost.addressInUse(a.first)) - { - AccountMask addressOptions(true); - if(_expectedStateOptions.size()) - { - try - { - addressOptions = _expectedStateOptions.at(a.first); - } - catch(std::out_of_range const&) - { - TBOOST_ERROR("expectedStateOptions map does not match expectedState in checkExpectedState!"); - break; - } - } - - 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.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.hasStorage()) - { - unordered_map<u256, u256> stateStorage = _statePost.storage(a.first); - for (auto const& s: _stateExpect.storage(a.first)) - CHECK((stateStorage[s.first] == s.second), - "Check State: " << a.first << ": incorrect storage [" << s.first << "] = " << toHex(stateStorage[s.first]) << ", expected [" << s.first << "] = " << toHex(s.second)); - - //Check for unexpected storage values - stateStorage = _stateExpect.storage(a.first); - for (auto const& s: _statePost.storage(a.first)) - CHECK((stateStorage[s.first] == s.second), - "Check State: " << a.first << ": incorrect storage [" << s.first << "] = " << toHex(s.second) << ", expected [" << s.first << "] = " << toHex(stateStorage[s.first])); - } - - 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)) << "'"); - } - } - return 0; -} - -int ImportTest::exportTest(bytes const& _output) -{ - int err = 0; - // export output - m_testObject["out"] = (_output.size() > 4096 && !Options::get().fulloutput) ? "#" + toString(_output.size()) : toHex(_output, 2, HexPrefix::Add); - - // compare expected output with post output - if (m_testObject.count("expectOut") > 0) - { - std::string warning = "Check State: Error! Unexpected output: " + m_testObject["out"].get_str() + " Expected: " + m_testObject["expectOut"].get_str(); - if (Options::get().checkState) - { - bool statement = (m_testObject["out"].get_str() == m_testObject["expectOut"].get_str()); - TBOOST_CHECK_MESSAGE(statement, warning); - if (!statement) - err = 1; - } - else - TBOOST_WARN_MESSAGE((m_testObject["out"].get_str() == m_testObject["expectOut"].get_str()), warning); - - m_testObject.erase(m_testObject.find("expectOut")); - } - - // export logs - m_testObject["logs"] = exportLog(m_logs); - - // compare expected state with post state - if (m_testObject.count("expect") > 0) - { - eth::AccountMaskMap stateMap; - State expectState(OverlayDB(), eth::BaseState::Empty); - importState(m_testObject["expect"].get_obj(), expectState, stateMap); - 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(m_statePost); - m_testObject["postStateRoot"] = toHex(m_statePost.rootHash().asBytes()); - - // export pre state - m_testObject["pre"] = fillJsonWithState(m_statePre); - m_testObject["env"] = makeAllFieldsHex(m_testObject["env"].get_obj()); - m_testObject["transaction"] = makeAllFieldsHex(m_testObject["transaction"].get_obj()); - return err; -} - -json_spirit::mObject fillJsonWithTransaction(Transaction _txn) -{ - json_spirit::mObject txObject; - txObject["nonce"] = toCompactHex(_txn.nonce(), HexPrefix::Add, 1); - txObject["data"] = toHex(_txn.data(), 2, HexPrefix::Add); - txObject["gasLimit"] = toCompactHex(_txn.gas(), HexPrefix::Add, 1); - txObject["gasPrice"] = toCompactHex(_txn.gasPrice(), HexPrefix::Add, 1); - txObject["r"] = toCompactHex(_txn.signature().r, HexPrefix::Add, 1); - txObject["s"] = toCompactHex(_txn.signature().s, HexPrefix::Add, 1); - txObject["v"] = toCompactHex(_txn.signature().v + 27, HexPrefix::Add, 1); - txObject["to"] = _txn.isCreation() ? "" : toString(_txn.receiveAddress()); - txObject["value"] = toCompactHex(_txn.value(), HexPrefix::Add, 1); - return txObject; -} - -json_spirit::mObject fillJsonWithState(State _state) -{ - json_spirit::mObject oState; - for (auto const& a: _state.addresses()) - { - json_spirit::mObject o; - o["balance"] = toCompactHex(_state.balance(a.first), HexPrefix::Add, 1); - o["nonce"] = toCompactHex(_state.transactionsFrom(a.first), HexPrefix::Add, 1); - { - json_spirit::mObject store; - for (auto const& s: _state.storage(a.first)) - store[toCompactHex(s.first, HexPrefix::Add, 1)] = toCompactHex(s.second, HexPrefix::Add, 1); - o["storage"] = store; - } - o["code"] = toHex(_state.code(a.first), 2, HexPrefix::Add); - oState[toString(a.first)] = o; - } - return oState; -} - -json_spirit::mArray exportLog(eth::LogEntries _logs) -{ - json_spirit::mArray ret; - if (_logs.size() == 0) return ret; - for (LogEntry const& l: _logs) - { - json_spirit::mObject o; - o["address"] = toString(l.address); - json_spirit::mArray topics; - for (auto const& t: l.topics) - topics.push_back(toString(t)); - o["topics"] = topics; - o["data"] = toHex(l.data, 2, HexPrefix::Add); - o["bloom"] = toString(l.bloom()); - ret.push_back(o); - } - return ret; -} - -u256 toInt(json_spirit::mValue const& _v) -{ - switch (_v.type()) - { - case json_spirit::str_type: return u256(_v.get_str()); - case json_spirit::int_type: return (u256)_v.get_uint64(); - case json_spirit::bool_type: return (u256)(uint64_t)_v.get_bool(); - case json_spirit::real_type: return (u256)(uint64_t)_v.get_real(); - default: cwarn << "Bad type for scalar: " << _v.type(); - } - return 0; -} - -byte toByte(json_spirit::mValue const& _v) -{ - switch (_v.type()) - { - case json_spirit::str_type: return (byte)stoi(_v.get_str()); - case json_spirit::int_type: return (byte)_v.get_uint64(); - case json_spirit::bool_type: return (byte)_v.get_bool(); - case json_spirit::real_type: return (byte)_v.get_real(); - default: cwarn << "Bad type for scalar: " << _v.type(); - } - return 0; -} - -bytes importByteArray(std::string const& _str) -{ - return fromHex(_str.substr(0, 2) == "0x" ? _str.substr(2) : _str, WhenError::Throw); -} - -bytes importData(json_spirit::mObject const& _o) -{ - bytes data; - if (_o.at("data").type() == json_spirit::str_type) - data = importByteArray(_o.at("data").get_str()); - else - for (auto const& j: _o.at("data").get_array()) - data.push_back(toByte(j)); - return data; -} - -bytes importCode(json_spirit::mObject& _o) -{ - bytes code; - if (_o["code"].type() == json_spirit::str_type) - if (_o["code"].get_str().find("0x") != 0) - code = compileLLL(_o["code"].get_str(), false); - else - code = fromHex(_o["code"].get_str().substr(2)); - else if (_o["code"].type() == json_spirit::array_type) - { - code.clear(); - for (auto const& j: _o["code"].get_array()) - code.push_back(toByte(j)); - } - return code; -} - -LogEntries importLog(json_spirit::mArray& _a) -{ - LogEntries logEntries; - for (auto const& l: _a) - { - json_spirit::mObject o = l.get_obj(); - // cant use BOOST_REQUIRE, because this function is used outside boost test (createRandomTest) - assert(o.count("address") > 0); - assert(o.count("topics") > 0); - assert(o.count("data") > 0); - assert(o.count("bloom") > 0); - LogEntry log; - log.address = Address(o["address"].get_str()); - for (auto const& t: o["topics"].get_array()) - log.topics.push_back(h256(t.get_str())); - log.data = importData(o); - logEntries.push_back(log); - } - return logEntries; -} - -void checkOutput(bytes const& _output, json_spirit::mObject& _o) -{ - int j = 0; - - if (_o["out"].get_str().find("#") == 0) - {TBOOST_CHECK(((u256)_output.size() == toInt(_o["out"].get_str().substr(1))));} - else if (_o["out"].type() == json_spirit::array_type) - for (auto const& d: _o["out"].get_array()) - { - TBOOST_CHECK_MESSAGE((_output[j] == toInt(d)), "Output byte [" << j << "] different!"); - ++j; - } - else if (_o["out"].get_str().find("0x") == 0) - {TBOOST_CHECK((_output == fromHex(_o["out"].get_str().substr(2))));} - else - TBOOST_CHECK((_output == fromHex(_o["out"].get_str()))); -} - -void checkStorage(map<u256, u256> _expectedStore, map<u256, u256> _resultStore, Address _expectedAddr) -{ - _expectedAddr = _expectedAddr; //unsed parametr when macro - for (auto&& expectedStorePair : _expectedStore) - { - auto& expectedStoreKey = expectedStorePair.first; - auto resultStoreIt = _resultStore.find(expectedStoreKey); - if (resultStoreIt == _resultStore.end()) - {TBOOST_ERROR(_expectedAddr << ": missing store key " << expectedStoreKey);} - else - { - auto& expectedStoreValue = expectedStorePair.second; - auto& resultStoreValue = resultStoreIt->second; - TBOOST_CHECK_MESSAGE((expectedStoreValue == resultStoreValue), _expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue); - } - } - TBOOST_CHECK_EQUAL(_resultStore.size(), _expectedStore.size()); - for (auto&& resultStorePair: _resultStore) - { - if (!_expectedStore.count(resultStorePair.first)) - TBOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); - } -} - -void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) -{ - TBOOST_REQUIRE_EQUAL(_resultLogs.size(), _expectedLogs.size()); - - for (size_t i = 0; i < _resultLogs.size(); ++i) - { - TBOOST_CHECK_EQUAL(_resultLogs[i].address, _expectedLogs[i].address); - TBOOST_CHECK_EQUAL(_resultLogs[i].topics, _expectedLogs[i].topics); - TBOOST_CHECK((_resultLogs[i].data == _expectedLogs[i].data)); - } -} - -void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates) -{ - TBOOST_REQUIRE_EQUAL(_resultCallCreates.size(), _expectedCallCreates.size()); - - for (size_t i = 0; i < _resultCallCreates.size(); ++i) - { - TBOOST_CHECK((_resultCallCreates[i].data() == _expectedCallCreates[i].data())); - TBOOST_CHECK((_resultCallCreates[i].receiveAddress() == _expectedCallCreates[i].receiveAddress())); - TBOOST_CHECK((_resultCallCreates[i].gas() == _expectedCallCreates[i].gas())); - TBOOST_CHECK((_resultCallCreates[i].value() == _expectedCallCreates[i].value())); - } -} - -void userDefinedTest(std::function<void(json_spirit::mValue&, bool)> doTests) -{ - if (!Options::get().singleTest) - return; - - if (Options::get().singleTestFile.empty() || Options::get().singleTestName.empty()) - { - cnote << "Missing user test specification\nUsage: testeth --singletest <filename> <testname>\n"; - return; - } - - auto& filename = Options::get().singleTestFile; - auto& testname = Options::get().singleTestName; - - if (g_logVerbosity != -1) - VerbosityHolder sentinel(12); - - try - { - cnote << "Testing user defined test: " << filename; - json_spirit::mValue v; - string s = contentsString(filename); - TBOOST_REQUIRE_MESSAGE((s.length() > 0), "Contents of " + filename + " is empty. "); - json_spirit::read_string(s, v); - json_spirit::mObject oSingleTest; - - json_spirit::mObject::const_iterator pos = v.get_obj().find(testname); - if (pos == v.get_obj().end()) - { - cnote << "Could not find test: " << testname << " in " << filename << "\n"; - return; - } - else - oSingleTest[pos->first] = pos->second; - - json_spirit::mValue v_singleTest(oSingleTest); - doTests(v_singleTest, test::Options::get().fillTests); - } - catch (Exception const& _e) - { - TBOOST_ERROR("Failed Test with Exception: " << diagnostic_information(_e)); - } - catch (std::exception const& _e) - { - TBOOST_ERROR("Failed Test with Exception: " << _e.what()); - } -} - -void executeTests(const string& _name, const string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function<void(json_spirit::mValue&, bool)> doTests) -{ - string testPath = getTestPath(); - testPath += _testPathAppendix; - - if (Options::get().stats) - Listener::registerListener(Stats::get()); - - if (Options::get().fillTests) - { - try - { - cnote << "Populating tests..."; - json_spirit::mValue v; - boost::filesystem::path p(__FILE__); - string s = asString(dev::contents(_pathToFiller.string() + "/" + _name + "Filler.json")); - TBOOST_REQUIRE_MESSAGE((s.length() > 0), "Contents of " + _pathToFiller.string() + "/" + _name + "Filler.json is empty."); - json_spirit::read_string(s, v); - doTests(v, true); - writeFile(testPath + "/" + _name + ".json", asBytes(json_spirit::write_string(v, true))); - } - catch (Exception const& _e) - { - TBOOST_ERROR("Failed filling test with Exception: " << diagnostic_information(_e)); - } - catch (std::exception const& _e) - { - TBOOST_ERROR("Failed filling test with Exception: " << _e.what()); - } - } - - try - { - cnote << "TEST " << _name << ":"; - json_spirit::mValue v; - string s = asString(dev::contents(testPath + "/" + _name + ".json")); - TBOOST_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?"); - json_spirit::read_string(s, v); - Listener::notifySuiteStarted(_name); - doTests(v, false); - } - catch (Exception const& _e) - { - TBOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e)); - } - catch (std::exception const& _e) - { - TBOOST_ERROR("Failed test with Exception: " << _e.what()); - } -} - -RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject const& _tObj) -{ - //Construct Rlp of the given transaction - RLPStream rlpStream; - rlpStream.appendList(_tObj.size()); - - if (_tObj.count("nonce")) - rlpStream << bigint(_tObj.at("nonce").get_str()); - - if (_tObj.count("gasPrice")) - rlpStream << bigint(_tObj.at("gasPrice").get_str()); - - if (_tObj.count("gasLimit")) - rlpStream << bigint(_tObj.at("gasLimit").get_str()); - - if (_tObj.count("to")) - { - if (_tObj.at("to").get_str().empty()) - rlpStream << ""; - else - rlpStream << importByteArray(_tObj.at("to").get_str()); - } - - if (_tObj.count("value")) - rlpStream << bigint(_tObj.at("value").get_str()); - - if (_tObj.count("data")) - rlpStream << importData(_tObj); - - if (_tObj.count("v")) - rlpStream << bigint(_tObj.at("v").get_str()); - - if (_tObj.count("r")) - rlpStream << bigint(_tObj.at("r").get_str()); - - if (_tObj.count("s")) - rlpStream << bigint(_tObj.at("s").get_str()); - - if (_tObj.count("extrafield")) - rlpStream << bigint(_tObj.at("extrafield").get_str()); - - return rlpStream; -} - -Options::Options() -{ - auto argc = boost::unit_test::framework::master_test_suite().argc; - auto argv = boost::unit_test::framework::master_test_suite().argv; - - for (auto i = 0; i < argc; ++i) - { - auto arg = std::string{argv[i]}; - if (arg == "--vm" && i + 1 < argc) - { - string vmKind = argv[++i]; - if (vmKind == "interpreter") - VMFactory::setKind(VMKind::Interpreter); - else if (vmKind == "jit") - VMFactory::setKind(VMKind::JIT); - else if (vmKind == "smart") - VMFactory::setKind(VMKind::Smart); - else - cerr << "Unknown VM kind: " << vmKind << endl; - } - else if (arg == "--jit") // TODO: Remove deprecated option "--jit" - VMFactory::setKind(VMKind::JIT); - else if (arg == "--vmtrace") - vmtrace = true; - else if (arg == "--filltests") - fillTests = true; - else if (arg == "--stats" && i + 1 < argc) - { - stats = true; - statsOutFile = argv[i + 1]; - } - else if (arg == "--performance") - performance = true; - else if (arg == "--quadratic") - quadratic = true; - else if (arg == "--memory") - memory = true; - else if (arg == "--inputlimits") - inputLimits = true; - else if (arg == "--bigdata") - bigData = true; - else if (arg == "--checkstate") - checkState = true; - else if (arg == "--wallet") - wallet = true; - else if (arg == "--nonetwork") - nonetwork = true; - else if (arg == "--network") - nonetwork = false; - else if (arg == "--nodag") - nodag = true; - else if (arg == "--all") - { - performance = true; - quadratic = true; - memory = true; - inputLimits = true; - bigData = true; - wallet = true; - } - else if (arg == "--singletest" && i + 1 < argc) - { - singleTest = true; - auto name1 = std::string{argv[i + 1]}; - if (i + 1 < argc) // two params - { - auto name2 = std::string{argv[i + 2]}; - if (name2[0] == '-') // not param, another option - singleTestName = std::move(name1); - else - { - singleTestFile = std::move(name1); - singleTestName = std::move(name2); - } - } - else - singleTestName = std::move(name1); - } - else if (arg == "--fulloutput") - fulloutput = true; - else if (arg == "--verbosity" && i + 1 < argc) - { - static std::ostringstream strCout; //static string to redirect logs to - std::string indentLevel = std::string{argv[i + 1]}; - if (indentLevel == "0") - { - logVerbosity = Verbosity::None; - std::cout.rdbuf(strCout.rdbuf()); - std::cerr.rdbuf(strCout.rdbuf()); - } - else if (indentLevel == "1") - logVerbosity = Verbosity::NiceReport; - else - logVerbosity = Verbosity::Full; - } - } - - //Default option - if (logVerbosity == Verbosity::NiceReport) - g_logVerbosity = -1; //disable cnote but leave cerr and cout -} - -Options const& Options::get() -{ - static Options instance; - return instance; -} - -LastHashes lastHashes(u256 _currentBlockNumber) -{ - LastHashes ret; - for (u256 i = 1; i <= 256 && i <= _currentBlockNumber; ++i) - ret.push_back(sha3(toString(_currentBlockNumber - i))); - return ret; -} - -dev::eth::Ethash::BlockHeader constructHeader( - h256 const& _parentHash, - h256 const& _sha3Uncles, - Address const& _coinbaseAddress, - 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) -{ - RLPStream rlpStream; - rlpStream.appendList(Ethash::BlockHeader::Fields); - - rlpStream << _parentHash << _sha3Uncles << _coinbaseAddress << _stateRoot << _transactionsRoot << _receiptsRoot << _logBloom - << _difficulty << _number << _gasLimit << _gasUsed << _timestamp << _extraData << h256{} << Nonce{}; - - return Ethash::BlockHeader(rlpStream.out(), CheckNothing, h256{}, HeaderData); -} - -void updateEthashSeal(dev::eth::Ethash::BlockHeader& _header, h256 const& _mixHash, dev::eth::Nonce const& _nonce) -{ - RLPStream source; - _header.streamRLP(source); - RLP sourceRlp(source.out()); - RLPStream header; - header.appendList(Ethash::BlockHeader::Fields); - for (size_t i = 0; i < BlockInfo::BasicFields; i++) - header << sourceRlp[i]; - - header << _mixHash << _nonce; - _header = Ethash::BlockHeader(header.out(), CheckNothing, h256{}, HeaderData); -} - namespace { Listener* g_listener; |