CJentzsch
10 years ago
429 changed files with 17969 additions and 9217 deletions
@ -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(); |
|||
} |
@ -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; |
|||
}; |
@ -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>&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>&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>&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>&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>&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>&Close</string> |
|||
</property> |
|||
<property name="shortcut"> |
|||
<string>Esc</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections/> |
|||
</ui> |
@ -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; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
@ -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") |
@ -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"] |
|||
|
@ -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 |
|||
|
@ -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 |
@ -1,4 +1,4 @@ |
|||
[ |
|||
{ "name": "eth_getWork", "params": [], "order": [], "returns": []}, |
|||
{ "name": "eth_submitWork", "params": ["", ""], "order": [], "returns": true} |
|||
{ "name": "eth_submitWork", "params": ["", "", ""], "order": [], "returns": true} |
|||
] |
|||
|
@ -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() |
|||
|
@ -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_
|
@ -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_
|
@ -0,0 +1,4 @@ |
|||
[ |
|||
{ "name": "eth_getWork", "params": [], "order": [], "returns": []}, |
|||
{ "name": "eth_submitWork", "params": ["", "", ""], "order": [], "returns": true} |
|||
] |
@ -0,0 +1,483 @@ |
|||
/*
|
|||
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(); |
|||
cout << "min/mean/max: " << results.begin()->second.rate() << "/" << (mean / _trials) << "/" << results.rbegin()->second.rate() << " H/s" << endl; |
|||
cout << "inner mean: " << (innerMean / (_trials - 2)) << " 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; |
|||
} |
|||
|
@ -0,0 +1,3 @@ |
|||
[ |
|||
{ "name": "report_benchmark", "params": [ "", 0 ], "order": [], "returns": 0 } |
|||
] |
@ -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 |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,158 @@ |
|||
/*
|
|||
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 ICAP.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "ICAP.h" |
|||
#include <boost/algorithm/string/case_conv.hpp> |
|||
#include <boost/algorithm/string.hpp> |
|||
#include <libdevcore/Base64.h> |
|||
#include <libdevcrypto/SHA3.h> |
|||
#include "Exceptions.h" |
|||
#include "ABI.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
|
|||
string ICAP::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(); |
|||
} |
|||
|
|||
std::pair<string, string> ICAP::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); |
|||
} |
|||
|
|||
ICAP ICAP::decoded(std::string const& _encoded) |
|||
{ |
|||
ICAP ret; |
|||
std::string country; |
|||
std::string data; |
|||
std::tie(country, data) = fromIBAN(_encoded); |
|||
if (country != "XE") |
|||
throw InvalidICAP(); |
|||
if (data.size() == 30) |
|||
{ |
|||
ret.m_type = Direct; |
|||
// Direct ICAP
|
|||
ret.m_direct = fromBase36<Address::size>(data); |
|||
} |
|||
else if (data.size() == 16) |
|||
{ |
|||
ret.m_type = Indirect; |
|||
ret.m_asset = data.substr(0, 3); |
|||
if (ret.m_asset == "XET" || ret.m_asset == "ETH") |
|||
{ |
|||
ret.m_institution = data.substr(3, 4); |
|||
ret.m_client = data.substr(7); |
|||
} |
|||
else |
|||
throw InvalidICAP(); |
|||
} |
|||
else |
|||
throw InvalidICAP(); |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
std::string ICAP::encoded() const |
|||
{ |
|||
if (m_type == Direct) |
|||
{ |
|||
if (!!m_direct[0]) |
|||
throw InvalidICAP(); |
|||
std::string d = toBase36<Address::size>(m_direct); |
|||
while (d.size() < 30) |
|||
d = "0" + d; |
|||
return iban("XE", d); |
|||
} |
|||
else if (m_type == Indirect) |
|||
{ |
|||
if ( |
|||
m_asset.find_first_not_of("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890") != string::npos || |
|||
m_institution.find_first_not_of("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890") != string::npos || |
|||
m_client.find_first_not_of("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890") != string::npos || |
|||
m_asset.size() != 3 || |
|||
(boost::to_upper_copy(m_asset) != "XET" && boost::to_upper_copy(m_asset) != "ETH") || |
|||
m_institution.size() != 4 || |
|||
m_client.size() != 9 |
|||
) |
|||
throw InvalidICAP(); |
|||
return iban("XE", m_asset + m_institution + m_client); |
|||
} |
|||
else |
|||
throw InvalidICAP(); |
|||
} |
|||
|
|||
pair<Address, bytes> ICAP::lookup(std::function<bytes(Address, bytes)> const& _call, Address const& _reg) const |
|||
{ |
|||
auto resolve = [&](string const& s) |
|||
{ |
|||
vector<string> ss; |
|||
boost::algorithm::split(ss, s, boost::is_any_of("/")); |
|||
Address r = _reg; |
|||
for (unsigned i = 0; i < ss.size() - 1; ++i) |
|||
r = abiOut<Address>(_call(r, abiIn("subRegistrar(bytes32)", toString32(ss[i])))); |
|||
return abiOut<Address>(_call(r, abiIn("addr(bytes32)", toString32(ss.back())))); |
|||
}; |
|||
if (m_asset == "XET") |
|||
{ |
|||
Address a = resolve(m_institution); |
|||
bytes d = abiIn("deposit(uint64)", fromBase36<8>(m_client)); |
|||
return make_pair(a, d); |
|||
} |
|||
else if (m_asset == "ETH") |
|||
{ |
|||
if (m_institution == "XREG") |
|||
return make_pair(resolve(m_client), bytes()); |
|||
else if (m_institution[0] != 'X') |
|||
return make_pair(resolve(m_institution + "/" + m_client), bytes()); |
|||
else |
|||
throw InterfaceNotSupported("ICAP::lookup(), bad institution"); |
|||
} |
|||
throw InterfaceNotSupported("ICAP::lookup(), bad asset"); |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,105 @@ |
|||
/*
|
|||
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 ICAP.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* |
|||
* Ethereum-specific data structures & algorithms. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <functional> |
|||
#include <boost/algorithm/string/case_conv.hpp> |
|||
#include <libdevcore/Common.h> |
|||
#include <libdevcore/Exceptions.h> |
|||
#include <libdevcore/FixedHash.h> |
|||
#include "Common.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
|
|||
struct InvalidICAP: virtual public dev::Exception {}; |
|||
|
|||
static const std::string EmptyString; |
|||
|
|||
/**
|
|||
* @brief Encapsulation of an ICAP address. |
|||
* Can be encoded, decoded, looked-up and inspected. |
|||
*/ |
|||
class ICAP |
|||
{ |
|||
public: |
|||
/// Construct null ICAP object.
|
|||
ICAP() = default; |
|||
/// Construct a direct ICAP object for given target address. Must have a zero first byte.
|
|||
ICAP(Address const& _target): m_type(Direct), m_direct(_target) {} |
|||
/// Construct an indirect ICAP object for given client and institution names.
|
|||
ICAP(std::string const& _client, std::string const& _inst): m_type(Indirect), m_client(boost::algorithm::to_upper_copy(_client)), m_institution(boost::algorithm::to_upper_copy(_inst)), m_asset("XET") {} |
|||
/// Construct an indirect ICAP object for given client, institution and asset names. You generally don't want to use this.
|
|||
ICAP(std::string const& _c, std::string const& _i, std::string const& _a): m_type(Indirect), m_client(boost::algorithm::to_upper_copy(_c)), m_institution(boost::algorithm::to_upper_copy(_i)), m_asset(boost::algorithm::to_upper_copy(_a)) {} |
|||
|
|||
/// Type of ICAP address.
|
|||
enum Type |
|||
{ |
|||
Invalid, |
|||
Direct, |
|||
Indirect |
|||
}; |
|||
|
|||
/// @returns IBAN encoding of client and data.
|
|||
static std::string iban(std::string _c, std::string _d); |
|||
/// @returns Client and data from given IBAN address.
|
|||
static std::pair<std::string, std::string> fromIBAN(std::string _iban); |
|||
|
|||
/// @returns the ICAP object for the ICAP address given.
|
|||
static ICAP decoded(std::string const& _encoded); |
|||
|
|||
/// @returns the encoded ICAP address.
|
|||
std::string encoded() const; |
|||
/// @returns type of ICAP.
|
|||
Type type() const { return m_type; } |
|||
/// @returns target address. Only valid when type() == Direct.
|
|||
Address const& direct() const { return m_type == Direct ? m_direct : ZeroAddress; } |
|||
/// @returns asset. Only valid when type() == Indirect.
|
|||
std::string const& asset() const { return m_type == Indirect ? m_asset : EmptyString; } |
|||
/// @returns target name. Only valid when type() == Indirect and asset() == "ETH".
|
|||
std::string const& target() const { return m_type == Indirect && m_asset == "ETH" ? m_client : EmptyString; } |
|||
/// @returns institution name. Only valid when type() == Indirect and asset() == "XET".
|
|||
std::string const& institution() const { return m_type == Indirect && m_asset == "XET" ? m_institution : EmptyString; } |
|||
/// @returns client name. Only valid when type() == Indirect and asset() == "XET".
|
|||
std::string const& client() const { return m_type == Indirect && m_asset == "XET" ? m_client : EmptyString; } |
|||
/// @returns target address. Always valid, but requires the Registry address and a function to make calls.
|
|||
std::pair<Address, bytes> address(std::function<bytes(Address, bytes)> const& _call, Address const& _reg) const { return m_type == Direct ? make_pair(direct(), bytes()) : m_type == Indirect ? lookup(_call, _reg) : make_pair(Address(), bytes()); } |
|||
|
|||
/// @returns target address. Looks up through the given Registry and call function. Only valid when type() == Indirect.
|
|||
std::pair<Address, bytes> lookup(std::function<bytes(Address, bytes)> const& _call, Address const& _reg) const; |
|||
|
|||
private: |
|||
Type m_type = Invalid; |
|||
Address m_direct; |
|||
std::string m_client; |
|||
std::string m_institution; |
|||
std::string m_asset; |
|||
}; |
|||
|
|||
|
|||
} |
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue