Browse Source

Merge remote-tracking branch 'upstream/develop' into walletTests

cl-refactor
CJentzsch 10 years ago
parent
commit
9cf8e8a986
  1. 25
      CMakeLists.txt
  2. 7
      abi/CMakeLists.txt
  3. 3
      alethzero/CMakeLists.txt
  4. 8
      alethzero/Context.h
  5. 6
      alethzero/DappLoader.cpp
  6. 4
      alethzero/Debugger.cpp
  7. 4
      alethzero/DownloadView.cpp
  8. 4
      alethzero/ExportState.cpp
  9. 195
      alethzero/Main.ui
  10. 250
      alethzero/MainWin.cpp
  11. 20
      alethzero/MainWin.h
  12. 6
      alethzero/OurWebThreeStubServer.cpp
  13. 14
      alethzero/Transact.cpp
  14. 16
      cmake/EthCompilerSettings.cmake
  15. 12
      cmake/EthExecutableHelper.cmake
  16. 7
      eth/CMakeLists.txt
  17. 16
      eth/main.cpp
  18. 6
      ethminer/CMakeLists.txt
  19. 2
      evmjit/libevmjit-cpp/Env.cpp
  20. 90
      exp/main.cpp
  21. 8
      libdevcore/Common.cpp
  22. 20
      libdevcore/Common.h
  23. 5
      libdevcore/FixedHash.h
  24. 13
      libdevcore/Guards.h
  25. 4
      libdevcore/Log.cpp
  26. 14
      libdevcrypto/Common.cpp
  27. 13
      libdevcrypto/Common.h
  28. 4
      libdevcrypto/CryptoPP.cpp
  29. 34
      libethash-cl/ethash_cl_miner.cpp
  30. 7
      libethash-cl/ethash_cl_miner.h
  31. 2
      libethcore/BlockInfo.cpp
  32. 2
      libethcore/CMakeLists.txt
  33. 6
      libethcore/Ethash.cpp
  34. 13
      libethcore/EthashAux.cpp
  35. 2
      libethcore/ICAP.h
  36. 36
      libethcore/Params.cpp
  37. 37
      libethcore/Params.h
  38. 26
      libethereum/BlockChain.cpp
  39. 20
      libethereum/BlockChain.h
  40. 13
      libethereum/BlockDetails.h
  41. 1
      libethereum/CanonBlockChain.cpp
  42. 14
      libethereum/Client.cpp
  43. 5
      libethereum/ClientBase.cpp
  44. 2
      libethereum/ClientBase.h
  45. 2
      libethereum/CommonNet.h
  46. 2
      libethereum/DownloadMan.cpp
  47. 3
      libethereum/DownloadMan.h
  48. 53
      libethereum/EthereumHost.cpp
  49. 4
      libethereum/EthereumHost.h
  50. 67
      libethereum/EthereumPeer.cpp
  51. 2
      libethereum/EthereumPeer.h
  52. 3
      libethereum/Interface.h
  53. 2
      libethereum/Precompiled.cpp
  54. 1
      libethereum/State.h
  55. 2
      libethereum/Transaction.h
  56. 1
      libethereum/TransactionQueue.cpp
  57. 2
      libevm/VM.h
  58. 4
      libevmasm/Assembly.cpp
  59. 4
      libevmasm/Assembly.h
  60. 0
      libevmasm/AssemblyItem.cpp
  61. 2
      libevmasm/AssemblyItem.h
  62. 33
      libevmasm/CMakeLists.txt
  63. 4
      libevmasm/CommonSubexpressionEliminator.cpp
  64. 4
      libevmasm/CommonSubexpressionEliminator.h
  65. 8
      libevmasm/ControlFlowGraph.cpp
  66. 0
      libevmasm/ControlFlowGraph.h
  67. 36
      libevmasm/Exceptions.h
  68. 6
      libevmasm/ExpressionClasses.cpp
  69. 2
      libevmasm/ExpressionClasses.h
  70. 4
      libevmasm/SemanticInformation.cpp
  71. 0
      libevmasm/SemanticInformation.h
  72. 0
      libevmasm/SourceLocation.h
  73. 4
      libevmcore/CMakeLists.txt
  74. 7
      libevmcore/Exceptions.h
  75. 69
      libevmcore/Params.cpp
  76. 69
      libevmcore/Params.h
  77. 2
      libjsqrc/setup.js
  78. 3
      liblll/CMakeLists.txt
  79. 2
      liblll/CodeFragment.h
  80. 23
      libp2p/Host.cpp
  81. 7
      libp2p/Host.h
  82. 2
      libp2p/Network.cpp
  83. 11
      libp2p/NodeTable.cpp
  84. 10
      libp2p/NodeTable.h
  85. 28
      libsolidity/AST.cpp
  86. 2
      libsolidity/AST.h
  87. 2
      libsolidity/ASTUtils.h
  88. 2
      libsolidity/CMakeLists.txt
  89. 7
      libsolidity/Compiler.cpp
  90. 2
      libsolidity/Compiler.h
  91. 2
      libsolidity/CompilerContext.h
  92. 42
      libsolidity/DeclarationContainer.cpp
  93. 4
      libsolidity/DeclarationContainer.h
  94. 18
      libsolidity/Exceptions.h
  95. 2
      libsolidity/ExpressionCompiler.h
  96. 2
      libsolidity/LValue.h
  97. 37
      libsolidity/NameAndTypeResolver.cpp
  98. 2
      libsolidity/Parser.cpp
  99. 2
      libsolidity/Scanner.h
  100. 74
      libsolidity/SourceReferenceFormatter.cpp

25
CMakeLists.txt

@ -305,6 +305,7 @@ endif()
add_subdirectory(libdevcore)
add_subdirectory(libevmcore)
add_subdirectory(libevmasm)
add_subdirectory(liblll)
if (SERPENT)
@ -388,23 +389,37 @@ endif()
if (WIN32)
# packaging stuff
include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "ethereum")
set(CPACK_PACKAGE_NAME "Ethereum")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Ethereum")
set(CPACK_PACKAGE_VENDOR "ethereum.org")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_VERSION "0.7")
set(CPACK_PACKAGE_VERSION "0.9")
set(CPACK_GENERATOR "NSIS")
# seems to be not working
# set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.bmp")
# our stuff
set(CPACK_COMPONENT_ALETHZERO_GROUP "Applications")
set(CPACK_COMPONENT_THIRD_GROUP "Applications")
set(CPACK_COMPONENT_MIX_GROUP "Applications")
set(CPACK_COMPONENTS_ALL alethzero third mix)
set(CPACK_COMPONENT_SOLC_GROUP "CLI")
set(CPACK_COMPONENT_ETH_GROUP "CLI")
set(CPACK_COMPONENT_ETHMINER_GROUP "CLI")
set(CPACK_COMPONENT_RLP_GROUP "CLI")
set(CPACK_COMPONENT_ABI_GROUP "CLI")
set(CPACK_COMPONENTS_ALL alethzero mix solc eth ethminer rlp abi)
# nsis specific stuff
set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ethereum")
if (CMAKE_CL_64)
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (Win64)")
else ()
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
endif()
set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} Ethereum")
set(CPACK_NSIS_HELP_LINK "https://github.com/ethereum/cpp-ethereum")
set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/ethereum/cpp-ethereum")
set(CPACK_NSIS_CONTACT "ethereum.org")

7
abi/CMakeLists.txt

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

3
alethzero/CMakeLists.txt

@ -55,8 +55,7 @@ target_link_libraries(${EXECUTABLE} lll)
if (SOLIDITY)
target_link_libraries(${EXECUTABLE} solidity)
endif ()
target_link_libraries(${EXECUTABLE} evmcore)
target_link_libraries(${EXECUTABLE} devcore)
target_link_libraries(${EXECUTABLE} evmasm)
target_link_libraries(${EXECUTABLE} web3jsonrpc)
target_link_libraries(${EXECUTABLE} jsqrc)
target_link_libraries(${EXECUTABLE} natspec)

8
alethzero/Context.h

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

6
alethzero/DappLoader.cpp

@ -69,7 +69,11 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri)
string32 name = ZeroString32;
QByteArray utf8 = parts[partIndex].toUtf8();
std::copy(utf8.data(), utf8.data() + utf8.size(), name.data());
address = abiOut<Address>(web3()->ethereum()->call(address, abiIn("subRegistrar(bytes32)", name)).output);
if (address != m_nameReg)
address = abiOut<Address>(web3()->ethereum()->call(address, abiIn("subRegistrar(bytes32)", name)).output);
else
address = abiOut<Address>(web3()->ethereum()->call(address, abiIn("register(bytes32)", name)).output);
domainParts.append(parts[partIndex]);
if (!address)
{

4
alethzero/Debugger.cpp

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

4
alethzero/DownloadView.cpp

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

4
alethzero/ExportState.cpp

@ -129,8 +129,8 @@ void ExportStateDialog::fillContracts()
ui->contracts->setEnabled(true);
for (auto i: ethereum()->addresses(m_block))
{
QString r = m_main->render(i);
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(r).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? ui->accounts : ui->contracts))
string r = m_main->render(i);
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? ui->accounts : ui->contracts))
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size));
}
}

195
alethzero/Main.ui

@ -53,23 +53,23 @@
</widget>
</item>
<item>
<widget class="QLabel" name="balance">
<widget class="QLabel" name="blockCount">
<property name="text">
<string>0 wei</string>
<string>1 block</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="peerCount">
<widget class="QLabel" name="balance">
<property name="text">
<string>0 peers</string>
<string>0 wei</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="blockCount">
<widget class="QLabel" name="peerCount">
<property name="text">
<string>1 block</string>
<string>0 peers</string>
</property>
</widget>
</item>
@ -160,8 +160,8 @@
<addaction name="killAccount"/>
<addaction name="separator"/>
<addaction name="loadJS"/>
<addaction name="separator"/>
<addaction name="exportState"/>
<addaction name="separator"/>
<addaction name="exportState"/>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
@ -190,7 +190,6 @@
<string>&amp;View</string>
</property>
<addaction name="showAll"/>
<addaction name="showAllAccounts"/>
<addaction name="separator"/>
<addaction name="preview"/>
</widget>
@ -218,43 +217,6 @@
<addaction name="menu_Debug"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="dockWidget_accounts">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Accounts</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="accounts">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_3">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
@ -294,6 +256,19 @@
</widget>
<widget class="QWidget" name="layoutWidget">
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1">
<widget class="QLineEdit" name="listenIP">
<property name="inputMask">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>Automatic</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
@ -304,16 +279,6 @@
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QSpinBox" name="idealPeers">
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="port">
<property name="minimum">
@ -327,20 +292,21 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="listenIP">
<property name="inputMask">
<string/>
</property>
<item row="3" column="3">
<widget class="QLabel" name="label_2">
<property name="text">
<string/>
<string>Public IP</string>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QLineEdit" name="forcePublicIP">
<property name="placeholderText">
<string>Automatic</string>
</property>
</widget>
</item>
<item row="0" column="0">
<item row="0" column="3">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Ideal &amp;Peers</string>
@ -350,21 +316,7 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="forcePublicIP">
<property name="placeholderText">
<string>Automatic</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Public IP</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>&amp;Client Name</string>
@ -374,13 +326,30 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="0" column="4">
<widget class="QSpinBox" name="idealPeers">
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="clientName">
<property name="placeholderText">
<string>Anonymous</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="5">
<widget class="QLineEdit" name="enode">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
@ -590,18 +559,21 @@
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_contracts">
<widget class="QDockWidget" name="dockWidget_accounts">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Contracts</string>
<string>Accounts</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_6">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
@ -614,12 +586,66 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QLineEdit" name="accountsFilter">
<property name="placeholderText">
<string>Filter...</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="showBasic">
<property name="text">
<string>Basic</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="showContracts">
<property name="text">
<string>Contracts</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="onlyNamed">
<property name="text">
<string>Only Named</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="refreshAccounts">
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QSplitter" name="splitter_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QListWidget" name="contracts">
<widget class="QListWidget" name="accounts">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@ -633,7 +659,7 @@
<enum>QFrame::NoFrame</enum>
</property>
</widget>
<widget class="QPlainTextEdit" name="contractInfo">
<widget class="QPlainTextEdit" name="accountInfo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>2</horstretch>
@ -1482,7 +1508,7 @@ font-size: 14pt</string>
</action>
<action name="exportState">
<property name="text">
<string>&amp;Export State...</string>
<string>&amp;Export State...</string>
</property>
</action>
<action name="debugStepBack">
@ -1732,7 +1758,6 @@ font-size: 14pt</string>
<tabstop>verbosity</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>urlEdit</tabstop>
<tabstop>idealPeers</tabstop>
<tabstop>listenIP</tabstop>
<tabstop>port</tabstop>
<tabstop>transactionQueue</tabstop>

250
alethzero/MainWin.cpp

