Browse Source

Merge branch 'develop' into whisper

cl-refactor
subtly 10 years ago
parent
commit
e27bde0d7f
  1. 232
      CMakeLists.txt
  2. 1
      CodingStandards.txt
  3. 7
      abi/CMakeLists.txt
  4. 2
      abi/main.cpp
  5. 14
      alethzero/CMakeLists.txt
  6. 8
      alethzero/Context.h
  7. 26
      alethzero/DappLoader.cpp
  8. 4
      alethzero/DappLoader.h
  9. 4
      alethzero/Debugger.cpp
  10. 4
      alethzero/DownloadView.cpp
  11. 1
      alethzero/DownloadView.h
  12. 183
      alethzero/ExportState.cpp
  13. 57
      alethzero/ExportState.h
  14. 183
      alethzero/ExportState.ui
  15. 226
      alethzero/Main.ui
  16. 461
      alethzero/MainWin.cpp
  17. 23
      alethzero/MainWin.h
  18. 11
      alethzero/MiningView.cpp
  19. 4
      alethzero/MiningView.h
  20. 4
      alethzero/NatspecHandler.cpp
  21. 6
      alethzero/OurWebThreeStubServer.cpp
  22. 43
      alethzero/Transact.cpp
  23. 2
      alethzero/Transact.ui
  24. 161
      cmake/CMakeParseArguments.cmake
  25. 29
      cmake/EthCompilerSettings.cmake
  26. 23
      cmake/EthDependencies.cmake
  27. 33
      cmake/EthExecutableHelper.cmake
  28. 17
      cmake/EthUtils.cmake
  29. 8
      cmake/FindCURL.cmake
  30. 33
      cmake/FindCpuid.cmake
  31. 1
      cmake/FindJsoncpp.cmake
  32. 1
      cmake/FindLevelDB.cmake
  33. 16
      cmake/FindMHD.cmake
  34. 136
      cmake/FindOpenCL.cmake
  35. 382
      cmake/FindPackageHandleStandardArgs.cmake
  36. 57
      cmake/FindPackageMessage.cmake
  37. 1
      cmake/Findjson_rpc_cpp.cmake
  38. 18
      cmake/scripts/copydlls.cmake
  39. 1
      cmake/scripts/jsonrpcstub.cmake
  40. 30
      cmake/scripts/resource.hpp.in
  41. 57
      cmake/scripts/resources.cmake
  42. 43
      docker/Dockerfile
  43. 31
      docker/README.md
  44. 23
      docker/supervisord.conf
  45. 14
      eth/CMakeLists.txt
  46. 39
      eth/Farm.h
  47. 28
      eth/PhoneHome.h
  48. 4
      eth/farm.json
  49. 634
      eth/main.cpp
  50. 3
      eth/phonehome.json
  51. 45
      ethminer/CMakeLists.txt
  52. 39
      ethminer/Farm.h
  53. 28
      ethminer/PhoneHome.h
  54. 4
      ethminer/farm.json
  55. 484
      ethminer/main.cpp
  56. 3
      ethminer/phonehome.json
  57. 2
      ethrpctest/CMakeLists.txt
  58. 2
      evmjit/libevmjit-cpp/CMakeLists.txt
  59. 2
      evmjit/libevmjit-cpp/Env.cpp
  60. 10
      exp/CMakeLists.txt
  61. 303
      exp/main.cpp
  62. 59
      extdep/CMakeLists.txt
  63. 16
      extdep/Readme.md
  64. 9
      extdep/cmake/FindCURL.cmake
  65. 13
      extdep/compile/argtable2.cmake
  66. 19
      extdep/compile/boost.cmake
  67. 33
      extdep/compile/cryptopp.cmake
  68. 29
      extdep/compile/curl.cmake
  69. 17
      extdep/compile/icu.cmake
  70. 16
      extdep/compile/jom.cmake
  71. 40
      extdep/compile/json-rpc-cpp.cmake
  72. 16
      extdep/compile/jsoncpp.cmake
  73. 23
      extdep/compile/leveldb.cmake
  74. 18
      extdep/compile/leveldb_osx.patch
  75. 32
      extdep/compile/qt.cmake
  76. 111
      extdep/compile/qt_configure.bat
  77. 11
      extdep/compile/qt_osx.patch
  78. 2
      extdep/compile/qt_tools.bat
  79. 14
      extdep/compile/snappy.cmake
  80. 74
      extdep/eth_download.cmake
  81. 38
      extdep/getstuff.bat
  82. 11
      extdep/miniupnpc.cmake
  83. 29
      extdep/scripts/json-rpc-cpp_osx.sh
  84. 12
      extdep/scripts/leveldb_osx.sh
  85. 8
      extdep/scripts/snappy_osx.sh
  86. 21
      libdevcore/Base64.h
  87. 6
      libdevcore/CMakeLists.txt
  88. 26
      libdevcore/Common.cpp
  89. 69
      libdevcore/Common.h
  90. 32
      libdevcore/CommonData.h
  91. 9
      libdevcore/CommonIO.h
  92. 2
      libdevcore/Exceptions.h
  93. 5
      libdevcore/FixedHash.h
  94. 84
      libdevcore/Guards.h
  95. 125
      libdevcore/Log.cpp
  96. 160
      libdevcore/Log.h
  97. 21
      libdevcore/RLP.cpp
  98. 9
      libdevcore/RLP.h
  99. 148
      libdevcore/Terminal.h
  100. 100
      libdevcore/Worker.cpp

232
CMakeLists.txt

@ -1,37 +1,45 @@
# cmake global
cmake_minimum_required(VERSION 2.8.12)
project(ethereum)
set(CMAKE_AUTOMOC ON)
# link_directories interprate relative paths with respect to CMAKE_CURRENT_SOURCE_DIR
cmake_policy(SET CMP0015 NEW)
# let cmake autolink dependencies on windows
# it's specified globally, cause qt libraries requires that on windows and they are also found globally
cmake_policy(SET CMP0020 NEW)
project(ethereum)
# 3.1 and above
if ((${CMAKE_MAJOR_VERSION} GREATER 2) AND (${CMAKE_MINOR_VERSION} GREATER 0))
# implicitly dereference variables (deprecated in 3.1)
cmake_policy(SET CMP0054 NEW)
endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
######################################################################################################
# user defined, defaults
# Normally, set(...CACHE...) creates cache variables, but does not modify them.
function(createDefaultCacheConfig)
set(VMTRACE OFF CACHE BOOL "VM tracing and run-time checks (useful for cross-implementation VM debugging)")
set(PARANOID OFF CACHE BOOL "Additional run-time checks")
set(JSONRPC ON CACHE BOOL "Build with jsonprc. default on")
set(FATDB OFF CACHE BOOL "Build with ability to list entries in the Trie. Doubles DB size, slows everything down, but good for looking at state diffs and trie contents.")
set(USENPM OFF CACHE BOOL "Use npm to recompile ethereum.js if it was changed")
set(PROFILING OFF CACHE BOOL "Build in support for profiling")
set(BUNDLE "none" CACHE STRING "Predefined bundle of software to build (none, full, user, tests, minimal).")
set(SOLIDITY ON CACHE BOOL "Build the Solidity language components")
set(SERPENT ON CACHE BOOL "Build the Serpent language components")
set(TOOLS ON CACHE BOOL "Build the tools components")
set(NCURSES ON CACHE BOOL "Build the NCurses components")
set(GUI ON CACHE BOOL "Build GUI components (AlethZero, Mix)")
set(TESTS ON CACHE BOOL "Build the tests.")
set(EVMJIT OFF CACHE BOOL "Build just-in-time compiler for EVM code (requires LLVM)")
set(ETHASHCL OFF CACHE BOOL "Build in support for GPU mining via OpenCL")
endfunction()
option(VMTRACE "VM tracing and run-time checks (useful for cross-implementation VM debugging)" OFF)
option(PARANOID "Additional run-time checks" OFF)
option(JSONRPC "Build with jsonprc. default on" ON)
option(FATDB "Build with ability to list entries in the Trie. Doubles DB size, slows everything down, but good for looking at state diffs and trie contents." OFF)
option(USENPM "Use npm to recompile ethereum.js if it was changed" OFF)
option(PROFILING "Build in support for profiling" OFF)
set(BUNDLE "none" CACHE STRING "Predefined bundle of software to build (none, full, user, tests, minimal).")
option(SOLIDITY "Build the Solidity language components" ON)
option(SERPENT "Build the Serpent language components" ON)
option(TOOLS "Build the tools components" ON)
option(NCURSES "Build the NCurses components" ON)
option(GUI "Build GUI components (AlethZero, Mix)" ON)
option(TESTS "Build the tests." ON)
option(EVMJIT "Build just-in-time compiler for EVM code (requires LLVM)" OFF)
option(ETHASHCL "Build in support for GPU mining via OpenCL" OFF)
# propagates CMake configuration options to the compiler
function(configureProject)
@ -62,6 +70,16 @@ function(configureProject)
if (GUI)
add_definitions(-DETH_GUI)
endif()
if (CPUID_FOUND)
add_definitions(-DETH_CPUID)
endif()
if (CURL_FOUND)
add_definitions(-DETH_CURL)
endif()
add_definitions(-DETH_TRUE)
endfunction()
set(CPPETHEREUM 1)
@ -118,9 +136,6 @@ endfunction()
######################################################################################################
set(CMAKE_AUTOMOC ON)
cmake_policy(SET CMP0015 NEW)
# Clear invalid option
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
if (PARANOID)
@ -133,97 +148,57 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
endif ()
endif ()
createDefaultCacheConfig()
configureProject()
# Force chromium.
set (ETH_HAVE_WEBENGINE 1)
# Normalise build options
# TODO: Abstract into something sensible and move into a function.
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(DECENT_PLATFORM OFF)
else ()
set(DECENT_PLATFORM ON)
endif ()
# Backwards compatibility
if (HEADLESS)
message("*** WARNING: -DHEADLESS=1 option is DEPRECATED! Use -DBUNDLE=minimal or -DGUI=0")
set(BUNDLE "minimal")
endif ()
if (PARANOID)
set(PARANOID ON)
else ()
set(PARANOID OFF)
endif ()
if (VMTRACE)
set(VMTRACE ON)
else ()
set(VMTRACE OFF)
endif ()
if (EVMJIT)
set(EVMJIT ON)
else ()
set(EVMJIT OFF)
endif()
if (FATDB)
set(FATDB ON)
else ()
set(FATDB OFF)
endif()
if (JSONRPC)
set(JSONRPC ON)
else ()
set(JSONRPC OFF)
endif ()
if (USENPM)
set(USENPM ON)
else ()
set(USENPM OFF)
endif ()
if (PROFILING)
set(PROFILING ON)
# TODO: Abstract into something sensible and move into a function.
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(DECENT_PLATFORM OFF)
else ()
set(PROFILING OFF)
set(DECENT_PLATFORM ON)
endif ()
macro(eth_format_option O)
if (${${O}})
set(${O} ON)
else()
set(${O} OFF)
endif()
endmacro()
macro(eth_format_option_on_decent_platform O)
if (${${O}})
set(${O} ${DECENT_PLATFORM})
else()
set(${O} OFF)
endif()
endmacro()
# Normalise build options
eth_format_option(PARANOID)
eth_format_option(VMTRACE)
eth_format_option(EVMJIT)
eth_format_option(FATDB)
eth_format_option(JSONRPC)
eth_format_option(USENPM)
eth_format_option(PROFILING)
eth_format_option(SOLIDITY)
eth_format_option(GUI)
eth_format_option(TESTS)
eth_format_option(TOOLS)
eth_format_option(ETHASHCL)
eth_format_option_on_decent_platform(SERPENT)
eth_format_option_on_decent_platform(NCURSES)
if (SOLIDITY)
set(SOLIDITY ON)
else ()
set(SOLIDITY OFF)
endif()
if (SERPENT)
set(SERPENT ${DECENT_PLATFORM})
else ()
set(SERPENT OFF)
endif()
if (GUI)
set(GUI ON)
set(JSONRPC ON)
else ()
set(GUI OFF)
endif ()
if (TESTS)
set(TESTS ON)
else ()
set(TESTS OFF)
endif ()
if (TOOLS)
set(TOOLS ON)
else ()
set(TOOLS OFF)
endif ()
if (ETHASHCL)
set(ETHASHCL ON)
else ()
set(ETHASHCL OFF)
endif()
if (NCURSES)
set(NCURSES ${DECENT_PLATFORM})
else ()
set(NCURSES OFF)
endif ()
if (BUNDLE STREQUAL "minimal")
set(SERPENT OFF)
@ -242,6 +217,15 @@ elseif (BUNDLE STREQUAL "full")
set(TOOLS ON)
set(TESTS ON)
set(FATDB ON)
elseif (BUNDLE STREQUAL "core")
set(SERPENT OFF)
set(SOLIDITY ON)
set(USENPM OFF)
set(GUI ON)
set(NCURSES OFF)
set(TOOLS ON)
set(TESTS OFF)
set(FATDB ON)
elseif (BUNDLE STREQUAL "tests")
set(SERPENT ${DECENT_PLATFORM})
set(SOLIDITY ON)
@ -267,12 +251,17 @@ if ("x${CMAKE_BUILD_TYPE}" STREQUAL "x")
set(CMAKE_BUILD_TYPE "Release")
endif ()
# Default TARGET_PLATFORM to "linux".
set(TARGET_PLATFORM CACHE STRING "linux")
# Default TARGET_PLATFORM to ${CMAKE_SYSTEM_NAME}
# change this once we support cross compiling
set(TARGET_PLATFORM CACHE STRING ${CMAKE_SYSTEM_NAME})
if ("x${TARGET_PLATFORM}" STREQUAL "x")
set(TARGET_PLATFORM "linux")
set(TARGET_PLATFORM ${CMAKE_SYSTEM_NAME})
endif ()
include(EthDependencies)
configureProject()
message("------------------------------------------------------------------------")
message("-- CMake Version ${CMAKE_VERSION}")
message("-- CMAKE_BUILD_TYPE Build type ${CMAKE_BUILD_TYPE}")
@ -280,6 +269,8 @@ message("-- TARGET_PLATFORM Target platform ${TARGET_P
message("-- BUNDLE Build bundle ${BUNDLE}")
message("--------------------------------------------------------------- features")
message("-- Chromium support ${ETH_HAVE_WEBENGINE}")
message("-- Hardware identification support ${CPUID_FOUND}")
message("-- HTTP Request support ${CURL_FOUND}")
message("-- VMTRACE VM execution tracing ${VMTRACE}")
message("-- PROFILING Profiling support ${PROFILING}")
message("-- FATDB Full database exploring ${FATDB}")
@ -297,17 +288,12 @@ message("-- EVMJIT Build LLVM-based JIT EVM (experimental!) ${EVMJIT}"
message("------------------------------------------------------------------------")
message("")
if ("${TARGET_PLATFORM}" STREQUAL "linux")
set(CMAKE_THREAD_LIBS_INIT pthread)
endif ()
set(CMAKE_THREAD_LIBS_INIT pthread)
include(EthCompilerSettings)
message("-- CXXFLAGS: ${CMAKE_CXX_FLAGS}")
# this must be an include, as a function it would messs up with variable scope!
include(EthDependencies)
# this must be an include, as a function it would mess up with variable scope!
include(EthExecutableHelper)
createBuildInfo()
@ -319,6 +305,7 @@ endif()
add_subdirectory(libdevcore)
add_subdirectory(libevmcore)
add_subdirectory(libevmasm)
add_subdirectory(liblll)
if (SERPENT)
@ -368,6 +355,7 @@ if (TOOLS)
add_subdirectory(rlp)
add_subdirectory(abi)
add_subdirectory(ethminer)
add_subdirectory(eth)
if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug")
@ -401,23 +389,37 @@ endif()
if (WIN32)
# packaging stuff
include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "ethereum")
set(CPACK_PACKAGE_NAME "Ethereum")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Ethereum")
set(CPACK_PACKAGE_VENDOR "ethereum.org")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_VERSION "0.7")
set(CPACK_PACKAGE_VERSION "0.9")
set(CPACK_GENERATOR "NSIS")
# seems to be not working
# set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.bmp")
# our stuff
set(CPACK_COMPONENT_ALETHZERO_GROUP "Applications")
set(CPACK_COMPONENT_THIRD_GROUP "Applications")
set(CPACK_COMPONENT_MIX_GROUP "Applications")
set(CPACK_COMPONENTS_ALL alethzero third mix)
set(CPACK_COMPONENT_SOLC_GROUP "CLI")
set(CPACK_COMPONENT_ETH_GROUP "CLI")
set(CPACK_COMPONENT_ETHMINER_GROUP "CLI")
set(CPACK_COMPONENT_RLP_GROUP "CLI")
set(CPACK_COMPONENT_ABI_GROUP "CLI")
set(CPACK_COMPONENTS_ALL alethzero mix solc eth ethminer rlp abi)
# nsis specific stuff
set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ethereum")
if (CMAKE_CL_64)
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (Win64)")
else ()
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
endif()
set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} Ethereum")
set(CPACK_NSIS_HELP_LINK "https://github.com/ethereum/cpp-ethereum")
set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/ethereum/cpp-ethereum")
set(CPACK_NSIS_CONTACT "ethereum.org")

1
CodingStandards.txt

@ -116,6 +116,7 @@ g. Never use a macro where adequate non-preprocessor C++ can be written.
h. Make use of auto whenever type is clear or unimportant:
- Always avoid doubly-stating the type.
- Use to avoid vast and unimportant type declarations.
- However, avoid using auto where type is not immediately obvious from the context, and especially not for arithmetic expressions.
i. Don't pass bools: prefer enumerations instead.
j. Prefer enum class to straight enum.

7
abi/CMakeLists.txt

@ -12,5 +12,8 @@ add_executable(${EXECUTABLE} ${SRC_LIST})
target_link_libraries(${EXECUTABLE} ethereum)
install( TARGETS ${EXECUTABLE} DESTINATION bin)
if (APPLE)
install(TARGETS ${EXECUTABLE} DESTINATION bin)
else()
eth_install_executable(${EXECUTABLE})
endif()

2
abi/main.cpp

@ -43,7 +43,7 @@ void help()
<< " -h,--help Print this help message and exit." << endl
<< " -V,--version Show the version and exit." << endl
<< "Input options:" << endl
<< " -f,--format-prefix Require all input formats to be prefixed e.g. 0x for hex, . for decimal, @ for binary." << endl
<< " -f,--format-prefix Require all input formats to be prefixed e.g. 0x for hex, + for decimal, ' for binary." << endl
<< " -F,--no-format-prefix Require no input format to be prefixed." << endl
<< " -t,--typing Require all arguments to be typed e.g. b32: (bytes32), u64: (uint64), b[]: (byte[]), i: (int256)." << endl
<< " -T,--no-typing Require no arguments to be typed." << endl

14
alethzero/CMakeLists.txt

@ -22,6 +22,7 @@ qt5_wrap_ui(ui_Main.h Main.ui)
qt5_wrap_ui(ui_Connect.h Connect.ui)
qt5_wrap_ui(ui_Debugger.h Debugger.ui)
qt5_wrap_ui(ui_Transact.h Transact.ui)
qt5_wrap_ui(ui_ExportState.h ExportState.ui)
file(GLOB HEADERS "*.h")
@ -34,7 +35,7 @@ endif ()
# eth_add_executable is defined in cmake/EthExecutableHelper.cmake
eth_add_executable(${EXECUTABLE}
ICON alethzero
UI_RESOURCES alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui
UI_RESOURCES alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui ExportState.ui
WIN_RESOURCES alethzero.rc
)
@ -51,18 +52,19 @@ target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} devcrypto)
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} lll)
target_link_libraries(${EXECUTABLE} solidity)
target_link_libraries(${EXECUTABLE} evmcore)
target_link_libraries(${EXECUTABLE} devcore)
if (SOLIDITY)
target_link_libraries(${EXECUTABLE} solidity)
endif ()
target_link_libraries(${EXECUTABLE} evmasm)
target_link_libraries(${EXECUTABLE} web3jsonrpc)
target_link_libraries(${EXECUTABLE} jsqrc)
target_link_libraries(${EXECUTABLE} natspec)
target_link_libraries(${EXECUTABLE} ${MHD_LIBRARIES})
if (NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC"))
if (SERPENT)
target_link_libraries(${EXECUTABLE} serpent)
endif()
# eth_install_executable is defined in cmake/EthExecutableHelper.cmake
eth_install_executable(${EXECUTABLE} DLLS ${MHD_DLL_RELEASE})
eth_install_executable(${EXECUTABLE} DLLS MHD_DLLS)

8
alethzero/Context.h

@ -59,10 +59,10 @@ class Context
public:
virtual ~Context();
virtual QString pretty(dev::Address _a) const = 0;
virtual QString prettyU256(dev::u256 _n) const = 0;
virtual QString render(dev::Address _a) const = 0;
virtual dev::Address fromString(QString const& _a) const = 0;
virtual std::string pretty(dev::Address const& _a) const = 0;
virtual std::string prettyU256(dev::u256 const& _n) const = 0;
virtual std::pair<dev::Address, dev::bytes> fromString(std::string const& _a) const = 0;
virtual std::string renderDiff(dev::eth::StateDiff const& _d) const = 0;
virtual std::string render(dev::Address const& _a) const = 0;
};

26
alethzero/DappLoader.cpp

@ -39,13 +39,10 @@ using namespace dev;
using namespace dev::eth;
using namespace dev::crypto;
Address c_registrar = Address("0000000000000000000000000000000000000a28");
Address c_urlHint = Address("0000000000000000000000000000000000000a29");
QString contentsOfQResource(std::string const& res);
DappLoader::DappLoader(QObject* _parent, WebThreeDirect* _web3):
QObject(_parent), m_web3(_web3)
DappLoader::DappLoader(QObject* _parent, WebThreeDirect* _web3, Address _nameReg):
QObject(_parent), m_web3(_web3), m_nameReg(_nameReg)
{
connect(&m_net, &QNetworkAccessManager::finished, this, &DappLoader::downloadComplete);
}
@ -61,31 +58,39 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri)
std::reverse(parts.begin(), parts.end());
parts.append(url.path().split('/', QString::SkipEmptyParts));
Address address = c_registrar;
Address address = m_nameReg;
Address lastAddress;
int partIndex = 0;
h256 contentHash;
while (address && partIndex < parts.length())
{
lastAddress = address;
string32 name = ZeroString32;
QByteArray utf8 = parts[partIndex].toUtf8();
std::copy(utf8.data(), utf8.data() + utf8.size(), name.data());
address = abiOut<Address>(web3()->ethereum()->call(address, abiIn("addr(string32)", name)).output);
if (address != m_nameReg)
address = abiOut<Address>(web3()->ethereum()->call(address, abiIn("subRegistrar(bytes32)", name)).output);
else
address = abiOut<Address>(web3()->ethereum()->call(address, abiIn("register(bytes32)", name)).output);
domainParts.append(parts[partIndex]);
if (!address)
{
//we have the address of the last part, try to get content hash
contentHash = abiOut<h256>(web3()->ethereum()->call(lastAddress, abiIn("content(string32)", name)).output);
contentHash = abiOut<h256>(web3()->ethereum()->call(lastAddress, abiIn("content(bytes32)", name)).output);
if (!contentHash)
throw dev::Exception() << errinfo_comment("Can't resolve address");
}
++partIndex;
}
string32 contentUrl = abiOut<string32>(web3()->ethereum()->call(c_urlHint, abiIn("url(hash256)", contentHash)).output);
string32 urlHintName = ZeroString32;
QByteArray utf8 = QString("urlhint").toUtf8();
std::copy(utf8.data(), utf8.data() + utf8.size(), urlHintName.data());
Address urlHint = abiOut<Address>(web3()->ethereum()->call(m_nameReg, abiIn("addr(bytes32)", urlHintName)).output);
string32 contentUrl = abiOut<string32>(web3()->ethereum()->call(urlHint, abiIn("url(bytes32)", contentHash)).output);
QString domain = domainParts.join('/');
parts.erase(parts.begin(), parts.begin() + partIndex);
QString path = parts.join('/');
@ -237,6 +242,7 @@ void DappLoader::loadDapp(QString const& _uri)
DappLocation location = resolveAppUri(_uri);
contentUri = location.contentUri;
hash = location.contentHash;
uri = contentUri;
}
QNetworkRequest request(contentUri);
m_uriHashes[uri] = hash;

4
alethzero/DappLoader.h

@ -29,6 +29,7 @@
#include <QUrl>
#include <QNetworkAccessManager>
#include <libdevcore/FixedHash.h>
#include <libdevcrypto/Common.h>
namespace dev
{
@ -69,7 +70,7 @@ class DappLoader: public QObject
{
Q_OBJECT
public:
DappLoader(QObject* _parent, dev::WebThreeDirect* _web3);
DappLoader(QObject* _parent, dev::WebThreeDirect* _web3, dev::Address _nameReg);
///Load a new DApp. Resolves a name with a name reg contract. Asynchronous. dappReady is emitted once everything is read, dappError othervise
///@param _uri Eth name path
void loadDapp(QString const& _uri);
@ -97,5 +98,6 @@ private:
std::map<QUrl, dev::h256> m_uriHashes;
std::set<QUrl> m_pageUrls;
QByteArray m_web3Js;
dev::Address m_nameReg;
};

4
alethzero/Debugger.cpp

@ -226,7 +226,7 @@ void Debugger::update()
QString stack;
for (auto i: ws.stack)
stack.prepend("<div>" + m_context->prettyU256(i) + "</div>");
stack.prepend("<div>" + QString::fromStdString(m_context->prettyU256(i)) + "</div>");
ui->debugStack->setHtml(stack);
ui->debugMemory->setHtml(QString::fromStdString(dev::memDump(ws.memory, 16, true)));
assert(m_session.codes.count(ws.code));
@ -246,7 +246,7 @@ void Debugger::update()
ui->debugStateInfo->setText(QString::fromStdString(ss.str()));
stringstream s;
for (auto const& i: ws.storage)
s << "@" << m_context->prettyU256(i.first).toStdString() << "&nbsp;&nbsp;&nbsp;&nbsp;" << m_context->prettyU256(i.second).toStdString() << "<br/>";
s << "@" << m_context->prettyU256(i.first) << "&nbsp;&nbsp;&nbsp;&nbsp;" << m_context->prettyU256(i.second) << "<br/>";
ui->debugStorage->setHtml(QString::fromStdString(s.str()));
}
}

4
alethzero/DownloadView.cpp

@ -39,13 +39,13 @@ void DownloadView::paintEvent(QPaintEvent*)
QPainter p(this);
p.fillRect(rect(), Qt::white);
if (!m_man || m_man->chain().empty() || !m_man->subCount())
if (!m_man || m_man->chainEmpty() || !m_man->subCount())
return;
double ratio = (double)rect().width() / rect().height();
if (ratio < 1)
ratio = 1 / ratio;
double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(m_man->chain().size() / ratio)));
double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(m_man->chainSize() / ratio)));
// QSizeF area(rect().width() / floor(rect().width() / n), rect().height() / floor(rect().height() / n));
QSizeF area(n, n);

1
alethzero/DownloadView.h

@ -32,7 +32,6 @@
#endif
namespace dev { namespace eth {
struct MineInfo;
class DownloadMan;
}}

183
alethzero/ExportState.cpp

@ -0,0 +1,183 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file ExportState.cpp
* @author Arkadiy Paronyan <arkadiy@ethdev.com>
* @date 2015
*/
#include "ExportState.h"
#include <QFileDialog>
#include <QTextStream>
#include <libethereum/Client.h>
#include "MainWin.h"
#include "ui_ExportState.h"
using namespace std;
using namespace dev;
using namespace dev::eth;
ExportStateDialog::ExportStateDialog(Main* _parent):
QDialog(_parent),
ui(new Ui::ExportState),
m_main(_parent)
{
ui->setupUi(this);
connect(ui->close, &QPushButton::clicked, this, &ExportStateDialog::close);
connect(ui->accounts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON);
connect(ui->contracts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON);
fillBlocks();
}
ExportStateDialog::~ExportStateDialog()
{
}
dev::eth::Client* ExportStateDialog::ethereum() const
{
return m_main->ethereum();
}
void ExportStateDialog::on_block_editTextChanged()
{
QString text = ui->block->currentText();
int i = ui->block->count();
while (i-- >= 0)
if (ui->block->itemText(i) == text)
return;
fillBlocks();
}
void ExportStateDialog::on_block_currentIndexChanged(int _index)
{
m_block = ui->block->itemData(_index).toUInt();
fillContracts();
}
void ExportStateDialog::fillBlocks()
{
BlockChain const& bc = ethereum()->blockChain();
QStringList filters = ui->block->currentText().toLower().split(QRegExp("\\s+"), QString::SkipEmptyParts);
const unsigned numLastBlocks = 10;
if (ui->block->count() == 0)
{
unsigned i = numLastBlocks;
for (auto h = bc.currentHash(); bc.details(h) && i; h = bc.details(h).parent, --i)
{
auto d = bc.details(h);
ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number);
if (h == bc.genesisHash())
break;
}
if (ui->block->currentIndex() < 0)
ui->block->setCurrentIndex(0);
m_recentBlocks = numLastBlocks - i;
}
int i = ui->block->count();
while (i > 0 && i >= m_recentBlocks)
ui->block->removeItem(i--);
h256Set blocks;
for (QString f: filters)
{
if (f.startsWith("#"))
f = f.remove(0, 1);
if (f.size() == 64)
{
h256 h(f.toStdString());
if (bc.isKnown(h))
blocks.insert(h);
for (auto const& b: bc.withBlockBloom(LogBloom().shiftBloom<3>(sha3(h)), 0, -1))
blocks.insert(bc.numberHash(b));
}
else if (f.toLongLong() <= bc.number())
blocks.insert(bc.numberHash((unsigned)f.toLongLong()));
else if (f.size() == 40)
{
Address h(f.toStdString());
for (auto const& b: bc.withBlockBloom(LogBloom().shiftBloom<3>(sha3(h)), 0, -1))
blocks.insert(bc.numberHash(b));
}
}
for (auto const& h: blocks)
{
auto d = bc.details(h);
ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number);
}
}
void ExportStateDialog::fillContracts()
{
ui->accounts->clear();
ui->contracts->clear();
ui->accounts->setEnabled(true);
ui->contracts->setEnabled(true);
for (auto i: ethereum()->addresses(m_block))
{
string r = m_main->render(i);
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? ui->accounts : ui->contracts))
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size));
}
}
void ExportStateDialog::generateJSON()
{
std::stringstream json;
json << "{\n";
std::string prefix;
for(QListWidgetItem* item: ui->accounts->selectedItems())
{
auto hba = item->data(Qt::UserRole).toByteArray();
auto address = Address((byte const*)hba.data(), Address::ConstructFromPointer);
json << prefix << "\t\"" << toHex(address.ref()) << "\": { \"wei\": \"" << ethereum()->balanceAt(address, m_block) << "\" }";
prefix = ",\n";
}
for(QListWidgetItem* item: ui->contracts->selectedItems())
{
auto hba = item->data(Qt::UserRole).toByteArray();
auto address = Address((byte const*)hba.data(), Address::ConstructFromPointer);
json << prefix << "\t\"" << toHex(address.ref()) << "\":\n\t{\n\t\t\"wei\": \"" << ethereum()->balanceAt(address, m_block) << "\",\n";
json << "\t\t\"code\": \"" << toHex(ethereum()->codeAt(address, m_block)) << "\",\n";
std::map<u256, u256> storage = ethereum()->storageAt(address, m_block);
if (!storage.empty())
{
json << "\t\t\"storage\":\n\t\t{\n";
for (auto s: storage)
json << "\t\t\t\"" << toHex(s.first) << "\": \"" << toHex(s.second) << "\"" << (s.first == storage.rbegin()->first ? "" : ",") <<"\n";
json << "\t\t}\n";
}
json << "\t}";
prefix = ",\n";
}
json << "\n}";
json.flush();
ui->json->setEnabled(true);
ui->json->setText(QString::fromStdString(json.str()));
ui->saveButton->setEnabled(true);
}
void ExportStateDialog::on_saveButton_clicked()
{
QString fn = QFileDialog::getSaveFileName(this, "Save state", QString(), "JSON Files (*.json)");
if (!fn.endsWith(".json"))
fn = fn.append(".json");
ofstream file(fn.toStdString());
if (file.is_open())
file << ui->json->toPlainText().toStdString();
}

57
alethzero/ExportState.h

@ -0,0 +1,57 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file ExportState.h
* @author Arkadiy Paronyan <arkadiy@ethdev.com>
* @date 2015
*/
#pragma once
#include <memory>
#include <QDialog>
#include <libethcore/Common.h>
namespace Ui { class ExportState; }
namespace dev { namespace eth { class Client; } }
class Main;
class ExportStateDialog: public QDialog
{
Q_OBJECT
public:
explicit ExportStateDialog(Main* _parent = 0);
virtual ~ExportStateDialog();
private slots:
void on_block_editTextChanged();
void on_block_currentIndexChanged(int _index);
void on_saveButton_clicked();
private:
dev::eth::Client* ethereum() const;
void fillBlocks();
void fillContracts();
void generateJSON();
private:
std::unique_ptr<Ui::ExportState> ui;
Main* m_main;
int m_recentBlocks = 0;
dev::eth::BlockNumber m_block = dev::eth::LatestBlock;
};

183
alethzero/ExportState.ui

@ -0,0 +1,183 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ExportState</class>
<widget class="QDialog" name="ExportState">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>490</width>
<height>522</height>
</rect>
</property>
<property name="windowTitle">
<string>Export State</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Block</string>
</property>
<property name="buddy">
<cstring>block</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="block">
<property name="editable">
<bool>true</bool>
</property>
<property name="currentText">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>&amp;Accounts</string>
</property>
<property name="buddy">
<cstring>accounts</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QListWidget" name="accounts">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>&amp;Contracts</string>
</property>
<property name="buddy">
<cstring>contracts</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QListWidget" name="contracts">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;JSON</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>json</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QTextEdit" name="json">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>2</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="saveButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Save...</string>
</property>
<property name="shortcut">
<string>Esc</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="close">
<property name="text">
<string>&amp;Close</string>
</property>
<property name="shortcut">
<string>Esc</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

226
alethzero/Main.ui

@ -53,23 +53,23 @@
</widget>
</item>
<item>
<widget class="QLabel" name="balance">
<widget class="QLabel" name="blockCount">
<property name="text">
<string>0 wei</string>
<string>1 block</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="peerCount">
<widget class="QLabel" name="balance">
<property name="text">
<string>0 peers</string>
<string>0 wei</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="blockCount">
<widget class="QLabel" name="peerCount">
<property name="text">
<string>1 block</string>
<string>0 peers</string>
</property>
</widget>
</item>
@ -150,6 +150,7 @@
<string>&amp;Tools</string>
</property>
<addaction name="mine"/>
<addaction name="turboMining"/>
<addaction name="separator"/>
<addaction name="newTransaction"/>
<addaction name="newAccount"/>
@ -159,6 +160,8 @@
<addaction name="killAccount"/>
<addaction name="separator"/>
<addaction name="loadJS"/>
<addaction name="separator"/>
<addaction name="exportState"/>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
@ -175,18 +178,18 @@
<addaction name="clearPending"/>
<addaction name="killBlockchain"/>
<addaction name="inject"/>
<addaction name="injectBlock"/>
<addaction name="forceMining"/>
<addaction name="turboMining"/>
<addaction name="separator"/>
<addaction name="usePrivate"/>
<addaction name="jitvm"/>
<addaction name="retryUnknown"/>
</widget>
<widget class="QMenu" name="menu_View">
<property name="title">
<string>&amp;View</string>
</property>
<addaction name="showAll"/>
<addaction name="showAllAccounts"/>
<addaction name="separator"/>
<addaction name="preview"/>
</widget>
@ -214,43 +217,6 @@
<addaction name="menu_Debug"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="dockWidget_accounts">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Accounts</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="accounts">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_3">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
@ -290,6 +256,19 @@
</widget>
<widget class="QWidget" name="layoutWidget">
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1">
<widget class="QLineEdit" name="listenIP">
<property name="inputMask">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>Automatic</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
@ -300,16 +279,6 @@
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QSpinBox" name="idealPeers">
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="port">
<property name="minimum">
@ -323,20 +292,21 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="listenIP">
<property name="inputMask">
<string/>
</property>
<item row="3" column="3">
<widget class="QLabel" name="label_2">
<property name="text">
<string/>
<string>Public IP</string>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QLineEdit" name="forcePublicIP">
<property name="placeholderText">
<string>Automatic</string>
</property>
</widget>
</item>
<item row="0" column="0">
<item row="0" column="3">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Ideal &amp;Peers</string>
@ -346,21 +316,7 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="forcePublicIP">
<property name="placeholderText">
<string>Automatic</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Public IP</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>&amp;Client Name</string>
@ -370,13 +326,30 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="0" column="4">
<widget class="QSpinBox" name="idealPeers">
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="clientName">
<property name="placeholderText">
<string>Anonymous</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="5">
<widget class="QLineEdit" name="enode">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
@ -586,18 +559,21 @@
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_contracts">
<widget class="QDockWidget" name="dockWidget_accounts">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Contracts</string>
<string>Accounts</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_6">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
@ -610,12 +586,66 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QLineEdit" name="accountsFilter">
<property name="placeholderText">
<string>Filter...</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="showBasic">
<property name="text">
<string>Basic</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="showContracts">
<property name="text">
<string>Contracts</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="onlyNamed">
<property name="text">
<string>Only Named</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="refreshAccounts">
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QSplitter" name="splitter_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QListWidget" name="contracts">
<widget class="QListWidget" name="accounts">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@ -629,7 +659,7 @@
<enum>QFrame::NoFrame</enum>
</property>
</widget>
<widget class="QPlainTextEdit" name="contractInfo">
<widget class="QPlainTextEdit" name="accountInfo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>2</horstretch>
@ -1476,6 +1506,11 @@ font-size: 14pt</string>
<string>&amp;Load Javascript...</string>
</property>
</action>
<action name="exportState">
<property name="text">
<string>&amp;Export State...</string>
</property>
</action>
<action name="debugStepBack">
<property name="enabled">
<bool>false</bool>
@ -1608,14 +1643,6 @@ font-size: 14pt</string>
<string>&amp;Enable LLL Optimizer</string>
</property>
</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">
<property name="checkable">
<bool>true</bool>
@ -1679,6 +1706,24 @@ font-size: 14pt</string>
<string>&amp;NatSpec Enabled</string>
</property>
</action>
<action name="turboMining">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;GPU Mining</string>
</property>
</action>
<action name="retryUnknown">
<property name="text">
<string>Retry Unknown Parent Blocks</string>
</property>
</action>
<action name="injectBlock">
<property name="text">
<string>In&amp;ject Block</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
@ -1713,7 +1758,6 @@ font-size: 14pt</string>
<tabstop>verbosity</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>urlEdit</tabstop>
<tabstop>idealPeers</tabstop>
<tabstop>listenIP</tabstop>
<tabstop>port</tabstop>
<tabstop>transactionQueue</tabstop>

461
alethzero/MainWin.cpp

