Browse Source

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

cl-refactor
debris 10 years ago
parent
commit
0dc12f8a6d
  1. 27
      alethzero/CMakeLists.txt
  2. 233
      alethzero/Main.ui
  3. 1
      alethzero/MainFace.cpp
  4. 3
      alethzero/MainFace.h
  5. 175
      alethzero/MainWin.cpp
  6. 13
      alethzero/MainWin.h
  7. 2
      alethzero/OurWebThreeStubServer.cpp
  8. 2
      alethzero/Transact.h
  9. 0
      alethzero/plugins/blockchain/AllAccounts.cpp
  10. 0
      alethzero/plugins/blockchain/AllAccounts.h
  11. 0
      alethzero/plugins/blockchain/AllAccounts.ui
  12. 0
      alethzero/plugins/brainwallet/BrainWallet.cpp
  13. 0
      alethzero/plugins/brainwallet/BrainWallet.h
  14. 0
      alethzero/plugins/brainwallet/BrainWallet.ui
  15. 0
      alethzero/plugins/log/LogPanel.cpp
  16. 0
      alethzero/plugins/log/LogPanel.h
  17. 0
      alethzero/plugins/log/LogPanel.ui
  18. 108
      alethzero/plugins/namers/NameRegNamer.cpp
  19. 59
      alethzero/plugins/namers/NameRegNamer.h
  20. 0
      alethzero/plugins/namers/NewAccount.cpp
  21. 0
      alethzero/plugins/namers/NewAccount.h
  22. 0
      alethzero/plugins/namers/NewAccount.ui
  23. 0
      alethzero/plugins/namers/OtherAccounts.cpp
  24. 0
      alethzero/plugins/namers/OtherAccounts.h
  25. 0
      alethzero/plugins/namers/OtherAccounts.ui
  26. 0
      alethzero/plugins/namers/OurAccounts.cpp
  27. 0
      alethzero/plugins/namers/OurAccounts.h
  28. 178
      alethzero/plugins/whisper/Whisper.cpp
  29. 60
      alethzero/plugins/whisper/Whisper.h
  30. 176
      alethzero/plugins/whisper/Whisper.ui
  31. 78
      alethzero/plugins/whisper/WhisperPeers.cpp
  32. 55
      alethzero/plugins/whisper/WhisperPeers.h
  33. 32
      alethzero/plugins/whisper/WhisperPeers.ui
  34. 8
      eth/main.cpp
  35. 5
      evmjit/CMakeLists.txt
  36. 4
      evmjit/include/evmjit/JIT-c.h
  37. 4
      evmjit/include/evmjit/JIT.h
  38. 6
      evmjit/libevmjit-cpp/JitVM.cpp
  39. 12
      evmjit/libevmjit/Array.cpp
  40. 8
      evmjit/libevmjit/Array.h
  41. 358
      evmjit/libevmjit/BasicBlock.cpp
  42. 97
      evmjit/libevmjit/BasicBlock.h
  43. 275
      evmjit/libevmjit/Compiler.cpp
  44. 35
      evmjit/libevmjit/Compiler.h
  45. 1
      evmjit/libevmjit/Optimizer.cpp
  46. 19
      evmjit/libevmjit/RuntimeManager.cpp
  47. 2
      evmjit/libevmjit/RuntimeManager.h
  48. 44
      evmjit/libevmjit/Stack.cpp
  49. 13
      evmjit/libevmjit/Stack.h
  50. 25
      libethcore/ABI.h
  51. 2
      libethereum/ClientBase.h
  52. 6
      libethereum/GasPricer.h
  53. 8
      libethereum/Interface.h
  54. 6
      libethereumx/Ethereum.h
  55. 4
      libevm/SmartVM.cpp
  56. 8
      libp2p/Host.cpp
  57. 10
      mix/ClientModel.cpp
  58. 2
      mix/MixClient.cpp
  59. 45
      test/TestHelper.cpp
  60. 13
      test/TestHelper.h
  61. 66
      test/boostTest.cpp
  62. 5
      test/fuzzTesting/fuzzHelper.cpp
  63. 25
      test/libdevcore/rlp.cpp
  64. 14
      test/libdevcrypto/AES.cpp
  65. 2
      test/libdevcrypto/hexPrefix.cpp
  66. 96
      test/libdevcrypto/trie.cpp
  67. 2
      test/libethcore/dagger.cpp
  68. 70
      test/libethereum/blockchain.cpp
  69. 8
      test/libethereum/gaspricer.cpp
  70. 4
      test/libethereum/genesis.cpp
  71. 22
      test/libethereum/state.cpp
  72. 2
      test/libethereum/stateOriginal.cpp
  73. 40
      test/libethereum/transactionTests.cpp
  74. 124
      test/libevm/VMTestsFiller/vmIOandFlowOperationsTestFiller.json
  75. 15
      test/libevm/vm.cpp
  76. 2
      test/libevm/vm.h
  77. 2
      test/libp2p/capability.cpp
  78. 6
      test/libp2p/peer.cpp
  79. 2
      test/libsolidity/solidityExecutionFramework.h
  80. 6
      test/libwhisper/bloomFilter.cpp
  81. 10
      test/libwhisper/whisperDB.cpp
  82. 3
      test/libwhisper/whisperMessage.cpp
  83. 4
      test/libwhisper/whisperTopic.cpp

