diff --git a/alethzero/DappLoader.cpp b/alethzero/DappLoader.cpp index 9baf0c82e..69555521d 100644 --- a/alethzero/DappLoader.cpp +++ b/alethzero/DappLoader.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -96,13 +97,31 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri) void DappLoader::downloadComplete(QNetworkReply* _reply) { + QUrl requestUrl = _reply->request().url(); + if (m_pageUrls.count(requestUrl) != 0) + { + //inject web3 js + QByteArray content = "\n"); + content.append(_reply->readAll()); + QString contentType = _reply->header(QNetworkRequest::ContentTypeHeader).toString(); + if (contentType.isEmpty()) + { + QMimeDatabase db; + contentType = db.mimeTypeForUrl(requestUrl).name(); + } + pageReady(content, contentType, requestUrl); + return; + } + try { //try to interpret as rlp QByteArray data = _reply->readAll(); _reply->deleteLater(); - h256 expected = m_uriHashes[_reply->request().url()]; + h256 expected = m_uriHashes[requestUrl]; bytes package(reinterpret_cast(data.constData()), reinterpret_cast(data.constData() + data.size())); Secp256k1 dec; dec.decrypt(expected, package); @@ -144,15 +163,7 @@ void DappLoader::loadDapp(RLP const& _rlp) if (entry->path == "/deployment.js") { //inject web3 code - QString code; - code += contentsOfQResource(":/js/bignumber.min.js"); - code += "\n"; - code += contentsOfQResource(":/js/webthree.js"); - code += "\n"; - code += contentsOfQResource(":/js/setup.js"); - code += "\n"; - QByteArray res = code.toLatin1(); - bytes b(res.data(), res.data() + res.size()); + bytes b(web3Content().data(), web3Content().data() + web3Content().size()); b.insert(b.end(), content.begin(), content.end()); dapp.content[hash] = b; } @@ -165,6 +176,22 @@ void DappLoader::loadDapp(RLP const& _rlp) emit dappReady(dapp); } +QByteArray const& DappLoader::web3Content() +{ + if (m_web3Js.isEmpty()) + { + QString code; + code += contentsOfQResource(":/js/bignumber.min.js"); + code += "\n"; + code += contentsOfQResource(":/js/webthree.js"); + code += "\n"; + code += contentsOfQResource(":/js/setup.js"); + code += "\n"; + m_web3Js = code.toLatin1(); + } + return m_web3Js; +} + Manifest DappLoader::loadManifest(std::string const& _manifest) { /// https://github.com/ethereum/go-ethereum/wiki/URL-Scheme @@ -216,3 +243,11 @@ void DappLoader::loadDapp(QString const& _uri) m_net.get(request); } +void DappLoader::loadPage(QString const& _uri) +{ + QUrl uri(_uri); + QNetworkRequest request(uri); + m_pageUrls.insert(uri); + m_net.get(request); +} + diff --git a/alethzero/DappLoader.h b/alethzero/DappLoader.h index 463b65d0a..deba62c68 100644 --- a/alethzero/DappLoader.h +++ b/alethzero/DappLoader.h @@ -73,9 +73,13 @@ public: ///Load a new DApp. Resolves a name with a name reg contract. Asynchronous. dappReady is emitted once everything is read, dappError othervise ///@param _uri Eth name path void loadDapp(QString const& _uri); + ///Load a regular html page + ///@param _uri Page Uri + void loadPage(QString const& _uri); signals: void dappReady(Dapp& _dapp); + void pageReady(QByteArray const& _content, QString const& _mimeType, QUrl const& _uri); void dappError(); private slots: @@ -86,9 +90,12 @@ private: DappLocation resolveAppUri(QString const& _uri); void loadDapp(dev::RLP const& _rlp); Manifest loadManifest(std::string const& _manifest); + QByteArray const& web3Content(); dev::WebThreeDirect* m_web3; QNetworkAccessManager m_net; std::map m_uriHashes; + std::set m_pageUrls; + QByteArray m_web3Js; }; diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 94a58dec0..bbacaf539 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -183,13 +183,6 @@ Main::Main(QWidget *parent) : m_webPage = webPage; connect(webPage, &WebPage::consoleMessage, [this](QString const& _msg) { Main::addConsoleMessage(_msg, QString()); }); ui->webView->setPage(m_webPage); - connect(ui->webView, &QWebEngineView::loadFinished, [this]() - { - auto f = ui->webView->page(); - f->runJavaScript(contentsOfQResource(":/js/bignumber.min.js")); - f->runJavaScript(contentsOfQResource(":/js/webthree.js")); - f->runJavaScript(contentsOfQResource(":/js/setup.js")); - }); connect(ui->webView, &QWebEngineView::titleChanged, [=]() { @@ -199,6 +192,7 @@ Main::Main(QWidget *parent) : m_dappHost.reset(new DappHost(8081)); m_dappLoader = new DappLoader(this, web3()); connect(m_dappLoader, &DappLoader::dappReady, this, &Main::dappLoaded); + connect(m_dappLoader, &DappLoader::pageReady, this, &Main::pageLoaded); // ui->webView->page()->settings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, true); // QWebEngineInspector* inspector = new QWebEngineInspector(); // inspector->setPage(page); @@ -264,7 +258,7 @@ NetworkPreferences Main::netPrefs() const { listenIP.clear(); } - + auto publicIP = ui->forcePublicIP->text().toStdString(); try { @@ -274,7 +268,7 @@ NetworkPreferences Main::netPrefs() const { publicIP.clear(); } - + if (isPublicAddress(publicIP)) return NetworkPreferences(publicIP, listenIP, ui->port->value(), ui->upnp->isChecked()); else @@ -918,6 +912,7 @@ void Main::on_urlEdit_returnPressed() { //try do resolve dapp url m_dappLoader->loadDapp(s); + return; } catch (...) { @@ -931,8 +926,7 @@ void Main::on_urlEdit_returnPressed() else url.setScheme("http"); else {} - qDebug() << url.toString(); - ui->webView->page()->setUrl(url); + m_dappLoader->loadPage(url.toString()); } void Main::on_nameReg_textChanged() @@ -1799,7 +1793,7 @@ void Main::on_connect_triggered() ui->net->setChecked(true); on_net_triggered(); } - + m_connect.setEnvironment(m_servers); if (m_connect.exec() == QDialog::Accepted) { @@ -1811,9 +1805,9 @@ void Main::on_connect_triggered() nodeID = NodeId(fromHex(m_connect.nodeId().toStdString())); } catch (BadHexCharacter&) {} - + m_connect.reset(); - + if (required) web3()->requirePeer(nodeID, host); else @@ -2016,3 +2010,8 @@ void Main::dappLoaded(Dapp& _dapp) QUrl url = m_dappHost->hostDapp(std::move(_dapp)); ui->webView->page()->setUrl(url); } + +void Main::pageLoaded(QByteArray const& _content, QString const& _mimeType, QUrl const& _uri) +{ + ui->webView->page()->setContent(_content, _mimeType, _uri); +} diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index fccbc855d..a5c74eeaa 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -179,6 +179,7 @@ private slots: // Dapps void dappLoaded(Dapp& _dapp); //qt does not support rvalue refs for signals + void pageLoaded(QByteArray const& _content, QString const& _mimeType, QUrl const& _uri); signals: void poll(); diff --git a/evmjit/libevmjit/ExecutionEngine.cpp b/evmjit/libevmjit/ExecutionEngine.cpp index 0ed4a65b5..e15dad969 100644 --- a/evmjit/libevmjit/ExecutionEngine.cpp +++ b/evmjit/libevmjit/ExecutionEngine.cpp @@ -88,10 +88,10 @@ void parseOptions() //cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler"); // FIXME: LLVM workaround: - // Manually select instruction scheduler other than "source". + // Manually select instruction scheduler. Confirmed bad schedulers: source, list-burr, list-hybrid. // "source" scheduler has a bug: http://llvm.org/bugs/show_bug.cgi?id=22304 auto envLine = std::getenv("EVMJIT"); - auto commandLine = std::string{"evmjit "} + (envLine ? envLine : "") + " -pre-RA-sched=list-burr\0"; + auto commandLine = std::string{"evmjit "} + (envLine ? envLine : "") + " -pre-RA-sched=list-ilp\0"; static const auto c_maxArgs = 20; char const* argv[c_maxArgs] = {nullptr, }; auto arg = std::strtok(&*commandLine.begin(), " "); diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 548f48da8..7e670cfaa 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -10,8 +10,26 @@ set(EXECUTABLE exp) add_executable(${EXECUTABLE} ${SRC_LIST}) +target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) + +if (READLINE_FOUND) + target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) +endif() + +if (JSONRPC) + target_link_libraries(${EXECUTABLE} web3jsonrpc) +endif() + +target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} p2p) +target_link_libraries(${EXECUTABLE} ethash-cl) +target_link_libraries(${EXECUTABLE} ethash) +target_link_libraries(${EXECUTABLE} OpenCL) install( TARGETS ${EXECUTABLE} DESTINATION bin) + + + + diff --git a/exp/main.cpp b/exp/main.cpp index 23c907ed1..6c067f83e 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -19,18 +19,25 @@ * @date 2014 * Ethereum client. */ +#define __CL_ENABLE_EXCEPTIONS +#define CL_USE_DEPRECATED_OPENCL_2_0_APIS +#include "libethash-cl/cl.hpp" + #include -#include #include #include #include #include #include -#include +#include #include +#include #include -#include +#include +#include #include +#include +#include #include #include #include @@ -101,6 +108,22 @@ int main() #else int main() { + std::vector platforms; + cl::Platform::get(&platforms); + if (platforms.empty()) + { + cdebug << "No OpenCL platforms found."; + return false; + } + + EthashCL ecl; + BlockInfo genesis = CanonBlockChain::genesis(); + TransientDirectory td; + std::pair r; + while (!r.first.completed) + r = ecl.mine(genesis, 1000); + EthashCL::assignResult(r.second, genesis); + assert(EthashCPU::verify(genesis)); return 0; } #endif diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 03f7547e7..ec3472605 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -28,6 +28,7 @@ endif() target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) # transitive dependencies for windows executables diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp index 46d6e3a6b..a1a1056cb 100644 --- a/libdevcore/CommonIO.cpp +++ b/libdevcore/CommonIO.cpp @@ -58,7 +58,7 @@ string dev::memDump(bytes const& _bytes, unsigned _width, bool _html) } // Don't forget to delete[] later. -bytesRef dev::contentsNew(std::string const& _file) +bytesRef dev::contentsNew(std::string const& _file, bytesRef _dest) { std::ifstream is(_file, std::ifstream::binary); if (!is) @@ -68,8 +68,10 @@ bytesRef dev::contentsNew(std::string const& _file) streamoff length = is.tellg(); if (length == 0) // return early, MSVC does not like reading 0 bytes return bytesRef(); + if (!_dest.empty() && _dest.size() != (unsigned)length) + return bytesRef(); is.seekg (0, is.beg); - bytesRef ret(new byte[length], length); + bytesRef ret = _dest.empty() ? bytesRef(new byte[length], length) : _dest; is.read((char*)ret.data(), length); is.close(); return ret; diff --git a/libdevcore/CommonIO.h b/libdevcore/CommonIO.h index f42f449bb..3889f6171 100644 --- a/libdevcore/CommonIO.h +++ b/libdevcore/CommonIO.h @@ -46,7 +46,7 @@ namespace dev bytes contents(std::string const& _file); std::string contentsString(std::string const& _file); /// Retrieve and returns the allocated contents of the given file. If the file doesn't exist or isn't readable, returns nullptr. Don't forget to delete [] when finished. -bytesRef contentsNew(std::string const& _file); +bytesRef contentsNew(std::string const& _file, bytesRef _dest = bytesRef()); /// Write the given binary data into the given file, replacing the file if it pre-exists. void writeFile(std::string const& _file, bytesConstRef _data); diff --git a/libdevcore/RangeMask.h b/libdevcore/RangeMask.h index 19262515c..bdf00e687 100644 --- a/libdevcore/RangeMask.h +++ b/libdevcore/RangeMask.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace dev { diff --git a/libtestutils/TransientDirectory.cpp b/libdevcore/TransientDirectory.cpp similarity index 95% rename from libtestutils/TransientDirectory.cpp rename to libdevcore/TransientDirectory.cpp index 694784e25..db702181e 100644 --- a/libtestutils/TransientDirectory.cpp +++ b/libdevcore/TransientDirectory.cpp @@ -20,11 +20,11 @@ */ #include -#include +#include "Exceptions.h" #include "TransientDirectory.h" +#include "CommonIO.h" using namespace std; using namespace dev; -using namespace dev::test; TransientDirectory::TransientDirectory(): TransientDirectory((boost::filesystem::temp_directory_path() / "eth_transient" / toString(FixedHash<4>::random())).string()) diff --git a/libtestutils/TransientDirectory.h b/libdevcore/TransientDirectory.h similarity index 96% rename from libtestutils/TransientDirectory.h rename to libdevcore/TransientDirectory.h index 21a338e59..6c90982a3 100644 --- a/libtestutils/TransientDirectory.h +++ b/libdevcore/TransientDirectory.h @@ -22,12 +22,9 @@ #pragma once #include -#include "Common.h" namespace dev { -namespace test -{ /** * @brief temporary directory implementation @@ -48,4 +45,3 @@ private: }; } -} diff --git a/libethash/util.h b/libethash/util.h index ba8957815..1e6d4fbab 100644 --- a/libethash/util.h +++ b/libethash/util.h @@ -29,7 +29,7 @@ extern "C" { #ifdef _MSC_VER void debugf(const char *str, ...); #else -#define debugf printf +#define debugf(...) fprintf(stderr, __VA_ARGS__) #endif static inline uint32_t min_u32(uint32_t a, uint32_t b) diff --git a/libethcore/Ethasher.cpp b/libethcore/Ethasher.cpp index 75f0bcd5a..6cd2504b3 100644 --- a/libethcore/Ethasher.cpp +++ b/libethcore/Ethasher.cpp @@ -123,6 +123,44 @@ ethash_params Ethasher::params(BlockInfo const& _header) return params((unsigned)_header.number); } +void Ethasher::readFull(BlockInfo const& _header, void* _dest) +{ + if (!m_fulls.count(_header.seedHash())) + { + // @memoryleak @bug place it on a pile for deletion - perhaps use shared_ptr. +/* if (!m_fulls.empty()) + { + delete [] m_fulls.begin()->second.data(); + m_fulls.erase(m_fulls.begin()); + }*/ + + try { + boost::filesystem::create_directories(getDataDir("ethash")); + } catch (...) {} + + auto info = rlpList(c_ethashRevision, _header.seedHash()); + std::string oldMemoFile = getDataDir("ethash") + "/full"; + std::string memoFile = getDataDir("ethash") + "/full-R" + toString(c_ethashRevision) + "-" + toHex(_header.seedHash().ref().cropped(0, 8)); + if (boost::filesystem::exists(oldMemoFile) && contents(oldMemoFile + ".info") == info) + { + // memofile valid - rename. + boost::filesystem::rename(oldMemoFile, memoFile); + } + + IGNORE_EXCEPTIONS(boost::filesystem::remove(oldMemoFile)); + IGNORE_EXCEPTIONS(boost::filesystem::remove(oldMemoFile + ".info")); + + ethash_params p = params((unsigned)_header.number); + bytesRef r = contentsNew(memoFile, bytesRef((byte*)_dest, p.full_size)); + if (!r) + { + auto c = light(_header); + ethash_prep_full(_dest, &p, c); + writeFile(memoFile, bytesConstRef((byte*)_dest, p.full_size)); + } + } +} + ethash_params Ethasher::params(unsigned _n) { ethash_params p; diff --git a/libethcore/Ethasher.h b/libethcore/Ethasher.h index 8d1a1e84c..32622929f 100644 --- a/libethcore/Ethasher.h +++ b/libethcore/Ethasher.h @@ -56,6 +56,8 @@ public: static ethash_params params(BlockInfo const& _header); static ethash_params params(unsigned _n); + void readFull(BlockInfo const& _header, void* _dest); + struct Result { h256 value; diff --git a/libethcore/ProofOfWork.cpp b/libethcore/ProofOfWork.cpp index a34e75d71..c87f51a78 100644 --- a/libethcore/ProofOfWork.cpp +++ b/libethcore/ProofOfWork.cpp @@ -33,32 +33,6 @@ #include #if ETH_ETHASHCL #include -#define ETHASH_REVISION REVISION -#define ETHASH_DATASET_BYTES_INIT DATASET_BYTES_INIT -#define ETHASH_DATASET_BYTES_GROWTH DATASET_BYTES_GROWTH -#define ETHASH_CACHE_BYTES_INIT CACHE_BYTES_INIT -#define ETHASH_CACHE_BYTES_GROWTH CACHE_BYTES_GROWTH -#define ETHASH_DAGSIZE_BYTES_INIT DAGSIZE_BYTES_INIT -#define ETHASH_DAG_GROWTH DAG_GROWTH -#define ETHASH_EPOCH_LENGTH EPOCH_LENGTH -#define ETHASH_MIX_BYTES MIX_BYTES -#define ETHASH_HASH_BYTES HASH_BYTES -#define ETHASH_DATASET_PARENTS DATASET_PARENTS -#define ETHASH_CACHE_ROUNDS CACHE_ROUNDS -#define ETHASH_ACCESSES ACCESSES -#undef REVISION -#undef DATASET_BYTES_INIT -#undef DATASET_BYTES_GROWTH -#undef CACHE_BYTES_INIT -#undef CACHE_BYTES_GROWTH -#undef DAGSIZE_BYTES_INIT -#undef DAG_GROWTH -#undef EPOCH_LENGTH -#undef MIX_BYTES -#undef HASH_BYTES -#undef DATASET_PARENTS -#undef CACHE_ROUNDS -#undef ACCESSES #endif #include "BlockInfo.h" #include "Ethasher.h" @@ -131,16 +105,16 @@ std::pair EthashCPU::mine(BlockInfo const& _header, #if ETH_ETHASHCL /* -struct ethash_cl_search_hook -{ - // reports progress, return true to abort - virtual bool found(uint64_t const* nonces, uint32_t count) = 0; - virtual bool searched(uint64_t start_nonce, uint32_t count) = 0; -}; - class ethash_cl_miner { public: + struct search_hook + { + // reports progress, return true to abort + virtual bool found(uint64_t const* nonces, uint32_t count) = 0; + virtual bool searched(uint64_t start_nonce, uint32_t count) = 0; + }; + ethash_cl_miner(); bool init(ethash_params const& params, const uint8_t seed[32], unsigned workgroup_size = 64); @@ -150,58 +124,63 @@ public: }; */ -struct EthashCLHook: public ethash_cl_search_hook +struct EthashCLHook: public ethash_cl_miner::search_hook { - virtual bool found(uint64_t const* _nonces, uint32_t _count) + void abort() + { + if (m_aborted) + return; + m_abort = true; + for (unsigned timeout = 0; timeout < 100 && !m_aborted; ++timeout) + std::this_thread::sleep_for(chrono::milliseconds(30)); + if (!m_aborted) + cwarn << "Couldn't abort. Abandoning OpenCL process."; + m_aborted = m_abort = false; + m_found.clear(); + } + + vector fetchFound() { vector ret; Guard l(x_all); std::swap(ret, m_found); return ret; } + uint64_t fetchTotal() { Guard l(x_all); auto ret = m_total; m_total = 0; return ret; } + +protected: + virtual bool found(uint64_t const* _nonces, uint32_t _count) override { Guard l(x_all); for (unsigned i = 0; i < _count; ++i) - found.push_back((Nonce)(u64)_nonces[i]); - if (abort) - { - aborted = true; - return true; - } - return false; + m_found.push_back((Nonce)(u64)_nonces[i]); + m_aborted = true; + return true; } - virtual bool searched(uint64_t _startNonce, uint32_t _count) + virtual bool searched(uint64_t _startNonce, uint32_t _count) override { Guard l(x_all); - total += _count; - last = _startNonce + _count; - if (abort) + m_total += _count; + m_last = _startNonce + _count; + if (m_abort) { - aborted = true; + m_aborted = true; return true; } return false; } - vector fetchFound() { vector ret; Guard l(x_all); std::swap(ret, found); return ret; } - uint64_t fetchTotal() { Guard l(x_all); auto ret = total; total = 0; return ret; } - +private: Mutex x_all; - vector found; - uint64_t total; - uint64_t last; - bool abort = false; - bool aborted = false; + vector m_found; + uint64_t m_total; + uint64_t m_last; + bool m_abort = false; + bool m_aborted = true; }; EthashCL::EthashCL(): - m_miner(new ethash_cl_miner), m_hook(new EthashCLHook) { } EthashCL::~EthashCL() { - m_hook->abort = true; - for (unsigned timeout = 0; timeout < 100 && !m_hook->aborted; ++timeout) - std::this_thread::sleep_for(chrono::milliseconds(30)); - if (!m_hook->aborted) - cwarn << "Couldn't abort. Abandoning OpenCL process."; } bool EthashCL::verify(BlockInfo const& _header) @@ -211,13 +190,16 @@ bool EthashCL::verify(BlockInfo const& _header) std::pair EthashCL::mine(BlockInfo const& _header, unsigned _msTimeout, bool, bool) { - if (m_lastHeader.seedHash() != _header.seedHash()) + if (!m_lastHeader || m_lastHeader.seedHash() != _header.seedHash()) { - m_miner->init(Ethasher::params(_header), _header.seedHash().data()); - // TODO: reinit probably won't work when seed changes. + if (m_miner) + m_hook->abort(); + m_miner.reset(new ethash_cl_miner); + m_miner->init(Ethasher::params(_header), [&](void* d){ Ethasher::get()->readFull(_header, d); }); } if (m_lastHeader != _header) { + m_hook->abort(); static std::random_device s_eng; uint64_t tryNonce = (uint64_t)(u64)(m_last = Nonce::random(s_eng)); m_miner->search(_header.headerHash(WithoutNonce).data(), tryNonce, *m_hook); @@ -228,10 +210,11 @@ std::pair EthashCL::mine(BlockInfo const& _header, unsi auto found = m_hook->fetchFound(); if (!found.empty()) { - h256 mixHash; // ????? - return std::make_pair(MineInfo{0.0, 1e99, 0, true}, EthashCL::Proof((Nonce)(u64)found[0], mixHash)); + Nonce n = (Nonce)(u64)found[0]; + auto result = Ethasher::eval(_header, n); + return std::make_pair(MineInfo(true), EthashCL::Proof{n, result.mixHash}); } - return std::make_pair(MineInfo{0.0, 1e99, 0, false}, EthashCL::Proof()); + return std::make_pair(MineInfo(false), EthashCL::Proof()); } #endif diff --git a/libethcore/ProofOfWork.h b/libethcore/ProofOfWork.h index 245a96a02..48d52049a 100644 --- a/libethcore/ProofOfWork.h +++ b/libethcore/ProofOfWork.h @@ -42,6 +42,8 @@ namespace eth struct MineInfo { + MineInfo() = default; + MineInfo(bool _completed): completed(_completed) {} void combine(MineInfo const& _m) { requirement = std::max(requirement, _m.requirement); best = std::min(best, _m.best); hashes += _m.hashes; completed = completed || _m.completed; } double requirement = 0; double best = 1e99; @@ -67,6 +69,8 @@ protected: }; #if ETH_ETHASHCL +class EthashCLHook; + class EthashCL { public: @@ -88,7 +92,7 @@ protected: BlockInfo m_lastHeader; Nonce m_mined; std::unique_ptr m_miner; - std::unique_ptr m_hook; + std::unique_ptr m_hook; }; using Ethash = EthashCL; diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 3df3b9bc3..8822394a3 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -25,19 +25,18 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) - target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} whisper) target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} ethcore) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) target_link_libraries(${EXECUTABLE} secp256k1) - if (ETHASHCL) target_link_libraries(${EXECUTABLE} ethash-cl) + target_link_libraries(${EXECUTABLE} OpenCL) endif () if (CMAKE_COMPILER_IS_MINGW) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 80788aa22..87f474afe 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -334,6 +334,7 @@ void Client::setMiningThreads(unsigned _threads) { stopMining(); #if ETH_ETHASHCL + (void)_threads; unsigned t = 1; #else auto t = _threads ? _threads : thread::hardware_concurrency(); diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 692081f96..57ae6a5e1 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -75,7 +75,7 @@ ExecutionResult ClientBase::call(Secret _secret, u256 _value, Address _dest, byt u256 n = temp.transactionsFrom(a); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); if (_ff == FudgeFactor::Lenient) - temp.addBalance(a, (u256)(t.gasRequired() * t.gasPrice() + t.value())); + temp.addBalance(a, (u256)(t.gas() * t.gasPrice() + t.value())); ret = temp.execute(bc().lastHashes(), t, Permanence::Reverted); } catch (...) diff --git a/libtestutils/BlockChainLoader.h b/libtestutils/BlockChainLoader.h index 6cb04c53c..58b1affaf 100644 --- a/libtestutils/BlockChainLoader.h +++ b/libtestutils/BlockChainLoader.h @@ -22,9 +22,9 @@ #pragma once #include #include +#include #include #include -#include "TransientDirectory.h" namespace dev { diff --git a/libtestutils/StateLoader.h b/libtestutils/StateLoader.h index e1346f69a..47eb26900 100644 --- a/libtestutils/StateLoader.h +++ b/libtestutils/StateLoader.h @@ -22,8 +22,8 @@ #pragma once #include +#include #include -#include "TransientDirectory.h" namespace dev { diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index c760005de..dae672f58 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -452,64 +452,55 @@ static TransactionSkeleton toTransaction(Json::Value const& _json) string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json) { - TransactionSkeleton t; - try { - t = toTransaction(_json); + string ret; + TransactionSkeleton t = toTransaction(_json); + + if (!t.from) + t.from = m_accounts->getDefaultTransactAccount(); + if (t.creation) + ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));; + if (!t.gasPrice) + t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow. + if (!t.gas) + t.gas = min(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice); + + if (m_accounts->isRealAccount(t.from)) + authenticate(t, false); + else if (m_accounts->isProxyAccount(t.from)) + authenticate(t, true); + + return ret; } catch (...) { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - - string ret; - if (!t.from) - t.from = m_accounts->getDefaultTransactAccount(); - if (t.creation) - ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));; - if (!t.gasPrice) - t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow. - if (!t.gas) - t.gas = min(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice); - - if (m_accounts->isRealAccount(t.from)) - authenticate(t, false); - else if (m_accounts->isProxyAccount(t.from)) - authenticate(t, true); - - return ret; } string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const& _blockNumber) { - TransactionSkeleton t; - int number; - try { - t = toTransaction(_json); - number = jsToBlockNumber(_blockNumber); + TransactionSkeleton t = toTransaction(_json); + if (!t.from) + t.from = m_accounts->getDefaultTransactAccount(); + // if (!m_accounts->isRealAccount(t.from)) + // return ret; + if (!t.gasPrice) + t.gasPrice = 10 * dev::eth::szabo; + if (!t.gas) + t.gas = client()->gasLimitRemaining(); + + return toJS(client()->call(m_accounts->secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice, jsToBlockNumber(_blockNumber), FudgeFactor::Lenient).output); } catch (...) { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - string ret; - if (!t.from) - t.from = m_accounts->getDefaultTransactAccount(); -// if (!m_accounts->isRealAccount(t.from)) -// return ret; - if (!t.gasPrice) - t.gasPrice = 10 * dev::eth::szabo; - if (!t.gas) - t.gas = client()->gasLimitRemaining(); - - ret = toJS(client()->call(m_accounts->secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice, number).output); - - return ret; } bool WebThreeStubServerBase::eth_flush() diff --git a/mix/qml/DebugInfoList.qml b/mix/qml/DebugInfoList.qml index 5b1a67519..b479d6d28 100644 --- a/mix/qml/DebugInfoList.qml +++ b/mix/qml/DebugInfoList.qml @@ -40,11 +40,9 @@ ColumnLayout { height: 25 id: header Image { - source: "qrc:/qml/img/opentriangleindicator.png" + source: "img/closedtriangleindicator.png" width: 15 height: 15 - sourceSize.width: 15 - sourceSize.height: 15 id: storageImgArrow } diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index e5c7e576d..ef83ef390 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -206,8 +206,8 @@ Rectangle { anchors.top: parent.top anchors.topMargin: 15 anchors.left: parent.left; - anchors.leftMargin: machineStates.sideMargin - width: debugScrollArea.width - machineStates.sideMargin * 2 - 20; + anchors.leftMargin: machineStates.sideMargin + width: debugScrollArea.width - machineStates.sideMargin * 2 - 20 ; spacing: machineStates.sideMargin Rectangle { @@ -218,15 +218,13 @@ Rectangle { color: "transparent" Rectangle { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left + anchors.fill: parent color: "transparent" - width: parent.width * 0.4 RowLayout { - anchors.horizontalCenter: parent.horizontalCenter + anchors.fill: parent id: jumpButtons spacing: 3 + layoutDirection: Qt.LeftToRight StepActionImage { @@ -239,6 +237,7 @@ Rectangle { buttonShortcut: "Ctrl+Shift+F8" buttonTooltip: qsTr("Start Debugging") visible: true + Layout.alignment: Qt.AlignLeft } StepActionImage @@ -351,35 +350,38 @@ Rectangle { buttonTooltip: qsTr("Run Forward") visible: false } - } - } - Rectangle { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.right: parent.right - width: parent.width * 0.6 - color: "transparent" - Slider { - id: statesSlider - anchors.fill: parent - tickmarksEnabled: true - stepSize: 1.0 - onValueChanged: Debugger.jumpTo(value); - style: SliderStyle { - groove: Rectangle { - implicitHeight: 3 - color: "#7da4cd" - radius: 8 - } - handle: Rectangle { - anchors.centerIn: parent - color: control.pressed ? "white" : "lightgray" - border.color: "gray" - border.width: 2 - implicitWidth: 10 - implicitHeight: 10 - radius: 12 + Rectangle { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + color: "transparent" + Layout.fillWidth: true + Layout.minimumWidth: parent.width * 0.2 + Layout.alignment: Qt.AlignRight + + Slider { + id: statesSlider + anchors.fill: parent + tickmarksEnabled: true + stepSize: 1.0 + onValueChanged: Debugger.jumpTo(value); + style: SliderStyle { + groove: Rectangle { + implicitHeight: 3 + color: "#7da4cd" + radius: 8 + } + handle: Rectangle { + anchors.centerIn: parent + color: control.pressed ? "white" : "lightgray" + border.color: "gray" + border.width: 2 + implicitWidth: 10 + implicitHeight: 10 + radius: 12 + } + } } } } @@ -480,7 +482,7 @@ Rectangle { anchors.top : parent.top anchors.bottom: parent.bottom anchors.right: parent.right - height: parent.height //- 2 * stateListContainer.border.width + height: parent.height color: "transparent" ColumnLayout { @@ -520,7 +522,6 @@ Rectangle { title : qsTr("Stack") itemDelegate: Item { id: renderedItem - //height: 25 width: parent.width RowLayout { diff --git a/mix/qml/StatusPane.qml b/mix/qml/StatusPane.qml index f3bde4a04..75a2edd4f 100644 --- a/mix/qml/StatusPane.qml +++ b/mix/qml/StatusPane.qml @@ -230,13 +230,26 @@ Rectangle { Button { z: 4 - anchors.right: parent.right - anchors.rightMargin: 9 - anchors.verticalCenter: parent.verticalCenter + anchors.centerIn: parent id: goToLineBtn text: "" - iconSource: "qrc:/qml/img/signerroricon32.png" + width: 30 + height: 30 action: goToCompilationError + style: ButtonStyle { + background: Rectangle { + color: "transparent" + + Image { + source: "qrc:/qml/img/warningicon.png" + height: 30 + width: 30 + sourceSize.width: 30 + sourceSize.height: 30 + anchors.centerIn: parent + } + } + } } } } diff --git a/mix/qml/html/cm/solarized.css b/mix/qml/html/cm/solarized.css index d8c31bfb5..b8cede806 100644 --- a/mix/qml/html/cm/solarized.css +++ b/mix/qml/html/cm/solarized.css @@ -154,8 +154,10 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png } /* + Active line. Negative margin compensates left padding of the text in the view-port + */ .cm-s-solarized.cm-s-dark .CodeMirror-activeline-background { background: rgba(255, 255, 255, 0.10); @@ -166,20 +168,24 @@ view-port /* Code execution */ .CodeMirror-exechighlight { - background: #eee8d5; + border-bottom: double 1px #94A2A2; } + /* Error annotation */ .CodeMirror-errorannotation { - border-bottom: 1px solid #b58900; + border-bottom: 1px solid #DD3330; + margin-bottom: 4px; } .CodeMirror-errorannotation-context { font-family: monospace; font-size: small; - color: #586e75; + color: #EEE9D5; background: #b58900; padding: 2px; + text-shadow: none !important; + border-top: solid 2px #063742; } span.CodeMirror-selectedtext { color: #586e75 !important; } diff --git a/mix/qml/img/closedtriangleindicator.png b/mix/qml/img/closedtriangleindicator.png index 440adb711..ccf6c66d4 100644 Binary files a/mix/qml/img/closedtriangleindicator.png and b/mix/qml/img/closedtriangleindicator.png differ diff --git a/mix/qml/img/closedtriangleindicator@2x.png b/mix/qml/img/closedtriangleindicator@2x.png new file mode 100644 index 000000000..b12cfef9c Binary files /dev/null and b/mix/qml/img/closedtriangleindicator@2x.png differ diff --git a/mix/qml/img/opentriangleindicator.png b/mix/qml/img/opentriangleindicator.png index 591a932e0..5da188206 100644 Binary files a/mix/qml/img/opentriangleindicator.png and b/mix/qml/img/opentriangleindicator.png differ diff --git a/mix/qml/img/opentriangleindicator@2x.png b/mix/qml/img/opentriangleindicator@2x.png index fd948d73b..320749684 100644 Binary files a/mix/qml/img/opentriangleindicator@2x.png and b/mix/qml/img/opentriangleindicator@2x.png differ diff --git a/mix/qml/img/signerroricon32.png b/mix/qml/img/signerroricon32.png deleted file mode 100644 index 703ac5e2c..000000000 Binary files a/mix/qml/img/signerroricon32.png and /dev/null differ diff --git a/mix/qml/img/warningicon.png b/mix/qml/img/warningicon.png new file mode 100644 index 000000000..0215030da Binary files /dev/null and b/mix/qml/img/warningicon.png differ diff --git a/mix/qml/img/warningicon@2x.png b/mix/qml/img/warningicon@2x.png new file mode 100644 index 000000000..e41615f37 Binary files /dev/null and b/mix/qml/img/warningicon@2x.png differ diff --git a/mix/res.qrc b/mix/res.qrc index f5798ca58..f175fab1f 100644 --- a/mix/res.qrc +++ b/mix/res.qrc @@ -20,6 +20,7 @@ qml/img/bugiconactive.png qml/img/bugiconinactive.png qml/img/closedtriangleindicator.png + qml/img/closedtriangleindicator@2x.png qml/img/closedtriangleindicator_filesproject.png qml/img/console.png qml/img/copy.png @@ -43,6 +44,7 @@ qml/img/note.png qml/img/openedfolder.png qml/img/opentriangleindicator.png + qml/img/opentriangleindicator@2x.png qml/img/opentriangleindicator_filesproject.png qml/img/plus.png qml/img/projecticon.png @@ -63,6 +65,7 @@ qml/img/copyiconactive.png qml/img/searchicon.png qml/img/stop_button2x.png - qml/img/signerroricon32.png + qml/img/warningicon.png + qml/img/warningicon@2x.png diff --git a/test/TestUtils.cpp b/test/TestUtils.cpp index 6222955d5..ff5169d55 100644 --- a/test/TestUtils.cpp +++ b/test/TestUtils.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include "TestUtils.h" diff --git a/test/blockchain.cpp b/test/blockchain.cpp index 6c1cfebd6..ab01df5a5 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include "TestHelper.h" diff --git a/test/state.cpp b/test/state.cpp index 813c3b4d7..65f333538 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -218,6 +218,8 @@ BOOST_AUTO_TEST_CASE(stCreateTest) BOOST_AUTO_TEST_CASE(stRandom) { + test::Options::get(); // parse command line options, e.g. to enable JIT + string testPath = dev::test::getTestPath(); testPath += "/StateTests/RandomTests"; diff --git a/test/vm.cpp b/test/vm.cpp index d92989133..4728b8a53 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -524,6 +524,8 @@ BOOST_AUTO_TEST_CASE(vmInputLimitsLightTest) BOOST_AUTO_TEST_CASE(vmRandom) { + test::Options::get(); // parse command line options, e.g. to enable JIT + string testPath = getTestPath(); testPath += "/VMTests/RandomTests";