@ -45,7 +45,8 @@
#endif
#include <libdevcrypto/FileSystem.h>
#include <libethcore/CommonJS.h>
#include <libethcore/Ethasher.h>
#include <libethcore/EthashAux.h>
#include <libethcore/ICAP.h>
#include <liblll/Compiler.h>
#include <liblll/CodeFragment.h>
#include <libsolidity/Scanner.h>
@ -71,6 +72,7 @@
#include "DappLoader.h"
#include "DappHost.h"
#include "WebPage.h"
#include "ExportState.h"
#include "ui_Main.h"
using namespace std;
using namespace dev;
@ -78,29 +80,29 @@ using namespace dev::p2p;
using namespace dev::eth;
namespace js = json_spirit;
QString Main::fromRaw(h256 _n, unsigned* _inc)
string Main::fromRaw(h256 _n, unsigned* _inc)
{
if (_n)
{
string s((char const*)_n.data(), 32);
auto l = s.find_first_of('\0');
if (!l)
return QString();
return string();
if (l != string::npos)
{
auto p = s.find_first_not_of('\0', l);
if (!(p == string::npos || (_inc && p == 31)))
return QString();
return string();
if (_inc)
*_inc = (byte)s[31];
s.resize(l);
}
for (auto i: s)
if (i < 32)
return QString();
return QString::fromStdString(s);
return string();
return s;
}
return QString();
return string();
}
QString contentsOfQResource(string const& res)
@ -116,6 +118,11 @@ QString contentsOfQResource(string const& res)
Address c_newConfig = Address("c6d9d2cd449a754c494264e1809c50e34d64562b");
//Address c_nameReg = Address("ddd1cea741d548f90d86fb87a3ae6492e18c03a1");
static QString filterOutTerminal(QString _s)
{
return _s.replace(QRegExp("\x1b\\[(\\d;)?\\d+m"), "");
}
Main::Main(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Main),
@ -130,17 +137,12 @@ Main::Main(QWidget *parent) :
{
simpleDebugOut(s, c);
m_logLock.lock();
m_logHistory.append(QString::fromStdString(s) + "\n");
m_logHistory.append(filterOutTerminal(QString::fromStdString(s)) + "\n");
m_logChanged = true;
m_logLock.unlock();
// ui->log->addItem(QString::fromStdString(s));
};
#if !ETH_FATDB
delete ui->dockWidget_accounts;
delete ui->dockWidget_contracts;
#endif
#if ETH_DEBUG
m_servers.append("127.0.0.1:30300");
#endif
@ -164,10 +166,10 @@ Main::Main(QWidget *parent) :
statusBar()->addPermanentWidget(ui->chainStatus);
statusBar()->addPermanentWidget(ui->blockCount);
ui->blockCount->setText(QString("PV%2 D%3 H%4 v%5").arg(eth::c_protocolVersion).arg(c_databaseVersion).arg(c_ethashVersion).arg(dev::Version));
ui->blockCount->setText(QString("PV%1.%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(eth::c_minorProtocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version));
connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved()));
QSettings s("ethereum", "alethzero");
m_networkConfig = s.value("peers").toByteArray();
bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size());
@ -190,13 +192,16 @@ Main::Main(QWidget *parent) :
});
m_dappHost.reset(new DappHost(8081));
m_dappLoader = new DappLoader(this, web3());
m_dappLoader = new DappLoader(this, web3(), getNameReg());
connect(m_dappLoader, &DappLoader::dappReady, this, &Main::dappLoaded);
connect(m_dappLoader, &DappLoader::pageReady, this, &Main::pageLoaded);
// ui->webView->page()->settings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, true);
// QWebEngineInspector* inspector = new QWebEngineInspector();
// inspector->setPage(page);
readSettings();
#if !ETH_FATDB
removeDockWidget(ui->dockWidget_accounts);
#endif
installWatches();
startTimer(100);
@ -212,6 +217,7 @@ Main::Main(QWidget *parent) :
Main::~Main()
{
m_httpConnector->StopListening();
writeSettings();
// Must do this here since otherwise m_ethereum'll be deleted (and therefore clearWatches() called by the destructor)
// *after* the client is dead.
@ -321,7 +327,8 @@ void Main::installWatches()
Address Main::getNameReg() const
{
return abiOut<Address>(ethereum()->call(c_newConfig, abiIn("lookup(uint256)", (u256)1)).output);
return Address("c6d9d2cd449a754c494264e1809c50e34d64562b");
// return abiOut<Address>(ethereum()->call(c_newConfig, abiIn("lookup(uint256)", (u256)1)).output);
}
Address Main::getCurrencies() const
@ -389,7 +396,7 @@ void Main::onNewBlock()
// update blockchain dependent views.
refreshBlockCount();
refreshBlockChain();
refreshAccounts();
ui->refreshAccounts->setEnabled(true);
// We must update balances since we can't filter updates to basic accounts.
refreshBalances();
@ -401,7 +408,7 @@ void Main::onNewPending()
// update any pending-transaction dependent views.
refreshPending();
refreshAccounts();
ui->refreshAccounts->setEnabled(true);
}
void Main::on_forceMining_triggered()
@ -501,143 +508,71 @@ static Public stringToPublic(QString const& _a)
return Public();
}
QString Main::pretty(dev::Address _a) const
std::string Main::pretty(dev::Address const& _a) const
{
auto g_newNameReg = getNameReg();
if (g_newNameReg)
{
QString s = QString::fromStdString(toString(abiOut<string32>(ethereum()->call(g_newNameReg, abiIn("nameOf(address)", _a)).output)));
if (s.size())
return s;
string n = toString(abiOut<string32>(ethereum()->call(g_newNameReg, abiIn("name(address)", _a)).output));
if (!n.empty())
return n;
}
h256 n;
return fromRaw(n);
}
template <size_t N> inline string toBase36(FixedHash<N> const& _h)
{
static char const* c_alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
typename FixedHash<N>::Arith a = _h;
std::string ret;
for (; a > 0; a /= 36)
ret = c_alphabet[(unsigned)a % 36] + ret;
return ret;
}
template <size_t N> inline FixedHash<N> fromBase36(string const& _h)
{
typename FixedHash<N>::Arith ret = 0;
for (char c: _h)
ret = ret * 36 + (c < 'A' ? c - '0' : (c - 'A' + 10));
return ret;
}
static string iban(std::string _c, std::string _d)
{
boost::to_upper(_c);
boost::to_upper(_d);
auto totStr = _d + _c + "00";
bigint tot = 0;
for (char x: totStr)
if (x >= 'A')
tot = tot * 100 + x - 'A' + 10;
else
tot = tot * 10 + x - '0';
unsigned check = (unsigned)(u256)(98 - tot % 97);
ostringstream out;
out << _c << setfill('0') << setw(2) << check << _d;
return out.str();
}
static std::pair<string, string> fromIban(std::string _iban)
{
if (_iban.size() < 4)
return std::make_pair(string(), string());
boost::to_upper(_iban);
std::string c = _iban.substr(0, 2);
std::string d = _iban.substr(4);
if (iban(c, d) != _iban)
return std::make_pair(string(), string());
return make_pair(c, d);
return string();
}
static string directICAP(dev::Address _a)
std::string Main::render(dev::Address const& _a) const
{
if (!!_a[0])
return string();
std::string d = toBase36<Address::size>(_a);
while (d.size() < 30)
d = "0" + d;
return iban("XE", d);
}
static Address fromICAP(std::string const& _s)
{
std::string country;
std::string data;
std::tie(country, data) = fromIban(_s);
if (country.empty())
return Address();
if (country == "XE" && data.size() == 30)
// Direct ICAP
return fromBase36<Address::size>(data);
// TODO: Indirect ICAP
return Address();
}
QString Main::render(dev::Address _a) const
{
QString p = pretty(_a);
if (!_a[0])
p += QString(p.isEmpty() ? "" : " ") + QString::fromStdString(directICAP(_a));
if (!p.isEmpty())
return p + " (" + QString::fromStdString(_a.abridged()) + ")";
return QString::fromStdString(_a.abridged());
}
string32 fromString(string const& _s)
{
string32 ret;
for (unsigned i = 0; i < 32 && i <= _s.size(); ++i)
ret[i] = i < _s.size() ? _s[i] : 0;
return ret;
string p = pretty(_a);
string n;
if (p.size() == 9 && p.find_first_not_of("QWERYUOPASDFGHJKLZXCVBNM1234567890") == string::npos)
p = ICAP(p, "XREG").encoded();
else
DEV_IGNORE_EXCEPTIONS(n = ICAP(_a).encoded());
if (n.empty())
n = _a.abridged();
return p.empty() ? n : (p + " " + n);
}
Address Main::fromString(QString const& _n) const
pair<Address, bytes> Main::fromString(std::string const& _n) const
{
if (_n == "(Create Contract)")
return Address();
return make_pair(Address(), bytes());
auto g_newNameReg = getNameReg();
if (g_newNameReg)
{
Address a = abiOut<Address>(ethereum()->call(g_newNameReg, abiIn("addressOf(string32)", ::fromString(_n.toStdString()))).output);
Address a = abiOut<Address>(ethereum()->call(g_newNameReg, abiIn("addr(bytes32)", ::toString32(_n))).output);
if (a)
return a;
return make_pair(a, bytes());
}
if (_n.size() == 40)
{
try
{
return Address(fromHex(_n.toStdString(), WhenError::Throw));
return make_pair(Address(fromHex(_n, WhenError::Throw)), bytes());
}
catch (BadHexCharacter& _e)
{
cwarn << "invalid hex character, address rejected";
cwarn << boost::diagnostic_information(_e);
return Address();
return make_pair(Address(), bytes());
}
catch (...)
{
cwarn << "address rejected";
return Address();
return make_pair(Address(), bytes());
}
}
else if (Address a = fromICAP(_n.toStdString()))
return a;
else
return Address();
try {
return ICAP::decoded(_n).address([&](Address const& a, bytes const& b) -> bytes
{
return ethereum()->call(a, b).output;
}, g_newNameReg);
}
catch (...) {}
return make_pair(Address(), bytes());
}
QString Main::lookup(QString const& _a) const
@ -663,7 +598,7 @@ QString Main::lookup(QString const& _a) const
return QString("%1.%2.%3.%4").arg((int)ret[28]).arg((int)ret[29]).arg((int)ret[30]).arg((int)ret[31]);
// TODO: support IPv6.
else if (ret)
return fromRaw(ret);
return QString::fromStdString(fromRaw(ret));
else
return _a;
}
@ -707,6 +642,7 @@ void Main::writeSettings()
s.setValue("upnp", ui->upnp->isChecked());
s.setValue("forceAddress", ui->forcePublicIP->text());
s.setValue("forceMining", ui->forceMining->isChecked());
s.setValue("turboMining", ui->turboMining->isChecked());
s.setValue("paranoia", ui->paranoia->isChecked());
s.setValue("natSpec", ui->natSpec->isChecked());
s.setValue("showAll", ui->showAll->isChecked());
@ -777,6 +713,8 @@ void Main::readSettings(bool _skipGeometry)
ui->dropPeers->setChecked(false);
ui->forceMining->setChecked(s.value("forceMining", false).toBool());
on_forceMining_triggered();
ui->turboMining->setChecked(s.value("turboMining", false).toBool());
on_turboMining_triggered();
ui->paranoia->setChecked(s.value("paranoia", false).toBool());
ui->natSpec->setChecked(s.value("natSpec", true).toBool());
ui->showAll->setChecked(s.value("showAll", false).toBool());
@ -877,22 +815,32 @@ void Main::on_exportKey_triggered()
if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size())
{
auto k = m_myKeys[ui->ourAccounts->currentRow()];
QMessageBox::information(this, "Export Account Key", "Secret key to account " + render(k.address()) + " is:\n" + QString::fromStdString(toHex(k.sec().ref())));
QMessageBox::information(this, "Export Account Key", "Secret key to account " + QString::fromStdString(render(k.address()) + " is:\n" + toHex(k.sec().ref())));
}
}
void Main::on_exportState_triggered()
{
ExportStateDialog dialog(this);
dialog.exec();
}
void Main::on_usePrivate_triggered()
{
if (ui->usePrivate->isChecked())
{
m_privateChain = QInputDialog::getText(this, "Enter Name", "Enter the name of your private chain", QLineEdit::Normal, QString("NewChain-%1").arg(time(0)));
if (m_privateChain.isEmpty())
ui->usePrivate->setChecked(false);
{
if (ui->usePrivate->isChecked())
ui->usePrivate->setChecked(false);
else
// was cancelled.
return;
}
}
else
{
m_privateChain.clear();
}
on_killBlockchain_triggered();
}
@ -949,7 +897,7 @@ void Main::on_preview_triggered()
void Main::refreshMining()
{
MineProgress p = ethereum()->miningProgress();
MiningProgress p = ethereum()->miningProgress();
ui->mineStatus->setText(ethereum()->isMining() ? QString("%1s @ %2kH/s").arg(p.ms / 1000).arg(p.ms ? p.hashes / p.ms : 0) : "Not mining");
if (!ui->miningView->isVisible())
return;
@ -986,7 +934,7 @@ void Main::refreshBalances()
for (auto i: m_myKeys)
{
u256 b = ethereum()->balanceAt(i.address());
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(b).c_str()).arg(render(i.address())).arg((unsigned)ethereum()->countAt(i.address())), ui->ourAccounts))
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(b).c_str()).arg(QString::fromStdString(render(i.address()))).arg((unsigned)ethereum()->countAt(i.address())), ui->ourAccounts))
->setData(Qt::UserRole, QByteArray((char const*)i.address().data(), Address::size));
totalBalance += b;
@ -1018,24 +966,24 @@ void Main::refreshNetwork()
map<h512, QString> sessions;
for (PeerSessionInfo const& i: ps)
ui->peers->addItem(QString("[%8 %7] %3 ms - %1:%2 - %4 %5 %6")
.arg(QString::fromStdString(i.host))
.arg(i.port)
.arg(chrono::duration_cast<chrono::milliseconds>(i.lastPing).count())
.arg(sessions[i.id] = QString::fromStdString(i.clientVersion))
.arg(QString::fromStdString(toString(i.caps)))
.arg(QString::fromStdString(toString(i.notes)))
.arg(i.socket)
.arg(QString::fromStdString(i.id.abridged())));
.arg(QString::fromStdString(i.host))
.arg(i.port)
.arg(chrono::duration_cast<chrono::milliseconds>(i.lastPing).count())
.arg(sessions[i.id] = QString::fromStdString(i.clientVersion))
.arg(QString::fromStdString(toString(i.caps)))
.arg(QString::fromStdString(toString(i.notes)))
.arg(i.socketId)
.arg(QString::fromStdString(i.id.abridged())));
auto ns = web3()->nodes();
for (p2p::Peer const& i: ns)
ui->nodes->insertItem(sessions.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8")
.arg(QString::fromStdString(i.id.abridged()))
.arg(QString::fromStdString(i.peerEndpoint().address().to_string()))
.arg(i.id == web3()->id() ? "self" : sessions.count(i.id) ? sessions[i.id] : "disconnected")
.arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect())) + " | " + QString::number(i.failedAttempts()) + "x" : "")
.arg(i.rating())
);
.arg(QString::fromStdString(i.id.abridged()))
.arg(QString::fromStdString(i.endpoint.address.to_string()))
.arg(i.id == web3()->id() ? "self" : sessions.count(i.id) ? sessions[i.id] : "disconnected")
.arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect())) + " | " + QString::number(i.failedAttempts()) + "x" : "")
.arg(i.rating())
);
}
}
@ -1044,7 +992,7 @@ void Main::refreshAll()
refreshBlockChain();
refreshBlockCount();
refreshPending();
refreshAccounts();
ui->refreshAccounts->setEnabled(true);
refreshBalances();
}
@ -1057,40 +1005,66 @@ void Main::refreshPending()
QString s = t.receiveAddress() ?
QString("%2 %5> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
.arg(render(t.safeSender()))
.arg(render(t.receiveAddress()))
.arg(QString::fromStdString(render(t.safeSender())))
.arg(QString::fromStdString(render(t.receiveAddress())))
.arg((unsigned)t.nonce())
.arg(ethereum()->codeAt(t.receiveAddress()).size() ? '*' : '-') :
QString("%2 +> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
.arg(render(t.safeSender()))
.arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce())))))
.arg(QString::fromStdString(render(t.safeSender())))
.arg(QString::fromStdString(render(right160(sha3(rlpList(t.safeSender(), t.nonce()))))))
.arg((unsigned)t.nonce());
ui->transactionQueue->addItem(s);
}
}
void Main::on_accountsFilter_textChanged()
{
ui->refreshAccounts->setEnabled(true);
}
void Main::on_showBasic_toggled()
{
ui->refreshAccounts->setEnabled(true);
}
void Main::on_showContracts_toggled()
{
ui->refreshAccounts->setEnabled(true);
}
void Main::on_onlyNamed_toggled()
{
ui->refreshAccounts->setEnabled(true);
}
void Main::on_refreshAccounts_clicked()
{
refreshAccounts();
}
void Main::refreshAccounts()
{
#if ETH_FATDB
DEV_TIMED_FUNCTION;
#if ETH_FATDB || !ETH_TRUE
cwatch << "refreshAccounts()";
ui->accounts->clear();
ui->contracts->clear();
for (auto n = 0; n < 2; ++n)
for (auto i: ethereum()->addresses())
{
auto r = render(i);
if (r.contains('(') == !n)
{
if (n == 0 || ui->showAllAccounts->isChecked())
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(r).arg((unsigned)ethereum()->countAt(i)), ui->accounts))
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size));
if (ethereum()->codeAt(i).size())
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(r).arg((unsigned)ethereum()->countAt(i)), ui->contracts))
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size));
}
}
bool showContract = ui->showContracts->isChecked();
bool showBasic = ui->showBasic->isChecked();
bool onlyNamed = ui->onlyNamed->isChecked();
for (auto const& i: ethereum()->addresses())
{
bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3);
if (!((showContract && isContract) || (showBasic && !isContract)))
continue;
string r = render(i);
if (onlyNamed && !(r.find('"') != string::npos || r.substr(0, 2) == "XE"))
continue;
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ui->accounts))
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size));
}
#endif
ui->refreshAccounts->setEnabled(false);
}
void Main::refreshBlockCount()
@ -1107,6 +1081,7 @@ void Main::on_turboMining_triggered()
void Main::refreshBlockChain()
{
DEV_TIMED_FUNCTION;
cwatch << "refreshBlockChain()";
// TODO: keep the same thing highlighted.
@ -1147,30 +1122,33 @@ void Main::refreshBlockChain()
blockItem->setSelected(true);
int n = 0;
auto b = bc.block(h);
for (auto const& i: RLP(b)[1])
{
Transaction t(i.data(), CheckTransaction::Everything);
QString s = t.receiveAddress() ?
QString(" %2 %5> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
.arg(render(t.safeSender()))
.arg(render(t.receiveAddress()))
.arg((unsigned)t.nonce())
.arg(ethereum()->codeAt(t.receiveAddress()).size() ? '*' : '-') :
QString(" %2 +> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
.arg(render(t.safeSender()))
.arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce())))))
.arg((unsigned)t.nonce());
QListWidgetItem* txItem = new QListWidgetItem(s, ui->blocks);
auto hba = QByteArray((char const*)h.data(), h.size);
txItem->setData(Qt::UserRole, hba);
txItem->setData(Qt::UserRole + 1, n);
if (oldSelected == hba)
txItem->setSelected(true);
n++;
try {
auto b = bc.block(h);
for (auto const& i: RLP(b)[1])
{
Transaction t(i.data(), CheckTransaction::Everything);
QString s = t.receiveAddress() ?
QString(" %2 %5> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
.arg(QString::fromStdString(render(t.safeSender())))
.arg(QString::fromStdString(render(t.receiveAddress())))
.arg((unsigned)t.nonce())
.arg(ethereum()->codeAt(t.receiveAddress()).size() ? '*' : '-') :
QString(" %2 +> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
.arg(QString::fromStdString(render(t.safeSender())))
.arg(QString::fromStdString(render(right160(sha3(rlpList(t.safeSender(), t.nonce()))))))
.arg((unsigned)t.nonce());
QListWidgetItem* txItem = new QListWidgetItem(s, ui->blocks);
auto hba = QByteArray((char const*)h.data(), h.size);
txItem->setData(Qt::UserRole, hba);
txItem->setData(Qt::UserRole + 1, n);
if (oldSelected == hba)
txItem->setSelected(true);
n++;
}
}
catch (...) {}
};
if (filters.empty())
@ -1303,7 +1281,7 @@ string Main::renderDiff(StateDiff const& _d) const
s << "<hr/>";
AccountDiff ad = i.second;
s << "<code style=\"white-space: pre; font-weight: bold\">" << lead(ad.changeType()) << " </code>" << " <b>" << render(i.first).toStdString() << "</b>";
s << "<code style=\"white-space: pre; font-weight: bold\">" << lead(ad.changeType()) << " </code>" << " <b>" << render(i.first) << "</b>";
if (!ad.exist.to())
continue;
@ -1336,7 +1314,7 @@ string Main::renderDiff(StateDiff const& _d) const
s << " * ";
s << " </code>";
s << prettyU256(i.first).toStdString();
s << prettyU256(i.first);
/* if (i.first > u256(1) << 246)
s << (h256)i.first;
else if (i.first > u160(1) << 150)
@ -1345,11 +1323,11 @@ string Main::renderDiff(StateDiff const& _d) const
s << hex << i.first;
*/
if (!i.second.from())
s << ": " << prettyU256(i.second.to()).toStdString();
s << ": " << prettyU256(i.second.to());
else if (!i.second.to())
s << " (" << prettyU256(i.second.from()).toStdString() << ")";
s << " (" << prettyU256(i.second.from()) << ")";
else
s << ": " << prettyU256(i.second.to()).toStdString() << " (" << prettyU256(i.second.from()).toStdString() << ")";
s << ": " << prettyU256(i.second.to()) << " (" << prettyU256(i.second.from()) << ")";
}
}
return s.str();
@ -1368,11 +1346,11 @@ void Main::on_transactionQueue_currentItemChanged()
auto ss = tx.safeSender();
h256 th = sha3(rlpList(ss, tx.nonce()));
s << "<h3>" << th << "</h3>";
s << "From: <b>" << pretty(ss).toStdString() << "</b> " << ss;
s << "From: <b>" << pretty(ss) << "</b> " << ss;
if (tx.isCreation())
s << "<br/>Creates: <b>" << pretty(right160(th)).toStdString() << "</b> " << right160(th);
s << "<br/>Creates: <b>" << pretty(right160(th)) << "</b> " << right160(th);
else
s << "<br/>To: <b>" << pretty(tx.receiveAddress()).toStdString() << "</b> " << tx.receiveAddress();
s << "<br/>To: <b>" << pretty(tx.receiveAddress()) << "</b> " << tx.receiveAddress();
s << "<br/>Value: <b>" << formatBalance(tx.value()) << "</b>";
s << "&nbsp;&emsp;&nbsp;#<b>" << tx.nonce() << "</b>";
s << "<br/>Gas price: <b>" << formatBalance(tx.gasPrice()) << "</b>";
@ -1393,6 +1371,8 @@ void Main::on_transactionQueue_currentItemChanged()
s << "<div>Log Bloom: " << receipt.bloom() << "</div>";
else
s << "<div>Log Bloom: <b><i>Uneventful</i></b></div>";
s << "<div>Gas Used: <b>" << receipt.gasUsed() << "</b></div>";
s << "<div>End State: <b>" << receipt.stateRoot().abridged() << "</b></div>";
auto r = receipt.rlp();
s << "<div>Receipt: " << toString(RLP(r)) << "</div>";
s << "<div>Receipt-Hex: " Span(Mono) << toHex(receipt.rlp()) << "</span></div>";
@ -1428,7 +1408,7 @@ void Main::on_inject_triggered()
try
{
bytes b = fromHex(s.toStdString(), WhenError::Throw);
ethereum()->inject(&b);
ethereum()->injectTransaction(b);
}
catch (BadHexCharacter& _e)
{
@ -1441,6 +1421,30 @@ void Main::on_inject_triggered()
}
}
void Main::on_injectBlock_triggered()
{
QString s = QInputDialog::getText(this, "Inject Block", "Enter block dump in hex");
try
{
bytes b = fromHex(s.toStdString(), WhenError::Throw);
ethereum()->injectBlock(b);
}
catch (BadHexCharacter& _e)
{
cwarn << "invalid hex character, transaction rejected";
cwarn << boost::diagnostic_information(_e);
}
catch (...)
{
cwarn << "block rejected";
}
}
static string htmlEscaped(string const& _s)
{
return QString::fromStdString(_s).toHtmlEscaped().toStdString();
}
void Main::on_blocks_currentItemChanged()
{
ui->info->clear();
@ -1470,7 +1474,7 @@ void Main::on_blocks_currentItemChanged()
s << "<div>D/TD: <b>" << info.difficulty << "</b>/<b>" << details.totalDifficulty << "</b> = 2^" << log2((double)info.difficulty) << "/2^" << log2((double)details.totalDifficulty) << "</div>";
s << "&nbsp;&emsp;&nbsp;Children: <b>" << details.children.size() << "</b></div>";
s << "<div>Gas used/limit: <b>" << info.gasUsed << "</b>/<b>" << info.gasLimit << "</b>" << "</div>";
s << "<div>Beneficiary: <b>" << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << " " << info.coinbaseAddress << "</b>" << "</div>";
s << "<div>Beneficiary: <b>" << htmlEscaped(pretty(info.coinbaseAddress)) << " " << info.coinbaseAddress << "</b>" << "</div>";
s << "<div>Seed hash: <b>" << info.seedHash() << "</b>" << "</div>";
s << "<div>Mix hash: <b>" << info.mixHash << "</b>" << "</div>";
s << "<div>Nonce: <b>" << info.nonce << "</b>" << "</div>";
@ -1478,7 +1482,7 @@ void Main::on_blocks_currentItemChanged()
s << "<div>Difficulty: <b>" << info.difficulty << "</b>" << "</div>";
if (info.number)
{
auto e = Ethasher::eval(info);
auto e = EthashAux::eval(info);
s << "<div>Proof-of-Work: <b>" << e.value << " &lt;= " << (h256)u256((bigint(1) << 256) / info.difficulty) << "</b> (mixhash: " << e.mixHash.abridged() << ")" << "</div>";
s << "<div>Parent: <b>" << info.parentHash << "</b>" << "</div>";
}
@ -1501,13 +1505,13 @@ void Main::on_blocks_currentItemChanged()
s << line << "Hash: <b>" << uncle.hash() << "</b>" << "</div>";
s << line << "Parent: <b>" << uncle.parentHash << "</b>" << "</div>";
s << line << "Number: <b>" << uncle.number << "</b>" << "</div>";
s << line << "Coinbase: <b>" << pretty(uncle.coinbaseAddress).toHtmlEscaped().toStdString() << " " << uncle.coinbaseAddress << "</b>" << "</div>";
s << line << "Coinbase: <b>" << htmlEscaped(pretty(uncle.coinbaseAddress)) << " " << uncle.coinbaseAddress << "</b>" << "</div>";
s << line << "Seed hash: <b>" << uncle.seedHash() << "</b>" << "</div>";
s << line << "Mix hash: <b>" << uncle.mixHash << "</b>" << "</div>";
s << line << "Nonce: <b>" << uncle.nonce << "</b>" << "</div>";
s << line << "Hash w/o nonce: <b>" << uncle.headerHash(WithoutNonce) << "</b>" << "</div>";
s << line << "Difficulty: <b>" << uncle.difficulty << "</b>" << "</div>";
auto e = Ethasher::eval(uncle);
auto e = EthashAux::eval(uncle);
s << line << "Proof-of-Work: <b>" << e.value << " &lt;= " << (h256)u256((bigint(1) << 256) / uncle.difficulty) << "</b> (mixhash: " << e.mixHash.abridged() << ")" << "</div>";
}
if (info.parentHash)
@ -1536,11 +1540,11 @@ void Main::on_blocks_currentItemChanged()
TransactionReceipt receipt = ethereum()->blockChain().receipts(h).receipts[txi];
s << "<h3>" << th << "</h3>";
s << "<h4>" << h << "[<b>" << txi << "</b>]</h4>";
s << "<div>From: <b>" << pretty(ss).toHtmlEscaped().toStdString() << " " << ss << "</b>" << "</div>";
s << "<div>From: <b>" << htmlEscaped(pretty(ss)) << " " << ss << "</b>" << "</div>";
if (tx.isCreation())
s << "<div>Creates: <b>" << pretty(right160(th)).toHtmlEscaped().toStdString() << "</b> " << right160(th) << "</div>";
s << "<div>Creates: <b>" << htmlEscaped(pretty(right160(th))) << "</b> " << right160(th) << "</div>";
else
s << "<div>To: <b>" << pretty(tx.receiveAddress()).toHtmlEscaped().toStdString() << "</b> " << tx.receiveAddress() << "</div>";
s << "<div>To: <b>" << htmlEscaped(pretty(tx.receiveAddress())) << "</b> " << tx.receiveAddress() << "</div>";
s << "<div>Value: <b>" << formatBalance(tx.value()) << "</b>" << "</div>";
s << "&nbsp;&emsp;&nbsp;#<b>" << tx.nonce() << "</b>" << "</div>";
s << "<div>Gas price: <b>" << formatBalance(tx.gasPrice()) << "</b>" << "</div>";
@ -1562,6 +1566,8 @@ void Main::on_blocks_currentItemChanged()
s << "<div>Log Bloom: " << receipt.bloom() << "</div>";
else
s << "<div>Log Bloom: <b><i>Uneventful</i></b></div>";
s << "<div>Gas Used: <b>" << receipt.gasUsed() << "</b></div>";
s << "<div>End State: <b>" << receipt.stateRoot().abridged() << "</b></div>";
auto r = receipt.rlp();
s << "<div>Receipt: " << toString(RLP(r)) << "</div>";
s << "<div>Receipt-Hex: " Span(Mono) << toHex(receipt.rlp()) << "</span></div>";
@ -1618,10 +1624,10 @@ void Main::debugDumpState(int _add)
}
}
void Main::on_contracts_currentItemChanged()
void Main::on_accounts_currentItemChanged()
{
ui->contractInfo->clear();
if (auto item = ui->contracts->currentItem())
ui->accountInfo->clear();
if (auto item = ui->accounts->currentItem())
{
auto hba = item->data(Qt::UserRole).toByteArray();
assert(hba.size() == 20);
@ -1632,16 +1638,16 @@ void Main::on_contracts_currentItemChanged()
{
auto storage = ethereum()->storageAt(address);
for (auto const& i: storage)
s << "@" << showbase << hex << prettyU256(i.first).toStdString() << "&nbsp;&nbsp;&nbsp;&nbsp;" << showbase << hex << prettyU256(i.second).toStdString() << "<br/>";
s << "@" << showbase << hex << prettyU256(i.first) << "&nbsp;&nbsp;&nbsp;&nbsp;" << showbase << hex << prettyU256(i.second) << "<br/>";
s << "<h4>Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")</h4>" << disassemble(ethereum()->codeAt(address));
s << Div(Mono) << toHex(ethereum()->codeAt(address)) << "</div>";
ui->contractInfo->appendHtml(QString::fromStdString(s.str()));
ui->accountInfo->appendHtml(QString::fromStdString(s.str()));
}
catch (dev::InvalidTrie)
{
ui->contractInfo->appendHtml("Corrupted trie.");
ui->accountInfo->appendHtml("Corrupted trie.");
}
ui->contractInfo->moveCursor(QTextCursor::Start);
ui->accountInfo->moveCursor(QTextCursor::Start);
}
}
@ -1673,16 +1679,6 @@ void Main::on_accounts_doubleClicked()
}
}
void Main::on_contracts_doubleClicked()
{
if (ui->contracts->count())
{
auto hba = ui->contracts->currentItem()->data(Qt::UserRole).toByteArray();
auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer);
qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray())));
}
}
static shh::FullTopic topicFromText(QString _s)
{
shh::BuildTopic ret;
@ -1749,6 +1745,11 @@ void Main::on_clearPending_triggered()
refreshAll();
}
void Main::on_retryUnknown_triggered()
{
ethereum()->retryUnkonwn();
}
void Main::on_killBlockchain_triggered()
{
writeSettings();
@ -1777,6 +1778,7 @@ void Main::on_net_triggered()
ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : h256());
web3()->startNetwork();
ui->downloadView->setDownloadMan(ethereum()->downloadMan());
ui->enode->setText(QString::fromStdString(web3()->enode()));
}
else
{
@ -1908,7 +1910,12 @@ void Main::on_killAccount_triggered()
if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size())
{
auto k = m_myKeys[ui->ourAccounts->currentRow()];
if (ethereum()->balanceAt(k.address()) != 0 && QMessageBox::critical(this, "Kill Account?!", "Account " + render(k.address()) + " has " + QString::fromStdString(formatBalance(ethereum()->balanceAt(k.address()))) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\nAre you sure you want to continue?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
if (
ethereum()->balanceAt(k.address()) != 0 &&
QMessageBox::critical(this, "Kill Account?!",
QString::fromStdString("Account " + render(k.address()) + " has " + formatBalance(ethereum()->balanceAt(k.address())) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\n"
"Are you sure you want to continue?"),
QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
return;
m_myKeys.erase(m_myKeys.begin() + ui->ourAccounts->currentRow());
keysChanged();
@ -1925,10 +1932,10 @@ void Main::on_go_triggered()
web3()->addNode(p2p::NodeId(), Host::pocHost());
}
QString Main::prettyU256(dev::u256 _n) const
std::string Main::prettyU256(dev::u256 const& _n) const
{
unsigned inc = 0;
QString raw;
string raw;
ostringstream s;
if (_n > szabo && _n < 1000000 * ether)
s << "<span style=\"color: #215\">" << formatBalance(_n) << "</span> <span style=\"color: #448\">(0x" << hex << (uint64_t)_n << ")</span>";
@ -1939,17 +1946,17 @@ QString Main::prettyU256(dev::u256 _n) const
else if ((_n >> 160) == 0)
{
Address a = right160(_n);
QString n = pretty(a);
if (n.isNull())
string n = pretty(a);
if (n.empty())
s << "<span style=\"color: #844\">0x</span><span style=\"color: #800\">" << a << "</span>";
else
s << "<span style=\"font-weight: bold; color: #800\">" << n.toHtmlEscaped().toStdString() << "</span> (<span style=\"color: #844\">0x</span><span style=\"color: #800\">" << a.abridged() << "</span>)";
s << "<span style=\"font-weight: bold; color: #800\">" << htmlEscaped(n) << "</span> (<span style=\"color: #844\">0x</span><span style=\"color: #800\">" << a.abridged() << "</span>)";
}
else if ((raw = fromRaw((h256)_n, &inc)).size())
return "<span style=\"color: #484\">\"</span><span style=\"color: #080\">" + raw.toHtmlEscaped() + "</span><span style=\"color: #484\">\"" + (inc ? " + " + QString::number(inc) : "") + "</span>";
return "<span style=\"color: #484\">\"</span><span style=\"color: #080\">" + htmlEscaped(raw) + "</span><span style=\"color: #484\">\"" + (inc ? " + " + toString(inc) : "") + "</span>";
else
s << "<span style=\"color: #466\">0x</span><span style=\"color: #044\">" << (h256)_n << "</span>";
return QString::fromStdString(s.str());
return s.str();
}
void Main::on_post_clicked()

23
alethzero/MainWin.h

@ -80,10 +80,10 @@ public:
bool confirm() const;
NatSpecFace* natSpec() { return &m_natSpecDB; }
QString pretty(dev::Address _a) const override;
QString prettyU256(dev::u256 _n) const override;
QString render(dev::Address _a) const override;
dev::Address fromString(QString const& _a) const override;
std::string pretty(dev::Address const& _a) const override;
std::string prettyU256(dev::u256 const& _n) const override;
std::string render(dev::Address const& _a) const override;
std::pair<dev::Address, dev::bytes> fromString(std::string const& _a) const override;
std::string renderDiff(dev::eth::StateDiff const& _d) const override;
QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; }
@ -131,16 +131,23 @@ private slots:
void on_importKeyFile_triggered();
void on_exportKey_triggered();
// Account pane
void on_accountsFilter_textChanged();
void on_showBasic_toggled();
void on_showContracts_toggled();
void on_onlyNamed_toggled();
void on_refreshAccounts_clicked();
// Tools
void on_newTransaction_triggered();
void on_loadJS_triggered();
void on_exportState_triggered();
// Stuff concerning the blocks/transactions/accounts panels
void ourAccountsRowsMoved();
void on_ourAccounts_doubleClicked();
void on_accounts_doubleClicked();
void on_contracts_doubleClicked();
void on_contracts_currentItemChanged();
void on_accounts_currentItemChanged();
void on_transactionQueue_currentItemChanged();
void on_blockChainFilter_textChanged();
void on_blocks_currentItemChanged();
@ -159,10 +166,12 @@ private slots:
void on_killBlockchain_triggered();
void on_clearPending_triggered();
void on_inject_triggered();
void on_injectBlock_triggered();
void on_forceMining_triggered();
void on_usePrivate_triggered();
void on_turboMining_triggered();
void on_jitvm_triggered();
void on_retryUnknown_triggered();
// Debugger
void on_debugCurrent_triggered();
@ -251,7 +260,7 @@ private:
std::unique_ptr<jsonrpc::HttpServer> m_httpConnector;
std::unique_ptr<OurWebThreeStubServer> m_server;
static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr);
static std::string fromRaw(dev::h256 _n, unsigned* _inc = nullptr);
NatspecHandler m_natSpecDB;
Transact m_transact;

11
alethzero/MiningView.cpp

@ -36,7 +36,7 @@ using namespace dev::eth;
// types
using dev::eth::MineInfo;
using dev::eth::MineProgress;
using dev::eth::MiningProgress;
// functions
using dev::toString;
@ -50,12 +50,13 @@ MiningView::MiningView(QWidget* _p): QWidget(_p)
{
}
void MiningView::appendStats(list<MineInfo> const& _i, MineProgress const& _p)
void MiningView::appendStats(list<MineInfo> const& _i, MiningProgress const& _p)
{
(void)_p;
if (_i.empty())
return;
unsigned o = m_values.size();
/* unsigned o = m_values.size();
for (MineInfo const& i: _i)
{
m_values.push_back(i.best);
@ -91,7 +92,7 @@ void MiningView::appendStats(list<MineInfo> const& _i, MineProgress const& _p)
m_completes.erase(remove_if(m_completes.begin(), m_completes.end(), [](int i){return i < 0;}), m_completes.end());
m_progress = _p;
update();
update();*/
}
void MiningView::resetStats()
@ -101,6 +102,7 @@ void MiningView::resetStats()
void MiningView::paintEvent(QPaintEvent*)
{
/*
Grapher g;
QPainter p(this);
@ -115,4 +117,5 @@ void MiningView::paintEvent(QPaintEvent*)
g.ruleY(r - 1, QColor(128, 128, 128));
for (auto r: m_completes)
g.ruleY(r, QColor(192, 64, 64));
*/
}

4
alethzero/MiningView.h

@ -42,14 +42,14 @@ class MiningView: public QWidget
public:
MiningView(QWidget* _p = nullptr);
void appendStats(std::list<dev::eth::MineInfo> const& _l, dev::eth::MineProgress const& _p);
void appendStats(std::list<dev::eth::MineInfo> const& _l, dev::eth::MiningProgress const& _p);
void resetStats();
protected:
virtual void paintEvent(QPaintEvent*);
private:
dev::eth::MineProgress m_progress;
dev::eth::MiningProgress m_progress;
unsigned m_duration = 300;
std::vector<float> m_values;
std::vector<float> m_bests;

4
alethzero/NatspecHandler.cpp

@ -51,14 +51,14 @@ NatspecHandler::~NatspecHandler()
void NatspecHandler::add(dev::h256 const& _contractHash, string const& _doc)
{
m_db->Put(m_writeOptions, _contractHash.ref(), _doc);
cdebug << "Registering NatSpec: " << _contractHash.abridged() << _doc;
cdebug << "Registering NatSpec: " << _contractHash << _doc;
}
string NatspecHandler::retrieve(dev::h256 const& _contractHash) const
{
string ret;
m_db->Get(m_readOptions, _contractHash.ref(), &ret);
cdebug << "Looking up NatSpec: " << _contractHash.abridged() << ret;
cdebug << "Looking up NatSpec: " << _contractHash << ret;
return ret;
}

6
alethzero/OurWebThreeStubServer.cpp

@ -73,7 +73,7 @@ bool OurWebThreeStubServer::showCreationNotice(TransactionSkeleton const& _t, bo
bool OurWebThreeStubServer::showSendNotice(TransactionSkeleton const& _t, bool _toProxy)
{
return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to).toStdString() + (_toProxy ? " (this transaction is not executed directly, but forwarded to another ÐApp)" : "") +
return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to) + (_toProxy ? " (this transaction is not executed directly, but forwarded to another ÐApp)" : "") +
", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + ".");
}
@ -81,7 +81,7 @@ bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t,
{
return showAuthenticationPopup("DANGEROUS! Unknown Contract Transaction!",
"ÐApp is attempting to call into an unknown contract at address " +
m_main->pretty(_t.to).toStdString() + ".\n\n" +
m_main->pretty(_t.to) + ".\n\n" +
(_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") +
"Call involves sending " +
formatBalance(_t.value) + " to the recipient, with additional network fees of up to " +
@ -137,7 +137,7 @@ bool OurWebThreeStubServer::validateTransaction(TransactionSkeleton const& _t, b
// otherwise it's a transaction to a contract for which we have the natspec
return showAuthenticationPopup("Contract Transaction",
"ÐApp attempting to conduct contract interaction with " +
m_main->pretty(_t.to).toStdString() +
m_main->pretty(_t.to) +
": <b>" + userNotice + "</b>.\n\n" +
(_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") +
(_t.value > 0 ?

43
alethzero/Transact.cpp

@ -30,14 +30,16 @@
#include <QMessageBox>
#include <liblll/Compiler.h>
#include <liblll/CodeFragment.h>
#if ETH_SOLIDITY || !ETH_TRUE
#include <libsolidity/CompilerStack.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/AST.h>
#include <libsolidity/SourceReferenceFormatter.h>
#endif
#include <libnatspec/NatspecExpressionEvaluator.h>
#include <libethereum/Client.h>
#include <libethereum/Utility.h>
#ifndef _MSC_VER
#if ETH_SERPENT
#include <libserpent/funcs.h>
#include <libserpent/util.h>
#endif
@ -108,12 +110,12 @@ void Transact::updateDestination()
cwatch << "updateDestination()";
QString s;
for (auto i: ethereum()->addresses())
if ((s = m_context->pretty(i)).size())
if ((s = QString::fromStdString(m_context->pretty(i))).size())
// A namereg address
if (ui->destination->findText(s, Qt::MatchExactly | Qt::MatchCaseSensitive) == -1)
ui->destination->addItem(s);
for (int i = 0; i < ui->destination->count(); ++i)
if (ui->destination->itemText(i) != "(Create Contract)" && !m_context->fromString(ui->destination->itemText(i)))
if (ui->destination->itemText(i) != "(Create Contract)" && !m_context->fromString(ui->destination->itemText(i).toStdString()).first)
ui->destination->removeItem(i--);
}
@ -139,10 +141,25 @@ void Transact::updateFee()
void Transact::on_destination_currentTextChanged(QString)
{
if (ui->destination->currentText().size() && ui->destination->currentText() != "(Create Contract)")
if (Address a = m_context->fromString(ui->destination->currentText()))
ui->calculatedName->setText(m_context->render(a));
{
auto p = m_context->fromString(ui->destination->currentText().toStdString());
if (p.first)
ui->calculatedName->setText(QString::fromStdString(m_context->render(p.first)));
else
ui->calculatedName->setText("Unknown Address");
if (!p.second.empty())
{
m_data = p.second;
ui->data->setPlainText(QString::fromStdString("0x" + toHex(m_data)));
ui->data->setEnabled(false);
}
else if (!ui->data->isEnabled())
{
m_data.clear();
ui->data->setPlainText("");
ui->data->setEnabled(true);
}
}
else
ui->calculatedName->setText("Create Contract");
rejigData();
@ -168,6 +185,7 @@ static std::string toString(TransactionException _te)
}
}
#if ETH_SOLIDITY
static string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, string const& _contractName)
{
string ret = "";
@ -182,6 +200,7 @@ static string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, s
}
return ret;
}
#endif
static tuple<vector<string>, bytes, string> userInputToCode(string const& _user, bool _opt)
{
@ -197,6 +216,7 @@ static tuple<vector<string>, bytes, string> userInputToCode(string const& _user,
boost::replace_all_copy(u, " ", "");
data = fromHex(u);
}
#if ETH_SOLIDITY || !ETH_TRUE
else if (sourceIsSolidity(_user))
{
dev::solidity::CompilerStack compiler(true);
@ -220,7 +240,8 @@ static tuple<vector<string>, bytes, string> userInputToCode(string const& _user,
errors.push_back("Solidity: Uncaught exception");
}
}
#ifndef _MSC_VER
#endif
#if ETH_SERPENT
else if (sourceIsSerpent(_user))
{
try
@ -325,7 +346,8 @@ void Transact::rejigData()
er = ethereum()->create(s, value(), m_data, gasNeeded, gasPrice());
else
{
to = m_context->fromString(ui->destination->currentText());
// TODO: cache like m_data.
to = m_context->fromString(ui->destination->currentText().toStdString()).first;
er = ethereum()->call(s, value(), to, m_data, gasNeeded, gasPrice());
}
gasNeeded = (qint64)(er.gasUsed + er.gasRefunded);
@ -394,6 +416,7 @@ void Transact::on_send_clicked()
// If execution is a contract creation, add Natspec to
// a local Natspec LEVELDB
ethereum()->submitTransaction(s, value(), m_data, ui->gas->value(), gasPrice());
#if ETH_SOLIDITY
string src = ui->data->toPlainText().toStdString();
if (sourceIsSolidity(src))
try
@ -407,9 +430,11 @@ void Transact::on_send_clicked()
}
}
catch (...) {}
#endif
}
else
ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText()), m_data, ui->gas->value(), gasPrice());
// TODO: cache like m_data.
ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText().toStdString()).first, m_data, ui->gas->value(), gasPrice());
close();
}
@ -428,7 +453,7 @@ void Transact::on_debug_clicked()
State st(ethereum()->postState());
Transaction t = isCreation() ?
Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) :
Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText()), m_data, st.transactionsFrom(dev::toAddress(s)), s);
Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText().toStdString()).first, m_data, st.transactionsFrom(dev::toAddress(s)), s);
Debugger dw(m_context, this);
Executive e(st, ethereum()->blockChain(), 0);
dw.populate(e, t);

2
alethzero/Transact.ui

@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
<string>Transact</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1" colspan="2">

161
cmake/CMakeParseArguments.cmake

@ -0,0 +1,161 @@
#.rst:
# CMakeParseArguments
# -------------------
#
#
#
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords>
# <multi_value_keywords> args...)
#
# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions
# for parsing the arguments given to that macro or function. It
# processes the arguments and defines a set of variables which hold the
# values of the respective options.
#
# The <options> argument contains all options for the respective macro,
# i.e. keywords which can be used when calling the macro without any
# value following, like e.g. the OPTIONAL keyword of the install()
# command.
#
# The <one_value_keywords> argument contains all keywords for this macro
# which are followed by one value, like e.g. DESTINATION keyword of the
# install() command.
#
# The <multi_value_keywords> argument contains all keywords for this
# macro which can be followed by more than one value, like e.g. the
# TARGETS or FILES keywords of the install() command.
#
# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
# keywords listed in <options>, <one_value_keywords> and
# <multi_value_keywords> a variable composed of the given <prefix>
# followed by "_" and the name of the respective keyword. These
# variables will then hold the respective value from the argument list.
# For the <options> keywords this will be TRUE or FALSE.
#
# All remaining arguments are collected in a variable
# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see
# whether your macro was called with unrecognized parameters.
#
# As an example here a my_install() macro, which takes similar arguments
# as the real install() command:
#
# ::
#
# function(MY_INSTALL)
# set(options OPTIONAL FAST)
# set(oneValueArgs DESTINATION RENAME)
# set(multiValueArgs TARGETS CONFIGURATIONS)
# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
# "${multiValueArgs}" ${ARGN} )
# ...
#
#
#
# Assume my_install() has been called like this:
#
# ::
#
# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
#
#
#
# After the cmake_parse_arguments() call the macro will have set the
# following variables:
#
# ::
#
# MY_INSTALL_OPTIONAL = TRUE
# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
# MY_INSTALL_DESTINATION = "bin"
# MY_INSTALL_RENAME = "" (was not used)
# MY_INSTALL_TARGETS = "foo;bar"
# MY_INSTALL_CONFIGURATIONS = "" (was not used)
# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
#
#
#
# You can then continue and process these variables.
#
# Keywords terminate lists of values, e.g. if directly after a
# one_value_keyword another recognized keyword follows, this is
# interpreted as the beginning of the new option. E.g.
# my_install(TARGETS foo DESTINATION OPTIONAL) would result in
# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION
# would be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
#=============================================================================
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
return()
endif()
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
# first set all result variables to empty/FALSE
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
set(${prefix}_${arg_name})
endforeach()
foreach(option ${_optionNames})
set(${prefix}_${option} FALSE)
endforeach()
set(${prefix}_UNPARSED_ARGUMENTS)
set(insideValues FALSE)
set(currentArgName)
# now iterate over all arguments and fill the result variables
foreach(currentArg ${ARGN})
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
if(insideValues)
if("${insideValues}" STREQUAL "SINGLE")
set(${prefix}_${currentArgName} ${currentArg})
set(insideValues FALSE)
elseif("${insideValues}" STREQUAL "MULTI")
list(APPEND ${prefix}_${currentArgName} ${currentArg})
endif()
else()
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
endif()
else()
if(NOT ${optionIndex} EQUAL -1)
set(${prefix}_${currentArg} TRUE)
set(insideValues FALSE)
elseif(NOT ${singleArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "SINGLE")
elseif(NOT ${multiArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "MULTI")
endif()
endif()
endforeach()
# propagate the result variables to the caller:
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
endforeach()
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
endfunction()

29
cmake/EthCompilerSettings.cmake

@ -8,15 +8,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_RELEASE")
set(ETH_SHARED 1)
if (PROFILING)
set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}")
add_definitions(-DETH_PROFILING_GPERF)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofiler")
# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -lprofiler")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler")
endif ()
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
@ -31,7 +22,6 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG")
set(ETH_SHARED 1)
if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++ -fcolor-diagnostics -Qunused-arguments -DBOOST_ASIO_HAS_CLANG_LIBCXX")
@ -55,12 +45,22 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# stack size 16MB
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075 /STACK:16777216")
# windows likes static
set(ETH_STATIC 1)
if (NOT ETH_STATIC)
message("Forcing static linkage for MSVC.")
set(ETH_STATIC 1)
endif ()
else ()
message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.")
endif ()
if (PROFILING AND (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")))
set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}")
add_definitions(-DETH_PROFILING_GPERF)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofiler")
# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -lprofiler")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler")
endif ()
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
option(USE_LD_GOLD "Use GNU gold linker" ON)
if (USE_LD_GOLD)
@ -72,3 +72,8 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA
endif ()
endif ()
if(ETH_STATIC)
set(BUILD_SHARED_LIBS OFF)
else()
set(BUILD_SHARED_LIBS ON)
endif(ETH_STATIC)

23
cmake/EthDependencies.cmake

@ -4,7 +4,11 @@
# by defining this variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ...
# this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory
string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name)
set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}")
if (CMAKE_CL_64)
set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}/x64")
else ()
set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}/Win32")
endif()
set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR})
# setup directory for cmake generated files and include it globally
@ -59,7 +63,7 @@ if (JSONRPC)
find_package(MHD)
message(" - microhttpd header: ${MHD_INCLUDE_DIRS}")
message(" - microhttpd lib : ${MHD_LIBRARIES}")
message(" - microhttpd dll : ${MHD_DLLS}")
endif() #JSONRPC
# TODO readline package does not yet check for correct version number
@ -86,7 +90,7 @@ endif()
# TODO it is also not required in msvc build
find_package (Gmp 6.0.0)
if (GMP_FOUND)
message(" - gmp Header: ${GMP_INCLUDE_DIRS}")
message(" - gmp header: ${GMP_INCLUDE_DIRS}")
message(" - gmp lib : ${GMP_LIBRARIES}")
endif()
@ -96,6 +100,19 @@ find_package (CURL)
message(" - curl header: ${CURL_INCLUDE_DIRS}")
message(" - curl lib : ${CURL_LIBRARIES}")
# cpuid required for eth
find_package (Cpuid)
if (CPUID_FOUND)
message(" - cpuid header: ${CPUID_INCLUDE_DIRS}")
message(" - cpuid lib : ${CPUID_LIBRARIES}")
endif()
find_package (OpenCL)
if (OpenCL_FOUND)
message(" - opencl header: ${OpenCL_INCLUDE_DIRS}")
message(" - opencl lib : ${OpenCL_LIBRARIES}")
endif()
# find location of jsonrpcstub
find_program(ETH_JSON_RPC_STUB jsonrpcstub)
message(" - jsonrpcstub location : ${ETH_JSON_RPC_STUB}")

33
cmake/EthExecutableHelper.cmake