@ -80,29 +80,29 @@ using namespace dev::p2p;
using namespace dev::eth;
namespace js = json_spirit;
QString Main::fromRaw(h256 _n, unsigned* _inc)
string Main::fromRaw(h256 _n, unsigned* _inc)
{
if (_n)
{
string s((char const*)_n.data(), 32);
auto l = s.find_first_of('\0');
if (!l)
return QString();
return string();
if (l != string::npos)
{
auto p = s.find_first_not_of('\0', l);
if (!(p == string::npos || (_inc && p == 31)))
return QString();
return string();
if (_inc)
*_inc = (byte)s[31];
s.resize(l);
}
for (auto i: s)
if (i < 32)
return QString();
return QString::fromStdString(s);
return string();
return s;
}
return QString();
return string();
}
QString contentsOfQResource(string const& res)
@ -143,11 +143,6 @@ Main::Main(QWidget *parent) :
// ui->log->addItem(QString::fromStdString(s));
};
#if !ETH_FATDB
delete ui->dockWidget_accounts;
delete ui->dockWidget_contracts;
#endif
#if ETH_DEBUG
m_servers.append("127.0.0.1:30300");
#endif
@ -204,6 +199,9 @@ Main::Main(QWidget *parent) :
// QWebEngineInspector* inspector = new QWebEngineInspector();
// inspector->setPage(page);
readSettings();
#if !ETH_FATDB
removeDockWidget(ui->dockWidget_accounts);
#endif
installWatches();
startTimer(100);
@ -398,7 +396,7 @@ void Main::onNewBlock()
// update blockchain dependent views.
refreshBlockCount();
refreshBlockChain();
refreshAccounts();
ui->refreshAccounts->setEnabled(true);
// We must update balances since we can't filter updates to basic accounts.
refreshBalances();
@ -410,7 +408,7 @@ void Main::onNewPending()
// update any pending-transaction dependent views.
refreshPending();
refreshAccounts();
ui->refreshAccounts->setEnabled(true);
}
void Main::on_forceMining_triggered()
@ -510,33 +508,33 @@ static Public stringToPublic(QString const& _a)
return Public();
}
QString Main::pretty(dev::Address _a) const
std::string Main::pretty(dev::Address const& _a) const
{
auto g_newNameReg = getNameReg();
if (g_newNameReg)
{
QString s = QString::fromStdString(toString(abiOut<string32>(ethereum()->call(g_newNameReg, abiIn("getName(address)", _a)).output)));
if (s.size())
return s;
string n = toString(abiOut<string32>(ethereum()->call(g_newNameReg, abiIn("name(address)", _a)).output));
if (!n.empty())
return n;
}
return QString();
return string();
}
QString Main::render(dev::Address _a) const
std::string Main::render(dev::Address const& _a) const
{
QString p = pretty(_a);
QString n;
try {
n = QString::fromStdString(ICAP(_a).encoded());
}
catch (...) {
n = QString::fromStdString(_a.abridged());
}
return p.isEmpty() ? n : (p + " " + n);
string p = pretty(_a);
string n;
if (p.size() == 9 && p.find_first_not_of("QWERYUOPASDFGHJKLZXCVBNM1234567890") == string::npos)
p = ICAP(p, "XREG").encoded();
else
DEV_IGNORE_EXCEPTIONS(n = ICAP(_a).encoded());
if (n.empty())
n = _a.abridged();
return p.empty() ? n : (p + " " + n);
}
pair<Address, bytes> Main::fromString(QString const& _n) const
pair<Address, bytes> Main::fromString(std::string const& _n) const
{
if (_n == "(Create Contract)")
return make_pair(Address(), bytes());
@ -544,7 +542,7 @@ pair<Address, bytes> Main::fromString(QString const& _n) const
auto g_newNameReg = getNameReg();
if (g_newNameReg)
{
Address a = abiOut<Address>(ethereum()->call(g_newNameReg, abiIn("addr(bytes32)", ::toString32(_n.toStdString()))).output);
Address a = abiOut<Address>(ethereum()->call(g_newNameReg, abiIn("addr(bytes32)", ::toString32(_n))).output);
if (a)
return make_pair(a, bytes());
}
@ -552,7 +550,7 @@ pair<Address, bytes> Main::fromString(QString const& _n) const
{
try
{
return make_pair(Address(fromHex(_n.toStdString(), WhenError::Throw)), bytes());
return make_pair(Address(fromHex(_n, WhenError::Throw)), bytes());
}
catch (BadHexCharacter& _e)
{
@ -568,7 +566,7 @@ pair<Address, bytes> Main::fromString(QString const& _n) const
}
else
try {
return ICAP::decoded(_n.toStdString()).address([&](Address const& a, bytes const& b) -> bytes
return ICAP::decoded(_n).address([&](Address const& a, bytes const& b) -> bytes
{
return ethereum()->call(a, b).output;
}, g_newNameReg);
@ -600,7 +598,7 @@ QString Main::lookup(QString const& _a) const
return QString("%1.%2.%3.%4").arg((int)ret[28]).arg((int)ret[29]).arg((int)ret[30]).arg((int)ret[31]);
// TODO: support IPv6.
else if (ret)
return fromRaw(ret);
return QString::fromStdString(fromRaw(ret));
else
return _a;
}
@ -817,7 +815,7 @@ void Main::on_exportKey_triggered()
if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size())
{
auto k = m_myKeys[ui->ourAccounts->currentRow()];
QMessageBox::information(this, "Export Account Key", "Secret key to account " + render(k.address()) + " is:\n" + QString::fromStdString(toHex(k.sec().ref())));
QMessageBox::information(this, "Export Account Key", "Secret key to account " + QString::fromStdString(render(k.address()) + " is:\n" + toHex(k.sec().ref())));
}
}
@ -936,7 +934,7 @@ void Main::refreshBalances()
for (auto i: m_myKeys)
{
u256 b = ethereum()->balanceAt(i.address());
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(b).c_str()).arg(render(i.address())).arg((unsigned)ethereum()->countAt(i.address())), ui->ourAccounts))
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(b).c_str()).arg(QString::fromStdString(render(i.address()))).arg((unsigned)ethereum()->countAt(i.address())), ui->ourAccounts))
->setData(Qt::UserRole, QByteArray((char const*)i.address().data(), Address::size));
totalBalance += b;
@ -968,24 +966,24 @@ void Main::refreshNetwork()
map<h512, QString> sessions;
for (PeerSessionInfo const& i: ps)
ui->peers->addItem(QString("[%8 %7] %3 ms - %1:%2 - %4 %5 %6")
.arg(QString::fromStdString(i.host))
.arg(i.port)
.arg(chrono::duration_cast<chrono::milliseconds>(i.lastPing).count())
.arg(sessions[i.id] = QString::fromStdString(i.clientVersion))
.arg(QString::fromStdString(toString(i.caps)))
.arg(QString::fromStdString(toString(i.notes)))
.arg(i.socketId)
.arg(QString::fromStdString(i.id.abridged())));
.arg(QString::fromStdString(i.host))
.arg(i.port)
.arg(chrono::duration_cast<chrono::milliseconds>(i.lastPing).count())
.arg(sessions[i.id] = QString::fromStdString(i.clientVersion))
.arg(QString::fromStdString(toString(i.caps)))
.arg(QString::fromStdString(toString(i.notes)))
.arg(i.socketId)
.arg(QString::fromStdString(i.id.abridged())));
auto ns = web3()->nodes();
for (p2p::Peer const& i: ns)
ui->nodes->insertItem(sessions.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8")
.arg(QString::fromStdString(i.id.abridged()))
.arg(QString::fromStdString(i.endpoint.address.to_string()))
.arg(i.id == web3()->id() ? "self" : sessions.count(i.id) ? sessions[i.id] : "disconnected")
.arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect())) + " | " + QString::number(i.failedAttempts()) + "x" : "")
.arg(i.rating())
);
.arg(QString::fromStdString(i.id.abridged()))
.arg(QString::fromStdString(i.endpoint.address.to_string()))
.arg(i.id == web3()->id() ? "self" : sessions.count(i.id) ? sessions[i.id] : "disconnected")
.arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect())) + " | " + QString::number(i.failedAttempts()) + "x" : "")
.arg(i.rating())
);
}
}
@ -994,7 +992,7 @@ void Main::refreshAll()
refreshBlockChain();
refreshBlockCount();
refreshPending();
refreshAccounts();
ui->refreshAccounts->setEnabled(true);
refreshBalances();
}
@ -1007,40 +1005,66 @@ void Main::refreshPending()
QString s = t.receiveAddress() ?
QString("%2 %5> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
.arg(render(t.safeSender()))
.arg(render(t.receiveAddress()))
.arg(QString::fromStdString(render(t.safeSender())))
.arg(QString::fromStdString(render(t.receiveAddress())))
.arg((unsigned)t.nonce())
.arg(ethereum()->codeAt(t.receiveAddress()).size() ? '*' : '-') :
QString("%2 +> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
.arg(render(t.safeSender()))
.arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce())))))
.arg(QString::fromStdString(render(t.safeSender())))
.arg(QString::fromStdString(render(right160(sha3(rlpList(t.safeSender(), t.nonce()))))))
.arg((unsigned)t.nonce());
ui->transactionQueue->addItem(s);
}
}
void Main::on_accountsFilter_textChanged()
{
ui->refreshAccounts->setEnabled(true);
}
void Main::on_showBasic_toggled()
{
ui->refreshAccounts->setEnabled(true);
}
void Main::on_showContracts_toggled()
{
ui->refreshAccounts->setEnabled(true);
}
void Main::on_onlyNamed_toggled()
{
ui->refreshAccounts->setEnabled(true);
}
void Main::on_refreshAccounts_clicked()
{
refreshAccounts();
}
void Main::refreshAccounts()
{
#if ETH_FATDB
DEV_TIMED_FUNCTION;
#if ETH_FATDB || !ETH_TRUE
cwatch << "refreshAccounts()";
ui->accounts->clear();
ui->contracts->clear();
for (auto n = 0; n < 2; ++n)
for (auto i: ethereum()->addresses())
{
auto r = render(i);
if (r.contains('(') == !n)
{
if (n == 0 || ui->showAllAccounts->isChecked())
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(r).arg((unsigned)ethereum()->countAt(i)), ui->accounts))
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size));
if (ethereum()->codeAt(i).size())
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(r).arg((unsigned)ethereum()->countAt(i)), ui->contracts))
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size));
}
}
bool showContract = ui->showContracts->isChecked();
bool showBasic = ui->showBasic->isChecked();
bool onlyNamed = ui->onlyNamed->isChecked();
for (auto const& i: ethereum()->addresses())
{
bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3);
if (!((showContract && isContract) || (showBasic && !isContract)))
continue;
string r = render(i);
if (onlyNamed && !(r.find('"') != string::npos || r.substr(0, 2) == "XE"))
continue;
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ui->accounts))
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size));
}
#endif
ui->refreshAccounts->setEnabled(false);
}
void Main::refreshBlockCount()
@ -1057,6 +1081,7 @@ void Main::on_turboMining_triggered()
void Main::refreshBlockChain()
{
DEV_TIMED_FUNCTION;
cwatch << "refreshBlockChain()";
// TODO: keep the same thing highlighted.
@ -1105,14 +1130,14 @@ void Main::refreshBlockChain()
QString s = t.receiveAddress() ?
QString(" %2 %5> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
.arg(render(t.safeSender()))
.arg(render(t.receiveAddress()))
.arg(QString::fromStdString(render(t.safeSender())))
.arg(QString::fromStdString(render(t.receiveAddress())))
.arg((unsigned)t.nonce())
.arg(ethereum()->codeAt(t.receiveAddress()).size() ? '*' : '-') :
QString(" %2 +> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
.arg(render(t.safeSender()))
.arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce())))))
.arg(QString::fromStdString(render(t.safeSender())))
.arg(QString::fromStdString(render(right160(sha3(rlpList(t.safeSender(), t.nonce()))))))
.arg((unsigned)t.nonce());
QListWidgetItem* txItem = new QListWidgetItem(s, ui->blocks);
auto hba = QByteArray((char const*)h.data(), h.size);
@ -1256,7 +1281,7 @@ string Main::renderDiff(StateDiff const& _d) const
s << "<hr/>";
AccountDiff ad = i.second;
s << "<code style=\"white-space: pre; font-weight: bold\">" << lead(ad.changeType()) << " </code>" << " <b>" << render(i.first).toStdString() << "</b>";
s << "<code style=\"white-space: pre; font-weight: bold\">" << lead(ad.changeType()) << " </code>" << " <b>" << render(i.first) << "</b>";
if (!ad.exist.to())
continue;
@ -1289,7 +1314,7 @@ string Main::renderDiff(StateDiff const& _d) const
s << " * ";
s << " </code>";
s << prettyU256(i.first).toStdString();
s << prettyU256(i.first);
/* if (i.first > u256(1) << 246)
s << (h256)i.first;
else if (i.first > u160(1) << 150)
@ -1298,11 +1323,11 @@ string Main::renderDiff(StateDiff const& _d) const
s << hex << i.first;
*/
if (!i.second.from())
s << ": " << prettyU256(i.second.to()).toStdString();
s << ": " << prettyU256(i.second.to());
else if (!i.second.to())
s << " (" << prettyU256(i.second.from()).toStdString() << ")";
s << " (" << prettyU256(i.second.from()) << ")";
else
s << ": " << prettyU256(i.second.to()).toStdString() << " (" << prettyU256(i.second.from()).toStdString() << ")";
s << ": " << prettyU256(i.second.to()) << " (" << prettyU256(i.second.from()) << ")";
}
}
return s.str();
@ -1321,11 +1346,11 @@ void Main::on_transactionQueue_currentItemChanged()
auto ss = tx.safeSender();
h256 th = sha3(rlpList(ss, tx.nonce()));
s << "<h3>" << th << "</h3>";
s << "From: <b>" << pretty(ss).toStdString() << "</b> " << ss;
s << "From: <b>" << pretty(ss) << "</b> " << ss;
if (tx.isCreation())
s << "<br/>Creates: <b>" << pretty(right160(th)).toStdString() << "</b> " << right160(th);
s << "<br/>Creates: <b>" << pretty(right160(th)) << "</b> " << right160(th);
else
s << "<br/>To: <b>" << pretty(tx.receiveAddress()).toStdString() << "</b> " << tx.receiveAddress();
s << "<br/>To: <b>" << pretty(tx.receiveAddress()) << "</b> " << tx.receiveAddress();
s << "<br/>Value: <b>" << formatBalance(tx.value()) << "</b>";
s << "&nbsp;&emsp;&nbsp;#<b>" << tx.nonce() << "</b>";
s << "<br/>Gas price: <b>" << formatBalance(tx.gasPrice()) << "</b>";
@ -1413,6 +1438,11 @@ void Main::on_injectBlock_triggered()
}
}
static string htmlEscaped(string const& _s)
{
return QString::fromStdString(_s).toHtmlEscaped().toStdString();
}
void Main::on_blocks_currentItemChanged()
{
ui->info->clear();
@ -1442,7 +1472,7 @@ void Main::on_blocks_currentItemChanged()
s << "<div>D/TD: <b>" << info.difficulty << "</b>/<b>" << details.totalDifficulty << "</b> = 2^" << log2((double)info.difficulty) << "/2^" << log2((double)details.totalDifficulty) << "</div>";
s << "&nbsp;&emsp;&nbsp;Children: <b>" << details.children.size() << "</b></div>";
s << "<div>Gas used/limit: <b>" << info.gasUsed << "</b>/<b>" << info.gasLimit << "</b>" << "</div>";
s << "<div>Beneficiary: <b>" << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << " " << info.coinbaseAddress << "</b>" << "</div>";
s << "<div>Beneficiary: <b>" << htmlEscaped(pretty(info.coinbaseAddress)) << " " << info.coinbaseAddress << "</b>" << "</div>";
s << "<div>Seed hash: <b>" << info.seedHash() << "</b>" << "</div>";
s << "<div>Mix hash: <b>" << info.mixHash << "</b>" << "</div>";
s << "<div>Nonce: <b>" << info.nonce << "</b>" << "</div>";
@ -1473,7 +1503,7 @@ void Main::on_blocks_currentItemChanged()
s << line << "Hash: <b>" << uncle.hash() << "</b>" << "</div>";
s << line << "Parent: <b>" << uncle.parentHash << "</b>" << "</div>";
s << line << "Number: <b>" << uncle.number << "</b>" << "</div>";
s << line << "Coinbase: <b>" << pretty(uncle.coinbaseAddress).toHtmlEscaped().toStdString() << " " << uncle.coinbaseAddress << "</b>" << "</div>";
s << line << "Coinbase: <b>" << htmlEscaped(pretty(uncle.coinbaseAddress)) << " " << uncle.coinbaseAddress << "</b>" << "</div>";
s << line << "Seed hash: <b>" << uncle.seedHash() << "</b>" << "</div>";
s << line << "Mix hash: <b>" << uncle.mixHash << "</b>" << "</div>";
s << line << "Nonce: <b>" << uncle.nonce << "</b>" << "</div>";
@ -1508,11 +1538,11 @@ void Main::on_blocks_currentItemChanged()
TransactionReceipt receipt = ethereum()->blockChain().receipts(h).receipts[txi];
s << "<h3>" << th << "</h3>";
s << "<h4>" << h << "[<b>" << txi << "</b>]</h4>";
s << "<div>From: <b>" << pretty(ss).toHtmlEscaped().toStdString() << " " << ss << "</b>" << "</div>";
s << "<div>From: <b>" << htmlEscaped(pretty(ss)) << " " << ss << "</b>" << "</div>";
if (tx.isCreation())
s << "<div>Creates: <b>" << pretty(right160(th)).toHtmlEscaped().toStdString() << "</b> " << right160(th) << "</div>";
s << "<div>Creates: <b>" << htmlEscaped(pretty(right160(th))) << "</b> " << right160(th) << "</div>";
else
s << "<div>To: <b>" << pretty(tx.receiveAddress()).toHtmlEscaped().toStdString() << "</b> " << tx.receiveAddress() << "</div>";
s << "<div>To: <b>" << htmlEscaped(pretty(tx.receiveAddress())) << "</b> " << tx.receiveAddress() << "</div>";
s << "<div>Value: <b>" << formatBalance(tx.value()) << "</b>" << "</div>";
s << "&nbsp;&emsp;&nbsp;#<b>" << tx.nonce() << "</b>" << "</div>";
s << "<div>Gas price: <b>" << formatBalance(tx.gasPrice()) << "</b>" << "</div>";
@ -1590,10 +1620,10 @@ void Main::debugDumpState(int _add)
}
}
void Main::on_contracts_currentItemChanged()
void Main::on_accounts_currentItemChanged()
{
ui->contractInfo->clear();
if (auto item = ui->contracts->currentItem())
ui->accountInfo->clear();
if (auto item = ui->accounts->currentItem())
{
auto hba = item->data(Qt::UserRole).toByteArray();
assert(hba.size() == 20);
@ -1604,16 +1634,16 @@ void Main::on_contracts_currentItemChanged()
{
auto storage = ethereum()->storageAt(address);
for (auto const& i: storage)
s << "@" << showbase << hex << prettyU256(i.first).toStdString() << "&nbsp;&nbsp;&nbsp;&nbsp;" << showbase << hex << prettyU256(i.second).toStdString() << "<br/>";
s << "@" << showbase << hex << prettyU256(i.first) << "&nbsp;&nbsp;&nbsp;&nbsp;" << showbase << hex << prettyU256(i.second) << "<br/>";
s << "<h4>Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")</h4>" << disassemble(ethereum()->codeAt(address));
s << Div(Mono) << toHex(ethereum()->codeAt(address)) << "</div>";
ui->contractInfo->appendHtml(QString::fromStdString(s.str()));
ui->accountInfo->appendHtml(QString::fromStdString(s.str()));
}
catch (dev::InvalidTrie)
{
ui->contractInfo->appendHtml("Corrupted trie.");
ui->accountInfo->appendHtml("Corrupted trie.");
}
ui->contractInfo->moveCursor(QTextCursor::Start);
ui->accountInfo->moveCursor(QTextCursor::Start);
}
}
@ -1645,16 +1675,6 @@ void Main::on_accounts_doubleClicked()
}
}
void Main::on_contracts_doubleClicked()
{
if (ui->contracts->count())
{
auto hba = ui->contracts->currentItem()->data(Qt::UserRole).toByteArray();
auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer);
qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray())));
}
}
static shh::FullTopic topicFromText(QString _s)
{
shh::BuildTopic ret;
@ -1754,6 +1774,7 @@ void Main::on_net_triggered()
ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : h256());
web3()->startNetwork();
ui->downloadView->setDownloadMan(ethereum()->downloadMan());
ui->enode->setText(QString::fromStdString(web3()->enode()));
}
else
{
@ -1885,7 +1906,12 @@ void Main::on_killAccount_triggered()
if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size())
{
auto k = m_myKeys[ui->ourAccounts->currentRow()];
if (ethereum()->balanceAt(k.address()) != 0 && QMessageBox::critical(this, "Kill Account?!", "Account " + render(k.address()) + " has " + QString::fromStdString(formatBalance(ethereum()->balanceAt(k.address()))) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\nAre you sure you want to continue?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
if (
ethereum()->balanceAt(k.address()) != 0 &&
QMessageBox::critical(this, "Kill Account?!",
QString::fromStdString("Account " + render(k.address()) + " has " + formatBalance(ethereum()->balanceAt(k.address())) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\n"
"Are you sure you want to continue?"),
QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
return;
m_myKeys.erase(m_myKeys.begin() + ui->ourAccounts->currentRow());
keysChanged();
@ -1902,10 +1928,10 @@ void Main::on_go_triggered()
web3()->addNode(p2p::NodeId(), Host::pocHost());
}
QString Main::prettyU256(dev::u256 _n) const
std::string Main::prettyU256(dev::u256 const& _n) const
{
unsigned inc = 0;
QString raw;
string raw;
ostringstream s;
if (_n > szabo && _n < 1000000 * ether)
s << "<span style=\"color: #215\">" << formatBalance(_n) << "</span> <span style=\"color: #448\">(0x" << hex << (uint64_t)_n << ")</span>";
@ -1916,17 +1942,17 @@ QString Main::prettyU256(dev::u256 _n) const
else if ((_n >> 160) == 0)
{
Address a = right160(_n);
QString n = pretty(a);
if (n.isNull())
string n = pretty(a);
if (n.empty())
s << "<span style=\"color: #844\">0x</span><span style=\"color: #800\">" << a << "</span>";
else
s << "<span style=\"font-weight: bold; color: #800\">" << n.toHtmlEscaped().toStdString() << "</span> (<span style=\"color: #844\">0x</span><span style=\"color: #800\">" << a.abridged() << "</span>)";
s << "<span style=\"font-weight: bold; color: #800\">" << htmlEscaped(n) << "</span> (<span style=\"color: #844\">0x</span><span style=\"color: #800\">" << a.abridged() << "</span>)";
}
else if ((raw = fromRaw((h256)_n, &inc)).size())
return "<span style=\"color: #484\">\"</span><span style=\"color: #080\">" + raw.toHtmlEscaped() + "</span><span style=\"color: #484\">\"" + (inc ? " + " + QString::number(inc) : "") + "</span>";
return "<span style=\"color: #484\">\"</span><span style=\"color: #080\">" + htmlEscaped(raw) + "</span><span style=\"color: #484\">\"" + (inc ? " + " + toString(inc) : "") + "</span>";
else
s << "<span style=\"color: #466\">0x</span><span style=\"color: #044\">" << (h256)_n << "</span>";
return QString::fromStdString(s.str());
return s.str();
}
void Main::on_post_clicked()

20
alethzero/MainWin.h

@ -80,10 +80,10 @@ public:
bool confirm() const;
NatSpecFace* natSpec() { return &m_natSpecDB; }
QString pretty(dev::Address _a) const override;
QString prettyU256(dev::u256 _n) const override;
QString render(dev::Address _a) const override;
std::pair<dev::Address, dev::bytes> fromString(QString const& _a) const override;
std::string pretty(dev::Address const& _a) const override;
std::string prettyU256(dev::u256 const& _n) const override;
std::string render(dev::Address const& _a) const override;
std::pair<dev::Address, dev::bytes> fromString(std::string const& _a) const override;
std::string renderDiff(dev::eth::StateDiff const& _d) const override;
QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; }
@ -131,6 +131,13 @@ private slots:
void on_importKeyFile_triggered();
void on_exportKey_triggered();
// Account pane
void on_accountsFilter_textChanged();
void on_showBasic_toggled();
void on_showContracts_toggled();
void on_onlyNamed_toggled();
void on_refreshAccounts_clicked();
// Tools
void on_newTransaction_triggered();
void on_loadJS_triggered();
@ -140,8 +147,7 @@ private slots:
void ourAccountsRowsMoved();
void on_ourAccounts_doubleClicked();
void on_accounts_doubleClicked();
void on_contracts_doubleClicked();
void on_contracts_currentItemChanged();
void on_accounts_currentItemChanged();
void on_transactionQueue_currentItemChanged();
void on_blockChainFilter_textChanged();
void on_blocks_currentItemChanged();
@ -254,7 +260,7 @@ private:
std::unique_ptr<jsonrpc::HttpServer> m_httpConnector;
std::unique_ptr<OurWebThreeStubServer> m_server;
static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr);
static std::string fromRaw(dev::h256 _n, unsigned* _inc = nullptr);
NatspecHandler m_natSpecDB;
Transact m_transact;

6
alethzero/OurWebThreeStubServer.cpp

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

14
alethzero/Transact.cpp

@ -110,12 +110,12 @@ void Transact::updateDestination()
cwatch << "updateDestination()";
QString s;
for (auto i: ethereum()->addresses())
if ((s = m_context->pretty(i)).size())
if ((s = QString::fromStdString(m_context->pretty(i))).size())
// A namereg address
if (ui->destination->findText(s, Qt::MatchExactly | Qt::MatchCaseSensitive) == -1)
ui->destination->addItem(s);
for (int i = 0; i < ui->destination->count(); ++i)
if (ui->destination->itemText(i) != "(Create Contract)" && !m_context->fromString(ui->destination->itemText(i)).first)
if (ui->destination->itemText(i) != "(Create Contract)" && !m_context->fromString(ui->destination->itemText(i).toStdString()).first)
ui->destination->removeItem(i--);
}
@ -142,9 +142,9 @@ void Transact::on_destination_currentTextChanged(QString)
{
if (ui->destination->currentText().size() && ui->destination->currentText() != "(Create Contract)")
{
auto p = m_context->fromString(ui->destination->currentText());
auto p = m_context->fromString(ui->destination->currentText().toStdString());
if (p.first)
ui->calculatedName->setText(m_context->render(p.first));
ui->calculatedName->setText(QString::fromStdString(m_context->render(p.first)));
else
ui->calculatedName->setText("Unknown Address");
if (!p.second.empty())
@ -347,7 +347,7 @@ void Transact::rejigData()
else
{
// TODO: cache like m_data.
to = m_context->fromString(ui->destination->currentText()).first;
to = m_context->fromString(ui->destination->currentText().toStdString()).first;
er = ethereum()->call(s, value(), to, m_data, gasNeeded, gasPrice());
}
gasNeeded = (qint64)(er.gasUsed + er.gasRefunded);
@ -434,7 +434,7 @@ void Transact::on_send_clicked()
}
else
// TODO: cache like m_data.
ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText()).first, m_data, ui->gas->value(), gasPrice());
ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText().toStdString()).first, m_data, ui->gas->value(), gasPrice());
close();
}
@ -453,7 +453,7 @@ void Transact::on_debug_clicked()
State st(ethereum()->postState());
Transaction t = isCreation() ?
Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) :
Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText()).first, m_data, st.transactionsFrom(dev::toAddress(s)), s);
Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText().toStdString()).first, m_data, st.transactionsFrom(dev::toAddress(s)), s);
Debugger dw(m_context, this);
Executive e(st, ethereum()->blockChain(), 0);
dw.populate(e, t);

