Browse Source

Merge pull request #247 from subtly/develop

Bug fixes, qtwebkit on osx, networking
cl-refactor
Gav Wood 11 years ago
parent
commit
5a3cb103aa
  1. 25
      .gitignore
  2. 198
      CMakeLists.txt
  3. 66
      alethzero/CMakeLists.txt
  4. 93
      alethzero/MainWin.cpp
  5. BIN
      alethzero/alethzero.icns
  6. 1
      eth/main.cpp
  7. 2
      libethereum/Client.cpp
  8. 3
      libethereum/Client.h
  9. 24
      libethereum/PeerServer.cpp
  10. 1
      libethereum/PeerServer.h
  11. 117
      libethereum/PeerSession.cpp
  12. 4
      libethereum/PeerSession.h
  13. 11
      libqethereum/CMakeLists.txt
  14. 33
      libqethereum/QEthereum.cpp
  15. 2
      libqethereum/QEthereum.h
  16. 9
      secp256k1/CMakeLists.txt
  17. 2
      test/peer.cpp
  18. 38
      walleth/EthereumMacOSXBundleInfo.plist.in
  19. 3
      walleth/MainWin.cpp

25
.gitignore

@ -30,4 +30,29 @@ build.*/
*.pyc
# MacOS Development
.DS_Store
# CocoaPods
Pods/
Podfile.lock
# Xcode
.DS_Store
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
*.xcworkspace
!default.xcworkspace
xcuserdata
*.xcuserstate
profile
*.moved-aside
DerivedData
project.pbxproj

198
CMakeLists.txt