@ -43,6 +43,22 @@ macro(eth_add_executable EXECUTABLE)
endmacro()
macro(eth_copy_dlls EXECUTABLE DLLS)
# dlls must be unsubstitud list variable (without ${}) in format
# optimized;path_to_dll.dll;debug;path_to_dlld.dll
list(GET ${DLLS} 1 DLL_RELEASE)
list(GET ${DLLS} 3 DLL_DEBUG)
add_custom_command(TARGET ${EXECUTABLE}
POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS
-DDLL_RELEASE="${DLL_RELEASE}"
-DDLL_DEBUG="${DLL_DEBUG}"
-DCONF="$<CONFIGURATION>"
-DDESTINATION="${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
-P "${ETH_SCRIPTS_DIR}/copydlls.cmake"
)
endmacro()
#
# this function requires the following variables to be specified:
# ETH_DEPENDENCY_INSTALL_DIR
@ -78,6 +94,7 @@ macro(eth_install_executable EXECUTABLE)
# This tool and next will inspect linked libraries in order to determine which dependencies are required
if (${CMAKE_CFG_INTDIR} STREQUAL ".")
# TODO: This should only happen for GUI application
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app")
else ()
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app")
@ -107,14 +124,18 @@ macro(eth_install_executable EXECUTABLE)
#copy additional dlls
foreach(dll ${ETH_INSTALL_EXECUTABLE_DLLS})
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS -E copy ${dll} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
)
eth_copy_dlls(${EXECUTABLE} ${dll})
endforeach(dll)
install( TARGETS ${EXECUTABLE} RUNTIME
DESTINATION bin
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Debug"
DESTINATION .
CONFIGURATIONS Debug
COMPONENT ${EXECUTABLE}
)
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Release"
DESTINATION .
CONFIGURATIONS Release
COMPONENT ${EXECUTABLE}
)

17
cmake/EthUtils.cmake

@ -62,3 +62,20 @@ macro(eth_add_test NAME)
endmacro()
# Creates C resources file from files
function(eth_add_resources RESOURCE_FILE OUT_FILE)
include("${RESOURCE_FILE}")
set(OUTPUT "${ETH_RESOURCE_LOCATION}/${ETH_RESOURCE_NAME}.hpp")
set(${OUT_FILE} "${OUTPUT}" PARENT_SCOPE)
set(filenames "${RESOURCE_FILE}")
list(APPEND filenames "${ETH_SCRIPTS_DIR}/resources.cmake")
foreach(resource ${ETH_RESOURCES})
list(APPEND filenames "${${resource}}")
endforeach(resource)
add_custom_command(OUTPUT ${OUTPUT}
COMMAND ${CMAKE_COMMAND} -DETH_RES_FILE="${RESOURCE_FILE}" -P "${ETH_SCRIPTS_DIR}/resources.cmake"
DEPENDS ${filenames}
)
endfunction()

8
cmake/FindCURL.cmake

@ -30,6 +30,7 @@ set(CURL_LIBRARIES ${CURL_LIBRARY})
# same naming convention as in qt (appending debug library with d)
# boost is using the same "hack" as us with "optimized" and "debug"
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
find_library(
CURL_LIBRARY_DEBUG
NAMES curld libcurld
@ -38,6 +39,13 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(CURL_LIBRARIES optimized ${CURL_LIBRARIES} debug ${CURL_LIBRARY_DEBUG})
# prepare dlls
string(REPLACE ".lib" ".dll" CURL_DLL ${CURL_LIBRARY})
string(REPLACE "/lib/" "/bin/" CURL_DLL ${CURL_DLL})
string(REPLACE ".lib" ".dll" CURL_DLL_DEBUG ${CURL_LIBRARY_DEBUG})
string(REPLACE "/lib/" "/bin/" CURL_DLL_DEBUG ${CURL_DLL_DEBUG})
set(CURL_DLLS optimized ${CURL_DLL} debug ${CURL_DLL_DEBUG})
endif()
# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE

33
cmake/FindCpuid.cmake

@ -0,0 +1,33 @@
# Find libcpuid
#
# Find the libcpuid includes and library
#
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH
#
# This module defines
# CPUID_INCLUDE_DIRS, where to find header, etc.
# CPUID_LIBRARIES, the libraries needed to use cpuid.
# CPUID_FOUND, If false, do not try to use cpuid.
# only look in default directories
find_path(
CPUID_INCLUDE_DIR
NAMES libcpuid/libcpuid.h
DOC "libcpuid include dir"
)
find_library(
CPUID_LIBRARY
NAMES cpuid
DOC "libcpuid library"
)
set(CPUID_INCLUDE_DIRS ${CPUID_INCLUDE_DIR})
set(CPUID_LIBRARIES ${CPUID_LIBRARY})
# handle the QUIETLY and REQUIRED arguments and set CPUID_FOUND to TRUE
# if all listed variables are TRUE, hide their existence from configuration view
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(cpuid DEFAULT_MSG CPUID_INCLUDE_DIR CPUID_LIBRARY)
mark_as_advanced (CPUID_INCLUDE_DIR CPUID_LIBRARY)

1
cmake/FindJsoncpp.cmake

@ -30,6 +30,7 @@ set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
# same naming convention as in qt (appending debug library with d)
# boost is using the same "hack" as us with "optimized" and "debug"
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
find_library(
JSONCPP_LIBRARY_DEBUG
NAMES jsoncppd

1
cmake/FindLevelDB.cmake

@ -29,6 +29,7 @@ set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARY})
# same naming convention as in qt (appending debug library with d)
# boost is using the same "hack" as us with "optimized" and "debug"
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
find_library(
LEVELDB_LIBRARY_DEBUG
NAMES leveldbd

16
cmake/FindMHD.cmake

@ -30,18 +30,20 @@ set(MHD_LIBRARIES ${MHD_LIBRARY})
# official MHD project actually uses _d suffix
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
#TODO: place dlls into CMAKE_CFG_INTDIR subfolders
string(REPLACE ".lib" ".dll" MHD_DLL_RELEASE ${MHD_LIBRARY})
string(REPLACE "/lib/" "/bin/" MHD_DLL_RELEASE ${MHD_DLL_RELEASE})
find_library(
MHD_LIBRARY_DEBUG
NAMES microhttpd_d microhttpd-10_d libmicrohttpd_d libmicrohttpd-dll_d
DOC "mhd debug library"
)
# always use release for now
#string(REPLACE ".lib" ".dll" MHD_DLL_DEBUG ${MHD_LIBRARY_DEBUG})
#set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG})
set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG})
# prepare dlls
string(REPLACE ".lib" ".dll" MHD_DLL ${MHD_LIBRARY})
string(REPLACE "/lib/" "/bin/" MHD_DLL ${MHD_DLL})
string(REPLACE ".lib" ".dll" MHD_DLL_DEBUG ${MHD_LIBRARY_DEBUG})
string(REPLACE "/lib/" "/bin/" MHD_DLL_DEBUG ${MHD_DLL_DEBUG})
set(MHD_DLLS optimized ${MHD_DLL} debug ${MHD_DLL_DEBUG})
endif()

136
cmake/FindOpenCL.cmake

@ -0,0 +1,136 @@
#.rst:
# FindOpenCL
# ----------
#
# Try to find OpenCL
#
# Once done this will define::
#
# OpenCL_FOUND - True if OpenCL was found
# OpenCL_INCLUDE_DIRS - include directories for OpenCL
# OpenCL_LIBRARIES - link against this library to use OpenCL
# OpenCL_VERSION_STRING - Highest supported OpenCL version (eg. 1.2)
# OpenCL_VERSION_MAJOR - The major version of the OpenCL implementation
# OpenCL_VERSION_MINOR - The minor version of the OpenCL implementation
#
# The module will also define two cache variables::
#
# OpenCL_INCLUDE_DIR - the OpenCL include directory
# OpenCL_LIBRARY - the path to the OpenCL library
#
#=============================================================================
# Copyright 2014 Matthaeus G. Chajdas
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
function(_FIND_OPENCL_VERSION)
include(CheckSymbolExists)
include(CMakePushCheckState)
set(CMAKE_REQUIRED_QUIET ${OpenCL_FIND_QUIETLY})
CMAKE_PUSH_CHECK_STATE()
foreach(VERSION "2_0" "1_2" "1_1" "1_0")
set(CMAKE_REQUIRED_INCLUDES "${OpenCL_INCLUDE_DIR}")
if(APPLE)
CHECK_SYMBOL_EXISTS(
CL_VERSION_${VERSION}
"${OpenCL_INCLUDE_DIR}/OpenCL/cl.h"
OPENCL_VERSION_${VERSION})
else()
CHECK_SYMBOL_EXISTS(
CL_VERSION_${VERSION}
"${OpenCL_INCLUDE_DIR}/CL/cl.h"
OPENCL_VERSION_${VERSION})
endif()
if(OPENCL_VERSION_${VERSION})
string(REPLACE "_" "." VERSION "${VERSION}")
set(OpenCL_VERSION_STRING ${VERSION} PARENT_SCOPE)
string(REGEX MATCHALL "[0-9]+" version_components "${VERSION}")
list(GET version_components 0 major_version)
list(GET version_components 1 minor_version)
set(OpenCL_VERSION_MAJOR ${major_version} PARENT_SCOPE)
set(OpenCL_VERSION_MINOR ${minor_version} PARENT_SCOPE)
break()
endif()
endforeach()
CMAKE_POP_CHECK_STATE()
endfunction()
find_path(OpenCL_INCLUDE_DIR
NAMES
CL/cl.h OpenCL/cl.h
PATHS
ENV "PROGRAMFILES(X86)"
ENV AMDAPPSDKROOT
ENV INTELOCLSDKROOT
ENV NVSDKCOMPUTE_ROOT
ENV CUDA_PATH
ENV ATISTREAMSDKROOT
PATH_SUFFIXES
include
OpenCL/common/inc
"AMD APP/include")
_FIND_OPENCL_VERSION()
if(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
find_library(OpenCL_LIBRARY
NAMES OpenCL
PATHS
ENV "PROGRAMFILES(X86)"
ENV AMDAPPSDKROOT
ENV INTELOCLSDKROOT
ENV CUDA_PATH
ENV NVSDKCOMPUTE_ROOT
ENV ATISTREAMSDKROOT
PATH_SUFFIXES
"AMD APP/lib/x86"
lib/x86
lib/Win32
OpenCL/common/lib/Win32)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
find_library(OpenCL_LIBRARY
NAMES OpenCL
PATHS
ENV "PROGRAMFILES(X86)"
ENV AMDAPPSDKROOT
ENV INTELOCLSDKROOT
ENV CUDA_PATH
ENV NVSDKCOMPUTE_ROOT
ENV ATISTREAMSDKROOT
PATH_SUFFIXES
"AMD APP/lib/x86_64"
lib/x86_64
lib/x64
OpenCL/common/lib/x64)
endif()
else()
find_library(OpenCL_LIBRARY
NAMES OpenCL)
endif()
set(OpenCL_LIBRARIES ${OpenCL_LIBRARY})
set(OpenCL_INCLUDE_DIRS ${OpenCL_INCLUDE_DIR})
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(
OpenCL
FOUND_VAR OpenCL_FOUND
REQUIRED_VARS OpenCL_LIBRARY OpenCL_INCLUDE_DIR
VERSION_VAR OpenCL_VERSION_STRING)
mark_as_advanced(
OpenCL_INCLUDE_DIR
OpenCL_LIBRARY)

382
cmake/FindPackageHandleStandardArgs.cmake

@ -0,0 +1,382 @@
#.rst:
# FindPackageHandleStandardArgs
# -----------------------------
#
#
#
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> ... )
#
# This function is intended to be used in FindXXX.cmake modules files.
# It handles the REQUIRED, QUIET and version-related arguments to
# find_package(). It also sets the <packagename>_FOUND variable. The
# package is considered found if all variables <var1>... listed contain
# valid results, e.g. valid filepaths.
#
# There are two modes of this function. The first argument in both
# modes is the name of the Find-module where it is called (in original
# casing).
#
# The first simple mode looks like this:
#
# ::
#
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name>
# (DEFAULT_MSG|"Custom failure message") <var1>...<varN> )
#
# If the variables <var1> to <varN> are all valid, then
# <UPPERCASED_NAME>_FOUND will be set to TRUE. If DEFAULT_MSG is given
# as second argument, then the function will generate itself useful
# success and error messages. You can also supply a custom error
# message for the failure case. This is not recommended.
#
# The second mode is more powerful and also supports version checking:
#
# ::
#
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME
# [FOUND_VAR <resultVar>]
# [REQUIRED_VARS <var1>...<varN>]
# [VERSION_VAR <versionvar>]
# [HANDLE_COMPONENTS]
# [CONFIG_MODE]
# [FAIL_MESSAGE "Custom failure message"] )
#
# In this mode, the name of the result-variable can be set either to
# either <UPPERCASED_NAME>_FOUND or <OriginalCase_Name>_FOUND using the
# FOUND_VAR option. Other names for the result-variable are not
# allowed. So for a Find-module named FindFooBar.cmake, the two
# possible names are FooBar_FOUND and FOOBAR_FOUND. It is recommended
# to use the original case version. If the FOUND_VAR option is not
# used, the default is <UPPERCASED_NAME>_FOUND.
#
# As in the simple mode, if <var1> through <varN> are all valid,
# <packagename>_FOUND will be set to TRUE. After REQUIRED_VARS the
# variables which are required for this package are listed. Following
# VERSION_VAR the name of the variable can be specified which holds the
# version of the package which has been found. If this is done, this
# version will be checked against the (potentially) specified required
# version used in the find_package() call. The EXACT keyword is also
# handled. The default messages include information about the required
# version and the version which has been actually found, both if the
# version is ok or not. If the package supports components, use the
# HANDLE_COMPONENTS option to enable handling them. In this case,
# find_package_handle_standard_args() will report which components have
# been found and which are missing, and the <packagename>_FOUND variable
# will be set to FALSE if any of the required components (i.e. not the
# ones listed after OPTIONAL_COMPONENTS) are missing. Use the option
# CONFIG_MODE if your FindXXX.cmake module is a wrapper for a
# find_package(... NO_MODULE) call. In this case VERSION_VAR will be
# set to <NAME>_VERSION and the macro will automatically check whether
# the Config module was found. Via FAIL_MESSAGE a custom failure
# message can be specified, if this is not used, the default message
# will be displayed.
#
# Example for mode 1:
#
# ::
#
# find_package_handle_standard_args(LibXml2 DEFAULT_MSG
# LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
#
#
#
# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and
# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to
# TRUE. If it is not found and REQUIRED was used, it fails with
# FATAL_ERROR, independent whether QUIET was used or not. If it is
# found, success will be reported, including the content of <var1>. On
# repeated Cmake runs, the same message won't be printed again.
#
# Example for mode 2:
#
# ::
#
# find_package_handle_standard_args(LibXslt
# FOUND_VAR LibXslt_FOUND
# REQUIRED_VARS LibXslt_LIBRARIES LibXslt_INCLUDE_DIRS
# VERSION_VAR LibXslt_VERSION_STRING)
#
# In this case, LibXslt is considered to be found if the variable(s)
# listed after REQUIRED_VAR are all valid, i.e. LibXslt_LIBRARIES and
# LibXslt_INCLUDE_DIRS in this case. The result will then be stored in
# LibXslt_FOUND . Also the version of LibXslt will be checked by using
# the version contained in LibXslt_VERSION_STRING. Since no
# FAIL_MESSAGE is given, the default messages will be printed.
#
# Another example for mode 2:
#
# ::
#
# find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
# find_package_handle_standard_args(Automoc4 CONFIG_MODE)
#
# In this case, FindAutmoc4.cmake wraps a call to find_package(Automoc4
# NO_MODULE) and adds an additional search directory for automoc4. Here
# the result will be stored in AUTOMOC4_FOUND. The following
# FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper
# success/error message.
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
# internal helper macro
macro(_FPHSA_FAILURE_MESSAGE _msg)
if (${_NAME}_FIND_REQUIRED)
message(FATAL_ERROR "${_msg}")
else ()
if (NOT ${_NAME}_FIND_QUIETLY)
message(STATUS "${_msg}")
endif ()
endif ()
endmacro()
# internal helper macro to generate the failure message when used in CONFIG_MODE:
macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
# <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
if(${_NAME}_CONFIG)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
else()
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
# List them all in the error message:
if(${_NAME}_CONSIDERED_CONFIGS)
set(configsText "")
list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
math(EXPR configsCount "${configsCount} - 1")
foreach(currentConfigIndex RANGE ${configsCount})
list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
set(configsText "${configsText} ${filename} (version ${version})\n")
endforeach()
if (${_NAME}_NOT_FOUND_MESSAGE)
set(configsText "${configsText} Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n")
endif()
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}")
else()
# Simple case: No Config-file was found at all:
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
endif()
endif()
endmacro()
function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in
# new extended or in the "old" mode:
set(options CONFIG_MODE HANDLE_COMPONENTS)
set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR)
set(multiValueArgs REQUIRED_VARS)
set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
if(${INDEX} EQUAL -1)
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
set(FPHSA_REQUIRED_VARS ${ARGN})
set(FPHSA_VERSION_VAR)
else()
CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
if(FPHSA_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
endif()
if(NOT FPHSA_FAIL_MESSAGE)
set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
endif()
endif()
# now that we collected all arguments, process them
if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
endif()
# In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package()
# when it successfully found the config-file, including version checking:
if(FPHSA_CONFIG_MODE)
list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
endif()
if(NOT FPHSA_REQUIRED_VARS)
message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
endif()
list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
string(TOUPPER ${_NAME} _NAME_UPPER)
string(TOLOWER ${_NAME} _NAME_LOWER)
if(FPHSA_FOUND_VAR)
if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$")
set(_FOUND_VAR ${FPHSA_FOUND_VAR})
else()
message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.")
endif()
else()
set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
endif()
# collect all variables which were not found, so they can be printed, so the
# user knows better what went wrong (#6375)
set(MISSING_VARS "")
set(DETAILS "")
# check if all passed variables are valid
unset(${_FOUND_VAR})
foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
if(NOT ${_CURRENT_VAR})
set(${_FOUND_VAR} FALSE)
set(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}")
else()
set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]")
endif()
endforeach()
if(NOT "${${_FOUND_VAR}}" STREQUAL "FALSE")
set(${_FOUND_VAR} TRUE)
endif()
# component handling
unset(FOUND_COMPONENTS_MSG)
unset(MISSING_COMPONENTS_MSG)
if(FPHSA_HANDLE_COMPONENTS)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(${_NAME}_${comp}_FOUND)
if(NOT DEFINED FOUND_COMPONENTS_MSG)
set(FOUND_COMPONENTS_MSG "found components: ")
endif()
set(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}")
else()
if(NOT DEFINED MISSING_COMPONENTS_MSG)
set(MISSING_COMPONENTS_MSG "missing components: ")
endif()
set(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}")
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_FOUND_VAR} FALSE)
set(MISSING_VARS "${MISSING_VARS} ${comp}")
endif()
endif()
endforeach()
set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
set(DETAILS "${DETAILS}[c${COMPONENT_MSG}]")
endif()
# version handling:
set(VERSION_MSG "")
set(VERSION_OK TRUE)
set(VERSION ${${FPHSA_VERSION_VAR}})
# check with DEFINED here as the requested or found version may be "0"
if (DEFINED ${_NAME}_FIND_VERSION)
if(DEFINED ${FPHSA_VERSION_VAR})
if(${_NAME}_FIND_VERSION_EXACT) # exact version required
# count the dots in the version string
string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${VERSION}")
# add one dot because there is one dot more than there are components
string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS)
if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT)
# Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT
# is at most 4 here. Therefore a simple lookup table is used.
if (${_NAME}_FIND_VERSION_COUNT EQUAL 1)
set(_VERSION_REGEX "[^.]*")
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2)
set(_VERSION_REGEX "[^.]*\\.[^.]*")
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3)
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*")
else ()
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
endif ()
string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${VERSION}")
unset(_VERSION_REGEX)
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD)
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
endif ()
unset(_VERSION_HEAD)
else ()
if (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
endif ()
endif ()
unset(_VERSION_DOTS)
else() # minimum version specified:
if ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
set(VERSION_MSG "(found suitable version \"${VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")")
endif ()
endif()
else()
# if the package was not found, but a version was given, add that to the output:
if(${_NAME}_FIND_VERSION_EXACT)
set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
else()
set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
endif()
endif()
else ()
if(VERSION)
set(VERSION_MSG "(found version \"${VERSION}\")")
endif()
endif ()
if(VERSION_OK)
set(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]")
else()
set(${_FOUND_VAR} FALSE)
endif()
# print the result:
if (${_FOUND_VAR})
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
else ()
if(FPHSA_CONFIG_MODE)
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
else()
if(NOT VERSION_OK)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
else()
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}")
endif()
endif()
endif ()
set(${_FOUND_VAR} ${${_FOUND_VAR}} PARENT_SCOPE)
endfunction()

57
cmake/FindPackageMessage.cmake

@ -0,0 +1,57 @@
#.rst:
# FindPackageMessage
# ------------------
#
#
#
# FIND_PACKAGE_MESSAGE(<name> "message for user" "find result details")
#
# This macro is intended to be used in FindXXX.cmake modules files. It
# will print a message once for each unique find result. This is useful
# for telling the user where a package was found. The first argument
# specifies the name (XXX) of the package. The second argument
# specifies the message to display. The third argument lists details
# about the find result so that if they change the message will be
# displayed again. The macro also obeys the QUIET argument to the
# find_package command.
#
# Example:
#
# ::
#
# if(X11_FOUND)
# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
# else()
# ...
# endif()
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
function(FIND_PACKAGE_MESSAGE pkg msg details)
# Avoid printing a message repeatedly for the same find result.
if(NOT ${pkg}_FIND_QUIETLY)
string(REPLACE "\n" "" details "${details}")
set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
# The message has not yet been printed.
message(STATUS "${msg}")
# Save the find details in the cache to avoid printing the same
# message again.
set("${DETAILS_VAR}" "${details}"
CACHE INTERNAL "Details about finding ${pkg}")
endif()
endif()
endfunction()

1
cmake/Findjson_rpc_cpp.cmake

@ -52,6 +52,7 @@ set (JSON_RPC_CPP_CLIENT_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP
# same naming convention as in qt (appending debug library with d)
# boost is using the same "hack" as us with "optimized" and "debug"
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
find_library(
JSON_RPC_CPP_COMMON_LIBRARY_DEBUG
NAMES jsonrpccpp-commond

18
cmake/scripts/copydlls.cmake

@ -0,0 +1,18 @@
# this module expects
# DLLS
# CONF
# DESTINATION
# example usage:
# cmake -DDLL_DEBUG=xd.dll -DDLL_RELEASE=x.dll -DCONFIGURATION=Release -DDESTINATION=dest -P scripts/copydlls.cmake
# this script is created cause we do not know configuration in multiconfiguration generators at cmake configure phase ;)
if ("${CONF}" STREQUAL "Release")
set(DLL ${DLL_RELEASE})
else () # Debug
set(DLL ${DLL_DEBUG})
endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${DLL}" "${DESTINATION}")

1
cmake/scripts/jsonrpcstub.cmake

@ -42,4 +42,3 @@ else()
replace_if_different("${SERVER_TMPFILE}" "${SERVER_OUTFILE}")
replace_if_different("${CLIENT_TMPFILE}" "${CLIENT_OUTFILE}")
endif()

30
cmake/scripts/resource.hpp.in

@ -0,0 +1,30 @@
// this file is autogenerated, do not modify!!!
#pragma once
#include <string>
#include <map>
namespace dev
{
namespace eth
{
class ${ETH_RESOURCE_NAME}
{
public:
${ETH_RESOURCE_NAME}()
{
${ETH_RESULT_DATA}
${ETH_RESULT_INIT}
}
std::string loadResourceAsString(std::string _name) { return std::string(m_resources[_name], m_sizes[_name]); }
private:
std::map <std::string, const char*> m_resources;
std::map <std::string, unsigned> m_sizes;
};
}
}

57
cmake/scripts/resources.cmake

@ -0,0 +1,57 @@
# based on: http://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake
#
# example:
# cmake -DETH_RES_FILE=test.cmake -P resources.cmake
#
# where test.cmake is:
#
# # BEGIN OF cmake.test
#
# set(copydlls "copydlls.cmake")
# set(conf "configure.cmake")
#
# # this three properties must be set!
#
# set(ETH_RESOURCE_NAME "EthResources")
# set(ETH_RESOURCE_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}")
# set(ETH_RESOURCES "copydlls" "conf")
#
# # END of cmake.test
#
# should define ETH_RESOURCES
include(${ETH_RES_FILE})
set(ETH_RESULT_DATA "")
set(ETH_RESULT_INIT "")
# resource is a name visible for cpp application
foreach(resource ${ETH_RESOURCES})
# filename is the name of file which will be used in app
set(filename ${${resource}})
# filedata is a file content
file(READ ${filename} filedata HEX)
# read full name of the file
file(GLOB filename ${filename})
# Convert hex data for C compatibility
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata})
# append static variables to result variable
set(ETH_RESULT_DATA "${ETH_RESULT_DATA} static const unsigned char eth_${resource}[] = {\n // ${filename}\n ${filedata}\n};\n")
# append init resources
set(ETH_RESULT_INIT "${ETH_RESULT_INIT} m_resources[\"${resource}\"] = (char const*)eth_${resource};\n")
set(ETH_RESULT_INIT "${ETH_RESULT_INIT} m_sizes[\"${resource}\"] = sizeof(eth_${resource});\n")
endforeach(resource)
set(ETH_DST_NAME "${ETH_RESOURCE_LOCATION}/${ETH_RESOURCE_NAME}")
configure_file("${CMAKE_CURRENT_LIST_DIR}/resource.hpp.in" "${ETH_DST_NAME}.hpp.tmp")
include("${CMAKE_CURRENT_LIST_DIR}/../EthUtils.cmake")
replace_if_different("${ETH_DST_NAME}.hpp.tmp" "${ETH_DST_NAME}.hpp")

43
docker/Dockerfile

@ -1,36 +1,31 @@
FROM ubuntu:14.04
FROM ubuntu:utopic
MAINTAINER caktux
ENV DEBIAN_FRONTEND noninteractive
# Usual update / upgrade
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get upgrade -q -y
RUN apt-get dist-upgrade -q -y
# Ethereum dependencies
RUN apt-get install -qy build-essential g++-4.8 git cmake libboost-all-dev libcurl4-openssl-dev wget
RUN apt-get install -qy automake unzip libgmp-dev libtool libleveldb-dev yasm libminiupnpc-dev libreadline-dev scons
RUN apt-get install -qy libjsoncpp-dev libargtable2-dev
RUN apt-get install -qy libncurses5-dev libcurl4-openssl-dev wget
RUN apt-get install -qy libjsoncpp-dev libargtable2-dev libmicrohttpd-dev
# Let our containers upgrade themselves
RUN apt-get install -q -y unattended-upgrades
# Ethereum PPA
RUN apt-get install -qy software-properties-common
# Install Ethereum
RUN apt-get install -q -y software-properties-common
RUN add-apt-repository ppa:ethereum/ethereum
RUN add-apt-repository ppa:ethereum/ethereum-dev
RUN apt-get update
RUN apt-get install -qy libcryptopp-dev libjson-rpc-cpp-dev
RUN apt-get install -q -y eth
# LLVM-3.5
RUN wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add -
RUN echo "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.5 main\ndeb-src http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.5 main" > /etc/apt/sources.list.d/llvm-trusty.list
RUN apt-get update
RUN apt-get install -qy llvm-3.5 libedit-dev
# Install supervisor
RUN apt-get install -q -y supervisor
# Fix llvm-3.5 cmake paths
RUN mkdir -p /usr/lib/llvm-3.5/share/llvm && ln -s /usr/share/llvm-3.5/cmake /usr/lib/llvm-3.5/share/llvm/cmake
# Add supervisor configs
ADD supervisord.conf supervisord.conf
# Build Ethereum (HEADLESS)
RUN git clone --depth=1 https://github.com/ethereum/cpp-ethereum
RUN mkdir -p cpp-ethereum/build
RUN cd cpp-ethereum/build && cmake .. -DHEADLESS=1 -DLLVM_DIR=/usr/share/llvm-3.5/cmake -DEVMJIT=1 && make -j $(cat /proc/cpuinfo | grep processor | wc -l) && make install
RUN ldconfig
EXPOSE 8080
EXPOSE 30303
ENTRYPOINT ["/usr/local/bin/eth"]
CMD ["-n", "-c", "/supervisord.conf"]
ENTRYPOINT ["/usr/bin/supervisord"]

31
docker/README.md

@ -1,17 +1,30 @@
# Dockerfile for cpp-ethereum
Dockerfile to build a bleeding edge cpp-ethereum docker image from source
docker build -t cppeth < Dockerfile
### Quick usage
Run a simple peer server
docker run -d ethereum/client-cpp
docker run -i cppeth -m off -o peer -x 256
### Building
GUI is compiled but not exposed. You can mount /cpp-ethereum/build to access binaries:
Dockerfile to build a cpp-ethereum docker image from source
cid = $(docker run -i -v /cpp-ethereum/build cppeth -m off -o peer -x 256)
docker inspect $cid # <-- Find volume path in JSON output
docker build -t cpp-ethereum .
You may also modify the Docker image to run the GUI and expose a
ssh/VNC server in order to tunnel an X11 or VNC session.
### Running
docker run -d cpp-ethereum
### Usage
First enter the container:
docker exec -it <container name> bash
Inspect logs:
cat /var/log/cpp-ethereum.log
cat /var/log/cpp-ethereum.err
Restart supervisor service:
supervisorctl restart cpp-ethereum

23
docker/supervisord.conf

@ -0,0 +1,23 @@
[supervisord]
nodaemon=false
[program:eth]
priority=30
directory=/
command=eth --bootstrap --json-rpc
user=root
autostart=true
autorestart=true
startsecs=10
stopsignal=QUIT
stdout_logfile=/var/log/eth.log
stderr_logfile=/var/log/eth.err
[unix_http_server]
file=%(here)s/supervisor.sock
[supervisorctl]
serverurl=unix://%(here)s/supervisor.sock
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

14
eth/CMakeLists.txt

@ -23,14 +23,22 @@ endif()
if (JSONRPC)
target_link_libraries(${EXECUTABLE} web3jsonrpc)
target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_CLIENT_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${CURL_LIBRARIES})
if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW)
eth_copy_dlls(${EXECUTABLE} CURL_DLLS)
endif()
endif()
target_link_libraries(${EXECUTABLE} webthree)
target_link_libraries(${EXECUTABLE} ethash)
if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW)
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy ${MHD_DLL_RELEASE} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
eth_copy_dlls("${EXECUTABLE}" MHD_DLLS)
endif()
install( TARGETS ${EXECUTABLE} DESTINATION bin )
if (APPLE)
install(TARGETS ${EXECUTABLE} DESTINATION bin)
else()
eth_install_executable(${EXECUTABLE})
endif()

39
eth/Farm.h