16
cmake/EthCompilerSettings.cmake

@ -9,14 +9,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_RELEASE")
if (PROFILING)
set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}")
add_definitions(-DETH_PROFILING_GPERF)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofiler")
# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -lprofiler")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler")
endif ()
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
@ -61,6 +53,14 @@ else ()
message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.")
endif ()
if (PROFILING AND (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")))
set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}")
add_definitions(-DETH_PROFILING_GPERF)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofiler")
# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -lprofiler")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler")
endif ()
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
option(USE_LD_GOLD "Use GNU gold linker" ON)
if (USE_LD_GOLD)

12
cmake/EthExecutableHelper.cmake

@ -94,6 +94,7 @@ macro(eth_install_executable EXECUTABLE)
# This tool and next will inspect linked libraries in order to determine which dependencies are required
if (${CMAKE_CFG_INTDIR} STREQUAL ".")
# TODO: This should only happen for GUI application
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app")
else ()
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app")
@ -126,8 +127,15 @@ macro(eth_install_executable EXECUTABLE)
eth_copy_dlls(${EXECUTABLE} ${dll})
endforeach(dll)
install( TARGETS ${EXECUTABLE} RUNTIME
DESTINATION bin
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Debug"
DESTINATION .
CONFIGURATIONS Debug
COMPONENT ${EXECUTABLE}
)
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Release"
DESTINATION .
CONFIGURATIONS Release
COMPONENT ${EXECUTABLE}
)

7
eth/CMakeLists.txt

@ -37,5 +37,8 @@ if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW)
eth_copy_dlls("${EXECUTABLE}" MHD_DLLS)
endif()
install( TARGETS ${EXECUTABLE} DESTINATION bin )
if (APPLE)
install(TARGETS ${EXECUTABLE} DESTINATION bin)
else()
eth_install_executable(${EXECUTABLE})
endif()

16
eth/main.cpp

@ -146,6 +146,7 @@ void help()
<< " --listen <port> Listen on the given port for incoming connections (default: 30303)." << endl
<< " -r,--remote <host>(:<port>) Connect to remote host (default: none)." << endl
<< " --port <port> Connect to remote port (default: 30303)." << endl
<< " --network-id <n> Only connect to other hosts with this network id (default:0)." << endl
<< " --upnp <on/off> Use UPnP for NAT (default: on)." << endl
#if ETH_JSONRPC || !ETH_TRUE
<< "Work farming mode:" << endl
@ -406,6 +407,7 @@ void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod)
int main(int argc, char** argv)
{
#if 0
cout << "\x1b[30mEthBlack\x1b[0m" << endl;
cout << "\x1b[90mEthCoal\x1b[0m" << endl;
cout << "\x1b[37mEthGray\x1b[0m" << endl;
@ -471,7 +473,7 @@ int main(int argc, char** argv)
cout << "\x1b[4;35mEthPurpleU\x1b[0m" << endl;
cout << "\x1b[4;36mEthCyanU\x1b[0m" << endl;
cout << "\x1b[4;37mEthWhiteU\x1b[0m" << endl;
#endif
// Init defaults
Defaults::get();
@ -515,6 +517,7 @@ int main(int argc, char** argv)
unsigned short remotePort = 30303;
unsigned peers = 5;
bool bootstrap = false;
unsigned networkId = 0;
/// Mining params
unsigned mining = 0;
@ -668,6 +671,15 @@ int main(int argc, char** argv)
return -1;
}
}
else if (arg == "--network-id" && i + 1 < argc)
try {
networkId = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
else if (arg == "--benchmark-warmup" && i + 1 < argc)
try {
benchmarkWarmup = stol(argv[++i]);
@ -1034,11 +1046,13 @@ int main(int argc, char** argv)
c->setForceMining(forceMining);
c->setTurboMining(minerType == MinerType::GPU);
c->setAddress(coinbase);
c->setNetworkId(networkId);
}
cout << "Transaction Signer: " << sigKey.address() << endl;
cout << "Mining Benefactor: " << coinbase << endl;
web3.startNetwork();
cout << "Node ID: " << web3.enode() << endl;
if (bootstrap)
web3.addNode(p2p::NodeId(), Host::pocHost());

6
ethminer/CMakeLists.txt

@ -37,5 +37,9 @@ if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW)
eth_copy_dlls("${EXECUTABLE}" MHD_DLLS)
endif()
install( TARGETS ${EXECUTABLE} DESTINATION bin )
if (APPLE)
install(TARGETS ${EXECUTABLE} DESTINATION bin)
else()
eth_install_executable(${EXECUTABLE})
endif()

2
evmjit/libevmjit-cpp/Env.cpp

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

90
exp/main.cpp