27
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
)

233
alethzero/Main.ui

@ -209,12 +209,6 @@
<addaction name="separator"/>
<addaction name="preview"/>
</widget>
<widget class="QMenu" name="menuWhispe">
<property name="title">
<string>&amp;Whisper</string>
</property>
<addaction name="newIdentity"/>
</widget>
<widget class="QMenu" name="menuDebug">
<property name="title">
<string>&amp;Debug</string>
@ -235,7 +229,6 @@
<addaction name="menuView"/>
<addaction name="menuNetwork"/>
<addaction name="menuTools"/>
<addaction name="menuWhispe"/>
<addaction name="menuDebug"/>
<addaction name="menuConfig"/>
<addaction name="menuHelp"/>
@ -978,224 +971,6 @@ font-size: 14pt</string>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_14">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Whisper</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_14">
<layout class="QGridLayout" name="gridLayout_4">
<item row="4" column="0" rowspan="2">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Data</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QLabel" name="label5_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Work to Prove</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="4">
<widget class="QPlainTextEdit" name="shhData">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
</widget>
</item>
<item row="3" column="1" colspan="4">
<widget class="QPlainTextEdit" name="shhTopic">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
</widget>
</item>
<item row="1" column="1" colspan="4">
<widget class="QComboBox" name="shhFrom">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Topic</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label5_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>To</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="QComboBox" name="shhTo">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="shhTtl">
<property name="suffix">
<string> seconds</string>
</property>
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>259200</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label5_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TTL</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label5_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>From</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QSpinBox" name="shhWork">
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QPushButton" name="post">
<property name="text">
<string>Post</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_15">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Active Whispers</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_15">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="whispers">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<action name="quit">
<property name="text">
<string>&amp;Quit</string>
@ -1635,13 +1410,6 @@ font-size: 14pt</string>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>shhTo</tabstop>
<tabstop>shhFrom</tabstop>
<tabstop>shhTtl</tabstop>
<tabstop>shhTopic</tabstop>
<tabstop>shhWork</tabstop>
<tabstop>shhData</tabstop>
<tabstop>post</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>urlEdit</tabstop>
<tabstop>listenIP</tabstop>
@ -1651,7 +1419,6 @@ font-size: 14pt</string>
<tabstop>blockChainFilter</tabstop>
<tabstop>nameReg</tabstop>
<tabstop>nodes</tabstop>
<tabstop>whispers</tabstop>
<tabstop>jsInput</tabstop>
</tabstops>
<resources/>

1
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);
}

3
alethzero/MainFace.h

@ -49,6 +49,7 @@ namespace az
class Plugin;
class MainFace;
class Main;
class OurWebThreeStubServer;
using WatchHandler = std::function<void(dev::eth::LocalisedLogEntries const&)>;
@ -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<dev::shh::WhisperHost> 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;

