Browse Source

Merge branch 'develop' of https://github.com/ethereum/cpp-ethereum into

core_pow

Conflicts:
	mix/MixClient.cpp
cl-refactor
arkpar 10 years ago
parent
commit
4783eafcfe
  1. 13
      CMakeLists.txt
  2. 55
      alethzero/DappLoader.cpp
  3. 7
      alethzero/DappLoader.h
  4. 18
      alethzero/Main.ui
  5. 20
      alethzero/MainWin.cpp
  6. 1
      alethzero/MainWin.h
  7. 4
      eth/main.cpp
  8. 4
      evmjit/libevmjit/ExecutionEngine.cpp
  9. 21
      exp/CMakeLists.txt
  10. 26
      exp/main.cpp
  11. 1
      libdevcore/CMakeLists.txt
  12. 2
      libdevcore/Common.cpp
  13. 6
      libdevcore/CommonIO.cpp
  14. 2
      libdevcore/CommonIO.h
  15. 1
      libdevcore/RangeMask.h
  16. 4
      libdevcore/TransientDirectory.cpp
  17. 4
      libdevcore/TransientDirectory.h
  18. 2
      libethash/util.h
  19. 7
      libethcore/BlockInfo.cpp
  20. 4
      libethcore/BlockInfo.h
  21. 38
      libethcore/Ethasher.cpp
  22. 2
      libethcore/Ethasher.h
  23. 146
      libethcore/ProofOfWork.cpp
  24. 40
      libethcore/ProofOfWork.h
  25. 2
      libethereum/BlockChain.cpp
  26. 7
      libethereum/CMakeLists.txt
  27. 33
      libethereum/Client.cpp
  28. 20
      libethereum/Client.h
  29. 2
      libethereum/ClientBase.cpp
  30. 3
      libethereum/ClientBase.h
  31. 4
      libethereum/Interface.h
  32. 4
      libethereum/Miner.cpp
  33. 13
      libethereum/Miner.h
  34. 27
      libethereum/State.cpp
  35. 22
      libethereum/State.h
  36. 2
      libtestutils/BlockChainLoader.h
  37. 2
      libtestutils/StateLoader.h
  38. 84
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  39. 1
      libweb3jsonrpc/WebThreeStubServerBase.h
  40. 7
      libweb3jsonrpc/abstractwebthreestubserver.h
  41. 5
      libweb3jsonrpc/spec.json
  42. 7
      mix/MixClient.cpp
  43. 3
      mix/MixClient.h
  44. 4
      mix/qml/DebugInfoList.qml
  45. 107
      mix/qml/Debugger.qml
  46. 21
      mix/qml/StatusPane.qml
  47. 122
      mix/qml/StepActionImage.qml
  48. 12
      mix/qml/html/cm/solarized.css
  49. BIN
      mix/qml/img/closedtriangleindicator.png
  50. BIN
      mix/qml/img/closedtriangleindicator@2x.png
  51. BIN
      mix/qml/img/opentriangleindicator.png
  52. BIN
      mix/qml/img/opentriangleindicator@2x.png
  53. BIN
      mix/qml/img/signerroricon32.png
  54. BIN
      mix/qml/img/warningicon.png
  55. BIN
      mix/qml/img/warningicon@2x.png
  56. 5
      mix/res.qrc
  57. 1
      test/TestUtils.cpp
  58. 9
      test/blockchain.cpp
  59. 2
      test/state.cpp
  60. 5
      test/stateOriginal.cpp
  61. 2
      test/vm.cpp
  62. 10
      test/webthreestubclient.h

13
CMakeLists.txt

@ -62,6 +62,8 @@ function(configureProject)
if (GUI) if (GUI)
add_definitions(-DETH_GUI) add_definitions(-DETH_GUI)
endif() endif()
add_definitions(-DETH_TRUE)
endfunction() endfunction()
set(CPPETHEREUM 1) set(CPPETHEREUM 1)
@ -134,7 +136,6 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
endif () endif ()
createDefaultCacheConfig() createDefaultCacheConfig()
configureProject()
# Force chromium. # Force chromium.
set (ETH_HAVE_WEBENGINE 1) set (ETH_HAVE_WEBENGINE 1)
@ -261,6 +262,8 @@ elseif (BUNDLE STREQUAL "user")
set(TESTS OFF) set(TESTS OFF)
endif () endif ()
configureProject()
# Default CMAKE_BUILD_TYPE to "Release". # Default CMAKE_BUILD_TYPE to "Release".
set(CMAKE_BUILD_TYPE CACHE STRING "Release") set(CMAKE_BUILD_TYPE CACHE STRING "Release")
if ("x${CMAKE_BUILD_TYPE}" STREQUAL "x") if ("x${CMAKE_BUILD_TYPE}" STREQUAL "x")
@ -270,7 +273,11 @@ endif ()
# Default TARGET_PLATFORM to "linux". # Default TARGET_PLATFORM to "linux".
set(TARGET_PLATFORM CACHE STRING "linux") set(TARGET_PLATFORM CACHE STRING "linux")
if ("x${TARGET_PLATFORM}" STREQUAL "x") if ("x${TARGET_PLATFORM}" STREQUAL "x")
set(TARGET_PLATFORM "linux") if (WIN32)
set(TARGET_PLATFORM "windows")
else ()
set(TARGET_PLATFORM "linux")
endif ()
endif () endif ()
message("------------------------------------------------------------------------") message("------------------------------------------------------------------------")
@ -306,7 +313,7 @@ include(EthCompilerSettings)
message("-- CXXFLAGS: ${CMAKE_CXX_FLAGS}") message("-- CXXFLAGS: ${CMAKE_CXX_FLAGS}")
# this must be an include, as a function it would messs up with variable scope! # this must be an include, as a function it would mess up with variable scope!
include(EthDependencies) include(EthDependencies)
include(EthExecutableHelper) include(EthExecutableHelper)

55
alethzero/DappLoader.cpp

@ -25,6 +25,7 @@
#include <QStringList> #include <QStringList>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QMimeDatabase>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libdevcrypto/CryptoPP.h> #include <libdevcrypto/CryptoPP.h>
@ -96,13 +97,31 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri)
void DappLoader::downloadComplete(QNetworkReply* _reply) void DappLoader::downloadComplete(QNetworkReply* _reply)
{ {
QUrl requestUrl = _reply->request().url();
if (m_pageUrls.count(requestUrl) != 0)
{
//inject web3 js
QByteArray content = "<script>\n";
content.append(web3Content());
content.append("</script>\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
{ {
//try to interpret as rlp //try to interpret as rlp
QByteArray data = _reply->readAll(); QByteArray data = _reply->readAll();
_reply->deleteLater(); _reply->deleteLater();
h256 expected = m_uriHashes[_reply->request().url()]; h256 expected = m_uriHashes[requestUrl];
bytes package(reinterpret_cast<unsigned char const*>(data.constData()), reinterpret_cast<unsigned char const*>(data.constData() + data.size())); bytes package(reinterpret_cast<unsigned char const*>(data.constData()), reinterpret_cast<unsigned char const*>(data.constData() + data.size()));
Secp256k1 dec; Secp256k1 dec;
dec.decrypt(expected, package); dec.decrypt(expected, package);
@ -144,15 +163,7 @@ void DappLoader::loadDapp(RLP const& _rlp)
if (entry->path == "/deployment.js") if (entry->path == "/deployment.js")
{ {
//inject web3 code //inject web3 code
QString code; bytes b(web3Content().data(), web3Content().data() + web3Content().size());
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());
b.insert(b.end(), content.begin(), content.end()); b.insert(b.end(), content.begin(), content.end());
dapp.content[hash] = b; dapp.content[hash] = b;
} }
@ -165,6 +176,22 @@ void DappLoader::loadDapp(RLP const& _rlp)
emit dappReady(dapp); 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) Manifest DappLoader::loadManifest(std::string const& _manifest)
{ {
/// https://github.com/ethereum/go-ethereum/wiki/URL-Scheme /// https://github.com/ethereum/go-ethereum/wiki/URL-Scheme
@ -216,3 +243,11 @@ void DappLoader::loadDapp(QString const& _uri)
m_net.get(request); m_net.get(request);
} }
void DappLoader::loadPage(QString const& _uri)
{
QUrl uri(_uri);
QNetworkRequest request(uri);
m_pageUrls.insert(uri);
m_net.get(request);
}

7
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 ///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 ///@param _uri Eth name path
void loadDapp(QString const& _uri); void loadDapp(QString const& _uri);
///Load a regular html page
///@param _uri Page Uri
void loadPage(QString const& _uri);
signals: signals:
void dappReady(Dapp& _dapp); void dappReady(Dapp& _dapp);
void pageReady(QByteArray const& _content, QString const& _mimeType, QUrl const& _uri);
void dappError(); void dappError();
private slots: private slots:
@ -86,9 +90,12 @@ private:
DappLocation resolveAppUri(QString const& _uri); DappLocation resolveAppUri(QString const& _uri);
void loadDapp(dev::RLP const& _rlp); void loadDapp(dev::RLP const& _rlp);
Manifest loadManifest(std::string const& _manifest); Manifest loadManifest(std::string const& _manifest);
QByteArray const& web3Content();
dev::WebThreeDirect* m_web3; dev::WebThreeDirect* m_web3;
QNetworkAccessManager m_net; QNetworkAccessManager m_net;
std::map<QUrl, dev::h256> m_uriHashes; std::map<QUrl, dev::h256> m_uriHashes;
std::set<QUrl> m_pageUrls;
QByteArray m_web3Js;
}; };

18
alethzero/Main.ui

@ -150,6 +150,7 @@
<string>&amp;Tools</string> <string>&amp;Tools</string>
</property> </property>
<addaction name="mine"/> <addaction name="mine"/>
<addaction name="turboMining"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="newTransaction"/> <addaction name="newTransaction"/>
<addaction name="newAccount"/> <addaction name="newAccount"/>
@ -176,7 +177,6 @@
<addaction name="killBlockchain"/> <addaction name="killBlockchain"/>
<addaction name="inject"/> <addaction name="inject"/>
<addaction name="forceMining"/> <addaction name="forceMining"/>
<addaction name="turboMining"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="usePrivate"/> <addaction name="usePrivate"/>
<addaction name="jitvm"/> <addaction name="jitvm"/>
@ -1608,14 +1608,6 @@ font-size: 14pt</string>
<string>&amp;Enable LLL Optimizer</string> <string>&amp;Enable LLL Optimizer</string>
</property> </property>
</action> </action>
<action name="turboMining">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Reserved Debug 1</string>
</property>
</action>
<action name="localNetworking"> <action name="localNetworking">
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
@ -1679,6 +1671,14 @@ font-size: 14pt</string>
<string>&amp;NatSpec Enabled</string> <string>&amp;NatSpec Enabled</string>
</property> </property>
</action> </action>
<action name="turboMining">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;GPU Mining</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>

20
alethzero/MainWin.cpp

@ -183,13 +183,6 @@ Main::Main(QWidget *parent) :
m_webPage = webPage; m_webPage = webPage;
connect(webPage, &WebPage::consoleMessage, [this](QString const& _msg) { Main::addConsoleMessage(_msg, QString()); }); connect(webPage, &WebPage::consoleMessage, [this](QString const& _msg) { Main::addConsoleMessage(_msg, QString()); });
ui->webView->setPage(m_webPage); 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, [=]() connect(ui->webView, &QWebEngineView::titleChanged, [=]()
{ {
@ -199,6 +192,7 @@ Main::Main(QWidget *parent) :
m_dappHost.reset(new DappHost(8081)); m_dappHost.reset(new DappHost(8081));
m_dappLoader = new DappLoader(this, web3()); m_dappLoader = new DappLoader(this, web3());
connect(m_dappLoader, &DappLoader::dappReady, this, &Main::dappLoaded); connect(m_dappLoader, &DappLoader::dappReady, this, &Main::dappLoaded);
connect(m_dappLoader, &DappLoader::pageReady, this, &Main::pageLoaded);
// ui->webView->page()->settings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, true); // ui->webView->page()->settings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, true);
// QWebEngineInspector* inspector = new QWebEngineInspector(); // QWebEngineInspector* inspector = new QWebEngineInspector();
// inspector->setPage(page); // inspector->setPage(page);
@ -713,6 +707,7 @@ void Main::writeSettings()
s.setValue("upnp", ui->upnp->isChecked()); s.setValue("upnp", ui->upnp->isChecked());
s.setValue("forceAddress", ui->forcePublicIP->text()); s.setValue("forceAddress", ui->forcePublicIP->text());
s.setValue("forceMining", ui->forceMining->isChecked()); s.setValue("forceMining", ui->forceMining->isChecked());
s.setValue("turboMining", ui->turboMining->isChecked());
s.setValue("paranoia", ui->paranoia->isChecked()); s.setValue("paranoia", ui->paranoia->isChecked());
s.setValue("natSpec", ui->natSpec->isChecked()); s.setValue("natSpec", ui->natSpec->isChecked());
s.setValue("showAll", ui->showAll->isChecked()); s.setValue("showAll", ui->showAll->isChecked());
@ -783,6 +778,8 @@ void Main::readSettings(bool _skipGeometry)
ui->dropPeers->setChecked(false); ui->dropPeers->setChecked(false);
ui->forceMining->setChecked(s.value("forceMining", false).toBool()); ui->forceMining->setChecked(s.value("forceMining", false).toBool());
on_forceMining_triggered(); on_forceMining_triggered();
ui->turboMining->setChecked(s.value("turboMining", false).toBool());
on_turboMining_triggered();
ui->paranoia->setChecked(s.value("paranoia", false).toBool()); ui->paranoia->setChecked(s.value("paranoia", false).toBool());
ui->natSpec->setChecked(s.value("natSpec", true).toBool()); ui->natSpec->setChecked(s.value("natSpec", true).toBool());
ui->showAll->setChecked(s.value("showAll", false).toBool()); ui->showAll->setChecked(s.value("showAll", false).toBool());
@ -918,6 +915,7 @@ void Main::on_urlEdit_returnPressed()
{ {
//try do resolve dapp url //try do resolve dapp url
m_dappLoader->loadDapp(s); m_dappLoader->loadDapp(s);
return;
} }
catch (...) catch (...)
{ {
@ -931,8 +929,7 @@ void Main::on_urlEdit_returnPressed()
else else
url.setScheme("http"); url.setScheme("http");
else {} else {}
qDebug() << url.toString(); m_dappLoader->loadPage(url.toString());
ui->webView->page()->setUrl(url);
} }
void Main::on_nameReg_textChanged() void Main::on_nameReg_textChanged()
@ -2016,3 +2013,8 @@ void Main::dappLoaded(Dapp& _dapp)
QUrl url = m_dappHost->hostDapp(std::move(_dapp)); QUrl url = m_dappHost->hostDapp(std::move(_dapp));
ui->webView->page()->setUrl(url); ui->webView->page()->setUrl(url);
} }
void Main::pageLoaded(QByteArray const& _content, QString const& _mimeType, QUrl const& _uri)
{
ui->webView->page()->setContent(_content, _mimeType, _uri);
}

1
alethzero/MainWin.h

@ -179,6 +179,7 @@ private slots:
// Dapps // Dapps
void dappLoaded(Dapp& _dapp); //qt does not support rvalue refs for signals void dappLoaded(Dapp& _dapp); //qt does not support rvalue refs for signals
void pageLoaded(QByteArray const& _content, QString const& _mimeType, QUrl const& _uri);
signals: signals:
void poll(); void poll();

4
eth/main.cpp

@ -273,7 +273,6 @@ int main(int argc, char** argv)
unsigned mining = ~(unsigned)0; unsigned mining = ~(unsigned)0;
int miners = -1; int miners = -1;
bool forceMining = false; bool forceMining = false;
bool turboMining = false;
KeyPair us = KeyPair::create(); KeyPair us = KeyPair::create();
Address coinbase = us.address(); Address coinbase = us.address();
@ -466,8 +465,6 @@ int main(int argc, char** argv)
bootstrap = true; bootstrap = true;
else if (arg == "-f" || arg == "--force-mining") else if (arg == "-f" || arg == "--force-mining")
forceMining = true; forceMining = true;
else if (arg == "-T" || arg == "--turbo-mining")
turboMining = true;
else if (arg == "-i" || arg == "--interactive") else if (arg == "-i" || arg == "--interactive")
interactive = true; interactive = true;
#if ETH_JSONRPC #if ETH_JSONRPC
@ -632,7 +629,6 @@ int main(int argc, char** argv)
{ {
c->setGasPricer(gasPricer); c->setGasPricer(gasPricer);
c->setForceMining(forceMining); c->setForceMining(forceMining);
c->setTurboMining(turboMining);
c->setAddress(coinbase); c->setAddress(coinbase);
} }

4
evmjit/libevmjit/ExecutionEngine.cpp

@ -88,10 +88,10 @@ void parseOptions()
//cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler"); //cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler");
// FIXME: LLVM workaround: // 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 // "source" scheduler has a bug: http://llvm.org/bugs/show_bug.cgi?id=22304
auto envLine = std::getenv("EVMJIT"); 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; static const auto c_maxArgs = 20;
char const* argv[c_maxArgs] = {nullptr, }; char const* argv[c_maxArgs] = {nullptr, };
auto arg = std::strtok(&*commandLine.begin(), " "); auto arg = std::strtok(&*commandLine.begin(), " ");

21
exp/CMakeLists.txt

@ -10,8 +10,27 @@ set(EXECUTABLE exp)
add_executable(${EXECUTABLE} ${SRC_LIST}) 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} ethereum)
target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} p2p)
if (ETHASHCL)
target_link_libraries(${EXECUTABLE} ethash-cl)
target_link_libraries(${EXECUTABLE} ethash)
target_link_libraries(${EXECUTABLE} OpenCL)
endif()
install( TARGETS ${EXECUTABLE} DESTINATION bin) install( TARGETS ${EXECUTABLE} DESTINATION bin)

26
exp/main.cpp

@ -19,18 +19,26 @@
* @date 2014 * @date 2014
* Ethereum client. * Ethereum client.
*/ */
#if ETH_ETHASHCL
#define __CL_ENABLE_EXCEPTIONS
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS
#include "libethash-cl/cl.hpp"
#endif
#include <functional> #include <functional>
#include <libethereum/AccountDiff.h>
#include <libdevcore/RangeMask.h> #include <libdevcore/RangeMask.h>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libdevcrypto/TrieDB.h> #include <libdevcore/TransientDirectory.h>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libdevcrypto/TrieDB.h>
#include <libp2p/All.h> #include <libp2p/All.h>
#include <libethereum/DownloadMan.h> #include <libethcore/Ethasher.h>
#include <libethcore/ProofOfWork.h>
#include <libethereum/All.h> #include <libethereum/All.h>
#include <libethereum/AccountDiff.h>
#include <libethereum/DownloadMan.h>
#include <liblll/All.h> #include <liblll/All.h>
#include <libwhisper/WhisperPeer.h> #include <libwhisper/WhisperPeer.h>
#include <libwhisper/WhisperHost.h> #include <libwhisper/WhisperHost.h>
@ -101,6 +109,18 @@ int main()
#else #else
int main() int main()
{ {
#if ETH_ETHASHCL
EthashCL ecl;
BlockInfo genesis = CanonBlockChain::genesis();
genesis.difficulty = 1 << 18;
cdebug << (h256)u256((bigint(1) << 256) / genesis.difficulty);
std::pair<MineInfo, Ethash::Proof> r;
while (!r.first.completed)
r = ecl.mine(genesis, 1000);
cdebug << r.second.mixHash << r.second.nonce;
EthashCL::assignResult(r.second, genesis);
assert(EthashCPU::verify(genesis));
#endif
return 0; return 0;
} }
#endif #endif

1
libdevcore/CMakeLists.txt

@ -28,6 +28,7 @@ endif()
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES})
# transitive dependencies for windows executables # transitive dependencies for windows executables

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
namespace dev namespace dev
{ {
char const* Version = "0.9.6"; char const* Version = "0.9.7";
} }

6
libdevcore/CommonIO.cpp

@ -58,7 +58,7 @@ string dev::memDump(bytes const& _bytes, unsigned _width, bool _html)
} }
// Don't forget to delete[] later. // 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); std::ifstream is(_file, std::ifstream::binary);
if (!is) if (!is)
@ -68,8 +68,10 @@ bytesRef dev::contentsNew(std::string const& _file)
streamoff length = is.tellg(); streamoff length = is.tellg();
if (length == 0) // return early, MSVC does not like reading 0 bytes if (length == 0) // return early, MSVC does not like reading 0 bytes
return bytesRef(); return bytesRef();
if (!_dest.empty() && _dest.size() != (unsigned)length)
return bytesRef();
is.seekg (0, is.beg); 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.read((char*)ret.data(), length);
is.close(); is.close();
return ret; return ret;

2
libdevcore/CommonIO.h