@ -0,0 +1,39 @@
/**
* This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY!
*/
#ifndef JSONRPC_CPP_STUB_FARM_H_
#define JSONRPC_CPP_STUB_FARM_H_
#include <jsonrpccpp/client.h>
class Farm : public jsonrpc::Client
{
public:
Farm(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {}
Json::Value eth_getWork() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_getWork",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
p.append(param3);
Json::Value result = this->CallMethod("eth_submitWork",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
};
#endif //JSONRPC_CPP_STUB_FARM_H_

28
eth/PhoneHome.h

@ -0,0 +1,28 @@
/**
* This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY!
*/
#ifndef JSONRPC_CPP_STUB_PHONEHOME_H_
#define JSONRPC_CPP_STUB_PHONEHOME_H_
#include <jsonrpccpp/client.h>
class PhoneHome : public jsonrpc::Client
{
public:
PhoneHome(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {}
int report_benchmark(const std::string& param1, int param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("report_benchmark",p);
if (result.isInt())
return result.asInt();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
};
#endif //JSONRPC_CPP_STUB_PHONEHOME_H_

4
eth/farm.json

@ -0,0 +1,4 @@
[
{ "name": "eth_getWork", "params": [], "order": [], "returns": []},
{ "name": "eth_submitWork", "params": ["", "", ""], "order": [], "returns": true}
]

634
eth/main.cpp

@ -32,20 +32,26 @@
#include <libdevcrypto/FileSystem.h>
#include <libevmcore/Instruction.h>
#include <libdevcore/StructuredLogger.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/EthashAux.h>
#include <libevm/VM.h>
#include <libevm/VMFactory.h>
#include <libethereum/All.h>
#include <libwebthree/WebThree.h>
#if ETH_READLINE
#if ETH_READLINE || !ETH_TRUE
#include <readline/readline.h>
#include <readline/history.h>
#endif
#if ETH_JSONRPC
#if ETH_JSONRPC || !ETH_TRUE
#include <libweb3jsonrpc/WebThreeStubServer.h>
#include <jsonrpccpp/server/connectors/httpserver.h>
#include <jsonrpccpp/client/connectors/httpclient.h>
#endif
#include <libethcore/Ethasher.h>
#include "BuildInfo.h"
#if ETH_JSONRPC || !ETH_TRUE
#include "PhoneHome.h"
#include "Farm.h"
#endif
using namespace std;
using namespace dev;
using namespace dev::p2p;
@ -88,7 +94,7 @@ void interactiveHelp()
<< " send Execute a given transaction with current secret." << endl
<< " contract Create a new contract with current secret." << endl
<< " peers List the peers that are connected" << endl
#if ETH_FATDB
#if ETH_FATDB || !ETH_TRUE
<< " listaccounts List the accounts on the network." << endl
<< " listcontracts List the contracts on the network." << endl
#endif
@ -106,46 +112,73 @@ void help()
{
cout
<< "Usage eth [OPTIONS]" << endl
<< "Options:" << endl
<< "Options:" << endl << endl
<< "Client mode (default):" << endl
<< " -o,--mode <full/peer> Start a full node or a peer node (default: full)." << endl
<< " -i,--interactive Enter interactive mode (default: non-interactive)." << endl
#if ETH_JSONRPC || !ETH_TRUE
<< " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl
<< " --json-rpc-port <n> Specify JSON-RPC server port (implies '-j', default: " << SensibleHttpPort << ")." << endl
#endif
<< " -K,--kill First kill the blockchain." << endl
<< " -R,--rebuild Rebuild the blockchain from the existing database." << endl
<< " -s,--secret <secretkeyhex> Set the secret key for use with send command (default: auto)." << endl
<< " -S,--session-secret <secretkeyhex> Set the secret key for use with send command, for this session only." << endl
<< "Client transacting:" << endl
<< " -B,--block-fees <n> Set the block fee profit in the reference unit e.g. ¢ (default: 15)." << endl
<< " -e,--ether-price <n> Set the ether price in the reference unit e.g. ¢ (default: 30.679)." << endl
<< " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl
<< "Client mining:" << endl
<< " -a,--address <addr> Set the coinbase (mining payout) address to addr (default: auto)." << endl
<< " -m,--mining <on/off/number> Enable mining, optionally for a specified number of blocks (default: off)" << endl
<< " -f,--force-mining Mine even when there are no transactions to mine (default: off)" << endl
<< " -C,--cpu When mining, use the CPU." << endl
<< " -G,--opencl When mining use the GPU via OpenCL." << endl
<< " --opencl-platform <n> When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl
<< " --opencl-device <n> When mining using -G/--opencl use OpenCL device n (default: 0)." << endl
<< " -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl
<< "Client networking:" << endl
<< " --client-name <name> Add a name to your client's version string (default: blank)." << endl
<< " -b,--bootstrap Connect to the default Ethereum peerserver." << endl
<< " -B,--block-fees <n> Set the block fee profit in the reference unit e.g. ¢ (Default: 15)." << endl
<< " -c,--client-name <name> Add a name to your client's version string (default: blank)." << endl
<< " -d,--db-path <path> Load database from path (default: ~/.ethereum " << endl
<< " <APPDATA>/Etherum or Library/Application Support/Ethereum)." << endl
<< " -x,--peers <number> Attempt to connect to given number of peers (default: 5)." << endl
<< " --public-ip <ip> Force public ip to given (default: auto)." << endl
<< " --listen-ip <ip>(:<port>) Listen on the given IP for incoming connections (default: 0.0.0.0)." << endl
<< " --listen <port> Listen on the given port for incoming connections (default: 30303)." << endl
<< " -r,--remote <host>(:<port>) Connect to remote host (default: none)." << endl
<< " --port <port> Connect to remote port (default: 30303)." << endl
<< " --network-id <n> Only connect to other hosts with this network id (default:0)." << endl
<< " --upnp <on/off> Use UPnP for NAT (default: on)." << endl
#if ETH_JSONRPC || !ETH_TRUE
<< "Work farming mode:" << endl
<< " -F,--farm <url> Put into mining farm mode with the work server at URL. Use with -G/--opencl." << endl
<< " --farm-recheck <n> Leave n ms between checks for changed work (default: 500)." << endl
#endif
<< "Ethash verify mode:" << endl
<< " -w,--check-pow <headerHash> <seedHash> <difficulty> <nonce> Check PoW credentials for validity." << endl
<< "Benchmarking mode:" << endl
<< " -M,--benchmark Benchmark for mining and exit; use with --cpu and --opencl." << endl
<< " --benchmark-warmup <seconds> Set the duration of warmup for the benchmark tests (default: 3)." << endl
<< " --benchmark-trial <seconds> Set the duration for each trial for the benchmark tests (default: 3)." << endl
<< " --benchmark-trials <n> Set the duration of warmup for the benchmark tests (default: 5)." << endl
#if ETH_JSONRPC || !ETH_TRUE
<< " --phone-home <on/off> When benchmarking, publish results (default: on)" << endl
#endif
<< "DAG creation mode:" << endl
<< " -D,--create-dag <this/next/number> Create the DAG in preparation for mining on given block and exit." << endl
<< " -e,--ether-price <n> Set the ether price in the reference unit e.g. ¢ (Default: 30.679)." << endl
<< "Import/export modes:" << endl
<< " -I,--import <file> Import file as a concatenated series of blocks and exit." << endl
<< " -E,--export <file> Export file as a concatenated series of blocks and exit." << endl
<< " --from <n> Export only from block n; n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl
<< " --to <n> Export only to block n (inclusive); n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl
<< " --only <n> Equivalent to --export-from n --export-to n." << endl
<< " -f,--force-mining Mine even when there are no transaction to mine (Default: off)" << endl
<< " -h,--help Show this help message and exit." << endl
<< " -i,--interactive Enter interactive mode (default: non-interactive)." << endl
<< " -I,--import <file> Import file as a concatenated series of blocks and exit." << endl
#if ETH_JSONRPC
<< " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl
<< " --json-rpc-port Specify JSON-RPC server port (implies '-j', default: " << SensibleHttpPort << ")." << endl
<< "General Options:" << endl
<< " -d,--db-path <path> Load database from path (default: " << getDataDir() << ")" << endl
#if ETH_EVMJIT || !ETH_TRUE
<< " -J,--jit Enable EVM JIT (default: off)." << endl
#endif
<< " -K,--kill First kill the blockchain." << endl
<< " --listen-ip <port> Listen on the given port for incoming connections (default: 30303)." << endl
<< " -l,--listen <ip> Listen on the given IP for incoming connections (default: 0.0.0.0)." << endl
<< " -u,--public-ip <ip> Force public ip to given (default: auto)." << endl
<< " -m,--mining <on/off/number> Enable mining, optionally for a specified number of blocks (Default: off)" << endl
<< " -n,--upnp <on/off> Use upnp for NAT (default: on)." << endl
<< " -o,--mode <full/peer> Start a full node or a peer node (Default: full)." << endl
<< " -p,--port <port> Connect to remote port (default: 30303)." << endl
<< " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl
<< " -R,--rebuild First rebuild the blockchain from the existing database." << endl
<< " -r,--remote <host> Connect to remote host (default: none)." << endl
<< " -s,--secret <secretkeyhex> Set the secret key for use with send command (default: auto)." << endl
<< " -t,--miners <number> Number of mining threads to start (Default: " << thread::hardware_concurrency() << ")" << endl
<< " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (Default: 8)." << endl
<< " -x,--peers <number> Attempt to connect to given number of peers (Default: 5)." << endl
<< " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (default: 8)." << endl
<< " -V,--version Show the version and exit." << endl
#if ETH_EVMJIT
<< " --jit Use EVM JIT (default: off)." << endl
#endif
<< " -h,--help Show this help message and exit." << endl
;
exit(0);
}
@ -210,7 +243,7 @@ void doInitDAG(unsigned _n)
BlockInfo bi;
bi.number = _n;
cout << "Initializing DAG for epoch beginning #" << (bi.number / 30000 * 30000) << " (seedhash " << bi.seedHash().abridged() << "). This will take a while." << endl;
Ethasher::get()->full(bi);
Ethash::prep(bi);
exit(0);
}
@ -219,7 +252,9 @@ enum class OperationMode
Node,
Import,
Export,
DAGInit
DAGInit,
Benchmark,
Farm
};
enum class Format
@ -229,8 +264,217 @@ enum class Format
Human
};
enum class MinerType
{
CPU,
GPU
};
void doBenchmark(MinerType _m, bool _phoneHome, unsigned _warmupDuration = 15, unsigned _trialDuration = 3, unsigned _trials = 5)
{
BlockInfo genesis = CanonBlockChain::genesis();
genesis.difficulty = 1 << 18;
cdebug << genesis.boundary();
GenericFarm<Ethash> f;
f.onSolutionFound([&](ProofOfWork::Solution) { return false; });
string platformInfo = _m == MinerType::CPU ? ProofOfWork::CPUMiner::platformInfo() : _m == MinerType::GPU ? ProofOfWork::GPUMiner::platformInfo() : "";
cout << "Benchmarking on platform: " << platformInfo << endl;
cout << "Preparing DAG..." << endl;
Ethash::prep(genesis);
genesis.difficulty = u256(1) << 63;
genesis.noteDirty();
f.setWork(genesis);
if (_m == MinerType::CPU)
f.startCPU();
else if (_m == MinerType::GPU)
f.startGPU();
map<uint64_t, MiningProgress> results;
uint64_t mean = 0;
uint64_t innerMean = 0;
for (unsigned i = 0; i <= _trials; ++i)
{
if (!i)
cout << "Warming up..." << endl;
else
cout << "Trial " << i << "... " << flush;
this_thread::sleep_for(chrono::seconds(i ? _trialDuration : _warmupDuration));
auto mp = f.miningProgress();
f.resetMiningProgress();
if (!i)
continue;
auto rate = mp.rate();
cout << rate << endl;
results[rate] = mp;
mean += rate;
if (i > 1 && i < 5)
innerMean += rate;
}
f.stop();
innerMean /= (_trials - 2);
cout << "min/mean/max: " << results.begin()->second.rate() << "/" << (mean / _trials) << "/" << results.rbegin()->second.rate() << " H/s" << endl;
cout << "inner mean: " << innerMean << " H/s" << endl;
(void)_phoneHome;
#if ETH_JSONRPC || !ETH_TRUE
if (_phoneHome)
{
cout << "Phoning home to find world ranking..." << endl;
jsonrpc::HttpClient client("http://gav.ethdev.com:3000/benchmark");
PhoneHome rpc(client);
try
{
unsigned ranking = rpc.report_benchmark(platformInfo, innerMean);
cout << "Ranked: " << ranking << " of all benchmarks." << endl;
}
catch (...)
{
cout << "Error phoning home. ET is sad." << endl;
}
}
#endif
exit(0);
}
struct HappyChannel: public LogChannel { static const char* name() { return ":-D"; } static const int verbosity = 1; };
struct SadChannel: public LogChannel { static const char* name() { return ":-("; } static const int verbosity = 1; };
void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod)
{
(void)_m;
(void)_remote;
(void)_recheckPeriod;
#if ETH_JSONRPC || !ETH_TRUE
jsonrpc::HttpClient client(_remote);
Farm rpc(client);
GenericFarm<Ethash> f;
if (_m == MinerType::CPU)
f.startCPU();
else if (_m == MinerType::GPU)
f.startGPU();
ProofOfWork::WorkPackage current;
while (true)
try
{
bool completed = false;
ProofOfWork::Solution solution;
f.onSolutionFound([&](ProofOfWork::Solution sol)
{
solution = sol;
return completed = true;
});
for (unsigned i = 0; !completed; ++i)
{
if (current)
cnote << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress();
else
cnote << "Getting work package...";
Json::Value v = rpc.eth_getWork();
h256 hh(v[0].asString());
if (hh != current.headerHash)
{
current.headerHash = hh;
current.seedHash = h256(v[1].asString());
current.boundary = h256(fromHex(v[2].asString()), h256::AlignRight);
cnote << "Got work package:" << current.headerHash << " < " << current.boundary;
f.setWork(current);
}
this_thread::sleep_for(chrono::milliseconds(_recheckPeriod));
}
cnote << "Solution found; submitting [" << solution.nonce << "," << current.headerHash << "," << solution.mixHash << "] to" << _remote << "...";
bool ok = rpc.eth_submitWork("0x" + toString(solution.nonce), "0x" + toString(current.headerHash), "0x" + toString(solution.mixHash));
if (ok)
clog(HappyChannel) << "Submitted and accepted.";
else
clog(SadChannel) << "Not accepted.";
current.reset();
}
catch (jsonrpc::JsonRpcException&)
{
for (auto i = 3; --i; this_thread::sleep_for(chrono::seconds(1)))
cerr << "JSON-RPC problem. Probably couldn't connect. Retrying in " << i << "... \r";
cerr << endl;
}
#endif
exit(0);
}
int main(int argc, char** argv)
{
#if 0
cout << "\x1b[30mEthBlack\x1b[0m" << endl;
cout << "\x1b[90mEthCoal\x1b[0m" << endl;
cout << "\x1b[37mEthGray\x1b[0m" << endl;
cout << "\x1b[97mEthWhite\x1b[0m" << endl;
cout << "\x1b[31mEthRed\x1b[0m" << endl;
cout << "\x1b[32mEthGreen\x1b[0m" << endl;
cout << "\x1b[33mEthYellow\x1b[0m" << endl;
cout << "\x1b[34mEthBlue\x1b[0m" << endl;
cout << "\x1b[35mEthPurple\x1b[0m" << endl;
cout << "\x1b[36mEthCyan\x1b[0m" << endl;
// High Intensity
cout << "\x1b[91mEthRedI\x1b[0m" << endl;
cout << "\x1b[92mEthLime\x1b[0m" << endl;
cout << "\x1b[93mEthYellowI\x1b[0m" << endl;
cout << "\x1b[94mEthBlueI\x1b[0m" << endl;
cout << "\x1b[95mEthPurpleI\x1b[0m" << endl;
cout << "\x1b[96mEthCyanI\x1b[0m" << endl;
// Bold
cout << "\x1b[1;30mEthBlackB\x1b[0m" << endl;
cout << "\x1b[1;90mEthCoalB\x1b[0m" << endl;
cout << "\x1b[1;37mEthGrayB\x1b[0m" << endl;
cout << "\x1b[1;97mEthWhiteB\x1b[0m" << endl;
cout << "\x1b[1;31mEthRedB\x1b[0m" << endl;
cout << "\x1b[1;32mEthGreenB\x1b[0m" << endl;
cout << "\x1b[1;33mEthYellowB\x1b[0m" << endl;
cout << "\x1b[1;34mEthBlueB\x1b[0m" << endl;
cout << "\x1b[1;35mEthPurpleB\x1b[0m" << endl;
cout << "\x1b[1;36mEthCyanB\x1b[0m" << endl;
// Bold High Intensity
cout << "\x1b[1;91mEthRedBI\x1b[0m" << endl;
cout << "\x1b[1;92mEthGreenBI\x1b[0m" << endl;
cout << "\x1b[1;93mEthYellowBI\x1b[0m" << endl;
cout << "\x1b[1;94mEthBlueBI\x1b[0m" << endl;
cout << "\x1b[1;95mEthPurpleBI\x1b[0m" << endl;
cout << "\x1b[1;96mEthCyanBI\x1b[0m" << endl;
// Background
cout << "\x1b[40mEthBlackOn\x1b[0m" << endl;
cout << "\x1b[100mEthCoalOn\x1b[0m" << endl;
cout << "\x1b[47mEthGrayOn\x1b[0m" << endl;
cout << "\x1b[107mEthWhiteOn\x1b[0m" << endl;
cout << "\x1b[41mEthRedOn\x1b[0m" << endl;
cout << "\x1b[42mEthGreenOn\x1b[0m" << endl;
cout << "\x1b[43mEthYellowOn\x1b[0m" << endl;
cout << "\x1b[44mEthBlueOn\x1b[0m" << endl;
cout << "\x1b[45mEthPurpleOn\x1b[0m" << endl;
cout << "\x1b[46mEthCyanOn\x1b[0m" << endl;
// High Intensity backgrounds
cout << "\x1b[101mEthRedOnI\x1b[0m" << endl;
cout << "\x1b[102mEthGreenOnI\x1b[0m" << endl;
cout << "\x1b[103mEthYellowOnI\x1b[0m" << endl;
cout << "\x1b[104mEthBlueOnI\x1b[0m" << endl;
cout << "\x1b[105mEthPurpleOnI\x1b[0m" << endl;
cout << "\x1b[106mEthCyanOnI\x1b[0m" << endl;
// Underline
cout << "\x1b[4;30mEthBlackU\x1b[0m" << endl;
cout << "\x1b[4;31mEthRedU\x1b[0m" << endl;
cout << "\x1b[4;32mEthGreenU\x1b[0m" << endl;
cout << "\x1b[4;33mEthYellowU\x1b[0m" << endl;
cout << "\x1b[4;34mEthBlueU\x1b[0m" << endl;
cout << "\x1b[4;35mEthPurpleU\x1b[0m" << endl;
cout << "\x1b[4;36mEthCyanU\x1b[0m" << endl;
cout << "\x1b[4;37mEthWhiteU\x1b[0m" << endl;
#endif
// Init defaults
Defaults::get();
@ -238,6 +482,12 @@ int main(int argc, char** argv)
OperationMode mode = OperationMode::Node;
string dbPath;
/// Mining options
MinerType minerType = MinerType::CPU;
unsigned openclPlatform = 0;
unsigned openclDevice = 0;
unsigned miningThreads = UINT_MAX;
/// File name for import/export.
string filename;
@ -268,14 +518,14 @@ int main(int argc, char** argv)
unsigned short remotePort = 30303;
unsigned peers = 5;
bool bootstrap = false;
unsigned networkId = 0;
/// Mining params
unsigned mining = ~(unsigned)0;
int miners = -1;
unsigned mining = 0;
bool forceMining = false;
bool turboMining = false;
KeyPair us = KeyPair::create();
Address coinbase = us.address();
KeyPair sigKey = KeyPair::create();
Secret sessionSecret;
Address coinbase = sigKey.address();
/// Structured logging params
bool structuredLogging = false;
@ -286,12 +536,22 @@ int main(int argc, char** argv)
double etherPrice = 30.679;
double blockFees = 15.0;
/// Benchmarking params
bool phoneHome = true;
unsigned benchmarkWarmup = 3;
unsigned benchmarkTrial = 3;
unsigned benchmarkTrials = 5;
/// Farm params
string farmURL = "http://127.0.0.1:8080";
unsigned farmRecheckPeriod = 500;
string configFile = getDataDir() + "/config.rlp";
bytes b = contents(configFile);
if (b.size())
{
RLP config(b);
us = KeyPair(config[0].toHash<Secret>());
sigKey = KeyPair(config[0].toHash<Secret>());
coinbase = config[1].toHash<Address>();
}
@ -301,13 +561,25 @@ int main(int argc, char** argv)
if (arg == "--listen-ip" && i + 1 < argc)
listenIP = argv[++i];
else if ((arg == "-l" || arg == "--listen" || arg == "--listen-port") && i + 1 < argc)
{
if (arg == "-l")
cerr << "-l is DEPRECATED. It will be removed for the Frontier. Use --listen-port instead." << endl;
listenPort = (short)atoi(argv[++i]);
}
else if ((arg == "-u" || arg == "--public-ip" || arg == "--public") && i + 1 < argc)
{
if (arg == "-u")
cerr << "-u is DEPRECATED. It will be removed for the Frontier. Use --public-ip instead." << endl;
publicIP = argv[++i];
}
else if ((arg == "-r" || arg == "--remote") && i + 1 < argc)
remoteHost = argv[++i];
else if ((arg == "-p" || arg == "--port") && i + 1 < argc)
{
if (arg == "-p")
cerr << "-p is DEPRECATED. It will be removed for the Frontier. Use --port instead (or place directly as host:port)." << endl;
remotePort = (short)atoi(argv[++i]);
}
else if ((arg == "-I" || arg == "--import") && i + 1 < argc)
{
mode = OperationMode::Import;
@ -318,6 +590,52 @@ int main(int argc, char** argv)
mode = OperationMode::Export;
filename = argv[++i];
}
else if ((arg == "-F" || arg == "--farm") && i + 1 < argc)
{
mode = OperationMode::Farm;
farmURL = argv[++i];
}
else if (arg == "--farm-recheck" && i + 1 < argc)
try {
farmRecheckPeriod = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--opencl-platform" && i + 1 < argc)
try {
openclPlatform = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--opencl-device" && i + 1 < argc)
try {
openclDevice = stol(argv[++i]);
miningThreads = 1;
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--phone-home" && i + 1 < argc)
{
string m = argv[++i];
if (isTrue(m))
phoneHome = true;
else if (isFalse(m))
phoneHome = false;
else
{
cerr << "Bad " << arg << " option: " << m << endl;
return -1;
}
}
else if (arg == "--format" && i + 1 < argc)
{
string m = argv[++i];
@ -339,8 +657,10 @@ int main(int argc, char** argv)
exportFrom = argv[++i];
else if (arg == "--only" && i + 1 < argc)
exportTo = exportFrom = argv[++i];
else if ((arg == "-n" || arg == "--upnp") && i + 1 < argc)
else if ((arg == "-n" || arg == "-u" || arg == "--upnp") && i + 1 < argc)
{
if (arg == "-n")
cerr << "-n is DEPRECATED. It will be removed for the Frontier. Use --upnp instead." << endl;
string m = argv[++i];
if (isTrue(m))
upnp = true;
@ -352,18 +672,57 @@ int main(int argc, char** argv)
return -1;
}
}
else if (arg == "--network-id" && i + 1 < argc)
try {
networkId = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--benchmark-warmup" && i + 1 < argc)
try {
benchmarkWarmup = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--benchmark-trial" && i + 1 < argc)
try {
benchmarkTrial = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--benchmark-trials" && i + 1 < argc)
try {
benchmarkTrials = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "-K" || arg == "--kill-blockchain" || arg == "--kill")
killChain = WithExisting::Kill;
else if (arg == "-B" || arg == "--rebuild")
else if (arg == "-R" || arg == "--rebuild")
killChain = WithExisting::Verify;
else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc)
{
if (arg == "-c")
cerr << "-c is DEPRECATED. It will be removed for the Frontier. Use --client-name instead." << endl;
clientName = argv[++i];
}
else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc)
try
{
try {
coinbase = h160(fromHex(argv[++i], WhenError::Throw));
}
catch (BadHexCharacter& _e)
catch (BadHexCharacter&)
{
cerr << "Bad hex in " << arg << " option: " << argv[i] << endl;
return -1;
@ -373,8 +732,14 @@ int main(int argc, char** argv)
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "-C" || arg == "--cpu")
minerType = MinerType::CPU;
else if (arg == "-G" || arg == "--opencl")
minerType = MinerType::GPU;
else if ((arg == "-s" || arg == "--secret") && i + 1 < argc)
us = KeyPair(h256(fromHex(argv[++i])));
sigKey = KeyPair(h256(fromHex(argv[++i])));
else if ((arg == "-S" || arg == "--session-secret") && i + 1 < argc)
sessionSecret = h256(fromHex(argv[++i]));
else if (arg == "--structured-logging-format" && i + 1 < argc)
structuredLoggingFormat = string(argv[++i]);
else if (arg == "--structured-logging")
@ -400,6 +765,45 @@ int main(int argc, char** argv)
return -1;
}
}
else if ((arg == "-w" || arg == "--check-pow") && i + 4 < argc)
{
string m;
try
{
BlockInfo bi;
m = boost::to_lower_copy(string(argv[++i]));
h256 powHash(m);
m = boost::to_lower_copy(string(argv[++i]));
h256 seedHash;
if (m.size() == 64 || m.size() == 66)
seedHash = h256(m);
else
seedHash = EthashAux::seedHash(stol(m));
m = boost::to_lower_copy(string(argv[++i]));
bi.difficulty = u256(m);
auto boundary = bi.boundary();
m = boost::to_lower_copy(string(argv[++i]));
bi.nonce = h64(m);
auto r = EthashAux::eval(seedHash, powHash, bi.nonce);
bool valid = r.value < boundary;
cout << (valid ? "VALID :-)" : "INVALID :-(") << endl;
cout << r.value << (valid ? " < " : " >= ") << boundary << endl;
cout << " where " << boundary << " = 2^256 / " << bi.difficulty << endl;
cout << " and " << r.value << " = ethash(" << powHash << ", " << bi.nonce << ")" << endl;
cout << " with seed as " << seedHash << endl;
if (valid)
cout << "(mixHash = " << r.mixHash << ")" << endl;
cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light(seedHash)->data()) << endl;
exit(0);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << m << endl;
return -1;
}
}
else if (arg == "-M" || arg == "--benchmark")
mode = OperationMode::Benchmark;
else if ((arg == "-B" || arg == "--block-fees") && i + 1 < argc)
{
try
@ -462,12 +866,21 @@ int main(int argc, char** argv)
return -1;
}
}
else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc)
{
try {
miningThreads = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
}
else if (arg == "-b" || arg == "--bootstrap")
bootstrap = true;
else if (arg == "-f" || arg == "--force-mining")
forceMining = true;
else if (arg == "-T" || arg == "--turbo-mining")
turboMining = true;
else if (arg == "-i" || arg == "--interactive")
interactive = true;
#if ETH_JSONRPC
@ -480,8 +893,6 @@ int main(int argc, char** argv)
g_logVerbosity = atoi(argv[++i]);
else if ((arg == "-x" || arg == "--peers") && i + 1 < argc)
peers = atoi(argv[++i]);
else if ((arg == "-t" || arg == "--miners") && i + 1 < argc)
miners = atoi(argv[++i]);
else if ((arg == "-o" || arg == "--mode") && i + 1 < argc)
{
string m = argv[++i];
@ -495,15 +906,12 @@ int main(int argc, char** argv)
return -1;
}
}
else if (arg == "--jit")
{
#if ETH_EVMJIT
else if (arg == "-J" || arg == "--jit")
{
jit = true;
#else
cerr << "EVM JIT not enabled" << endl;
return -1;
#endif
}
#endif
else if (arg == "-h" || arg == "--help")
help();
else if (arg == "-V" || arg == "--version")
@ -517,15 +925,35 @@ int main(int argc, char** argv)
{
RLPStream config(2);
config << us.secret() << coinbase;
config << sigKey.secret() << coinbase;
writeFile(configFile, config.out());
}
if (sessionSecret)
sigKey = KeyPair(sessionSecret);
if (minerType == MinerType::CPU)
ProofOfWork::CPUMiner::setNumInstances(miningThreads);
else if (minerType == MinerType::GPU)
{
ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform);
ProofOfWork::GPUMiner::setDefaultDevice(openclDevice);
ProofOfWork::GPUMiner::setNumInstances(miningThreads);
}
// Two codepaths is necessary since named block require database, but numbered
// blocks are superuseful to have when database is already open in another process.
if (mode == OperationMode::DAGInit && !(initDAG == LatestBlock || initDAG == PendingBlock))
doInitDAG(initDAG);
if (mode == OperationMode::Benchmark)
doBenchmark(minerType, phoneHome, benchmarkWarmup, benchmarkTrial, benchmarkTrials);
if (mode == OperationMode::Farm)
doFarm(minerType, farmURL, farmRecheckPeriod);
if (!clientName.empty())
clientName += "/";
@ -533,16 +961,14 @@ int main(int argc, char** argv)
VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter);
auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp);
auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp");
std::string clientImplString = "Ethereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : "");
std::string clientImplString = "++eth/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : "");
dev::WebThreeDirect web3(
clientImplString,
dbPath,
killChain,
nodeMode == NodeMode::Full ? set<string>{"eth", "shh"} : set<string>(),
netPrefs,
&nodesState,
miners
);
&nodesState);
if (mode == OperationMode::DAGInit)
doInitDAG(web3.ethereum()->blockChain().number() + (initDAG == PendingBlock ? 30000 : 0));
@ -597,26 +1023,13 @@ int main(int argc, char** argv)
in.read((char*)block.data(), 8);
block.resize(RLP(block, RLP::LaisezFaire).actualSize());
in.read((char*)block.data() + 8, block.size() - 8);
try
switch (web3.ethereum()->injectBlock(block))
{
web3.ethereum()->injectBlock(block);
good++;
}
catch (AlreadyHaveBlock const&)
{
alreadyHave++;
}
catch (UnknownParent const&)
{
unknownParent++;
}
catch (FutureTime const&)
{
futureTime++;
}
catch (...)
{
bad++;
case ImportResult::Success: good++; break;
case ImportResult::AlreadyKnown: alreadyHave++; break;
case ImportResult::UnknownParent: unknownParent++; break;
case ImportResult::FutureTime: futureTime++; break;
default: bad++; break;
}
}
cout << (good + bad + futureTime + unknownParent + alreadyHave) << " total: " << good << " ok, " << alreadyHave << " got, " << futureTime << " future, " << unknownParent << " unknown parent, " << bad << " malformed." << endl;
@ -632,13 +1045,15 @@ int main(int argc, char** argv)
{
c->setGasPricer(gasPricer);
c->setForceMining(forceMining);
c->setTurboMining(turboMining);
c->setTurboMining(minerType == MinerType::GPU);
c->setAddress(coinbase);
c->setNetworkId(networkId);
}
cout << "Transaction Signer: " << us.address() << endl;
cout << "Transaction Signer: " << sigKey.address() << endl;
cout << "Mining Benefactor: " << coinbase << endl;
web3.startNetwork();
cout << "Node ID: " << web3.enode() << endl;
if (bootstrap)
web3.addNode(p2p::NodeId(), Host::pocHost());
@ -651,8 +1066,7 @@ int main(int argc, char** argv)
if (jsonrpc > -1)
{
jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads));
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector<KeyPair>({us})));
jsonrpcServer->setIdentities({us});
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector<KeyPair>({sigKey})));
jsonrpcServer->StartListening();
}
#endif
@ -725,13 +1139,33 @@ int main(int argc, char** argv)
else if (c && cmd == "setblockfees")
{
iss >> blockFees;
gasPricer->setRefBlockFees(u256(blockFees * 1000));
try
{
gasPricer->setRefBlockFees(u256(blockFees * 1000));
}
catch (Overflow const& _e)
{
cout << boost::diagnostic_information(_e);
}
cout << "Block fees: " << blockFees << endl;
}
else if (c && cmd == "setetherprice")
{
iss >> etherPrice;
gasPricer->setRefPrice(u256(double(ether / 1000) / etherPrice));
if (etherPrice == 0)
cout << "ether price cannot be set to zero" << endl;
else
{
try
{
gasPricer->setRefPrice(u256(double(ether / 1000) / etherPrice));
}
catch (Overflow const& _e)
{
cout << boost::diagnostic_information(_e);
}
}
cout << "ether Price: " << etherPrice << endl;
}
else if (c && cmd == "setpriority")
@ -776,8 +1210,7 @@ int main(int argc, char** argv)
if (jsonrpc < 0)
jsonrpc = SensibleHttpPort;
jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads));
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector<KeyPair>({us})));
jsonrpcServer->setIdentities({us});
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector<KeyPair>({sigKey})));
jsonrpcServer->StartListening();
}
else if (cmd == "jsonstop")
@ -789,12 +1222,11 @@ int main(int argc, char** argv)
#endif
else if (cmd == "address")
{
cout << "Current address:" << endl
<< toHex(us.address().asArray()) << endl;
cout << "Current address:" << endl << sigKey.address() << endl;
}
else if (cmd == "secret")
{
cout << "Secret Key: " << toHex(us.secret().asArray()) << endl;
cout << "Secret Key: " << sigKey.secret() << endl;
}
else if (c && cmd == "block")
{
@ -809,7 +1241,7 @@ int main(int argc, char** argv)
}
else if (c && cmd == "balance")
{
cout << "Current balance: " << formatBalance( c->balanceAt(us.address())) << " = " <<c->balanceAt(us.address()) << " wei" << endl;
cout << "Current balance: " << formatBalance( c->balanceAt(sigKey.address())) << " = " <<c->balanceAt(sigKey.address()) << " wei" << endl;
}
else if (c && cmd == "transact")
{
@ -907,9 +1339,9 @@ int main(int argc, char** argv)
{
string hexAddr;
u256 amount;
int size = hexAddr.length();
iss >> hexAddr >> amount;
int size = hexAddr.length();
if (size < 40)
{
if (size > 0)
@ -925,7 +1357,7 @@ int main(int argc, char** argv)
try
{
Address dest = h160(fromHex(hexAddr, WhenError::Throw));
c->submitTransaction(us.secret(), amount, dest, bytes(), minGas);
c->submitTransaction(sigKey.secret(), amount, dest, bytes(), minGas);
}
catch (BadHexCharacter& _e)
{
@ -994,7 +1426,7 @@ int main(int argc, char** argv)
else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas;
else
c->submitTransaction(us.secret(), endowment, init, gas, gasPrice);
c->submitTransaction(sigKey.secret(), endowment, init, gas, gasPrice);
}
else
cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX";
@ -1111,7 +1543,7 @@ int main(int argc, char** argv)
{
string hexSec;
iss >> hexSec;
us = KeyPair(h256(fromHex(hexSec)));
sigKey = KeyPair(h256(fromHex(hexSec)));
}
else
cwarn << "Require parameter: setSecret HEXSECRETKEY";
@ -1151,7 +1583,7 @@ int main(int argc, char** argv)
string path;
iss >> path;
RLPStream config(2);
config << us.secret() << coinbase;
config << sigKey.secret() << coinbase;
writeFile(path, config.out());
}
else
@ -1167,7 +1599,7 @@ int main(int argc, char** argv)
if (b.size())
{
RLP config(b);
us = KeyPair(config[0].toHash<Secret>());
sigKey = KeyPair(config[0].toHash<Secret>());
coinbase = config[1].toHash<Address>();
}
else

3
eth/phonehome.json

@ -0,0 +1,3 @@
[
{ "name": "report_benchmark", "params": [ "", 0 ], "order": [], "returns": 0 }
]

45
ethminer/CMakeLists.txt

@ -0,0 +1,45 @@
cmake_policy(SET CMP0015 NEW)
set(CMAKE_AUTOMOC OFF)
aux_source_directory(. SRC_LIST)
include_directories(BEFORE ..)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
set(EXECUTABLE ethminer)
file(GLOB HEADERS "*.h")
add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
add_dependencies(${EXECUTABLE} BuildInfo.h)
target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES})
if (READLINE_FOUND)
target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES})
endif()
if (JSONRPC)
target_link_libraries(${EXECUTABLE} web3jsonrpc)
target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_CLIENT_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${CURL_LIBRARIES})
if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW)
eth_copy_dlls(${EXECUTABLE} CURL_DLLS)
endif()
endif()
target_link_libraries(${EXECUTABLE} webthree)
target_link_libraries(${EXECUTABLE} ethash)
if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW)
eth_copy_dlls("${EXECUTABLE}" MHD_DLLS)
endif()
if (APPLE)
install(TARGETS ${EXECUTABLE} DESTINATION bin)
else()
eth_install_executable(${EXECUTABLE})
endif()