175
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<Address>(ethereum()->call(c_newConfig, abiIn("lookup(uint256)", (u256)3)).output);
// return abiOut<Address>(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<Plugin> 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<Plugin> p)
{
p->readSettings(s);
});
static_cast<TrivialGasPricer*>(ethereum()->gasPricer().get())->setAsk(u256(s.value("askPrice", QString::fromStdString(toString(c_defaultGasPrice))).toString().toStdString()));
static_cast<TrivialGasPricer*>(ethereum()->gasPricer().get())->setBid(u256(s.value("bidPrice", QString::fromStdString(toString(c_defaultGasPrice))).toString().toStdString()));
static_cast<TrivialGasPricer*>(ethereum()->gasPricer().get())->setAsk(u256(s.value("askPrice", QString::fromStdString(toString(DefaultGasPrice))).toString().toStdString()));
static_cast<TrivialGasPricer*>(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<Public, Secret> 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));

13
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<shh::WhisperHost> whisper() const override { return m_webThree->whisper(); }
@ -96,8 +97,6 @@ public:
std::pair<Address, bytes> fromString(std::string const& _a) const override;
std::string renderDiff(eth::StateDiff const& _d) const override;
QList<KeyPair> 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<KeyPair> m_myIdentities;
eth::KeyManager m_keyManager;
QString m_privateChain;
dev::Address m_nameReg;

2
alethzero/OurWebThreeStubServer.cpp

@ -34,7 +34,7 @@ OurWebThreeStubServer::OurWebThreeStubServer(
jsonrpc::AbstractServerConnector& _conn,
Main* _main
):
WebThreeStubServer(_conn, *_main->web3(), make_shared<OurAccountHolder>(_main), _main->owned().toVector().toStdVector(), _main->keyManager(), *static_cast<TrivialGasPricer*>(_main->ethereum()->gasPricer().get())),
WebThreeStubServer(_conn, *_main->web3(), make_shared<OurAccountHolder>(_main), vector<KeyPair>{}, _main->keyManager(), *static_cast<TrivialGasPricer*>(_main->ethereum()->gasPricer().get())),
m_main(_main)
{
}

2
alethzero/Transact.h

@ -105,6 +105,8 @@ private:
MainFace* m_main = nullptr;
NatSpecFace* m_natSpecDB = nullptr;
bool m_allGood = false;
bool m_determiningGas = false;
};
}

0
alethzero/AllAccounts.cpp → alethzero/plugins/blockchain/AllAccounts.cpp

0
alethzero/AllAccounts.h → alethzero/plugins/blockchain/AllAccounts.h

0
alethzero/AllAccounts.ui → alethzero/plugins/blockchain/AllAccounts.ui

0
alethzero/BrainWallet.cpp → alethzero/plugins/brainwallet/BrainWallet.cpp

0
alethzero/BrainWallet.h → alethzero/plugins/brainwallet/BrainWallet.h

0
alethzero/BrainWallet.ui → alethzero/plugins/brainwallet/BrainWallet.ui

0
alethzero/LogPanel.cpp → alethzero/plugins/log/LogPanel.cpp

0
alethzero/LogPanel.h → alethzero/plugins/log/LogPanel.h

0
alethzero/LogPanel.ui → alethzero/plugins/log/LogPanel.ui