@ -33,6 +33,7 @@
#endif
#include <functional>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <libdevcore/RangeMask.h>
#include <libdevcore/Log.h>
#include <libdevcore/Common.h>
@ -43,6 +44,7 @@
#include <libdevcrypto/TrieDB.h>
#include <libp2p/All.h>
#include <libethcore/ProofOfWork.h>
#include <libdevcrypto/FileSystem.h>
#include <libethereum/All.h>
#include <libethereum/Farm.h>
#include <libethereum/AccountDiff.h>
@ -58,8 +60,94 @@ using namespace dev::eth;
using namespace dev::p2p;
using namespace dev::shh;
namespace js = json_spirit;
namespace fs = boost::filesystem;
#if 0
#if 1
inline h128 fromUUID(std::string const& _uuid) { return h128(boost::replace_all_copy(_uuid, "-", "")); }
class KeyManager: public Worker
{
public:
KeyManager() { readKeys(); }
~KeyManager() {}
Secret secret(h128 const& _uuid, std::string const& _pass)
{
auto it = m_keys.find(_uuid);
if (it == m_keys.end())
return Secret();
return Secret(decrypt(it->second, _pass));
}
private:
void readKeys(std::string const& _keysPath = getDataDir("web3") + "/keys")
{
fs::path p(_keysPath);
js::mValue v;
for (fs::directory_iterator it(p); it != fs::directory_iterator(); ++it)
if (is_regular_file(it->path()))
{
cdebug << "Reading" << it->path();
js::read_string(contentsString(it->path().string()), v);
js::mObject o = v.get_obj();
int version = o.count("Version") ? stoi(o["Version"].get_str()) : o.count("version") ? o["version"].get_int() : 0;
if (version == 2)
m_keys[fromUUID(o["id"].get_str())] = o["crypto"];
else
cwarn << "Cannot read key version" << version;
}
}
static bytes decrypt(js::mValue const& _v, std::string const& _pass)
{
js::mObject o = _v.get_obj();
bytes pKey;
if (o["kdf"].get_str() == "pbkdf2")
{
auto params = o["kdfparams"].get_obj();
unsigned iterations = params["c"].get_int();
bytes salt = fromHex(params["salt"].get_str());
pKey = pbkdf2(_pass, salt, iterations).asBytes();
}
else
{
cwarn << "Unknown KDF" << o["kdf"].get_str() << "not supported.";
return bytes();
}
// TODO check MAC
h256 mac(o["mac"].get_str());
(void)mac;
bytes cipherText = fromHex(o["ciphertext"].get_str());
bytes ret;
if (o["cipher"].get_str() == "aes-128-cbc")
{
auto params = o["cipherparams"].get_obj();
h128 key(sha3(h128(pKey, h128::AlignRight)), h128::AlignRight);
h128 iv(params["iv"].get_str());
decryptSymNoAuth(key, iv, &cipherText, ret);
}
else
{
cwarn << "Unknown cipher" << o["cipher"].get_str() << "not supported.";
return bytes();
}
return ret;
}
std::map<h128, js::mValue> m_keys;
};
int main()
{
KeyManager keyman;
cdebug << "Secret key for 0498f19a-59db-4d54-ac95-33901b4f1870 is " << keyman.secret(fromUUID("0498f19a-59db-4d54-ac95-33901b4f1870"), "foo");
}
#elif 0
int main()
{
DownloadMan man;

8
libdevcore/Common.cpp

@ -21,13 +21,14 @@
#include "Common.h"
#include "Exceptions.h"
#include "Log.h"
using namespace std;
using namespace dev;
namespace dev
{
char const* Version = "0.9.14";
char const* Version = "0.9.15";
void HasInvariants::checkInvariants() const
{
@ -35,5 +36,10 @@ void HasInvariants::checkInvariants() const
BOOST_THROW_EXCEPTION(FailedInvariant());
}
TimerHelper::~TimerHelper()
{
cdebug << "Timer" << id << t.elapsed() << "s";
}
}

20
libdevcore/Common.h

@ -37,6 +37,7 @@
#include <vector>
#include <set>
#include <functional>
#include <boost/timer.hpp>
#pragma warning(push)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
@ -168,6 +169,25 @@ private:
#define DEV_INVARIANT_CHECK (void)0;
#endif
class TimerHelper
{
public:
TimerHelper(char const* _id): id(_id) {}
~TimerHelper();
private:
boost::timer t;
char const* id;
};
#define DEV_TIMED(S) for (::std::pair<::dev::TimerHelper, bool> __eth_t(#S, true); __eth_t.second; __eth_t.second = false)
#define DEV_TIMED_SCOPE(S) ::dev::TimerHelper __eth_t(S)
#if WIN32
#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__FUNCSIG__)
#else
#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__PRETTY_FUNCTION__)
#endif
enum class WithExisting: int
{
Trust = 0,

5
libdevcore/FixedHash.h

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

13
libdevcore/Guards.h

@ -22,6 +22,7 @@
#pragma once
#include <mutex>
#include <atomic>
#include <boost/thread.hpp>
namespace dev
@ -61,6 +62,18 @@ struct GenericUnguardSharedBool
MutexType& m;
};
/** @brief Simple lock that waits for release without making context switch */
class SpinLock
{
public:
SpinLock() { m_lock.clear(); }
void lock() { while (m_lock.test_and_set(std::memory_order_acquire)) {} }
void unlock() { m_lock.clear(std::memory_order_release); }
private:
std::atomic_flag m_lock;
};
using SpinGuard = std::lock_guard<SpinLock>;
/** @brief Simple block guard.
* The expression/block following is guarded though the given mutex.
* Usage:

4
libdevcore/Log.cpp

@ -158,8 +158,8 @@ void dev::setThreadName(string const& _n)
void dev::simpleDebugOut(std::string const& _s, char const*)
{
static Mutex s_lock;
Guard l(s_lock);
static SpinLock s_lock;
SpinGuard l(s_lock);
cerr << _s << endl << flush;

14
libdevcrypto/Common.cpp

@ -112,13 +112,13 @@ bool dev::decryptSym(Secret const& _k, bytesConstRef _cipher, bytes& o_plain)
return decrypt(_k, _cipher, o_plain);
}
h128 dev::encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_cipher)
h128 dev::encryptSymNoAuth(h128 const& _k, bytesConstRef _plain, bytes& o_cipher)
{
h128 iv(Nonce::get());
return encryptSymNoAuth(_k, _plain, o_cipher, iv);
}
h128 dev::encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_cipher, h128 const& _iv)
h128 dev::encryptSymNoAuth(h128 const& _k, bytesConstRef _plain, bytes& o_cipher, h128 const& _iv)
{
o_cipher.resize(_plain.size());
@ -139,7 +139,7 @@ h128 dev::encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_ciph
}
}
bool dev::decryptSymNoAuth(Secret const& _k, h128 const& _iv, bytesConstRef _cipher, bytes& o_plaintext)
bool dev::decryptSymNoAuth(h128 const& _k, h128 const& _iv, bytesConstRef _cipher, bytes& o_plaintext)
{
o_plaintext.resize(_cipher.size());
@ -175,6 +175,14 @@ bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash)
return s_secp256k1.verify(_p, _s, _hash.ref(), true);
}
h256 dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations)
{
h256 ret;
PKCS5_PBKDF2_HMAC<SHA256> pbkdf;
pbkdf.DeriveKey(ret.data(), ret.size, 0, (byte*)_pass.data(), _pass.size(), _salt.data(), _salt.size(), _iterations);
return ret;
}
KeyPair KeyPair::create()
{
static boost::thread_specific_ptr<mt19937_64> s_eng;

13
libdevcrypto/Common.h

@ -103,13 +103,13 @@ void encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher);
bool decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext);
/// Encrypts payload with random IV/ctr using AES128-CTR.
h128 encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_cipher);
h128 encryptSymNoAuth(h128 const& _k, bytesConstRef _plain, bytes& o_cipher);
/// Encrypts payload with specified IV/ctr using AES128-CTR.
h128 encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_cipher, h128 const& _iv);
h128 encryptSymNoAuth(h128 const& _k, bytesConstRef _plain, bytes& o_cipher, h128 const& _iv);
/// Decrypts payload with specified IV/ctr.
bool decryptSymNoAuth(Secret const& _k, h128 const& _iv, bytesConstRef _cipher, bytes& o_plaintext);
/// Decrypts payload with specified IV/ctr using AES128-CTR.
bool decryptSymNoAuth(h128 const& _k, h128 const& _iv, bytesConstRef _cipher, bytes& o_plaintext);
/// Recovers Public key from signed message hash.
Public recover(Signature const& _sig, h256 const& _hash);
@ -120,6 +120,9 @@ Signature sign(Secret const& _k, h256 const& _hash);
/// Verify signature.
bool verify(Public const& _k, Signature const& _s, h256 const& _hash);
/// Derive key via PBKDF2.
h256 pbkdf2(std::string const& _pass, bytes const& _salt, unsigned _iterations);
/// Simple class that represents a "key pair".
/// All of the data of the class can be regenerated from the secret key (m_secret) alone.
/// Actually stores a tuplet of secret, public and address (the right 160-bits of the public).
@ -164,7 +167,7 @@ struct InvalidState: public dev::Exception {};
/// Key derivation
h256 kdf(Secret const& _priv, h256 const& _hash);
/**
* @brief Generator for nonce material
*/

4
libdevcrypto/CryptoPP.cpp

@ -79,7 +79,7 @@ void Secp256k1::encryptECIES(Public const& _k, bytes& io_cipher)
ctx.Final(mKey.data());
bytes cipherText;
encryptSymNoAuth(*(Secret*)eKey.data(), bytesConstRef(&io_cipher), cipherText, h128());
encryptSymNoAuth(h128(eKey), bytesConstRef(&io_cipher), cipherText, h128());
if (cipherText.empty())
return;
@ -139,7 +139,7 @@ bool Secp256k1::decryptECIES(Secret const& _k, bytes& io_text)
if (mac[i] != msgMac[i])
return false;
decryptSymNoAuth(*(Secret*)eKey.data(), iv, cipherNoIV, plain);
decryptSymNoAuth(h128(eKey), iv, cipherNoIV, plain);
io_text.resize(plain.size());
io_text.swap(plain);

34
libethash-cl/ethash_cl_miner.cpp

@ -88,6 +88,13 @@ std::string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _devic
return "{ \"platform\": \"" + platforms[platform_num].getInfo<CL_PLATFORM_NAME>() + "\", \"device\": \"" + device.getInfo<CL_DEVICE_NAME>() + "\", \"version\": \"" + device_version + "\" }";
}
unsigned ethash_cl_miner::get_num_platforms()
{
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
return platforms.size();
}
unsigned ethash_cl_miner::get_num_devices(unsigned _platformId)
{
std::vector<cl::Platform> platforms;
@ -117,14 +124,11 @@ void ethash_cl_miner::finish()
}
}
bool ethash_cl_miner::init(ethash_params const& params, std::function<void(void*)> _fillDAG, unsigned workgroup_size, unsigned _platformId, unsigned _deviceId)
bool ethash_cl_miner::init(uint8_t const* _dag, uint64_t _dagSize, unsigned workgroup_size, unsigned _platformId, unsigned _deviceId)
{
// store params
m_params = params;
// get all platforms
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
if (platforms.empty())
{
cout << "No OpenCL platforms found." << endl;
@ -137,10 +141,10 @@ bool ethash_cl_miner::init(ethash_params const& params, std::function<void(void*
cout << "Using platform: " << platforms[_platformId].getInfo<CL_PLATFORM_NAME>().c_str() << endl;
// get GPU device of the default platform
std::vector<cl::Device> devices;
// get GPU device of the default platform
std::vector<cl::Device> devices;
platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices);
if (devices.empty())
if (devices.empty())
{
cout << "No OpenCL devices found." << endl;
return false;
@ -171,7 +175,7 @@ bool ethash_cl_miner::init(ethash_params const& params, std::function<void(void*
// patch source code
std::string code(ETHASH_CL_MINER_KERNEL, ETHASH_CL_MINER_KERNEL + ETHASH_CL_MINER_KERNEL_SIZE);
add_definition(code, "GROUP_SIZE", m_workgroup_size);
add_definition(code, "DAG_SIZE", (unsigned)(params.full_size / ETHASH_MIX_BYTES));
add_definition(code, "DAG_SIZE", (unsigned)(_dagSize / ETHASH_MIX_BYTES));
add_definition(code, "ACCESSES", ETHASH_ACCESSES);
add_definition(code, "MAX_OUTPUTS", c_max_search_results);
//debugf("%s", code.c_str());
@ -194,18 +198,20 @@ bool ethash_cl_miner::init(ethash_params const& params, std::function<void(void*
m_search_kernel = cl::Kernel(program, "ethash_search");
// create buffer for dag
m_dag = cl::Buffer(m_context, CL_MEM_READ_ONLY, params.full_size);
m_dag = cl::Buffer(m_context, CL_MEM_READ_ONLY, _dagSize);
// create buffer for header
m_header = cl::Buffer(m_context, CL_MEM_READ_ONLY, 32);
// compute dag on CPU
{
m_queue.enqueueWriteBuffer(m_dag, CL_TRUE, 0, _dagSize, _dag);
// if this throws then it's because we probably need to subdivide the dag uploads for compatibility
void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, m_opencl_1_1 ? CL_MAP_WRITE : CL_MAP_WRITE_INVALIDATE_REGION, 0, params.full_size);
// void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, m_opencl_1_1 ? CL_MAP_WRITE : CL_MAP_WRITE_INVALIDATE_REGION, 0, _dagSize);
// memcpying 1GB: horrible... really. horrible. but necessary since we can't mmap *and* gpumap.
_fillDAG(dag_ptr);
m_queue.enqueueUnmapMemObject(m_dag, dag_ptr);
// _fillDAG(dag_ptr);
// m_queue.enqueueUnmapMemObject(m_dag, dag_ptr);
}
// create mining buffers

7
libethash-cl/ethash_cl_miner.h

@ -31,11 +31,11 @@ public:
public:
ethash_cl_miner();
bool init(ethash_params const& params, std::function<void(void*)> _fillDAG, unsigned workgroup_size = 64, unsigned _platformId = 0, unsigned _deviceId = 0);
static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0);
static unsigned get_num_platforms();
static unsigned get_num_devices(unsigned _platformId = 0);
static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0);
bool init(uint8_t const* _dag, uint64_t _dagSize, unsigned workgroup_size = 64, unsigned _platformId = 0, unsigned _deviceId = 0);
void finish();
void hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count);
void search(uint8_t const* header, uint64_t target, search_hook& hook);
@ -43,7 +43,6 @@ public:
private:
enum { c_max_search_results = 63, c_num_buffers = 2, c_hash_batch_size = 1024, c_search_batch_size = 1024*256 };
ethash_params m_params;
cl::Context m_context;
cl::CommandQueue m_queue;
cl::Kernel m_hash_kernel;

2
libethcore/BlockInfo.cpp

@ -23,10 +23,10 @@
#include <libdevcore/RLP.h>
#include <libdevcrypto/TrieDB.h>
#include <libethcore/Common.h>
#include <libethcore/Params.h>
#include "EthashAux.h"
#include "ProofOfWork.h"
#include "Exceptions.h"
#include "Params.h"
#include "BlockInfo.h"
using namespace std;
using namespace dev;

2
libethcore/CMakeLists.txt

@ -28,7 +28,7 @@ add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
target_link_libraries(${EXECUTABLE} ethash)
target_link_libraries(${EXECUTABLE} devcrypto)
target_link_libraries(${EXECUTABLE} devcore)
target_link_libraries(${EXECUTABLE} evmcore)
if (ETHASHCL)
target_link_libraries(${EXECUTABLE} ethash-cl)

6
libethcore/Ethash.cpp

@ -309,10 +309,10 @@ void Ethash::GPUMiner::workLoop()
delete m_miner;
m_miner = new ethash_cl_miner;
auto p = EthashAux::params(m_minerSeed);
auto cb = [&](void* d) { EthashAux::full(m_minerSeed, bytesRef((byte*)d, p.full_size)); };
unsigned device = instances() > 1 ? index() : s_deviceId;
m_miner->init(p, cb, 32, s_platformId, device);
EthashAux::FullType dag = EthashAux::full(m_minerSeed);
m_miner->init(dag->data.data(), dag->data.size(), 32, s_platformId, device);
}
uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192);

13
libethcore/EthashAux.cpp

@ -33,7 +33,6 @@
#include <libdevcrypto/CryptoPP.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcrypto/FileSystem.h>
#include <libethcore/Params.h>
#include "BlockInfo.h"
using namespace std;
using namespace chrono;
@ -87,13 +86,10 @@ ethash_params EthashAux::params(h256 const& _seedHash)
{
Guard l(get()->x_epochs);
unsigned epoch = 0;
try
auto epochIter = get()->m_epochs.find(_seedHash);
if (epochIter == get()->m_epochs.end())
{
epoch = get()->m_epochs.at(_seedHash);
}
catch (...)
{
// cdebug << "Searching for seedHash " << _seedHash;
// cdebug << "Searching for seedHash " << _seedHash;
for (h256 h; h != _seedHash && epoch < 2048; ++epoch, h = sha3(h), get()->m_epochs[h] = epoch) {}
if (epoch == 2048)
{
@ -102,6 +98,8 @@ ethash_params EthashAux::params(h256 const& _seedHash)
throw std::invalid_argument(error.str());
}
}
else
epoch = epochIter->second;
return params(epoch * ETHASH_EPOCH_LENGTH);
}
@ -135,7 +133,6 @@ EthashAux::LightAllocation::~LightAllocation()
ethash_delete_light(light);
}
EthashAux::FullType EthashAux::full(BlockInfo const& _header, bytesRef _dest, bool _createIfMissing)
{
return full(_header.seedHash(), _dest, _createIfMissing);

2
libethcore/ICAP.h

@ -51,8 +51,6 @@ public:
ICAP() = default;
/// Construct a direct ICAP object for given target address. Must have a zero first byte.
ICAP(Address const& _target): m_type(Direct), m_direct(_target) {}
/// Construct an indirect ICAP object for given target name.
ICAP(std::string const& _target): m_type(Indirect), m_client(boost::algorithm::to_upper_copy(_target)), m_asset("ETH") {}
/// Construct an indirect ICAP object for given client and institution names.
ICAP(std::string const& _client, std::string const& _inst): m_type(Indirect), m_client(boost::algorithm::to_upper_copy(_client)), m_institution(boost::algorithm::to_upper_copy(_inst)), m_asset("XET") {}
/// Construct an indirect ICAP object for given client, institution and asset names. You generally don't want to use this.

36
libethcore/Params.cpp

@ -14,7 +14,7 @@
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 FeeStructure.cpp
/** @file Params.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
@ -36,40 +36,6 @@ u256 const c_gasLimitBoundDivisor = 1024;
u256 const c_minimumDifficulty = 131072;
u256 const c_difficultyBoundDivisor = 2048;
u256 const c_durationLimit = 8;
u256 const c_stackLimit = 1024;
u256 const c_tierStepGas[] = {0, 2, 3, 5, 8, 10, 20, 0};
u256 const c_expGas = 10;
u256 const c_expByteGas = 10;
u256 const c_sha3Gas = 30;
u256 const c_sha3WordGas = 6;
u256 const c_sloadGas = 50;
u256 const c_sstoreSetGas = 20000;
u256 const c_sstoreResetGas = 5000;
u256 const c_sstoreRefundGas = 15000;
u256 const c_jumpdestGas = 1;
u256 const c_logGas = 375;
u256 const c_logDataGas = 8;
u256 const c_logTopicGas = 375;
u256 const c_createGas = 32000;
u256 const c_callGas = 40;
u256 const c_callStipend = 2300;
u256 const c_callValueTransferGas = 9000;
u256 const c_callNewAccountGas = 25000;
u256 const c_suicideRefundGas = 24000;
u256 const c_memoryGas = 3;
u256 const c_quadCoeffDiv = 512;
u256 const c_createDataGas = 200;
u256 const c_txGas = 21000;
u256 const c_txDataZeroGas = 4;
u256 const c_txDataNonZeroGas = 68;
u256 const c_copyGas = 3;
u256 const c_ecrecoverGas = 3000;
u256 const c_sha256Gas = 60;
u256 const c_sha256WordGas = 12;
u256 const c_ripemd160Gas = 600;
u256 const c_ripemd160WordGas = 120;
u256 const c_identityGas = 15;
u256 const c_identityWordGas = 3;
//--- END: AUTOGENERATED FROM /feeStructure.json
}

37
libethcore/Params.h

@ -14,7 +14,7 @@
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 FeeStructure.h
/** @file Params.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
@ -37,41 +37,6 @@ extern u256 const c_minimumDifficulty;
extern u256 const c_difficultyBoundDivisor;
extern u256 const c_durationLimit;
extern u256 const c_maximumExtraDataSize;
extern u256 const c_stackLimit;
extern u256 const c_tierStepGas[8]; ///< Once per operation, for a selection of them.
extern u256 const c_expGas; ///< Once per EXP instuction.
extern u256 const c_expByteGas; ///< Times ceil(log256(exponent)) for the EXP instruction.
extern u256 const c_sha3Gas; ///< Once per SHA3 operation.
extern u256 const c_sha3WordGas; ///< Once per word of the SHA3 operation's data.
extern u256 const c_copyGas; ///< Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
extern u256 const c_sloadGas; ///< Once per SLOAD operation.
extern u256 const c_sstoreSetGas; ///< Once per SSTORE operation if the zeroness changes from zero.
extern u256 const c_sstoreResetGas; ///< Once per SSTORE operation if the zeroness does not change from zero. NOTE: when c_sstoreSetGas does not apply.
extern u256 const c_sstoreRefundGas; ///< Refunded gas, once per SSTORE operation if the zeroness changes to zero.
extern u256 const c_jumpdestGas; ///< Once per JUMPDEST operation.
extern u256 const c_logGas; ///< Per LOG* operation.
extern u256 const c_logDataGas; ///< Per byte in a LOG* operation's data.
extern u256 const c_logTopicGas; ///< Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
extern u256 const c_createGas; ///< Once per CREATE operation & contract-creation transaction.
extern u256 const c_createDataGas;
extern u256 const c_callGas; ///< Once per CALL operation & message call transaction.
extern u256 const c_callStipend; ///< Free gas given at beginning of call.
extern u256 const c_callNewAccountGas; ///< Paid for CALL when the destination address didn't exist prior.
extern u256 const c_callValueTransferGas; ///< Paid for CALL when the value transfor is non-zero.
extern u256 const c_suicideRefundGas; ///< Refunded following a suicide operation.
extern u256 const c_memoryGas; ///< Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
extern u256 const c_quadCoeffDiv; ///< Divisor for the quadratic particle of the memory cost equation.
extern u256 const c_txGas; ///< Per transaction. NOTE: Not payable on data of calls between transactions.
extern u256 const c_txDataZeroGas; ///< Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions.
extern u256 const c_txDataNonZeroGas; ///< Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
extern u256 const c_ecrecoverGas;
extern u256 const c_sha256Gas;
extern u256 const c_sha256WordGas;
extern u256 const c_ripemd160Gas;
extern u256 const c_ripemd160WordGas;
extern u256 const c_identityGas;
extern u256 const c_identityWordGas;
}
}

26
libethereum/BlockChain.cpp

@ -37,6 +37,7 @@
#include <libethcore/Exceptions.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/BlockInfo.h>
#include <libethcore/Params.h>
#include <liblll/Compiler.h>
#include "GenesisInfo.h"
#include "State.h"
@ -47,7 +48,7 @@ using namespace dev::eth;
namespace js = json_spirit;
#define ETH_CATCH 1
#define ETH_TIMED_IMPORTS 1
#define ETH_TIMED_IMPORTS 0
#ifdef _WIN32
const char* BlockChainDebug::name() { return EthBlue "8" EthWhite " <>"; }
@ -473,7 +474,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
t.restart();
#endif
#if ETH_PARANOIA
#if ETH_PARANOIA || !ETH_TRUE
checkConsistency();
#endif
@ -488,7 +489,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
ETH_WRITE_GUARDED(x_details)
m_details[bi.parentHash].children.push_back(bi.hash());
#if ETH_TIMED_IMPORTS
#if ETH_TIMED_IMPORTS || !ETH_TRUE
collation = t.elapsed();
t.restart();
#endif
@ -496,18 +497,15 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
blocksBatch.Put(toSlice(bi.hash()), (ldb::Slice)ref(_block));
ETH_READ_GUARDED(x_details)
extrasBatch.Put(toSlice(bi.parentHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp()));
extrasBatch.Put(toSlice(bi.hash(), ExtraDetails), (ldb::Slice)dev::ref(BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {}).rlp()));
extrasBatch.Put(toSlice(bi.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(blb.rlp()));
extrasBatch.Put(toSlice(bi.hash(), ExtraReceipts), (ldb::Slice)dev::ref(br.rlp()));
#if ETH_TIMED_IMPORTS
#if ETH_TIMED_IMPORTS || !ETH_TRUE
writing = t.elapsed();
t.restart();
#endif
#if ETH_PARANOIA
checkConsistency();
#endif
}
#if ETH_CATCH
catch (InvalidNonce const& _e)
@ -609,7 +607,6 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
}
clog(BlockChainNote) << " Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << route;
noteCanonChanged();
StructuredLogger::chainNewHead(
bi.headerHash(WithoutNonce).abridged(),
@ -632,6 +629,10 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
m_lastBlockNumber = newLastBlockNumber;
}
#if ETH_PARANOIA || !ETH_TRUE
checkConsistency();
#endif
#if ETH_TIMED_IMPORTS
checkBest = t.elapsed();
cnote << "Import took:" << total.elapsed();
@ -642,6 +643,9 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
cnote << "checkBest:" << checkBest;
#endif
if (!route.empty())
noteCanonChanged();
if (isKnown(bi.hash()) && !details(bi.hash()))
{
clog(BlockChainDebug) << "Known block just inserted has no details.";
@ -767,7 +771,7 @@ void BlockChain::noteUsed(h256 const& _h, unsigned _extra) const
m_inUse.insert(id);
}
template <class T> static unsigned getHashSize(map<h256, T> const& _map)
template <class T> static unsigned getHashSize(unordered_map<h256, T> const& _map)
{
unsigned ret = 0;
for (auto const& i: _map)
@ -855,7 +859,7 @@ void BlockChain::garbageCollect(bool _force)
}
}
m_cacheUsage.pop_back();
m_cacheUsage.push_front(std::set<CacheID>{});
m_cacheUsage.push_front(std::unordered_set<CacheID>{});
}
void BlockChain::checkConsistency()

20
libethereum/BlockChain.h

@ -28,6 +28,8 @@
#include <deque>
#include <chrono>
#include <unordered_map>
#include <unordered_set>
#include <libdevcore/Log.h>
#include <libdevcore/Exceptions.h>
#include <libdevcore/Guards.h>
@ -40,6 +42,14 @@
#include "BlockQueue.h"
namespace ldb = leveldb;
namespace std
{
template <> struct hash<pair<dev::h256, unsigned>>
{
size_t operator()(pair<dev::h256, unsigned> const& _x) const { return hash<dev::h256>()(_x.first) ^ hash<unsigned>()(_x.second); }
};
}
namespace dev
{
@ -66,7 +76,7 @@ std::map<Address, Account> const& genesisState();
ldb::Slice toSlice(h256 const& _h, unsigned _sub = 0);
using BlocksHash = std::map<h256, bytes>;
using BlocksHash = std::unordered_map<h256, bytes>;
using TransactionHashes = h256s;
using UncleHashes = h256s;
using ImportRoute = std::pair<h256s, h256s>;
@ -144,7 +154,7 @@ public:
UncleHashes uncleHashes() const { return uncleHashes(currentHash()); }
/// Get the hash for a given block's number.
h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras<BlockHash, ExtraBlockHash>(h256(u256(_i)), m_blockHashes, x_blockHashes, NullBlockHash).value; }
h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras<BlockHash, ExtraBlockHash>(h256(_i), m_blockHashes, x_blockHashes, NullBlockHash).value; }
/// Get the last N hashes for a given block. (N is determined by the LastHashes type.)
LastHashes lastHashes() const { return lastHashes(number()); }
@ -251,7 +261,7 @@ private:
void open(std::string const& _path, WithExisting _we = WithExisting::Trust);
void close();
template<class T, unsigned N> T queryExtras(h256 const& _h, std::map<h256, T>& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const
template<class T, unsigned N> T queryExtras(h256 const& _h, std::unordered_map<h256, T>& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const
{
{
ReadGuard l(_x);
@ -295,8 +305,8 @@ private:
using CacheID = std::pair<h256, unsigned>;
mutable Mutex x_cacheUsage;
mutable std::deque<std::set<CacheID>> m_cacheUsage;
mutable std::set<CacheID> m_inUse;
mutable std::deque<std::unordered_set<CacheID>> m_cacheUsage;
mutable std::unordered_set<CacheID> m_inUse;
void noteUsed(h256 const& _h, unsigned _extra = (unsigned)-1) const;
std::chrono::system_clock::time_point m_lastCollection;

13
libethereum/BlockDetails.h

@ -21,6 +21,7 @@
#pragma once
#include <unordered_map>
#pragma warning(push)
#pragma warning(disable: 4100 4267)
#include <leveldb/db.h>
@ -114,12 +115,12 @@ struct TransactionAddress
static const unsigned size = 67;
};
using BlockDetailsHash = std::map<h256, BlockDetails>;
using BlockLogBloomsHash = std::map<h256, BlockLogBlooms>;
using BlockReceiptsHash = std::map<h256, BlockReceipts>;
using TransactionAddressHash = std::map<h256, TransactionAddress>;
using BlockHashHash = std::map<h256, BlockHash>;
using BlocksBloomsHash = std::map<h256, BlocksBlooms>;
using BlockDetailsHash = std::unordered_map<h256, BlockDetails>;
using BlockLogBloomsHash = std::unordered_map<h256, BlockLogBlooms>;
using BlockReceiptsHash = std::unordered_map<h256, BlockReceipts>;
using TransactionAddressHash = std::unordered_map<h256, TransactionAddress>;
using BlockHashHash = std::unordered_map<h256, BlockHash>;
using BlocksBloomsHash = std::unordered_map<h256, BlocksBlooms>;
static const BlockDetails NullBlockDetails;
static const BlockLogBlooms NullBlockLogBlooms;

1
libethereum/CanonBlockChain.cpp

@ -29,6 +29,7 @@
#include <libethcore/Exceptions.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/BlockInfo.h>
#include <libethcore/Params.h>
#include <liblll/Compiler.h>
#include "GenesisInfo.h"
#include "State.h"

14
libethereum/Client.cpp

@ -36,12 +36,6 @@ using namespace dev;
using namespace dev::eth;
using namespace p2p;
namespace dev
{
struct TimerHelper { TimerHelper(char const* _id): id(_id) {} ~TimerHelper() { cdebug << "Timer" << id << t.elapsed() << "s"; } boost::timer t; char const* id; };
#define DEV_TIMED(S) for (::std::pair<::dev::TimerHelper, bool> __eth_t(#S, true); __eth_t.second; __eth_t.second = false)
}
VersionChecker::VersionChecker(string const& _dbPath):
m_path(_dbPath.size() ? _dbPath : Defaults::dbPath())
{
@ -586,7 +580,9 @@ void Client::onChainChanged(ImportRoute const& _ir)
for (auto const& t: m_postMine.pending())
{
clog(ClientNote) << "Resubmitting post-mine transaction " << t;
m_tq.import(t, TransactionQueue::ImportCallback(), IfDropped::Retry);
auto ir = m_tq.import(t, TransactionQueue::ImportCallback(), IfDropped::Retry);
if (ir != ImportResult::Success)
onTransactionQueueReady();
}
ETH_READ_GUARDED(x_working) DEV_TIMED(post) ETH_WRITE_GUARDED(x_postMine)
m_postMine = m_working;
@ -596,6 +592,10 @@ void Client::onChainChanged(ImportRoute const& _ir)
onPostStateChanged();
}
// Quick hack for now - the TQ at this point already has the prior pending transactions in it;
// we should resync with it manually until we are stricter about what constitutes "knowing".
onTransactionQueueReady();
noteChanged(changeds);
}

5
libethereum/ClientBase.cpp

@ -142,6 +142,11 @@ bytes ClientBase::codeAt(Address _a, BlockNumber _block) const
return asOf(_block).code(_a);
}
h256 ClientBase::codeHashAt(Address _a, BlockNumber _block) const
{
return asOf(_block).codeHash(_a);
}
map<u256, u256> ClientBase::storageAt(Address _a, BlockNumber _block) const
{
return asOf(_block).storage(_a);

2
libethereum/ClientBase.h

@ -92,12 +92,14 @@ public:
using Interface::countAt;
using Interface::stateAt;
using Interface::codeAt;
using Interface::codeHashAt;
using Interface::storageAt;
virtual u256 balanceAt(Address _a, BlockNumber _block) const override;
virtual u256 countAt(Address _a, BlockNumber _block) const override;
virtual u256 stateAt(Address _a, u256 _l, BlockNumber _block) const override;
virtual bytes codeAt(Address _a, BlockNumber _block) const override;
virtual h256 codeHashAt(Address _a, BlockNumber _block) const override;
virtual std::map<u256, u256> storageAt(Address _a, BlockNumber _block) const override;
virtual LocalisedLogEntries logs(unsigned _watchId) const override;

2
libethereum/CommonNet.h

@ -56,7 +56,7 @@ class EthereumPeer;
enum
{
StatusPacket = 0,
GetTransactionsPacket,
NewBlockHashesPacket,
TransactionsPacket,
GetBlockHashesPacket,
BlockHashesPacket,

2
libethereum/DownloadMan.cpp

@ -50,7 +50,7 @@ h256Set DownloadSub::nextFetch(unsigned _n)
m_indices.clear();
m_remaining.clear();
if (!m_man || m_man->chain().empty())
if (!m_man || m_man->chainEmpty())
return h256Set();
m_asked = (~(m_man->taken() + m_attempted)).lowest(_n);

3
libethereum/DownloadMan.h

@ -143,7 +143,8 @@ public:
return ret;
}
h256s chain() const { ReadGuard l(m_lock); return m_chain; }
size_t chainSize() const { ReadGuard l(m_lock); return m_chain.size(); }
size_t chainEmpty() const { ReadGuard l(m_lock); return m_chain.empty(); }
void foreachSub(std::function<void(DownloadSub const&)> const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); }
unsigned subCount() const { ReadGuard l(x_subs); return m_subs.size(); }
RangeMask<unsigned> blocksGot() const { ReadGuard l(m_lock); return m_blocksGot; }

53
libethereum/EthereumHost.cpp

@ -122,7 +122,7 @@ void EthereumHost::noteDoneBlocks(EthereumPeer* _who, bool _clemency)
// Done our chain-get.
clog(NetNote) << "Chain download complete.";
// 1/100th for each useful block hash.
_who->addRating(m_man.chain().size() / 100);
_who->addRating(m_man.chainSize() / 100);
m_man.reset();
}
else if (_who->isSyncing())
@ -189,7 +189,7 @@ void EthereumHost::maintainTransactions()
for (auto const& i: ts)
{
bool unsent = !m_transactionsSent.count(i.first);
for (auto const& p: randomSelection(100, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); }))
for (auto const& p: randomSelection(0, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); }).second)
peerTransactions[p].push_back(i.first);
}
for (auto const& t: ts)
@ -218,28 +218,28 @@ void EthereumHost::maintainTransactions()
}
}
std::vector<std::shared_ptr<EthereumPeer>> EthereumHost::randomSelection(unsigned _percent, std::function<bool(EthereumPeer*)> const& _allow)
pair<vector<shared_ptr<EthereumPeer>>, vector<shared_ptr<EthereumPeer>>> EthereumHost::randomSelection(unsigned _percent, std::function<bool(EthereumPeer*)> const& _allow)
{
std::vector<std::shared_ptr<EthereumPeer>> candidates;
candidates.reserve(peerSessions().size());
pair<vector<shared_ptr<EthereumPeer>>, vector<shared_ptr<EthereumPeer>>> ret;
ret.second.reserve(peerSessions().size());
for (auto const& j: peerSessions())
{
auto pp = j.first->cap<EthereumPeer>();
if (_allow(pp.get()))
candidates.push_back(pp);
ret.second.push_back(pp);
}
std::vector<std::shared_ptr<EthereumPeer>> ret;
for (unsigned i = (peerSessions().size() * _percent + 99) / 100; i-- && candidates.size();)
ret.second.reserve((peerSessions().size() * _percent + 99) / 100);
for (unsigned i = (peerSessions().size() * _percent + 99) / 100; i-- && ret.second.size();)
{
unsigned n = rand() % candidates.size();
ret.push_back(std::move(candidates[n]));
candidates.erase(candidates.begin() + n);
unsigned n = rand() % ret.second.size();
ret.first.push_back(std::move(ret.second[n]));
ret.second.erase(ret.second.begin() + n);
}
return ret;
}
void EthereumHost::maintainBlocks(h256 _currentHash)
void EthereumHost::maintainBlocks(h256 const& _currentHash)
{
// Send any new blocks.
auto detailsFrom = m_chain.details(m_latestBlockSent);
@ -253,17 +253,28 @@ void EthereumHost::maintainBlocks(h256 _currentHash)
h256s blocks = get<0>(m_chain.treeRoute(m_latestBlockSent, _currentHash, false, false, true));
for (auto const& p: randomSelection(100, [&](EthereumPeer* p){return !p->m_knownBlocks.count(_currentHash); }))
auto s = randomSelection(25, [&](EthereumPeer* p){ ETH_GUARDED(p->x_knownBlocks) return !p->m_knownBlocks.count(_currentHash); return false; });
for (shared_ptr<EthereumPeer> const& p: s.first)
for (auto const& b: blocks)
if (!p->m_knownBlocks.count(b))
{
RLPStream ts;
p->prep(ts, NewBlockPacket, 2).appendRaw(m_chain.block(b), 1).append(m_chain.details(b).totalDifficulty);
{
RLPStream ts;
p->prep(ts, NewBlockPacket, 2).appendRaw(m_chain.block(b), 1).append(m_chain.details(b).totalDifficulty);
Guard l(p->x_knownBlocks);
p->sealAndSend(ts);
p->m_knownBlocks.clear();
}
Guard l(p->x_knownBlocks);
p->sealAndSend(ts);
p->m_knownBlocks.clear();
}
for (shared_ptr<EthereumPeer> const& p: s.second)
{
RLPStream ts;
p->prep(ts, NewBlockHashesPacket, blocks.size());
for (auto const& b: blocks)
ts.append(b);
Guard l(p->x_knownBlocks);
p->sealAndSend(ts);
p->m_knownBlocks.clear();
}
}
m_latestBlockSent = _currentHash;
}

4
libethereum/EthereumHost.h

@ -80,7 +80,7 @@ public:
void noteNewBlocks() { m_newBlocks = true; }
private:
std::vector<std::shared_ptr<EthereumPeer>> randomSelection(unsigned _percent = 25, std::function<bool(EthereumPeer*)> const& _allow = [](EthereumPeer const*){ return true; });
std::pair<std::vector<std::shared_ptr<EthereumPeer>>, std::vector<std::shared_ptr<EthereumPeer>>> randomSelection(unsigned _percent = 25, std::function<bool(EthereumPeer*)> const& _allow = [](EthereumPeer const*){ return true; });
/// Session is tell us that we may need (re-)syncing with the peer.
void noteNeedsSyncing(EthereumPeer* _who);
@ -92,7 +92,7 @@ private:
void doWork();
void maintainTransactions();
void maintainBlocks(h256 _currentBlock);
void maintainBlocks(h256 const& _currentBlock);
/// Get a bunch of needed blocks.
/// Removes them from our list of needed blocks.

67
libethereum/EthereumPeer.cpp

@ -326,12 +326,12 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
transition(Asking::Nothing);
break;
}
case GetTransactionsPacket: break; // DEPRECATED.
case TransactionsPacket:
{
clog(NetAllDetail) << "Transactions (" << dec << _r.itemCount() << "entries)";
unsigned itemCount = _r.itemCount();
clog(NetAllDetail) << "Transactions (" << dec << itemCount << "entries)";
Guard l(x_knownTransactions);
for (unsigned i = 0; i < _r.itemCount(); ++i)
for (unsigned i = 0; i < itemCount; ++i)
{
auto h = sha3(_r[i].data());
m_knownTransactions.insert(h);
@ -373,21 +373,22 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
}
case BlockHashesPacket:
{
clog(NetMessageSummary) << "BlockHashes (" << dec << _r.itemCount() << "entries)" << (_r.itemCount() ? "" : ": NoMoreHashes");
unsigned itemCount = _r.itemCount();
clog(NetMessageSummary) << "BlockHashes (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreHashes");
if (m_asking != Asking::Hashes)
{
cwarn << "Peer giving us hashes when we didn't ask for them.";
break;
}
if (_r.itemCount() == 0)
if (itemCount == 0)
{
transition(Asking::Blocks);
return true;
}
unsigned knowns = 0;
unsigned unknowns = 0;
for (unsigned i = 0; i < _r.itemCount(); ++i)
for (unsigned i = 0; i < itemCount; ++i)
{
addRating(1);
auto h = _r[i].toHash<h256>();
@ -454,12 +455,13 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
}
case BlocksPacket:
{
clog(NetMessageSummary) << "Blocks (" << dec << _r.itemCount() << "entries)" << (_r.itemCount() ? "" : ": NoMoreBlocks");
unsigned itemCount = _r.itemCount();
clog(NetMessageSummary) << "Blocks (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreBlocks");
if (m_asking != Asking::Blocks)
clog(NetWarn) << "Unexpected Blocks received!";
if (_r.itemCount() == 0)
if (itemCount == 0)
{
// Got to this peer's latest block - just give up.
transition(Asking::Nothing);
@ -472,7 +474,7 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
unsigned got = 0;
unsigned repeated = 0;
for (unsigned i = 0; i < _r.itemCount(); ++i)
for (unsigned i = 0; i < itemCount; ++i)
{
auto h = BlockInfo::headerHash(_r[i].data());
if (m_sub.noteBlock(h))
@ -557,8 +559,51 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
default:;
}
Guard l(x_knownBlocks);
m_knownBlocks.insert(h);
ETH_GUARDED(x_knownBlocks)
m_knownBlocks.insert(h);
}
break;
}
case NewBlockHashesPacket:
{
clog(NetMessageSummary) << "NewBlockHashes";
if (host()->isSyncing())
clog(NetMessageSummary) << "Ignoring since we're already downloading.";
else
{
unsigned knowns = 0;
unsigned unknowns = 0;
unsigned itemCount = _r.itemCount();
for (unsigned i = 0; i < itemCount; ++i)
{
addRating(1);
auto h = _r[i].toHash<h256>();
ETH_GUARDED(x_knownBlocks)
m_knownBlocks.insert(h);
auto status = host()->m_bq.blockStatus(h);
if (status == QueueStatus::Importing || status == QueueStatus::Ready || host()->m_chain.isKnown(h))
knowns++;
else if (status == QueueStatus::Bad)
{
cwarn << "block hash bad!" << h << ". Bailing...";
return true;
}
else if (status == QueueStatus::Unknown)
{
unknowns++;
m_syncingNeededBlocks.push_back(h);
}
else
knowns++;
}
clog(NetMessageSummary) << knowns << "knowns," << unknowns << "unknowns";
if (unknowns > 0)
{
host()->m_man.resetToChain(m_syncingNeededBlocks);
host()->changeSyncer(this);
transition(Asking::Blocks);
}
return true;
}
break;
}

2
libethereum/EthereumPeer.h

@ -129,7 +129,7 @@ private:
/// This is built as we ask for hashes. Once no more hashes are given, we present this to the
/// host who initialises the DownloadMan and m_sub becomes active for us to begin asking for blocks.
h256s m_syncingNeededBlocks; ///< The blocks that we should download from this peer.
h256 m_syncingLastReceivedHash; ///< Hash more recently received from peer.
h256 m_syncingLastReceivedHash; ///< Hash most recently received from peer.
h256 m_syncingLatestHash; ///< Peer's latest block's hash, as of the current sync.
u256 m_syncingTotalDifficulty; ///< Peer's latest block's total difficulty, as of the current sync.

3
libethereum/Interface.h

@ -25,7 +25,6 @@
#include <libdevcore/CommonIO.h>
#include <libdevcore/Guards.h>
#include <libdevcrypto/Common.h>
#include <libethcore/Params.h>
#include <libethcore/ProofOfWork.h>
#include "LogFilter.h"
#include "Transaction.h"
@ -100,12 +99,14 @@ public:
u256 countAt(Address _a) const { return countAt(_a, m_default); }
u256 stateAt(Address _a, u256 _l) const { return stateAt(_a, _l, m_default); }
bytes codeAt(Address _a) const { return codeAt(_a, m_default); }
h256 codeHashAt(Address _a) const { return codeHashAt(_a, m_default); }
std::map<u256, u256> storageAt(Address _a) const { return storageAt(_a, m_default); }
virtual u256 balanceAt(Address _a, BlockNumber _block) const = 0;
virtual u256 countAt(Address _a, BlockNumber _block) const = 0;
virtual u256 stateAt(Address _a, u256 _l, BlockNumber _block) const = 0;
virtual bytes codeAt(Address _a, BlockNumber _block) const = 0;
virtual h256 codeHashAt(Address _a, BlockNumber _block) const = 0;
virtual std::map<u256, u256> storageAt(Address _a, BlockNumber _block) const = 0;
// [LOGS API]

2
libethereum/Precompiled.cpp

@ -24,7 +24,7 @@
#include <libdevcrypto/SHA3.h>
#include <libdevcrypto/Common.h>
#include <libethcore/Common.h>
#include <libethcore/Params.h>
#include <libevmcore/Params.h>
using namespace std;
using namespace dev;
using namespace dev::eth;

1
libethereum/State.h

@ -31,7 +31,6 @@
#include <libethcore/BlockInfo.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/Miner.h>
#include <libethcore/Params.h>
#include <libevm/ExtVMFace.h>
#include "TransactionQueue.h"
#include "Account.h"

2
libethereum/Transaction.h

@ -24,7 +24,7 @@
#include <libdevcore/RLP.h>
#include <libdevcrypto/SHA3.h>
#include <libethcore/Common.h>
#include <libethcore/Params.h>
#include <libevmcore/Params.h>
namespace dev
{
namespace eth

1
libethereum/TransactionQueue.cpp

@ -36,7 +36,6 @@ ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, ImportCallb
h256 h = sha3(_transactionRLP);
UpgradableGuard l(m_lock);
// TODO: keep old transactions around and check in State for nonce validity
auto ir = check_WITH_LOCK(h, _ik);
if (ir != ImportResult::Success)

2
libevm/VM.h

@ -27,7 +27,7 @@
#include <libevmcore/Instruction.h>
#include <libdevcrypto/SHA3.h>
#include <libethcore/BlockInfo.h>
#include <libethcore/Params.h>
#include <libevmcore/Params.h>
#include "VMFace.h"
namespace dev

4
libevmcore/Assembly.cpp → libevmasm/Assembly.cpp

@ -22,8 +22,8 @@
#include "Assembly.h"
#include <fstream>
#include <libdevcore/Log.h>
#include <libevmcore/CommonSubexpressionEliminator.h>
#include <libevmcore/ControlFlowGraph.h>
#include <libevmasm/CommonSubexpressionEliminator.h>
#include <libevmasm/ControlFlowGraph.h>
#include <json/json.h>
using namespace std;
using namespace dev;

4
libevmcore/Assembly.h → libevmasm/Assembly.h

@ -25,9 +25,9 @@
#include <sstream>
#include <libdevcore/Common.h>
#include <libdevcore/Assertions.h>
#include <libevmcore/SourceLocation.h>
#include <libevmcore/Instruction.h>
#include <libevmcore/AssemblyItem.h>
#include <libevmasm/SourceLocation.h>
#include <libevmasm/AssemblyItem.h>
#include "Exceptions.h"
#include <json/json.h>

0
libevmcore/AssemblyItem.cpp → libevmasm/AssemblyItem.cpp

2
libevmcore/AssemblyItem.h → libevmasm/AssemblyItem.h

@ -25,8 +25,8 @@
#include <sstream>
#include <libdevcore/Common.h>
#include <libdevcore/Assertions.h>
#include <libevmcore/SourceLocation.h>
#include <libevmcore/Instruction.h>
#include <libevmasm/SourceLocation.h>
#include "Exceptions.h"
namespace dev

33
libevmasm/CMakeLists.txt

@ -0,0 +1,33 @@
cmake_policy(SET CMP0015 NEW)
# this policy was introduced in cmake 3.0
# remove if, once 3.0 will be used on unix
if (${CMAKE_MAJOR_VERSION} GREATER 2)
# old policy do not use MACOSX_RPATH
cmake_policy(SET CMP0042 OLD)
endif()
set(CMAKE_AUTOMOC OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
aux_source_directory(. SRC_LIST)
include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
include_directories(BEFORE ..)
include_directories(${Boost_INCLUDE_DIRS})
set(EXECUTABLE evmasm)
file(GLOB HEADERS "*.h")
if (ETH_STATIC)
add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
else()
add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
endif()
target_link_libraries(${EXECUTABLE} evmcore)
target_link_libraries(${EXECUTABLE} devcrypto)
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

4
libevmcore/CommonSubexpressionEliminator.cpp → libevmasm/CommonSubexpressionEliminator.cpp

@ -24,8 +24,8 @@
#include <functional>
#include <boost/range/adaptor/reversed.hpp>
#include <libdevcrypto/SHA3.h>
#include <libevmcore/CommonSubexpressionEliminator.h>
#include <libevmcore/AssemblyItem.h>
#include <libevmasm/CommonSubexpressionEliminator.h>
#include <libevmasm/AssemblyItem.h>
using namespace std;
using namespace dev;

4
libevmcore/CommonSubexpressionEliminator.h → libevmasm/CommonSubexpressionEliminator.h

@ -30,8 +30,8 @@
#include <ostream>
#include <libdevcore/CommonIO.h>
#include <libdevcore/Exceptions.h>
#include <libevmcore/ExpressionClasses.h>
#include <libevmcore/SemanticInformation.h>
#include <libevmasm/ExpressionClasses.h>
#include <libevmasm/SemanticInformation.h>
namespace dev
{

8
libevmcore/ControlFlowGraph.cpp → libevmasm/ControlFlowGraph.cpp

@ -21,11 +21,11 @@
* Control flow analysis for the optimizer.
*/
#include <libevmcore/ControlFlowGraph.h>
#include <libevmasm/ControlFlowGraph.h>
#include <map>
#include <libevmcore/Exceptions.h>
#include <libevmcore/AssemblyItem.h>
#include <libevmcore/SemanticInformation.h>
#include <libevmasm/Exceptions.h>
#include <libevmasm/AssemblyItem.h>
#include <libevmasm/SemanticInformation.h>
using namespace std;
using namespace dev;

0
libevmcore/ControlFlowGraph.h → libevmasm/ControlFlowGraph.h

36
libevmasm/Exceptions.h

@ -0,0 +1,36 @@
/*
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 Exceptions.h
* @author Christian <c@ethdev.com>
* @date 2014
*/
#pragma once
#include <libdevcore/Exceptions.h>
namespace dev
{
namespace eth
{
struct AssemblyException: virtual Exception {};
struct OptimizerException: virtual AssemblyException {};
struct StackTooDeepException: virtual OptimizerException {};
}
}

6
libevmcore/ExpressionClasses.cpp → libevmasm/ExpressionClasses.cpp

@ -21,14 +21,14 @@
* Container for equivalence classes of expressions for use in common subexpression elimination.
*/
#include <libevmcore/ExpressionClasses.h>
#include <libevmasm/ExpressionClasses.h>
#include <utility>
#include <tuple>
#include <functional>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/noncopyable.hpp>
#include <libevmcore/Assembly.h>
#include <libevmcore/CommonSubexpressionEliminator.h>
#include <libevmasm/Assembly.h>
#include <libevmasm/CommonSubexpressionEliminator.h>
using namespace std;
using namespace dev;

2
libevmcore/ExpressionClasses.h → libevmasm/ExpressionClasses.h

@ -27,7 +27,7 @@
#include <map>
#include <memory>
#include <libdevcore/Common.h>
#include <libevmcore/AssemblyItem.h>
#include <libevmasm/AssemblyItem.h>
namespace dev
{

4
libevmcore/SemanticInformation.cpp → libevmasm/SemanticInformation.cpp

@ -21,8 +21,8 @@
* Helper to provide semantic information about assembly items.
*/
#include <libevmcore/SemanticInformation.h>
#include <libevmcore/AssemblyItem.h>
#include <libevmasm/SemanticInformation.h>
#include <libevmasm/AssemblyItem.h>
using namespace std;
using namespace dev;

0
libevmcore/SemanticInformation.h → libevmasm/SemanticInformation.h

0
libevmcore/SourceLocation.h → libevmasm/SourceLocation.h

4
libevmcore/CMakeLists.txt

@ -7,11 +7,8 @@ if (${CMAKE_MAJOR_VERSION} GREATER 2)
endif()
set(CMAKE_AUTOMOC OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
aux_source_directory(. SRC_LIST)
include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
include_directories(BEFORE ..)
include_directories(${Boost_INCLUDE_DIRS})
@ -22,7 +19,6 @@ file(GLOB HEADERS "*.h")
add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
target_link_libraries(${EXECUTABLE} devcore)
target_link_libraries(${EXECUTABLE} devcrypto)
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

7
libevmcore/Exceptions.h

@ -28,11 +28,8 @@ namespace dev
namespace eth
{
struct AssemblyException: virtual Exception {};
struct InvalidDeposit: virtual AssemblyException {};
struct InvalidOpcode: virtual AssemblyException {};
struct OptimizerException: virtual AssemblyException {};
struct StackTooDeepException: virtual OptimizerException {};
struct InvalidDeposit: virtual Exception {};
struct InvalidOpcode: virtual Exception {};
}
}

69
libevmcore/Params.cpp

@ -0,0 +1,69 @@
/*
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 Params.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Params.h"
using namespace std;
namespace dev
{
namespace eth
{
//--- BEGIN: AUTOGENERATED FROM github.com/ethereum/common/params.json
u256 const c_stackLimit = 1024;
u256 const c_tierStepGas[] = {0, 2, 3, 5, 8, 10, 20, 0};
u256 const c_expGas = 10;
u256 const c_expByteGas = 10;
u256 const c_sha3Gas = 30;
u256 const c_sha3WordGas = 6;
u256 const c_sloadGas = 50;
u256 const c_sstoreSetGas = 20000;
u256 const c_sstoreResetGas = 5000;
u256 const c_sstoreRefundGas = 15000;
u256 const c_jumpdestGas = 1;
u256 const c_logGas = 375;
u256 const c_logDataGas = 8;
u256 const c_logTopicGas = 375;
u256 const c_createGas = 32000;
u256 const c_callGas = 40;
u256 const c_callStipend = 2300;
u256 const c_callValueTransferGas = 9000;
u256 const c_callNewAccountGas = 25000;
u256 const c_suicideRefundGas = 24000;
u256 const c_memoryGas = 3;
u256 const c_quadCoeffDiv = 512;
u256 const c_createDataGas = 200;
u256 const c_txGas = 21000;
u256 const c_txDataZeroGas = 4;
u256 const c_txDataNonZeroGas = 68;
u256 const c_copyGas = 3;
u256 const c_ecrecoverGas = 3000;
u256 const c_sha256Gas = 60;
u256 const c_sha256WordGas = 12;
u256 const c_ripemd160Gas = 600;
u256 const c_ripemd160WordGas = 120;
u256 const c_identityGas = 15;
u256 const c_identityWordGas = 3;
//--- END: AUTOGENERATED FROM /feeStructure.json
}
}

69
libevmcore/Params.h

@ -0,0 +1,69 @@
/*
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 Params.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <libdevcore/Common.h>
namespace dev
{
namespace eth
{
//--- BEGIN: AUTOGENERATED FROM /feeStructure.json
extern u256 const c_stackLimit;
extern u256 const c_tierStepGas[8]; ///< Once per operation, for a selection of them.
extern u256 const c_expGas; ///< Once per EXP instuction.
extern u256 const c_expByteGas; ///< Times ceil(log256(exponent)) for the EXP instruction.
extern u256 const c_sha3Gas; ///< Once per SHA3 operation.
extern u256 const c_sha3WordGas; ///< Once per word of the SHA3 operation's data.
extern u256 const c_copyGas; ///< Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
extern u256 const c_sloadGas; ///< Once per SLOAD operation.
extern u256 const c_sstoreSetGas; ///< Once per SSTORE operation if the zeroness changes from zero.
extern u256 const c_sstoreResetGas; ///< Once per SSTORE operation if the zeroness does not change from zero. NOTE: when c_sstoreSetGas does not apply.
extern u256 const c_sstoreRefundGas; ///< Refunded gas, once per SSTORE operation if the zeroness changes to zero.
extern u256 const c_jumpdestGas; ///< Once per JUMPDEST operation.
extern u256 const c_logGas; ///< Per LOG* operation.
extern u256 const c_logDataGas; ///< Per byte in a LOG* operation's data.
extern u256 const c_logTopicGas; ///< Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
extern u256 const c_createGas; ///< Once per CREATE operation & contract-creation transaction.
extern u256 const c_createDataGas;
extern u256 const c_callGas; ///< Once per CALL operation & message call transaction.
extern u256 const c_callStipend; ///< Free gas given at beginning of call.
extern u256 const c_callNewAccountGas; ///< Paid for CALL when the destination address didn't exist prior.
extern u256 const c_callValueTransferGas; ///< Paid for CALL when the value transfor is non-zero.
extern u256 const c_suicideRefundGas; ///< Refunded following a suicide operation.
extern u256 const c_memoryGas; ///< Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
extern u256 const c_quadCoeffDiv; ///< Divisor for the quadratic particle of the memory cost equation.
extern u256 const c_txGas; ///< Per transaction. NOTE: Not payable on data of calls between transactions.
extern u256 const c_txDataZeroGas; ///< Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions.
extern u256 const c_txDataNonZeroGas; ///< Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
extern u256 const c_ecrecoverGas;
extern u256 const c_sha256Gas;
extern u256 const c_sha256WordGas;
extern u256 const c_ripemd160Gas;
extern u256 const c_ripemd160WordGas;
extern u256 const c_identityGas;
extern u256 const c_identityWordGas;
}
}

2
libjsqrc/setup.js

@ -21,5 +21,5 @@
*/
var web3 = require('web3');
web3.setProvider(new web3.providers.HttpProvider("http://localhost:8080"));
web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545"));

3
liblll/CMakeLists.txt

@ -21,8 +21,7 @@ file(GLOB HEADERS "*.h")
add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
target_link_libraries(${EXECUTABLE} evmcore)
target_link_libraries(${EXECUTABLE} devcore)
target_link_libraries(${EXECUTABLE} evmasm)
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

2
liblll/CodeFragment.h

@ -23,7 +23,7 @@
#include <libdevcore/Common.h>
#include <libevmcore/Instruction.h>
#include <libevmcore/Assembly.h>
#include <libevmasm/Assembly.h>
#include "Exceptions.h"
namespace boost { namespace spirit { class utree; } }

23
libp2p/Host.cpp

@ -208,7 +208,7 @@ void Host::startPeerSession(Public const& _id, RLP const& _rlp, RLPXFrameIO* _io
// create session so disconnects are managed
auto ps = make_shared<Session>(this, _io, p, PeerSessionInfo({_id, clientVersion, _endpoint.address().to_string(), listenPort, chrono::steady_clock::duration(), _rlp[2].toSet<CapDesc>(), 0, map<string, string>()}));
if (protocolVersion != dev::p2p::c_protocolVersion)
if (protocolVersion < dev::p2p::c_protocolVersion)
{
ps->disconnect(IncompatibleProtocol);
return;
@ -226,7 +226,7 @@ void Host::startPeerSession(Public const& _id, RLP const& _rlp, RLPXFrameIO* _io
return;
}
if (peerCount() > 2 * m_idealPeerCount)
if (!peerSlotsAvailable(Ingress))
{
ps->disconnect(TooManyPeers);
return;
@ -271,7 +271,7 @@ void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e)
clog(NetNote) << "p2p.host.peers.events.peerAdded " << _n << p->endpoint;
}
}
if (peerCount() < m_idealPeerCount)
if (peerSlotsAvailable(Egress))
connect(p);
}
}
@ -341,7 +341,7 @@ void Host::runAcceptor()
auto socket = make_shared<RLPXSocket>(new bi::tcp::socket(m_ioService));
m_tcp4Acceptor.async_accept(socket->ref(), [=](boost::system::error_code ec)
{
if (peerCount() > 2 * m_idealPeerCount)
if (peerCount() > 9 * m_idealPeerCount)
{
clog(NetConnect) << "Dropping incoming connect due to maximum peer count (2 * ideal peer count): " << socket->remoteEndpoint();
socket->close();
@ -413,7 +413,6 @@ void Host::requirePeer(NodeId const& _n, NodeIPEndpoint const& _endpoint)
// create or update m_peers entry
shared_ptr<Peer> p;
ETH_RECURSIVE_GUARDED(x_sessions)
{
if (m_peers.count(_n))
{
p = m_peers[_n];
@ -425,7 +424,6 @@ void Host::requirePeer(NodeId const& _n, NodeIPEndpoint const& _endpoint)
p.reset(new Peer(node));
m_peers[_n] = p;
}
}
connect(p);
}
else if (m_nodeTable)
@ -438,6 +436,7 @@ void Host::requirePeer(NodeId const& _n, NodeIPEndpoint const& _endpoint)
t->async_wait([this, _n](boost::system::error_code const& _ec)
{
if (!_ec && m_nodeTable)
// FIXME RACE CONDITION (use weak_ptr or mutex).
if (auto n = m_nodeTable->node(_n))
requirePeer(n.id, n.endpoint);
});
@ -464,7 +463,7 @@ void Host::connect(std::shared_ptr<Peer> const& _p)
return;
}
if (!m_nodeTable->haveNode(_p->id))
if (!!m_nodeTable && !m_nodeTable->haveNode(_p->id))
{
clog(NetWarn) << "Aborted connect. Node not in node table.";
m_nodeTable->addNode(*_p.get());
@ -578,7 +577,11 @@ void Host::run(boost::system::error_code const&)
// is always live and to ensure reputation and fallback timers are properly
// updated. // disconnectLatePeers();
int openSlots = m_idealPeerCount - peerCount();
// todo: update peerSlotsAvailable()
unsigned pendingCount = 0;
ETH_GUARDED(x_pendingNodeConns)
pendingCount = m_pendingPeerConns.size();
int openSlots = m_idealPeerCount - peerCount() - pendingCount;
if (openSlots > 0)
{
list<shared_ptr<Peer>> toConnect;
@ -759,7 +762,7 @@ void Host::restoreNetwork(bytesConstRef _b)
// todo: ipv6, bi::address_v6(i[0].toArray<byte, 16>()
Node n((NodeId)i[2], NodeIPEndpoint(bi::address_v4(i[0].toArray<byte, 4>()), i[1].toInt<uint16_t>(), i[1].toInt<uint16_t>()));
if (i.itemCount() == 3 && n.endpoint.isAllowed())
m_nodeTable->addNode(n);
m_nodeTable->addNode(n, NodeTable::NodeRelation::Known);
else if (i.itemCount() == 10)
{
n.required = i[3].toInt<bool>();
@ -776,7 +779,7 @@ void Host::restoreNetwork(bytesConstRef _b)
if (p->required)
requirePeer(p->id, n.endpoint);
else
m_nodeTable->addNode(*p.get());
m_nodeTable->addNode(*p.get(), NodeTable::NodeRelation::Known);
}
}
}

7
libp2p/Host.h

@ -135,6 +135,8 @@ public:
// TODO: P2P this should be combined with peers into a HostStat object of some kind; coalesce data, as it's only used for status information.
Peers getPeers() const { RecursiveGuard l(x_sessions); Peers ret; for (auto const& i: m_peers) ret.push_back(*i.second); return ret; }
NetworkPreferences const& networkPreferences() const { return m_netPrefs; }
void setNetworkPreferences(NetworkPreferences const& _p, bool _dropPeers = false) { m_dropPeers = _dropPeers; auto had = isStarted(); if (had) stop(); m_netPrefs = _p; if (had) start(); }
/// Start network. @threadsafe
@ -162,6 +164,8 @@ protected:
void restoreNetwork(bytesConstRef _b);
private:
enum PeerSlotRatio { Egress = 2, Ingress = 9 };
bool havePeerSession(NodeId _id) { RecursiveGuard l(x_sessions); return m_sessions.count(_id) ? !!m_sessions[_id].lock() : false; }
/// Determines and sets m_tcpPublic to publicly advertised address.
@ -169,6 +173,9 @@ private:
void connect(std::shared_ptr<Peer> const& _p);
/// Returns true if pending and connected peer count is less than maximum
bool peerSlotsAvailable(PeerSlotRatio _type) { Guard l(x_pendingNodeConns); return peerCount() + m_pendingPeerConns.size() < _type * m_idealPeerCount; }
/// Ping the peers to update the latency information and disconnect peers which have timed out.
void keepAlivePeers();

2
libp2p/Network.cpp

@ -226,7 +226,7 @@ bi::tcp::endpoint Network::resolveHost(string const& _addr)
boost::system::error_code ec;
// resolve returns an iterator (host can resolve to multiple addresses)
bi::tcp::resolver r(s_resolverIoService);
auto it = r.resolve({split[0], toString(port)}, ec);
auto it = r.resolve({bi::tcp::v4(), split[0], toString(port)}, ec);
if (ec)
clog(NetWarn) << "Error resolving host address..." << LogTag::Url << _addr << ":" << LogTag::Error << ec.message();
else

11
libp2p/NodeTable.cpp

@ -81,8 +81,17 @@ shared_ptr<NodeEntry> NodeTable::addNode(Public const& _pubk, NodeIPEndpoint con
return addNode(node);
}
shared_ptr<NodeEntry> NodeTable::addNode(Node const& _node)
shared_ptr<NodeEntry> NodeTable::addNode(Node const& _node, NodeRelation _relation)
{
if (_relation == Known)
{
shared_ptr<NodeEntry> ret(new NodeEntry(m_node, _node.id, _node.endpoint));
ret->pending = false;
m_nodes[_node.id] = ret;
noteActiveNode(_node.id, _node.endpoint);
return ret;
}
// re-enable tcp checks when NAT hosts are handled by discover
// we handle when tcp endpoint is 0 below
if (_node.endpoint.address.to_string() == "0.0.0.0")

10
libp2p/NodeTable.h

@ -133,12 +133,14 @@ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this<NodeTable>
using EvictionTimeout = std::pair<NodeIdTimePoint, NodeId>; ///< First NodeId (NodeIdTimePoint) may be evicted and replaced with second NodeId.
public:
enum NodeRelation { Unknown = 0, Known };
/// Constructor requiring host for I/O, credentials, and IP Address and port to listen on.
NodeTable(ba::io_service& _io, KeyPair const& _alias, NodeIPEndpoint const& _endpoint);
~NodeTable();
/// Returns distance based on xor metric two node ids. Used by NodeEntry and NodeTable.
static unsigned distance(NodeId const& _a, NodeId const& _b) { u512 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; }
static unsigned distance(NodeId const& _a, NodeId const& _b) { u256 d = sha3(_a) ^ sha3(_b); unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; }
/// Set event handler for NodeEntryAdded and NodeEntryDropped events.
void setEventHandler(NodeTableEventHandler* _handler) { m_nodeEventHandler.reset(_handler); }
@ -149,8 +151,8 @@ public:
/// Add node. Node will be pinged and empty shared_ptr is returned if NodeId is uknown.
std::shared_ptr<NodeEntry> addNode(Public const& _pubk, NodeIPEndpoint const& _ep);
/// Add node. Node will be pinged and empty shared_ptr is returned if node has never been seen.
std::shared_ptr<NodeEntry> addNode(Node const& _node);
/// Add node. Node will be pinged and empty shared_ptr is returned if node has never been seen or NodeId is empty.
std::shared_ptr<NodeEntry> addNode(Node const& _node, NodeRelation _relation = NodeRelation::Unknown);
/// To be called when node table is empty. Runs node discovery with m_node.id as the target in order to populate node-table.
void discover();
@ -178,7 +180,7 @@ private:
/// Constants for Kademlia, derived from address space.
static unsigned const s_addressByteSize = sizeof(NodeId); ///< Size of address type in bytes.
static unsigned const s_addressByteSize = h256::size; ///< Size of address type in bytes.
static unsigned const s_bits = 8 * s_addressByteSize; ///< Denoted by n in [Kademlia].
static unsigned const s_bins = s_bits - 1; ///< Size of m_state (excludes root, which is us).
static unsigned const s_maxSteps = boost::static_log2<s_bits>::value; ///< Max iterations of discovery. (discover)

28
libsolidity/AST.cpp

@ -96,8 +96,8 @@ void ContractDefinition::checkTypeRequirements()
FixedHash<4> const& hash = it.first;
if (hashes.count(hash))
BOOST_THROW_EXCEPTION(createTypeError(
std::string("Function signature hash collision for ") +
it.second->externalSignature()));
string("Function signature hash collision for ") + it.second->externalSignature()
));
hashes.insert(hash);
}
}
@ -140,12 +140,22 @@ void ContractDefinition::checkDuplicateFunctions() const
map<string, vector<FunctionDefinition const*>> functions;
for (ASTPointer<FunctionDefinition> const& function: getDefinedFunctions())
functions[function->getName()].push_back(function.get());
if (functions[getName()].size() > 1)
{
SecondarySourceLocation ssl;
auto it = functions[getName()].begin();
++it;
for (; it != functions[getName()].end(); ++it)
ssl.append("Another declaration is here:", (*it)->getLocation());
BOOST_THROW_EXCEPTION(
DeclarationError() <<
errinfo_sourceLocation(getLocation()) <<
errinfo_comment("More than one constructor defined.")
errinfo_sourceLocation(functions[getName()].front()->getLocation()) <<
errinfo_comment("More than one constructor defined.") <<
errinfo_secondarySourceLocation(ssl)
);
}
for (auto const& it: functions)
{
vector<FunctionDefinition const*> const& overloads = it.second;
@ -155,7 +165,9 @@ void ContractDefinition::checkDuplicateFunctions() const
BOOST_THROW_EXCEPTION(
DeclarationError() <<
errinfo_sourceLocation(overloads[j]->getLocation()) <<
errinfo_comment("Function with same name and arguments already defined.")
errinfo_comment("Function with same name and arguments defined twice.") <<
errinfo_secondarySourceLocation(SecondarySourceLocation().append(
"Other declaration is here:", overloads[i]->getLocation()))
);
}
}
@ -299,12 +311,12 @@ void ContractDefinition::checkExternalTypeClashes() const
));
}
std::vector<ASTPointer<EventDefinition>> const& ContractDefinition::getInterfaceEvents() const
vector<ASTPointer<EventDefinition>> const& ContractDefinition::getInterfaceEvents() const
{
if (!m_interfaceEvents)
{
set<string> eventsSeen;
m_interfaceEvents.reset(new std::vector<ASTPointer<EventDefinition>>());
m_interfaceEvents.reset(new vector<ASTPointer<EventDefinition>>());
for (ContractDefinition const* contract: getLinearizedBaseContracts())
for (ASTPointer<EventDefinition> const& e: contract->getEvents())
if (eventsSeen.count(e->getName()) == 0)
@ -944,7 +956,7 @@ void Identifier::overloadResolution(TypePointers const& _argumentTypes)
solAssert(!m_referencedDeclaration, "Referenced declaration should be null before overload resolution.");
solAssert(!m_overloadedDeclarations.empty(), "No candidates for overload resolution found.");
std::vector<Declaration const*> possibles;
vector<Declaration const*> possibles;
if (m_overloadedDeclarations.size() == 1)
m_referencedDeclaration = *m_overloadedDeclarations.begin();

2
libsolidity/AST.h

@ -27,7 +27,7 @@
#include <vector>
#include <memory>
#include <boost/noncopyable.hpp>
#include <libevmcore/SourceLocation.h>
#include <libevmasm/SourceLocation.h>
#include <libsolidity/Utils.h>
#include <libsolidity/ASTForward.h>
#include <libsolidity/Token.h>

2
libsolidity/ASTUtils.h

@ -22,7 +22,7 @@
#pragma once
#include <libevmcore/SourceLocation.h>
#include <libevmasm/SourceLocation.h>
#include <libsolidity/ASTVisitor.h>
namespace dev

2
libsolidity/CMakeLists.txt

@ -22,7 +22,7 @@ file(GLOB HEADERS "*.h")
add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} evmcore)
target_link_libraries(${EXECUTABLE} evmasm)
target_link_libraries(${EXECUTABLE} devcrypto)
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )

7
libsolidity/Compiler.cpp

@ -24,7 +24,7 @@
#include <algorithm>
#include <boost/range/adaptor/reversed.hpp>
#include <libevmcore/Instruction.h>
#include <libevmcore/Assembly.h>
#include <libevmasm/Assembly.h>
#include <libsolidity/AST.h>
#include <libsolidity/ExpressionCompiler.h>
#include <libsolidity/CompilerUtils.h>
@ -431,7 +431,8 @@ bool Compiler::visit(ForStatement const& _forStatement)
CompilerContext::LocationSetter locationSetter(m_context, _forStatement);
eth::AssemblyItem loopStart = m_context.newTag();
eth::AssemblyItem loopEnd = m_context.newTag();
m_continueTags.push_back(loopStart);
eth::AssemblyItem loopNext = m_context.newTag();
m_continueTags.push_back(loopNext);
m_breakTags.push_back(loopEnd);
if (_forStatement.getInitializationExpression())
@ -449,6 +450,8 @@ bool Compiler::visit(ForStatement const& _forStatement)
_forStatement.getBody().accept(*this);
m_context << loopNext;
// for's loop expression if existing
if (_forStatement.getLoopExpression())
_forStatement.getLoopExpression()->accept(*this);

2
libsolidity/Compiler.h

@ -26,7 +26,7 @@
#include <functional>
#include <libsolidity/ASTVisitor.h>
#include <libsolidity/CompilerContext.h>
#include <libevmcore/Assembly.h>
#include <libevmasm/Assembly.h>
namespace dev {
namespace solidity {

2
libsolidity/CompilerContext.h

@ -26,7 +26,7 @@
#include <stack>
#include <utility>
#include <libevmcore/Instruction.h>
#include <libevmcore/Assembly.h>
#include <libevmasm/Assembly.h>
#include <libsolidity/ASTForward.h>
#include <libsolidity/Types.h>
#include <libdevcore/Common.h>

42
libsolidity/DeclarationContainer.cpp

@ -28,6 +28,28 @@ using namespace std;
using namespace dev;
using namespace dev::solidity;
Declaration const* DeclarationContainer::conflictingDeclaration(Declaration const& _declaration) const
{
ASTString const& name(_declaration.getName());
solAssert(!name.empty(), "");
vector<Declaration const*> declarations;
if (m_declarations.count(name))
declarations += m_declarations.at(name);
if (m_invisibleDeclarations.count(name))
declarations += m_invisibleDeclarations.at(name);
if (dynamic_cast<FunctionDefinition const*>(&_declaration))
{
// check that all other declarations with the same name are functions
for (Declaration const* declaration: declarations)
if (!dynamic_cast<FunctionDefinition const*>(declaration))
return declaration;
}
else if (!declarations.empty())
return declarations.front();
return nullptr;
}
bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, bool _invisible, bool _update)
{
ASTString const& name(_declaration.getName());
@ -40,24 +62,8 @@ bool DeclarationContainer::registerDeclaration(Declaration const& _declaration,
m_declarations.erase(name);
m_invisibleDeclarations.erase(name);
}
else
{
vector<Declaration const*> declarations;
if (m_declarations.count(name))
declarations += m_declarations.at(name);
if (m_invisibleDeclarations.count(name))
declarations += m_invisibleDeclarations.at(name);
if (dynamic_cast<FunctionDefinition const*>(&_declaration))
{
// check that all other declarations with the same name are functions
for (Declaration const* declaration: declarations)
if (!dynamic_cast<FunctionDefinition const*>(declaration))
return false;
}
else if (!declarations.empty())
return false;
}
else if (conflictingDeclaration(_declaration))
return false;
if (_invisible)
m_invisibleDeclarations[name].insert(&_declaration);

4
libsolidity/DeclarationContainer.h

@ -34,7 +34,7 @@ namespace solidity
{
/**
* Container that stores mappings betwee names and declarations. It also contains a link to the
* Container that stores mappings between names and declarations. It also contains a link to the
* enclosing scope.
*/
class DeclarationContainer
@ -51,6 +51,8 @@ public:
std::set<Declaration const*> resolveName(ASTString const& _name, bool _recursive = false) const;
Declaration const* getEnclosingDeclaration() const { return m_enclosingDeclaration; }
std::map<ASTString, std::set<Declaration const*>> const& getDeclarations() const { return m_declarations; }
/// @returns whether declaration is valid, and if not also returns previous declaration.
Declaration const* conflictingDeclaration(Declaration const& _declaration) const;
private:
Declaration const* m_enclosingDeclaration;

18
libsolidity/Exceptions.h

@ -23,8 +23,9 @@
#pragma once
#include <string>
#include <utility>
#include <libdevcore/Exceptions.h>
#include <libevmcore/SourceLocation.h>
#include <libevmasm/SourceLocation.h>
namespace dev
{
@ -38,7 +39,22 @@ struct CompilerError: virtual Exception {};
struct InternalCompilerError: virtual Exception {};
struct DocstringParsingError: virtual Exception {};
using errorSourceLocationInfo = std::pair<std::string, SourceLocation>;
class SecondarySourceLocation
{
public:
SecondarySourceLocation& append(std::string const& _errMsg, SourceLocation const& _sourceLocation)
{
infos.push_back(std::make_pair(_errMsg, _sourceLocation));
return *this;
}
std::vector<errorSourceLocationInfo> infos;
};
using errinfo_sourceLocation = boost::error_info<struct tag_sourceLocation, SourceLocation>;
using errinfo_secondarySourceLocation = boost::error_info<struct tag_secondarySourceLocation, SecondarySourceLocation>;
}
}

2
libsolidity/ExpressionCompiler.h

@ -25,7 +25,7 @@
#include <memory>
#include <boost/noncopyable.hpp>
#include <libdevcore/Common.h>
#include <libevmcore/SourceLocation.h>
#include <libevmasm/SourceLocation.h>
#include <libsolidity/Utils.h>
#include <libsolidity/ASTVisitor.h>
#include <libsolidity/LValue.h>

2
libsolidity/LValue.h

@ -23,7 +23,7 @@
#pragma once
#include <memory>
#include <libevmcore/SourceLocation.h>
#include <libevmasm/SourceLocation.h>
#include <libsolidity/ArrayUtils.h>
namespace dev

37
libsolidity/NameAndTypeResolver.cpp

@ -354,9 +354,33 @@ void DeclarationRegistrationHelper::closeCurrentScope()
void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaration, bool _opensScope)
{
if (!m_scopes[m_currentScope].registerDeclaration(_declaration, !_declaration.isVisibleInContract()))
BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_declaration.getLocation())
<< errinfo_comment("Identifier already declared."));
//@todo the exception should also contain the location of the first declaration
{
SourceLocation firstDeclarationLocation;
SourceLocation secondDeclarationLocation;
Declaration const* conflictingDeclaration = m_scopes[m_currentScope].conflictingDeclaration(_declaration);
solAssert(conflictingDeclaration, "");
if (_declaration.getLocation().start < conflictingDeclaration->getLocation().start)
{
firstDeclarationLocation = _declaration.getLocation();
secondDeclarationLocation = conflictingDeclaration->getLocation();
}
else
{
firstDeclarationLocation = conflictingDeclaration->getLocation();
secondDeclarationLocation = _declaration.getLocation();
}
BOOST_THROW_EXCEPTION(
DeclarationError() <<
errinfo_sourceLocation(secondDeclarationLocation) <<
errinfo_comment("Identifier already declared.") <<
errinfo_secondarySourceLocation(
SecondarySourceLocation().append("The previous declaration is here:", firstDeclarationLocation)
)
);
}
_declaration.setScope(m_currentScope);
if (_opensScope)
enterNewSubScope(_declaration);
@ -435,8 +459,11 @@ bool ReferencesResolver::visit(Identifier& _identifier)
{
auto declarations = m_resolver.getNameFromCurrentScope(_identifier.getName());
if (declarations.empty())
BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_identifier.getLocation())
<< errinfo_comment("Undeclared identifier."));
BOOST_THROW_EXCEPTION(
DeclarationError() <<
errinfo_sourceLocation(_identifier.getLocation()) <<
errinfo_comment("Undeclared identifier.")
);
else if (declarations.size() == 1)
_identifier.setReferencedDeclaration(**declarations.begin(), m_currentContract);
else

