diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt
index 73061b38a..e4dfabc5f 100644
--- a/alethzero/CMakeLists.txt
+++ b/alethzero/CMakeLists.txt
@@ -14,6 +14,15 @@ endif ()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(. SRC_LIST)
+file(GLOB_RECURSE SRC_LIST "./plugins/*.cpp")
+file(GLOB_RECURSE HEADERS "./plugins/*.h")
+aux_source_directory(. SRC_LIST)
+
+file(GLOB_RECURSE PLUGIN_UI RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/plugins/*.ui")
+foreach(ITEM ${PLUGIN_UI})
+ get_filename_component(UI_NAME ${ITEM} NAME_WE)
+ qt5_wrap_ui(ui_${UI_NAME}.h ./${ITEM})
+endforeach()
include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
include_directories(BEFORE ..)
@@ -39,10 +48,6 @@ qt5_wrap_ui(ui_GasPricing.h GasPricing.ui)
# Extensions
qt5_wrap_ui(ui_AllAccounts.h AllAccounts.ui)
-qt5_wrap_ui(ui_LogPanel.h LogPanel.ui)
-qt5_wrap_ui(ui_BrainWallet.h BrainWallet.ui)
-qt5_wrap_ui(ui_OtherAccounts.h OtherAccounts.ui)
-qt5_wrap_ui(ui_NewAccount.h NewAccount.ui)
file(GLOB HEADERS "*.h")
@@ -55,19 +60,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
- ExportState.ui
- GetPassword.ui
- GasPricing.ui
- AllAccounts.ui
- LogPanel.ui
- BrainWallet.ui
- OtherAccounts.ui
- NewAccount.ui
+ UI_RESOURCES ${PLUGIN_UI} alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui ExportState.ui GetPassword.ui GasPricing.ui
WIN_RESOURCES alethzero.rc
)
diff --git a/alethzero/Main.ui b/alethzero/Main.ui
index 69846f34c..52e973fe8 100644
--- a/alethzero/Main.ui
+++ b/alethzero/Main.ui
@@ -209,12 +209,6 @@
-
-
-
- QDockWidget::DockWidgetFeatureMask
-
-
- Whisper
-
-
- 1
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Data
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Work to Prove
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- QFrame::NoFrame
-
-
- 0
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- QFrame::NoFrame
-
-
- 0
-
-
-
- -
-
-
- false
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Topic
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- To
-
-
-
- -
-
-
- true
-
-
-
- -
-
-
- seconds
-
-
- 5
-
-
- 259200
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- TTL
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- From
-
-
-
- -
-
-
- ms
-
-
- 1
-
-
- 1000
-
-
- 50
-
-
-
- -
-
-
- Post
-
-
-
-
-
-
-
-
- QDockWidget::DockWidgetFeatureMask
-
-
- Active Whispers
-
-
- 2
-
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
- -
-
-
- QFrame::NoFrame
-
-
-
-
-
-
&Quit
@@ -1635,13 +1410,6 @@ font-size: 14pt
- shhTo
- shhFrom
- shhTtl
- shhTopic
- shhWork
- shhData
- post
tabWidget
urlEdit
listenIP
@@ -1651,7 +1419,6 @@ font-size: 14pt
blockChainFilter
nameReg
nodes
- whispers
jsInput
diff --git a/alethzero/MainFace.cpp b/alethzero/MainFace.cpp
index 5c9651f73..9382fdf26 100644
--- a/alethzero/MainFace.cpp
+++ b/alethzero/MainFace.cpp
@@ -58,6 +58,7 @@ QDockWidget* Plugin::dock(Qt::DockWidgetArea _area, QString _title)
if (!m_dock)
{
m_dock = new QDockWidget(_title, m_main);
+ m_dock->setObjectName(_title);
m_main->addDockWidget(_area, m_dock);
m_dock->setFeatures(QDockWidget::AllDockWidgetFeatures | QDockWidget::DockWidgetVerticalTitleBar);
}
diff --git a/alethzero/MainFace.h b/alethzero/MainFace.h
index 525cc312d..2c25b0584 100644
--- a/alethzero/MainFace.h
+++ b/alethzero/MainFace.h
@@ -49,6 +49,7 @@ namespace az
class Plugin;
class MainFace;
class Main;
+class OurWebThreeStubServer;
using WatchHandler = std::function;
@@ -89,10 +90,12 @@ public:
// TODO: provide a set of available web3 modules.
virtual dev::WebThreeDirect* web3() const = 0;
virtual dev::eth::Client* ethereum() const = 0;
+ virtual OurWebThreeStubServer* web3Server() const = 0;
virtual std::shared_ptr whisper() const = 0;
virtual unsigned installWatch(dev::eth::LogFilter const& _tf, WatchHandler const& _f) = 0;
virtual unsigned installWatch(dev::h256 const& _tf, WatchHandler const& _f) = 0;
+ virtual void uninstallWatch(unsigned _id) = 0;
// Account naming API
virtual void install(AccountNamer* _adopt) = 0;
diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp
index 60455969a..1fb84dddc 100644
--- a/alethzero/MainWin.cpp
+++ b/alethzero/MainWin.cpp
@@ -94,8 +94,8 @@ QString dev::az::contentsOfQResource(string const& res)
}
//Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f");
-Address c_newConfig = Address("c6d9d2cd449a754c494264e1809c50e34d64562b");
-//Address c_nameReg = Address("ddd1cea741d548f90d86fb87a3ae6492e18c03a1");
+//Address c_newConfig = Address("c6d9d2cd449a754c494264e1809c50e34d64562b");
+Address c_nameReg = Address("96d76ae3397b52d9f61215270df65d72358709e3");
Main::Main(QWidget* _parent):
MainFace(_parent),
@@ -197,8 +197,6 @@ Main::Main(QWidget* _parent):
auto w3ss = new OurWebThreeStubServer(*m_httpConnector, this);
m_server.reset(w3ss);
auto sessionKey = w3ss->newSession(SessionPermissions{{Privilege::Admin}});
- connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString)));
- m_server->setIdentities(keysAsVector(owned()));
m_server->StartListening();
WebPage* webPage = new WebPage(this);
@@ -387,29 +385,6 @@ void Main::on_sentinel_triggered()
ethereum()->setSentinel(sentinel.toStdString());
}
-void Main::on_newIdentity_triggered()
-{
- KeyPair kp = KeyPair::create();
- m_myIdentities.append(kp);
- m_server->setIdentities(keysAsVector(owned()));
- refreshWhisper();
-}
-
-void Main::refreshWhisper()
-{
- ui->shhFrom->clear();
- for (auto i: m_server->ids())
- ui->shhFrom->addItem(QString::fromStdString(toHex(i.first.ref())));
-}
-
-void Main::addNewId(QString _ids)
-{
- KeyPair kp(jsToSecret(_ids.toStdString()));
- m_myIdentities.push_back(kp);
- m_server->setIdentities(keysAsVector(owned()));
- refreshWhisper();
-}
-
NetworkPreferences Main::netPrefs() const
{
auto listenIP = ui->listenIP->text().toStdString();
@@ -486,8 +461,8 @@ void Main::installWatches()
cdebug << "newBlock watch ID: " << newBlockId;
cdebug << "newPending watch ID: " << newPendingId;
- installWatch(LogFilter().address(c_newConfig), [=](LocalisedLogEntries const&) { installNameRegWatch(); });
- installWatch(LogFilter().address(c_newConfig), [=](LocalisedLogEntries const&) { installCurrenciesWatch(); });
+// installWatch(LogFilter().address(c_newConfig), [=](LocalisedLogEntries const&) { installNameRegWatch(); });
+// installWatch(LogFilter().address(c_newConfig), [=](LocalisedLogEntries const&) { installCurrenciesWatch(); });
}
Address Main::getNameReg() const
@@ -498,7 +473,8 @@ Address Main::getNameReg() const
Address Main::getCurrencies() const
{
- return abiOut(ethereum()->call(c_newConfig, abiIn("lookup(uint256)", (u256)3)).output);
+// return abiOut(ethereum()->call(c_newConfig, abiIn("lookup(uint256)", (u256)3)).output);
+ return Address();
}
bool Main::doConfirm()
@@ -665,17 +641,6 @@ void Main::addConsoleMessage(QString const& _js, QString const& _s)
ui->jsConsole->setHtml(r);
}
-static Public stringToPublic(QString const& _a)
-{
- string sn = _a.toStdString();
- if (_a.size() == sizeof(Public) * 2)
- return Public(fromHex(_a.toStdString()));
- else if (_a.size() == sizeof(Public) * 2 + 2 && _a.startsWith("0x"))
- return Public(fromHex(_a.mid(2).toStdString()));
- else
- return Public();
-}
-
std::string Main::pretty(dev::Address const& _a) const
{
auto g_newNameReg = getNameReg();
@@ -806,17 +771,6 @@ void Main::writeSettings()
{
QSettings s("ethereum", "alethzero");
s.remove("address");
- {
- QByteArray b;
- b.resize(sizeof(Secret) * m_myIdentities.size());
- auto p = b.data();
- for (auto i: m_myIdentities)
- {
- memcpy(p, &(i.secret()), sizeof(Secret));
- p += sizeof(Secret);
- }
- s.setValue("identities", b);
- }
forEach([&](std::shared_ptr p)
{
@@ -904,27 +858,12 @@ void Main::readSettings(bool _skipGeometry)
restoreGeometry(s.value("geometry").toByteArray());
restoreState(s.value("windowState").toByteArray());
- {
- m_myIdentities.clear();
- QByteArray b = s.value("identities").toByteArray();
- if (!b.isEmpty())
- {
- Secret k;
- for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i)
- {
- memcpy(k.writable().data(), b.data() + i * sizeof(Secret), sizeof(Secret));
- if (!count(m_myIdentities.begin(), m_myIdentities.end(), KeyPair(k)))
- m_myIdentities.append(KeyPair(k));
- }
- }
- }
-
forEach([&](std::shared_ptr p)
{
p->readSettings(s);
});
- static_cast(ethereum()->gasPricer().get())->setAsk(u256(s.value("askPrice", QString::fromStdString(toString(c_defaultGasPrice))).toString().toStdString()));
- static_cast(ethereum()->gasPricer().get())->setBid(u256(s.value("bidPrice", QString::fromStdString(toString(c_defaultGasPrice))).toString().toStdString()));
+ static_cast(ethereum()->gasPricer().get())->setAsk(u256(s.value("askPrice", QString::fromStdString(toString(DefaultGasPrice))).toString().toStdString()));
+ static_cast(ethereum()->gasPricer().get())->setBid(u256(s.value("bidPrice", QString::fromStdString(toString(DefaultGasPrice))).toString().toStdString()));
ui->upnp->setChecked(s.value("upnp", true).toBool());
ui->forcePublicIP->setText(s.value("forceAddress", "").toString());
@@ -1522,7 +1461,6 @@ void Main::timerEvent(QTimerEvent*)
{
interval = 0;
refreshNetwork();
- refreshWhispers();
refreshCache();
refreshBlockCount();
poll();
@@ -1952,60 +1890,6 @@ void Main::on_ourAccounts_doubleClicked()
m_logHistory.clear();
}*/
-static shh::Topics topicFromText(QString _s)
-{
- shh::BuildTopic ret;
- while (_s.size())
- {
- QRegExp r("(@|\\$)?\"([^\"]*)\"(\\s.*)?");
- QRegExp d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?");
- QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?");
- bytes part;
- if (r.exactMatch(_s))
- {
- for (auto i: r.cap(2))
- part.push_back((byte)i.toLatin1());
- if (r.cap(1) != "$")
- for (int i = r.cap(2).size(); i < 32; ++i)
- part.push_back(0);
- else
- part.push_back(0);
- _s = r.cap(3);
- }
- else if (d.exactMatch(_s))
- {
- u256 v(d.cap(2).toStdString());
- if (d.cap(6) == "szabo")
- v *= szabo;
- else if (d.cap(5) == "finney")
- v *= finney;
- else if (d.cap(4) == "ether")
- v *= ether;
- bytes bs = dev::toCompactBigEndian(v);
- if (d.cap(1) != "$")
- for (auto i = bs.size(); i < 32; ++i)
- part.push_back(0);
- for (auto b: bs)
- part.push_back(b);
- _s = d.cap(7);
- }
- else if (h.exactMatch(_s))
- {
- bytes bs = fromHex((((h.cap(3).size() & 1) ? "0" : "") + h.cap(3)).toStdString());
- if (h.cap(1) != "$")
- for (auto i = bs.size(); i < 32; ++i)
- part.push_back(0);
- for (auto b: bs)
- part.push_back(b);
- _s = h.cap(5);
- }
- else
- _s = _s.mid(1);
- ret.shift(part);
- }
- return ret;
-}
-
void Main::on_clearPending_triggered()
{
writeSettings();
@@ -2215,19 +2099,6 @@ std::string Main::prettyU256(dev::u256 const& _n) const
return s.str();
}
-void Main::on_post_clicked()
-{
- return;
- shh::Message m;
- m.setTo(stringToPublic(ui->shhTo->currentText()));
- m.setPayload(parseData(ui->shhData->toPlainText().toStdString()));
- Public f = stringToPublic(ui->shhFrom->currentText());
- Secret from;
- if (m_server->ids().count(f))
- from = m_server->ids().at(f);
- whisper()->inject(m.seal(from, topicFromText(ui->shhTopic->toPlainText()), ui->shhTtl->value(), ui->shhWork->value()));
-}
-
int Main::authenticate(QString _title, QString _text)
{
QMessageBox userInput(this);
@@ -2240,36 +2111,6 @@ int Main::authenticate(QString _title, QString _text)
return userInput.exec();
}
-void Main::refreshWhispers()
-{
- return;
- ui->whispers->clear();
- for (auto const& w: whisper()->all())
- {
- shh::Envelope const& e = w.second;
- shh::Message m;
- for (pair const& i: m_server->ids())
- if (!!(m = e.open(shh::Topics(), i.second)))
- break;
- if (!m)
- m = e.open(shh::Topics());
-
- QString msg;
- if (m.from())
- // Good message.
- msg = QString("{%1 -> %2} %3").arg(m.from() ? m.from().abridged().c_str() : "???").arg(m.to() ? m.to().abridged().c_str() : "*").arg(toHex(m.payload()).c_str());
- else if (m)
- // Maybe message.
- msg = QString("{%1 -> %2} %3 (?)").arg(m.from() ? m.from().abridged().c_str() : "???").arg(m.to() ? m.to().abridged().c_str() : "*").arg(toHex(m.payload()).c_str());
-
- time_t ex = e.expiry();
- QString t(ctime(&ex));
- t.chop(1);
- QString item = QString("[%1 - %2s] *%3 %5 %4").arg(t).arg(e.ttl()).arg(e.workProved()).arg(toString(e.topic()).c_str()).arg(msg);
- ui->whispers->addItem(item);
- }
-}
-
void Main::dappLoaded(Dapp& _dapp)
{
QUrl url = m_dappHost->hostDapp(std::move(_dapp));
diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h
index c110f54e8..db9298704 100644
--- a/alethzero/MainWin.h
+++ b/alethzero/MainWin.h
@@ -84,6 +84,7 @@ public:
~Main();
WebThreeDirect* web3() const override { return m_webThree.get(); }
+ OurWebThreeStubServer* web3Server() const override { return m_server.get(); }
eth::Client* ethereum() const override { return m_webThree->ethereum(); }
std::shared_ptr whisper() const override { return m_webThree->whisper(); }
@@ -96,8 +97,6 @@ public:
std::pair fromString(std::string const& _a) const override;
std::string renderDiff(eth::StateDiff const& _d) const override;
- QList owned() const { return m_myIdentities; }
-
u256 gasPrice() const override;
eth::KeyManager& keyManager() override { return m_keyManager; }
@@ -198,17 +197,11 @@ private slots:
void on_debugDumpStatePre_triggered() { debugDumpState(0); }
void on_dumpBlockState_triggered();
- // Whisper
- void on_newIdentity_triggered();
- void on_post_clicked();
-
// Config
void on_gasPrices_triggered();
void on_sentinel_triggered();
- void refreshWhisper();
void refreshBlockChain();
- void addNewId(QString _ids);
// Dapps
void dappLoaded(Dapp& _dapp); //qt does not support rvalue refs for signals
@@ -239,7 +232,7 @@ private:
unsigned installWatch(eth::LogFilter const& _tf, WatchHandler const& _f) override;
unsigned installWatch(h256 const& _tf, WatchHandler const& _f) override;
- void uninstallWatch(unsigned _w);
+ void uninstallWatch(unsigned _w) override;
void keysChanged();
@@ -258,7 +251,6 @@ private:
void refreshNetwork();
void refreshMining();
- void refreshWhispers();
void refreshCache();
void refreshAll();
@@ -280,7 +272,6 @@ private:
QByteArray m_networkConfig;
QStringList m_servers;
- QList m_myIdentities;
eth::KeyManager m_keyManager;
QString m_privateChain;
dev::Address m_nameReg;
diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp
index 0eea40c2c..1015e565c 100644
--- a/alethzero/OurWebThreeStubServer.cpp
+++ b/alethzero/OurWebThreeStubServer.cpp
@@ -34,7 +34,7 @@ OurWebThreeStubServer::OurWebThreeStubServer(
jsonrpc::AbstractServerConnector& _conn,
Main* _main
):
- WebThreeStubServer(_conn, *_main->web3(), make_shared(_main), _main->owned().toVector().toStdVector(), _main->keyManager(), *static_cast(_main->ethereum()->gasPricer().get())),
+ WebThreeStubServer(_conn, *_main->web3(), make_shared(_main), vector{}, _main->keyManager(), *static_cast(_main->ethereum()->gasPricer().get())),
m_main(_main)
{
}
diff --git a/alethzero/Transact.h b/alethzero/Transact.h
index 60d4a3c2e..015e9d3cc 100644
--- a/alethzero/Transact.h
+++ b/alethzero/Transact.h
@@ -105,6 +105,8 @@ private:
MainFace* m_main = nullptr;
NatSpecFace* m_natSpecDB = nullptr;
bool m_allGood = false;
+
+ bool m_determiningGas = false;
};
}
diff --git a/alethzero/AllAccounts.cpp b/alethzero/plugins/blockchain/AllAccounts.cpp
similarity index 100%
rename from alethzero/AllAccounts.cpp
rename to alethzero/plugins/blockchain/AllAccounts.cpp
diff --git a/alethzero/AllAccounts.h b/alethzero/plugins/blockchain/AllAccounts.h
similarity index 100%
rename from alethzero/AllAccounts.h
rename to alethzero/plugins/blockchain/AllAccounts.h
diff --git a/alethzero/AllAccounts.ui b/alethzero/plugins/blockchain/AllAccounts.ui
similarity index 100%
rename from alethzero/AllAccounts.ui
rename to alethzero/plugins/blockchain/AllAccounts.ui
diff --git a/alethzero/BrainWallet.cpp b/alethzero/plugins/brainwallet/BrainWallet.cpp
similarity index 100%
rename from alethzero/BrainWallet.cpp
rename to alethzero/plugins/brainwallet/BrainWallet.cpp
diff --git a/alethzero/BrainWallet.h b/alethzero/plugins/brainwallet/BrainWallet.h
similarity index 100%
rename from alethzero/BrainWallet.h
rename to alethzero/plugins/brainwallet/BrainWallet.h
diff --git a/alethzero/BrainWallet.ui b/alethzero/plugins/brainwallet/BrainWallet.ui
similarity index 100%
rename from alethzero/BrainWallet.ui
rename to alethzero/plugins/brainwallet/BrainWallet.ui
diff --git a/alethzero/LogPanel.cpp b/alethzero/plugins/log/LogPanel.cpp
similarity index 100%
rename from alethzero/LogPanel.cpp
rename to alethzero/plugins/log/LogPanel.cpp
diff --git a/alethzero/LogPanel.h b/alethzero/plugins/log/LogPanel.h
similarity index 100%
rename from alethzero/LogPanel.h
rename to alethzero/plugins/log/LogPanel.h
diff --git a/alethzero/LogPanel.ui b/alethzero/plugins/log/LogPanel.ui
similarity index 100%
rename from alethzero/LogPanel.ui
rename to alethzero/plugins/log/LogPanel.ui
diff --git a/alethzero/plugins/namers/NameRegNamer.cpp b/alethzero/plugins/namers/NameRegNamer.cpp
new file mode 100644
index 000000000..312fcbc18
--- /dev/null
+++ b/alethzero/plugins/namers/NameRegNamer.cpp
@@ -0,0 +1,108 @@
+/*
+ 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 .
+*/
+/** @file NameRegNamer.h
+ * @author Gav Wood
+ * @date 2015
+ */
+
+#include "NameRegNamer.h"
+#include
+#include
+#include
+using namespace std;
+using namespace dev;
+using namespace az;
+using namespace eth;
+
+DEV_AZ_NOTE_PLUGIN(NameRegNamer);
+
+NameRegNamer::NameRegNamer(MainFace* _m):
+ AccountNamerPlugin(_m, "NameRegNamer")
+{
+}
+
+NameRegNamer::~NameRegNamer()
+{
+}
+
+string NameRegNamer::toName(Address const& _a) const
+{
+ for (auto const& r: m_registrars)
+ {
+ string n = abiOut(main()->ethereum()->call(Address(1), 0, r, abiIn("name(address)", _a), 1000000, DefaultGasPrice, PendingBlock, FudgeFactor::Lenient).output);
+ if (!n.empty())
+ return n;
+ }
+ return string();
+}
+
+Address NameRegNamer::toAddress(std::string const& _n) const
+{
+ for (auto const& r: m_registrars)
+ if (Address a = abiOut(main()->ethereum()->call(r, abiIn("addr(string)", _n)).output))
+ return a;
+ return Address();
+}
+
+Addresses NameRegNamer::knownAddresses() const
+{
+ return m_knownCache;
+}
+
+void NameRegNamer::killRegistrar(Address const& _r)
+{
+ if (m_filters.count(_r))
+ {
+ main()->uninstallWatch(m_filters.at(_r));
+ m_filters.erase(_r);
+ }
+ for (auto i = m_registrars.begin(); i != m_registrars.end();)
+ if (*i == _r)
+ i = m_registrars.erase(i);
+ else
+ ++i;
+}
+
+void NameRegNamer::updateCache()
+{
+// m_forwardCache.clear();
+// m_reverseCache.clear();
+ m_knownCache.clear();
+#if ETH_FATDB || !ETH_TRUE
+ for (auto const& r: m_registrars)
+ for (u256 const& a: keysOf(ethereum()->storageAt(r)))
+ if (a < u256(1) << 160)
+ m_knownCache.push_back(Address((u160)a - 1));
+#endif
+}
+
+void NameRegNamer::readSettings(QSettings const& _s)
+{
+ (void)_s;
+ while (!m_registrars.empty())
+ killRegistrar(m_registrars.back());
+
+ Address a("047cdba9627a8686bb24b3a65d87dab7efa53d31");
+ m_registrars.push_back(a);
+ m_filters[a] = main()->installWatch(LogFilter().address(a), [=](LocalisedLogEntries const&){ updateCache(); });
+
+ noteKnownChanged();
+}
+
+void NameRegNamer::writeSettings(QSettings&)
+{
+}
diff --git a/alethzero/plugins/namers/NameRegNamer.h b/alethzero/plugins/namers/NameRegNamer.h
new file mode 100644
index 000000000..d56e9d41b
--- /dev/null
+++ b/alethzero/plugins/namers/NameRegNamer.h
@@ -0,0 +1,59 @@
+/*
+ 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 .
+*/
+/** @file NameRegNamer.h
+ * @author Gav Wood
+ * @date 2015
+ */
+
+#pragma once
+
+#include "MainFace.h"
+
+namespace dev
+{
+namespace az
+{
+
+class NameRegNamer: public QObject, public AccountNamerPlugin
+{
+ Q_OBJECT
+
+public:
+ NameRegNamer(MainFace* _m);
+ ~NameRegNamer();
+
+private:
+ void readSettings(QSettings const&) override;
+ void writeSettings(QSettings&) override;
+
+ std::string toName(Address const&) const override;
+ Address toAddress(std::string const&) const override;
+ Addresses knownAddresses() const override;
+
+ void updateCache();
+ void killRegistrar(Address const& _r);
+
+ Addresses m_registrars;
+ std::unordered_map m_filters;
+
+ mutable Addresses m_knownCache;
+// mutable std::unordered_map m_forwardCache;
+// mutable std::unordered_map m_reverseCache;
+};
+
+}
+}
diff --git a/alethzero/NewAccount.cpp b/alethzero/plugins/namers/NewAccount.cpp
similarity index 100%
rename from alethzero/NewAccount.cpp
rename to alethzero/plugins/namers/NewAccount.cpp
diff --git a/alethzero/NewAccount.h b/alethzero/plugins/namers/NewAccount.h
similarity index 100%
rename from alethzero/NewAccount.h
rename to alethzero/plugins/namers/NewAccount.h
diff --git a/alethzero/NewAccount.ui b/alethzero/plugins/namers/NewAccount.ui
similarity index 100%
rename from alethzero/NewAccount.ui
rename to alethzero/plugins/namers/NewAccount.ui
diff --git a/alethzero/OtherAccounts.cpp b/alethzero/plugins/namers/OtherAccounts.cpp
similarity index 100%
rename from alethzero/OtherAccounts.cpp
rename to alethzero/plugins/namers/OtherAccounts.cpp
diff --git a/alethzero/OtherAccounts.h b/alethzero/plugins/namers/OtherAccounts.h
similarity index 100%
rename from alethzero/OtherAccounts.h
rename to alethzero/plugins/namers/OtherAccounts.h
diff --git a/alethzero/OtherAccounts.ui b/alethzero/plugins/namers/OtherAccounts.ui
similarity index 100%
rename from alethzero/OtherAccounts.ui
rename to alethzero/plugins/namers/OtherAccounts.ui
diff --git a/alethzero/OurAccounts.cpp b/alethzero/plugins/namers/OurAccounts.cpp
similarity index 100%
rename from alethzero/OurAccounts.cpp
rename to alethzero/plugins/namers/OurAccounts.cpp
diff --git a/alethzero/OurAccounts.h b/alethzero/plugins/namers/OurAccounts.h
similarity index 100%
rename from alethzero/OurAccounts.h
rename to alethzero/plugins/namers/OurAccounts.h
diff --git a/alethzero/plugins/whisper/Whisper.cpp b/alethzero/plugins/whisper/Whisper.cpp
new file mode 100644
index 000000000..cb5d9908f
--- /dev/null
+++ b/alethzero/plugins/whisper/Whisper.cpp
@@ -0,0 +1,178 @@
+/*
+ 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 .
+*/
+/** @file Whisper.cpp
+ * @author Gav Wood
+ * @date 2015
+ */
+
+#include "Whisper.h"
+#include
+#include
+#include
+#include
+#include
+#include "OurWebThreeStubServer.h"
+#include "ui_Whisper.h"
+using namespace std;
+using namespace dev;
+using namespace az;
+using namespace eth;
+
+DEV_AZ_NOTE_PLUGIN(Whisper);
+
+static Public stringToPublic(QString const& _a)
+{
+ string sn = _a.toStdString();
+ if (_a.size() == sizeof(Public) * 2)
+ return Public(fromHex(_a.toStdString()));
+ else if (_a.size() == sizeof(Public) * 2 + 2 && _a.startsWith("0x"))
+ return Public(fromHex(_a.mid(2).toStdString()));
+ else
+ return Public();
+}
+
+static shh::Topics topicFromText(QString _s)
+{
+ shh::BuildTopic ret;
+ while (_s.size())
+ {
+ QRegExp r("(@|\\$)?\"([^\"]*)\"(\\s.*)?");
+ QRegExp d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?");
+ QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?");
+ bytes part;
+ if (r.exactMatch(_s))
+ {
+ for (auto i: r.cap(2))
+ part.push_back((byte)i.toLatin1());
+ if (r.cap(1) != "$")
+ for (int i = r.cap(2).size(); i < 32; ++i)
+ part.push_back(0);
+ else
+ part.push_back(0);
+ _s = r.cap(3);
+ }
+ else if (d.exactMatch(_s))
+ {
+ u256 v(d.cap(2).toStdString());
+ if (d.cap(6) == "szabo")
+ v *= szabo;
+ else if (d.cap(5) == "finney")
+ v *= finney;
+ else if (d.cap(4) == "ether")
+ v *= ether;
+ bytes bs = dev::toCompactBigEndian(v);
+ if (d.cap(1) != "$")
+ for (auto i = bs.size(); i < 32; ++i)
+ part.push_back(0);
+ for (auto b: bs)
+ part.push_back(b);
+ _s = d.cap(7);
+ }
+ else if (h.exactMatch(_s))
+ {
+ bytes bs = fromHex((((h.cap(3).size() & 1) ? "0" : "") + h.cap(3)).toStdString());
+ if (h.cap(1) != "$")
+ for (auto i = bs.size(); i < 32; ++i)
+ part.push_back(0);
+ for (auto b: bs)
+ part.push_back(b);
+ _s = h.cap(5);
+ }
+ else
+ _s = _s.mid(1);
+ ret.shift(part);
+ }
+ return ret;
+}
+
+
+Whisper::Whisper(MainFace* _m):
+ Plugin(_m, "Whisper"),
+ m_ui(new Ui::Whisper)
+{
+ dock(Qt::RightDockWidgetArea, "Whisper")->setWidget(new QWidget);
+ m_ui->setupUi(dock()->widget());
+ connect(addMenuItem("New Whisper identity.", "menuNetwork", true), &QAction::triggered, this, &Whisper::on_newIdentity_triggered);
+ connect(_m->web3Server(), &OurWebThreeStubServer::onNewId, this, &Whisper::addNewId);
+}
+
+void Whisper::readSettings(QSettings const& _s)
+{
+ m_myIdentities.clear();
+ QByteArray b = _s.value("identities").toByteArray();
+ if (!b.isEmpty())
+ {
+ Secret k;
+ for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i)
+ {
+ memcpy(k.writable().data(), b.data() + i * sizeof(Secret), sizeof(Secret));
+ if (!count(m_myIdentities.begin(), m_myIdentities.end(), KeyPair(k)))
+ m_myIdentities.append(KeyPair(k));
+ }
+ }
+ main()->web3Server()->setIdentities(keysAsVector(m_myIdentities));
+ refreshWhisper();
+}
+
+void Whisper::writeSettings(QSettings& _s)
+{
+ QByteArray b;
+ b.resize(sizeof(Secret) * m_myIdentities.size());
+ auto p = b.data();
+ for (auto i: m_myIdentities)
+ {
+ memcpy(p, &(i.secret()), sizeof(Secret));
+ p += sizeof(Secret);
+ }
+ _s.setValue("identities", b);
+}
+
+void Whisper::addNewId(QString _ids)
+{
+ KeyPair kp(jsToSecret(_ids.toStdString()));
+ m_myIdentities.push_back(kp);
+ main()->web3Server()->setIdentities(keysAsVector(m_myIdentities));
+ refreshWhisper();
+}
+
+void Whisper::refreshWhisper()
+{
+ m_ui->shhFrom->clear();
+ for (auto i: main()->web3Server()->ids())
+ m_ui->shhFrom->addItem(QString::fromStdString(toHex(i.first.ref())));
+}
+
+void Whisper::on_newIdentity_triggered()
+{
+ KeyPair kp = KeyPair::create();
+ m_myIdentities.append(kp);
+ main()->web3Server()->setIdentities(keysAsVector(m_myIdentities));
+ refreshWhisper();
+}
+
+void Whisper::on_post_clicked()
+{
+ return;
+ shh::Message m;
+ m.setTo(stringToPublic(m_ui->shhTo->currentText()));
+ m.setPayload(parseData(m_ui->shhData->toPlainText().toStdString()));
+ Public f = stringToPublic(m_ui->shhFrom->currentText());
+ Secret from;
+ if (main()->web3Server()->ids().count(f))
+ from = main()->web3Server()->ids().at(f);
+ whisper()->inject(m.seal(from, topicFromText(m_ui->shhTopic->toPlainText()), m_ui->shhTtl->value(), m_ui->shhWork->value()));
+}
diff --git a/alethzero/plugins/whisper/Whisper.h b/alethzero/plugins/whisper/Whisper.h
new file mode 100644
index 000000000..bcc1d16df
--- /dev/null
+++ b/alethzero/plugins/whisper/Whisper.h
@@ -0,0 +1,60 @@
+/*
+ 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 .
+*/
+/** @file Whisper.h
+ * @author Gav Wood
+ * @date 2015
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include "MainFace.h"
+
+namespace Ui
+{
+class Whisper;
+}
+
+namespace dev
+{
+namespace az
+{
+
+class Whisper: public QObject, public Plugin
+{
+ Q_OBJECT
+
+public:
+ Whisper(MainFace* _m);
+
+private:
+ void readSettings(QSettings const&) override;
+ void writeSettings(QSettings&) override;
+ void refreshWhisper();
+ void addNewId(QString _ids);
+ void on_newIdentity_triggered();
+ void on_post_clicked();
+
+ Ui::Whisper* m_ui;
+ QList m_myIdentities;
+};
+
+}
+}
diff --git a/alethzero/plugins/whisper/Whisper.ui b/alethzero/plugins/whisper/Whisper.ui
new file mode 100644
index 000000000..e143c2f93
--- /dev/null
+++ b/alethzero/plugins/whisper/Whisper.ui
@@ -0,0 +1,176 @@
+
+
+ Whisper
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Data
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Work to Prove
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::NoFrame
+
+
+ 0
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::NoFrame
+
+
+ 0
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Topic
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ To
+
+
+
+ -
+
+
+ true
+
+
+
+ -
+
+
+ seconds
+
+
+ 5
+
+
+ 259200
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ TTL
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ From
+
+
+
+ -
+
+
+ ms
+
+
+ 1
+
+
+ 1000
+
+
+ 50
+
+
+
+ -
+
+
+ Post
+
+
+
+
+
+
+
+
diff --git a/alethzero/plugins/whisper/WhisperPeers.cpp b/alethzero/plugins/whisper/WhisperPeers.cpp
new file mode 100644
index 000000000..07198f93d
--- /dev/null
+++ b/alethzero/plugins/whisper/WhisperPeers.cpp
@@ -0,0 +1,78 @@
+/*
+ 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 .
+*/
+/** @file WhisperPeers.cpp
+ * @author Gav Wood
+ * @date 2015
+ */
+
+#include "WhisperPeers.h"
+#include
+#include
+#include
+#include
+#include "OurWebThreeStubServer.h"
+#include "ui_WhisperPeers.h"
+using namespace std;
+using namespace dev;
+using namespace az;
+using namespace eth;
+
+DEV_AZ_NOTE_PLUGIN(WhisperPeers);
+
+WhisperPeers::WhisperPeers(MainFace* _m):
+ Plugin(_m, "WhisperPeers"),
+ m_ui(new Ui::WhisperPeers)
+{
+ dock(Qt::RightDockWidgetArea, "Active Whispers")->setWidget(new QWidget);
+ m_ui->setupUi(dock()->widget());
+ startTimer(1000);
+}
+
+void WhisperPeers::timerEvent(QTimerEvent*)
+{
+ refreshWhispers();
+}
+
+void WhisperPeers::refreshWhispers()
+{
+ return;
+ m_ui->whispers->clear();
+ for (auto const& w: whisper()->all())
+ {
+ shh::Envelope const& e = w.second;
+ shh::Message m;
+ for (pair const& i: main()->web3Server()->ids())
+ if (!!(m = e.open(shh::Topics(), i.second)))
+ break;
+ if (!m)
+ m = e.open(shh::Topics());
+
+ QString msg;
+ if (m.from())
+ // Good message.
+ msg = QString("{%1 -> %2} %3").arg(m.from() ? m.from().abridged().c_str() : "???").arg(m.to() ? m.to().abridged().c_str() : "*").arg(toHex(m.payload()).c_str());
+ else if (m)
+ // Maybe message.
+ msg = QString("{%1 -> %2} %3 (?)").arg(m.from() ? m.from().abridged().c_str() : "???").arg(m.to() ? m.to().abridged().c_str() : "*").arg(toHex(m.payload()).c_str());
+
+ time_t ex = e.expiry();
+ QString t(ctime(&ex));
+ t.chop(1);
+ QString item = QString("[%1 - %2s] *%3 %5 %4").arg(t).arg(e.ttl()).arg(e.workProved()).arg(toString(e.topic()).c_str()).arg(msg);
+ m_ui->whispers->addItem(item);
+ }
+}
diff --git a/alethzero/plugins/whisper/WhisperPeers.h b/alethzero/plugins/whisper/WhisperPeers.h
new file mode 100644
index 000000000..2e9ade3a2
--- /dev/null
+++ b/alethzero/plugins/whisper/WhisperPeers.h
@@ -0,0 +1,55 @@
+/*
+ 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 .
+*/
+/** @file WhisperPeers.h
+ * @author Gav Wood
+ * @date 2015
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include "MainFace.h"
+
+namespace Ui
+{
+class WhisperPeers;
+}
+
+namespace dev
+{
+namespace az
+{
+
+class WhisperPeers: public QObject, public Plugin
+{
+ Q_OBJECT
+
+public:
+ WhisperPeers(MainFace* _m);
+
+private:
+ void timerEvent(QTimerEvent*) override;
+ void refreshWhispers();
+
+ Ui::WhisperPeers* m_ui;
+};
+
+}
+}
diff --git a/alethzero/plugins/whisper/WhisperPeers.ui b/alethzero/plugins/whisper/WhisperPeers.ui
new file mode 100644
index 000000000..d73c215e8
--- /dev/null
+++ b/alethzero/plugins/whisper/WhisperPeers.ui
@@ -0,0 +1,32 @@
+
+
+ WhisperPeers
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ QFrame::NoFrame
+
+
+
+
+
+
+
+
diff --git a/eth/main.cpp b/eth/main.cpp
index 68f1da726..7be21eb3d 100644
--- a/eth/main.cpp
+++ b/eth/main.cpp
@@ -109,8 +109,8 @@ void help()
/*<< " -B,--block-fees Set the block fee profit in the reference unit e.g. ¢ (default: 15)." << endl
<< " -e,--ether-price 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*/
- << " --ask Set the minimum ask gas price under which no transactions will be mined (default " << toString(c_defaultGasPrice) << " )." << endl
- << " --bid Set the bid gas price for to pay for transactions (default " << toString(c_defaultGasPrice) << " )." << endl
+ << " --ask Set the minimum ask gas price under which no transactions will be mined (default " << toString(DefaultGasPrice) << " )." << endl
+ << " --bid Set the bid gas price for to pay for transactions (default " << toString(DefaultGasPrice) << " )." << endl
<< endl
<< "Client mining:" << endl
<< " -a,--address Set the coinbase (mining payout) address to addr (default: auto)." << endl
@@ -338,8 +338,8 @@ int main(int argc, char** argv)
// TransactionPriority priority = TransactionPriority::Medium;
// double etherPrice = 30.679;
// double blockFees = 15.0;
- u256 askPrice = c_defaultGasPrice;
- u256 bidPrice = c_defaultGasPrice;
+ u256 askPrice = DefaultGasPrice;
+ u256 bidPrice = DefaultGasPrice;
// javascript console
bool useConsole = false;
diff --git a/evmjit/CMakeLists.txt b/evmjit/CMakeLists.txt
index 619477119..49bf7f73d 100644
--- a/evmjit/CMakeLists.txt
+++ b/evmjit/CMakeLists.txt
@@ -3,13 +3,14 @@ cmake_minimum_required(VERSION 2.8.12)
if (${CMAKE_VERSION} VERSION_GREATER 3.0)
cmake_policy(SET CMP0042 OLD) # fix MACOSX_RPATH
cmake_policy(SET CMP0048 NEW) # allow VERSION argument in project()
- project(EVMJIT VERSION 0.9.0 LANGUAGES CXX)
+ project(EVMJIT VERSION 0.9.0.1 LANGUAGES CXX)
else()
project(EVMJIT)
- set(EVMJIT_VERSION "0.9.0")
+ set(EVMJIT_VERSION "0.9.0.1")
set(EVMJIT_VERSION_MAJOR 0)
set(EVMJIT_VERSION_MINOR 9)
set(EVMJIT_VERSION_PATCH 0)
+ set(EVMJIT_VERSION_TWEAK 1)
endif()
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
diff --git a/evmjit/include/evmjit/JIT-c.h b/evmjit/include/evmjit/JIT-c.h
index d7c792451..4e0993ab7 100644
--- a/evmjit/include/evmjit/JIT-c.h
+++ b/evmjit/include/evmjit/JIT-c.h
@@ -47,10 +47,6 @@ typedef enum evmjit_return_code
// Standard error codes
OutOfGas = -1,
- StackUnderflow = -2,
- BadJumpDestination = -3,
- BadInstruction = -4,
- Rejected = -5, ///< Input data (code, gas, block info, etc.) does not meet JIT requirement and execution request has been rejected
// Internal error codes
LLVMError = -101,
diff --git a/evmjit/include/evmjit/JIT.h b/evmjit/include/evmjit/JIT.h
index e74534243..285a33218 100644
--- a/evmjit/include/evmjit/JIT.h
+++ b/evmjit/include/evmjit/JIT.h
@@ -101,10 +101,6 @@ enum class ReturnCode
// Standard error codes
OutOfGas = -1,
- StackUnderflow = -2,
- BadJumpDestination = -3,
- BadInstruction = -4,
- Rejected = -5, ///< Input data (code, gas, block info, etc.) does not meet JIT requirement and execution request has been rejected
// Internal error codes
LLVMError = -101,
diff --git a/evmjit/libevmjit-cpp/JitVM.cpp b/evmjit/libevmjit-cpp/JitVM.cpp
index 2bc9043db..6db58b594 100644
--- a/evmjit/libevmjit-cpp/JitVM.cpp
+++ b/evmjit/libevmjit-cpp/JitVM.cpp
@@ -60,14 +60,8 @@ bytesConstRef JitVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _on
_ext.suicide(right160(jit2eth(m_data.address)));
break;
- case evmjit::ReturnCode::BadJumpDestination:
- BOOST_THROW_EXCEPTION(BadJumpDestination());
case evmjit::ReturnCode::OutOfGas:
BOOST_THROW_EXCEPTION(OutOfGas());
- case evmjit::ReturnCode::StackUnderflow: // FIXME: Remove support for detail errors
- BOOST_THROW_EXCEPTION(StackUnderflow());
- case evmjit::ReturnCode::BadInstruction:
- BOOST_THROW_EXCEPTION(BadInstruction());
case evmjit::ReturnCode::LinkerWorkaround: // never happens
env_sload(); // but forces linker to include env_* JIT callback functions
break;
diff --git a/evmjit/libevmjit/Array.cpp b/evmjit/libevmjit/Array.cpp
index 96329afd5..4f1f47d6e 100644
--- a/evmjit/libevmjit/Array.cpp
+++ b/evmjit/libevmjit/Array.cpp
@@ -217,11 +217,7 @@ llvm::Type* Array::getType()
}
Array::Array(llvm::IRBuilder<>& _builder, char const* _name) :
- CompilerHelper(_builder),
- m_pushFunc([this](){ return createArrayPushFunc(); }),
- m_setFunc([this](){ return createArraySetFunc(); }),
- m_getFunc([this](){ return createArrayGetFunc(); }),
- m_freeFunc([this](){ return createFreeFunc(); })
+ CompilerHelper(_builder)
{
m_array = m_builder.CreateAlloca(getType(), nullptr, _name);
m_builder.CreateStore(llvm::ConstantAggregateZero::get(getType()), m_array);
@@ -229,11 +225,7 @@ Array::Array(llvm::IRBuilder<>& _builder, char const* _name) :
Array::Array(llvm::IRBuilder<>& _builder, llvm::Value* _array) :
CompilerHelper(_builder),
- m_array(_array),
- m_pushFunc([this](){ return createArrayPushFunc(); }),
- m_setFunc([this](){ return createArraySetFunc(); }),
- m_getFunc([this](){ return createArrayGetFunc(); }),
- m_freeFunc([this](){ return createFreeFunc(); })
+ m_array(_array)
{
m_builder.CreateStore(llvm::ConstantAggregateZero::get(getType()), m_array);
}
diff --git a/evmjit/libevmjit/Array.h b/evmjit/libevmjit/Array.h
index 41842f0c9..a2db976b3 100644
--- a/evmjit/libevmjit/Array.h
+++ b/evmjit/libevmjit/Array.h
@@ -59,10 +59,10 @@ private:
llvm::Function* getReallocFunc();
LazyFunction m_pushFunc = {[this](){ return createArrayPushFunc(); }}; // TODO: If works on MSVC, remove form initialization list
- LazyFunction m_setFunc;
+ LazyFunction m_setFunc = {[this](){ return createArraySetFunc(); }};
LazyFunction m_getPtrFunc = {[this](){ return createGetPtrFunc(); }};
- LazyFunction m_getFunc;
- LazyFunction m_freeFunc;
+ LazyFunction m_getFunc = {[this](){ return createArrayGetFunc(); }};
+ LazyFunction m_freeFunc = {[this](){ return createFreeFunc(); }};
LazyFunction m_extendFunc = {[this](){ return createExtendFunc(); }};
LazyFunction m_reallocFunc = {[this](){ return getReallocFunc(); }};
};
@@ -70,5 +70,3 @@ private:
}
}
}
-
-
diff --git a/evmjit/libevmjit/BasicBlock.cpp b/evmjit/libevmjit/BasicBlock.cpp
index be57a28b8..47b590103 100644
--- a/evmjit/libevmjit/BasicBlock.cpp
+++ b/evmjit/libevmjit/BasicBlock.cpp
@@ -20,53 +20,42 @@ namespace eth
namespace jit
{
-static const char* jumpDestName = "JmpDst.";
-static const char* basicBlockName = "Instr.";
-
-BasicBlock::BasicBlock(instr_idx _firstInstrIdx, code_iterator _begin, code_iterator _end, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest) :
+BasicBlock::BasicBlock(instr_idx _firstInstrIdx, code_iterator _begin, code_iterator _end, llvm::Function* _mainFunc):
m_firstInstrIdx{_firstInstrIdx},
m_begin(_begin),
m_end(_end),
- m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {isJumpDest ? jumpDestName : basicBlockName, std::to_string(_firstInstrIdx)}, _mainFunc)),
- m_stack(*this),
- m_builder(_builder),
- m_isJumpDest(isJumpDest)
-{}
-
-BasicBlock::BasicBlock(std::string _name, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest) :
- m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), _name, _mainFunc)),
- m_stack(*this),
- m_builder(_builder),
- m_isJumpDest(isJumpDest)
+ m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {"Instr.", std::to_string(_firstInstrIdx)}, _mainFunc))
{}
-BasicBlock::LocalStack::LocalStack(BasicBlock& _owner) :
- m_bblock(_owner)
+LocalStack::LocalStack(Stack& _globalStack):
+ m_global(_globalStack)
{}
-void BasicBlock::LocalStack::push(llvm::Value* _value)
+void LocalStack::push(llvm::Value* _value)
{
assert(_value->getType() == Type::Word);
- m_bblock.m_currentStack.push_back(_value);
- m_bblock.m_tosOffset += 1;
- m_maxSize = std::max(m_maxSize, m_bblock.m_tosOffset);
+ m_local.push_back(_value);
+ m_maxSize = std::max(m_maxSize, size());
}
-llvm::Value* BasicBlock::LocalStack::pop()
+llvm::Value* LocalStack::pop()
{
- auto result = get(0);
+ auto item = get(0);
+ assert(!m_local.empty() || !m_input.empty());
- if (m_bblock.m_currentStack.size() > 0)
- m_bblock.m_currentStack.pop_back();
+ if (m_local.size() > 0)
+ m_local.pop_back();
+ else
+ ++m_globalPops;
- m_bblock.m_tosOffset -= 1;
- return result;
+ m_minSize = std::min(m_minSize, size());
+ return item;
}
/**
* Pushes a copy of _index-th element (tos is 0-th elem).
*/
-void BasicBlock::LocalStack::dup(size_t _index)
+void LocalStack::dup(size_t _index)
{
auto val = get(_index);
push(val);
@@ -76,7 +65,7 @@ void BasicBlock::LocalStack::dup(size_t _index)
* Swaps tos with _index-th element (tos is 0-th elem).
* _index must be > 0.
*/
-void BasicBlock::LocalStack::swap(size_t _index)
+void LocalStack::swap(size_t _index)
{
assert(_index > 0);
auto val = get(_index);
@@ -85,306 +74,73 @@ void BasicBlock::LocalStack::swap(size_t _index)
set(0, val);
}
-std::vector::iterator BasicBlock::LocalStack::getItemIterator(size_t _index)
+llvm::Value* LocalStack::get(size_t _index)
{
- auto& currentStack = m_bblock.m_currentStack;
- if (_index < currentStack.size())
- return currentStack.end() - _index - 1;
-
- // Need to map more elements from the EVM stack
- auto nNewItems = 1 + _index - currentStack.size();
- currentStack.insert(currentStack.begin(), nNewItems, nullptr);
+ if (_index < m_local.size())
+ return *(m_local.rbegin() + _index); // count from back
- return currentStack.end() - _index - 1;
-}
-
-llvm::Value* BasicBlock::LocalStack::get(size_t _index)
-{
- auto& initialStack = m_bblock.m_initialStack;
- auto itemIter = getItemIterator(_index);
+ auto idx = _index - m_local.size() + m_globalPops;
+ if (idx >= m_input.size())
+ m_input.resize(idx + 1);
+ auto& item = m_input[idx];
- if (*itemIter == nullptr)
+ if (!item)
{
- // Need to fetch a new item from the EVM stack
- assert(static_cast(_index) >= m_bblock.m_tosOffset);
- size_t initialIdx = _index - m_bblock.m_tosOffset;
- if (initialIdx >= initialStack.size())
- {
- auto nNewItems = 1 + initialIdx - initialStack.size();
- initialStack.insert(initialStack.end(), nNewItems, nullptr);
- }
-
- assert(initialStack[initialIdx] == nullptr);
- // Create a dummy value.
- std::string name = "get_" + std::to_string(_index);
- initialStack[initialIdx] = m_bblock.m_builder.CreatePHI(Type::Word, 0, std::move(name));
- *itemIter = initialStack[initialIdx];
+ item = m_global.get(idx); // Reach an item from global stack
+ m_minSize = std::min(m_minSize, -static_cast(idx) - 1); // and remember required stack size
}
- return *itemIter;
+ return item;
}
-void BasicBlock::LocalStack::set(size_t _index, llvm::Value* _word)
-{
- auto itemIter = getItemIterator(_index);
- *itemIter = _word;
-}
-
-
-
-
-
-void BasicBlock::synchronizeLocalStack(Stack& _evmStack)
+void LocalStack::set(size_t _index, llvm::Value* _word)
{
- auto blockTerminator = m_llvmBB->getTerminator();
- assert(blockTerminator != nullptr);
- if (blockTerminator->getOpcode() != llvm::Instruction::Ret)
- {
- // Not needed in case of ret instruction. Ret also invalidates the stack.
- m_builder.SetInsertPoint(blockTerminator);
-
- auto currIter = m_currentStack.begin();
- auto endIter = m_currentStack.end();
-
- // Update (emit set()) changed values
- for (int idx = (int)m_currentStack.size() - 1 - m_tosOffset;
- currIter < endIter && idx >= 0;
- ++currIter, --idx)
- {
- assert(static_cast(idx) < m_initialStack.size());
- if (*currIter != m_initialStack[idx]) // value needs update
- _evmStack.set(static_cast(idx), *currIter);
- }
-
- // Pop values
- if (m_tosOffset < 0)
- _evmStack.pop(static_cast(-m_tosOffset));
-
- // Push new values
- for (; currIter < endIter; ++currIter)
- {
- assert(*currIter != nullptr);
- _evmStack.push(*currIter);
- }
- }
-
- // Emit get() for all (used) values from the initial stack
- for (size_t idx = 0; idx < m_initialStack.size(); ++idx)
+ if (_index < m_local.size())
{
- auto val = m_initialStack[idx];
- if (val == nullptr)
- continue;
-
- llvm::PHINode* phi = llvm::cast(val);
- // Insert call to get() just before the PHI node and replace
- // the uses of PHI with the uses of this new instruction.
- m_builder.SetInsertPoint(phi);
- auto newVal = _evmStack.get(idx); // OPT: Value may be never user but we need to check stack heigth
- // It is probably a good idea to keep heigth as a local variable accesible by LLVM directly
- phi->replaceAllUsesWith(newVal);
- phi->eraseFromParent();
+ *(m_local.rbegin() + _index) = _word;
+ return;
}
- // Reset the stack
- m_initialStack.erase(m_initialStack.begin(), m_initialStack.end());
- m_currentStack.erase(m_currentStack.begin(), m_currentStack.end());
- m_tosOffset = 0;
+ auto idx = _index - m_local.size() + m_globalPops;
+ assert(idx < m_input.size());
+ m_input[idx] = _word;
}
-void BasicBlock::linkLocalStacks(std::vector basicBlocks, llvm::IRBuilder<>& _builder)
-{
- struct BBInfo
- {
- BasicBlock& bblock;
- std::vector predecessors;
- size_t inputItems;
- size_t outputItems;
- std::vector phisToRewrite;
-
- BBInfo(BasicBlock& _bblock) :
- bblock(_bblock),
- predecessors(),
- inputItems(0),
- outputItems(0)
- {
- auto& initialStack = bblock.m_initialStack;
- for (auto it = initialStack.begin();
- it != initialStack.end() && *it != nullptr;
- ++it, ++inputItems);
-
- //if (bblock.localStack().m_tosOffset > 0)
- // outputItems = bblock.localStack().m_tosOffset;
- auto& exitStack = bblock.m_currentStack;
- for (auto it = exitStack.rbegin();
- it != exitStack.rend() && *it != nullptr;
- ++it, ++outputItems);
- }
- };
-
- std::map cfg;
-
- // Create nodes in cfg
- for (auto bb : basicBlocks)
- cfg.emplace(bb->llvm(), *bb);
-
- // Create edges in cfg: for each bb info fill the list
- // of predecessor infos.
- for (auto& pair : cfg)
- {
- auto bb = pair.first;
- auto& info = pair.second;
-
- for (auto predIt = llvm::pred_begin(bb); predIt != llvm::pred_end(bb); ++predIt)
- {
- auto predInfoEntry = cfg.find(*predIt);
- if (predInfoEntry != cfg.end()) // FIXME: It is wrong - will skip entry block
- info.predecessors.push_back(&predInfoEntry->second);
- }
- }
- // Iteratively compute inputs and outputs of each block, until reaching fixpoint.
- bool valuesChanged = true;
- while (valuesChanged)
+void LocalStack::finalize(llvm::IRBuilder<>& _builder, llvm::BasicBlock& _bb)
+{
+ auto blockTerminator = _bb.getTerminator();
+ assert(blockTerminator);
+ if (blockTerminator->getOpcode() != llvm::Instruction::Ret)
{
- for (auto& pair : cfg)
- {
- DLOG(bb) << pair.second.bblock.llvm()->getName().str()
- << ": in " << pair.second.inputItems
- << ", out " << pair.second.outputItems
- << "\n";
- }
+ // Not needed in case of ret instruction. Ret invalidates the stack.
+ _builder.SetInsertPoint(blockTerminator);
- valuesChanged = false;
- for (auto& pair : cfg)
+ // Update items fetched from global stack ignoring the poped ones
+ assert(m_globalPops <= m_input.size()); // pop() always does get()
+ for (auto i = m_globalPops; i < m_input.size(); ++i)
{
- auto& info = pair.second;
-
- if (&info.bblock == basicBlocks.front())
- info.inputItems = 0; // we cannot use phi nodes for first block as it is a successor of entry block
-
- if (info.predecessors.empty())
- info.inputItems = 0; // no consequences for other blocks, so leave valuesChanged false
-
- for (auto predInfo : info.predecessors)
- {
- if (predInfo->outputItems < info.inputItems)
- {
- info.inputItems = predInfo->outputItems;
- valuesChanged = true;
- }
- else if (predInfo->outputItems > info.inputItems)
- {
- predInfo->outputItems = info.inputItems;
- valuesChanged = true;
- }
- }
+ if (m_input[i])
+ m_global.set(i, m_input[i]);
}
- }
-
- // Propagate values between blocks.
- for (auto& entry : cfg)
- {
- auto& info = entry.second;
- auto& bblock = info.bblock;
- llvm::BasicBlock::iterator fstNonPhi(bblock.llvm()->getFirstNonPHI());
- auto phiIter = bblock.m_initialStack.begin();
- for (size_t index = 0; index < info.inputItems; ++index, ++phiIter)
+ // Add new items
+ auto pops = m_globalPops; // Copy pops counter to keep original value
+ for (auto& item: m_local)
{
- assert(llvm::isa(*phiIter));
- auto phi = llvm::cast(*phiIter);
-
- for (auto predIt : info.predecessors)
- {
- auto& predExitStack = predIt->bblock.m_currentStack;
- auto value = *(predExitStack.end() - 1 - index);
- phi->addIncoming(value, predIt->bblock.llvm());
- }
-
- // Move phi to the front
- if (llvm::BasicBlock::iterator(phi) != bblock.llvm()->begin())
- {
- phi->removeFromParent();
- _builder.SetInsertPoint(bblock.llvm(), bblock.llvm()->begin());
- _builder.Insert(phi);
- }
+ if (pops) // Override poped global items
+ m_global.set(--pops, item); // using pops counter as the index
+ else
+ m_global.push(item);
}
- // The items pulled directly from predecessors block must be removed
- // from the list of items that has to be popped from the initial stack.
- auto& initialStack = bblock.m_initialStack;
- initialStack.erase(initialStack.begin(), initialStack.begin() + info.inputItems);
- // Initial stack shrinks, so the size difference grows:
- bblock.m_tosOffset += (int)info.inputItems;
- }
-
- // We must account for the items that were pushed directly to successor
- // blocks and thus should not be on the list of items to be pushed onto
- // to EVM stack
- for (auto& entry : cfg)
- {
- auto& info = entry.second;
- auto& bblock = info.bblock;
-
- auto& exitStack = bblock.m_currentStack;
- exitStack.erase(exitStack.end() - info.outputItems, exitStack.end());
- bblock.m_tosOffset -= (int)info.outputItems; // FIXME: Fix types
- }
-}
-
-void BasicBlock::dump()
-{
- dump(std::cerr, false);
-}
-
-void BasicBlock::dump(std::ostream& _out, bool _dotOutput)
-{
- llvm::raw_os_ostream out(_out);
-
- out << (_dotOutput ? "" : "Initial stack:\n");
- for (auto val : m_initialStack)
- {
- if (val == nullptr)
- out << " ?";
- else if (llvm::isa(val))
- out << " " << val->getName();
- else if (llvm::isa(val))
- out << *val;
- else
- out << " " << *val;
-
- out << (_dotOutput ? "\\l" : "\n");
- }
-
- out << (_dotOutput ? "| " : "Instructions:\n");
- for (auto ins = m_llvmBB->begin(); ins != m_llvmBB->end(); ++ins)
- out << *ins << (_dotOutput ? "\\l" : "\n");
-
- if (! _dotOutput)
- out << "Current stack (offset = " << m_tosOffset << "):\n";
- else
- out << "|";
-
- for (auto val = m_currentStack.rbegin(); val != m_currentStack.rend(); ++val)
- {
- if (*val == nullptr)
- out << " ?";
- else if (llvm::isa(*val))
- out << " " << (*val)->getName();
- else if (llvm::isa(*val))
- out << **val;
- else
- out << " " << **val;
- out << (_dotOutput ? "\\l" : "\n");
+ // Pop not overriden items
+ if (pops)
+ m_global.pop(pops);
}
-
- if (! _dotOutput)
- out << " ...\n----------------------------------------\n";
}
-
-
}
}
}
diff --git a/evmjit/libevmjit/BasicBlock.h b/evmjit/libevmjit/BasicBlock.h
index ddf73a04c..a6e420efc 100644
--- a/evmjit/libevmjit/BasicBlock.h
+++ b/evmjit/libevmjit/BasicBlock.h
@@ -14,52 +14,58 @@ namespace jit
using namespace evmjit;
using instr_idx = uint64_t;
-class BasicBlock
+class LocalStack
{
public:
- class LocalStack
- {
- public:
- /// Pushes value on stack
- void push(llvm::Value* _value);
+ explicit LocalStack(Stack& _globalStack);
+ LocalStack(LocalStack const&) = delete;
+ void operator=(LocalStack const&) = delete;
+
+ /// Pushes value on stack
+ void push(llvm::Value* _value);
- /// Pops and returns top value
- llvm::Value* pop();
+ /// Pops and returns top value
+ llvm::Value* pop();
- /// Duplicates _index'th value on stack
- void dup(size_t _index);
+ /// Duplicates _index'th value on stack
+ void dup(size_t _index);
- /// Swaps _index'th value on stack with a value on stack top.
- /// @param _index Index of value to be swaped. Must be > 0.
- void swap(size_t _index);
+ /// Swaps _index'th value on stack with a value on stack top.
+ /// @param _index Index of value to be swaped. Must be > 0.
+ void swap(size_t _index);
- size_t getMaxSize() const { return m_maxSize; }
- int getDiff() const { return m_bblock.m_tosOffset; }
+ ssize_t size() const { return static_cast(m_local.size()) - static_cast(m_globalPops); }
+ ssize_t minSize() const { return m_minSize; }
+ ssize_t maxSize() const { return m_maxSize; }
- private:
- LocalStack(BasicBlock& _owner);
- LocalStack(LocalStack const&) = delete;
- void operator=(LocalStack const&) = delete;
- friend BasicBlock;
+ /// Finalize local stack: check the requirements and update of the global stack.
+ void finalize(llvm::IRBuilder<>& _builder, llvm::BasicBlock& _bb);
- /// Gets _index'th value from top (counting from 0)
- llvm::Value* get(size_t _index);
+private:
+ /// Gets _index'th value from top (counting from 0)
+ llvm::Value* get(size_t _index);
- /// Sets _index'th value from top (counting from 0)
- void set(size_t _index, llvm::Value* _value);
+ /// Sets _index'th value from top (counting from 0)
+ void set(size_t _index, llvm::Value* _value);
- std::vector::iterator getItemIterator(size_t _index);
+ /// Items fetched from global stack. First element matches the top of the global stack.
+ /// Can contain nulls if some items has been skipped.
+ std::vector m_input;
- private:
- BasicBlock& m_bblock;
- int m_maxSize = 0; ///< Max size reached by the stack.
- };
+ /// Local stack items that has not been pushed to global stack. First item is just above global stack.
+ std::vector m_local;
- explicit BasicBlock(instr_idx _firstInstrIdx, code_iterator _begin, code_iterator _end, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest);
- explicit BasicBlock(std::string _name, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest);
+ Stack& m_global; ///< Reference to global stack.
- BasicBlock(const BasicBlock&) = delete;
- BasicBlock& operator=(const BasicBlock&) = delete;
+ size_t m_globalPops = 0; ///< Number of items poped from global stack. In other words: global - local stack overlap.
+ ssize_t m_minSize = 0; ///< Minimum reached local stack size. Can be negative.
+ ssize_t m_maxSize = 0; ///< Maximum reached local stack size.
+};
+
+class BasicBlock
+{
+public:
+ explicit BasicBlock(instr_idx _firstInstrIdx, code_iterator _begin, code_iterator _end, llvm::Function* _mainFunc);
llvm::BasicBlock* llvm() { return m_llvmBB; }
@@ -67,61 +73,12 @@ public:
code_iterator begin() const { return m_begin; }
code_iterator end() const { return m_end; }
- bool isJumpDest() const { return m_isJumpDest; }
-
- llvm::Value* getJumpTarget() const { return m_jumpTarget; }
- void setJumpTarget(llvm::Value* _jumpTarget) { m_jumpTarget = _jumpTarget; }
-
- LocalStack& localStack() { return m_stack; }
-
- /// Optimization: propagates values between local stacks in basic blocks
- /// to avoid excessive pushing/popping on the EVM stack.
- static void linkLocalStacks(std::vector _basicBlocks, llvm::IRBuilder<>& _builder);
-
- /// Synchronize current local stack with the EVM stack.
- void synchronizeLocalStack(Stack& _evmStack);
-
- /// Prints local stack and block instructions to stderr.
- /// Useful for calling in a debugger session.
- void dump();
- void dump(std::ostream& os, bool _dotOutput = false);
-
private:
instr_idx const m_firstInstrIdx = 0; ///< Code index of first instruction in the block
- code_iterator const m_begin = {}; ///< Iterator pointing code beginning of the block
- code_iterator const m_end = {}; ///< Iterator pointing code end of the block
-
- llvm::BasicBlock* const m_llvmBB;
-
- /// Basic black state vector (stack) - current/end values and their positions on stack
- /// @internal Must be AFTER m_llvmBB
- LocalStack m_stack;
-
- llvm::IRBuilder<>& m_builder;
-
- /// This stack contains LLVM values that correspond to items found at
- /// the EVM stack when the current basic block starts executing.
- /// Location 0 corresponds to the top of the EVM stack, location 1 is
- /// the item below the top and so on. The stack grows as the code
- /// accesses more items on the EVM stack but once a value is put on
- /// the stack, it will never be replaced.
- std::vector m_initialStack;
-
- /// This stack tracks the contents of the EVM stack as the basic block
- /// executes. It may grow on both sides, as the code pushes items on
- /// top of the stack or changes existing items.
- std::vector m_currentStack;
-
- /// How many items higher is the current stack than the initial one.
- /// May be negative.
- int m_tosOffset = 0;
-
- /// Is the basic block a valid jump destination.
- /// JUMPDEST is the first instruction of the basic block.
- bool const m_isJumpDest = false;
+ code_iterator const m_begin = {}; ///< Iterator pointing code beginning of the block
+ code_iterator const m_end = {}; ///< Iterator pointing code end of the block
- /// If block finishes with dynamic jump target index is stored here
- llvm::Value* m_jumpTarget = nullptr;
+ llvm::BasicBlock* const m_llvmBB; ///< Reference to the LLVM BasicBlock
};
}
diff --git a/evmjit/libevmjit/Compiler.cpp b/evmjit/libevmjit/Compiler.cpp
index 61aa464a6..182b5fef8 100644
--- a/evmjit/libevmjit/Compiler.cpp
+++ b/evmjit/libevmjit/Compiler.cpp
@@ -36,7 +36,7 @@ Compiler::Compiler(Options const& _options):
Type::init(m_builder.getContext());
}
-void Compiler::createBasicBlocks(code_iterator _codeBegin, code_iterator _codeEnd)
+std::vector Compiler::createBasicBlocks(code_iterator _codeBegin, code_iterator _codeEnd, llvm::SwitchInst& _jumpTable)
{
/// Helper function that skips push data and finds next iterator (can be the end)
auto skipPushDataAndGetNext = [](code_iterator _curr, code_iterator _end)
@@ -54,8 +54,9 @@ void Compiler::createBasicBlocks(code_iterator _codeBegin, code_iterator _codeEn
if (*(_codeEnd - 1) != static_cast(Instruction::STOP))
break;
+ std::vector blocks;
+
auto begin = _codeBegin; // begin of current block
- bool nextJumpDest = false;
for (auto curr = begin, next = begin; curr != _codeEnd; curr = next)
{
next = skipPushDataAndGetNext(curr, _codeEnd);
@@ -71,10 +72,6 @@ void Compiler::createBasicBlocks(code_iterator _codeBegin, code_iterator _codeEn
isEnd = true;
break;
- case Instruction::JUMPDEST:
- nextJumpDest = true;
- break;
-
default:
break;
}
@@ -86,42 +83,32 @@ void Compiler::createBasicBlocks(code_iterator _codeBegin, code_iterator _codeEn
if (isEnd)
{
auto beginIdx = begin - _codeBegin;
- m_basicBlocks.emplace(std::piecewise_construct, std::forward_as_tuple(beginIdx),
- std::forward_as_tuple(beginIdx, begin, next, m_mainFunc, m_builder, nextJumpDest));
- nextJumpDest = false;
+ blocks.emplace_back(beginIdx, begin, next, m_mainFunc);
+ if (Instruction(*begin) == Instruction::JUMPDEST)
+ _jumpTable.addCase(Constant::get(beginIdx), blocks.back().llvm());
begin = next;
}
}
+
+ return blocks;
}
-llvm::BasicBlock* Compiler::getJumpTableBlock(RuntimeManager& _runtimeManager)
+void Compiler::fillJumpTable()
{
- if (!m_jumpTableBlock)
+ assert(m_jumpTableBB);
+ if (llvm::pred_empty(m_jumpTableBB))
{
- m_jumpTableBlock.reset(new BasicBlock("JumpTable", m_mainFunc, m_builder, true));
- InsertPointGuard g{m_builder};
- m_builder.SetInsertPoint(m_jumpTableBlock->llvm());
- auto dest = m_builder.CreatePHI(Type::Word, 8, "target");
- auto switchInstr = m_builder.CreateSwitch(dest, getBadJumpBlock(_runtimeManager));
- for (auto&& p : m_basicBlocks)
- {
- if (p.second.isJumpDest())
- switchInstr->addCase(Constant::get(p.first), p.second.llvm());
- }
+ m_jumpTableBB->eraseFromParent(); // remove if unused
+ return;
}
- return m_jumpTableBlock->llvm();
-}
-llvm::BasicBlock* Compiler::getBadJumpBlock(RuntimeManager& _runtimeManager)
-{
- if (!m_badJumpBlock)
+ // TODO: Extend this function as `resolveJumps()` and fill gaps in branch instructions.
+ auto target = llvm::cast(m_jumpTableBB->begin());
+ for (auto pred: llvm::predecessors(m_jumpTableBB))
{
- m_badJumpBlock.reset(new BasicBlock("BadJump", m_mainFunc, m_builder, true));
- InsertPointGuard g{m_builder};
- m_builder.SetInsertPoint(m_badJumpBlock->llvm());
- _runtimeManager.exit(ReturnCode::BadJumpDestination);
+ auto targetMd = llvm::cast(pred->getTerminator()->getMetadata("target")->getOperand(0));
+ target->addIncoming(targetMd->getValue(), pred);
}
- return m_badJumpBlock->llvm();
}
std::unique_ptr Compiler::compile(code_iterator _begin, code_iterator _end, std::string const& _id)
@@ -135,16 +122,24 @@ std::unique_ptr Compiler::compile(code_iterator _begin, code_itera
// Create entry basic block
auto entryBlock = llvm::BasicBlock::Create(m_builder.getContext(), {}, m_mainFunc);
+
+ m_stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc);
+ m_abortBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Abort", m_mainFunc);
+ m_jumpTableBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "JumpTable", m_mainFunc);
+ m_builder.SetInsertPoint(m_jumpTableBB);
+ auto target = m_builder.CreatePHI(Type::Word, 16, "target");
+ auto& jumpTable = *m_builder.CreateSwitch(target, m_abortBB);
+
m_builder.SetInsertPoint(entryBlock);
- createBasicBlocks(_begin, _end);
+ auto blocks = createBasicBlocks(_begin, _end, jumpTable);
// Init runtime structures.
RuntimeManager runtimeManager(m_builder, _begin, _end);
GasMeter gasMeter(m_builder, runtimeManager);
Memory memory(runtimeManager, gasMeter);
Ext ext(runtimeManager, memory);
- Stack stack(m_builder, runtimeManager);
+ Stack stack(m_builder);
runtimeManager.setStack(stack); // Runtime Manager will free stack memory
Arith256 arith(m_builder);
@@ -162,87 +157,39 @@ std::unique_ptr Compiler::compile(code_iterator _begin, code_itera
auto normalFlow = m_builder.CreateICmpEQ(r, m_builder.getInt32(0));
runtimeManager.setJmpBuf(jmpBuf);
- // TODO: Create Stop basic block on demand
- m_stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc);
- m_abortBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Abort", m_mainFunc);
-
- auto firstBB = m_basicBlocks.empty() ? m_stopBB : m_basicBlocks.begin()->second.llvm();
+ auto firstBB = blocks.empty() ? m_stopBB : blocks.front().llvm();
m_builder.CreateCondBr(normalFlow, firstBB, m_abortBB, Type::expectTrue);
- for (auto basicBlockPairIt = m_basicBlocks.begin(); basicBlockPairIt != m_basicBlocks.end(); ++basicBlockPairIt)
+ for (auto it = blocks.begin(); it != blocks.end(); ++it)
{
- auto& basicBlock = basicBlockPairIt->second;
- auto iterCopy = basicBlockPairIt;
- ++iterCopy;
- auto nextBasicBlock = (iterCopy != m_basicBlocks.end()) ? iterCopy->second.llvm() : nullptr;
- compileBasicBlock(basicBlock, runtimeManager, arith, memory, ext, gasMeter, nextBasicBlock);
+ // TODO: Rewrite
+ auto nextIt = it + 1;
+ auto nextBasicBlock = (nextIt != blocks.end()) ? nextIt->llvm() : nullptr; // TODO: What with Stop block?
+ compileBasicBlock(*it, runtimeManager, arith, memory, ext, gasMeter, nextBasicBlock, stack, jumpTable);
}
// Code for special blocks:
- // TODO: move to separate function.
m_builder.SetInsertPoint(m_stopBB);
runtimeManager.exit(ReturnCode::Stop);
m_builder.SetInsertPoint(m_abortBB);
runtimeManager.exit(ReturnCode::OutOfGas);
- removeDeadBlocks();
-
- // Link jump table target index
- if (m_jumpTableBlock)
- {
- auto phi = llvm::cast(&m_jumpTableBlock->llvm()->getInstList().front());
- for (auto predIt = llvm::pred_begin(m_jumpTableBlock->llvm()); predIt != llvm::pred_end(m_jumpTableBlock->llvm()); ++predIt)
- {
- BasicBlock* pred = nullptr;
- for (auto&& p : m_basicBlocks)
- {
- if (p.second.llvm() == *predIt)
- {
- pred = &p.second;
- break;
- }
- }
-
- phi->addIncoming(pred->getJumpTarget(), pred->llvm());
- }
- }
-
- dumpCFGifRequired("blocks-init.dot");
-
- if (m_options.optimizeStack)
- {
- std::vector blockList;
- for (auto& entry : m_basicBlocks)
- blockList.push_back(&entry.second);
-
- if (m_jumpTableBlock)
- blockList.push_back(m_jumpTableBlock.get());
-
- BasicBlock::linkLocalStacks(blockList, m_builder);
-
- dumpCFGifRequired("blocks-opt.dot");
- }
-
- for (auto& entry : m_basicBlocks)
- entry.second.synchronizeLocalStack(stack);
- if (m_jumpTableBlock)
- m_jumpTableBlock->synchronizeLocalStack(stack);
-
- dumpCFGifRequired("blocks-sync.dot");
+ fillJumpTable();
return module;
}
void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runtimeManager,
- Arith256& _arith, Memory& _memory, Ext& _ext, GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock)
+ Arith256& _arith, Memory& _memory, Ext& _ext, GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock, Stack& _globalStack,
+ llvm::SwitchInst& jumpTable)
{
if (!_nextBasicBlock) // this is the last block in the code
_nextBasicBlock = m_stopBB;
m_builder.SetInsertPoint(_basicBlock.llvm());
- auto& stack = _basicBlock.localStack();
+ LocalStack stack{_globalStack};
for (auto it = _basicBlock.begin(); it != _basicBlock.end(); ++it)
{
@@ -609,44 +556,23 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti
case Instruction::JUMP:
case Instruction::JUMPI:
{
- llvm::BasicBlock* targetBlock = nullptr;
+ auto jumpBlock = m_jumpTableBB;
auto target = stack.pop();
- if (auto constant = llvm::dyn_cast(target))
- {
- auto&& c = constant->getValue();
- auto targetIdx = c.getActiveBits() <= 64 ? c.getZExtValue() : -1;
- auto it = m_basicBlocks.find(targetIdx);
- targetBlock = (it != m_basicBlocks.end() && it->second.isJumpDest()) ? it->second.llvm() : getBadJumpBlock(_runtimeManager);
- }
+ auto jumpInst = (inst == Instruction::JUMP) ?
+ m_builder.CreateBr(jumpBlock) :
+ m_builder.CreateCondBr(m_builder.CreateICmpNE(stack.pop(), Constant::get(0), "jump.check"), jumpBlock, _nextBasicBlock);
- // TODO: Improve; check for constants
- if (inst == Instruction::JUMP)
+ if (auto constant = llvm::dyn_cast(target))
{
- if (targetBlock)
- {
- m_builder.CreateBr(targetBlock);
- }
- else
- {
- _basicBlock.setJumpTarget(target);
- m_builder.CreateBr(getJumpTableBlock(_runtimeManager));
- }
+ // If target index is a constant do direct jump to the target block.
+ auto bb = jumpTable.findCaseValue(constant).getCaseSuccessor();
+ jumpInst->setSuccessor(0, bb);
}
- else // JUMPI
+ else
{
- auto val = stack.pop();
- auto zero = Constant::get(0);
- auto cond = m_builder.CreateICmpNE(val, zero, "nonzero");
-
- if (targetBlock)
- {
- m_builder.CreateCondBr(cond, targetBlock, _nextBasicBlock);
- }
- else
- {
- _basicBlock.setJumpTarget(target);
- m_builder.CreateCondBr(cond, getJumpTableBlock(_runtimeManager), _nextBasicBlock);
- }
+ // Attach medatada to branch instruction with information about target index.
+ auto targetMd = llvm::MDNode::get(jumpInst->getContext(), llvm::LocalAsMetadata::get(target));
+ jumpInst->setMetadata("target", targetMd);
}
break;
}
@@ -868,109 +794,12 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti
if (!_basicBlock.llvm()->getTerminator())
m_builder.CreateBr(_nextBasicBlock);
- m_builder.SetInsertPoint(_basicBlock.llvm()->getFirstNonPHI());
- _runtimeManager.checkStackLimit(_basicBlock.localStack().getMaxSize(), _basicBlock.localStack().getDiff());
-}
-
-
-
-void Compiler::removeDeadBlocks()
-{
- // Remove dead basic blocks
- auto sthErased = false;
- do
- {
- sthErased = false;
- for (auto it = m_basicBlocks.begin(); it != m_basicBlocks.end();)
- {
- auto llvmBB = it->second.llvm();
- if (llvm::pred_begin(llvmBB) == llvm::pred_end(llvmBB))
- {
- llvmBB->eraseFromParent();
- m_basicBlocks.erase(it++);
- sthErased = true;
- }
- else
- ++it;
- }
- }
- while (sthErased);
-
- if (m_jumpTableBlock && llvm::pred_begin(m_jumpTableBlock->llvm()) == llvm::pred_end(m_jumpTableBlock->llvm()))
- {
- m_jumpTableBlock->llvm()->eraseFromParent();
- m_jumpTableBlock.reset();
- }
-
- if (m_badJumpBlock && llvm::pred_begin(m_badJumpBlock->llvm()) == llvm::pred_end(m_badJumpBlock->llvm()))
- {
- m_badJumpBlock->llvm()->eraseFromParent();
- m_badJumpBlock.reset();
- }
-}
+ stack.finalize(m_builder, *_basicBlock.llvm()); // TODO: Use references
-void Compiler::dumpCFGifRequired(std::string const& _dotfilePath)
-{
- if (! m_options.dumpCFG)
- return;
-
- // TODO: handle i/o failures
- std::ofstream ofs(_dotfilePath);
- dumpCFGtoStream(ofs);
- ofs.close();
+ m_builder.SetInsertPoint(_basicBlock.llvm()->getFirstNonPHI()); // TODO: Move to LocalStack::finalize
+ _runtimeManager.checkStackLimit(stack.minSize(), stack.maxSize(), stack.size());
}
-void Compiler::dumpCFGtoStream(std::ostream& _out)
-{
- _out << "digraph BB {\n"
- << " node [shape=record, fontname=Courier, fontsize=10];\n"
- << " entry [share=record, label=\"entry block\"];\n";
-
- std::vector blocks;
- for (auto& pair : m_basicBlocks)
- blocks.push_back(&pair.second);
- if (m_jumpTableBlock)
- blocks.push_back(m_jumpTableBlock.get());
- if (m_badJumpBlock)
- blocks.push_back(m_badJumpBlock.get());
-
- // std::map phiNodesPerBlock;
-
- // Output nodes
- for (auto bb : blocks)
- {
- std::string blockName = bb->llvm()->getName();
-
- std::ostringstream oss;
- bb->dump(oss, true);
-
- _out << " \"" << blockName << "\" [shape=record, label=\" { " << blockName << "|" << oss.str() << "} \"];\n";
- }
-
- // Output edges
- for (auto bb : blocks)
- {
- std::string blockName = bb->llvm()->getName();
-
- auto end = llvm::pred_end(bb->llvm());
- for (llvm::pred_iterator it = llvm::pred_begin(bb->llvm()); it != end; ++it)
- {
- _out << " \"" << (*it)->getName().str() << "\" -> \"" << blockName << "\" ["
- << ((m_jumpTableBlock.get() && *it == m_jumpTableBlock.get()->llvm()) ? "style = dashed, " : "")
- << "];\n";
- }
- }
-
- _out << "}\n";
-}
-
-void Compiler::dump()
-{
- for (auto& entry : m_basicBlocks)
- entry.second.dump();
- if (m_jumpTableBlock != nullptr)
- m_jumpTableBlock->dump();
-}
}
}
diff --git a/evmjit/libevmjit/Compiler.h b/evmjit/libevmjit/Compiler.h
index 0b31ae0f2..af45acedb 100644
--- a/evmjit/libevmjit/Compiler.h
+++ b/evmjit/libevmjit/Compiler.h
@@ -15,9 +15,6 @@ public:
struct Options
{
- /// Optimize stack operations between basic blocks
- bool optimizeStack = true;
-
/// Rewrite switch instructions to sequences of branches
bool rewriteSwitchToBranches = true;
@@ -25,32 +22,18 @@ public:
bool dumpCFG = false;
};
- using ProgramCounter = uint64_t;
-
Compiler(Options const& _options);
std::unique_ptr compile(code_iterator _begin, code_iterator _end, std::string const& _id);
private:
- void createBasicBlocks(code_iterator _begin, code_iterator _end);
-
- void compileBasicBlock(BasicBlock& _basicBlock, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock);
-
- llvm::BasicBlock* getJumpTableBlock(RuntimeManager& _runtimeManager);
-
- llvm::BasicBlock* getBadJumpBlock(RuntimeManager& _runtimeManager);
+ std::vector createBasicBlocks(code_iterator _begin, code_iterator _end, llvm::SwitchInst& _switchInst);
- void removeDeadBlocks();
+ void compileBasicBlock(BasicBlock& _basicBlock, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter,
+ llvm::BasicBlock* _nextBasicBlock, class Stack& _globalStack, llvm::SwitchInst& _jumpTable);
- /// Dumps basic block graph in graphviz format to a file, if option dumpCFG is enabled.
- void dumpCFGifRequired(std::string const& _dotfilePath);
-
- /// Dumps basic block graph in graphviz format to a stream.
- void dumpCFGtoStream(std::ostream& _out);
-
- /// Dumps all basic blocks to stderr. Useful in a debugging session.
- void dump();
+ void fillJumpTable();
/// Compiler options
Options const& m_options;
@@ -58,9 +41,6 @@ private:
/// Helper class for generating IR
llvm::IRBuilder<> m_builder;
- /// Maps a program counter pc to a basic block that starts at pc (if any).
- std::map m_basicBlocks;
-
/// Stop basic block - terminates execution with STOP code (0)
llvm::BasicBlock* m_stopBB = nullptr;
@@ -68,13 +48,10 @@ private:
llvm::BasicBlock* m_abortBB = nullptr;
/// Block with a jump table.
- std::unique_ptr m_jumpTableBlock;
-
- /// Destination for invalid jumps
- std::unique_ptr m_badJumpBlock;
+ llvm::BasicBlock* m_jumpTableBB = nullptr;
/// Main program function
- llvm::Function* m_mainFunc = nullptr;
+ llvm::Function* m_mainFunc = nullptr; // TODO: Remove
};
}
diff --git a/evmjit/libevmjit/Optimizer.cpp b/evmjit/libevmjit/Optimizer.cpp
index dea3ea2a0..9cc6aa54a 100644
--- a/evmjit/libevmjit/Optimizer.cpp
+++ b/evmjit/libevmjit/Optimizer.cpp
@@ -114,6 +114,7 @@ bool LowerEVMPass::doFinalization(llvm::Module&)
bool prepare(llvm::Module& _module)
{
auto pm = llvm::legacy::PassManager{};
+ pm.add(llvm::createCFGSimplificationPass());
pm.add(llvm::createDeadCodeEliminationPass());
pm.add(new LowerEVMPass{});
return pm.run(_module);
diff --git a/evmjit/libevmjit/RuntimeManager.cpp b/evmjit/libevmjit/RuntimeManager.cpp
index 971f14abd..bce378b64 100644
--- a/evmjit/libevmjit/RuntimeManager.cpp
+++ b/evmjit/libevmjit/RuntimeManager.cpp
@@ -110,8 +110,8 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB
m_gasPtr = m_builder.CreateAlloca(Type::Gas, nullptr, "gas.ptr");
m_builder.CreateStore(m_dataElts[RuntimeData::Index::Gas], m_gasPtr);
- llvm::Type* checkStackLimitArgs[] = {Type::Size->getPointerTo(), Type::Size, Type::Size, Type::BytePtr};
- m_checkStackLimit = llvm::Function::Create(llvm::FunctionType::get(Type::Void, checkStackLimitArgs, false), llvm::Function::PrivateLinkage, "stack.checkSize", getModule());
+ llvm::Type* checkStackLimitArgs[] = {Type::Size->getPointerTo(), Type::Size, Type::Size, Type::Size, Type::BytePtr};
+ m_checkStackLimit = llvm::Function::Create(llvm::FunctionType::get(Type::Void, checkStackLimitArgs, false), llvm::Function::PrivateLinkage, "evm.stack.require", getModule());
m_checkStackLimit->setDoesNotThrow();
m_checkStackLimit->setDoesNotCapture(1);
@@ -121,7 +121,9 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB
auto currSizePtr = &m_checkStackLimit->getArgumentList().front();
currSizePtr->setName("currSize");
- auto max = currSizePtr->getNextNode();
+ auto min = currSizePtr->getNextNode();
+ min->setName("min");
+ auto max = min->getNextNode();
max->setName("max");
auto diff = max->getNextNode();
diff->setName("diff");
@@ -131,8 +133,11 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB
InsertPointGuard guard{m_builder};
m_builder.SetInsertPoint(checkBB);
auto currSize = m_builder.CreateLoad(currSizePtr, "cur");
- auto maxSize = m_builder.CreateNUWAdd(currSize, max, "maxSize");
- auto ok = m_builder.CreateICmpULE(maxSize, m_builder.getInt64(1024), "ok");
+ auto minSize = m_builder.CreateAdd(currSize, min, "minSize", false, true);
+ auto maxSize = m_builder.CreateAdd(currSize, max, "maxSize", true, true);
+ auto minOk = m_builder.CreateICmpSGE(minSize, m_builder.getInt64(0), "min.ok");
+ auto maxOk = m_builder.CreateICmpULE(maxSize, m_builder.getInt64(1024), "max.ok");
+ auto ok = m_builder.CreateAnd(minOk, maxOk, "ok");
m_builder.CreateCondBr(ok, updateBB, outOfStackBB, Type::expectTrue);
m_builder.SetInsertPoint(updateBB);
@@ -145,9 +150,9 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB
m_builder.CreateUnreachable();
}
-void RuntimeManager::checkStackLimit(size_t _max, int _diff)
+void RuntimeManager::checkStackLimit(ssize_t _min, ssize_t _max, ssize_t _diff)
{
- createCall(m_checkStackLimit, {m_stackSize, m_builder.getInt64(_max), m_builder.getInt64(_diff), getJmpBuf()});
+ createCall(m_checkStackLimit, {m_stackSize, m_builder.getInt64(_min), m_builder.getInt64(_max), m_builder.getInt64(_diff), getJmpBuf()});
}
llvm::Value* RuntimeManager::getRuntimePtr()
diff --git a/evmjit/libevmjit/RuntimeManager.h b/evmjit/libevmjit/RuntimeManager.h
index 8c0728aaf..8511c8898 100644
--- a/evmjit/libevmjit/RuntimeManager.h
+++ b/evmjit/libevmjit/RuntimeManager.h
@@ -50,7 +50,7 @@ public:
static llvm::StructType* getRuntimeType();
static llvm::StructType* getRuntimeDataType();
- void checkStackLimit(size_t _max, int _diff);
+ void checkStackLimit(ssize_t _min, ssize_t _max, ssize_t _diff);
private:
llvm::Value* getPtr(RuntimeData::Index _index);
diff --git a/evmjit/libevmjit/Stack.cpp b/evmjit/libevmjit/Stack.cpp
index b7b8f25b1..273aa3855 100644
--- a/evmjit/libevmjit/Stack.cpp
+++ b/evmjit/libevmjit/Stack.cpp
@@ -16,52 +16,14 @@ namespace eth
namespace jit
{
-Stack::Stack(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager):
+Stack::Stack(llvm::IRBuilder<>& _builder):
CompilerHelper(_builder),
- m_runtimeManager(_runtimeManager),
m_stack(_builder, "stack")
{}
-llvm::Function* Stack::getGetFunc()
-{
- auto& func = m_get;
- if (!func)
- {
- llvm::Type* argTypes[] = {Type::Size, Type::Size, Type::BytePtr};
- func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::ExternalLinkage, "stack.require", getModule());
-
- auto index = &func->getArgumentList().front();
- index->setName("index");
- auto size = index->getNextNode();
- size->setName("size");
- auto jmpBuf = size->getNextNode();
- jmpBuf->setName("jmpBuf");
-
- InsertPointGuard guard{m_builder};
- auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), {}, func);
- auto underflowBB = llvm::BasicBlock::Create(m_builder.getContext(), "Underflow", func);
- auto returnBB = llvm::BasicBlock::Create(m_builder.getContext(), "Return", func);
-
- m_builder.SetInsertPoint(entryBB);
- auto underflow = m_builder.CreateICmpUGE(index, size, "underflow");
- m_builder.CreateCondBr(underflow, underflowBB, returnBB);
-
- m_builder.SetInsertPoint(underflowBB);
- m_runtimeManager.abort(jmpBuf);
- m_builder.CreateUnreachable();
-
- m_builder.SetInsertPoint(returnBB);
- m_builder.CreateRetVoid();
- }
- return func;
-}
-
llvm::Value* Stack::get(size_t _index)
{
- createCall(getGetFunc(), {m_builder.getInt64(_index), m_stack.size(), m_runtimeManager.getJmpBuf()});
- auto value = m_stack.get(m_builder.CreateSub(m_stack.size(), m_builder.getInt64(_index + 1)));
- //return m_builder.CreateLoad(valuePtr);
- return value;
+ return m_stack.get(m_builder.CreateSub(m_stack.size(), m_builder.getInt64(_index + 1)));
}
void Stack::set(size_t _index, llvm::Value* _value)
@@ -71,8 +33,6 @@ void Stack::set(size_t _index, llvm::Value* _value)
void Stack::pop(size_t _count)
{
- // FIXME: Pop does not check for stack underflow but looks like not needed
- // We should place stack.require() check and begining of every BB
m_stack.pop(m_builder.getInt64(_count));
}
diff --git a/evmjit/libevmjit/Stack.h b/evmjit/libevmjit/Stack.h
index ad10dae12..72e3d88d2 100644
--- a/evmjit/libevmjit/Stack.h
+++ b/evmjit/libevmjit/Stack.h
@@ -1,7 +1,5 @@
#pragma once
-#include
-
#include "Array.h"
namespace dev
@@ -10,12 +8,11 @@ namespace eth
{
namespace jit
{
-class RuntimeManager;
-class Stack : public CompilerHelper
+class Stack: public CompilerHelper
{
public:
- Stack(llvm::IRBuilder<>& builder, RuntimeManager& runtimeManager);
+ Stack(llvm::IRBuilder<>& builder);
llvm::Value* get(size_t _index);
void set(size_t _index, llvm::Value* _value);
@@ -24,10 +21,6 @@ public:
void free() { m_stack.free(); }
private:
- llvm::Function* getGetFunc();
-
- RuntimeManager& m_runtimeManager;
- llvm::Function* m_get = nullptr;
Array m_stack;
};
@@ -35,5 +28,3 @@ private:
}
}
}
-
-
diff --git a/libethcore/ABI.h b/libethcore/ABI.h
index 7d7be90dd..5b7d160d0 100644
--- a/libethcore/ABI.h
+++ b/libethcore/ABI.h
@@ -43,7 +43,17 @@ template struct ABISerialiser {};
template struct ABISerialiser> { static bytes serialise(FixedHash const& _t) { static_assert(N <= 32, "Cannot serialise hash > 32 bytes."); static_assert(N > 0, "Cannot serialise zero-length hash."); return bytes(32 - N, 0) + _t.asBytes(); } };
template <> struct ABISerialiser { static bytes serialise(u256 const& _t) { return h256(_t).asBytes(); } };
template <> struct ABISerialiser { static bytes serialise(u160 const& _t) { return bytes(12, 0) + h160(_t).asBytes(); } };
-template <> struct ABISerialiser { static bytes serialise(string32 const& _t) { return bytesConstRef((byte const*)_t.data(), 32).toBytes(); } };
+template <> struct ABISerialiser { static bytes serialise(string32 const& _t) { bytes ret; bytesConstRef((byte const*)_t.data(), 32).populate(bytesRef(&ret)); return ret; } };
+template <> struct ABISerialiser
+{
+ static bytes serialise(std::string const& _t)
+ {
+ bytes ret = h256(u256(32)).asBytes() + h256(u256(_t.size())).asBytes();
+ ret.resize(ret.size() + (_t.size() + 31) / 32 * 32);
+ bytesConstRef(&_t).populate(bytesRef(&ret).cropped(64));
+ return ret;
+ }
+};
inline bytes abiInAux() { return {}; }
template bytes abiInAux(T const& _t, U const& ... _u)
@@ -61,6 +71,19 @@ template struct ABIDeserialiser> { static FixedHash
template <> struct ABIDeserialiser { static u256 deserialise(bytesConstRef& io_t) { u256 ret = fromBigEndian(io_t.cropped(0, 32)); io_t = io_t.cropped(32); return ret; } };
template <> struct ABIDeserialiser { static u160 deserialise(bytesConstRef& io_t) { u160 ret = fromBigEndian(io_t.cropped(12, 20)); io_t = io_t.cropped(32); return ret; } };
template <> struct ABIDeserialiser { static string32 deserialise(bytesConstRef& io_t) { string32 ret; io_t.cropped(0, 32).populate(bytesRef((byte*)ret.data(), 32)); io_t = io_t.cropped(32); return ret; } };
+template <> struct ABIDeserialiser
+{
+ static std::string deserialise(bytesConstRef& io_t)
+ {
+ unsigned o = (uint16_t)u256(h256(io_t.cropped(0, 32)));
+ unsigned s = (uint16_t)u256(h256(io_t.cropped(o, 32)));
+ std::string ret;
+ ret.resize(s);
+ io_t.cropped(o + 32, s).populate(bytesRef((byte*)ret.data(), s));
+ io_t = io_t.cropped(32);
+ return ret;
+ }
+};
template T abiOut(bytes const& _data)
{
diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h
index e5e93e5d1..504fb2dbd 100644
--- a/libethereum/ClientBase.h
+++ b/libethereum/ClientBase.h
@@ -148,7 +148,7 @@ public:
using Interface::addresses;
virtual Addresses addresses(BlockNumber _block) const override;
virtual u256 gasLimitRemaining() const override;
- virtual u256 gasBidPrice() const override { return c_defaultGasPrice; }
+ virtual u256 gasBidPrice() const override { return DefaultGasPrice; }
/// Get the coinbase address
virtual Address address() const override;
diff --git a/libethereum/GasPricer.h b/libethereum/GasPricer.h
index 9a89fe94d..47867fee7 100644
--- a/libethereum/GasPricer.h
+++ b/libethereum/GasPricer.h
@@ -40,7 +40,7 @@ enum class TransactionPriority
Highest = 8
};
-static const u256 c_defaultGasPrice = 50 * shannon;
+static const u256 DefaultGasPrice = 50 * shannon;
class GasPricer
{
@@ -68,8 +68,8 @@ public:
u256 bid(TransactionPriority = TransactionPriority::Medium) const override { return m_bid; }
private:
- u256 m_ask = c_defaultGasPrice;
- u256 m_bid = c_defaultGasPrice;
+ u256 m_ask = DefaultGasPrice;
+ u256 m_bid = DefaultGasPrice;
};
}
diff --git a/libethereum/Interface.h b/libethereum/Interface.h
index 9c109000f..ed9659f3b 100644
--- a/libethereum/Interface.h
+++ b/libethereum/Interface.h
@@ -71,25 +71,25 @@ public:
virtual std::pair submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) = 0;
/// Submits the given message-call transaction.
- void submitTransaction(Secret const& _secret, u256 const& _value, Address const& _dest, bytes const& _data = bytes(), u256 const& _gas = 10000, u256 const& _gasPrice = c_defaultGasPrice, u256 const& _nonce = UndefinedU256);
+ void submitTransaction(Secret const& _secret, u256 const& _value, Address const& _dest, bytes const& _data = bytes(), u256 const& _gas = 1000000, u256 const& _gasPrice = DefaultGasPrice, u256 const& _nonce = UndefinedU256);
/// Submits a new contract-creation transaction.
/// @returns the new contract's address (assuming it all goes through).
- Address submitTransaction(Secret const& _secret, u256 const& _endowment, bytes const& _init, u256 const& _gas = 10000, u256 const& _gasPrice = c_defaultGasPrice, u256 const& _nonce = UndefinedU256);
+ Address submitTransaction(Secret const& _secret, u256 const& _endowment, bytes const& _init, u256 const& _gas = 1000000, u256 const& _gasPrice = DefaultGasPrice, u256 const& _nonce = UndefinedU256);
/// Blocks until all pending transactions have been processed.
virtual void flushTransactions() = 0;
/// Makes the given call. Nothing is recorded into the state.
virtual ExecutionResult call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) = 0;
- ExecutionResult call(Address const& _from, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = c_defaultGasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return call(_from, _value, _dest, _data, _gas, _gasPrice, m_default, _ff); }
+ ExecutionResult call(Address const& _from, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 1000000, u256 _gasPrice = DefaultGasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return call(_from, _value, _dest, _data, _gas, _gasPrice, m_default, _ff); }
ExecutionResult call(Secret const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) { return call(toAddress(_secret), _value, _dest, _data, _gas, _gasPrice, _blockNumber, _ff); }
ExecutionResult call(Secret const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return call(toAddress(_secret), _value, _dest, _data, _gas, _gasPrice, _ff); }
/// Does the given creation. Nothing is recorded into the state.
/// @returns the pair of the Address of the created contract together with its code.
virtual ExecutionResult create(Address const& _from, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) = 0;
- ExecutionResult create(Address const& _from, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = c_defaultGasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return create(_from, _value, _data, _gas, _gasPrice, m_default, _ff); }
+ ExecutionResult create(Address const& _from, u256 _value, bytes const& _data = bytes(), u256 _gas = 1000000, u256 _gasPrice = DefaultGasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return create(_from, _value, _data, _gas, _gasPrice, m_default, _ff); }
ExecutionResult create(Secret const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) { return create(toAddress(_secret), _value, _data, _gas, _gasPrice, _blockNumber, _ff); }
ExecutionResult create(Secret const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return create(toAddress(_secret), _value, _data, _gas, _gasPrice, _ff); }
diff --git a/libethereumx/Ethereum.h b/libethereumx/Ethereum.h
index 73392ea88..50eab0de3 100644
--- a/libethereumx/Ethereum.h
+++ b/libethereumx/Ethereum.h
@@ -62,11 +62,11 @@ public:
~Ethereum();
/// Submits the given message-call transaction.
- void submitTransaction(Secret const& _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = c_defaultGasPrice);
+ void submitTransaction(Secret const& _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = DefaultGasPrice);
/// Submits a new contract-creation transaction.
/// @returns the new contract's address (assuming it all goes through).
- Address submitTransaction(Secret const& _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = c_defaultGasPrice);
+ Address submitTransaction(Secret const& _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = DefaultGasPrice);
/// Injects the RLP-encoded transaction given by the _rlp into the transaction queue directly.
void inject(bytesConstRef _rlp);
@@ -75,7 +75,7 @@ public:
void flushTransactions();
/// Makes the given call. Nothing is recorded into the state.
- bytes call(Address const& _from, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = c_defaultGasPrice);
+ bytes call(Address const& _from, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = DefaultGasPrice);
// Informational stuff
diff --git a/libevm/SmartVM.cpp b/libevm/SmartVM.cpp
index 565e88213..965adf13e 100644
--- a/libevm/SmartVM.cpp
+++ b/libevm/SmartVM.cpp
@@ -54,7 +54,7 @@ namespace
bool isStopSentinel()
{
- assert((!code.empty() || !codeHash) && "'empty code => empty hash' invariand failed");
+ assert((!code.empty() || !codeHash) && "'empty code => empty hash' invariant failed");
return code.empty();
}
};
@@ -102,7 +102,7 @@ bytesConstRef SmartVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _
clog(JitInfo) << "JIT: " << codeHash;
vmKind = VMKind::JIT;
}
- else
+ else if (!_ext.code.empty()) // This check is needed for VM tests
{
static JitWorker s_worker;
diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp
index 9086664a4..2356e10be 100644
--- a/libp2p/Host.cpp
+++ b/libp2p/Host.cpp
@@ -530,14 +530,8 @@ void Host::connect(std::shared_ptr const& _p)
return;
}
- if (!!m_nodeTable && !m_nodeTable->haveNode(_p->id))
- {
- // connect was attempted, so try again by adding to node table
- m_nodeTable->addNode(*_p.get());
- // abort unless peer is required
- if (!_p->required)
- return;
- }
+ if (!!m_nodeTable && !m_nodeTable->haveNode(_p->id) && !_p->required)
+ return;
// prevent concurrently connecting to a node
Peer *nptr = _p.get();
diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp
index f5e978971..d5973ce5e 100644
--- a/mix/ClientModel.cpp
+++ b/mix/ClientModel.cpp
@@ -446,9 +446,13 @@ void ClientModel::executeSequence(vector const& _sequence)
if (contractAddressIter == m_contractAddresses.end())
{
emit runFailed("Contract '" + transaction.contractId + tr(" not deployed.") + "' " + tr(" Cannot call ") + transaction.functionId);
- break;
+ Address fakeAddress = Address::random();
+ std::pair contractToken = resolvePair(transaction.contractId);
+ m_contractNames[fakeAddress] = contractToken.first;
+ callAddress(fakeAddress, encoder.encodedData(), transaction); //Transact to a random fake address to that transaction is added to the list anyway
}
- callAddress(contractAddressIter->second, encoder.encodedData(), transaction);
+ else
+ callAddress(contractAddressIter->second, encoder.encodedData(), transaction);
}
m_gasCosts.append(m_client->lastExecution().gasUsed);
onNewTransaction();
@@ -833,9 +837,9 @@ void ClientModel::onNewTransaction()
else
{
//transaction/call
- if (tr.transactionData.size() > 0 && tr.transactionData.front().size() >= 4)
+ if (tr.inputParameters.size() >= 4)
{
- functionHash = FixedHash<4>(tr.transactionData.front().data(), FixedHash<4>::ConstructFromPointer);
+ functionHash = FixedHash<4>(tr.inputParameters.data(), FixedHash<4>::ConstructFromPointer);
function = QString::fromStdString(toJS(functionHash));
abi = true;
}
diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp
index 2d43ddc96..7d2125436 100644
--- a/mix/MixClient.cpp
+++ b/mix/MixClient.cpp
@@ -269,7 +269,7 @@ void MixClient::mine()
RLPStream header;
h.streamRLP(header);
m_postMine.sealBlock(header.out());
- bc().import(m_postMine.blockData(), m_stateDB, (ImportRequirements::Everything & ~ImportRequirements::ValidSeal) != 0);
+ bc().import(m_postMine.blockData(), m_postMine.state().db(), (ImportRequirements::Everything & ~ImportRequirements::ValidSeal) != 0);
m_postMine.sync(bc());
m_preMine = m_postMine;
}
diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp
index 4a3de4dc6..15a5d5633 100644
--- a/test/TestHelper.cpp
+++ b/test/TestHelper.cpp
@@ -253,12 +253,16 @@ void ImportTest::importTransaction(json_spirit::mObject const& o_tr)
importTransaction(o_tr, m_transaction);
}
-void ImportTest::compareStates(State const& _stateExpect, State const& _statePost, AccountMaskMap const _expectedStateOptions, WhenError _throw)
+int ImportTest::compareStates(State const& _stateExpect, State const& _statePost, AccountMaskMap const _expectedStateOptions, WhenError _throw)
{
#define CHECK(a,b) \
{ \
if (_throw == WhenError::Throw) \
- {TBOOST_CHECK_MESSAGE(a,b);}\
+ { \
+ TBOOST_CHECK_MESSAGE(a, b); \
+ if (!a) \
+ return 1; \
+ } \
else \
{TBOOST_WARN_MESSAGE(a,b);} \
}
@@ -309,12 +313,13 @@ void ImportTest::compareStates(State const& _stateExpect, State const& _statePos
"Check State: " << a.first << ": incorrect code '" << toHex(_statePost.code(a.first)) << "', expected '" << toHex(_stateExpect.code(a.first)) << "'");
}
}
+ return 0;
}
-void ImportTest::exportTest(bytes const& _output)
+int ImportTest::exportTest(bytes const& _output)
{
+ int err = 0;
// export output
-
m_testObject["out"] = (_output.size() > 4096 && !Options::get().fulloutput) ? "#" + toString(_output.size()) : toHex(_output, 2, HexPrefix::Add);
// compare expected output with post output
@@ -322,7 +327,12 @@ void ImportTest::exportTest(bytes const& _output)
{
std::string warning = "Check State: Error! Unexpected output: " + m_testObject["out"].get_str() + " Expected: " + m_testObject["expectOut"].get_str();
if (Options::get().checkState)
- {TBOOST_CHECK_MESSAGE((m_testObject["out"].get_str() == m_testObject["expectOut"].get_str()), warning);}
+ {
+ bool statement = (m_testObject["out"].get_str() == m_testObject["expectOut"].get_str());
+ TBOOST_CHECK_MESSAGE(statement, warning);
+ if (!statement)
+ err = 1;
+ }
else
TBOOST_WARN_MESSAGE((m_testObject["out"].get_str() == m_testObject["expectOut"].get_str()), warning);
@@ -350,6 +360,7 @@ void ImportTest::exportTest(bytes const& _output)
m_testObject["pre"] = fillJsonWithState(m_statePre);
m_testObject["env"] = makeAllFieldsHex(m_testObject["env"].get_obj());
m_testObject["transaction"] = makeAllFieldsHex(m_testObject["transaction"].get_obj());
+ return err;
}
json_spirit::mObject fillJsonWithTransaction(Transaction _txn)
@@ -566,7 +577,10 @@ void userDefinedTest(std::function doTests)
auto& filename = Options::get().singleTestFile;
auto& testname = Options::get().singleTestName;
- VerbosityHolder sentinel(12);
+
+ if (g_logVerbosity != -1)
+ VerbosityHolder sentinel(12);
+
try
{
cnote << "Testing user defined test: " << filename;
@@ -631,7 +645,7 @@ void executeTests(const string& _name, const string& _testPathAppendix, const bo
try
{
- std::cout << "TEST " << _name << ":\n";
+ cnote << "TEST " << _name << ":";
json_spirit::mValue v;
string s = asString(dev::contents(testPath + "/" + _name + ".json"));
TBOOST_REQUIRE_MESSAGE((s.length() > 0), "Contents of " + testPath + "/" + _name + ".json is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?");
@@ -773,7 +787,26 @@ Options::Options()
}
else if (arg == "--fulloutput")
fulloutput = true;
+ else if (arg == "--verbosity" && i + 1 < argc)
+ {
+ static std::ostringstream strCout; //static string to redirect logs to
+ std::string indentLevel = std::string{argv[i + 1]};
+ if (indentLevel == "0")
+ {
+ logVerbosity = Verbosity::None;
+ std::cout.rdbuf(strCout.rdbuf());
+ std::cerr.rdbuf(strCout.rdbuf());
+ }
+ else if (indentLevel == "1")
+ logVerbosity = Verbosity::NiceReport;
+ else
+ logVerbosity = Verbosity::Full;
+ }
}
+
+ //Default option
+ if (logVerbosity == Verbosity::NiceReport)
+ g_logVerbosity = -1; //disable cnote but leave cerr and cout
}
Options const& Options::get()
diff --git a/test/TestHelper.h b/test/TestHelper.h
index 5f2f8d6d5..e5cf13233 100644
--- a/test/TestHelper.h
+++ b/test/TestHelper.h
@@ -22,7 +22,6 @@
#pragma once
#include
-
#include
#include
@@ -143,8 +142,8 @@ public:
static json_spirit::mObject& makeAllFieldsHex(json_spirit::mObject& _o);
bytes executeTest();
- void exportTest(bytes const& _output);
- static void compareStates(eth::State const& _stateExpect, eth::State const& _statePost, eth::AccountMaskMap const _expectedStateOptions = eth::AccountMaskMap(), WhenError _throw = WhenError::Throw);
+ int exportTest(bytes const& _output);
+ static int compareStates(eth::State const& _stateExpect, eth::State const& _statePost, eth::AccountMaskMap const _expectedStateOptions = eth::AccountMaskMap(), WhenError _throw = WhenError::Throw);
eth::State m_statePre;
eth::State m_statePost;
@@ -218,6 +217,13 @@ void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs)
TBOOST_CHECK((_expectedAddrs == _resultAddrs));
}*/
+enum class Verbosity
+{
+ Full,
+ NiceReport,
+ None
+};
+
class Options
{
public:
@@ -227,6 +233,7 @@ public:
std::string statsOutFile; ///< Stats output file. "out" for standard output
bool checkState = false;///< Throw error when checking test states
bool fulloutput = false;///< Replace large output to just it's length
+ Verbosity logVerbosity = Verbosity::NiceReport;
/// Test selection
/// @{
diff --git a/test/boostTest.cpp b/test/boostTest.cpp
index 1523a7a11..f448c48e3 100644
--- a/test/boostTest.cpp
+++ b/test/boostTest.cpp
@@ -18,11 +18,75 @@
* @author Marko Simovic
* @date 2014
* Stub for generating main boost.test module.
+ * Original code taken from boost sources.
*/
#define BOOST_TEST_MODULE EthereumTests
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
-#define BOOST_DISABLE_WIN32 //disables SEH warning
+//#define BOOST_DISABLE_WIN32 //disables SEH warning
+#define BOOST_TEST_NO_MAIN
#include
#pragma GCC diagnostic pop
+
+#include
+using namespace boost::unit_test;
+
+//Custom Boost Initialization
+test_suite* init_func( int argc, char* argv[] )
+{
+ if (argc == 0)
+ argv[1]=(char*)"a";
+
+ dev::test::Options::get();
+
+ return 0;
+}
+
+//Custom Boost Unit Test Main
+int main( int argc, char* argv[] )
+{
+ try
+ {
+ framework::init( init_func, argc, argv );
+
+ if( !runtime_config::test_to_run().is_empty() )
+ {
+ test_case_filter filter( runtime_config::test_to_run() );
+
+ traverse_test_tree( framework::master_test_suite().p_id, filter );
+ }
+
+ framework::run();
+
+ results_reporter::make_report();
+
+ return runtime_config::no_result_code()
+ ? boost::exit_success
+ : results_collector.results( framework::master_test_suite().p_id ).result_code();
+ }
+ catch (framework::nothing_to_test const&)
+ {
+ return boost::exit_success;
+ }
+ catch (framework::internal_error const& ex)
+ {
+ results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl;
+
+ return boost::exit_exception_failure;
+ }
+ catch (framework::setup_error const& ex)
+ {
+ results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
+
+ return boost::exit_exception_failure;
+ }
+ catch (...)
+ {
+ results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
+
+ return boost::exit_exception_failure;
+ }
+
+ return 0;
+}
diff --git a/test/fuzzTesting/fuzzHelper.cpp b/test/fuzzTesting/fuzzHelper.cpp
index 863c2477c..63fad5a46 100644
--- a/test/fuzzTesting/fuzzHelper.cpp
+++ b/test/fuzzTesting/fuzzHelper.cpp
@@ -402,13 +402,12 @@ void RandomCodeOptions::setWeights()
opCodeProbability = boostDescreteDistrib(weights);
}
-
BOOST_AUTO_TEST_SUITE(RandomCodeTests)
BOOST_AUTO_TEST_CASE(rndCode)
{
std::string code;
- std::cerr << "Testing Random Code: ";
+ cnote << "Testing Random Code: ";
try
{
code = dev::test::RandomCode::generate(10);
@@ -417,7 +416,7 @@ BOOST_AUTO_TEST_CASE(rndCode)
{
BOOST_ERROR("Exception thrown when generating random code!");
}
- std::cerr << code;
+ cnote << code;
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libdevcore/rlp.cpp b/test/libdevcore/rlp.cpp
index e64621053..d351bb41a 100644
--- a/test/libdevcore/rlp.cpp
+++ b/test/libdevcore/rlp.cpp
@@ -52,6 +52,7 @@ namespace dev
void doRlpTests(json_spirit::mValue& v, bool _fillin)
{
+ string testname;
for (auto& i: v.get_obj())
{
js::mObject& o = i.second.get_obj();
@@ -61,9 +62,11 @@ namespace dev
continue;
}
- cout << " " << i.first << endl;
- TBOOST_REQUIRE((o.count("out") > 0));
- TBOOST_REQUIRE((!o["out"].is_null()));
+ cnote << " " << i.first;
+ testname = "(" + i.first + ") ";
+
+ TBOOST_REQUIRE_MESSAGE((o.count("out") > 0), testname + "out not set!");
+ TBOOST_REQUIRE_MESSAGE((!o["out"].is_null()), testname + "out is set to null!");
if (_fillin)
{
@@ -88,7 +91,7 @@ namespace dev
else
{
//Check Encode
- TBOOST_REQUIRE((o.count("in") > 0));
+ TBOOST_REQUIRE_MESSAGE((o.count("in") > 0), testname + "in not set!");
RlpType rlpType = RlpType::Test;
if (o["in"].type() == js::str_type)
{
@@ -112,7 +115,7 @@ namespace dev
msg << " But Computed: " << computedText;
TBOOST_CHECK_MESSAGE(
(expectedText == computedText),
- msg.str()
+ testname + msg.str()
);
}
@@ -155,11 +158,11 @@ namespace dev
//Check that there was an exception as input is INVALID
if (rlpType == RlpType::Invalid && !was_exception)
- TBOOST_ERROR("Expected RLP Exception as rlp should be invalid!");
+ TBOOST_ERROR(testname + "Expected RLP Exception as rlp should be invalid!");
//input is VALID check that there was no exceptions
if (was_exception)
- TBOOST_ERROR("Unexpected RLP Exception!");
+ TBOOST_ERROR(testname + "Unexpected RLP Exception!");
}
}
}
@@ -256,11 +259,11 @@ BOOST_AUTO_TEST_CASE(EmptyArrayList)
}
catch (Exception const& _e)
{
- TBOOST_ERROR("Failed test with Exception: " << _e.what());
+ TBOOST_ERROR("(EmptyArrayList) Failed test with Exception: " << _e.what());
}
catch (exception const& _e)
{
- TBOOST_ERROR("Failed test with Exception: " << _e.what());
+ TBOOST_ERROR("(EmptyArrayList) Failed test with Exception: " << _e.what());
}
}
@@ -302,11 +305,11 @@ BOOST_AUTO_TEST_CASE(rlpRandom)
catch (Exception const& _e)
{
- TBOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e));
+ TBOOST_ERROR(path.filename().string() + "Failed test with Exception: " << diagnostic_information(_e));
}
catch (std::exception const& _e)
{
- TBOOST_ERROR("Failed test with Exception: " << _e.what());
+ TBOOST_ERROR(path.filename().string() + "Failed test with Exception: " << _e.what());
}
}
}
diff --git a/test/libdevcrypto/AES.cpp b/test/libdevcrypto/AES.cpp
index 0617033aa..3991a7471 100644
--- a/test/libdevcrypto/AES.cpp
+++ b/test/libdevcrypto/AES.cpp
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
using namespace std;
using namespace dev;
@@ -33,7 +34,7 @@ BOOST_AUTO_TEST_SUITE(AES)
BOOST_AUTO_TEST_CASE(AesDecrypt)
{
- cout << "AesDecrypt" << endl;
+ cnote << "AesDecrypt";
bytes seed = fromHex("2dbaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621");
KeyPair kp(sha3Secure(aesDecrypt(&seed, "test")));
BOOST_CHECK(Address("07746f871de684297923f933279555dda418f8a2") == kp.address());
@@ -41,7 +42,7 @@ BOOST_AUTO_TEST_CASE(AesDecrypt)
BOOST_AUTO_TEST_CASE(AesDecryptWrongSeed)
{
- cout << "AesDecryptWrongSeed" << endl;
+ cnote << "AesDecryptWrongSeed";
bytes seed = fromHex("badaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621");
KeyPair kp(sha3Secure(aesDecrypt(&seed, "test")));
BOOST_CHECK(Address("07746f871de684297923f933279555dda418f8a2") != kp.address());
@@ -49,7 +50,7 @@ BOOST_AUTO_TEST_CASE(AesDecryptWrongSeed)
BOOST_AUTO_TEST_CASE(AesDecryptWrongPassword)
{
- cout << "AesDecryptWrongPassword" << endl;
+ cnote << "AesDecryptWrongPassword";
bytes seed = fromHex("2dbaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621");
KeyPair kp(sha3Secure(aesDecrypt(&seed, "badtest")));
BOOST_CHECK(Address("07746f871de684297923f933279555dda418f8a2") != kp.address());
@@ -57,24 +58,23 @@ BOOST_AUTO_TEST_CASE(AesDecryptWrongPassword)
BOOST_AUTO_TEST_CASE(AesDecryptFailInvalidSeed)
{
- cout << "AesDecryptFailInvalidSeed" << endl;
+ cnote << "AesDecryptFailInvalidSeed";
bytes seed = fromHex("xdbaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621");
BOOST_CHECK(bytes() == aesDecrypt(&seed, "test"));
}
BOOST_AUTO_TEST_CASE(AesDecryptFailInvalidSeedSize)
{
- cout << "AesDecryptFailInvalidSeedSize" << endl;
+ cnote << "AesDecryptFailInvalidSeedSize";
bytes seed = fromHex("000102030405060708090a0b0c0d0e0f");
BOOST_CHECK(bytes() == aesDecrypt(&seed, "test"));
}
BOOST_AUTO_TEST_CASE(AesDecryptFailInvalidSeed2)
{
- cout << "AesDecryptFailInvalidSeed2" << endl;
+ cnote << "AesDecryptFailInvalidSeed2";
bytes seed = fromHex("000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f");
BOOST_CHECK(bytes() == aesDecrypt(&seed, "test"));
}
BOOST_AUTO_TEST_SUITE_END()
-
diff --git a/test/libdevcrypto/hexPrefix.cpp b/test/libdevcrypto/hexPrefix.cpp
index 4d89ec594..6c87387cf 100644
--- a/test/libdevcrypto/hexPrefix.cpp
+++ b/test/libdevcrypto/hexPrefix.cpp
@@ -29,7 +29,7 @@
#include
#include
#include
-#include "../TestHelper.h"
+#include
using namespace std;
using namespace dev;
diff --git a/test/libdevcrypto/trie.cpp b/test/libdevcrypto/trie.cpp
index be88c7cee..23fec311b 100644
--- a/test/libdevcrypto/trie.cpp
+++ b/test/libdevcrypto/trie.cpp
@@ -27,7 +27,7 @@
#include
#include
#include "MemTrie.h"
-#include "../TestHelper.h"
+#include
using namespace std;
using namespace dev;
@@ -315,35 +315,35 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
MemoryDB m;
GenericTrieDB t(&m);
t.init(); // initialise as empty tree.
- cout << t;
- cout << m;
- cout << t.root() << endl;
- cout << stringMapHash256(StringMap()) << endl;
+ cnote << t;
+ cnote << m;
+ cnote << t.root();
+ cnote << stringMapHash256(StringMap());
t.insert(string("tesz"), string("test"));
- cout << t;
- cout << m;
- cout << t.root() << endl;
- cout << stringMapHash256({{"test", "test"}}) << endl;
+ cnote << t;
+ cnote << m;
+ cnote << t.root();
+ cnote << stringMapHash256({{"test", "test"}});
t.insert(string("tesa"), string("testy"));
- cout << t;
- cout << m;
- cout << t.root() << endl;
- cout << stringMapHash256({{"test", "test"}, {"te", "testy"}}) << endl;
- cout << t.at(string("test")) << endl;
- cout << t.at(string("te")) << endl;
- cout << t.at(string("t")) << endl;
+ cnote << t;
+ cnote << m;
+ cnote << t.root();
+ cnote << stringMapHash256({{"test", "test"}, {"te", "testy"}});
+ cnote << t.at(string("test"));
+ cnote << t.at(string("te"));
+ cnote << t.at(string("t"));
t.remove(string("te"));
- cout << m;
- cout << t.root() << endl;
- cout << stringMapHash256({{"test", "test"}}) << endl;
+ cnote << m;
+ cnote << t.root();
+ cnote << stringMapHash256({{"test", "test"}});
t.remove(string("test"));
- cout << m;
- cout << t.root() << endl;
- cout << stringMapHash256(StringMap()) << endl;
+ cnote << m;
+ cnote << t.root();
+ cnote << stringMapHash256(StringMap());
}
{
MemoryDB m;
@@ -351,37 +351,37 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
t.init(); // initialise as empty tree.
t.insert(string("a"), string("A"));
t.insert(string("b"), string("B"));
- cout << t;
- cout << m;
- cout << t.root() << endl;
- cout << stringMapHash256({{"b", "B"}, {"a", "A"}}) << endl;
+ cnote << t;
+ cnote << m;
+ cnote << t.root();
+ cnote << stringMapHash256({{"b", "B"}, {"a", "A"}});
bytes r(stringMapRlp256({{"b", "B"}, {"a", "A"}}));
- cout << RLP(r) << endl;
+ cnote << RLP(r);
}
{
MemTrie t;
t.insert("dog", "puppy");
- cout << hex << t.hash256() << endl;
+ cnote << hex << t.hash256();
bytes r(t.rlp());
- cout << RLP(r) << endl;
+ cnote << RLP(r);
}
{
MemTrie t;
t.insert("bed", "d");
t.insert("be", "e");
- cout << hex << t.hash256() << endl;
+ cnote << hex << t.hash256();
bytes r(t.rlp());
- cout << RLP(r) << endl;
+ cnote << RLP(r);
}
{
- cout << hex << stringMapHash256({{"dog", "puppy"}, {"doe", "reindeer"}}) << endl;
+ cnote << hex << stringMapHash256({{"dog", "puppy"}, {"doe", "reindeer"}});
MemTrie t;
t.insert("dog", "puppy");
t.insert("doe", "reindeer");
- cout << hex << t.hash256() << endl;
+ cnote << hex << t.hash256();
bytes r(t.rlp());
- cout << RLP(r) << endl;
- cout << toHex(t.rlp()) << endl;
+ cnote << RLP(r);
+ cnote << toHex(t.rlp());
}
{
MemoryDB m;
@@ -397,12 +397,12 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
t.insert(a, b);
s[a] = b;
- cout << endl << "-------------------------------" << endl;
- cout << a << " -> " << b << endl;
- cout << d;
- cout << m;
- cout << d.root() << endl;
- cout << stringMapHash256(s) << endl;
+ cnote << "/n-------------------------------";
+ cnote << a << " -> " << b;
+ cnote << d;
+ cnote << m;
+ cnote << d.root();
+ cnote << stringMapHash256(s);
BOOST_REQUIRE(d.check(true));
BOOST_REQUIRE_EQUAL(t.hash256(), stringMapHash256(s));
@@ -421,12 +421,12 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
t.remove(a);
d.remove(string(a));
- /*cout << endl << "-------------------------------" << endl;
- cout << "X " << a << endl;
- cout << d;
- cout << m;
- cout << d.root() << endl;
- cout << hash256(s) << endl;*/
+ /*cnote << endl << "-------------------------------";
+ cnote << "X " << a;
+ cnote << d;
+ cnote << m;
+ cnote << d.root();
+ cnote << hash256(s);*/
BOOST_REQUIRE(d.check(true));
BOOST_REQUIRE(t.at(a).empty());
@@ -559,9 +559,11 @@ BOOST_AUTO_TEST_CASE(trieStess)
// for (auto i: dm2.get())
// cwarn << i.first << ": " << RLP(i.second);
d2.debugStructure(cerr);
- g_logVerbosity = 99;
+ if (g_logVerbosity != -1)
+ g_logVerbosity = 99;
d2.remove(k);
- g_logVerbosity = 4;
+ if (g_logVerbosity != -1)
+ g_logVerbosity = 4;
cwarn << "Good?" << d2.root();
}
diff --git a/test/libethcore/dagger.cpp b/test/libethcore/dagger.cpp
index 0473a0136..9841b1b4b 100644
--- a/test/libethcore/dagger.cpp
+++ b/test/libethcore/dagger.cpp
@@ -25,7 +25,7 @@
#include
#include
#include
-#include "../TestHelper.h"
+#include
using namespace std;
using namespace dev;
diff --git a/test/libethereum/blockchain.cpp b/test/libethereum/blockchain.cpp
index 0be4d6622..3ec623685 100644
--- a/test/libethereum/blockchain.cpp
+++ b/test/libethereum/blockchain.cpp
@@ -53,6 +53,7 @@ mArray importUncles(mObject const& _blObj, vector& _vBiUncles, vect
void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
{
+ string testname;
for (auto& i: _v.get_obj())
{
mObject& o = i.second.get_obj();
@@ -62,7 +63,8 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
continue;
}
- cerr << i.first << endl;
+ cnote << i.first;
+ testname = "(" + i.first + ") ";
TBOOST_REQUIRE(o.count("genesisBlockHeader"));
TBOOST_REQUIRE(o.count("pre"));
@@ -81,7 +83,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
if (_fillin)
biGenesisBlock = constructBlock(o["genesisBlockHeader"].get_obj(), trueState.rootHash());
else
- TBOOST_CHECK_MESSAGE((biGenesisBlock.stateRoot() == trueState.rootHash()), "root hash does not match");
+ TBOOST_CHECK_MESSAGE((biGenesisBlock.stateRoot() == trueState.rootHash()), testname + "root hash does not match");
if (_fillin)
{
@@ -381,24 +383,24 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
if (importedAndBest)
{
//Check the fields restored from RLP to original fields
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.headerHash(WithProof) == blockFromRlp.headerHash(WithProof)), "hash in given RLP not matching the block hash!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.parentHash() == blockFromRlp.parentHash()), "parentHash in given RLP not matching the block parentHash!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.sha3Uncles() == blockFromRlp.sha3Uncles()), "sha3Uncles in given RLP not matching the block sha3Uncles!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.beneficiary() == blockFromRlp.beneficiary()),"beneficiary in given RLP not matching the block beneficiary!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.stateRoot() == blockFromRlp.stateRoot()), "stateRoot in given RLP not matching the block stateRoot!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.transactionsRoot() == blockFromRlp.transactionsRoot()), "transactionsRoot in given RLP not matching the block transactionsRoot!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.receiptsRoot() == blockFromRlp.receiptsRoot()), "receiptsRoot in given RLP not matching the block receiptsRoot!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.logBloom() == blockFromRlp.logBloom()), "logBloom in given RLP not matching the block logBloom!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.difficulty() == blockFromRlp.difficulty()), "difficulty in given RLP not matching the block difficulty!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.number() == blockFromRlp.number()), "number in given RLP not matching the block number!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.gasLimit() == blockFromRlp.gasLimit()),"gasLimit in given RLP not matching the block gasLimit!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.gasUsed() == blockFromRlp.gasUsed()), "gasUsed in given RLP not matching the block gasUsed!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.timestamp() == blockFromRlp.timestamp()), "timestamp in given RLP not matching the block timestamp!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.extraData() == blockFromRlp.extraData()), "extraData in given RLP not matching the block extraData!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.mixHash() == blockFromRlp.mixHash()), "mixHash in given RLP not matching the block mixHash!");
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields.nonce() == blockFromRlp.nonce()), "nonce in given RLP not matching the block nonce!");
-
- TBOOST_CHECK_MESSAGE((blockHeaderFromFields == blockFromRlp), "However, blockHeaderFromFields != blockFromRlp!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.headerHash(WithProof) == blockFromRlp.headerHash(WithProof)), testname + "hash in given RLP not matching the block hash!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.parentHash() == blockFromRlp.parentHash()), testname + "parentHash in given RLP not matching the block parentHash!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.sha3Uncles() == blockFromRlp.sha3Uncles()), testname + "sha3Uncles in given RLP not matching the block sha3Uncles!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.beneficiary() == blockFromRlp.beneficiary()), testname + "beneficiary in given RLP not matching the block beneficiary!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.stateRoot() == blockFromRlp.stateRoot()), testname + "stateRoot in given RLP not matching the block stateRoot!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.transactionsRoot() == blockFromRlp.transactionsRoot()), testname + "transactionsRoot in given RLP not matching the block transactionsRoot!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.receiptsRoot() == blockFromRlp.receiptsRoot()), testname + "receiptsRoot in given RLP not matching the block receiptsRoot!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.logBloom() == blockFromRlp.logBloom()), testname + "logBloom in given RLP not matching the block logBloom!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.difficulty() == blockFromRlp.difficulty()), testname + "difficulty in given RLP not matching the block difficulty!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.number() == blockFromRlp.number()), testname + "number in given RLP not matching the block number!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.gasLimit() == blockFromRlp.gasLimit()),"testname + gasLimit in given RLP not matching the block gasLimit!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.gasUsed() == blockFromRlp.gasUsed()), testname + "gasUsed in given RLP not matching the block gasUsed!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.timestamp() == blockFromRlp.timestamp()), testname + "timestamp in given RLP not matching the block timestamp!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.extraData() == blockFromRlp.extraData()), testname + "extraData in given RLP not matching the block extraData!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.mixHash() == blockFromRlp.mixHash()), testname + "mixHash in given RLP not matching the block mixHash!");
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields.nonce() == blockFromRlp.nonce()), testname + "nonce in given RLP not matching the block nonce!");
+
+ TBOOST_CHECK_MESSAGE((blockHeaderFromFields == blockFromRlp), testname + "However, blockHeaderFromFields != blockFromRlp!");
//Check transaction list
@@ -445,18 +447,18 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
for (size_t i = 0; i < txsFromField.size(); ++i)
{
- TBOOST_CHECK_MESSAGE((txsFromField[i].data() == txsFromRlp[i].data()), "transaction data in rlp and in field do not match");
- TBOOST_CHECK_MESSAGE((txsFromField[i].gas() == txsFromRlp[i].gas()), "transaction gasLimit in rlp and in field do not match");
- TBOOST_CHECK_MESSAGE((txsFromField[i].gasPrice() == txsFromRlp[i].gasPrice()), "transaction gasPrice in rlp and in field do not match");
- TBOOST_CHECK_MESSAGE((txsFromField[i].nonce() == txsFromRlp[i].nonce()), "transaction nonce in rlp and in field do not match");
- TBOOST_CHECK_MESSAGE((txsFromField[i].signature().r == txsFromRlp[i].signature().r), "transaction r in rlp and in field do not match");
- TBOOST_CHECK_MESSAGE((txsFromField[i].signature().s == txsFromRlp[i].signature().s), "transaction s in rlp and in field do not match");
- TBOOST_CHECK_MESSAGE((txsFromField[i].signature().v == txsFromRlp[i].signature().v), "transaction v in rlp and in field do not match");
- TBOOST_CHECK_MESSAGE((txsFromField[i].receiveAddress() == txsFromRlp[i].receiveAddress()), "transaction receiveAddress in rlp and in field do not match");
- TBOOST_CHECK_MESSAGE((txsFromField[i].value() == txsFromRlp[i].value()), "transaction receiveAddress in rlp and in field do not match");
-
- TBOOST_CHECK_MESSAGE((txsFromField[i] == txsFromRlp[i]), "transactions from rlp and transaction from field do not match");
- TBOOST_CHECK_MESSAGE((txsFromField[i].rlp() == txsFromRlp[i].rlp()), "transactions rlp do not match");
+ TBOOST_CHECK_MESSAGE((txsFromField[i].data() == txsFromRlp[i].data()), testname + "transaction data in rlp and in field do not match");
+ TBOOST_CHECK_MESSAGE((txsFromField[i].gas() == txsFromRlp[i].gas()), testname + "transaction gasLimit in rlp and in field do not match");
+ TBOOST_CHECK_MESSAGE((txsFromField[i].gasPrice() == txsFromRlp[i].gasPrice()), testname + "transaction gasPrice in rlp and in field do not match");
+ TBOOST_CHECK_MESSAGE((txsFromField[i].nonce() == txsFromRlp[i].nonce()), testname + "transaction nonce in rlp and in field do not match");
+ TBOOST_CHECK_MESSAGE((txsFromField[i].signature().r == txsFromRlp[i].signature().r), testname + "transaction r in rlp and in field do not match");
+ TBOOST_CHECK_MESSAGE((txsFromField[i].signature().s == txsFromRlp[i].signature().s), testname + "transaction s in rlp and in field do not match");
+ TBOOST_CHECK_MESSAGE((txsFromField[i].signature().v == txsFromRlp[i].signature().v), testname + "transaction v in rlp and in field do not match");
+ TBOOST_CHECK_MESSAGE((txsFromField[i].receiveAddress() == txsFromRlp[i].receiveAddress()), testname + "transaction receiveAddress in rlp and in field do not match");
+ TBOOST_CHECK_MESSAGE((txsFromField[i].value() == txsFromRlp[i].value()), testname + "transaction receiveAddress in rlp and in field do not match");
+
+ TBOOST_CHECK_MESSAGE((txsFromField[i] == txsFromRlp[i]), testname + "transactions from rlp and transaction from field do not match");
+ TBOOST_CHECK_MESSAGE((txsFromField[i].rlp() == txsFromRlp[i].rlp()), testname + "transactions rlp do not match");
}
// check uncle list
@@ -477,7 +479,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
}
catch(...)
{
- TBOOST_ERROR("invalid uncle header");
+ TBOOST_ERROR(testname + "invalid uncle header");
}
uBlHsFromField.push_back(uncleBlockHeader);
}
@@ -494,13 +496,13 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
TBOOST_REQUIRE_EQUAL(uBlHsFromField.size(), uBlHsFromRlp.size());
for (size_t i = 0; i < uBlHsFromField.size(); ++i)
- TBOOST_CHECK_MESSAGE((uBlHsFromField[i] == uBlHsFromRlp[i]), "block header in rlp and in field do not match");
+ TBOOST_CHECK_MESSAGE((uBlHsFromField[i] == uBlHsFromRlp[i]), testname + "block header in rlp and in field do not match");
}//importedAndBest
}//all blocks
TBOOST_REQUIRE((o.count("lastblockhash") > 0));
TBOOST_CHECK_MESSAGE((toString(trueBc.info().hash()) == o["lastblockhash"].get_str()),
- "Boost check: " + i.first + " lastblockhash does not match " + toString(trueBc.info().hash()) + " expected: " + o["lastblockhash"].get_str());
+ testname + "Boost check: " + i.first + " lastblockhash does not match " + toString(trueBc.info().hash()) + " expected: " + o["lastblockhash"].get_str());
}
}
}
diff --git a/test/libethereum/gaspricer.cpp b/test/libethereum/gaspricer.cpp
index f5a6b50be..8f54b05ea 100644
--- a/test/libethereum/gaspricer.cpp
+++ b/test/libethereum/gaspricer.cpp
@@ -55,13 +55,13 @@ BOOST_AUTO_TEST_CASE(trivialGasPricer)
{
cnote << "trivialGasPricer";
std::shared_ptr gp(new TrivialGasPricer);
- BOOST_CHECK_EQUAL(gp->ask(Block()), c_defaultGasPrice);
- BOOST_CHECK_EQUAL(gp->bid(), c_defaultGasPrice);
+ BOOST_CHECK_EQUAL(gp->ask(Block()), DefaultGasPrice);
+ BOOST_CHECK_EQUAL(gp->bid(), DefaultGasPrice);
bytes bl = CanonBlockChain::createGenesisBlock();
gp->update(FullBlockChain(bl, AccountMap(), TransientDirectory().path(), WithExisting::Kill));
- BOOST_CHECK_EQUAL(gp->ask(Block()), c_defaultGasPrice);
- BOOST_CHECK_EQUAL(gp->bid(), c_defaultGasPrice);
+ BOOST_CHECK_EQUAL(gp->ask(Block()), DefaultGasPrice);
+ BOOST_CHECK_EQUAL(gp->bid(), DefaultGasPrice);
}
BOOST_AUTO_TEST_CASE(basicGasPricerNoUpdate)
diff --git a/test/libethereum/genesis.cpp b/test/libethereum/genesis.cpp
index 8d4b2878f..aa0825c42 100644
--- a/test/libethereum/genesis.cpp
+++ b/test/libethereum/genesis.cpp
@@ -21,11 +21,13 @@
*/
#include
+#include
+
#include
#include "../JsonSpiritHeaders.h"
#include
#include
-#include "../TestHelper.h"
+#include
using namespace std;
using namespace dev;
diff --git a/test/libethereum/state.cpp b/test/libethereum/state.cpp
index 4c9d998b2..30c0ccff0 100644
--- a/test/libethereum/state.cpp
+++ b/test/libethereum/state.cpp
@@ -41,6 +41,7 @@ namespace dev { namespace test {
void doStateTests(json_spirit::mValue& v, bool _fillin)
{
+ string testname;
for (auto& i: v.get_obj())
{
mObject& o = i.second.get_obj();
@@ -50,10 +51,12 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
continue;
}
- std::cout << " " << i.first << std::endl;
- TBOOST_REQUIRE((o.count("env") > 0));
- TBOOST_REQUIRE((o.count("pre") > 0));
- TBOOST_REQUIRE((o.count("transaction") > 0));
+ cnote << i.first;
+ testname = "(" + i.first + ") ";
+
+ TBOOST_REQUIRE_MESSAGE((o.count("env") > 0), testname + "env not set!");
+ TBOOST_REQUIRE_MESSAGE((o.count("pre") > 0), testname + "pre not set!");
+ TBOOST_REQUIRE_MESSAGE((o.count("transaction") > 0), testname + "transaction not set!");
ImportTest importer(o, _fillin);
const State importedStatePost = importer.m_statePost;
@@ -66,9 +69,10 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
if (_fillin)
{
#if ETH_FATDB
- importer.exportTest(output);
+ if (importer.exportTest(output))
+ cerr << testname << endl;
#else
- BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("You can not fill tests when FATDB is switched off"));
+ BOOST_THROW_EXCEPTION(Exception() << errinfo_comment(testname + "You can not fill tests when FATDB is switched off"));
#endif
}
else
@@ -86,7 +90,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
#if ETH_FATDB
ImportTest::compareStates(importer.m_statePost, importedStatePost);
#endif
- TBOOST_CHECK_MESSAGE((importer.m_statePost.rootHash() == h256(o["postStateRoot"].get_str())), "wrong post state root");
+ TBOOST_CHECK_MESSAGE((importer.m_statePost.rootHash() == h256(o["postStateRoot"].get_str())), testname + "wrong post state root");
}
}
}
@@ -237,11 +241,11 @@ BOOST_AUTO_TEST_CASE(stRandom)
}
catch (Exception const& _e)
{
- BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e));
+ BOOST_ERROR(path.filename().string() + "Failed test with Exception: " << diagnostic_information(_e));
}
catch (std::exception const& _e)
{
- BOOST_ERROR("Failed test with Exception: " << _e.what());
+ BOOST_ERROR(path.filename().string() + "Failed test with Exception: " << _e.what());
}
}
}
diff --git a/test/libethereum/stateOriginal.cpp b/test/libethereum/stateOriginal.cpp
index 21b332762..8ed3b228d 100644
--- a/test/libethereum/stateOriginal.cpp
+++ b/test/libethereum/stateOriginal.cpp
@@ -20,6 +20,7 @@
* State test functions.
*/
+#include
#include
#include
#include
@@ -27,7 +28,6 @@
#include
#include
#include
-#include
using namespace std;
using namespace dev;
diff --git a/test/libethereum/transactionTests.cpp b/test/libethereum/transactionTests.cpp
index f6bde061a..d2f7523b0 100644
--- a/test/libethereum/transactionTests.cpp
+++ b/test/libethereum/transactionTests.cpp
@@ -32,6 +32,7 @@ namespace dev { namespace test {
void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
{
+ string testname;
for (auto& i: _v.get_obj())
{
mObject& o = i.second.get_obj();
@@ -41,7 +42,8 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
continue;
}
- cerr << i.first << endl;
+ testname = "(" + i.first + ") ";
+ cnote << testname;
if (_fillin)
{
TBOOST_REQUIRE((o.count("transaction") > 0));
@@ -55,7 +57,7 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
{
Transaction txFromFields(rlpStream.out(), CheckTransaction::Everything);
if (!txFromFields.signature().isValid())
- BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") );
+ BOOST_THROW_EXCEPTION(Exception() << errinfo_comment(testname + "transaction from RLP signature is invalid") );
o["sender"] = toString(txFromFields.sender());
o["transaction"] = ImportTest::makeAllFieldsHex(tObj);
@@ -69,9 +71,9 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
{
bool expectInValid = (o["expect"].get_str() == "invalid");
if (Options::get().checkState)
- {TBOOST_CHECK_MESSAGE(expectInValid, "Check state: Transaction '" << i.first << "' is expected to be valid!");}
+ {TBOOST_CHECK_MESSAGE(expectInValid, testname + "Check state: Transaction '" << i.first << "' is expected to be valid!");}
else
- {TBOOST_WARN_MESSAGE(expectInValid, "Check state: Transaction '" << i.first << "' is expected to be valid!");}
+ {TBOOST_WARN_MESSAGE(expectInValid, testname + "Check state: Transaction '" << i.first << "' is expected to be valid!");}
o.erase(o.find("expect"));
}
@@ -82,9 +84,9 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
{
bool expectValid = (o["expect"].get_str() == "valid");
if (Options::get().checkState)
- {TBOOST_CHECK_MESSAGE(expectValid, "Check state: Transaction '" << i.first << "' is expected to be invalid!");}
+ {TBOOST_CHECK_MESSAGE(expectValid, testname + "Check state: Transaction '" << i.first << "' is expected to be invalid!");}
else
- {TBOOST_WARN_MESSAGE(expectValid, "Check state: Transaction '" << i.first << "' is expected to be invalid!");}
+ {TBOOST_WARN_MESSAGE(expectValid, testname + "Check state: Transaction '" << i.first << "' is expected to be invalid!");}
o.erase(o.find("expect"));
}
@@ -99,39 +101,39 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
RLP rlp(stream);
txFromRlp = Transaction(rlp.data(), CheckTransaction::Everything);
if (!txFromRlp.signature().isValid())
- BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") );
+ BOOST_THROW_EXCEPTION(Exception() << errinfo_comment(testname + "transaction from RLP signature is invalid") );
}
catch(Exception const& _e)
{
cnote << i.first;
cnote << "Transaction Exception: " << diagnostic_information(_e);
- TBOOST_CHECK_MESSAGE((o.count("transaction") == 0), "A transaction object should not be defined because the RLP is invalid!");
+ TBOOST_CHECK_MESSAGE((o.count("transaction") == 0), testname + "A transaction object should not be defined because the RLP is invalid!");
continue;
}
catch(...)
{
- TBOOST_CHECK_MESSAGE((o.count("transaction") == 0), "A transaction object should not be defined because the RLP is invalid!");
+ TBOOST_CHECK_MESSAGE((o.count("transaction") == 0), testname + "A transaction object should not be defined because the RLP is invalid!");
continue;
}
- TBOOST_REQUIRE((o.count("transaction") > 0));
+ TBOOST_REQUIRE_MESSAGE((o.count("transaction") > 0), testname + "Expected a valid transaction!");
mObject tObj = o["transaction"].get_obj();
Transaction txFromFields(createRLPStreamFromTransactionFields(tObj).out(), CheckTransaction::Everything);
//Check the fields restored from RLP to original fields
- TBOOST_CHECK_MESSAGE((txFromFields.data() == txFromRlp.data()), "Data in given RLP not matching the Transaction data!");
- TBOOST_CHECK_MESSAGE((txFromFields.value() == txFromRlp.value()), "Value in given RLP not matching the Transaction value!");
- TBOOST_CHECK_MESSAGE((txFromFields.gasPrice() == txFromRlp.gasPrice()), "GasPrice in given RLP not matching the Transaction gasPrice!");
- TBOOST_CHECK_MESSAGE((txFromFields.gas() == txFromRlp.gas()),"Gas in given RLP not matching the Transaction gas!");
- TBOOST_CHECK_MESSAGE((txFromFields.nonce() == txFromRlp.nonce()),"Nonce in given RLP not matching the Transaction nonce!");
- TBOOST_CHECK_MESSAGE((txFromFields.receiveAddress() == txFromRlp.receiveAddress()), "Receive address in given RLP not matching the Transaction 'to' address!");
- TBOOST_CHECK_MESSAGE((txFromFields.sender() == txFromRlp.sender()), "Transaction sender address in given RLP not matching the Transaction 'vrs' signature!");
- TBOOST_CHECK_MESSAGE((txFromFields == txFromRlp), "However, txFromFields != txFromRlp!");
+ TBOOST_CHECK_MESSAGE((txFromFields.data() == txFromRlp.data()), testname + "Data in given RLP not matching the Transaction data!");
+ TBOOST_CHECK_MESSAGE((txFromFields.value() == txFromRlp.value()), testname + "Value in given RLP not matching the Transaction value!");
+ TBOOST_CHECK_MESSAGE((txFromFields.gasPrice() == txFromRlp.gasPrice()), testname + "GasPrice in given RLP not matching the Transaction gasPrice!");
+ TBOOST_CHECK_MESSAGE((txFromFields.gas() == txFromRlp.gas()), testname + "Gas in given RLP not matching the Transaction gas!");
+ TBOOST_CHECK_MESSAGE((txFromFields.nonce() == txFromRlp.nonce()), testname + "Nonce in given RLP not matching the Transaction nonce!");
+ TBOOST_CHECK_MESSAGE((txFromFields.receiveAddress() == txFromRlp.receiveAddress()), testname + "Receive address in given RLP not matching the Transaction 'to' address!");
+ TBOOST_CHECK_MESSAGE((txFromFields.sender() == txFromRlp.sender()), testname + "Transaction sender address in given RLP not matching the Transaction 'vrs' signature!");
+ TBOOST_CHECK_MESSAGE((txFromFields == txFromRlp), testname + "However, txFromFields != txFromRlp!");
TBOOST_REQUIRE ((o.count("sender") > 0));
Address addressReaded = Address(o["sender"].get_str());
- TBOOST_CHECK_MESSAGE((txFromFields.sender() == addressReaded || txFromRlp.sender() == addressReaded), "Signature address of sender does not match given sender address!");
+ TBOOST_CHECK_MESSAGE((txFromFields.sender() == addressReaded || txFromRlp.sender() == addressReaded), testname + "Signature address of sender does not match given sender address!");
}
}//for
}//doTransactionTests
diff --git a/test/libevm/VMTestsFiller/vmIOandFlowOperationsTestFiller.json b/test/libevm/VMTestsFiller/vmIOandFlowOperationsTestFiller.json
index ece519112..4dfa41f6a 100644
--- a/test/libevm/VMTestsFiller/vmIOandFlowOperationsTestFiller.json
+++ b/test/libevm/VMTestsFiller/vmIOandFlowOperationsTestFiller.json
@@ -2281,6 +2281,130 @@
}
},
+ "DynamicJump_value1": {
+ "env" : {
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+ "currentNumber" : "0",
+ "currentGasLimit" : "1000000",
+ "currentDifficulty" : "256",
+ "currentTimestamp" : "1",
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "100000000000000000000000",
+ "nonce" : "0",
+ "code" : "(asm 1 2 3 CALLVALUE JUMP
+ JUMPDEST POP POP 0 MSTORE MSIZE 0 RETURN
+ JUMPDEST POP 0 MSTORE MSIZE 0 RETURN
+ JUMPDEST 0 MSTORE MSIZE 0 RETURN)",
+ "storage": {}
+ }
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "8",
+ "data" : "",
+ "gasPrice" : "100000000000000",
+ "gas" : "100000"
+ }
+ },
+
+ "DynamicJump_value2": {
+ "env" : {
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+ "currentNumber" : "0",
+ "currentGasLimit" : "1000000",
+ "currentDifficulty" : "256",
+ "currentTimestamp" : "1",
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "100000000000000000000000",
+ "nonce" : "0",
+ "code" : "(asm 1 2 3 CALLVALUE JUMP
+ JUMPDEST POP POP 0 MSTORE MSIZE 0 RETURN
+ JUMPDEST POP 0 MSTORE MSIZE 0 RETURN
+ JUMPDEST 0 MSTORE MSIZE 0 RETURN)",
+ "storage": {}
+ }
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "18",
+ "data" : "",
+ "gasPrice" : "100000000000000",
+ "gas" : "100000"
+ }
+ },
+
+ "DynamicJump_value3": {
+ "env" : {
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+ "currentNumber" : "0",
+ "currentGasLimit" : "1000000",
+ "currentDifficulty" : "256",
+ "currentTimestamp" : "1",
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "100000000000000000000000",
+ "nonce" : "0",
+ "code" : "(asm 1 2 3 CALLVALUE JUMP
+ JUMPDEST POP POP 0 MSTORE MSIZE 0 RETURN
+ JUMPDEST POP 0 MSTORE MSIZE 0 RETURN
+ JUMPDEST 0 MSTORE MSIZE 0 RETURN)",
+ "storage": {}
+ }
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "27",
+ "data" : "",
+ "gasPrice" : "100000000000000",
+ "gas" : "100000"
+ }
+ },
+
+ "DynamicJump_valueUnderflow": {
+ "env" : {
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+ "currentNumber" : "0",
+ "currentGasLimit" : "1000000",
+ "currentDifficulty" : "256",
+ "currentTimestamp" : "1",
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "100000000000000000000000",
+ "nonce" : "0",
+ "code" : "(asm 1 2 3 CALLVALUE JUMP
+ JUMPDEST POP POP 0 MSTORE MSIZE 0 RETURN
+ JUMPDEST POP 0 MSTORE MSIZE 0 RETURN
+ JUMPDEST POP POP POP 0 MSTORE MSIZE 0 RETURN)",
+ "storage": {}
+ }
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "27",
+ "data" : "",
+ "gasPrice" : "100000000000000",
+ "gas" : "100000"
+ }
+ },
+
"BlockNumberDynamicJumpiAfterStop": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
diff --git a/test/libevm/vm.cpp b/test/libevm/vm.cpp
index 44e0ebe84..ec28f0005 100644
--- a/test/libevm/vm.cpp
+++ b/test/libevm/vm.cpp
@@ -296,6 +296,7 @@ namespace dev { namespace test {
void doVMTests(json_spirit::mValue& v, bool _fillin)
{
+ string testname;
for (auto& i: v.get_obj())
{
mObject& o = i.second.get_obj();
@@ -305,10 +306,12 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
continue;
}
- std::cout << " " << i.first << "\n";
- TBOOST_REQUIRE((o.count("env") > 0));
- TBOOST_REQUIRE((o.count("pre") > 0));
- TBOOST_REQUIRE((o.count("exec") > 0));
+ cnote << i.first;
+ testname = "(" + i.first + ") ";
+
+ TBOOST_REQUIRE_MESSAGE((o.count("env") > 0), testname + "env not set!");
+ TBOOST_REQUIRE_MESSAGE((o.count("pre") > 0), testname + "pre not set!");
+ TBOOST_REQUIRE_MESSAGE((o.count("exec") > 0), testname + "exec not set!");
FakeExtVM fev(eth::EnvInfo{});
fev.importEnv(o["env"].get_obj());
@@ -338,7 +341,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
}
catch (VMException const&)
{
- std::cout << " Safe VM Exception\n";
+ cnote << " Safe VM Exception\n";
vmExceptionOccured = true;
}
catch (Exception const& _e)
@@ -535,7 +538,7 @@ BOOST_AUTO_TEST_CASE(vmRandom)
{
try
{
- std::cout << "TEST " << path.filename() << "\n";
+ cnote << "TEST " << path.filename();
json_spirit::mValue v;
string s = asString(dev::contents(path.string()));
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + path.string() + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?");
diff --git a/test/libevm/vm.h b/test/libevm/vm.h
index c41ebf5dc..c51afbd02 100644
--- a/test/libevm/vm.h
+++ b/test/libevm/vm.h
@@ -26,6 +26,7 @@ along with cpp-ethereum. If not, see .
#include
#include
+#include
#include
#include
@@ -38,7 +39,6 @@ along with cpp-ethereum. If not, see .
#include
#include
#include
-#include
namespace dev { namespace test {
diff --git a/test/libp2p/capability.cpp b/test/libp2p/capability.cpp
index e60f7f131..fffc43c40 100644
--- a/test/libp2p/capability.cpp
+++ b/test/libp2p/capability.cpp
@@ -102,7 +102,9 @@ BOOST_AUTO_TEST_CASE(capability)
if (test::Options::get().nonetwork)
return;
- VerbosityHolder verbosityHolder(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder verbosityHolder(10);
+
cnote << "Testing Capability...";
const char* const localhost = "127.0.0.1";
diff --git a/test/libp2p/peer.cpp b/test/libp2p/peer.cpp
index 43308b450..570c443ec 100644
--- a/test/libp2p/peer.cpp
+++ b/test/libp2p/peer.cpp
@@ -43,7 +43,9 @@ BOOST_AUTO_TEST_CASE(host)
if (test::Options::get().nonetwork)
return;
- VerbosityHolder setTemporaryLevel(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(10);
+
NetworkPreferences host1prefs("127.0.0.1", 30321, false);
NetworkPreferences host2prefs("127.0.0.1", 30322, false);
Host host1("Test", host1prefs);
@@ -88,7 +90,8 @@ BOOST_AUTO_TEST_CASE(saveNodes)
if (test::Options::get().nonetwork)
return;
- VerbosityHolder reduceVerbosity(2);
+ if (g_logVerbosity != -1)
+ VerbosityHolder reduceVerbosity(2);
std::list hosts;
unsigned const c_step = 10;
@@ -152,7 +155,8 @@ BOOST_AUTO_TEST_CASE(requirePeer)
if (test::Options::get().nonetwork)
return;
- VerbosityHolder temporaryLevel(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder reduceVerbosity(10);
unsigned const step = 10;
const char* const localhost = "127.0.0.1";
diff --git a/test/libsolidity/solidityExecutionFramework.h b/test/libsolidity/solidityExecutionFramework.h
index 98241b2ff..05f93bb60 100644
--- a/test/libsolidity/solidityExecutionFramework.h
+++ b/test/libsolidity/solidityExecutionFramework.h
@@ -44,7 +44,9 @@ class ExecutionFramework
public:
ExecutionFramework()
{
- g_logVerbosity = 0;
+ if (g_logVerbosity != -1)
+ g_logVerbosity = 0;
+ //m_state.resetCurrent();
}
bytes const& compileAndRunWithoutCheck(
diff --git a/test/libwhisper/bloomFilter.cpp b/test/libwhisper/bloomFilter.cpp
index d7d4bd849..6516f81b1 100644
--- a/test/libwhisper/bloomFilter.cpp
+++ b/test/libwhisper/bloomFilter.cpp
@@ -106,7 +106,9 @@ BOOST_AUTO_TEST_SUITE(bloomFilter)
BOOST_AUTO_TEST_CASE(falsePositiveRate)
{
- VerbosityHolder setTemporaryLevel(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(10);
+
cnote << "Testing Bloom Filter False Positive Rate...";
TopicBloomFilterTest f;
@@ -124,7 +126,9 @@ BOOST_AUTO_TEST_CASE(falsePositiveRate)
BOOST_AUTO_TEST_CASE(bloomFilterRandom)
{
- VerbosityHolder setTemporaryLevel(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(10);
+
cnote << "Testing Bloom Filter matching...";
TopicBloomFilterShort f;
@@ -150,7 +154,9 @@ BOOST_AUTO_TEST_CASE(bloomFilterRandom)
BOOST_AUTO_TEST_CASE(bloomFilterRaw)
{
- VerbosityHolder setTemporaryLevel(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(10);
+
cnote << "Testing Raw Bloom matching...";
TopicBloomFilterShort f;
diff --git a/test/libwhisper/whisperDB.cpp b/test/libwhisper/whisperDB.cpp
index 3d7b09915..bc56c4b4c 100644
--- a/test/libwhisper/whisperDB.cpp
+++ b/test/libwhisper/whisperDB.cpp
@@ -41,7 +41,9 @@ BOOST_FIXTURE_TEST_SUITE(whisperDB, P2PFixture)
BOOST_AUTO_TEST_CASE(basic)
{
- VerbosityHolder setTemporaryLevel(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(10);
+
cnote << "Testing Whisper DB...";
string s;
@@ -86,7 +88,9 @@ BOOST_AUTO_TEST_CASE(basic)
BOOST_AUTO_TEST_CASE(persistence)
{
- VerbosityHolder setTemporaryLevel(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(10);
+
cnote << "Testing persistence of Whisper DB...";
string s;
@@ -135,7 +139,9 @@ BOOST_AUTO_TEST_CASE(messages)
return;
cnote << "Testing load/save Whisper messages...";
- VerbosityHolder setTemporaryLevel(2);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(2);
+
unsigned const TestSize = 3;
map m1;
map preexisting;
@@ -193,7 +199,9 @@ BOOST_AUTO_TEST_CASE(corruptedData)
return;
cnote << "Testing corrupted data...";
- VerbosityHolder setTemporaryLevel(2);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(2);
+
map m;
h256 x = h256::random();
@@ -222,7 +230,9 @@ BOOST_AUTO_TEST_CASE(filters)
return;
cnote << "Testing filters saving...";
- VerbosityHolder setTemporaryLevel(2);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(2);
+
h256 persistID(0xC0FFEE);
{
diff --git a/test/libwhisper/whisperMessage.cpp b/test/libwhisper/whisperMessage.cpp
index f0c0aedc9..662653540 100644
--- a/test/libwhisper/whisperMessage.cpp
+++ b/test/libwhisper/whisperMessage.cpp
@@ -82,7 +82,9 @@ BOOST_AUTO_TEST_SUITE(whisperMessage)
BOOST_AUTO_TEST_CASE(seal)
{
- VerbosityHolder setTemporaryLevel(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(10);
+
cnote << "Testing Envelope encryption...";
for (unsigned int i = 1; i < 10; ++i)
@@ -91,7 +93,8 @@ BOOST_AUTO_TEST_CASE(seal)
BOOST_AUTO_TEST_CASE(work)
{
- VerbosityHolder setTemporaryLevel(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(10);
cnote << "Testing proof of work...";
Secret zero;
diff --git a/test/libwhisper/whisperTopic.cpp b/test/libwhisper/whisperTopic.cpp
index 39d953e31..0ea7b2dd5 100644
--- a/test/libwhisper/whisperTopic.cpp
+++ b/test/libwhisper/whisperTopic.cpp
@@ -47,7 +47,8 @@ BOOST_AUTO_TEST_CASE(topic)
return;
cnote << "Testing Whisper...";
- VerbosityHolder setTemporaryLevel(0);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(0);
uint16_t port1 = 30311;
Host host1("Test", NetworkPreferences("127.0.0.1", port1, false));
@@ -161,6 +162,7 @@ BOOST_AUTO_TEST_CASE(forwarding)
}
});
+
// Host must be configured not to share peers.
uint16_t port2 = 30313;
Host host2("Forwarder", NetworkPreferences("127.0.0.1", port2, false));
@@ -392,7 +394,9 @@ BOOST_AUTO_TEST_CASE(selfAddressed)
if (test::Options::get().nonetwork)
return;
- VerbosityHolder setTemporaryLevel(10);
+ if (g_logVerbosity != -1)
+ VerbosityHolder setTemporaryLevel(10);
+
cnote << "Testing self-addressed messaging with bloom filter matching...";
char const* text = "deterministic pseudorandom test";