108
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 <http://www.gnu.org/licenses/>.
*/
/** @file NameRegNamer.h
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#include "NameRegNamer.h"
#include <QSettings>
#include <libdevcore/Log.h>
#include <libethereum/Client.h>
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<string>(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<Address>(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&)
{
}

59
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 <http://www.gnu.org/licenses/>.
*/
/** @file NameRegNamer.h
* @author Gav Wood <i@gavwood.com>
* @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<Address, unsigned> m_filters;
mutable Addresses m_knownCache;
// mutable std::unordered_map<Address, std::string> m_forwardCache;
// mutable std::unordered_map<std::string, Address> m_reverseCache;
};
}
}

0
alethzero/NewAccount.cpp → alethzero/plugins/namers/NewAccount.cpp

0
alethzero/NewAccount.h → alethzero/plugins/namers/NewAccount.h

0
alethzero/NewAccount.ui → alethzero/plugins/namers/NewAccount.ui

0
alethzero/OtherAccounts.cpp → alethzero/plugins/namers/OtherAccounts.cpp

0
alethzero/OtherAccounts.h → alethzero/plugins/namers/OtherAccounts.h

0
alethzero/OtherAccounts.ui → alethzero/plugins/namers/OtherAccounts.ui

0
alethzero/OurAccounts.cpp → alethzero/plugins/namers/OurAccounts.cpp

0
alethzero/OurAccounts.h → alethzero/plugins/namers/OurAccounts.h

178
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 <http://www.gnu.org/licenses/>.
*/
/** @file Whisper.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#include "Whisper.h"
#include <QSettings>
#include <libethereum/Client.h>
#include <libethereum/Utility.h>
#include <libwhisper/WhisperHost.h>
#include <libweb3jsonrpc/WebThreeStubServerBase.h>
#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()));
}

60
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 <http://www.gnu.org/licenses/>.
*/
/** @file Whisper.h
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#pragma once
#include <QMutex>
#include <QString>
#include <QPair>
#include <QList>
#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<KeyPair> m_myIdentities;
};
}
}

176
alethzero/plugins/whisper/Whisper.ui

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Whisper</class>
<widget class="QWidget" name="WhisperWidget">
<layout class="QGridLayout" name="gridLayout_4">
<item row="4" column="0" rowspan="2">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Data</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QLabel" name="label5_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Work to Prove</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="4">
<widget class="QPlainTextEdit" name="shhData">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
</widget>
</item>
<item row="3" column="1" colspan="4">
<widget class="QPlainTextEdit" name="shhTopic">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
</widget>
</item>
<item row="1" column="1" colspan="4">
<widget class="QComboBox" name="shhFrom">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Topic</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label5_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>To</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="QComboBox" name="shhTo">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="shhTtl">
<property name="suffix">
<string> seconds</string>
</property>
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>259200</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label5_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TTL</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label5_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>From</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QSpinBox" name="shhWork">
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QPushButton" name="post">
<property name="text">
<string>Post</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

78
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 <http://www.gnu.org/licenses/>.
*/
/** @file WhisperPeers.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#include "WhisperPeers.h"
#include <QSettings>
#include <libethereum/Client.h>
#include <libwhisper/WhisperHost.h>
#include <libweb3jsonrpc/WebThreeStubServerBase.h>
#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<Public, Secret> 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);
}
}

55
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 <http://www.gnu.org/licenses/>.
*/
/** @file WhisperPeers.h
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#pragma once
#include <QMutex>
#include <QString>
#include <QPair>
#include <QList>
#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;
};
}
}

32
alethzero/plugins/whisper/WhisperPeers.ui

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WhisperPeers</class>
<widget class="QWidget" name="whisperPeersWidget">
<layout class="QHBoxLayout" name="whisperPeersLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="whispers">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

8
eth/main.cpp

@ -109,8 +109,8 @@ void help()
/*<< " -B,--block-fees <n> Set the block fee profit in the reference unit e.g. ¢ (default: 15)." << endl
<< " -e,--ether-price <n> Set the ether price in the reference unit e.g. ¢ (default: 30.679)." << endl
<< " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl*/
<< " --ask <wei> Set the minimum ask gas price under which no transactions will be mined (default " << toString(c_defaultGasPrice) << " )." << endl
<< " --bid <wei> Set the bid gas price for to pay for transactions (default " << toString(c_defaultGasPrice) << " )." << endl
<< " --ask <wei> Set the minimum ask gas price under which no transactions will be mined (default " << toString(DefaultGasPrice) << " )." << endl
<< " --bid <wei> Set the bid gas price for to pay for transactions (default " << toString(DefaultGasPrice) << " )." << endl
<< endl
<< "Client mining:" << endl
<< " -a,--address <addr> 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;

5
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)

4
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,

4
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,

6
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;

12
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);
}

8
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:
}
}
}

358
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<llvm::Value*>::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);
return currentStack.end() - _index - 1;
}
if (_index < m_local.size())
return *(m_local.rbegin() + _index); // count from back
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)
{
// Need to fetch a new item from the EVM stack
assert(static_cast<int>(_index) >= m_bblock.m_tosOffset);
size_t initialIdx = _index - m_bblock.m_tosOffset;
if (initialIdx >= initialStack.size())
if (!item)
{
auto nNewItems = 1 + initialIdx - initialStack.size();
initialStack.insert(initialStack.end(), nNewItems, nullptr);
item = m_global.get(idx); // Reach an item from global stack
m_minSize = std::min(m_minSize, -static_cast<ssize_t>(idx) - 1); // and remember required stack size
}
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];
}
return *itemIter;
return item;
}
void BasicBlock::LocalStack::set(size_t _index, llvm::Value* _word)
void LocalStack::set(size_t _index, llvm::Value* _word)
{
auto itemIter = getItemIterator(_index);
*itemIter = _word;
}
void BasicBlock::synchronizeLocalStack(Stack& _evmStack)
{
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<size_t>(idx) < m_initialStack.size());
if (*currIter != m_initialStack[idx]) // value needs update
_evmStack.set(static_cast<size_t>(idx), *currIter);
}
// Pop values
if (m_tosOffset < 0)
_evmStack.pop(static_cast<size_t>(-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<llvm::PHINode>(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<BasicBlock*> basicBlocks, llvm::IRBuilder<>& _builder)
{
struct BBInfo
{
BasicBlock& bblock;
std::vector<BBInfo*> predecessors;
size_t inputItems;
size_t outputItems;
std::vector<llvm::PHINode*> 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<llvm::BasicBlock*, BBInfo> 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)
{
for (auto& pair : cfg)
{
DLOG(bb) << pair.second.bblock.llvm()->getName().str()
<< ": in " << pair.second.inputItems
<< ", out " << pair.second.outputItems
<< "\n";
}
valuesChanged = false;
for (auto& pair : cfg)
{
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;
}
}
}
}
// 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)
{
assert(llvm::isa<llvm::PHINode>(*phiIter));
auto phi = llvm::cast<llvm::PHINode>(*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())
void LocalStack::finalize(llvm::IRBuilder<>& _builder, llvm::BasicBlock& _bb)
{
auto blockTerminator = _bb.getTerminator();
assert(blockTerminator);
if (blockTerminator->getOpcode() != llvm::Instruction::Ret)
{
phi->removeFromParent();
_builder.SetInsertPoint(bblock.llvm(), bblock.llvm()->begin());
_builder.Insert(phi);
}
}
// 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;
}
// Not needed in case of ret instruction. Ret invalidates the stack.
_builder.SetInsertPoint(blockTerminator);
// 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)
// 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 = 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
if (m_input[i])
m_global.set(i, m_input[i]);
}
}
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)
// Add new items
auto pops = m_globalPops; // Copy pops counter to keep original value
for (auto& item: m_local)
{
if (val == nullptr)
out << " ?";
else if (llvm::isa<llvm::ExtractValueInst>(val))
out << " " << val->getName();
else if (llvm::isa<llvm::Instruction>(val))
out << *val;
if (pops) // Override poped global items
m_global.set(--pops, item); // using pops counter as the index
else
out << " " << *val;
out << (_dotOutput ? "\\l" : "\n");
m_global.push(item);
}
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<llvm::ExtractValueInst>(*val))
out << " " << (*val)->getName();
else if (llvm::isa<llvm::Instruction>(*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";
}
}
}
}

97
evmjit/libevmjit/BasicBlock.h

@ -14,12 +14,13 @@ namespace jit
using namespace evmjit;
using instr_idx = uint64_t;
class BasicBlock
class LocalStack
{
public:
class LocalStack
{
public:
explicit LocalStack(Stack& _globalStack);
LocalStack(LocalStack const&) = delete;
void operator=(LocalStack const&) = delete;
/// Pushes value on stack
void push(llvm::Value* _value);
@ -33,33 +34,38 @@ public:
/// @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<ssize_t>(m_local.size()) - static_cast<ssize_t>(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);
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);
std::vector<llvm::Value*>::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<llvm::Value*> 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<llvm::Value*> 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<BasicBlock*> _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<llvm::Value*> 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<llvm::Value*> 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;
/// 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
};
}

275
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<BasicBlock> 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<byte>(Instruction::STOP))
break;
std::vector<BasicBlock> 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)
{
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)
assert(m_jumpTableBB);
if (llvm::pred_empty(m_jumpTableBB))
{
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<llvm::PHINode>(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<llvm::LocalAsMetadata>(pred->getTerminator()->getMetadata("target")->getOperand(0));
target->addIncoming(targetMd->getValue(), pred);
}
return m_badJumpBlock->llvm();
}
std::unique_ptr<llvm::Module> Compiler::compile(code_iterator _begin, code_iterator _end, std::string const& _id)
@ -135,16 +122,24 @@ std::unique_ptr<llvm::Module> 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<llvm::Module> 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<llvm::PHINode>(&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<BasicBlock*> 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<llvm::ConstantInt>(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);
}
// TODO: Improve; check for constants
if (inst == Instruction::JUMP)
{
if (targetBlock)
{
m_builder.CreateBr(targetBlock);
}
else
{
_basicBlock.setJumpTarget(target);
m_builder.CreateBr(getJumpTableBlock(_runtimeManager));
}
}
else // JUMPI
{
auto val = stack.pop();
auto zero = Constant::get(0);
auto cond = m_builder.CreateICmpNE(val, zero, "nonzero");
auto jumpInst = (inst == Instruction::JUMP) ?
m_builder.CreateBr(jumpBlock) :
m_builder.CreateCondBr(m_builder.CreateICmpNE(stack.pop(), Constant::get(0), "jump.check"), jumpBlock, _nextBasicBlock);
if (targetBlock)
if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(target))
{
m_builder.CreateCondBr(cond, targetBlock, _nextBasicBlock);
// If target index is a constant do direct jump to the target block.
auto bb = jumpTable.findCaseValue(constant).getCaseSuccessor();
jumpInst->setSuccessor(0, bb);
}
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();
}
}
void Compiler::dumpCFGifRequired(std::string const& _dotfilePath)
{
if (! m_options.dumpCFG)
return;
stack.finalize(m_builder, *_basicBlock.llvm()); // TODO: Use references
// 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<BasicBlock*> 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<BasicBlock*,int> 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();
}
}
}

35
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<llvm::Module> 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<BasicBlock> 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<ProgramCounter, BasicBlock> 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<BasicBlock> m_jumpTableBlock;
/// Destination for invalid jumps
std::unique_ptr<BasicBlock> m_badJumpBlock;
llvm::BasicBlock* m_jumpTableBB = nullptr;
/// Main program function
llvm::Function* m_mainFunc = nullptr;
llvm::Function* m_mainFunc = nullptr; // TODO: Remove
};
}

1
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);

19
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()

2
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);

44
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));
}

13
evmjit/libevmjit/Stack.h

@ -1,7 +1,5 @@
#pragma once
#include <functional>
#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:
}
}
}

25
libethcore/ABI.h

@ -43,7 +43,17 @@ template <class T> struct ABISerialiser {};
template <unsigned N> struct ABISerialiser<FixedHash<N>> { static bytes serialise(FixedHash<N> 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<u256> { static bytes serialise(u256 const& _t) { return h256(_t).asBytes(); } };
template <> struct ABISerialiser<u160> { static bytes serialise(u160 const& _t) { return bytes(12, 0) + h160(_t).asBytes(); } };
template <> struct ABISerialiser<string32> { static bytes serialise(string32 const& _t) { return bytesConstRef((byte const*)_t.data(), 32).toBytes(); } };
template <> struct ABISerialiser<string32> { static bytes serialise(string32 const& _t) { bytes ret; bytesConstRef((byte const*)_t.data(), 32).populate(bytesRef(&ret)); return ret; } };
template <> struct ABISerialiser<std::string>
{
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 <class T, class ... U> bytes abiInAux(T const& _t, U const& ... _u)
@ -61,6 +71,19 @@ template <unsigned N> struct ABIDeserialiser<FixedHash<N>> { static FixedHash<N>
template <> struct ABIDeserialiser<u256> { static u256 deserialise(bytesConstRef& io_t) { u256 ret = fromBigEndian<u256>(io_t.cropped(0, 32)); io_t = io_t.cropped(32); return ret; } };
template <> struct ABIDeserialiser<u160> { static u160 deserialise(bytesConstRef& io_t) { u160 ret = fromBigEndian<u160>(io_t.cropped(12, 20)); io_t = io_t.cropped(32); return ret; } };
template <> struct ABIDeserialiser<string32> { 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<std::string>
{
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 <class T> T abiOut(bytes const& _data)
{

2
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;

6
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;
};
}

8
libethereum/Interface.h

@ -71,25 +71,25 @@ public:
virtual std::pair<h256, Address> 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); }

6
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

4
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;

8
libp2p/Host.cpp

@ -530,14 +530,8 @@ void Host::connect(std::shared_ptr<Peer> 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)
if (!!m_nodeTable && !m_nodeTable->haveNode(_p->id) && !_p->required)
return;
}
// prevent concurrently connecting to a node
Peer *nptr = _p.get();

10
mix/ClientModel.cpp

@ -446,8 +446,12 @@ void ClientModel::executeSequence(vector<TransactionSettings> 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<QString, int> 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
}
else
callAddress(contractAddressIter->second, encoder.encodedData(), transaction);
}
m_gasCosts.append(m_client->lastExecution().gasUsed);
@ -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;
}

2
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;
}

45
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<void(json_spirit::mValue&, bool)> doTests)
auto& filename = Options::get().singleTestFile;
auto& testname = Options::get().singleTestName;
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()

13
test/TestHelper.h

@ -22,7 +22,6 @@
#pragma once
#include <functional>
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
@ -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
/// @{

66
test/boostTest.cpp

@ -18,11 +18,75 @@
* @author Marko Simovic <markobarko@gmail.com>
* @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 <boost/test/included/unit_test.hpp>
#pragma GCC diagnostic pop
#include <test/TestHelper.h>
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;
}

5
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()

25
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());
}
}
}

14
test/libdevcrypto/AES.cpp

@ -25,6 +25,7 @@
#include <libdevcore/SHA3.h>
#include <libdevcrypto/AES.h>
#include <libdevcore/FixedHash.h>
#include <test/TestHelper.h>
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()

2
test/libdevcrypto/hexPrefix.cpp

@ -29,7 +29,7 @@
#include <libdevcore/CommonIO.h>
#include <libdevcore/Base64.h>
#include <libdevcore/TrieCommon.h>
#include "../TestHelper.h"
#include <test/TestHelper.h>
using namespace std;
using namespace dev;

96
test/libdevcrypto/trie.cpp

@ -27,7 +27,7 @@
#include <libdevcore/TrieDB.h>
#include <libdevcore/TrieHash.h>
#include "MemTrie.h"
#include "../TestHelper.h"
#include <test/TestHelper.h>
using namespace std;
using namespace dev;
@ -315,35 +315,35 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
MemoryDB m;
GenericTrieDB<MemoryDB> 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,8 +559,10 @@ BOOST_AUTO_TEST_CASE(trieStess)
// for (auto i: dm2.get())
// cwarn << i.first << ": " << RLP(i.second);
d2.debugStructure(cerr);
if (g_logVerbosity != -1)
g_logVerbosity = 99;
d2.remove(k);
if (g_logVerbosity != -1)
g_logVerbosity = 4;
cwarn << "Good?" << d2.root();

2
test/libethcore/dagger.cpp

@ -25,7 +25,7 @@
#include <libdevcore/CommonIO.h>
#include <libethcore/EthashAux.h>
#include <boost/test/unit_test.hpp>
#include "../TestHelper.h"
#include <test/TestHelper.h>
using namespace std;
using namespace dev;

70
test/libethereum/blockchain.cpp

@ -53,6 +53,7 @@ mArray importUncles(mObject const& _blObj, vector<BlockHeader>& _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].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]), "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] == 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());
}
}
}

8
test/libethereum/gaspricer.cpp

@ -55,13 +55,13 @@ BOOST_AUTO_TEST_CASE(trivialGasPricer)
{
cnote << "trivialGasPricer";
std::shared_ptr<dev::eth::GasPricer> 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<Ethash>::createGenesisBlock();
gp->update(FullBlockChain<Ethash>(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)

4
test/libethereum/genesis.cpp

@ -21,11 +21,13 @@
*/
#include <fstream>
#include <random>
#include <boost/test/unit_test.hpp>
#include "../JsonSpiritHeaders.h"
#include <libdevcore/CommonIO.h>
#include <libethereum/CanonBlockChain.h>
#include "../TestHelper.h"
#include <test/TestHelper.h>
using namespace std;
using namespace dev;

22
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());
}
}
}

2
test/libethereum/stateOriginal.cpp

@ -20,6 +20,7 @@
* State test functions.
*/
#include <test/TestHelper.h>
#include <boost/test/unit_test.hpp>
#include <boost/filesystem/operations.hpp>
#include <libethereum/CanonBlockChain.h>
@ -27,7 +28,6 @@
#include <libethcore/Farm.h>
#include <libethcore/BasicAuthority.h>
#include <libethereum/Defaults.h>
#include <test/TestHelper.h>
using namespace std;
using namespace dev;

40
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

124
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",

15
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?");

2
test/libevm/vm.h