@ -46,7 +46,7 @@ namespace dev
bytes contents(std::string const& _file); bytes contents(std::string const& _file);
std::string contentsString(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. /// 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. /// Write the given binary data into the given file, replacing the file if it pre-exists.
void writeFile(std::string const& _file, bytesConstRef _data); void writeFile(std::string const& _file, bytesConstRef _data);

1
libdevcore/RangeMask.h

@ -25,6 +25,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <assert.h>
namespace dev namespace dev
{ {

4
libtestutils/TransientDirectory.cpp → libdevcore/TransientDirectory.cpp

@ -20,11 +20,11 @@
*/ */
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <libdevcore/Exceptions.h> #include "Exceptions.h"
#include "TransientDirectory.h" #include "TransientDirectory.h"
#include "CommonIO.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::test;
TransientDirectory::TransientDirectory(): TransientDirectory::TransientDirectory():
TransientDirectory((boost::filesystem::temp_directory_path() / "eth_transient" / toString(FixedHash<4>::random())).string()) TransientDirectory((boost::filesystem::temp_directory_path() / "eth_transient" / toString(FixedHash<4>::random())).string())

4
libtestutils/TransientDirectory.h → libdevcore/TransientDirectory.h

@ -22,12 +22,9 @@
#pragma once #pragma once
#include <string> #include <string>
#include "Common.h"
namespace dev namespace dev
{ {
namespace test
{
/** /**
* @brief temporary directory implementation * @brief temporary directory implementation
@ -48,4 +45,3 @@ private:
}; };
} }
}

2
libethash/util.h

@ -29,7 +29,7 @@ extern "C" {
#ifdef _MSC_VER #ifdef _MSC_VER
void debugf(const char *str, ...); void debugf(const char *str, ...);
#else #else
#define debugf printf #define debugf(...) fprintf(stderr, __VA_ARGS__)
#endif #endif
static inline uint32_t min_u32(uint32_t a, uint32_t b) static inline uint32_t min_u32(uint32_t a, uint32_t b)

7
libethcore/BlockInfo.cpp

@ -75,6 +75,13 @@ h256 const& BlockInfo::hash() const
return m_hash; return m_hash;
} }
h256 const& BlockInfo::boundary() const
{
if (!m_boundary)
m_boundary = (h256)(u256)((bigint(1) << 256) / difficulty);
return m_boundary;
}
BlockInfo BlockInfo::fromHeader(bytesConstRef _header, Strictness _s, h256 const& _h) BlockInfo BlockInfo::fromHeader(bytesConstRef _header, Strictness _s, h256 const& _h)
{ {
BlockInfo ret; BlockInfo ret;

4
libethcore/BlockInfo.h

@ -118,7 +118,7 @@ public:
void clear(); void clear();
void noteDirty() const { m_hash = m_seedHash = h256(); } void noteDirty() const { m_hash = m_seedHash = m_boundary = h256(); }
void populateFromHeader(RLP const& _header, Strictness _s = IgnoreNonce, h256 const& _h = h256()); void populateFromHeader(RLP const& _header, Strictness _s = IgnoreNonce, h256 const& _h = h256());
void populate(bytesConstRef _block, Strictness _s = IgnoreNonce, h256 const& _h = h256()); void populate(bytesConstRef _block, Strictness _s = IgnoreNonce, h256 const& _h = h256());
@ -131,6 +131,7 @@ public:
u256 selectGasLimit(BlockInfo const& _parent) const; u256 selectGasLimit(BlockInfo const& _parent) const;
h256 const& seedHash() const; h256 const& seedHash() const;
h256 const& hash() const; h256 const& hash() const;
h256 const& boundary() const;
/// sha3 of the header only. /// sha3 of the header only.
h256 headerHash(IncludeNonce _n) const; h256 headerHash(IncludeNonce _n) const;
@ -139,6 +140,7 @@ public:
private: private:
mutable h256 m_seedHash; mutable h256 m_seedHash;
mutable h256 m_hash; ///< SHA3 hash of the block header! Not serialised. mutable h256 m_hash; ///< SHA3 hash of the block header! Not serialised.
mutable h256 m_boundary; ///< 2^256 / difficulty
}; };
inline std::ostream& operator<<(std::ostream& _out, BlockInfo const& _bi) inline std::ostream& operator<<(std::ostream& _out, BlockInfo const& _bi)

38
libethcore/Ethasher.cpp

@ -123,6 +123,44 @@ ethash_params Ethasher::params(BlockInfo const& _header)
return params((unsigned)_header.number); 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 Ethasher::params(unsigned _n)
{ {
ethash_params p; ethash_params p;

2
libethcore/Ethasher.h

@ -56,6 +56,8 @@ public:
static ethash_params params(BlockInfo const& _header); static ethash_params params(BlockInfo const& _header);
static ethash_params params(unsigned _n); static ethash_params params(unsigned _n);
void readFull(BlockInfo const& _header, void* _dest);
struct Result struct Result
{ {
h256 value; h256 value;

146
libethcore/ProofOfWork.cpp

@ -33,32 +33,6 @@
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#if ETH_ETHASHCL #if ETH_ETHASHCL
#include <libethash-cl/ethash_cl_miner.h> #include <libethash-cl/ethash_cl_miner.h>
#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 #endif
#include "BlockInfo.h" #include "BlockInfo.h"
#include "Ethasher.h" #include "Ethasher.h"
@ -71,12 +45,12 @@ namespace dev
namespace eth namespace eth
{ {
bool EthashCPU::verify(BlockInfo const& _header) bool EthashPoW::verify(BlockInfo const& _header)
{ {
return Ethasher::verify(_header); return Ethasher::verify(_header);
} }
std::pair<MineInfo, EthashCPU::Proof> EthashCPU::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo) std::pair<MineInfo, EthashCPU::Proof> EthashCPU::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue)
{ {
Ethasher::Miner m(_header); Ethasher::Miner m(_header);
@ -93,8 +67,6 @@ std::pair<MineInfo, EthashCPU::Proof> EthashCPU::mine(BlockInfo const& _header,
// //
// evaluate until we run out of time // evaluate until we run out of time
auto startTime = std::chrono::steady_clock::now(); auto startTime = std::chrono::steady_clock::now();
if (!_turbo)
std::this_thread::sleep_for(std::chrono::milliseconds(_msTimeout * 90 / 100));
double best = 1e99; // high enough to be effectively infinity :) double best = 1e99; // high enough to be effectively infinity :)
Proof result; Proof result;
unsigned hashCount = 0; unsigned hashCount = 0;
@ -128,19 +100,19 @@ std::pair<MineInfo, EthashCPU::Proof> EthashCPU::mine(BlockInfo const& _header,
return ret; return ret;
} }
#if ETH_ETHASHCL #if ETH_ETHASHCL || !ETH_TRUE
/* /*
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 class ethash_cl_miner
{ {
public: 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(); ethash_cl_miner();
bool init(ethash_params const& params, const uint8_t seed[32], unsigned workgroup_size = 64); bool init(ethash_params const& params, const uint8_t seed[32], unsigned workgroup_size = 64);
@ -150,77 +122,87 @@ 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;
cdebug << "Attempting to abort";
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<Nonce> fetchFound() { vector<Nonce> 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); Guard l(x_all);
for (unsigned i = 0; i < _count; ++i) for (unsigned i = 0; i < _count; ++i)
found.push_back((Nonce)(u64)_nonces[i]); m_found.push_back((Nonce)(u64)_nonces[i]);
if (abort) m_aborted = true;
{ cdebug << "Found nonces: " << vector<uint64_t>(_nonces, _nonces + _count);
aborted = true; return true;
return true;
}
return false;
} }
virtual bool searched(uint64_t _startNonce, uint32_t _count) virtual bool searched(uint64_t _startNonce, uint32_t _count) override
{ {
Guard l(x_all); Guard l(x_all);
total += _count; cdebug << "Searched" << _count << "from" << _startNonce;
last = _startNonce + _count; m_total += _count;
if (abort) m_last = _startNonce + _count;
if (m_abort)
{ {
aborted = true; m_aborted = true;
return true; return true;
} }
return false; return false;
} }
vector<Nonce> fetchFound() { vector<Nonce> ret; Guard l(x_all); std::swap(ret, found); return ret; } private:
uint64_t fetchTotal() { Guard l(x_all); auto ret = total; total = 0; return ret; }
Mutex x_all; Mutex x_all;
vector<Nonce> found; vector<Nonce> m_found;
uint64_t total; uint64_t m_total;
uint64_t last; uint64_t m_last;
bool abort = false; bool m_abort = false;
bool aborted = false; bool m_aborted = true;
}; };
EthashCL::EthashCL(): EthashCL::EthashCL():
m_miner(new ethash_cl_miner),
m_hook(new EthashCLHook) m_hook(new EthashCLHook)
{ {
} }
EthashCL::~EthashCL() 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)
{
return Ethasher::verify(_header);
} }
std::pair<MineInfo, Ethash::Proof> EthashCL::mine(BlockInfo const& _header, unsigned _msTimeout, bool, bool) std::pair<MineInfo, Ethash::Proof> EthashCL::mine(BlockInfo const& _header, unsigned _msTimeout, bool)
{ {
if (m_lastHeader.seedHash() != _header.seedHash()) if (!m_lastHeader || m_lastHeader.seedHash() != _header.seedHash())
{ {
m_miner->init(Ethasher::params(_header), _header.seedHash().data()); if (m_miner)
// TODO: reinit probably won't work when seed changes. m_hook->abort();
m_miner.reset(new ethash_cl_miner);
auto cb = [&](void* d) {
Ethasher::get()->readFull(_header, d);
};
m_miner->init(Ethasher::params(_header), cb, 32);
} }
if (m_lastHeader != _header) if (m_lastHeader != _header)
{ {
m_hook->abort();
static std::random_device s_eng; static std::random_device s_eng;
uint64_t tryNonce = (uint64_t)(u64)(m_last = Nonce::random(s_eng)); auto hh = _header.headerHash(WithoutNonce);
m_miner->search(_header.headerHash(WithoutNonce).data(), tryNonce, *m_hook); uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)_header.boundary() >> 192);
m_miner->search(hh.data(), upper64OfBoundary, *m_hook);
} }
m_lastHeader = _header; m_lastHeader = _header;
@ -228,10 +210,14 @@ std::pair<MineInfo, Ethash::Proof> EthashCL::mine(BlockInfo const& _header, unsi
auto found = m_hook->fetchFound(); auto found = m_hook->fetchFound();
if (!found.empty()) if (!found.empty())
{ {
h256 mixHash; // ????? for (auto const& n: found)
return std::make_pair(MineInfo{0.0, 1e99, 0, true}, EthashCL::Proof((Nonce)(u64)found[0], mixHash)); {
auto result = Ethasher::eval(_header, n);
if (result.value < _header.boundary())
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 #endif

40
libethcore/ProofOfWork.h

@ -42,6 +42,8 @@ namespace eth
struct MineInfo 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; } 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 requirement = 0;
double best = 1e99; double best = 1e99;
@ -49,7 +51,7 @@ struct MineInfo
bool completed = false; bool completed = false;
}; };
class EthashCPU class EthashPoW
{ {
public: public:
struct Proof struct Proof
@ -59,36 +61,39 @@ public:
}; };
static bool verify(BlockInfo const& _header); static bool verify(BlockInfo const& _header);
std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false);
static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; } static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; }
virtual unsigned defaultTimeout() const { return 100; }
virtual std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true) = 0;
};
class EthashCPU: public EthashPoW
{
public:
std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true) override;
protected: protected:
Nonce m_last; Nonce m_last;
}; };
#if ETH_ETHASHCL #if ETH_ETHASHCL || !ETH_TRUE
class EthashCL class EthashCLHook;
class EthashCL: public EthashPoW
{ {
public: public:
struct Proof
{
Nonce nonce;
h256 mixHash;
};
EthashCL(); EthashCL();
~EthashCL(); ~EthashCL();
static bool verify(BlockInfo const& _header); std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true) override;
std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false); unsigned defaultTimeout() const override { return 500; }
static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; }
protected: protected:
Nonce m_last; Nonce m_last;
BlockInfo m_lastHeader; BlockInfo m_lastHeader;
Nonce m_mined; Nonce m_mined;
std::unique_ptr<ethash_cl_miner> m_miner; std::unique_ptr<ethash_cl_miner> m_miner;
std::unique_ptr<ethash_cl_search_hook> m_hook; std::unique_ptr<EthashCLHook> m_hook;
}; };
using Ethash = EthashCL; using Ethash = EthashCL;
@ -103,8 +108,9 @@ public:
using Proof = Nonce; using Proof = Nonce;
static bool verify(BlockInfo const& _header) { return (bigint)(u256)Evaluator::eval(_header.headerHash(WithoutNonce), _header.nonce) <= (bigint(1) << 256) / _header.difficulty; } static bool verify(BlockInfo const& _header) { return (bigint)(u256)Evaluator::eval(_header.headerHash(WithoutNonce), _header.nonce) <= (bigint(1) << 256) / _header.difficulty; }
inline std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false); inline std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true);
static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r; } static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r; }
unsigned defaultTimeout() const { return 100; }
protected: protected:
Nonce m_last; Nonce m_last;
@ -121,7 +127,7 @@ using SHA3ProofOfWork = ProofOfWorkEngine<SHA3Evaluator>;
using ProofOfWork = Ethash; using ProofOfWork = Ethash;
template <class Evaluator> template <class Evaluator>
std::pair<MineInfo, typename ProofOfWorkEngine<Evaluator>::Proof> ProofOfWorkEngine<Evaluator>::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo) std::pair<MineInfo, typename ProofOfWorkEngine<Evaluator>::Proof> ProofOfWorkEngine<Evaluator>::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue)
{ {
auto headerHashWithoutNonce = _header.headerHash(WithoutNonce); auto headerHashWithoutNonce = _header.headerHash(WithoutNonce);
auto difficulty = _header.difficulty; auto difficulty = _header.difficulty;
@ -138,8 +144,6 @@ std::pair<MineInfo, typename ProofOfWorkEngine<Evaluator>::Proof> ProofOfWorkEng
// //
// evaluate until we run out of time // evaluate until we run out of time
auto startTime = std::chrono::steady_clock::now(); auto startTime = std::chrono::steady_clock::now();
if (!_turbo)
std::this_thread::sleep_for(std::chrono::milliseconds(_msTimeout * 90 / 100));
double best = 1e99; // high enough to be effectively infinity :) double best = 1e99; // high enough to be effectively infinity :)
ProofOfWorkEngine<Evaluator>::Proof solution; ProofOfWorkEngine<Evaluator>::Proof solution;
unsigned h = 0; unsigned h = 0;

2
libethereum/BlockChain.cpp

@ -601,7 +601,7 @@ pair<h256s, h256> BlockChain::import(bytes const& _block, OverlayDB const& _db,
m_extrasDB->Put(m_writeOptions, toSlice(h, ExtraTransactionAddress), (ldb::Slice)dev::ref(m_transactionAddresses[h].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(h, ExtraTransactionAddress), (ldb::Slice)dev::ref(m_transactionAddresses[h].rlp()));
} }
clog(BlockChainNote) << " Imported and best" << td << ". Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << toString(route); clog(BlockChainNote) << " Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << toString(route);
noteCanonChanged(); noteCanonChanged();
StructuredLogger::chainNewHead( StructuredLogger::chainNewHead(

7
libethereum/CMakeLists.txt

@ -25,19 +25,18 @@ else()
add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
endif() endif()
target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES})
target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} evm)
target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} lll)
target_link_libraries(${EXECUTABLE} whisper) target_link_libraries(${EXECUTABLE} whisper)
target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} p2p)
target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcrypto)
target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES})
target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} secp256k1)
if (ETHASHCL) if (ETHASHCL)
target_link_libraries(${EXECUTABLE} ethash-cl) target_link_libraries(${EXECUTABLE} ethash-cl)
target_link_libraries(${EXECUTABLE} OpenCL)
endif () endif ()
if (CMAKE_COMPILER_IS_MINGW) if (CMAKE_COMPILER_IS_MINGW)

33
libethereum/Client.cpp

@ -259,16 +259,28 @@ void Client::clearPending()
noteChanged(changeds); noteChanged(changeds);
} }
template <class T>
static string filtersToString(T const& _fs)
{
stringstream ret;
ret << "{";
unsigned i = 0;
for (h256 const& f: _fs)
ret << (i++ ? ", " : "") << (f == PendingChangedFilter ? "pending" : f == ChainChangedFilter ? "chain" : f.abridged());
ret << "}";
return ret.str();
}
void Client::noteChanged(h256Set const& _filters) void Client::noteChanged(h256Set const& _filters)
{ {
Guard l(x_filtersWatches); Guard l(x_filtersWatches);
if (_filters.size()) if (_filters.size())
cnote << "noteChanged(" << _filters << ")"; cnote << "noteChanged(" << filtersToString(_filters) << ")";
// accrue all changes left in each filter into the watches. // accrue all changes left in each filter into the watches.
for (auto& w: m_watches) for (auto& w: m_watches)
if (_filters.count(w.second.id)) if (_filters.count(w.second.id))
{ {
cwatch << "!!!" << w.first << w.second.id; cwatch << "!!!" << w.first << (m_filters.count(w.second.id) ? w.second.id.abridged() : w.second.id == PendingChangedFilter ? "pending" : w.second.id == ChainChangedFilter ? "chain" : "???");
if (m_filters.count(w.second.id)) // Normal filtering watch if (m_filters.count(w.second.id)) // Normal filtering watch
w.second.changes += m_filters.at(w.second.id).changes; w.second.changes += m_filters.at(w.second.id).changes;
else // Special ('pending'/'latest') watch else // Special ('pending'/'latest') watch
@ -333,10 +345,10 @@ void Client::setForceMining(bool _enable)
void Client::setMiningThreads(unsigned _threads) void Client::setMiningThreads(unsigned _threads)
{ {
stopMining(); stopMining();
#if ETH_ETHASHCL
unsigned t = 1;
#else
auto t = _threads ? _threads : thread::hardware_concurrency(); auto t = _threads ? _threads : thread::hardware_concurrency();
#if ETH_ETHASHCL || !ETH_TRUE
if (m_turboMining)
t = 1;
#endif #endif
WriteGuard l(x_localMiners); WriteGuard l(x_localMiners);
m_localMiners.clear(); m_localMiners.clear();
@ -355,6 +367,15 @@ MineProgress Client::miningProgress() const
return ret; return ret;
} }
uint64_t Client::hashrate() const
{
uint64_t ret = 0;
ReadGuard l(x_localMiners);
for (LocalMiner const& m: m_localMiners)
ret += m.miningProgress().hashes / m.miningProgress().ms;
return ret / 1000;
}
std::list<MineInfo> Client::miningHistory() std::list<MineInfo> Client::miningHistory()
{ {
std::list<MineInfo> ret; std::list<MineInfo> ret;
@ -522,7 +543,7 @@ void Client::doWork()
clog(ClientChat) << "Live block:" << h.abridged(); clog(ClientChat) << "Live block:" << h.abridged();
for (auto const& th: m_bc.transactionHashes(h)) for (auto const& th: m_bc.transactionHashes(h))
{ {
clog(ClientNote) << "Safely dropping transaction " << th; clog(ClientNote) << "Safely dropping transaction " << th.abridged();
m_tq.drop(th); m_tq.drop(th);
} }
} }

20
libethereum/Client.h

@ -188,25 +188,27 @@ public:
bool forceMining() const { return m_forceMining; } bool forceMining() const { return m_forceMining; }
/// Enable/disable forcing of mining to happen, even without transactions. /// Enable/disable forcing of mining to happen, even without transactions.
void setForceMining(bool _enable); void setForceMining(bool _enable);
/// Are we mining as fast as we can? /// Are we allowed to GPU mine?
bool turboMining() const { return m_turboMining; } bool turboMining() const { return m_turboMining; }
/// Enable/disable fast mining. /// Enable/disable GPU mining.
void setTurboMining(bool _enable = true) { m_turboMining = _enable; } void setTurboMining(bool _enable = true) { bool was = isMining(); stopMining(); m_turboMining = _enable; setMiningThreads(0); if (was) startMining(); }
/// Stops mining and sets the number of mining threads (0 for automatic). /// Stops mining and sets the number of mining threads (0 for automatic).
virtual void setMiningThreads(unsigned _threads = 0); void setMiningThreads(unsigned _threads = 0) override;
/// Get the effective number of mining threads. /// Get the effective number of mining threads.
virtual unsigned miningThreads() const { ReadGuard l(x_localMiners); return m_localMiners.size(); } unsigned miningThreads() const override { ReadGuard l(x_localMiners); return m_localMiners.size(); }
/// Start mining. /// Start mining.
/// NOT thread-safe - call it & stopMining only from a single thread /// NOT thread-safe - call it & stopMining only from a single thread
virtual void startMining() { startWorking(); { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.start(); } } void startMining() override { startWorking(); { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.start(); } }
/// Stop mining. /// Stop mining.
/// NOT thread-safe /// NOT thread-safe
virtual void stopMining() { { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.stop(); } } void stopMining() override { { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.stop(); } }
/// Are we mining now? /// Are we mining now?
virtual bool isMining() { { ReadGuard l(x_localMiners); if (!m_localMiners.empty() && m_localMiners[0].isRunning()) return true; } return false; } bool isMining() const override { { ReadGuard l(x_localMiners); if (!m_localMiners.empty() && m_localMiners[0].isRunning()) return true; } return false; }
/// Are we mining now?
uint64_t hashrate() const override;
/// Check the progress of the mining. /// Check the progress of the mining.
virtual MineProgress miningProgress() const; MineProgress miningProgress() const override;
/// Get and clear the mining history. /// Get and clear the mining history.
std::list<MineInfo> miningHistory(); std::list<MineInfo> miningHistory();

2
libethereum/ClientBase.cpp

@ -75,7 +75,7 @@ ExecutionResult ClientBase::call(Secret _secret, u256 _value, Address _dest, byt
u256 n = temp.transactionsFrom(a); u256 n = temp.transactionsFrom(a);
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret);
if (_ff == FudgeFactor::Lenient) 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); ret = temp.execute(bc().lastHashes(), t, Permanence::Reverted);
} }
catch (...) catch (...)

3
libethereum/ClientBase.h

@ -146,7 +146,8 @@ public:
virtual unsigned miningThreads() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::miningThreads")); } virtual unsigned miningThreads() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::miningThreads")); }
virtual void startMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::startMining")); } virtual void startMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::startMining")); }
virtual void stopMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::stopMining")); } virtual void stopMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::stopMining")); }
virtual bool isMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::isMining")); } virtual bool isMining() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::isMining")); }
virtual uint64_t hashrate() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::hashrate")); }
virtual eth::MineProgress miningProgress() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::miningProgress")); } virtual eth::MineProgress miningProgress() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::miningProgress")); }
virtual std::pair<h256, u256> getWork() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::getWork")); } virtual std::pair<h256, u256> getWork() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::getWork")); }
virtual bool submitWork(eth::ProofOfWork::Proof const&) override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::submitWork")); } virtual bool submitWork(eth::ProofOfWork::Proof const&) override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::submitWork")); }

4
libethereum/Interface.h

@ -183,7 +183,9 @@ public:
/// NOT thread-safe /// NOT thread-safe
virtual void stopMining() = 0; virtual void stopMining() = 0;
/// Are we mining now? /// Are we mining now?
virtual bool isMining() = 0; virtual bool isMining() const = 0;
/// Current hash rate.
virtual uint64_t hashrate() const = 0;
/// Get hash of the current block to be mined minus the nonce (the 'work hash'). /// Get hash of the current block to be mined minus the nonce (the 'work hash').
virtual std::pair<h256, u256> getWork() = 0; virtual std::pair<h256, u256> getWork() = 0;

4
libethereum/Miner.cpp

@ -34,12 +34,14 @@ LocalMiner::LocalMiner(MinerHost* _host, unsigned _id):
AsyncMiner(_host, _id), AsyncMiner(_host, _id),
Worker("miner-" + toString(_id)) Worker("miner-" + toString(_id))
{ {
m_pow.reset(_host->turbo() ? new Ethash : (Ethash*)new EthashCPU);
} }
void LocalMiner::setup(MinerHost* _host, unsigned _id) void LocalMiner::setup(MinerHost* _host, unsigned _id)
{ {
AsyncMiner::setup(_host, _id); AsyncMiner::setup(_host, _id);
setName("miner-" + toString(m_id)); setName("miner-" + toString(m_id));
m_pow.reset(_host->turbo() ? new Ethash : (Ethash*)new EthashCPU);
} }
void LocalMiner::doWork() void LocalMiner::doWork()
@ -66,7 +68,7 @@ void LocalMiner::doWork()
if (m_miningStatus == Mining) if (m_miningStatus == Mining)
{ {
// Mine for a while. // Mine for a while.
MineInfo mineInfo = m_mineState.mine(100, m_host->turbo()); MineInfo mineInfo = m_mineState.mine(m_pow.get());
{ {
Guard l(x_mineInfo); Guard l(x_mineInfo);

13
libethereum/Miner.h

@ -60,8 +60,8 @@ public:
virtual void setupState(State& _s) = 0; ///< Reset the given State object to the one that should be being mined. virtual void setupState(State& _s) = 0; ///< Reset the given State object to the one that should be being mined.
virtual void onProgressed() {} ///< Called once some progress has been made. virtual void onProgressed() {} ///< Called once some progress has been made.
virtual void onComplete() {} ///< Called once a block is found. virtual void onComplete() {} ///< Called once a block is found.
virtual bool turbo() const = 0; ///< @returns true iff the Miner should mine as fast as possible.
virtual bool force() const = 0; ///< @returns true iff the Miner should mine regardless of the number of transactions. virtual bool force() const = 0; ///< @returns true iff the Miner should mine regardless of the number of transactions.
virtual bool turbo() const = 0; ///< @returns true iff the Miner should use GPU if possible.
}; };
class Miner class Miner
@ -93,7 +93,7 @@ public:
virtual void stop() {} virtual void stop() {}
/// @returns true iff the mining has been start()ed. It may still not be actually mining, depending on the host's turbo() & force(). /// @returns true iff the mining has been start()ed. It may still not be actually mining, depending on the host's turbo() & force().
virtual bool isRunning() { return false; } virtual bool isRunning() const { return false; }
protected: protected:
MinerHost* m_host = nullptr; ///< Our host. MinerHost* m_host = nullptr; ///< Our host.
@ -122,10 +122,10 @@ public:
LocalMiner(MinerHost* _host, unsigned _id = 0); LocalMiner(MinerHost* _host, unsigned _id = 0);
/// Move-constructor. /// Move-constructor.
LocalMiner(LocalMiner&& _m): Worker((Worker&&)_m) { std::swap(m_host, _m.m_host); } LocalMiner(LocalMiner&& _m): Worker((Worker&&)_m) { std::swap(m_host, _m.m_host); std::swap(m_pow, _m.m_pow); }
/// Move-assignment. /// Move-assignment.
LocalMiner& operator=(LocalMiner&& _m) { Worker::operator=((Worker&&)_m); std::swap(m_host, _m.m_host); return *this; } LocalMiner& operator=(LocalMiner&& _m) { Worker::operator=((Worker&&)_m); std::swap(m_host, _m.m_host); std::swap(m_pow, _m.m_pow); return *this; }
/// Destructor. Stops miner. /// Destructor. Stops miner.
~LocalMiner() { stop(); } ~LocalMiner() { stop(); }
@ -143,7 +143,7 @@ public:
virtual void noteStateChange() override { m_miningStatus = Preparing; } virtual void noteStateChange() override { m_miningStatus = Preparing; }
/// @returns true iff the mining has been start()ed. It may still not be actually mining, depending on the host's turbo() & force(). /// @returns true iff the mining has been start()ed. It may still not be actually mining, depending on the host's turbo() & force().
bool isRunning() { return isWorking(); } bool isRunning() const override { return isWorking(); }
/// @returns true if mining is complete. /// @returns true if mining is complete.
virtual bool isComplete() const override { return m_miningStatus == Mined; } virtual bool isComplete() const override { return m_miningStatus == Mined; }
@ -167,8 +167,9 @@ private:
enum MiningStatus { Waiting, Preparing, Mining, Mined, Stopping, Stopped }; enum MiningStatus { Waiting, Preparing, Mining, Mined, Stopping, Stopped };
MiningStatus m_miningStatus = Waiting; ///< TODO: consider mutex/atomic variable. MiningStatus m_miningStatus = Waiting; ///< TODO: consider mutex/atomic variable.
State m_mineState; ///< The state on which we are mining, generally equivalent to m_postMine. State m_mineState; ///< The state on which we are mining, generally equivalent to m_postMine.
std::unique_ptr<EthashPoW> m_pow; ///< Our miner.
mutable std::mutex x_mineInfo; ///< Lock for the mining progress & history. mutable Mutex x_mineInfo; ///< Lock for the mining progress & history.
MineProgress m_mineProgress; ///< What's our progress? MineProgress m_mineProgress; ///< What's our progress?
std::list<MineInfo> m_mineHistory; ///< What the history of our mining? std::list<MineInfo> m_mineHistory; ///< What the history of our mining?
}; };

27
libethereum/State.cpp

@ -451,7 +451,7 @@ bool State::cull(TransactionQueue& _tq) const
{ {
try try
{ {
if (i.second.nonce() <= transactionsFrom(i.second.sender())) if (i.second.nonce() < transactionsFrom(i.second.sender()))
{ {
_tq.drop(i.first); _tq.drop(i.first);
ret = true; ret = true;
@ -856,33 +856,12 @@ void State::commitToMine(BlockChain const& _bc)
m_committedToMine = true; m_committedToMine = true;
} }
MineInfo State::mine(unsigned _msTimeout, bool _turbo)
{
// Update difficulty according to timestamp.
m_currentBlock.difficulty = m_currentBlock.calculateDifficulty(m_previousBlock);
MineInfo ret;
// TODO: Miner class that keeps dagger between mine calls (or just non-polling mining).
ProofOfWork::Proof r;
tie(ret, r) = m_pow.mine(m_currentBlock, _msTimeout, true, _turbo);
if (!ret.completed)
m_currentBytes.clear();
else
{
ProofOfWork::assignResult(r, m_currentBlock);
cnote << "Completed" << m_currentBlock.headerHash(WithoutNonce).abridged() << m_currentBlock.nonce.abridged() << m_currentBlock.difficulty << ProofOfWork::verify(m_currentBlock);
}
return ret;
}
bool State::completeMine(ProofOfWork::Proof const& _nonce) bool State::completeMine(ProofOfWork::Proof const& _nonce)
{ {
ProofOfWork::assignResult(_nonce, m_currentBlock); ProofOfWork::assignResult(_nonce, m_currentBlock);
if (!m_pow.verify(m_currentBlock)) // if (!m_pow.verify(m_currentBlock))
return false; // return false;
cnote << "Completed" << m_currentBlock.headerHash(WithoutNonce).abridged() << m_currentBlock.nonce.abridged() << m_currentBlock.difficulty << ProofOfWork::verify(m_currentBlock); cnote << "Completed" << m_currentBlock.headerHash(WithoutNonce).abridged() << m_currentBlock.nonce.abridged() << m_currentBlock.difficulty << ProofOfWork::verify(m_currentBlock);

22
libethereum/State.h

@ -168,7 +168,25 @@ public:
/// This function is thread-safe. You can safely have other interactions with this object while it is happening. /// This function is thread-safe. You can safely have other interactions with this object while it is happening.
/// @param _msTimeout Timeout before return in milliseconds. /// @param _msTimeout Timeout before return in milliseconds.
/// @returns Information on the mining. /// @returns Information on the mining.
MineInfo mine(unsigned _msTimeout = 1000, bool _turbo = false); template <class ProofOfWork> MineInfo mine(ProofOfWork* _pow)
{
// Update difficulty according to timestamp.
m_currentBlock.difficulty = m_currentBlock.calculateDifficulty(m_previousBlock);
MineInfo ret;
typename ProofOfWork::Proof r;
std::tie(ret, r) = _pow->mine(m_currentBlock, _pow->defaultTimeout(), true);
if (!ret.completed)
m_currentBytes.clear();
else
{
ProofOfWork::assignResult(r, m_currentBlock);
cnote << "Completed" << m_currentBlock.headerHash(WithoutNonce).abridged() << m_currentBlock.nonce.abridged() << m_currentBlock.difficulty << ProofOfWork::verify(m_currentBlock);
}
return ret;
}
/** Commit to DB and build the final block if the previous call to mine()'s result is completion. /** Commit to DB and build the final block if the previous call to mine()'s result is completion.
* Typically looks like: * Typically looks like:
@ -371,8 +389,6 @@ private:
Address m_ourAddress; ///< Our address (i.e. the address to which fees go). Address m_ourAddress; ///< Our address (i.e. the address to which fees go).
ProofOfWork m_pow; ///< The PoW mining class.
u256 m_blockReward; u256 m_blockReward;
static std::string c_defaultPath; static std::string c_defaultPath;

2
libtestutils/BlockChainLoader.h

@ -22,9 +22,9 @@
#pragma once #pragma once
#include <string> #include <string>
#include <json/json.h> #include <json/json.h>
#include <libdevcore/TransientDirectory.h>
#include <libethereum/BlockChain.h> #include <libethereum/BlockChain.h>
#include <libethereum/State.h> #include <libethereum/State.h>
#include "TransientDirectory.h"
namespace dev namespace dev
{ {

2
libtestutils/StateLoader.h

@ -22,8 +22,8 @@
#pragma once #pragma once
#include <json/json.h> #include <json/json.h>
#include <libdevcore/TransientDirectory.h>
#include <libethereum/State.h> #include <libethereum/State.h>
#include "TransientDirectory.h"
namespace dev namespace dev
{ {

84
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -26,7 +26,7 @@
#include <jsonrpccpp/common/exception.h> #include <jsonrpccpp/common/exception.h>
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#if ETH_SOLIDITY #if ETH_SOLIDITY || !ETH_TRUE
#include <libsolidity/CompilerStack.h> #include <libsolidity/CompilerStack.h>
#include <libsolidity/Scanner.h> #include <libsolidity/Scanner.h>
#include <libsolidity/SourceReferenceFormatter.h> #include <libsolidity/SourceReferenceFormatter.h>
@ -38,7 +38,7 @@
#include <libethcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include <libwhisper/Message.h> #include <libwhisper/Message.h>
#include <libwhisper/WhisperHost.h> #include <libwhisper/WhisperHost.h>
#if ETH_SERPENT #if ETH_SERPENT || !ETH_TRUE
#include <libserpent/funcs.h> #include <libserpent/funcs.h>
#endif #endif
#include "WebThreeStubServerBase.h" #include "WebThreeStubServerBase.h"
@ -296,6 +296,11 @@ string WebThreeStubServerBase::eth_coinbase()
return toJS(client()->address()); return toJS(client()->address());
} }
string WebThreeStubServerBase::eth_hashrate()
{
return toJS(client()->hashrate());
}
bool WebThreeStubServerBase::eth_mining() bool WebThreeStubServerBase::eth_mining()
{ {
return client()->isMining(); return client()->isMining();
@ -449,64 +454,55 @@ static TransactionSkeleton toTransaction(Json::Value const& _json)
string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json) string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json)
{ {
TransactionSkeleton t;
try 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<u256>(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 (...) catch (...)
{ {
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); 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<u256>(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) string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const& _blockNumber)
{ {
TransactionSkeleton t;
int number;
try try
{ {
t = toTransaction(_json); TransactionSkeleton t = toTransaction(_json);
number = jsToBlockNumber(_blockNumber); 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 (...) catch (...)
{ {
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); 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() bool WebThreeStubServerBase::eth_flush()
@ -611,10 +607,10 @@ Json::Value WebThreeStubServerBase::eth_getCompilers()
{ {
Json::Value ret(Json::arrayValue); Json::Value ret(Json::arrayValue);
ret.append("lll"); ret.append("lll");
#if SOLIDITY #if ETH_SOLIDITY || !TRUE
ret.append("solidity"); ret.append("solidity");
#endif #endif
#if SERPENT #if ETH_SERPENT || !TRUE
ret.append("serpent"); ret.append("serpent");
#endif #endif
return ret; return ret;
@ -636,7 +632,7 @@ string WebThreeStubServerBase::eth_compileSerpent(string const& _code)
// TODO throw here jsonrpc errors // TODO throw here jsonrpc errors
string res; string res;
(void)_code; (void)_code;
#if SERPENT #if ETH_SERPENT || !ETH_TRUE
try try
{ {
res = toJS(dev::asBytes(::compile(_code))); res = toJS(dev::asBytes(::compile(_code)));
@ -658,7 +654,7 @@ string WebThreeStubServerBase::eth_compileSolidity(string const& _code)
// TOOD throw here jsonrpc errors // TOOD throw here jsonrpc errors
(void)_code; (void)_code;
string res; string res;
#if SOLIDITY #if ETH_SOLIDITY || !ETH_TRUE
dev::solidity::CompilerStack compiler; dev::solidity::CompilerStack compiler;
try try
{ {

1
libweb3jsonrpc/WebThreeStubServerBase.h

@ -78,6 +78,7 @@ public:
virtual bool net_listening(); virtual bool net_listening();
virtual std::string eth_protocolVersion(); virtual std::string eth_protocolVersion();
virtual std::string eth_hashrate();
virtual std::string eth_coinbase(); virtual std::string eth_coinbase();
virtual bool eth_mining(); virtual bool eth_mining();
virtual std::string eth_gasPrice(); virtual std::string eth_gasPrice();

7
libweb3jsonrpc/abstractwebthreestubserver.h

@ -18,6 +18,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
this->bindAndAddMethod(jsonrpc::Procedure("net_peerCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::net_peerCountI); this->bindAndAddMethod(jsonrpc::Procedure("net_peerCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::net_peerCountI);
this->bindAndAddMethod(jsonrpc::Procedure("net_listening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::net_listeningI); this->bindAndAddMethod(jsonrpc::Procedure("net_listening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::net_listeningI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_protocolVersion", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_protocolVersionI); this->bindAndAddMethod(jsonrpc::Procedure("eth_protocolVersion", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_protocolVersionI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_hashrate", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_hashrateI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_coinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_coinbaseI); this->bindAndAddMethod(jsonrpc::Procedure("eth_coinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_coinbaseI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_mining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_miningI); this->bindAndAddMethod(jsonrpc::Procedure("eth_mining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_miningI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_gasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_gasPriceI); this->bindAndAddMethod(jsonrpc::Procedure("eth_gasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_gasPriceI);
@ -98,6 +99,11 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
(void)request; (void)request;
response = this->eth_protocolVersion(); response = this->eth_protocolVersion();
} }
inline virtual void eth_hashrateI(const Json::Value &request, Json::Value &response)
{
(void)request;
response = this->eth_hashrate();
}
inline virtual void eth_coinbaseI(const Json::Value &request, Json::Value &response) inline virtual void eth_coinbaseI(const Json::Value &request, Json::Value &response)
{ {
(void)request; (void)request;
@ -309,6 +315,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
virtual std::string net_peerCount() = 0; virtual std::string net_peerCount() = 0;
virtual bool net_listening() = 0; virtual bool net_listening() = 0;
virtual std::string eth_protocolVersion() = 0; virtual std::string eth_protocolVersion() = 0;
virtual std::string eth_hashrate() = 0;
virtual std::string eth_coinbase() = 0; virtual std::string eth_coinbase() = 0;
virtual bool eth_mining() = 0; virtual bool eth_mining() = 0;
virtual std::string eth_gasPrice() = 0; virtual std::string eth_gasPrice() = 0;

5
libweb3jsonrpc/spec.json

@ -6,8 +6,9 @@
{ "name": "net_peerCount", "params": [], "order": [], "returns" : "" }, { "name": "net_peerCount", "params": [], "order": [], "returns" : "" },
{ "name": "net_listening", "params": [], "order": [], "returns" : false }, { "name": "net_listening", "params": [], "order": [], "returns" : false },
{ "name": "eth_protocolVersion", "params": [], "order": [], "returns" : "" }, { "name": "eth_protocolVersion", "params": [], "order": [], "returns" : "" },
{ "name": "eth_coinbase", "params": [], "order": [], "returns" : "" }, { "name": "eth_hashrate", "params": [], "order": [], "returns" : "" },
{ "name": "eth_coinbase", "params": [], "order": [], "returns" : "" },
{ "name": "eth_mining", "params": [], "order": [], "returns" : false }, { "name": "eth_mining", "params": [], "order": [], "returns" : false },
{ "name": "eth_gasPrice", "params": [], "order": [], "returns" : "" }, { "name": "eth_gasPrice", "params": [], "order": [], "returns" : "" },
{ "name": "eth_accounts", "params": [], "order": [], "returns" : [] }, { "name": "eth_accounts", "params": [], "order": [], "returns" : [] },

7
mix/MixClient.cpp

@ -390,11 +390,16 @@ void MixClient::stopMining()
//no-op //no-op
} }
bool MixClient::isMining() bool MixClient::isMining() const
{ {
return false; return false;
} }
uint64_t MixClient::hashrate() const
{
return 0;
}
eth::MineProgress MixClient::miningProgress() const eth::MineProgress MixClient::miningProgress() const
{ {
return eth::MineProgress(); return eth::MineProgress();

3
mix/MixClient.h

@ -67,7 +67,8 @@ public:
unsigned miningThreads() const override; unsigned miningThreads() const override;
void startMining() override; void startMining() override;
void stopMining() override; void stopMining() override;
bool isMining() override; bool isMining() const override;
uint64_t hashrate() const override;
eth::MineProgress miningProgress() const override; eth::MineProgress miningProgress() const override;
std::pair<h256, u256> getWork() override { return std::pair<h256, u256>(); } std::pair<h256, u256> getWork() override { return std::pair<h256, u256>(); }
bool submitWork(eth::ProofOfWork::Proof const&) override { return false; } bool submitWork(eth::ProofOfWork::Proof const&) override { return false; }

4
mix/qml/DebugInfoList.qml

@ -40,11 +40,9 @@ ColumnLayout {
height: 25 height: 25
id: header id: header
Image { Image {
source: "qrc:/qml/img/opentriangleindicator.png" source: "img/closedtriangleindicator.png"
width: 15 width: 15
height: 15 height: 15
sourceSize.width: 15
sourceSize.height: 15
id: storageImgArrow id: storageImgArrow
} }

107
mix/qml/Debugger.qml

@ -4,6 +4,7 @@ import QtQuick.Controls.Styles 1.1
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import Qt.labs.settings 1.0 import Qt.labs.settings 1.0
import QtGraphicalEffects 1.0
import "js/Debugger.js" as Debugger import "js/Debugger.js" as Debugger
import "js/ErrorLocationFormater.js" as ErrorLocationFormater import "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "." import "."
@ -207,7 +208,7 @@ Rectangle {
anchors.topMargin: 15 anchors.topMargin: 15
anchors.left: parent.left; anchors.left: parent.left;
anchors.leftMargin: machineStates.sideMargin anchors.leftMargin: machineStates.sideMargin
width: debugScrollArea.width - machineStates.sideMargin * 2 - 20; width: debugScrollArea.width - machineStates.sideMargin * 2 - 20 ;
spacing: machineStates.sideMargin spacing: machineStates.sideMargin
Rectangle { Rectangle {
@ -218,27 +219,26 @@ Rectangle {
color: "transparent" color: "transparent"
Rectangle { Rectangle {
anchors.top: parent.top anchors.fill: parent
anchors.bottom: parent.bottom
anchors.left: parent.left
color: "transparent" color: "transparent"
width: parent.width * 0.4
RowLayout { RowLayout {
anchors.horizontalCenter: parent.horizontalCenter anchors.fill: parent
id: jumpButtons id: jumpButtons
spacing: 3 spacing: 3
layoutDirection: Qt.LeftToRight
StepActionImage StepActionImage
{ {
id: playAction id: playAction
enabledStateImg: "qrc:/qml/img/play_button.png" enabledStateImg: "qrc:/qml/img/play_button.png"
disableStateImg: "qrc:/qml/img/play_button.png" disableStateImg: "qrc:/qml/img/play_button.png"
buttonLeft: true
onClicked: projectModel.stateListModel.runState(transactionLog.selectedStateIndex) onClicked: projectModel.stateListModel.runState(transactionLog.selectedStateIndex)
width: 30 width: 23
height: 30
buttonShortcut: "Ctrl+Shift+F8" buttonShortcut: "Ctrl+Shift+F8"
buttonTooltip: qsTr("Start Debugging") buttonTooltip: qsTr("Start Debugging")
visible: true visible: true
Layout.alignment: Qt.AlignLeft
} }
StepActionImage StepActionImage
@ -247,8 +247,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/stop_button2x.png" enabledStateImg: "qrc:/qml/img/stop_button2x.png"
disableStateImg: "qrc:/qml/img/stop_button2x.png" disableStateImg: "qrc:/qml/img/stop_button2x.png"
onClicked: Debugger.init(null); onClicked: Debugger.init(null);
width: 30 width: 23
height: 30
buttonShortcut: "Ctrl+Shift+F9" buttonShortcut: "Ctrl+Shift+F9"
buttonTooltip: qsTr("Stop Debugging") buttonTooltip: qsTr("Stop Debugging")
visible: true visible: true
@ -260,8 +259,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpoutback.png" enabledStateImg: "qrc:/qml/img/jumpoutback.png"
disableStateImg: "qrc:/qml/img/jumpoutbackdisabled.png" disableStateImg: "qrc:/qml/img/jumpoutbackdisabled.png"
onClicked: Debugger.runBack() onClicked: Debugger.runBack()
width: 30 width: 23
height: 30
buttonShortcut: "Ctrl+Shift+F5" buttonShortcut: "Ctrl+Shift+F5"
buttonTooltip: qsTr("Run Back") buttonTooltip: qsTr("Run Back")
visible: false visible: false
@ -273,8 +271,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpoutback.png" enabledStateImg: "qrc:/qml/img/jumpoutback.png"
disableStateImg: "qrc:/qml/img/jumpoutbackdisabled.png" disableStateImg: "qrc:/qml/img/jumpoutbackdisabled.png"
onClicked: Debugger.stepOutBack() onClicked: Debugger.stepOutBack()
width: 30 width: 23
height: 30
buttonShortcut: "Ctrl+Shift+F11" buttonShortcut: "Ctrl+Shift+F11"
buttonTooltip: qsTr("Step Out Back") buttonTooltip: qsTr("Step Out Back")
} }
@ -285,8 +282,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpintoback.png" enabledStateImg: "qrc:/qml/img/jumpintoback.png"
disableStateImg: "qrc:/qml/img/jumpintobackdisabled.png" disableStateImg: "qrc:/qml/img/jumpintobackdisabled.png"
onClicked: Debugger.stepIntoBack() onClicked: Debugger.stepIntoBack()
width: 30 width: 23
height: 30
buttonShortcut: "Ctrl+F11" buttonShortcut: "Ctrl+F11"
buttonTooltip: qsTr("Step Into Back") buttonTooltip: qsTr("Step Into Back")
} }
@ -297,8 +293,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpoverback.png" enabledStateImg: "qrc:/qml/img/jumpoverback.png"
disableStateImg: "qrc:/qml/img/jumpoverbackdisabled.png" disableStateImg: "qrc:/qml/img/jumpoverbackdisabled.png"
onClicked: Debugger.stepOverBack() onClicked: Debugger.stepOverBack()
width: 30 width: 23
height: 30
buttonShortcut: "Ctrl+F10" buttonShortcut: "Ctrl+F10"
buttonTooltip: qsTr("Step Over Back") buttonTooltip: qsTr("Step Over Back")
} }
@ -309,8 +304,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpoverforward.png" enabledStateImg: "qrc:/qml/img/jumpoverforward.png"
disableStateImg: "qrc:/qml/img/jumpoverforwarddisabled.png" disableStateImg: "qrc:/qml/img/jumpoverforwarddisabled.png"
onClicked: Debugger.stepOverForward() onClicked: Debugger.stepOverForward()
width: 30 width: 23
height: 30
buttonShortcut: "F10" buttonShortcut: "F10"
buttonTooltip: qsTr("Step Over Forward") buttonTooltip: qsTr("Step Over Forward")
} }
@ -321,8 +315,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpintoforward.png" enabledStateImg: "qrc:/qml/img/jumpintoforward.png"
disableStateImg: "qrc:/qml/img/jumpintoforwarddisabled.png" disableStateImg: "qrc:/qml/img/jumpintoforwarddisabled.png"
onClicked: Debugger.stepIntoForward() onClicked: Debugger.stepIntoForward()
width: 30 width: 23
height: 30
buttonShortcut: "F11" buttonShortcut: "F11"
buttonTooltip: qsTr("Step Into Forward") buttonTooltip: qsTr("Step Into Forward")
} }
@ -333,10 +326,10 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpoutforward.png" enabledStateImg: "qrc:/qml/img/jumpoutforward.png"
disableStateImg: "qrc:/qml/img/jumpoutforwarddisabled.png" disableStateImg: "qrc:/qml/img/jumpoutforwarddisabled.png"
onClicked: Debugger.stepOutForward() onClicked: Debugger.stepOutForward()
width: 30 width: 45
height: 30
buttonShortcut: "Shift+F11" buttonShortcut: "Shift+F11"
buttonTooltip: qsTr("Step Out Forward") buttonTooltip: qsTr("Step Out Forward")
buttonRight: true
} }
StepActionImage StepActionImage
@ -345,41 +338,44 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpoutforward.png" enabledStateImg: "qrc:/qml/img/jumpoutforward.png"
disableStateImg: "qrc:/qml/img/jumpoutforwarddisabled.png" disableStateImg: "qrc:/qml/img/jumpoutforwarddisabled.png"
onClicked: Debugger.runForward() onClicked: Debugger.runForward()
width: 30 width: 45
height: 30
buttonShortcut: "Ctrl+F5" buttonShortcut: "Ctrl+F5"
buttonTooltip: qsTr("Run Forward") buttonTooltip: qsTr("Run Forward")
visible: false visible: false
buttonRight: true
} }
}
}
Rectangle { Rectangle {
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
width: parent.width * 0.6 color: "transparent"
color: "transparent" Layout.fillWidth: true
Slider { Layout.minimumWidth: parent.width * 0.2
id: statesSlider Layout.alignment: Qt.AlignRight
anchors.fill: parent
tickmarksEnabled: true Slider {
stepSize: 1.0 id: statesSlider
onValueChanged: Debugger.jumpTo(value); anchors.fill: parent
style: SliderStyle { tickmarksEnabled: true
groove: Rectangle { stepSize: 1.0
implicitHeight: 3 onValueChanged: Debugger.jumpTo(value);
color: "#7da4cd" style: SliderStyle {
radius: 8 groove: Rectangle {
} implicitHeight: 3
handle: Rectangle { color: "#7da4cd"
anchors.centerIn: parent radius: 8
color: control.pressed ? "white" : "lightgray" }
border.color: "gray" handle: Rectangle {
border.width: 2 anchors.centerIn: parent
implicitWidth: 10 color: control.pressed ? "white" : "lightgray"
implicitHeight: 10 border.color: "gray"
radius: 12 border.width: 2
implicitWidth: 10
implicitHeight: 10
radius: 12
}
}
} }
} }
} }
@ -480,7 +476,7 @@ Rectangle {
anchors.top : parent.top anchors.top : parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
height: parent.height //- 2 * stateListContainer.border.width height: parent.height
color: "transparent" color: "transparent"
ColumnLayout ColumnLayout
{ {
@ -520,7 +516,6 @@ Rectangle {
title : qsTr("Stack") title : qsTr("Stack")
itemDelegate: Item { itemDelegate: Item {
id: renderedItem id: renderedItem
//height: 25
width: parent.width width: parent.width
RowLayout RowLayout
{ {

21
mix/qml/StatusPane.qml

@ -230,13 +230,26 @@ Rectangle {
Button Button
{ {
z: 4 z: 4
anchors.right: parent.right anchors.centerIn: parent
anchors.rightMargin: 9
anchors.verticalCenter: parent.verticalCenter
id: goToLineBtn id: goToLineBtn
text: "" text: ""
iconSource: "qrc:/qml/img/signerroricon32.png" width: 30
height: 30
action: goToCompilationError 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
}
}
}
} }
} }
} }

122
mix/qml/StepActionImage.qml

@ -4,15 +4,22 @@ import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.1 import QtQuick.Controls.Styles 1.1
Rectangle { Rectangle {
id: buttonActionContainer id: buttonActionContainer
color: "transparent"
property string disableStateImg property string disableStateImg
property string enabledStateImg property string enabledStateImg
property string buttonTooltip property string buttonTooltip
property string buttonShortcut property string buttonShortcut
property bool buttonLeft
property bool buttonRight
signal clicked signal clicked
color: "transparent"
width: 35
height: 24
function enabled(state) function enabled(state)
{ {
buttonAction.enabled = state; buttonAction.enabled = state;
@ -22,29 +29,104 @@ Rectangle {
debugImage.source = disableStateImg; debugImage.source = disableStateImg;
} }
Button Rectangle {
{ color: "#DCDADA"
anchors.fill: parent width: 10
id: debugImg height: 24
/* iconSource: enabledStateImg radius: 4
*/ action: buttonAction x: 0
visible: buttonLeft
Rectangle {
anchors {
left: parent.left
right: parent.right
top: parent.top
bottom: parent.bottom
bottomMargin:debugImg.pressed? 0 : 1;
topMargin:debugImg.pressed? 1 : 0;
}
color: "#FCFBFC"
radius: 3
}
} }
Image { Rectangle {
id: debugImage color: "#DCDADA"
source: enabledStateImg width: 10
anchors.centerIn: parent height: 24
fillMode: Image.PreserveAspectFit radius: 4
width: 15 x: 25
height: 15 visible: buttonRight
Rectangle {
anchors {
left: parent.left
right: parent.right
top: parent.top
bottom: parent.bottom
bottomMargin:debugImg.pressed? 0 : 1;
topMargin:debugImg.pressed? 1 : 0;
}
color: "#FCFBFC"
radius: 3
}
} }
Action {
tooltip: buttonTooltip Rectangle {
id: buttonAction id: contentRectangle
shortcut: buttonShortcut width: 25
onTriggered: { height: 24
buttonActionContainer.clicked(); color: "#DCDADA"
x: 5
Rectangle {
anchors {
left: parent.left
right: parent.right
top: parent.top
bottom: parent.bottom
bottomMargin:debugImg.pressed? 0 : 1;
topMargin:debugImg.pressed? 1 : 0;
}
color: "#FCFBFC"
Image {
id: debugImage
source: enabledStateImg
anchors.centerIn: parent
anchors.topMargin: debugImg.pressed? 1 : 0;
fillMode: Image.PreserveAspectFit
width: 15
height: 15
}
}
Button {
anchors.fill: parent
id: debugImg
action: buttonAction
style: Rectangle {
color: "transparent"
}
}
Action {
tooltip: buttonTooltip
id: buttonAction
shortcut: buttonShortcut
onTriggered: {
// contentRectangle.anchors.bottomMargin = 0
// contentRectangle.anchors.topMargin = 1
buttonActionContainer.clicked();
}
} }
} }
} }

12
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 Active line. Negative margin compensates left padding of the text in the
view-port view-port
*/ */
.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background { .cm-s-solarized.cm-s-dark .CodeMirror-activeline-background {
background: rgba(255, 255, 255, 0.10); background: rgba(255, 255, 255, 0.10);
@ -166,20 +168,24 @@ view-port
/* Code execution */ /* Code execution */
.CodeMirror-exechighlight { .CodeMirror-exechighlight {
background: #eee8d5; border-bottom: double 1px #94A2A2;
} }
/* Error annotation */ /* Error annotation */
.CodeMirror-errorannotation { .CodeMirror-errorannotation {
border-bottom: 1px solid #b58900; border-bottom: 1px solid #DD3330;
margin-bottom: 4px;
} }
.CodeMirror-errorannotation-context { .CodeMirror-errorannotation-context {
font-family: monospace; font-family: monospace;
font-size: small; font-size: small;
color: #586e75; color: #EEE9D5;
background: #b58900; background: #b58900;
padding: 2px; padding: 2px;
text-shadow: none !important;
border-top: solid 2px #063742;
} }
span.CodeMirror-selectedtext { color: #586e75 !important; } span.CodeMirror-selectedtext { color: #586e75 !important; }

BIN
mix/qml/img/closedtriangleindicator.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 242 B

BIN
mix/qml/img/closedtriangleindicator@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

BIN
mix/qml/img/opentriangleindicator.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 B

After

Width:  |  Height:  |  Size: 257 B

BIN
mix/qml/img/opentriangleindicator@2x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 836 B

After

Width:  |  Height:  |  Size: 429 B

BIN
mix/qml/img/signerroricon32.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

BIN
mix/qml/img/warningicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

BIN
mix/qml/img/warningicon@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

5
mix/res.qrc

@ -20,6 +20,7 @@
<file>qml/img/bugiconactive.png</file> <file>qml/img/bugiconactive.png</file>
<file>qml/img/bugiconinactive.png</file> <file>qml/img/bugiconinactive.png</file>
<file>qml/img/closedtriangleindicator.png</file> <file>qml/img/closedtriangleindicator.png</file>
<file>qml/img/closedtriangleindicator@2x.png</file>
<file>qml/img/closedtriangleindicator_filesproject.png</file> <file>qml/img/closedtriangleindicator_filesproject.png</file>
<file>qml/img/console.png</file> <file>qml/img/console.png</file>
<file>qml/img/copy.png</file> <file>qml/img/copy.png</file>
@ -43,6 +44,7 @@
<file>qml/img/note.png</file> <file>qml/img/note.png</file>
<file>qml/img/openedfolder.png</file> <file>qml/img/openedfolder.png</file>
<file>qml/img/opentriangleindicator.png</file> <file>qml/img/opentriangleindicator.png</file>
<file>qml/img/opentriangleindicator@2x.png</file>
<file>qml/img/opentriangleindicator_filesproject.png</file> <file>qml/img/opentriangleindicator_filesproject.png</file>
<file>qml/img/plus.png</file> <file>qml/img/plus.png</file>
<file>qml/img/projecticon.png</file> <file>qml/img/projecticon.png</file>
@ -63,6 +65,7 @@
<file>qml/img/copyiconactive.png</file> <file>qml/img/copyiconactive.png</file>
<file>qml/img/searchicon.png</file> <file>qml/img/searchicon.png</file>
<file>qml/img/stop_button2x.png</file> <file>qml/img/stop_button2x.png</file>
<file>qml/img/signerroricon32.png</file> <file>qml/img/warningicon.png</file>
<file>qml/img/warningicon@2x.png</file>
</qresource> </qresource>
</RCC> </RCC>

1
test/TestUtils.cpp

@ -22,6 +22,7 @@
#include <thread> #include <thread>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <libtestutils/Common.h>
#include <libtestutils/BlockChainLoader.h> #include <libtestutils/BlockChainLoader.h>
#include <libtestutils/FixedClient.h> #include <libtestutils/FixedClient.h>
#include "TestUtils.h" #include "TestUtils.h"

9
test/blockchain.cpp

@ -22,7 +22,7 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <libdevcrypto/FileSystem.h> #include <libdevcrypto/FileSystem.h>
#include <libtestutils/TransientDirectory.h> #include <libdevcore/TransientDirectory.h>
#include <libethereum/CanonBlockChain.h> #include <libethereum/CanonBlockChain.h>
#include "TestHelper.h" #include "TestHelper.h"
@ -192,7 +192,8 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
state.sync(bc, txs, gp); state.sync(bc, txs, gp);
state.commitToMine(bc); state.commitToMine(bc);
MineInfo info; MineInfo info;
for (info.completed = false; !info.completed; info = state.mine()) {} ProofOfWork pow;
for (info.completed = false; !info.completed; info = state.mine(&pow)) {}
state.completeMine(); state.completeMine();
} }
catch (Exception const& _e) catch (Exception const& _e)
@ -577,7 +578,7 @@ void overwriteBlockHeader(BlockInfo& _currentBlockHeader, mObject& _blObj)
std::pair<MineInfo, Ethash::Proof> ret; std::pair<MineInfo, Ethash::Proof> ret;
while (!ProofOfWork::verify(_currentBlockHeader)) while (!ProofOfWork::verify(_currentBlockHeader))
{ {
ret = pow.mine(_currentBlockHeader, 1000, true, true); ret = pow.mine(_currentBlockHeader, 1000, true);
Ethash::assignResult(ret.second, _currentBlockHeader); Ethash::assignResult(ret.second, _currentBlockHeader);
} }
} }
@ -623,7 +624,7 @@ void updatePoW(BlockInfo& _bi)
std::pair<MineInfo, Ethash::Proof> ret; std::pair<MineInfo, Ethash::Proof> ret;
while (!ProofOfWork::verify(_bi)) while (!ProofOfWork::verify(_bi))
{ {
ret = pow.mine(_bi, 10000, true, true); ret = pow.mine(_bi, 10000, true);
Ethash::assignResult(ret.second, _bi); Ethash::assignResult(ret.second, _bi);
} }
_bi.noteDirty(); _bi.noteDirty();

2
test/state.cpp

@ -218,6 +218,8 @@ BOOST_AUTO_TEST_CASE(stCreateTest)
BOOST_AUTO_TEST_CASE(stRandom) BOOST_AUTO_TEST_CASE(stRandom)
{ {
test::Options::get(); // parse command line options, e.g. to enable JIT
string testPath = dev::test::getTestPath(); string testPath = dev::test::getTestPath();
testPath += "/StateTests/RandomTests"; testPath += "/StateTests/RandomTests";

5
test/stateOriginal.cpp

@ -68,7 +68,8 @@ BOOST_AUTO_TEST_CASE(Complex)
// Mine to get some ether! // Mine to get some ether!
s.commitToMine(bc); s.commitToMine(bc);
while (!s.mine(100, true).completed) {} ProofOfWork pow;
while (!s.mine(&pow).completed) {}
s.completeMine(); s.completeMine();
bc.attemptImport(s.blockData(), stateDB); bc.attemptImport(s.blockData(), stateDB);
@ -88,7 +89,7 @@ BOOST_AUTO_TEST_CASE(Complex)
// Mine to get some ether and set in stone. // Mine to get some ether and set in stone.
s.commitToMine(bc); s.commitToMine(bc);
s.commitToMine(bc); s.commitToMine(bc);
while (!s.mine(100, true).completed) {} while (!s.mine(&pow).completed) {}
s.completeMine(); s.completeMine();
bc.attemptImport(s.blockData(), stateDB); bc.attemptImport(s.blockData(), stateDB);

2
test/vm.cpp

@ -524,6 +524,8 @@ BOOST_AUTO_TEST_CASE(vmInputLimitsLightTest)
BOOST_AUTO_TEST_CASE(vmRandom) BOOST_AUTO_TEST_CASE(vmRandom)
{ {
test::Options::get(); // parse command line options, e.g. to enable JIT
string testPath = getTestPath(); string testPath = getTestPath();
testPath += "/VMTests/RandomTests"; testPath += "/VMTests/RandomTests";

10
test/webthreestubclient.h

@ -72,6 +72,16 @@ class WebThreeStubClient : public jsonrpc::Client
else else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
} }
std::string eth_hashrate() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_hashrate",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_coinbase() throw (jsonrpc::JsonRpcException) std::string eth_coinbase() throw (jsonrpc::JsonRpcException)
{ {
Json::Value p; Json::Value p;

Loading…
Cancel
Save