2
libsolidity/Parser.cpp

@ -22,7 +22,7 @@
#include <vector>
#include <libdevcore/Log.h>
#include <libevmcore/SourceLocation.h>
#include <libevmasm/SourceLocation.h>
#include <libsolidity/Parser.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/Exceptions.h>

2
libsolidity/Scanner.h

@ -55,7 +55,7 @@
#include <libdevcore/Common.h>
#include <libdevcore/Log.h>
#include <libdevcore/CommonData.h>
#include <libevmcore/SourceLocation.h>
#include <libevmasm/SourceLocation.h>
#include <libsolidity/Token.h>
namespace dev

74
libsolidity/SourceReferenceFormatter.cpp

@ -32,9 +32,11 @@ namespace dev
namespace solidity
{
void SourceReferenceFormatter::printSourceLocation(ostream& _stream,
SourceLocation const& _location,
Scanner const& _scanner)
void SourceReferenceFormatter::printSourceLocation(
ostream& _stream,
SourceLocation const& _location,
Scanner const& _scanner
)
{
int startLine;
int startColumn;
@ -46,11 +48,11 @@ void SourceReferenceFormatter::printSourceLocation(ostream& _stream,
{
string line = _scanner.getLineAtPosition(_location.start);
_stream << line << endl;
std::for_each(line.cbegin(), line.cbegin() + startColumn,
[&_stream](char const& ch)
{
_stream << (ch == '\t' ? '\t' : ' ');
});
for_each(
line.cbegin(),
line.cbegin() + startColumn,
[&_stream](char const& ch) { _stream << (ch == '\t' ? '\t' : ' '); }
);
_stream << "^";
if (endColumn > startColumn + 2)
_stream << string(endColumn - startColumn - 2, '-');
@ -59,33 +61,65 @@ void SourceReferenceFormatter::printSourceLocation(ostream& _stream,
_stream << endl;
}
else
_stream << _scanner.getLineAtPosition(_location.start) << endl
<< string(startColumn, ' ') << "^\n"
<< "Spanning multiple lines.\n";
_stream <<
_scanner.getLineAtPosition(_location.start) <<
endl <<
string(startColumn, ' ') <<
"^\n" <<
"Spanning multiple lines.\n";
}
void SourceReferenceFormatter::printExceptionInformation(ostream& _stream,
Exception const& _exception,
string const& _name,
CompilerStack const& _compiler)
void SourceReferenceFormatter::printSourceName(
ostream& _stream,
SourceLocation const& _location,
Scanner const& _scanner
)
{
int startLine;
int startColumn;
tie(startLine, startColumn) = _scanner.translatePositionToLineColumn(_location.start);
_stream << *_location.sourceName << ":" << (startLine + 1) << ":" << (startColumn + 1) << ": ";
}
void SourceReferenceFormatter::printExceptionInformation(
ostream& _stream,
Exception const& _exception,
string const& _name,
CompilerStack const& _compiler
)
{
SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);
Scanner const* scanner;
auto secondarylocation = boost::get_error_info<errinfo_secondarySourceLocation>(_exception);
Scanner const* scanner = nullptr;
if (location)
{
scanner = &_compiler.getScanner(*location->sourceName);
int startLine;
int startColumn;
tie(startLine, startColumn) = scanner->translatePositionToLineColumn(location->start);
_stream << *location->sourceName << ":" << (startLine + 1) << ":" << (startColumn + 1) << ": ";
printSourceName(_stream, *location, *scanner);
}
_stream << _name;
if (string const* description = boost::get_error_info<errinfo_comment>(_exception))
_stream << ": " << *description << endl;
if (location)
{
scanner = &_compiler.getScanner(*location->sourceName);
printSourceLocation(_stream, *location, *scanner);
}
if (secondarylocation && !secondarylocation->infos.empty())
{
for (auto info: secondarylocation->infos)
{
scanner = &_compiler.getScanner(*info.second.sourceName);
_stream << info.first << " ";
printSourceName(_stream, info.second, *scanner);
_stream << endl;
printSourceLocation(_stream, info.second, *scanner);
}
_stream << endl;
}
}
}

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

Loading…
Cancel
Save