@ -1,51 +1,37 @@
# cmake global
project(ethereum)
cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_AUTOMOC ON)
cmake_policy(SET CMP0015 NEW)
set(HEADLESS CACHE BOOL 0)
set(LANGUAGES CACHE BOOL 0)
# user defined, defaults
# Normally, set(...CACHE...) creates cache variables, but does not modify them.
if ("x${PARANOIA}" STREQUAL "x")
if ("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug")
set(PARANOIA CACHE BOOL 1)
else ()
set(PARANOIA CACHE BOOL 0)
endif ()
endif ()
set(HEADLESS OFF CACHE BOOL "Do not compile GUI (AlethZero)")
set(LANGUAGES OFF CACHE BOOL "Limit build to Serpent/LLL tools")
set(VMTRACE OFF CACHE BOOL "VM tracing and run-time checks (useful for cross-implementation VM debugging)")
set(PARANOIA OFF CACHE BOOL "Additional run-time checks")
if ("x${VMTRACE}" STREQUAL "x")
if ("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug")
set(VMTRACE CACHE BOOL 1)
else ()
set(VMTRACE CACHE BOOL 0)
endif ()
if (LANGUAGES)
add_definitions(-DETH_LANGUAGES)
endif ()
if (PARANOIA)
add_definitions(-DETH_PARANOIA)
else()
set(PARANOIA 0)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
add_definitions(-DETH_PARANOIA)
else ()
message(FATAL_ERROR "Paranoia requires debug.")
endif ()
endif ()
if (VMTRACE)
add_definitions(-DETH_VMTRACE)
else()
set(VMTRACE 0)
endif ()
if (LANGUAGES)
add_definitions(-DETH_LANGUAGES)
else()
set(LANGUAGES 0)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
add_definitions(-DETH_VMTRACE)
else ()
message(FATAL_ERROR "VM tracing requires debug.")
endif ()
endif ()
if (NOT HEADLESS)
set(HEADLESS 0)
endif()
message("LANGUAGES: ${LANGUAGES}; VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}")
# Default TARGET_PLATFORM to "linux".
@ -58,13 +44,19 @@ if ("${TARGET_PLATFORM}" STREQUAL "linux")
set(CMAKE_THREAD_LIBS_INIT pthread)
endif ()
# Initialize CXXFLAGS.
# Set default build type to Release w/debug info
# if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
# set(CMAKE_BUILD_TYPE RelWithDebInfo)
# endif()
# Initialize CXXFLAGS
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG")
# Windows
if ("${TARGET_PLATFORM}" STREQUAL "w64")
set(CMAKE_SYSTEM_NAME Windows)
@ -96,6 +88,7 @@ else ()
set(ETH_SHARED 1)
endif()
# Set build platform; to be written to BuildInfo.h
if (CMAKE_COMPILER_IS_MINGW)
set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/mingw")
elseif (CMAKE_COMPILER_IS_MSYS)
@ -104,16 +97,17 @@ elseif (CMAKE_COMPILER_IS_GNUCXX)
set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/g++")
elseif (CMAKE_COMPILER_IS_MSVC)
set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/msvc")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/clang")
else ()
set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/unknown")
endif ()
message("CXXFLAGS: ${CMAKE_CXX_FLAGS}")
#add_definitions("-DETH_BUILD_TYPE=${ETH_BUILD_TYPE}")
#add_definitions("-DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM}")
# Compiler-specific C++11 activation.
# C++11 check and activation
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
@ -133,51 +127,43 @@ if("${TARGET_PLATFORM}" STREQUAL "w64")
set(CRYPTOPP_ID /usr/x86_64-w64-mingw32/include/cryptopp)
else()
# Look for available Crypto++ version and if it is >= 5.6.2
find_path(CRYPTOPP_ID cryptlib.h
find_path(ID cryptlib.h
../cryptopp/src
../../cryptopp/src)
if(CRYPTOPP_ID STREQUAL "CRYPTOPP_ID-NOTFOUND")
message("Trying system cryptopp...")
find_path(CRYPTOPP_ID cryptlib.h
/usr/include/cryptopp
/usr/include/crypto++
/usr/local/include/cryptopp
/usr/local/include/crypto++
/opt/local/include/cryptopp
/opt/local/include/crypto++
)
find_library(CRYPTOPP_LS NAMES cryptoppeth cryptopp
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
)
else()
message("Local cryptopp OK.")
set(CRYPTOPP_LS ${CRYPTOPP_ID}/../target/build/release/libcryptopp.so)
endif()
../../cryptopp/src
/usr/include/cryptopp
/usr/include/crypto++
/usr/local/include/cryptopp
/usr/local/include/crypto++
/opt/local/include/cryptopp
/opt/local/include/crypto++
)
find_library(LS NAMES cryptoppeth cryptopp
../cryptopp/src/../target/build/release
../../cryptopp/src/../target/build/release
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
)
if (CRYPTOPP_LS STREQUAL "CRYPTOPP_LS-NOTFOUND")
message(FATAL_ERROR "Couldn't find Crypto++ version >= 5.6.2.")
else()
message(STATUS "Found Crypto++: ${CRYPTOPP_ID}, ${CRYPTOPP_LS}")
set(_CRYPTOPP_VERSION_HEADER ${CRYPTOPP_ID}/config.h)
if (ID AND LS)
message(STATUS "Found Crypto++: ${ID}, ${LS}")
set(_CRYPTOPP_VERSION_HEADER ${ID}/config.h)
if(EXISTS ${_CRYPTOPP_VERSION_HEADER})
file(STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION ${_CRYPTOPP_VERSION})
if(${_CRYPTOPP_VERSION} LESS 562)
set(CRYPTOPP_ID CACHE FILEPATH "" FORCE)
set(CRYPTOPP_LS CACHE FILEPATH "" FORCE)
message(STATUS "Crypto++ version found is smaller than 5.6.2.")
message(FATAL_ERROR "Crypto++ version found is smaller than 5.6.2.")
else()
set(CRYPTOPP_ID ${ID} CACHE FILEPATH "")
set(CRYPTOPP_LS ${LS} CACHE FILEPATH "")
message(STATUS "Crypto++ found and version greater or equal to 5.6.2")
endif()
endif()
else()
message(STATUS "Crypto++ Not Found: ${CRYPTOPP_ID}, ${CRYPTOPP_LS}")
endif()
# Not really worth caching. We want to reevaluate anyway.
mark_as_advanced(CRYPTOPP_ID CRYPTOPP_LS)
find_path( LEVELDB_ID leveldb/db.h
/usr/include
/usr/local/include
@ -310,40 +296,32 @@ else()
endif()
if(CRYPTOPP_ID)
include_directories(${CRYPTOPP_ID})
include_directories(${CRYPTOPP_ID})
endif()
if(PYTHON_ID)
include_directories(${PYTHON_ID})
include_directories(${PYTHON_ID})
endif()
if(MINIUPNPC_ID)
include_directories(${MINIUPNPC_ID})
include_directories(${MINIUPNPC_ID})
endif()
if(LEVELDB_ID)
include_directories(${LEVELDB_ID})
include_directories(${LEVELDB_ID})
endif()
if(READLINE_ID)
include_directories(${READLINE_ID})
include_directories(${READLINE_ID})
endif()
if(JSONRPC_ID)
include_directories(${JSONRPC_ID})
endif()
# if (NOT APPLE)
# link_directories(${CRYPTOPP_LS})
# link_directories(${LEVELDB_LS})
# link_directories(${MINIUPNPC_LS})
# link_directories(${PYTHON_LS})
# link_directories(${READLINE_LS})
# link_directories(${JSONRPC_LS})
# endif()
# Generate header file containing useful build information
add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BUILD_TYPE} ${ETH_BUILD_PLATFORM})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
link_directories(/usr/local/lib)
include_directories(/usr/local/include)
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
endif()
add_subdirectory(libethential)
add_subdirectory(libevmface)
@ -357,34 +335,40 @@ endif()
add_subdirectory(lllc)
add_subdirectory(sc)
if (NOT LANGUAGES)
add_subdirectory(secp256k1)
add_subdirectory(libethcore)
add_subdirectory(libevm)
add_subdirectory(libethereum)
add_subdirectory(test)
add_subdirectory(eth)
if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug")
add_subdirectory(exp)
endif ()
if(NOT ("${TARGET_PLATFORM}" STREQUAL "w64"))
add_subdirectory(neth)
endif ()
if(QTQML)
add_definitions(-DETH_QTQML)
endif()
add_subdirectory(secp256k1)
add_subdirectory(libethcore)
add_subdirectory(libevm)
add_subdirectory(libethereum)
add_subdirectory(test)
add_subdirectory(eth)
if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug")
add_subdirectory(exp)
endif ()
if(NOT ("${TARGET_PLATFORM}" STREQUAL "w64"))
add_subdirectory(neth)
endif ()
if(QTQML)
add_definitions(-DETH_QTQML)
endif()
if(NOT HEADLESS)
add_subdirectory(libqethereum)
add_subdirectory(alethzero)
if(QTQML)
add_subdirectory(walleth)
endif()
endif()
if(NOT HEADLESS)
if ("${TARGET_PLATFORM}" STREQUAL "w64")
cmake_policy(SET CMP0020 NEW)
endif ()
add_subdirectory(libqethereum)
add_subdirectory(alethzero)
if(QTQML)
add_subdirectory(walleth)
endif()
endif()
endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SRC_LIST BuildInfo.h)
enable_testing()
add_test(NAME alltests WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth)
#unset(HEADLESS CACHE)
#unset(TARGET_PLATFORM CACHE)