39
ethminer/Farm.h

@ -0,0 +1,39 @@
/**
* This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY!
*/
#ifndef JSONRPC_CPP_STUB_FARM_H_
#define JSONRPC_CPP_STUB_FARM_H_
#include <jsonrpccpp/client.h>
class Farm : public jsonrpc::Client
{
public:
Farm(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {}
Json::Value eth_getWork() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_getWork",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
p.append(param3);
Json::Value result = this->CallMethod("eth_submitWork",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
};
#endif //JSONRPC_CPP_STUB_FARM_H_

28
ethminer/PhoneHome.h

@ -0,0 +1,28 @@
/**
* This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY!
*/
#ifndef JSONRPC_CPP_STUB_PHONEHOME_H_
#define JSONRPC_CPP_STUB_PHONEHOME_H_
#include <jsonrpccpp/client.h>
class PhoneHome : public jsonrpc::Client
{
public:
PhoneHome(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {}
int report_benchmark(const std::string& param1, int param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("report_benchmark",p);
if (result.isInt())
return result.asInt();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
};
#endif //JSONRPC_CPP_STUB_PHONEHOME_H_

4
ethminer/farm.json

@ -0,0 +1,4 @@
[
{ "name": "eth_getWork", "params": [], "order": [], "returns": []},
{ "name": "eth_submitWork", "params": ["", "", ""], "order": [], "returns": true}
]

484
ethminer/main.cpp

@ -0,0 +1,484 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file main.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
* Ethereum client.
*/
#include <thread>
#include <chrono>
#include <fstream>
#include <iostream>
#include <signal.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim_all.hpp>
#include <libdevcrypto/FileSystem.h>
#include <libevmcore/Instruction.h>
#include <libdevcore/StructuredLogger.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/EthashAux.h>
#include <libevm/VM.h>
#include <libevm/VMFactory.h>
#include <libethereum/All.h>
#include <libwebthree/WebThree.h>
#if ETH_JSONRPC || !ETH_TRUE
#include <libweb3jsonrpc/WebThreeStubServer.h>
#include <jsonrpccpp/server/connectors/httpserver.h>
#include <jsonrpccpp/client/connectors/httpclient.h>
#endif
#include "BuildInfo.h"
#if ETH_JSONRPC || !ETH_TRUE
#include "PhoneHome.h"
#include "Farm.h"
#endif
using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::eth;
using namespace boost::algorithm;
using dev::eth::Instruction;
#undef RETURN
bool isTrue(std::string const& _m)
{
return _m == "on" || _m == "yes" || _m == "true" || _m == "1";
}
bool isFalse(std::string const& _m)
{
return _m == "off" || _m == "no" || _m == "false" || _m == "0";
}
void help()
{
cout
<< "Usage ethminer [OPTIONS]" << endl
<< "Options:" << endl << endl
#if ETH_JSONRPC || !ETH_TRUE
<< "Work farming mode:" << endl
<< " -F,--farm <url> Put into mining farm mode with the work server at URL (default: http://127.0.0.1:8080)" << endl
<< " --farm-recheck <n> Leave n ms between checks for changed work (default: 500)." << endl
#endif
<< "Benchmarking mode:" << endl
<< " -M,--benchmark Benchmark for mining and exit; use with --cpu and --opencl." << endl
<< " --benchmark-warmup <seconds> Set the duration of warmup for the benchmark tests (default: 3)." << endl
<< " --benchmark-trial <seconds> Set the duration for each trial for the benchmark tests (default: 3)." << endl
<< " --benchmark-trials <n> Set the duration of warmup for the benchmark tests (default: 5)." << endl
#if ETH_JSONRPC || !ETH_TRUE
<< " --phone-home <on/off> When benchmarking, publish results (default: on)" << endl
#endif
<< "DAG creation mode:" << endl
<< " -D,--create-dag <number> Create the DAG in preparation for mining on given block and exit." << endl
<< "General Options:" << endl
<< " -C,--cpu When mining, use the CPU." << endl
<< " -G,--opencl When mining use the GPU via OpenCL." << endl
<< " --opencl-platform <n> When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl
<< " --opencl-device <n> When mining using -G/--opencl use OpenCL device n (default: 0)." << endl
<< " -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl
<< " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (default: 8)." << endl
<< " -V,--version Show the version and exit." << endl
<< " -h,--help Show this help message and exit." << endl
;
exit(0);
}
string credits()
{
std::ostringstream cout;
cout
<< "Ethereum (++) " << dev::Version << endl
<< " Code by Gav Wood et al, (c) 2013, 2014, 2015." << endl
<< " Based on a design by Vitalik Buterin." << endl << endl;
return cout.str();
}
void version()
{
cout << "eth version " << dev::Version << endl;
cout << "eth network protocol version: " << dev::eth::c_protocolVersion << endl;
cout << "Client database version: " << dev::eth::c_databaseVersion << endl;
cout << "Build: " << DEV_QUOTED(ETH_BUILD_PLATFORM) << "/" << DEV_QUOTED(ETH_BUILD_TYPE) << endl;
exit(0);
}
void doInitDAG(unsigned _n)
{
BlockInfo bi;
bi.number = _n;
cout << "Initializing DAG for epoch beginning #" << (bi.number / 30000 * 30000) << " (seedhash " << bi.seedHash().abridged() << "). This will take a while." << endl;
Ethash::prep(bi);
exit(0);
}
enum class OperationMode
{
DAGInit,
Benchmark,
Farm
};
enum class MinerType
{
CPU,
GPU
};
void doBenchmark(MinerType _m, bool _phoneHome, unsigned _warmupDuration = 15, unsigned _trialDuration = 3, unsigned _trials = 5)
{
BlockInfo genesis = CanonBlockChain::genesis();
genesis.difficulty = 1 << 18;
cdebug << genesis.boundary();
GenericFarm<Ethash> f;
f.onSolutionFound([&](ProofOfWork::Solution) { return false; });
string platformInfo = _m == MinerType::CPU ? ProofOfWork::CPUMiner::platformInfo() : _m == MinerType::GPU ? ProofOfWork::GPUMiner::platformInfo() : "";
cout << "Benchmarking on platform: " << platformInfo << endl;
cout << "Preparing DAG..." << endl;
Ethash::prep(genesis);
genesis.difficulty = u256(1) << 63;
genesis.noteDirty();
f.setWork(genesis);
if (_m == MinerType::CPU)
f.startCPU();
else if (_m == MinerType::GPU)
f.startGPU();
map<uint64_t, MiningProgress> results;
uint64_t mean = 0;
uint64_t innerMean = 0;
for (unsigned i = 0; i <= _trials; ++i)
{
if (!i)
cout << "Warming up..." << endl;
else
cout << "Trial " << i << "... " << flush;
this_thread::sleep_for(chrono::seconds(i ? _trialDuration : _warmupDuration));
auto mp = f.miningProgress();
f.resetMiningProgress();
if (!i)
continue;
auto rate = mp.rate();
cout << rate << endl;
results[rate] = mp;
mean += rate;
if (i > 1 && i < 5)
innerMean += rate;
}
f.stop();
innerMean /= (_trials - 2);
cout << "min/mean/max: " << results.begin()->second.rate() << "/" << (mean / _trials) << "/" << results.rbegin()->second.rate() << " H/s" << endl;
cout << "inner mean: " << innerMean << " H/s" << endl;
(void)_phoneHome;
#if ETH_JSONRPC || !ETH_TRUE
if (_phoneHome)
{
cout << "Phoning home to find world ranking..." << endl;
jsonrpc::HttpClient client("http://gav.ethdev.com:3000/benchmark");
PhoneHome rpc(client);
try
{
unsigned ranking = rpc.report_benchmark(platformInfo, innerMean);
cout << "Ranked: " << ranking << " of all benchmarks." << endl;
}
catch (...)
{
cout << "Error phoning home. ET is sad." << endl;
}
}
#endif
exit(0);
}
struct HappyChannel: public LogChannel { static const char* name() { return ":-D"; } static const int verbosity = 1; };
struct SadChannel: public LogChannel { static const char* name() { return ":-("; } static const int verbosity = 1; };
void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod)
{
(void)_m;
(void)_remote;
(void)_recheckPeriod;
#if ETH_JSONRPC || !ETH_TRUE
jsonrpc::HttpClient client(_remote);
Farm rpc(client);
GenericFarm<Ethash> f;
if (_m == MinerType::CPU)
f.startCPU();
else if (_m == MinerType::GPU)
f.startGPU();
ProofOfWork::WorkPackage current;
while (true)
try
{
bool completed = false;
ProofOfWork::Solution solution;
f.onSolutionFound([&](ProofOfWork::Solution sol)
{
solution = sol;
return completed = true;
});
for (unsigned i = 0; !completed; ++i)
{
if (current)
cnote << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress();
else
cnote << "Getting work package...";
Json::Value v = rpc.eth_getWork();
h256 hh(v[0].asString());
if (hh != current.headerHash)
{
current.headerHash = hh;
current.seedHash = h256(v[1].asString());
current.boundary = h256(fromHex(v[2].asString()), h256::AlignRight);
cnote << "Got work package:" << current.headerHash << " < " << current.boundary;
f.setWork(current);
}
this_thread::sleep_for(chrono::milliseconds(_recheckPeriod));
}
cnote << "Solution found; submitting [" << solution.nonce << "," << current.headerHash << "," << solution.mixHash << "] to" << _remote << "...";
bool ok = rpc.eth_submitWork("0x" + toString(solution.nonce), "0x" + toString(current.headerHash), "0x" + toString(solution.mixHash));
if (ok)
clog(HappyChannel) << "Submitted and accepted.";
else
clog(SadChannel) << "Not accepted.";
current.reset();
}
catch (jsonrpc::JsonRpcException&)
{
for (auto i = 3; --i; this_thread::sleep_for(chrono::seconds(1)))
cerr << "JSON-RPC problem. Probably couldn't connect. Retrying in " << i << "... \r";
cerr << endl;
}
#endif
exit(0);
}
int main(int argc, char** argv)
{
// Init defaults
Defaults::get();
/// Operating mode.
OperationMode mode = OperationMode::Farm;
/// Mining options
MinerType minerType = MinerType::CPU;
unsigned openclPlatform = 0;
unsigned openclDevice = 0;
unsigned miningThreads = UINT_MAX;
/// DAG initialisation param.
unsigned initDAG = 0;
/// Benchmarking params
bool phoneHome = true;
unsigned benchmarkWarmup = 3;
unsigned benchmarkTrial = 3;
unsigned benchmarkTrials = 5;
/// Farm params
string farmURL = "http://127.0.0.1:8080";
unsigned farmRecheckPeriod = 500;
for (int i = 1; i < argc; ++i)
{
string arg = argv[i];
if ((arg == "-F" || arg == "--farm") && i + 1 < argc)
{
mode = OperationMode::Farm;
farmURL = argv[++i];
}
else if (arg == "--farm-recheck" && i + 1 < argc)
try {
farmRecheckPeriod = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--opencl-platform" && i + 1 < argc)
try {
openclPlatform = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--opencl-device" && i + 1 < argc)
try {
openclDevice = stol(argv[++i]);
miningThreads = 1;
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--phone-home" && i + 1 < argc)
{
string m = argv[++i];
if (isTrue(m))
phoneHome = true;
else if (isFalse(m))
phoneHome = false;
else
{
cerr << "Bad " << arg << " option: " << m << endl;
return -1;
}
}
else if (arg == "--benchmark-warmup" && i + 1 < argc)
try {
benchmarkWarmup = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--benchmark-trial" && i + 1 < argc)
try {
benchmarkTrial = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--benchmark-trials" && i + 1 < argc)
try {
benchmarkTrials = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "-C" || arg == "--cpu")
minerType = MinerType::CPU;
else if (arg == "-G" || arg == "--opencl")
minerType = MinerType::GPU;
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc)
{
string m = boost::to_lower_copy(string(argv[++i]));
mode = OperationMode::DAGInit;
try
{
initDAG = stol(m);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << m << endl;
return -1;
}
}
else if ((arg == "-w" || arg == "--check-pow") && i + 4 < argc)
{
string m;
try
{
BlockInfo bi;
m = boost::to_lower_copy(string(argv[++i]));
h256 powHash(m);
m = boost::to_lower_copy(string(argv[++i]));
h256 seedHash;
if (m.size() == 64 || m.size() == 66)
seedHash = h256(m);
else
seedHash = EthashAux::seedHash(stol(m));
m = boost::to_lower_copy(string(argv[++i]));
bi.difficulty = u256(m);
auto boundary = bi.boundary();
m = boost::to_lower_copy(string(argv[++i]));
bi.nonce = h64(m);
auto r = EthashAux::eval(seedHash, powHash, bi.nonce);
bool valid = r.value < boundary;
cout << (valid ? "VALID :-)" : "INVALID :-(") << endl;
cout << r.value << (valid ? " < " : " >= ") << boundary << endl;
cout << " where " << boundary << " = 2^256 / " << bi.difficulty << endl;
cout << " and " << r.value << " = ethash(" << powHash << ", " << bi.nonce << ")" << endl;
cout << " with seed as " << seedHash << endl;
if (valid)
cout << "(mixHash = " << r.mixHash << ")" << endl;
cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light(seedHash)->data()) << endl;
exit(0);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << m << endl;
return -1;
}
}
else if (arg == "-M" || arg == "--benchmark")
mode = OperationMode::Benchmark;
else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc)
{
try {
miningThreads = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
}
else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc)
g_logVerbosity = atoi(argv[++i]);
else if (arg == "-h" || arg == "--help")
help();
else if (arg == "-V" || arg == "--version")
version();
else
{
cerr << "Invalid argument: " << arg << endl;
exit(-1);
}
}
if (minerType == MinerType::CPU)
ProofOfWork::CPUMiner::setNumInstances(miningThreads);
else if (minerType == MinerType::GPU)
{
ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform);
ProofOfWork::GPUMiner::setDefaultDevice(openclDevice);
ProofOfWork::GPUMiner::setNumInstances(miningThreads);
}
if (mode == OperationMode::DAGInit)
doInitDAG(initDAG);
if (mode == OperationMode::Benchmark)
doBenchmark(minerType, phoneHome, benchmarkWarmup, benchmarkTrial, benchmarkTrials);
if (mode == OperationMode::Farm)
doFarm(minerType, farmURL, farmRecheckPeriod);
return 0;
}

3
ethminer/phonehome.json

@ -0,0 +1,3 @@
[
{ "name": "report_benchmark", "params": [ "", 0 ], "order": [], "returns": 0 }
]

2
ethrpctest/CMakeLists.txt

@ -28,7 +28,7 @@ target_link_libraries(${EXECUTABLE} testutils)
target_link_libraries(${EXECUTABLE} web3jsonrpc)
if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW)
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy ${MHD_DLL_RELEASE} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
eth_copy_dlls("${EXECUTABLE}" MHD_DLLS)
endif()
install( TARGETS ${EXECUTABLE} DESTINATION bin )

2
evmjit/libevmjit-cpp/CMakeLists.txt

@ -15,7 +15,7 @@ else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # add PIC for archive
endif()
add_library(${TARGET_NAME} ${SOURCES})
add_library(${TARGET_NAME} STATIC ${SOURCES})
set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "libs")
include_directories(../..)

2
evmjit/libevmjit-cpp/Env.cpp

@ -1,7 +1,7 @@
#pragma GCC diagnostic ignored "-Wconversion"
#include <libdevcrypto/SHA3.h>
#include <libethcore/Params.h>
#include <libevmcore/Params.h>
#include <libevm/ExtVMFace.h>
#include "Utils.h"

10
exp/CMakeLists.txt

@ -3,6 +3,7 @@ set(CMAKE_AUTOMOC OFF)
aux_source_directory(. SRC_LIST)
include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
include_directories(BEFORE ..)
include_directories(${LEVELDB_INCLUDE_DIRS})
@ -23,10 +24,11 @@ endif()
target_link_libraries(${EXECUTABLE} webthree)
target_link_libraries(${EXECUTABLE} ethereum)
target_link_libraries(${EXECUTABLE} p2p)
target_link_libraries(${EXECUTABLE} ethash-cl)
target_link_libraries(${EXECUTABLE} ethash)
target_link_libraries(${EXECUTABLE} OpenCL)
if (ETHASHCL)
target_link_libraries(${EXECUTABLE} ethash-cl)
target_link_libraries(${EXECUTABLE} ethash)
target_link_libraries(${EXECUTABLE} OpenCL)
endif()
install( TARGETS ${EXECUTABLE} DESTINATION bin)

303
exp/main.cpp

@ -19,11 +19,21 @@
* @date 2014
* Ethereum client.
*/
#if ETH_ETHASHCL
#define __CL_ENABLE_EXCEPTIONS
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS
#include "libethash-cl/cl.hpp"
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#include <libethash-cl/cl.hpp>
#pragma clang diagnostic pop
#else
#include <libethash-cl/cl.hpp>
#endif
#endif
#include <functional>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <libdevcore/RangeMask.h>
#include <libdevcore/Log.h>
#include <libdevcore/Common.h>
@ -33,11 +43,13 @@
#include <libdevcore/CommonIO.h>
#include <libdevcrypto/TrieDB.h>
#include <libp2p/All.h>
#include <libethcore/Ethasher.h>
#include <libethcore/ProofOfWork.h>
#include <libdevcrypto/FileSystem.h>
#include <libethereum/All.h>
#include <libethereum/Farm.h>
#include <libethereum/AccountDiff.h>
#include <libethereum/DownloadMan.h>
#include <libethereum/Client.h>
#include <liblll/All.h>
#include <libwhisper/WhisperPeer.h>
#include <libwhisper/WhisperHost.h>
@ -48,8 +60,142 @@ using namespace dev::eth;
using namespace dev::p2p;
using namespace dev::shh;
namespace js = json_spirit;
namespace fs = boost::filesystem;
#if 1
inline h128 fromUUID(std::string const& _uuid) { return h128(boost::replace_all_copy(_uuid, "-", "")); }
class KeyManager: public Worker
{
public:
KeyManager() { readKeys(); }
~KeyManager() {}
Secret secret(h128 const& _uuid, function<std::string()> const& _pass)
{
auto rit = m_ready.find(_uuid);
if (rit != m_ready.end())
return rit->second;
auto it = m_keys.find(_uuid);
if (it == m_keys.end())
return Secret();
Secret ret(decrypt(it->second, _pass()));
if (ret)
m_ready[_uuid] = ret;
return ret;
}
h128 create(std::string const& _pass)
{
auto s = Secret::random();
h128 r(sha3(s));
m_ready[r] = s;
m_keys[r] = encrypt(s.asBytes(), _pass);
return r;
}
private:
void writeKeys(std::string const& _keysPath = getDataDir("web3") + "/keys")
{
(void)_keysPath;
}
void readKeys(std::string const& _keysPath = getDataDir("web3") + "/keys")
{
fs::path p(_keysPath);
js::mValue v;
for (fs::directory_iterator it(p); it != fs::directory_iterator(); ++it)
if (is_regular_file(it->path()))
{
cdebug << "Reading" << it->path();
js::read_string(contentsString(it->path().string()), v);
if (v.type() == js::obj_type)
{
js::mObject o = v.get_obj();
int version = o.count("Version") ? stoi(o["Version"].get_str()) : o.count("version") ? o["version"].get_int() : 0;
if (version == 2)
m_keys[fromUUID(o["id"].get_str())] = o["crypto"];
else
cwarn << "Cannot read key version" << version;
}
else
cwarn << "Invalid JSON in key file" << it->path().string();
}
}
static js::mValue encrypt(bytes const& _v, std::string const& _pass)
{
(void)_v;
(void)_pass;
return js::mValue();
}
#if 0
static bytes decrypt(js::mValue const& _v, std::string const& _pass)
{
js::mObject o = _v.get_obj();
// derive key
bytes derivedKey;
if (o["kdf"].get_str() == "pbkdf2")
{
auto params = o["kdfparams"].get_obj();
if (params["prf"].get_str() != "hmac-sha256")
{
cwarn << "Unknown PRF for PBKDF2" << params["prf"].get_str() << "not supported.";
return bytes();
}
unsigned iterations = params["c"].get_int();
bytes salt = fromHex(params["salt"].get_str());
derivedKey = pbkdf2(_pass, salt, iterations, params["dklen"].get_int());
}
else
{
cwarn << "Unknown KDF" << o["kdf"].get_str() << "not supported.";
return bytes();
}
bytes cipherText = fromHex(o["ciphertext"].get_str());
// check MAC
h256 mac(o["mac"].get_str());
h256 macExp = sha3(bytesConstRef(&derivedKey).cropped(derivedKey.size() - 16).toBytes() + cipherText);
if (mac != macExp)
{
cwarn << "Invalid key - MAC mismatch; expected" << toString(macExp) << ", got" << toString(mac);
return bytes();
}
// decrypt
bytes ret;
if (o["cipher"].get_str() == "aes-128-cbc")
{
auto params = o["cipherparams"].get_obj();
h128 key(sha3(h128(derivedKey, h128::AlignRight)), h128::AlignRight);
h128 iv(params["iv"].get_str());
decryptSymNoAuth(key, iv, &cipherText, ret);
}
else
{
cwarn << "Unknown cipher" << o["cipher"].get_str() << "not supported.";
return bytes();
}
return ret;
}
mutable std::map<h128, Secret> m_ready;
std::map<h128, js::mValue> m_keys;
};
int main()
{
cdebug << toHex(pbkdf2("password", asBytes("salt"), 1, 20));
KeyManager keyman;
cdebug << "Secret key for 0498f19a-59db-4d54-ac95-33901b4f1870 is " << keyman.secret(fromUUID("0498f19a-59db-4d54-ac95-33901b4f1870"), [](){ return "foo"; });
}
#elif 0
int main()
{
DownloadMan man;
@ -105,25 +251,144 @@ int main()
cnote << "State after transaction: " << s;
cnote << before.diff(s);
}
#else
#elif 0
int main()
{
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
if (platforms.empty())
GenericFarm<Ethash> f;
BlockInfo genesis = CanonBlockChain::genesis();
genesis.difficulty = 1 << 18;
cdebug << genesis.boundary();
auto mine = [](GenericFarm<Ethash>& f, BlockInfo const& g, unsigned timeout) {
BlockInfo bi = g;
bool completed = false;
f.onSolutionFound([&](ProofOfWork::Solution sol)
{
ProofOfWork::assignResult(sol, bi);
return completed = true;
});
f.setWork(bi);
for (unsigned i = 0; !completed && i < timeout * 10; ++i, cout << f.miningProgress() << "\r" << flush)
this_thread::sleep_for(chrono::milliseconds(100));
cout << endl << flush;
cdebug << bi.mixHash << bi.nonce << (Ethash::verify(bi) ? "GOOD" : "bad");
};
Ethash::prep(genesis);
genesis.difficulty = u256(1) << 40;
genesis.noteDirty();
f.startCPU();
mine(f, genesis, 10);
f.startGPU();
cdebug << "Good:";
genesis.difficulty = 1 << 18;
genesis.noteDirty();
mine(f, genesis, 30);
cdebug << "Bad:";
genesis.difficulty = (u256(1) << 40);
genesis.noteDirty();
mine(f, genesis, 30);
f.stop();
return 0;
}
#elif 0
void mine(State& s, BlockChain const& _bc)
{
s.commitToMine(_bc);
GenericFarm<ProofOfWork> f;
bool completed = false;
f.onSolutionFound([&](ProofOfWork::Solution sol)
{
cdebug << "No OpenCL platforms found.";
return false;
}
return completed = s.completeMine<ProofOfWork>(sol);
});
f.setWork(s.info());
f.startCPU();
while (!completed)
this_thread::sleep_for(chrono::milliseconds(20));
}
#elif 0
int main()
{
cnote << "Testing State...";
KeyPair me = sha3("Gav Wood");
KeyPair myMiner = sha3("Gav's Miner");
// KeyPair you = sha3("123");
Defaults::setDBPath(boost::filesystem::temp_directory_path().string() + "/" + toString(chrono::system_clock::now().time_since_epoch().count()));
OverlayDB stateDB = State::openDB();
CanonBlockChain bc;
cout << bc;
State s(stateDB, BaseState::CanonGenesis, myMiner.address());
cout << s;
// Sync up - this won't do much until we use the last state.
s.sync(bc);
cout << s;
// Mine to get some ether!
mine(s, bc);
bc.attemptImport(s.blockData(), stateDB);
cout << bc;
s.sync(bc);
cout << s;
// Inject a transaction to transfer funds from miner to me.
Transaction t(1000, 10000, 30000, me.address(), bytes(), s.transactionsFrom(myMiner.address()), myMiner.secret());
assert(t.sender() == myMiner.address());
s.execute(bc.lastHashes(), t);
cout << s;
// Mine to get some ether and set in stone.
s.commitToMine(bc);
s.commitToMine(bc);
mine(s, bc);
bc.attemptImport(s.blockData(), stateDB);
cout << bc;
s.sync(bc);
cout << s;
return 0;
}
#else
int main()
{
string tempDir = boost::filesystem::temp_directory_path().string() + "/" + toString(chrono::system_clock::now().time_since_epoch().count());
KeyPair myMiner = sha3("Gav's Miner");
p2p::Host net("Test");
cdebug << "Path:" << tempDir;
Client c(&net, tempDir);
c.setAddress(myMiner.address());
this_thread::sleep_for(chrono::milliseconds(1000));
c.startMining();
this_thread::sleep_for(chrono::milliseconds(6000));
c.stopMining();
EthashCL ecl;
BlockInfo genesis = CanonBlockChain::genesis();
TransientDirectory td;
std::pair<MineInfo, Ethash::Proof> r;
while (!r.first.completed)
r = ecl.mine(genesis, 1000);
EthashCL::assignResult(r.second, genesis);
assert(EthashCPU::verify(genesis));
return 0;
}
#endif

59
extdep/CMakeLists.txt

@ -1,59 +0,0 @@
cmake_minimum_required(VERSION 2.8.12)
include(ExternalProject)
include(CMakeParseArguments)
include(eth_download.cmake)
# all dependencies will be installed into this directory, separated by platform
string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name)
set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}")
set(ETH_DEPENDENCY_SERVER "https://build.ethdev.com/builds/${_system_name}-precompiled")
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/bin)
if (ETH_COMPILE)
# json-rpc-cpp and its dependencies
include(compile/jsoncpp.cmake)
include(compile/argtable2.cmake)
include(compile/curl.cmake)
include(compile/json-rpc-cpp.cmake)
# qt and its dependencies
include(compile/icu.cmake)
include(compile/jom.cmake)
include(compile/qt.cmake)
# leveldb and its dependencies
include(compile/snappy.cmake)
include(compile/leveldb.cmake)
# cryptopp
include(compile/cryptopp.cmake)
# boost
include(compile/boost.cmake)
else()
eth_download(jsoncpp)
eth_download(microhttpd)
eth_download(json-rpc-cpp
VERSION 4.2
OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh
)
if (APPLE)
eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh)
endif()
eth_download(leveldb OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/leveldb_osx.sh)
eth_download(qt VERSION 5.4)
eth_download(cryptopp)
eth_download(boost)
eth_download(curl)
endif()
# will be re-eanbled later
# include(miniupnpc.cmake)
# if install phase of extep fails, even if libs are already created, the ethereum install will fail

16
extdep/Readme.md

@ -1,16 +0,0 @@
# cpp-ethereum external dependencies
**This is Work-in-Progress!**
This directory hosts the external libraries that are needed to build cpp-ethereum.
To automatically download, build, and link libraries, do
```
cd extdep; mkdir build; cd build; cmake ..; make
```
this will take some time.
To check which libraries are already included, check `CMakeLists.txt`. Other libraries still need to be fetched via the system's package manager.
Libraries will be installed in `cpp-ethereum/extdep/install/<platform-name>`

9
extdep/cmake/FindCURL.cmake

@ -1,9 +0,0 @@
# hacky way to resolve nested dependencies - needed for json-rpc-cpp
find_library(CURL_LIBRARY NAMES curl
PATHS
${ETH_DEPENDENCY_INSTALL_DIR}/lib
)
set(CURL_LIBRARIES ${CURL_LIBRARY})
set(CURL_INCLUDE_DIRS ${ETH_DEPENDENCY_INSTALL_DIR}/include)

13
extdep/compile/argtable2.cmake

@ -1,13 +0,0 @@
if (APPLE)
elseif (WIN32)
ExternalProject_Add(argtable2
GIT_REPOSITORY https://github.com/debris/argtable.git
GIT_TAG master
BINARY_DIR argtable2-prefix/src/argtable2
CONFIGURE_COMMAND cmake .
BUILD_COMMAND devenv argtable2.sln /build release
INSTALL_COMMAND cmd /c cp src/Release/argtable2.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp src/argtable2.h ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
endif()

19
extdep/compile/boost.cmake

@ -1,19 +0,0 @@
if (APPLE)
elseif (WIN32)
set(boost_address_model)
# on windows 64:
# set(boost_address_model address-model=64)
set(boost_targets --with-filesystem --with-system --with-thread --with-date_time --with-regex --with-test --with-chrono --with-program_options)
ExternalProject_Add(boost
URL http://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.gz
BINARY_DIR boost-prefix/src/boost
CONFIGURE_COMMAND ./bootstrap.bat
BUILD_COMMAND ./b2.exe -j4 --build-type=complete link=static runtime-link=shared variant=debug,release threading=multi ${boost_addressModel} ${boost_targets} install --prefix=${ETH_DEPENDENCY_INSTALL_DIR}
INSTALL_COMMAND cmake -E rename ${ETH_DEPENDENCY_INSTALL_DIR}/include/boost-1_55/boost ${ETH_DEPENDENCY_INSTALL_DIR}/include/boost
)
else()
endif()

33
extdep/compile/cryptopp.cmake

@ -1,33 +0,0 @@
# CryptoPP does not have good cross-platform support, there exist several different other projects to make it work ...
# TODO the OS X build throws a lot of warnings, but compiles fine
if (APPLE)
ExternalProject_Add(cryptopp
URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip
BINARY_DIR cryptopp-prefix/src/cryptopp
CONFIGURE_COMMAND ""
BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM
INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR}
)
elseif (WIN32)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp)
ExternalProject_Add(cryptopp
SVN_REPOSITORY http://svn.code.sf.net/p/cryptopp/code/trunk/c5
SVN_REVISION -r "541"
BINARY_DIR cryptopp-prefix/src/cryptopp
CONFIGURE_COMMAND devenv cryptest.sln /upgrade
BUILD_COMMAND devenv cryptest.sln /build release
INSTALL_COMMAND cmd /c cp Win32/DLL_Output/Release/cryptopp.dll ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp Win32/DLL_Output/Release/cryptopp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp *.h ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp
)
# on Linux, the default Makefile does not work.
else()
ExternalProject_Add(cryptopp
URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip
BINARY_DIR cryptopp-prefix/src/cryptopp
CONFIGURE_COMMAND ""
BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR}
INSTALL_COMMAND ""
)
endif()

29
extdep/compile/curl.cmake

@ -1,29 +0,0 @@
if (APPLE)
ExternalProject_Add(curl
URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2
BINARY_DIR curl-prefix/src/curl
CONFIGURE_COMMAND ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install
)
elseif (WIN32)
ExternalProject_Add(curl
GIT_REPOSITORY https://github.com/debris/libcurl-7.29
GIT_TAG master
BINARY_DIR curl-prefix/src/curl
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmd /c cp lib/release/libcurl.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/curl ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
ExternalProject_Add(curl
URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2
BINARY_DIR curl-prefix/src/curl
CONFIGURE_COMMAND CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install
)
endif()

17
extdep/compile/icu.cmake

@ -1,17 +0,0 @@
if (APPLE)
elseif (WIN32)
ExternalProject_Add(icu
GIT_REPOSITORY https://github.com/debris/icu-win32.git
GIT_TAG master
BINARY_DIR icu-prefix/src/icu
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR}
)
else()
endif()

16
extdep/compile/jom.cmake

@ -1,16 +0,0 @@
if (APPLE)
elseif (WIN32)
ExternalProject_Add(jom
URL http://download.qt-project.org/official_releases/jom/jom.zip
BINARY_DIR jom-prefix/src/jom
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmake -E copy jom.exe ${ETH_DEPENDENCY_INSTALL_DIR}/bin
)
else()
endif()

40
extdep/compile/json-rpc-cpp.cmake

@ -1,40 +0,0 @@
# json-rpc-cpp is under heavy development, not yet stable, and multiplatform builds are not yet available.
# DO NOT MESS WITH THESE SETTINGS! IF YOU HAVE TO MAKE CHANGES HERE, CONSULT sven@ethdev.com BEFOREHAND!!
# DO NOT CHANGE ANYTHING HERE!
if(APPLE)
ExternalProject_Add(json-rpc-cpp
# DEPENDS argtable2 jsoncpp
# DEPENDS curl # re-enable later, when we build curl again
GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git
GIT_TAG v0.3.2
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp
CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev .
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install && ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh . ${ETH_DEPENDENCY_INSTALL_DIR}
)
elseif (WIN32)
ExternalProject_Add(json-rpc-cpp
DEPENDS argtable2 jsoncpp curl
GIT_REPOSITORY https://github.com/debris/libjson-rpc-cpp.git
GIT_TAG windows
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp
CONFIGURE_COMMAND cmake -DCMAKE_PREFIX_PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCURL_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libcurl.lib .
BUILD_COMMAND devenv libjson-rpc-cpp.sln /build release
INSTALL_COMMAND cmd /c cp lib/Release/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R src/jsonrpccpp ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
ExternalProject_Add(json-rpc-cpp
# DEPENDS argtable2 jsoncpp
# DEPENDS curl # re-enable later, when we build curl again
GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git
GIT_TAG v0.3.2
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp
CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST .
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install
)
endif()

16
extdep/compile/jsoncpp.cmake

@ -1,16 +0,0 @@
if (APPLE)
elseif (WIN32)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp)
ExternalProject_Add(jsoncpp
GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp
GIT_TAG svn-import
BINARY_DIR jsoncpp-prefix/src/jsoncpp
CONFIGURE_COMMAND cmake .
BUILD_COMMAND devenv jsoncpp.sln /build release
INSTALL_COMMAND cmd /c cp lib/Release/jsoncpp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/json ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp
)
else()
endif()

23
extdep/compile/leveldb.cmake

@ -1,23 +0,0 @@
if (APPLE)
ExternalProject_Add(leveldb
#DEPENDS snappy
URL https://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz
BINARY_DIR leveldb-prefix/src/leveldb
#CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/compile/leveldb_osx.patch
CONFIGURE_COMMAND ""
BUILD_COMMAND export ETH_DEPENDENCY_INSTALL_DIR=${ETH_DEPENDENCY_INSTALL_DIR} && make -j 3
INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && cp libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib
)
elseif (WIN32)
ExternalProject_Add(leveldb
GIT_REPOSITORY https://github.com/debris/leveldb-win32.git
GIT_TAG master
BINARY_DIR leveldb-prefix/src/leveldb
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmd /c cp lib/LibLevelDB.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib/leveldb.lib && cp -R include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
endif()

18
extdep/compile/leveldb_osx.patch

@ -1,18 +0,0 @@
--- Makefile 2014-11-07 00:54:05.000000000 +0100
+++ MakefilePatch 2014-11-07 00:56:59.000000000 +0100
@@ -17,11 +17,11 @@
# this file is generated by the previous line to set build flags and sources
include build_config.mk
-CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
-CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT)
+CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
+CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -DSNAPPY -I$(ETH_DEPENDENCY_INSTALL_DIR)/include
-LDFLAGS += $(PLATFORM_LDFLAGS)
-LIBS += $(PLATFORM_LIBS)
+LDFLAGS += $(PLATFORM_LDFLAGS) -L$(ETH_DEPENDENCY_INSTALL_DIR)/lib
+LIBS += $(PLATFORM_LIBS) -lsnappy
LIBOBJECTS = $(SOURCES:.cc=.o)
MEMENVOBJECTS = $(MEMENV_SOURCES:.cc=.o)

32
extdep/compile/qt.cmake

@ -1,32 +0,0 @@
if (APPLE)
ExternalProject_add(qt
URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz
BINARY_DIR qt-prefix/src/qt
PATCH_COMMAND patch -d qtmultimedia/src/plugins/avfoundation/mediaplayer < ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_osx.patch
CONFIGURE_COMMAND ./configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -system-zlib -qt-libpng -qt-libjpeg -confirm-license -opensource -nomake tests -release -nomake examples -no-xcb -arch x86_64
BUILD_COMMAND make
INSTALL_COMMAND make install
)
elseif(WIN32)
ExternalProject_Add(qt
DEPENDS icu jom
URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz
BINARY_DIR qt-prefix/src/qt
UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_tools.bat
#PATCH_COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_configure.bat qtbase/configure.bat
CONFIGURE_COMMAND configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -opensource -confirm-license -release -opengl desktop -platform win32-msvc2013 -icu -I ${ETH_DEPENDENCY_INSTALL_DIR}/include -L ${ETH_DEPENDENCY_INSTALL_DIR}/lib -nomake tests -nomake examples
BUILD_COMMAND nmake
INSTALL_COMMAND nmake install
)
ExternalProject_Add_Step(qt configure_paths
COMMAND set PATH=${ETH_DEPENDENCY_INSTALL_DIR}/bin;%cd%/gnuwin32/bin;%cd%/qtbase/bin;%PATH%
DEPENDEES patch
DEPENDERS configure
)
else()
endif()

111
extdep/compile/qt_configure.bat

@ -1,111 +0,0 @@
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
:: Contact: http://www.qt-project.org/legal
::
:: This file is part of the tools applications of the Qt Toolkit.
::
:: $QT_BEGIN_LICENSE:LGPL$
:: Commercial License Usage
:: Licensees holding valid commercial Qt licenses may use this file in
:: accordance with the commercial license agreement provided with the
:: Software or, alternatively, in accordance with the terms contained in
:: a written agreement between you and Digia. For licensing terms and
:: conditions see http://qt.digia.com/licensing. For further information
:: use the contact form at http://qt.digia.com/contact-us.
::
:: GNU Lesser General Public License Usage
:: Alternatively, this file may be used under the terms of the GNU Lesser
:: General Public License version 2.1 as published by the Free Software
:: Foundation and appearing in the file LICENSE.LGPL included in the
:: packaging of this file. Please review the following information to
:: ensure the GNU Lesser General Public License version 2.1 requirements
:: will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
::
:: In addition, as a special exception, Digia gives you certain additional
:: rights. These rights are described in the Digia Qt LGPL Exception
:: version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
::
:: GNU General Public License Usage
:: Alternatively, this file may be used under the terms of the GNU
:: General Public License version 3.0 as published by the Free Software
:: Foundation and appearing in the file LICENSE.GPL included in the
:: packaging of this file. Please review the following information to
:: ensure the GNU General Public License version 3.0 requirements will be
:: met: http://www.gnu.org/copyleft/gpl.html.
::
::
:: $QT_END_LICENSE$
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
set QTSRC=%~dp0
set QTDIR=%CD%
::if not exist %QTSRC%\.gitignore goto sconf
echo Please wait while bootstrapping configure ...
for %%C in (cl.exe icl.exe g++.exe perl.exe) do set %%C=%%~$PATH:C
if "%perl.exe%" == "" (
echo Perl not found in PATH. Aborting. >&2
exit /b 1
)
if not exist mkspecs (
md mkspecs
if errorlevel 1 goto exit
)
perl %QTSRC%bin\syncqt.pl -minimal -module QtCore -outdir %QTDIR% %QTSRC%
if errorlevel 1 goto exit
if not exist tools\configure (
md tools\configure
if errorlevel 1 goto exit
)
cd tools\configure
if errorlevel 1 goto exit
echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile
echo/>> Makefile
for /f "tokens=3 usebackq" %%V in (`findstr QT_VERSION_STR %QTSRC%\src\corelib\global\qglobal.h`) do @echo QTVERSION = %%~V>> Makefile
if not "%cl.exe%" == "" (
echo CXX = cl>>Makefile
echo EXTRA_CXXFLAGS =>>Makefile
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
set make=nmake
) else if not "%icl.exe%" == "" (
echo CXX = icl>>Makefile
echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
set make=nmake
) else if not "%g++.exe%" == "" (
echo CXX = g++>>Makefile
echo EXTRA_CXXFLAGS =>>Makefile
rem This must NOT have a trailing space.
echo QTSRC = %QTSRC:\=/%>> Makefile
set tmpl=mingw
set make=mingw32-make
) else (
echo No suitable compiler found in PATH. Aborting. >&2
cd ..\..
exit /b 1
)
echo/>> Makefile
type %QTSRC%tools\configure\Makefile.%tmpl% >> Makefile
%make%
if errorlevel 1 (cd ..\.. & exit /b 1)
cd ..\..
:conf
configure.exe -srcdir %QTSRC% %*
goto exit
:sconf
%QTSRC%\configure.exe %*
:exit

11
extdep/compile/qt_osx.patch

@ -1,11 +0,0 @@
--- avfmediaplayersession.mm 2014-09-11 12:48:26.000000000 +0200
+++ avfmediaplayersessionPatch.mm 2014-12-01 12:53:14.000000000 +0100
@@ -295,7 +295,7 @@
//AVPlayerItem "status" property value observer.
if (context == AVFMediaPlayerSessionObserverStatusObservationContext)
{
- AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
+ AVPlayerStatus status = (AVPlayerStatus)[[change objectForKey:NSKeyValueChangeNewKey] integerValue];
switch (status)
{
//Indicates that the status of the player is not yet known because

2
extdep/compile/qt_tools.bat

@ -1,2 +0,0 @@
rem : import VC environment vars
call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86

14
extdep/compile/snappy.cmake

@ -1,14 +0,0 @@
if (APPLE)
ExternalProject_Add(snappy
URL https://snappy.googlecode.com/files/snappy-1.1.1.tar.gz
BINARY_DIR snappy-prefix/src/snappy
CONFIGURE_COMMAND ./configure --disable-dependency-tracking --prefix=${ETH_DEPENDENCY_INSTALL_DIR}
BUILD_COMMAND ""
INSTALL_COMMAND make install
)
elseif(WIN32)
else()
endif()

74
extdep/eth_download.cmake

@ -1,74 +0,0 @@
# this macro requires the following variables to be specified:
#
# ETH_DEPENDENCY_SERVER - server from which dependencies should be downloaded
# ETH_DEPENDENCY_INSTALL_DIR - install location for all dependencies
#
# usage:
#
# eth_download("json-rpc-cpp")
# eth_download("json-rpc-cpp" VERSION "0.3.2")
#
# params:
# VERSION - exact version we want to use
# OSX_SCRIPT - script which will be executed on apple in install phase
# UNIX_SCRIPT - script which will be executed on unix in install phase
# WIN_SCRIPT - script which will be executed on win in install phase
# OSX_SCRIPT, WIN_SCRIPT, UNIX_SCRIPT are taking 2 params:
# $1 is package_source,
# $2 is ETH_DEPENDENCY_INSTALL_DIR
#
# parsing arguments
# http://www.cmake.org/cmake/help/v3.0/module/CMakeParseArguments.html
#
# for macos you may need to specify OSX_SCRIPT with install_name_tool to fix dylib
# http://stackoverflow.com/questions/2985315/using-install-name-tool-whats-going-wrong
#
# TODO:
# check if install_command is handling symlinks correctly on linux and windows
macro(eth_download eth_package_name)
set (extra_macro_args ${ARGN})
set (options)
set (one_value_args VERSION OSX_SCRIPT UNIX_SCRIPT WIN_SCRIPT)
set (multi_value_args)
cmake_parse_arguments (ETH_DOWNLOAD "${options}" "${one_value_args}" "${multi_value_args}" ${extra_macro_args})
if (ETH_DOWNLOAD_VERSION)
set(eth_tar_name "${eth_package_name}-${ETH_DOWNLOAD_VERSION}.tar.gz")
else()
set(eth_tar_name "${eth_package_name}.tar.gz")
endif()
message(STATUS "download path for ${eth_package_name} is : ${ETH_DEPENDENCY_SERVER}/${eth_tar_name}")
# we need that to copy symlinks
# see http://superuser.com/questions/138587/how-to-copy-symbolic-links
if (APPLE)
set (eth_package_copy cp -a . ${ETH_DEPENDENCY_INSTALL_DIR})
set (eth_package_install ${ETH_DOWNLOAD_OSX_SCRIPT})
elseif (UNIX)
set (eth_package_copy cp -a . ${ETH_DEPENDENCY_INSTALL_DIR})
set (eth_package_install ${ETH_DOWNLOAD_UNIX_SCRIPT})
else ()
set (eth_package_copy cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR})
set (eth_package_install ${ETH_DOWNLOAD_WIN_SCRIPT})
endif()
if (eth_package_install)
message(STATUS "install script: ${eth_package_install}")
set (eth_package_install ${eth_package_install} . ${ETH_DEPENDENCY_INSTALL_DIR})
else ()
set (eth_package_install echo 0) # cause empty string is not handled properly
endif()
ExternalProject_Add(${eth_package_name}
URL ${ETH_DEPENDENCY_SERVER}/${eth_tar_name}
BINARY_DIR ${eth_package_name}-prefix/src/${eth_package_name}
CONFIGURE_COMMAND ""
BUILD_COMMAND ${eth_package_copy}
INSTALL_COMMAND ${eth_package_install}
)
endmacro()

38
extdep/getstuff.bat

@ -0,0 +1,38 @@
REM get stuff!
if not exist download mkdir download
if not exist install mkdir install
if not exist install\windows mkdir install\windows
set eth_server=https://build.ethdev.com/builds/windows-precompiled
call :download boost 1.55.0
call :download cryptopp 5.6.2
call :download curl 7.4.2
call :download jsoncpp 1.6.2
call :download json-rpc-cpp 0.5.0
call :download leveldb 1.2
call :download microhttpd 0.9.2
call :download qt 5.4.1
goto :EOF
:download
set eth_name=%1
set eth_version=%2
cd download
if not exist %eth_name%-%eth_version%.tar.gz (
for /f "tokens=2 delims={}" %%g in ('bitsadmin /create %eth_name%-%eth_version%.tar.gz') do (
bitsadmin /transfer {%%g} /download /priority normal %eth_server%/%eth_name%-%eth_version%.tar.gz %cd%\%eth_name%-%eth_version%.tar.gz
bitsadmin /cancel {%%g}
)
)
if not exist %eth_name%-%eth_version% cmake -E tar -zxvf %eth_name%-%eth_version%.tar.gz
cmake -E copy_directory %eth_name%-%eth_version% ..\install\windows
cd ..
goto :EOF

11
extdep/miniupnpc.cmake

@ -1,11 +0,0 @@
# TODO this file is not used yet, but will be in future
include(ExternalProject)
ExternalProject_Add(miniupnpc
URL http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.9.20141027.tar.gz
BINARY_DIR miniupnpc-prefix/src/miniupnpc
CONFIGURE_COMMAND ""
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install INSTALLPREFIX=${ETH_DEPENDENCY_INSTALL_DIR}
)

29
extdep/scripts/json-rpc-cpp_osx.sh

@ -1,29 +0,0 @@
#!/bin/bash
ETH_DEPENDENCY_SOURCE_DIR=$1
ETH_DEPENDENCY_INSTALL_DIR=$2
OLD_COMMON_DYLIB="libjsonrpccpp-common.0.dylib"
COMMON_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-common.0.dylib
SERVER_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-server.0.dylib
CLIENT_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-client.0.dylib
# fix bin
STAB_EXEC=${ETH_DEPENDENCY_INSTALL_DIR}/bin/jsonrpcstub
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${STAB_EXEC}
# fix common
install_name_tool -id ${COMMON_DYLIB} ${COMMON_DYLIB}
# fix server
install_name_tool -id ${SERVER_DYLIB} ${SERVER_DYLIB}
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${SERVER_DYLIB}
# fix client
install_name_tool -id ${CLIENT_DYLIB} ${CLIENT_DYLIB}
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${CLIENT_DYLIB}
# TODO fix argtable and jsoncpp once they are downloaded as dependencies

12
extdep/scripts/leveldb_osx.sh

@ -1,12 +0,0 @@
#!/bin/bash
ETH_DEPENDENCY_SOURCE_DIR=$1
ETH_DEPENDENCY_INSTALL_DIR=$2
OLD_SNAPPY_DYLIB="/Users/marekkotewicz/ethereum/cpp-ethereum/extdep/install/darwin/lib/libsnappy.1.dylib"
SNAPPY_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libsnappy.dylib
LEVELDB_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib
install_name_tool -id ${LEVELDB_DYLIB} ${LEVELDB_DYLIB}
install_name_tool -change ${OLD_SNAPPY_DYLIB} ${SNAPPY_DYLIB} ${LEVELDB_DYLIB}

8
extdep/scripts/snappy_osx.sh

@ -1,8 +0,0 @@
#!/bin/bash
ETH_DEPENDENCY_SOURCE_DIR=$1
ETH_DEPENDENCY_INSTALL_DIR=$2
SNAPPY_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libsnappy.dylib
install_name_tool -id ${SNAPPY_DYLIB} ${SNAPPY_DYLIB}

21
libdevcore/Base64.h

@ -30,7 +30,8 @@
#include <vector>
#include <string>
#include <libdevcore/Common.h>
#include "Common.h"
#include "FixedHash.h"
namespace dev
{
@ -38,4 +39,22 @@ namespace dev
std::string toBase64(bytesConstRef _in);
bytes fromBase64(std::string const& _in);
template <size_t N> inline std::string toBase36(FixedHash<N> const& _h)
{
static char const* c_alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
typename FixedHash<N>::Arith a = _h;
std::string ret;
for (; a > 0; a /= 36)
ret = c_alphabet[(unsigned)a % 36] + ret;
return ret;
}
template <size_t N> inline FixedHash<N> fromBase36(std::string const& _h)
{
typename FixedHash<N>::Arith ret = 0;
for (char c: _h)
ret = ret * 36 + (c < 'A' ? c - '0' : (c - 'A' + 10));
return ret;
}
}

6
libdevcore/CMakeLists.txt

@ -20,11 +20,7 @@ set(EXECUTABLE devcore)
file(GLOB HEADERS "*.h")
if(ETH_STATIC)
add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
else()
add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
endif()
add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARIES})

26
libdevcore/Common.cpp

@ -20,14 +20,36 @@
*/
#include "Common.h"
#include "Exceptions.h"
#include "Log.h"
using namespace std;
using namespace dev;
namespace dev
{
char const* Version = "0.9.6";
char const* Version = "0.9.15o";
void HasInvariants::checkInvariants() const
{
if (!invariants())
BOOST_THROW_EXCEPTION(FailedInvariant());
}
struct TimerChannel: public LogChannel { static const char* name(); static const int verbosity = 0; };
#ifdef _WIN32
const char* TimerChannel::name() { return EthRed " ! "; }
#else
const char* TimerChannel::name() { return EthRed ""; }
#endif
TimerHelper::~TimerHelper()
{
auto e = m_t.elapsed();
if (!m_ms || e * 1000 > m_ms)
clog(TimerChannel) << m_id << e << "s";
}
}

69
libdevcore/Common.h

@ -37,6 +37,7 @@
#include <vector>
#include <set>
#include <functional>
#include <boost/timer.hpp>
#pragma warning(push)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
@ -52,6 +53,8 @@ using byte = uint8_t;
#define DEV_QUOTED_HELPER(s) #s
#define DEV_QUOTED(s) DEV_QUOTED_HELPER(s)
#define DEV_IGNORE_EXCEPTIONS(X) try { X; } catch (...) {}
namespace dev
{
@ -126,14 +129,75 @@ inline N diff(N const& _a, N const& _b)
}
/// RAII utility class whose destructor calls a given function.
class ScopeGuard {
class ScopeGuard
{
public:
ScopeGuard(std::function<void(void)> _f): m_f(_f) {}
~ScopeGuard() { m_f(); }
private:
std::function<void(void)> m_f;
};
/// Inheritable for classes that have invariants.
class HasInvariants
{
public:
/// Check invariants are met, throw if not.
void checkInvariants() const;
protected:
/// Reimplement to specify the invariants.
virtual bool invariants() const = 0;
};
/// RAII checker for invariant assertions.
class InvariantChecker
{
public:
InvariantChecker(HasInvariants* _this): m_this(_this) { m_this->checkInvariants(); }
~InvariantChecker() { m_this->checkInvariants(); }
private:
HasInvariants const* m_this;
};
/// Scope guard for invariant check in a class derived from HasInvariants.
#if ETH_DEBUG
#define DEV_INVARIANT_CHECK ::dev::InvariantChecker __dev_invariantCheck(this)
#else
#define DEV_INVARIANT_CHECK (void)0;
#endif
/// Simple scope-based timer helper.
class TimerHelper
{
public:
TimerHelper(char const* _id, unsigned _msReportWhenGreater = 0): m_id(_id), m_ms(_msReportWhenGreater) {}
~TimerHelper();
private:
boost::timer m_t;
char const* m_id;
unsigned m_ms;
};
#define DEV_TIMED(S) for (::std::pair<::dev::TimerHelper, bool> __eth_t(#S, true); __eth_t.second; __eth_t.second = false)
#define DEV_TIMED_SCOPE(S) ::dev::TimerHelper __eth_t(S)
#if WIN32
#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__FUNCSIG__)
#else
#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__PRETTY_FUNCTION__)
#endif
#define DEV_TIMED_IF(S, MS) for (::std::pair<::dev::TimerHelper, bool> __eth_t(::dev::TimerHelper(#S, MS), true); __eth_t.second; __eth_t.second = false)
#define DEV_TIMED_SCOPE_IF(S) ::dev::TimerHelper __eth_t(S, MS)
#if WIN32
#define DEV_TIMED_FUNCTION_IF(MS) DEV_TIMED_SCOPE_IF(__FUNCSIG__, MS)
#else
#define DEV_TIMED_FUNCTION_IF(MS) DEV_TIMED_SCOPE_IF(__PRETTY_FUNCTION__, MS)
#endif
enum class WithExisting: int
{
Trust = 0,
@ -143,7 +207,8 @@ enum class WithExisting: int
}
namespace std {
namespace std
{
inline dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b)
{

32
libdevcore/CommonData.h

@ -41,17 +41,22 @@ enum class WhenError
Throw = 1,
};
enum class HexPrefix
{
DontAdd = 0,
Add = 1,
};
/// Convert a series of bytes to the corresponding string of hex duplets.
/// @param _w specifies the width of the first of the elements. Defaults to two - enough to represent a byte.
/// @example toHex("A\x69") == "4169"
template <class _T>
std::string toHex(_T const& _data, int _w = 2)
std::string toHex(_T const& _data, int _w = 2, HexPrefix _prefix = HexPrefix::DontAdd)
{
std::ostringstream ret;
unsigned ii = 0;
for (auto i: _data)
ret << std::hex << std::setfill('0') << std::setw(ii++ ? 2 : _w) << (int)(typename std::make_unsigned<decltype(i)>::type)i;
return ret.str();
return (_prefix == HexPrefix::Add) ? "0x" + ret.str() : ret.str();
}
/// Converts a (printable) ASCII hex character into the correspnding integer value.
@ -116,9 +121,9 @@ inline void toBigEndian(_T _val, _Out& o_out)
template <class _T, class _In>
inline _T fromBigEndian(_In const& _bytes)
{
_T ret = 0;
_T ret = (_T)0;
for (auto i: _bytes)
ret = (ret << 8) | (byte)(typename std::make_unsigned<typename _In::value_type>::type)i;
ret = (_T)((ret << 8) | (byte)(typename std::make_unsigned<typename _In::value_type>::type)i);
return ret;
}
@ -128,9 +133,6 @@ inline std::string toBigEndianString(u160 _val) { std::string ret(20, '\0'); toB
inline bytes toBigEndian(u256 _val) { bytes ret(32); toBigEndian(_val, ret); return ret; }
inline bytes toBigEndian(u160 _val) { bytes ret(20); toBigEndian(_val, ret); return ret; }
/// Convenience function for conversion of a u256 to hex
inline std::string toHex(u256 val) { return toHex(toBigEndian(val)); }
/// Convenience function for toBigEndian.
/// @returns a byte array just big enough to represent @a _val.
template <class _T>
@ -150,15 +152,27 @@ inline bytes toCompactBigEndian(byte _val, unsigned _min = 0)
/// Convenience function for toBigEndian.
/// @returns a string just big enough to represent @a _val.
template <class _T>
inline std::string toCompactBigEndianString(_T _val)
inline std::string toCompactBigEndianString(_T _val, unsigned _min = 0)
{
int i = 0;
for (_T v = _val; v; ++i, v >>= 8) {}
std::string ret(i, '\0');
std::string ret(std::max<unsigned>(_min, i), '\0');
toBigEndian(_val, ret);
return ret;
}
/// Convenience function for conversion of a u256 to hex
inline std::string toHex(u256 val, HexPrefix prefix = HexPrefix::DontAdd)
{
std::string str = toHex(toBigEndian(val));
return (prefix == HexPrefix::Add) ? "0x" + str : str;
}
inline std::string toCompactHex(u256 val, HexPrefix prefix = HexPrefix::DontAdd, unsigned _min = 0)
{
std::string str = toHex(toCompactBigEndian(val, _min));
return (prefix == HexPrefix::Add) ? "0x" + str : str;
}
// Algorithms for string and string-like collections.

9
libdevcore/CommonIO.h

@ -45,7 +45,8 @@ namespace dev
/// Retrieve and returns the contents of the given file. If the file doesn't exist or isn't readable, returns an empty bytes.
bytes contents(std::string const& _file);
std::string contentsString(std::string const& _file);
/// Retrieve and returns the allocated contents of the given file. If the file doesn't exist or isn't readable, returns nullptr. Don't forget to delete [] when finished.
/// Retrieve and returns the allocated contents of the given file; if @_dest is given, don't allocate, use it directly.
/// If the file doesn't exist or isn't readable, returns bytesRef(). Don't forget to delete [] the returned value's data when finished.
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.
@ -76,7 +77,11 @@ template <class T, class U> inline std::ostream& operator<<(std::ostream& _out,
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::multimap<T, U> const& _e);
template <class _S, class _T> _S& operator<<(_S& _out, std::shared_ptr<_T> const& _p);
template <class T> inline std::string toString(std::chrono::time_point<T> const& _e, std::string _format = "")
#ifdef _WIN32
template <class T> inline std::string toString(std::chrono::time_point<T> const& _e, std::string _format = "%Y-%m-%d %H:%M:%S")
#else
template <class T> inline std::string toString(std::chrono::time_point<T> const& _e, std::string _format = "%F %T")
#endif
{
unsigned long milliSecondsSinceEpoch = std::chrono::duration_cast<std::chrono::milliseconds>(_e.time_since_epoch()).count();
auto const durationSinceEpoch = std::chrono::milliseconds(milliSecondsSinceEpoch);

2
libdevcore/Exceptions.h

@ -51,7 +51,9 @@ struct NoUPnPDevice: virtual Exception {};
struct RootNotFound: virtual Exception {};
struct BadRoot: virtual Exception {};
struct FileError: virtual Exception {};
struct Overflow: virtual Exception {};
struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} };
struct FailedInvariant: virtual Exception {};
// error information to be added to exceptions
using errinfo_invalidSymbol = boost::error_info<struct tag_invalidSymbol, char>;

5
libdevcore/FixedHash.h

@ -64,6 +64,9 @@ public:
/// Convert from the corresponding arithmetic type.
FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); }
/// Convert from unsigned
explicit FixedHash(unsigned _u) { toBigEndian(_u, m_data); }
/// Explicitly construct, copying from a byte array.
explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min<unsigned>(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } }
@ -80,7 +83,7 @@ public:
operator Arith() const { return fromBigEndian<Arith>(m_data); }
/// @returns true iff this is the empty hash.
explicit operator bool() const { return ((Arith)*this) != 0; }
explicit operator bool() const { return std::any_of(m_data.begin(), m_data.end(), [](byte _b) { return _b != 0; }); }
// The obvious comparison operators.
bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; }