@ -26,6 +26,7 @@ along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
#include <fstream>
#include <cstdint>
#include <test/TestHelper.h>
#include <boost/test/unit_test.hpp>
#include <json_spirit/json_spirit.h>
@ -38,7 +39,6 @@ along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
#include <libethereum/Transaction.h>
#include <libethereum/ExtVM.h>
#include <libethereum/State.h>
#include <test/TestHelper.h>
namespace dev { namespace test {

2
test/libp2p/capability.cpp

@ -102,7 +102,9 @@ BOOST_AUTO_TEST_CASE(capability)
if (test::Options::get().nonetwork)
return;
if (g_logVerbosity != -1)
VerbosityHolder verbosityHolder(10);
cnote << "Testing Capability...";
const char* const localhost = "127.0.0.1";

6
test/libp2p/peer.cpp

@ -43,7 +43,9 @@ BOOST_AUTO_TEST_CASE(host)
if (test::Options::get().nonetwork)
return;
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,6 +90,7 @@ BOOST_AUTO_TEST_CASE(saveNodes)
if (test::Options::get().nonetwork)
return;
if (g_logVerbosity != -1)
VerbosityHolder reduceVerbosity(2);
std::list<Host*> hosts;
@ -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";

2
test/libsolidity/solidityExecutionFramework.h

@ -44,7 +44,9 @@ class ExecutionFramework
public:
ExecutionFramework()
{
if (g_logVerbosity != -1)
g_logVerbosity = 0;
//m_state.resetCurrent();
}
bytes const& compileAndRunWithoutCheck(

6
test/libwhisper/bloomFilter.cpp

@ -106,7 +106,9 @@ BOOST_AUTO_TEST_SUITE(bloomFilter)
BOOST_AUTO_TEST_CASE(falsePositiveRate)
{
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)
{
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)
{
if (g_logVerbosity != -1)
VerbosityHolder setTemporaryLevel(10);
cnote << "Testing Raw Bloom matching...";
TopicBloomFilterShort f;

10
test/libwhisper/whisperDB.cpp

@ -41,7 +41,9 @@ BOOST_FIXTURE_TEST_SUITE(whisperDB, P2PFixture)
BOOST_AUTO_TEST_CASE(basic)
{
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)
{
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...";
if (g_logVerbosity != -1)
VerbosityHolder setTemporaryLevel(2);
unsigned const TestSize = 3;
map<h256, Envelope> m1;
map<h256, Envelope> preexisting;
@ -193,7 +199,9 @@ BOOST_AUTO_TEST_CASE(corruptedData)
return;
cnote << "Testing corrupted data...";
if (g_logVerbosity != -1)
VerbosityHolder setTemporaryLevel(2);
map<h256, Envelope> m;
h256 x = h256::random();
@ -222,7 +230,9 @@ BOOST_AUTO_TEST_CASE(filters)
return;
cnote << "Testing filters saving...";
if (g_logVerbosity != -1)
VerbosityHolder setTemporaryLevel(2);
h256 persistID(0xC0FFEE);
{

3
test/libwhisper/whisperMessage.cpp

@ -82,7 +82,9 @@ BOOST_AUTO_TEST_SUITE(whisperMessage)
BOOST_AUTO_TEST_CASE(seal)
{
if (g_logVerbosity != -1)
VerbosityHolder setTemporaryLevel(10);
cnote << "Testing Envelope encryption...";
for (unsigned int i = 1; i < 10; ++i)
@ -91,6 +93,7 @@ BOOST_AUTO_TEST_CASE(seal)
BOOST_AUTO_TEST_CASE(work)
{
if (g_logVerbosity != -1)
VerbosityHolder setTemporaryLevel(10);
cnote << "Testing proof of work...";

4
test/libwhisper/whisperTopic.cpp

@ -47,6 +47,7 @@ BOOST_AUTO_TEST_CASE(topic)
return;
cnote << "Testing Whisper...";
if (g_logVerbosity != -1)
VerbosityHolder setTemporaryLevel(0);
uint16_t port1 = 30311;
@ -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;
if (g_logVerbosity != -1)
VerbosityHolder setTemporaryLevel(10);
cnote << "Testing self-addressed messaging with bloom filter matching...";
char const* text = "deterministic pseudorandom test";

Loading…
Cancel
Save