66
alethzero/CMakeLists.txt

@ -1,30 +1,18 @@
cmake_policy(SET CMP0015 NEW)
if ("${TARGET_PLATFORM}" STREQUAL "w64")
cmake_policy(SET CMP0020 NEW)
endif ()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(. SRC_LIST)
include_directories(..)
# Find Qt5 for Apple and update src_list for windows
if (APPLE)
# homebrew defaults to qt4 and installs qt5 as 'keg-only'
# which places it into /usr/local/opt insteadof /usr/local.
# Add homebrew path for qt5
set(CMAKE_PREFIX_PATH /usr/local/opt/qt5)
include_directories(/usr/local/opt/qt5/include /usr/local/include)
elseif ("${TARGET_PLATFORM}" STREQUAL "w64")
set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp)
include_directories(/usr/x86_64-w64-mingw32/include /usr/x86_64-w64-mingw32/include/QtCore /usr/x86_64-w64-mingw32/include/QtGui /usr/x86_64-w64-mingw32/include/QtQuick /usr/x86_64-w64-mingw32/include/QtQml /usr/x86_64-w64-mingw32/include/QtNetwork /usr/x86_64-w64-mingw32/include/QtWidgets /usr/x86_64-w64-mingw32/include/QtWebKit /usr/x86_64-w64-mingw32/include/QtWebKitWidgets)
elseif (UNIX)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake")
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake")
endif ()
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Quick REQUIRED)
@ -33,12 +21,12 @@ find_package(Qt5Network REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5WebKit REQUIRED)
find_package(Qt5WebKitWidgets REQUIRED)
qt5_wrap_ui(ui_Main.h Main.ui)
# Set name of binary and add_executable()
if (APPLE)
set(EXECUTEABLE AlethZero)
set(CMAKE_INSTALL_PREFIX ./)
set(BIN_INSTALL_DIR ".")
set(DOC_INSTALL_DIR ".")
@ -50,9 +38,14 @@ if (APPLE)
set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}")
set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE})
set(MACOSX_BUNDLE_ICON_FILE alethzero)
include(BundleUtilities)
add_executable(${EXECUTEABLE} MACOSX_BUNDLE Main.ui ${SRC_LIST})
add_executable(${EXECUTEABLE} MACOSX_BUNDLE alethzero.icns Main.ui ${SRC_LIST})
set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in")
SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS)
SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
else ()
set(EXECUTEABLE alethzero)
add_executable(${EXECUTEABLE} Main.ui ${SRC_LIST})
@ -62,36 +55,29 @@ qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets)
target_link_libraries(${EXECUTEABLE} qethereum ethereum evm ethcore secp256k1 gmp ${CRYPTOPP_LS} serpent lll evmface ethential)
if (APPLE)
set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in")
SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS)
# This is a workaround for when the build-type defaults to Debug, and when a multi-config generator like xcode is used, where the type
# will not be set but defaults to release.
set(generator_lowercase "${CMAKE_GENERATOR}")
string(TOLOWER "${CMAKE_GENERATOR}" generator_lowercase)
if ("${generator_lowercase}" STREQUAL "xcode")
# TODO: Not sure how to resolve this. Possibly \${TARGET_BUILD_DIR}
set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}/Debug")
# First have qt5 install plugins and frameworks
add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD
COMMAND /usr/local/opt/qt5/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
# This tool and next will inspect linked libraries in order to determine which dependencies are required
if (${CMAKE_CFG_INTDIR} STREQUAL ".")
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTEABLE}.app")
else ()
set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}")
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTEABLE}.app")
endif ()
set(APPS ${binary_build_dir}/${EXECUTEABLE}.app)
# This tool and the next will automatically looked at the linked libraries in order to determine what dependencies are required. Thus, target_link_libaries only needs to add ethereum and secp256k1 (above)
install(CODE "
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS 1)
fixup_bundle(\"${APPS}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\")
fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\")
" COMPONENT RUNTIME )
add_custom_target(addframeworks ALL
COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTEABLE}.app
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
DEPENDS ${PROJECT_NAME}
)
# Cleanup duplicate libs from macdeployqt
install(CODE "
file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\")
if (LINGER_RM)
file(REMOVE \${LINGER_RM})
endif ()
")
elseif ("${TARGET_PLATFORM}" STREQUAL "w64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms")

93
alethzero/MainWin.cpp

@ -84,10 +84,6 @@ using eth::g_logPost;
using eth::g_logVerbosity;
using eth::c_instructionInfo;
// Horrible global for the mainwindow. Needed for the QEthereums to find the Main window which acts as multiplexer for now.
// Can get rid of this once we've sorted out ITC for signalling & multiplexed querying.
Main* g_main = nullptr;
static void initUnits(QComboBox* _b)
{
for (auto n = (::uint)units().size(); n-- != 0; )
@ -100,24 +96,9 @@ Main::Main(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Main)
{
g_main = this;
setWindowFlags(Qt::Window);
ui->setupUi(this);
g_logPost = [=](std::string const& s, char const* c) { simpleDebugOut(s, c); ui->log->addItem(QString::fromStdString(s)); };
m_client.reset(new Client("AlethZero"));
m_refresh = new QTimer(this);
connect(m_refresh, SIGNAL(timeout()), SLOT(refresh()));
m_refresh->start(100);
m_refreshNetwork = new QTimer(this);
connect(m_refreshNetwork, SIGNAL(timeout()), SLOT(refreshNetwork()));
m_refreshNetwork->start(1000);
m_refreshMining = new QTimer(this);
connect(m_refreshMining, SIGNAL(timeout()), SLOT(refreshMining()));
m_refreshMining->start(200);
connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved()));
#if 0&&ETH_DEBUG
m_servers.append("192.168.0.10:30301");
@ -147,7 +128,6 @@ Main::Main(QWidget *parent) :
cerr << "Network protocol version: " << eth::c_protocolVersion << endl;
ui->configDock->close();
on_verbosity_valueChanged();
initUnits(ui->gasPriceUnits);
initUnits(ui->valueUnits);
@ -160,27 +140,60 @@ Main::Main(QWidget *parent) :
statusBar()->addPermanentWidget(ui->peerCount);
statusBar()->addPermanentWidget(ui->mineStatus);
statusBar()->addPermanentWidget(ui->blockCount);
connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved()));
connect(ui->webView, &QWebView::titleChanged, [=]()
m_client.reset(new Client("AlethZero"));
m_client->start();
connect(ui->webView, &QWebView::loadStarted, [this]()
{
ui->tabWidget->setTabText(0, ui->webView->title());
});
QEthereum *eth = new QEthereum(this, this->m_client.get(), this->owned());
this->m_ethereum = eth;
connect(this, SIGNAL(changed()), this->m_ethereum, SIGNAL(changed()));
QWebFrame* f = this->ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
eth->setup(f);
f->addToJavaScriptWindowObject("env", this, QWebFrame::QtOwnership);
connect(f, &QWebFrame::javaScriptWindowObjectCleared, [f, eth, this]()
{
f->disconnect();
f->addToJavaScriptWindowObject("env", this, QWebFrame::QtOwnership);
f->addToJavaScriptWindowObject("eth", eth, QWebFrame::ScriptOwnership);
f->evaluateJavaScript("eth.watch = function(a, s, f) { eth.changed.connect(f ? f : s) }");
f->evaluateJavaScript("eth.newBlock = function(f) { eth.changed.connect(f) }");
f->evaluateJavaScript("eth.create = function(s, v, c, g, p, f) { var v = eth.doCreate(s, v, c, g, p); if (f) f(v) }");
f->evaluateJavaScript("eth.transact = function(s, v, t, d, g, p, f) { eth.doTransact(s, v, t, d, g, p); if (f) f() }");
f->evaluateJavaScript("eth.transactions = function(a) { return JSON.parse(eth.getTransactions(JSON.stringify(a))); }");
f->evaluateJavaScript("String.prototype.pad = function(l, r) { return eth.pad(this, l, r) }");
f->evaluateJavaScript("String.prototype.bin = function() { return eth.toBinary(this) }");
f->evaluateJavaScript("String.prototype.unbin = function(l) { return eth.fromBinary(this) }");
f->evaluateJavaScript("String.prototype.unpad = function(l) { return eth.unpad(this) }");
f->evaluateJavaScript("String.prototype.dec = function() { return eth.toDecimal(this) }");
f->evaluateJavaScript("String.prototype.sha3 = function() { return eth.sha3(this) }");
});
});
connect(ui->webView, &QWebView::loadFinished, [=]()
{
this->changed();
});
QWebFrame* f = ui->webView->page()->currentFrame();
connect(f, &QWebFrame::javaScriptWindowObjectCleared, [=](){
auto qe = new QEthereum(this, m_client.get(), owned());
qe->setup(f);
f->addToJavaScriptWindowObject("env", this, QWebFrame::QtOwnership);
connect(ui->webView, &QWebView::titleChanged, [=]()
{
ui->tabWidget->setTabText(0, ui->webView->title());
});
readSettings();
refresh();
m_refresh = new QTimer(this);
connect(m_refresh, SIGNAL(timeout()), SLOT(refresh()));
m_refresh->start(100);
{
QSettings s("ethereum", "alethzero");
if (s.value("splashMessage", true).toBool())
@ -618,6 +631,23 @@ void Main::refreshBlockChain()
void Main::refresh(bool _override)
{
// 7/18, Alex: aggregating timers, prelude to better threading?
// Runs much faster on slower dual-core processors
static int interval = 100;
// refresh mining every 200ms
if(interval / 100 % 2 == 0)
refreshMining();
// refresh peer list every 1000ms, reset counter
if(interval == 1000)
{
interval = 0;
refreshNetwork();
} else
interval += 100;
eth::ClientGuard g(m_client.get());
auto const& st = state();
@ -625,7 +655,7 @@ void Main::refresh(bool _override)
if (c || _override)
{
changed();
updateBlockCount();
auto acs = st.addresses();
@ -1189,6 +1219,7 @@ void Main::on_killBlockchain_triggered()
ui->net->setChecked(false);
m_client.reset();
m_client.reset(new Client("AlethZero", Address(), string(), true));
m_client->start();
readSettings();
}

BIN
alethzero/alethzero.icns

Binary file not shown.

1
eth/main.cpp

@ -292,6 +292,7 @@ int main(int argc, char** argv)
if (!clientName.empty())
clientName += "/";
Client c("Ethereum(++)/" + clientName + "v" + eth::EthVersion + "/" ETH_QUOTED(ETH_BUILD_TYPE) "/" ETH_QUOTED(ETH_BUILD_PLATFORM), coinbase, dbPath);
c.start();
cout << credits();
cout << "Address: " << endl << toHex(us.address().asArray()) << endl;

2
libethereum/Client.cpp

@ -63,7 +63,9 @@ Client::Client(std::string const& _clientVersion, Address _us, std::string const
Defaults::setDBPath(_dbPath);
m_vc.setOk();
m_changed = true;
}
void Client::start() {
static const char* c_threadName = "eth";
m_work.reset(new thread([&](){

3
libethereum/Client.h

@ -130,6 +130,9 @@ public:
/// Constructor.
explicit Client(std::string const& _clientVersion, Address _us = Address(), std::string const& _dbPath = std::string(), bool _forceClean = false);
// Start client. Boost require threads are started outside constructor.
void start();
/// Destructor.
~Client();

24
libethereum/PeerServer.cpp

@ -323,25 +323,6 @@ void PeerServer::connect(bi::tcp::endpoint const& _ep)
});
}
bool PeerServer::sync()
{
bool ret = false;
if (isInitialised())
for (auto i = m_peers.begin(); i != m_peers.end();)
{
auto p = i->second.lock();
if (p && p->m_socket.is_open() &&
(p->m_disconnect == chrono::steady_clock::time_point::max() || chrono::steady_clock::now() - p->m_disconnect < chrono::seconds(1))) // kill old peers that should be disconnected.
++i;
else
{
i = m_peers.erase(i);
ret = true;
}
}
return ret;
}
bool PeerServer::ensureInitialised(BlockChain& _bc, TransactionQueue& _tq)
{
if (m_latestBlockSent == h256())
@ -361,10 +342,7 @@ bool PeerServer::ensureInitialised(BlockChain& _bc, TransactionQueue& _tq)
bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, OverlayDB& _o)
{
bool ret = ensureInitialised(_bc, _tq);
if (sync())
ret = true;
if (m_mode == NodeMode::Full)
{
for (auto it = m_incomingTransactions.begin(); it != m_incomingTransactions.end(); ++it)

1
libethereum/PeerServer.h

@ -58,7 +58,6 @@ public:
/// Sync with the BlockChain. It might contain one of our mined blocks, we might have new candidates from the network.
bool sync(BlockChain& _bc, TransactionQueue&, OverlayDB& _o);
bool sync();
/// Conduct I/O, polling, syncing, whatever.
/// Ideally all time-consuming I/O is done in a background thread or otherwise asynchronously, but you get this call every 100ms or so anyway.

117
libethereum/PeerSession.cpp

@ -32,11 +32,12 @@ using namespace eth;
#define clogS(X) eth::LogOutputStream<X, true>(false) << "| " << std::setw(2) << m_socket.native_handle() << "] "
static const eth::uint c_maxHashes = 32; ///< Maximum number of hashes GetChain will ever send.
static const eth::uint c_maxBlocks = 32; ///< Maximum number of blocks Blocks will ever send. BUG: if this gets too big (e.g. 2048) stuff starts going wrong.
static const eth::uint c_maxBlocks = 64; ///< Maximum number of blocks Blocks will ever send. BUG: if this gets too big (e.g. 2048) stuff starts going wrong.
static const eth::uint c_maxBlocksAsk = 256; ///< Maximum number of blocks we ask to receive in Blocks (when using GetChain).
PeerSession::PeerSession(PeerServer* _s, bi::tcp::socket _socket, uint _rNId, bi::address _peerAddress, unsigned short _peerPort):
m_server(_s),
m_strand(_socket.get_io_service()),
m_socket(std::move(_socket)),
m_reqNetworkId(_rNId),
m_listenPort(_peerPort),
@ -49,7 +50,16 @@ PeerSession::PeerSession(PeerServer* _s, bi::tcp::socket _socket, uint _rNId, bi
PeerSession::~PeerSession()
{
m_socket.close();
m_strand.post([=]()
{
if (!m_writeq.empty())
m_writeq.clear();
try {
if (m_socket.is_open())
m_socket.close();
}catch (...){}
});
}
bi::tcp::endpoint PeerSession::endpoint() const
@ -62,8 +72,6 @@ bi::tcp::endpoint PeerSession::endpoint() const
return bi::tcp::endpoint();
}
// TODO: BUG! 256 -> work out why things start to break with big packet sizes -> g.t. ~370 blocks.
bool PeerSession::interpret(RLP const& _r)
{
clogS(NetRight) << _r;
@ -280,21 +288,26 @@ bool PeerSession::interpret(RLP const& _r)
uint parentNumber = 0;
RLPStream s;
if (m_server->m_chain->details(parent))
// try to find parent in our blockchain
// todo: add some delta() fn to blockchain
BlockDetails f_parent = m_server->m_chain->details(parent);
if (f_parent)
{
latestNumber = m_server->m_chain->number(latest);
parentNumber = m_server->m_chain->number(parent);
parentNumber = f_parent.number;
uint count = min<uint>(latestNumber - parentNumber, baseCount);
clogS(NetAllDetail) << "Requires " << dec << (latestNumber - parentNumber) << " blocks from " << latestNumber << " to " << parentNumber;
clogS(NetAllDetail) << latest << " - " << parent;
prep(s);
s.appendList(1 + count) << BlocksPacket;
uint endNumber = m_server->m_chain->number(parent);
uint endNumber = parentNumber;
uint startNumber = endNumber + count;
clogS(NetAllDetail) << "Sending " << dec << count << " blocks from " << startNumber << " to " << endNumber;
// append blocks
uint n = latestNumber;
// seek back (occurs when count is limited by baseCount)
for (; n > startNumber; n--, h = m_server->m_chain->details(h).parent) {}
for (uint i = 0; i < count; ++i, --n, h = m_server->m_chain->details(h).parent)
{
@ -428,19 +441,8 @@ void PeerSession::sendDestroy(bytes& _msg)
cwarn << "INVALID PACKET CONSTRUCTED!";
}
auto self(shared_from_this());
bytes* buffer = new bytes(std::move(_msg));
if (m_socket.is_open())
ba::async_write(m_socket, ba::buffer(*buffer), [self, buffer](boost::system::error_code ec, std::size_t /*length*/)
{
delete buffer;
if (ec)
{
cwarn << "Error sending: " << ec.message();
self->dropped();
}
// cbug << length << " bytes written (EC: " << ec << ")";
});
bytes buffer = bytes(std::move(_msg));
m_strand.post(boost::bind(&PeerSession::writeImpl, this, buffer));
}
void PeerSession::send(bytesConstRef _msg)
@ -452,19 +454,39 @@ void PeerSession::send(bytesConstRef _msg)
cwarn << "INVALID PACKET CONSTRUCTED!";
}
auto self(shared_from_this());
bytes* buffer = new bytes(_msg.toBytes());
bytes buffer = bytes(_msg.toBytes());
m_strand.post(boost::bind(&PeerSession::writeImpl, this, buffer));
}
void PeerSession::writeImpl(bytes& _buffer)
{
m_writeq.push_back(_buffer);
if (m_writeq.size() > 1)
return;
this->write();
}
void PeerSession::write()
{
if (m_writeq.empty())
return;
const bytes& bytes = m_writeq[0];
if (m_socket.is_open())
ba::async_write(m_socket, ba::buffer(*buffer), [self, buffer](boost::system::error_code ec, std::size_t /*length*/)
ba::async_write(m_socket, ba::buffer(bytes), m_strand.wrap([this](boost::system::error_code ec, std::size_t /*length*/)
{
delete buffer;
// must check que, as write callback can occur following dropped()
if (!m_writeq.empty())
this->m_writeq.pop_front();
if (ec)
{
cwarn << "Error sending: " << ec.message();
self->dropped();
}
// cbug << length << " bytes written (EC: " << ec << ")";
});
this->dropped();
} else
m_strand.post(boost::bind(&PeerSession::write, this));
}));
}
void PeerSession::dropped()
@ -474,12 +496,18 @@ void PeerSession::dropped()
clogS(NetNote) << "Closing " << m_socket.remote_endpoint();
m_socket.close();
}catch (...){}
for (auto i = m_server->m_peers.begin(); i != m_server->m_peers.end(); ++i)
if (i->second.lock().get() == this)
{
m_server->m_peers.erase(i);
break;
}
// block future writes by running in strand and clearing queue
m_strand.post([=]()
{
m_writeq.clear();
for (auto i = m_server->m_peers.begin(); i != m_server->m_peers.end(); ++i)
if (i->second.lock().get() == this)
{
m_server->m_peers.erase(i);
break;
}
});
}
void PeerSession::disconnect(int _reason)
@ -514,14 +542,24 @@ void PeerSession::start()
void PeerSession::doRead()
{
// ignore packets received while waiting to disconnect
if (chrono::steady_clock::now() - m_disconnect > chrono::seconds(0))
return;
auto self(shared_from_this());
m_socket.async_read_some(boost::asio::buffer(m_data), [this,self](boost::system::error_code ec, std::size_t length)
{
if (ec)
// If error is end of file, ignore
if (ec && ec.category() != boost::asio::error::get_misc_category() && ec.value() != boost::asio::error::eof)
{
// got here with length of 1241...
cwarn << "Error reading: " << ec.message();
dropped();
}
else if(ec && length == 0)
{
return;
}
else
{
try
@ -532,12 +570,8 @@ void PeerSession::doRead()
{
if (m_incoming[0] != 0x22 || m_incoming[1] != 0x40 || m_incoming[2] != 0x08 || m_incoming[3] != 0x91)
{
clogS(NetWarn) << "Out of alignment.";
disconnect(BadProtocol);
return;
clogS(NetNote) << "Skipping: " << hex << showbase << (int)m_incoming[0] << dec;
memmove(m_incoming.data(), m_incoming.data() + 1, m_incoming.size() - 1);
m_incoming.resize(m_incoming.size() - 1);
doRead();
}
else
{
@ -547,7 +581,6 @@ void PeerSession::doRead()
break;
// enough has come in.
// cerr << "Received " << len << ": " << toHex(bytesConstRef(m_incoming.data() + 8, len)) << endl;
auto data = bytesConstRef(m_incoming.data(), tlen);
if (!checkPacket(data))
{

4
libethereum/PeerSession.h

@ -62,7 +62,11 @@ private:
void sealAndSend(RLPStream& _s);
void sendDestroy(bytes& _msg);
void send(bytesConstRef _msg);
void writeImpl(bytes& _buffer);
void write();
PeerServer* m_server;
boost::asio::strand m_strand;
std::deque<bytes> m_writeq;
bi::tcp::socket m_socket;
std::array<byte, 65536> m_data;

11
libqethereum/CMakeLists.txt

@ -79,18 +79,11 @@ if (APPLE)
set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}")
endif ()
set(APPS ${binary_build_dir}/${EXECUTABLE}.app)
# This tool and the next will automatically looked at the linked libraries in order to determine what dependencies are required. Thus, target_link_libaries only needs to add ethereum and secp256k1 (above)
install(CODE "
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS 1)
fixup_bundle(\"${APPS}\" \"${BUNDLELIBS}\" \"../libethereum ../secp256k1\")
" COMPONENT RUNTIME )
set(APPS ${binary_build_dir}/${EXECUTABLE})
if (${ADDFRAMEWORKS})
add_custom_target(addframeworks ALL
COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTABLE}.app
COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTABLE}
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
DEPENDS ${PROJECT_NAME}
)

33
libqethereum/QEthereum.cpp

@ -233,44 +233,17 @@ QString unpadded(QString _s)
QEthereum::QEthereum(QObject* _p, Client* _c, QList<eth::KeyPair> _accounts): QObject(_p), m_client(_c), m_accounts(_accounts)
{
connect(_p, SIGNAL(changed()), SIGNAL(changed()));
// required to prevent crash on osx when performing addto/evaluatejavascript calls
this->moveToThread(_p->thread());
}
QEthereum::~QEthereum()
{
}
void QEthereum::setAccounts(QList<eth::KeyPair> _l)
{
cnote << "WAS:";
for (auto i: m_accounts)
cnote << i.sec();
cnote << "NOW:";
for (auto i: _l)
cnote << i.sec();
m_accounts = _l;
changed();
}
void QEthereum::setup(QWebFrame* _e)
{
// disconnect
disconnect(SIGNAL(changed()));
_e->addToJavaScriptWindowObject("eth", this, QWebFrame::ScriptOwnership);
/* _e->addToJavaScriptWindowObject("u256", new U256Helper, QWebFrame::ScriptOwnership);
_e->addToJavaScriptWindowObject("key", new KeyHelper, QWebFrame::ScriptOwnership);
_e->addToJavaScriptWindowObject("bytes", new BytesHelper, QWebFrame::ScriptOwnership);*/
_e->evaluateJavaScript("eth.newBlock = function(f) { eth.changed.connect(f) }");
_e->evaluateJavaScript("eth.watch = function(a, s, f) { eth.changed.connect(f ? f : s) }");
_e->evaluateJavaScript("eth.create = function(s, v, c, g, p, f) { var v = eth.doCreate(s, v, c, g, p); if (f) f(v) }");
_e->evaluateJavaScript("eth.transact = function(s, v, t, d, g, p, f) { eth.doTransact(s, v, t, d, g, p); if (f) f() }");
_e->evaluateJavaScript("eth.transactions = function(a) { return JSON.parse(eth.getTransactions(JSON.stringify(a))); }");
_e->evaluateJavaScript("String.prototype.pad = function(l, r) { return eth.pad(this, l, r) }");
_e->evaluateJavaScript("String.prototype.bin = function() { return eth.toBinary(this) }");
_e->evaluateJavaScript("String.prototype.unbin = function(l) { return eth.fromBinary(this) }");
_e->evaluateJavaScript("String.prototype.unpad = function(l) { return eth.unpad(this) }");
_e->evaluateJavaScript("String.prototype.dec = function() { return eth.toDecimal(this) }");
_e->evaluateJavaScript("String.prototype.sha3 = function() { return eth.sha3(this) }");
// Alex: JS codes moved to mainwin until qtwebkit bugs are resolved (#245)
}
void QEthereum::teardown(QWebFrame*)

2
libqethereum/QEthereum.h

@ -376,7 +376,7 @@ public:
void setup(QWebFrame* _e);
void teardown(QWebFrame* _e);
void setAccounts(QList<eth::KeyPair> _l);
void setAccounts(QList<eth::KeyPair> _l) { m_accounts = _l; this->changed(); }
Q_INVOKABLE QString ethTest() const { return "Hello world!"; }
Q_INVOKABLE QEthereum* self() { return this; }

9
secp256k1/CMakeLists.txt

@ -5,7 +5,6 @@ set(CMAKE_ASM_COMPILER "yasm")
set(EXECUTABLE secp256k1)
file(GLOB HEADERS "*.h")
#aux_source_directory(. SRC_LIST)
if ("${TARGET_PLATFORM}" STREQUAL "w64")
add_custom_command(
@ -23,10 +22,10 @@ if ("${TARGET_PLATFORM}" STREQUAL "w64")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -DUSE_FIELD_5X52 -DUSE_FIELD_5X52_ASM -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM")
elseif(APPLE)
# set(CMAKE_INSTALL_PREFIX ../lib)
if(ETH_STATIC)
add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c field_5x52_asm.asm)
else()
find_library(GMP_LS gmp /usr/local/lib)
add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c field_5x52_asm.asm)
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DUSE_FIELD_GMP -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM")
@ -39,7 +38,11 @@ else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DUSE_FIELD_GMP -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM")
endif()
target_link_libraries(${EXECUTABLE} gmp)
if (NOT GMP_LS)
set(GMP_LS gmp)
endif ()
target_link_libraries(${EXECUTABLE} ${GMP_LS})
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

2
test/peer.cpp

@ -57,7 +57,7 @@ int peerTest(int argc, char** argv)
for (int i = 0; ; ++i)
{
this_thread::sleep_for(chrono::milliseconds(100));
pn.sync();
// pn.sync();
if (!(i % 10))
pn.pingAll();
}

38
walleth/EthereumMacOSXBundleInfo.plist.in

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSRequiresCarbon</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

3
walleth/MainWin.cpp

@ -63,7 +63,8 @@ Main::Main(QWidget *parent) :
g_qmlMain = this;
m_client.reset(new Client("Walleth", Address(), eth::getDataDir() + "/Walleth"));
m_client->start();
g_qmlClient = m_client.get();
qRegisterMetaType<eth::u256>("eth::u256");

Loading…
Cancel
Save