84
libdevcore/Guards.h

@ -22,6 +22,7 @@
#pragma once
#include <mutex>
#include <atomic>
#include <boost/thread.hpp>
namespace dev
@ -38,4 +39,87 @@ using UpgradableGuard = boost::upgrade_lock<boost::shared_mutex>;
using UpgradeGuard = boost::upgrade_to_unique_lock<boost::shared_mutex>;
using WriteGuard = boost::unique_lock<boost::shared_mutex>;
template <class GuardType, class MutexType>
struct GenericGuardBool: GuardType
{
GenericGuardBool(MutexType& _m): GuardType(_m) {}
bool b = true;
};
template <class MutexType>
struct GenericUnguardBool
{
GenericUnguardBool(MutexType& _m): m(_m) { m.unlock(); }
~GenericUnguardBool() { m.lock(); }
bool b = true;
MutexType& m;
};
template <class MutexType>
struct GenericUnguardSharedBool
{
GenericUnguardSharedBool(MutexType& _m): m(_m) { m.unlock_shared(); }
~GenericUnguardSharedBool() { m.lock_shared(); }
bool b = true;
MutexType& m;
};
/** @brief Simple lock that waits for release without making context switch */
class SpinLock
{
public:
SpinLock() { m_lock.clear(); }
void lock() { while (m_lock.test_and_set(std::memory_order_acquire)) {} }
void unlock() { m_lock.clear(std::memory_order_release); }
private:
std::atomic_flag m_lock;
};
using SpinGuard = std::lock_guard<SpinLock>;
/** @brief Simple block guard.
* The expression/block following is guarded though the given mutex.
* Usage:
* @code
* Mutex m;
* unsigned d;
* ...
* ETH_(m) d = 1;
* ...
* ETH_(m) { for (auto d = 10; d > 0; --d) foo(d); d = 0; }
* @endcode
*
* There are several variants of this basic mechanism for different Mutex types and Guards.
*
* There is also the UNGUARD variant which allows an unguarded expression/block to exist within a
* guarded expression. eg:
*
* @code
* Mutex m;
* int d;
* ...
* ETH_(m)
* {
* for (auto d = 50; d > 25; --d)
* foo(d);
* ETH_UNGUARDED(m)
* bar();
* for (; d > 0; --d)
* foo(d);
* }
* @endcode
*/
#define DEV_GUARDED(MUTEX) \
for (GenericGuardBool<Guard, Mutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
#define DEV_READ_GUARDED(MUTEX) \
for (GenericGuardBool<ReadGuard, SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
#define DEV_WRITE_GUARDED(MUTEX) \
for (GenericGuardBool<WriteGuard, SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
#define DEV_RECURSIVE_GUARDED(MUTEX) \
for (GenericGuardBool<RecursiveGuard, RecursiveMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
#define DEV_UNGUARDED(MUTEX) \
for (GenericUnguardBool<Mutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
#define DEV_READ_UNGUARDED(MUTEX) \
for (GenericUnguardSharedBool<SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
#define DEV_WRITE_UNGUARDED(MUTEX) \
for (GenericUnguardBool<SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
}

125
libdevcore/Log.cpp

@ -23,25 +23,143 @@
#include <string>
#include <iostream>
#include <thread>
#include <boost/asio/ip/tcp.hpp>
#include "Guards.h"
using namespace std;
using namespace dev;
//⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙
// Logging
int dev::g_logVerbosity = 5;
map<type_info const*, bool> dev::g_logOverride;
ThreadLocalLogName dev::t_logThreadName("main");
#ifdef _WIN32
const char* LogChannel::name() { return EthGray "..."; }
const char* LeftChannel::name() { return EthNavy "<--"; }
const char* RightChannel::name() { return EthGreen "-->"; }
const char* WarnChannel::name() { return EthOnRed EthBlackBold " X"; }
const char* NoteChannel::name() { return EthBlue " i"; }
const char* DebugChannel::name() { return EthWhite " D"; }
#else
const char* LogChannel::name() { return EthGray "···"; }
const char* LeftChannel::name() { return EthNavy "◀▬▬"; }
const char* RightChannel::name() { return EthGreen "▬▬▶"; }
const char* WarnChannel::name() { return EthOnRed EthBlackBold ""; }
const char* NoteChannel::name() { return EthBlue ""; }
const char* DebugChannel::name() { return EthWhite ""; }
#endif
LogOutputStreamBase::LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v, bool _autospacing):
m_autospacing(_autospacing),
m_verbosity(_v)
{
auto it = g_logOverride.find(_info);
if ((it != g_logOverride.end() && it->second == true) || (it == g_logOverride.end() && (int)_v <= g_logVerbosity))
{
time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
char buf[24];
if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0)
buf[0] = '\0'; // empty if case strftime fails
static char const* c_begin = " " EthViolet;
static char const* c_sep1 = EthReset EthBlack "|" EthNavy;
static char const* c_sep2 = EthReset EthBlack "|" EthTeal;
static char const* c_end = EthReset " ";
m_sstr << _id << c_begin << buf << c_sep1 << getThreadName() << ThreadContext::join(c_sep2) << c_end;
}
}
void LogOutputStreamBase::append(boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> const& _t)
{
m_sstr << EthNavyUnder "tcp://" << _t << EthReset;
}
/// Associate a name with each thread for nice logging.
struct ThreadLocalLogName
{
ThreadLocalLogName(std::string const& _name) { m_name.reset(new string(_name)); }
boost::thread_specific_ptr<std::string> m_name;
};
/// Associate a name with each thread for nice logging.
struct ThreadLocalLogContext
{
ThreadLocalLogContext() = default;
void push(std::string const& _name)
{
if (!m_contexts.get())
m_contexts.reset(new vector<string>);
m_contexts->push_back(_name);
}
void pop()
{
m_contexts->pop_back();
}
string join(string const& _prior)
{
string ret;
if (m_contexts.get())
for (auto const& i: *m_contexts)
ret += _prior + i;
return ret;
}
boost::thread_specific_ptr<std::vector<std::string>> m_contexts;
};
ThreadLocalLogContext g_logThreadContext;
ThreadLocalLogName g_logThreadName("main");
void dev::ThreadContext::push(string const& _n)
{
g_logThreadContext.push(_n);
}
void dev::ThreadContext::pop()
{
g_logThreadContext.pop();
}
string dev::ThreadContext::join(string const& _prior)
{
return g_logThreadContext.join(_prior);
}
// foward declare without all of Windows.h
#ifdef _WIN32
extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* lpOutputString);
#endif
string dev::getThreadName()
{
#ifdef __linux__
char buffer[128];
pthread_getname_np(pthread_self(), buffer, 127);
buffer[127] = 0;
return buffer;
#else
return g_logThreadName.m_name.get() ? *g_logThreadName.m_name.get() : "<unknown>";
#endif
}
void dev::setThreadName(string const& _n)
{
#ifdef __linux__
pthread_setname_np(pthread_self(), _n.c_str());
#else
g_logThreadName.m_name.reset(new std::string(_n));
#endif
}
void dev::simpleDebugOut(std::string const& _s, char const*)
{
static Mutex s_lock;
Guard l(s_lock);
static SpinLock s_lock;
SpinGuard l(s_lock);
cerr << _s << endl << flush;
@ -55,4 +173,3 @@ void dev::simpleDebugOut(std::string const& _s, char const*)
}
std::function<void(std::string const&, char const*)> dev::g_logPost = simpleDebugOut;

160
libdevcore/Log.h

@ -27,7 +27,13 @@
#include <chrono>
#include <boost/thread.hpp>
#include "vector_ref.h"
#include "Common.h"
#include "CommonIO.h"
#include "CommonData.h"
#include "FixedHash.h"
#include "Terminal.h"
namespace boost { namespace asio { namespace ip { template<class T>class basic_endpoint; class tcp; } } }
namespace dev
{
@ -53,57 +59,149 @@ extern std::function<void(std::string const&, char const*)> g_logPost;
/// or equal to the currently output verbosity (g_logVerbosity).
extern std::map<std::type_info const*, bool> g_logOverride;
/// Associate a name with each thread for nice logging.
struct ThreadLocalLogName
#define ETH_THREAD_CONTEXT(name) for (std::pair<dev::ThreadContext, bool> __eth_thread_context(name, true); p.second; p.second = false)
class ThreadContext
{
ThreadLocalLogName(std::string _name) { m_name.reset(new std::string(_name)); };
boost::thread_specific_ptr<std::string> m_name;
public:
ThreadContext(std::string const& _info) { push(_info); }
~ThreadContext() { pop(); }
static void push(std::string const& _n);
static void pop();
static std::string join(std::string const& _prior);
};
/// The current thread's name.
extern ThreadLocalLogName t_logThreadName;
/// Set the current thread's log name.
void setThreadName(std::string const& _n);
/// Set the current thread's log name.
inline void setThreadName(char const* _n) { t_logThreadName.m_name.reset(new std::string(_n)); }
std::string getThreadName();
/// The default logging channels. Each has an associated verbosity and three-letter prefix (name() ).
/// Channels should inherit from LogChannel and define name() and verbosity.
struct LogChannel { static const char* name() { return " "; } static const int verbosity = 1; };
struct LeftChannel: public LogChannel { static const char* name() { return "<<<"; } };
struct RightChannel: public LogChannel { static const char* name() { return ">>>"; } };
struct WarnChannel: public LogChannel { static const char* name() { return "!!!"; } static const int verbosity = 0; };
struct NoteChannel: public LogChannel { static const char* name() { return "***"; } };
struct DebugChannel: public LogChannel { static const char* name() { return "---"; } static const int verbosity = 0; };
struct LogChannel { static const char* name(); static const int verbosity = 1; };
struct LeftChannel: public LogChannel { static const char* name(); };
struct RightChannel: public LogChannel { static const char* name(); };
struct WarnChannel: public LogChannel { static const char* name(); static const int verbosity = 0; };
struct NoteChannel: public LogChannel { static const char* name(); };
struct DebugChannel: public LogChannel { static const char* name(); static const int verbosity = 0; };
enum class LogTag
{
None,
Url,
Error,
Special
};
/// Logging class, iostream-like, that can be shifted to.
template <class Id, bool _AutoSpacing = true>
class LogOutputStream
class LogOutputStreamBase
{
public:
/// Construct a new object.
/// If _term is true the the prefix info is terminated with a ']' character; if not it ends only with a '|' character.
LogOutputStream(bool _term = true)
LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v, bool _autospacing);
void comment(std::string const& _t)
{
std::type_info const* i = &typeid(Id);
auto it = g_logOverride.find(i);
if ((it != g_logOverride.end() && it->second == true) || (it == g_logOverride.end() && Id::verbosity <= g_logVerbosity))
switch (m_logTag)
{
time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
char buf[24];
if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0)
buf[0] = '\0'; // empty if case strftime fails
m_sstr << Id::name() << " [ " << buf << " | " << (t_logThreadName.m_name.get() ? *t_logThreadName.m_name.get() : std::string("<unknown>")) << (_term ? " ] " : "");
case LogTag::Url: m_sstr << EthNavyUnder; break;
case LogTag::Error: m_sstr << EthRedBold; break;
case LogTag::Special: m_sstr << EthWhiteBold; break;
default:;
}
m_sstr << _t << EthReset;
m_logTag = LogTag::None;
}
void append(unsigned long _t) { m_sstr << EthBlue << _t << EthReset; }
void append(long _t) { m_sstr << EthBlue << _t << EthReset; }
void append(unsigned int _t) { m_sstr << EthBlue << _t << EthReset; }
void append(int _t) { m_sstr << EthBlue << _t << EthReset; }
void append(bigint const& _t) { m_sstr << EthNavy << _t << EthReset; }
void append(u256 const& _t) { m_sstr << EthNavy << _t << EthReset; }
void append(u160 const& _t) { m_sstr << EthNavy << _t << EthReset; }
void append(double _t) { m_sstr << EthBlue << _t << EthReset; }
template <unsigned N> void append(FixedHash<N> const& _t) { m_sstr << EthTeal "#" << _t.abridged() << EthReset; }
void append(h160 const& _t) { m_sstr << EthRed "@" << _t.abridged() << EthReset; }
void append(h256 const& _t) { m_sstr << EthCyan "#" << _t.abridged() << EthReset; }
void append(h512 const& _t) { m_sstr << EthTeal "##" << _t.abridged() << EthReset; }
void append(std::string const& _t) { m_sstr << EthGreen "\"" + _t + "\"" EthReset; }
void append(bytes const& _t) { m_sstr << EthYellow "%" << toHex(_t) << EthReset; }
void append(bytesConstRef _t) { m_sstr << EthYellow "%" << toHex(_t) << EthReset; }
void append(boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> const& _t);
template <class T> void append(std::vector<T> const& _t)
{
m_sstr << EthWhite "[" EthReset;
int n = 0;
for (auto const& i: _t)
{
m_sstr << (n++ ? EthWhite ", " EthReset : "");
append(i);
}
m_sstr << EthWhite "]" EthReset;
}
template <class T> void append(std::set<T> const& _t)
{
m_sstr << EthYellow "{" EthReset;
int n = 0;
for (auto const& i: _t)
{
m_sstr << (n++ ? EthYellow ", " EthReset : "");
append(i);
}
m_sstr << EthYellow "}" EthReset;
}
template <class T, class U> void append(std::map<T, U> const& _t)
{
m_sstr << EthLime "{" EthReset;
int n = 0;
for (auto const& i: _t)
{
m_sstr << (n++ ? EthLime ", " EthReset : "");
append(i.first);
m_sstr << (n++ ? EthLime ": " EthReset : "");
append(i.second);
}
m_sstr << EthLime "}" EthReset;
}
template <class T, class U> void append(std::pair<T, U> const& _t)
{
m_sstr << EthPurple "(" EthReset;
append(_t.first);
m_sstr << EthPurple ", " EthReset;
append(_t.second);
m_sstr << EthPurple ")" EthReset;
}
template <class T> void append(T const& _t)
{
m_sstr << toString(_t);
}
protected:
bool m_autospacing = false;
unsigned m_verbosity = 0;
std::stringstream m_sstr; ///< The accrued log entry.
LogTag m_logTag = LogTag::None;
};
/// Logging class, iostream-like, that can be shifted to.
template <class Id, bool _AutoSpacing = true>
class LogOutputStream: LogOutputStreamBase
{
public:
/// Construct a new object.
/// If _term is true the the prefix info is terminated with a ']' character; if not it ends only with a '|' character.
LogOutputStream(): LogOutputStreamBase(Id::name(), &typeid(Id), Id::verbosity, _AutoSpacing) {}
/// Destructor. Posts the accrued log entry to the g_logPost function.
~LogOutputStream() { if (Id::verbosity <= g_logVerbosity) g_logPost(m_sstr.str(), Id::name()); }
/// Shift arbitrary data to the log. Spaces will be added between items as required.
template <class T> LogOutputStream& operator<<(T const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; m_sstr << _t; } return *this; }
LogOutputStream& operator<<(std::string const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; comment(_t); } return *this; }
private:
std::stringstream m_sstr; ///< The accrued log entry.
LogOutputStream& operator<<(LogTag _t) { m_logTag = _t; return *this; }
/// Shift arbitrary data to the log. Spaces will be added between items as required.
template <class T> LogOutputStream& operator<<(T const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; append(_t); } return *this; }
};
// Simple cout-like stream objects for accessing common log channels.

21
libdevcore/RLP.cpp

@ -111,10 +111,24 @@ unsigned RLP::actualSize() const
return 0;
}
void RLP::requireGood() const
{
if (isNull())
BOOST_THROW_EXCEPTION(BadRLP());
byte n = m_data[0];
if (n != c_rlpDataImmLenStart + 1)
return;
if (m_data.size() < 2)
BOOST_THROW_EXCEPTION(BadRLP());
if (m_data[1] < c_rlpDataImmLenStart)
BOOST_THROW_EXCEPTION(BadRLP());
}
bool RLP::isInt() const
{
if (isNull())
return false;
requireGood();
byte n = m_data[0];
if (n < c_rlpDataImmLenStart)
return !!n;
@ -141,6 +155,7 @@ unsigned RLP::length() const
{
if (isNull())
return 0;
requireGood();
unsigned ret = 0;
byte n = m_data[0];
if (n < c_rlpDataImmLenStart)
@ -151,6 +166,9 @@ unsigned RLP::length() const
{
if ((int)m_data.size() <= n - c_rlpDataIndLenZero)
BOOST_THROW_EXCEPTION(BadRLP());
if ((int)m_data.size() > 1)
if (m_data[1] == 0)
BOOST_THROW_EXCEPTION(BadRLP());
for (int i = 0; i < n - c_rlpDataIndLenZero; ++i)
ret = (ret << 8) | m_data[i + 1];
}
@ -160,6 +178,9 @@ unsigned RLP::length() const
{
if ((int)m_data.size() <= n - c_rlpListIndLenZero)
BOOST_THROW_EXCEPTION(BadRLP());
if ((int)m_data.size() > 1)
if (m_data[1] == 0)
BOOST_THROW_EXCEPTION(BadRLP());
for (int i = 0; i < n - c_rlpListIndLenZero; ++i)
ret = (ret << 8) | m_data[i + 1];
}

9
libdevcore/RLP.h

@ -253,6 +253,7 @@ public:
/// Converts to int of type given; if isString(), decodes as big-endian bytestream. @returns 0 if not an int or string.
template <class _T = unsigned> _T toInt(int _flags = Strict) const
{
requireGood();
if ((!isInt() && !(_flags & AllowNonCanon)) || isList() || isNull())
if (_flags & ThrowOnFail)
BOOST_THROW_EXCEPTION(BadCast());
@ -273,6 +274,7 @@ public:
template <class _N> _N toHash(int _flags = Strict) const
{
requireGood();
if (!isData() || (length() > _N::size && (_flags & FailIfTooBig)) || (length() < _N::size && (_flags & FailIfTooSmall)))
if (_flags & ThrowOnFail)
BOOST_THROW_EXCEPTION(BadCast());
@ -290,7 +292,7 @@ public:
RLPs toList() const;
/// @returns the data payload. Valid for all types.
bytesConstRef payload() const { return m_data.cropped(payloadOffset()); }
bytesConstRef payload() const { auto l = length(); if (l > m_data.size()) throw BadRLP(); return m_data.cropped(payloadOffset(), l); }
/// @returns the theoretical size of this item.
/// @note Under normal circumstances, is equivalent to m_data.size() - use that unless you know it won't work.
@ -300,10 +302,13 @@ private:
/// Disable construction from rvalue
explicit RLP(bytes const&&) {}
/// Throws if is non-canonical data (i.e. single byte done in two bytes that could be done in one).
void requireGood() const;
/// Single-byte data payload.
bool isSingleByte() const { return !isNull() && m_data[0] < c_rlpDataImmLenStart; }
/// @returns the bytes used to encode the length of the data. Valid for all types.
/// @returns the amount of bytes used to encode the length of the data. Valid for all types.
unsigned lengthSize() const { if (isData() && m_data[0] > c_rlpDataIndLenZero) return m_data[0] - c_rlpDataIndLenZero; if (isList() && m_data[0] > c_rlpListIndLenZero) return m_data[0] - c_rlpListIndLenZero; return 0; }
/// @returns the size in bytes of the payload, as given by the RLP as opposed to as inferred from m_data.

148
libdevcore/Terminal.h

@ -0,0 +1,148 @@
#pragma once
namespace dev
{
namespace con
{
#ifdef _WIN32
#define EthReset "" // Text Reset
#define EthReset "" // Text Reset
// Regular Colors
#define EthBlack "" // Black
#define EthCoal "" // Black
#define EthGray "" // White
#define EthWhite "" // White
#define EthMaroon "" // Red
#define EthRed "" // Red
#define EthGreen "" // Green
#define EthLime "" // Green
#define EthOrange "" // Yellow
#define EthYellow "" // Yellow
#define EthNavy "" // Blue
#define EthBlue "" // Blue
#define EthViolet "" // Purple
#define EthPurple "" // Purple
#define EthTeal "" // Cyan
#define EthCyan "" // Cyan
#define EthBlackBold "" // Black
#define EthCoalBold "" // Black
#define EthGrayBold "" // White
#define EthWhiteBold "" // White
#define EthMaroonBold "" // Red
#define EthRedBold "" // Red
#define EthGreenBold "" // Green
#define EthLimeBold "" // Green
#define EthOrangeBold "" // Yellow
#define EthYellowBold "" // Yellow
#define EthNavyBold "" // Blue
#define EthBlueBold "" // Blue
#define EthVioletBold "" // Purple
#define EthPurpleBold "" // Purple
#define EthTealBold "" // Cyan
#define EthCyanBold "" // Cyan
// Background
#define EthOnBlack "" // Black
#define EthOnCoal "" // Black
#define EthOnGray "" // White
#define EthOnWhite "" // White
#define EthOnMaroon "" // Red
#define EthOnRed "" // Red
#define EthOnGreen "" // Green
#define EthOnLime "" // Green
#define EthOnOrange "" // Yellow
#define EthOnYellow "" // Yellow
#define EthOnNavy "" // Blue
#define EthOnBlue "" // Blue
#define EthOnViolet "" // Purple
#define EthOnPurple "" // Purple
#define EthOnTeal "" // Cyan
#define EthOnCyan "" // Cyan
// Underline
#define EthBlackUnder "" // Black
#define EthGrayUnder "" // White
#define EthMaroonUnder "" // Red
#define EthGreenUnder "" // Green
#define EthOrangeUnder "" // Yellow
#define EthNavyUnder "" // Blue
#define EthVioletUnder "" // Purple
#define EthTealUnder "" // Cyan
#else
#define EthReset "\x1b[0m" // Text Reset
// Regular Colors
#define EthBlack "\x1b[30m" // Black
#define EthCoal "\x1b[90m" // Black
#define EthGray "\x1b[37m" // White
#define EthWhite "\x1b[97m" // White
#define EthMaroon "\x1b[31m" // Red
#define EthRed "\x1b[91m" // Red
#define EthGreen "\x1b[32m" // Green
#define EthLime "\x1b[92m" // Green
#define EthOrange "\x1b[33m" // Yellow
#define EthYellow "\x1b[93m" // Yellow
#define EthNavy "\x1b[34m" // Blue
#define EthBlue "\x1b[94m" // Blue
#define EthViolet "\x1b[35m" // Purple
#define EthPurple "\x1b[95m" // Purple
#define EthTeal "\x1b[36m" // Cyan
#define EthCyan "\x1b[96m" // Cyan
#define EthBlackBold "\x1b[1;30m" // Black
#define EthCoalBold "\x1b[1;90m" // Black
#define EthGrayBold "\x1b[1;37m" // White
#define EthWhiteBold "\x1b[1;97m" // White
#define EthMaroonBold "\x1b[1;31m" // Red
#define EthRedBold "\x1b[1;91m" // Red
#define EthGreenBold "\x1b[1;32m" // Green
#define EthLimeBold "\x1b[1;92m" // Green
#define EthOrangeBold "\x1b[1;33m" // Yellow
#define EthYellowBold "\x1b[1;93m" // Yellow
#define EthNavyBold "\x1b[1;34m" // Blue
#define EthBlueBold "\x1b[1;94m" // Blue
#define EthVioletBold "\x1b[1;35m" // Purple
#define EthPurpleBold "\x1b[1;95m" // Purple
#define EthTealBold "\x1b[1;36m" // Cyan
#define EthCyanBold "\x1b[1;96m" // Cyan
// Background
#define EthOnBlack "\x1b[40m" // Black
#define EthOnCoal "\x1b[100m" // Black
#define EthOnGray "\x1b[47m" // White
#define EthOnWhite "\x1b[107m" // White
#define EthOnMaroon "\x1b[41m" // Red
#define EthOnRed "\x1b[101m" // Red
#define EthOnGreen "\x1b[42m" // Green
#define EthOnLime "\x1b[102m" // Green
#define EthOnOrange "\x1b[43m" // Yellow
#define EthOnYellow "\x1b[103m" // Yellow
#define EthOnNavy "\x1b[44m" // Blue
#define EthOnBlue "\x1b[104m" // Blue
#define EthOnViolet "\x1b[45m" // Purple
#define EthOnPurple "\x1b[105m" // Purple
#define EthOnTeal "\x1b[46m" // Cyan
#define EthOnCyan "\x1b[106m" // Cyan
// Underline
#define EthBlackUnder "\x1b[4;30m" // Black
#define EthGrayUnder "\x1b[4;37m" // White
#define EthMaroonUnder "\x1b[4;31m" // Red
#define EthGreenUnder "\x1b[4;32m" // Green
#define EthOrangeUnder "\x1b[4;33m" // Yellow
#define EthNavyUnder "\x1b[4;34m" // Blue
#define EthVioletUnder "\x1b[4;35m" // Purple
#define EthTealUnder "\x1b[4;36m" // Cyan
#endif
}
}

100
libdevcore/Worker.cpp

@ -29,37 +29,89 @@ using namespace dev;
void Worker::startWorking()
{
cnote << "startWorking for thread" << m_name;
// cnote << "startWorking for thread" << m_name;
Guard l(x_work);
if (m_work)
return;
cnote << "Spawning" << m_name;
m_stop = false;
m_work.reset(new thread([&]()
{
setThreadName(m_name.c_str());
startedWorking();
while (!m_stop)
WorkerState ex = WorkerState::Stopped;
m_state.compare_exchange_strong(ex, WorkerState::Starting);
}
else
{
m_state = WorkerState::Starting;
m_work.reset(new thread([&]()
{
if (m_idleWaitMs)
this_thread::sleep_for(chrono::milliseconds(m_idleWaitMs));
doWork();
}
cnote << "Finishing up worker thread";
doneWorking();
}));
setThreadName(m_name.c_str());
// cnote << "Thread begins";
while (m_state != WorkerState::Killing)
{
WorkerState ex = WorkerState::Starting;
bool ok = m_state.compare_exchange_strong(ex, WorkerState::Started);
// cnote << "Trying to set Started: Thread was" << (unsigned)ex << "; " << ok;
(void)ok;
startedWorking();
// cnote << "Entering work loop...";
workLoop();
// cnote << "Finishing up worker thread...";
doneWorking();
// ex = WorkerState::Stopping;
// m_state.compare_exchange_strong(ex, WorkerState::Stopped);
ex = m_state.exchange(WorkerState::Stopped);
// cnote << "State: Stopped: Thread was" << (unsigned)ex;
if (ex == WorkerState::Killing || ex == WorkerState::Starting)
m_state.exchange(ex);
// cnote << "Waiting until not Stopped...";
DEV_TIMED_IF(Worker stopping, 100)
while (m_state == WorkerState::Stopped)
this_thread::sleep_for(chrono::milliseconds(20));
}
}));
// cnote << "Spawning" << m_name;
}
DEV_TIMED_IF(Start worker, 100)
while (m_state != WorkerState::Started)
this_thread::sleep_for(chrono::microseconds(20));
}
void Worker::stopWorking()
{
cnote << "stopWorking for thread" << m_name;
Guard l(x_work);
if (!m_work)
return;
cnote << "Stopping" << m_name;
m_stop = true;
m_work->join();
m_work.reset();
cnote << "Stopped" << m_name;
DEV_GUARDED(x_work)
if (m_work)
{
WorkerState ex = WorkerState::Started;
m_state.compare_exchange_strong(ex, WorkerState::Stopping);
DEV_TIMED_IF(Stop worker, 100)
while (m_state != WorkerState::Stopped)
this_thread::sleep_for(chrono::microseconds(20));
}
}
void Worker::terminate()
{
// cnote << "stopWorking for thread" << m_name;
DEV_GUARDED(x_work)
if (m_work)
{
m_state.exchange(WorkerState::Killing);
DEV_TIMED_IF(Terminate worker, 100)
m_work->join();
m_work.reset();
}
}
void Worker::workLoop()
{
while (m_state == WorkerState::Started)
{
if (m_idleWaitMs)
this_thread::sleep_for(chrono::milliseconds(m_idleWaitMs));
doWork();
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save