Browse Source

Major reorganisation.

New libs (libethsupport, libevm, liblll).
New LLLC binary.
cl-refactor
Gav Wood 11 years ago
parent
commit
e8217ea489
  1. 4
      CMakeLists.txt
  2. 13
      alethzero/MainWin.cpp
  3. 4
      alethzero/MainWin.h
  4. 10
      eth/CommonJS.h
  5. 3
      eth/EthStubServer.cpp
  6. 4
      eth/main.cpp
  7. 36
      libethcore/BlockInfo.cpp
  8. 15
      libethcore/BlockInfo.h
  9. 1
      libethcore/CMakeLists.txt
  10. 0
      libethcore/CommonEth.cpp
  11. 4
      libethcore/CommonEth.h
  12. 36
      libethcore/CryptoHeaders.h
  13. 4
      libethcore/Dagger.cpp
  14. 0
      libethcore/Dagger.h
  15. 49
      libethcore/Exceptions.h
  16. 232
      libethcore/Instruction.cpp
  17. 152
      libethcore/Instruction.h
  18. 73
      libethcore/vector_ref.h
  19. 2
      libethereum/AddressState.cpp
  20. 4
      libethereum/AddressState.h
  21. 61
      libethereum/BlockChain.cpp
  22. 13
      libethereum/BlockChain.h
  23. 3
      libethereum/CMakeLists.txt
  24. 2
      libethereum/Client.cpp
  25. 4
      libethereum/Client.h
  26. 2
      libethereum/Defaults.cpp
  27. 2
      libethereum/Defaults.h
  28. 48
      libethereum/Exceptions.h
  29. 2
      libethereum/Executive.cpp
  30. 2
      libethereum/Executive.h
  31. 4
      libethereum/ExtVM.h
  32. 4
      libethereum/PeerNetwork.h
  33. 7
      libethereum/PeerServer.cpp
  34. 2
      libethereum/PeerServer.h
  35. 5
      libethereum/PeerSession.cpp
  36. 4
      libethereum/PeerSession.h
  37. 40
      libethereum/State.cpp
  38. 19
      libethereum/State.h
  39. 6
      libethereum/Transaction.cpp
  40. 4
      libethereum/Transaction.h
  41. 4
      libethereum/TransactionQueue.cpp
  42. 2
      libethereum/TransactionQueue.h
  43. 68
      libethsupport/CMakeLists.txt
  44. 0
      libethsupport/Common.cpp
  45. 0
      libethsupport/Common.h
  46. 0
      libethsupport/CommonData.cpp
  47. 0
      libethsupport/CommonData.h
  48. 0
      libethsupport/CommonIO.cpp
  49. 0
      libethsupport/CommonIO.h
  50. 0
      libethsupport/FileSystem.cpp
  51. 0
      libethsupport/FileSystem.h
  52. 0
      libethsupport/FixedHash.cpp
  53. 0
      libethsupport/FixedHash.h
  54. 0
      libethsupport/Log.cpp
  55. 0
      libethsupport/Log.h
  56. 0
      libethsupport/RLP.cpp
  57. 0
      libethsupport/RLP.h
  58. 0
      libethsupport/TrieCommon.cpp
  59. 0
      libethsupport/TrieCommon.h
  60. 0
      libethsupport/TrieDB.cpp
  61. 0
      libethsupport/TrieDB.h
  62. 0
      libethsupport/UPnP.cpp
  63. 0
      libethsupport/UPnP.h
  64. 70
      libevm/CMakeLists.txt
  65. 0
      libevm/ExtVMFace.cpp
  66. 5
      libevm/ExtVMFace.h
  67. 0
      libevm/FeeStructure.cpp
  68. 2
      libevm/FeeStructure.h
  69. 0
      libevm/VM.cpp
  70. 16
      libevm/VM.h
  71. 0
      liblll/Assembly.cpp
  72. 0
      liblll/Assembly.h
  73. 70
      liblll/CMakeLists.txt
  74. 399
      liblll/CodeFragment.cpp
  75. 185
      liblll/CodeFragment.h
  76. 61
      liblll/Compiler.cpp
  77. 35
      liblll/Compiler.h
  78. 37
      liblll/CompilerState.cpp
  79. 49
      liblll/CompilerState.h
  80. 91
      liblll/Parser.cpp
  81. 38
      liblll/Parser.h
  82. 7
      libqethereum/QEthereum.cpp
  83. 4
      libqethereum/QEthereum.h
  84. 56
      lllc/CMakeLists.txt
  85. 106
      lllc/main.cpp
  86. 4
      neth/main.cpp
  87. 4
      test/MemTrie.cpp
  88. 4
      test/MemTrie.h
  89. 4
      test/TrieHash.cpp
  90. 4
      test/TrieHash.h
  91. 6
      test/crypto.cpp
  92. 4
      test/dagger.cpp
  93. 4
      test/hexPrefix.cpp
  94. 4
      test/main.cpp
  95. 6
      test/rlp.cpp
  96. 2
      test/trie.cpp
  97. 9
      test/vm.cpp
  98. 6
      walleth/MainWin.cpp
  99. 2
      walleth/MainWin.h

4
CMakeLists.txt

@ -255,9 +255,13 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
add_subdirectory(secp256k1)
add_subdirectory(libethsupport)
add_subdirectory(libethcore)
add_subdirectory(liblll)
add_subdirectory(libevm)
add_subdirectory(libethereum)
add_subdirectory(test)
add_subdirectory(lllc)
add_subdirectory(eth)
if (NOT ("${TARGET_PLATFORM}" STREQUAL "w64"))
add_subdirectory(neth)

13
alethzero/MainWin.cpp

@ -13,12 +13,14 @@
#include <QtWebKitWidgets/QWebFrame>
#include <QtGui/QClipboard>
#include <QtCore/QtCore>
#include <libethereum/Dagger.h>
#include <libethcore/Dagger.h>
#include <liblll/Compiler.h>
#include <liblll/CodeFragment.h>
#include <libevm/VM.h>
#include <libethereum/BlockChain.h>
#include <libethereum/ExtVM.h>
#include <libethereum/Client.h>
#include <libethereum/Instruction.h>
#include <libethereum/PeerServer.h>
#include <libethereum/VM.h>
#include <libethereum/ExtVM.h>
#include "BuildInfo.h"
#include "MainWin.h"
#include "ui_Main.h"
@ -37,6 +39,7 @@ using eth::Client;
using eth::Instruction;
using eth::KeyPair;
using eth::NodeMode;
using eth::BlockChain;
using eth::PeerInfo;
using eth::RLP;
using eth::Secret;
@ -197,7 +200,7 @@ Main::Main(QWidget *parent) :
}
#endif
cerr << "State root: " << BlockInfo::genesis().stateRoot << endl << "Block Hash: " << sha3(BlockInfo::createGenesisBlock()) << endl << "Block RLP: " << RLP(BlockInfo::createGenesisBlock()) << endl << "Block Hex: " << toHex(BlockInfo::createGenesisBlock()) << endl;
cerr << "State root: " << BlockChain::genesis().stateRoot << endl << "Block Hash: " << sha3(BlockChain::createGenesisBlock()) << endl << "Block RLP: " << RLP(BlockChain::createGenesisBlock()) << endl << "Block Hex: " << toHex(BlockChain::createGenesisBlock()) << endl;
cerr << "Network protocol version: " << eth::c_protocolVersion << endl;
ui->configDock->close();

4
alethzero/MainWin.h

@ -6,8 +6,8 @@
#include <QtCore/QAbstractListModel>
#include <QtCore/QMutex>
#include <QtWidgets/QMainWindow>
#include <libethcore/RLP.h>
#include <libethereum/CommonEth.h>
#include <libethsupport/RLP.h>
#include <libethcore/CommonEth.h>
#include <libethereum/State.h>
#include <libqethereum/QEthereum.h>

10
eth/CommonJS.h

@ -23,11 +23,11 @@
#pragma once
#include <string>
#include <libethcore/Common.h>
#include <libethcore/CommonIO.h>
#include <libethcore/CommonData.h>
#include <libethcore/FixedHash.h>
#include <libethereum/CommonEth.h>
#include <libethsupport/Common.h>
#include <libethsupport/CommonIO.h>
#include <libethsupport/CommonData.h>
#include <libethsupport/FixedHash.h>
#include <libethcore/CommonEth.h>
namespace eth
{

3
eth/EthStubServer.cpp

@ -22,8 +22,9 @@
#if ETH_JSONRPC
#include "EthStubServer.h"
#include <libethcore/Instruction.h>
#include <liblll/Compiler.h>
#include <libethereum/Client.h>
#include <libethereum/Instruction.h>
#include "CommonJS.h"
using namespace std;
using namespace eth;

4
eth/main.cpp

@ -24,13 +24,13 @@
#include <chrono>
#include <fstream>
#include <iostream>
#include <libethcore/FileSystem.h>
#include <libethsupport/FileSystem.h>
#include <libethcore/Instruction.h>
#include <libethereum/Defaults.h>
#include <libethereum/Client.h>
#include <libethereum/PeerNetwork.h>
#include <libethereum/BlockChain.h>
#include <libethereum/State.h>
#include <libethereum/Instruction.h>
#if ETH_READLINE
#include <readline/readline.h>
#include <readline/history.h>

36
libethereum/BlockInfo.cpp → libethcore/BlockInfo.cpp

@ -19,17 +19,16 @@
* @date 2014
*/
#include <libethcore/Common.h>
#include <libethcore/RLP.h>
#include <libethcore/TrieDB.h>
#include <libethsupport/Common.h>
#include <libethsupport/RLP.h>
#include <libethsupport/TrieDB.h>
#include "Dagger.h"
#include "Exceptions.h"
#include "State.h"
#include "BlockInfo.h"
using namespace std;
using namespace eth;
BlockInfo* BlockInfo::s_genesis = nullptr;
u256 eth::c_genesisDifficulty = (u256)1 << 22;
BlockInfo::BlockInfo(): timestamp(Invalid256)
{
@ -47,27 +46,6 @@ BlockInfo BlockInfo::fromHeader(bytesConstRef _block)
return ret;
}
bytes BlockInfo::createGenesisBlock()
{
RLPStream block(3);
auto sha3EmptyList = sha3(RLPEmptyList);
h256 stateRoot;
{
BasicMap db;
TrieDB<Address, BasicMap> state(&db);
state.init();
eth::commit(genesisState(), db, state);
stateRoot = state.root();
}
block.appendList(13) << h256() << sha3EmptyList << h160();
block.append(stateRoot, false, true) << bytes() << c_genesisDifficulty << 0 << 0 << 1000000 << 0 << (uint)0 << string() << sha3(bytes(1, 42));
block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList);
return block.out();
}
h256 BlockInfo::headerHashWithoutNonce() const
{
RLPStream s;
@ -84,12 +62,6 @@ void BlockInfo::fillStream(RLPStream& _s, bool _nonce) const
_s << nonce;
}
void BlockInfo::populateGenesis()
{
bytes genesisBlock = createGenesisBlock();
populate(&genesisBlock);
}
void BlockInfo::populateFromHeader(RLP const& _header, bool _checkNonce)
{
int field = 0;

15
libethereum/BlockInfo.h → libethcore/BlockInfo.h

@ -21,12 +21,15 @@
#pragma once
#include <libethcore/Common.h>
#include "Transaction.h"
#include <libethsupport/Common.h>
#include <libethsupport/RLP.h>
#include "CommonEth.h"
namespace eth
{
extern u256 c_genesisDifficulty;
/** @brief Encapsulation of a block header.
* Class to contain all of a block header's data. It is able to parse a block header and populate
* from some given RLP block serialisation with the static fromHeader(), through the method
@ -103,14 +106,6 @@ public:
/// No-nonce sha3 of the header only.
h256 headerHashWithoutNonce() const;
void fillStream(RLPStream& _s, bool _nonce) const;
static BlockInfo const& genesis() { if (!s_genesis) (s_genesis = new BlockInfo)->populateGenesis(); return *s_genesis; }
static bytes createGenesisBlock();
private:
void populateGenesis();
static BlockInfo* s_genesis;
};
inline std::ostream& operator<<(std::ostream& _out, BlockInfo const& _bi)

1
libethcore/CMakeLists.txt

@ -21,6 +21,7 @@ include_directories(..)
include_directories(${MINIUPNPC_ID})
include_directories(${LEVELDB_ID})
target_link_libraries(${EXECUTABLE} ethsupport)
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})

0
libethereum/CommonEth.cpp → libethcore/CommonEth.cpp

4
libethereum/CommonEth.h → libethcore/CommonEth.h

@ -23,8 +23,8 @@
#pragma once
#include <libethcore/Common.h>
#include <libethcore/FixedHash.h>
#include <libethsupport/Common.h>
#include <libethsupport/FixedHash.h>
namespace eth
{

36
libethcore/CryptoHeaders.h

@ -1,36 +0,0 @@
/*
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 CryptoHeaders.h
* @author Tim Hughes <tim@twistedfury.com>
* @date 2014
*/
#pragma once
// need to leave this one disabled
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma warning(push)
#pragma warning(disable:4100 4244)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <sha.h>
#include <sha3.h>
#include <ripemd.h>
#include <secp256k1/secp256k1.h>
#pragma warning(pop)
#pragma GCC diagnostic pop

4
libethereum/Dagger.cpp → libethcore/Dagger.cpp

@ -23,8 +23,8 @@
#include <chrono>
#include <array>
#include <random>
#include <libethcore/CryptoHeaders.h>
#include <libethcore/Common.h>
#include <libethsupport/CryptoHeaders.h>
#include <libethsupport/Common.h>
#include "Dagger.h"
using namespace std;
using namespace std::chrono;

0
libethereum/Dagger.h → libethcore/Dagger.h

49
libethcore/Exceptions.h

@ -1,27 +1,40 @@
#pragma once
#include <exception>
#include "CommonIO.h"
#include "CommonData.h"
#include "FixedHash.h"
#include <libethsupport/Exceptions.h>
namespace eth
{
class Exception: public std::exception
{
public:
virtual std::string description() const { return typeid(*this).name(); }
virtual char const* what() const noexcept { return typeid(*this).name(); }
};
class BadHexCharacter: public Exception {};
class NotEnoughCash: public Exception {};
class RLPException: public Exception {};
class BadCast: public RLPException {};
class BadRLP: public RLPException {};
class NoNetworking: public Exception {};
class NoUPnPDevice: public Exception {};
class RootNotFound: public Exception {};
class GasPriceTooLow: public Exception {};
class BlockGasLimitReached: public Exception {};
class NoSuchContract: public Exception {};
class ContractAddressCollision: public Exception {};
class FeeTooSmall: public Exception {};
class TooMuchGasUsed: public Exception {};
class ExtraDataTooBig: public Exception {};
class InvalidSignature: public Exception {};
class InvalidTransactionFormat: public Exception { public: InvalidTransactionFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid transaction format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } };
class InvalidBlockFormat: public Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } };
class InvalidBlockHeaderFormat: public Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } };
class InvalidUnclesHash: public Exception {};
class InvalidUncle: public Exception {};
class UncleNotAnUncle: public Exception {};
class DuplicateUncleNonce: public Exception {};
class InvalidStateRoot: public Exception {};
class InvalidTransactionsHash: public Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual std::string description() const { return "Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref()); } };
class InvalidTransaction: public Exception {};
class InvalidDifficulty: public Exception {};
class InvalidGasLimit: public Exception {};
class InvalidMinGasPrice: public Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual std::string description() const { return "Invalid minimum gas price (provided: " + toString(provided) + " limit:" + toString(limit) + ")"; } };
class InvalidTransactionGasUsed: public Exception {};
class InvalidTransactionStateRoot: public Exception {};
class InvalidTimestamp: public Exception {};
class InvalidNonce: public Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0): required(_required), candidate(_candidate) {} u256 required; u256 candidate; virtual std::string description() const { return "Invalid nonce (r: " + toString(required) + " c:" + toString(candidate) + ")"; } };
class InvalidBlockNonce: public Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0): h(_h), n(_n), d(_d) {} h256 h; h256 n; u256 d; virtual std::string description() const { return "Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")"; } };
class InvalidParentHash: public Exception {};
class InvalidNumber: public Exception {};
class InvalidContractAddress: public Exception {};
}

232
libethcore/Instruction.cpp

@ -0,0 +1,232 @@
/*
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 Instruction.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Instruction.h"
#include "CommonEth.h"
using namespace std;
using namespace eth;
const std::map<std::string, Instruction> eth::c_instructions =
{
{ "STOP", Instruction::STOP },
{ "ADD", Instruction::ADD },
{ "SUB", Instruction::SUB },
{ "MUL", Instruction::MUL },
{ "DIV", Instruction::DIV },
{ "SDIV", Instruction::SDIV },
{ "MOD", Instruction::MOD },
{ "SMOD", Instruction::SMOD },
{ "EXP", Instruction::EXP },
{ "NEG", Instruction::NEG },
{ "LT", Instruction::LT },
{ "GT", Instruction::GT },
{ "SLT", Instruction::SLT },
{ "SGT", Instruction::SGT },
{ "EQ", Instruction::EQ },
{ "NOT", Instruction::NOT },
{ "AND", Instruction::AND },
{ "OR", Instruction::OR },
{ "XOR", Instruction::XOR },
{ "BYTE", Instruction::BYTE },
{ "SHA3", Instruction::SHA3 },
{ "ADDRESS", Instruction::ADDRESS },
{ "BALANCE", Instruction::BALANCE },
{ "ORIGIN", Instruction::ORIGIN },
{ "CALLER", Instruction::CALLER },
{ "CALLVALUE", Instruction::CALLVALUE },
{ "CALLDATALOAD", Instruction::CALLDATALOAD },
{ "CALLDATASIZE", Instruction::CALLDATASIZE },
{ "CALLDATACOPY", Instruction::CALLDATACOPY },
{ "CODESIZE", Instruction::CODESIZE },
{ "CODECOPY", Instruction::CODECOPY },
{ "GASPRICE", Instruction::GASPRICE },
{ "PREVHASH", Instruction::PREVHASH },
{ "COINBASE", Instruction::COINBASE },
{ "TIMESTAMP", Instruction::TIMESTAMP },
{ "NUMBER", Instruction::NUMBER },
{ "DIFFICULTY", Instruction::DIFFICULTY },
{ "GASLIMIT", Instruction::GASLIMIT },
{ "POP", Instruction::POP },
{ "DUP", Instruction::DUP },
{ "SWAP", Instruction::SWAP },
{ "MLOAD", Instruction::MLOAD },
{ "MSTORE", Instruction::MSTORE },
{ "MSTORE8", Instruction::MSTORE8 },
{ "SLOAD", Instruction::SLOAD },
{ "SSTORE", Instruction::SSTORE },
{ "JUMP", Instruction::JUMP },
{ "JUMPI", Instruction::JUMPI },
{ "PC", Instruction::PC },
{ "MEMSIZE", Instruction::MEMSIZE },
{ "GAS", Instruction::GAS },
{ "PUSH1", Instruction::PUSH1 },
{ "PUSH2", Instruction::PUSH2 },
{ "PUSH3", Instruction::PUSH3 },
{ "PUSH4", Instruction::PUSH4 },
{ "PUSH5", Instruction::PUSH5 },
{ "PUSH6", Instruction::PUSH6 },
{ "PUSH7", Instruction::PUSH7 },
{ "PUSH8", Instruction::PUSH8 },
{ "PUSH9", Instruction::PUSH9 },
{ "PUSH10", Instruction::PUSH10 },
{ "PUSH11", Instruction::PUSH11 },
{ "PUSH12", Instruction::PUSH12 },
{ "PUSH13", Instruction::PUSH13 },
{ "PUSH14", Instruction::PUSH14 },
{ "PUSH15", Instruction::PUSH15 },
{ "PUSH16", Instruction::PUSH16 },
{ "PUSH17", Instruction::PUSH17 },
{ "PUSH18", Instruction::PUSH18 },
{ "PUSH19", Instruction::PUSH19 },
{ "PUSH20", Instruction::PUSH20 },
{ "PUSH21", Instruction::PUSH21 },
{ "PUSH22", Instruction::PUSH22 },
{ "PUSH23", Instruction::PUSH23 },
{ "PUSH24", Instruction::PUSH24 },
{ "PUSH25", Instruction::PUSH25 },
{ "PUSH26", Instruction::PUSH26 },
{ "PUSH27", Instruction::PUSH27 },
{ "PUSH28", Instruction::PUSH28 },
{ "PUSH29", Instruction::PUSH29 },
{ "PUSH30", Instruction::PUSH30 },
{ "PUSH31", Instruction::PUSH31 },
{ "PUSH32", Instruction::PUSH32 },
{ "CREATE", Instruction::CREATE },
{ "CALL", Instruction::CALL },
{ "RETURN", Instruction::RETURN },
{ "SUICIDE", Instruction::SUICIDE }
};
const std::map<Instruction, InstructionInfo> eth::c_instructionInfo =
{ // Add, Args, Ret
{ Instruction::STOP, { "STOP", 0, 0, 0 } },
{ Instruction::ADD, { "ADD", 0, 2, 1 } },
{ Instruction::SUB, { "SUB", 0, 2, 1 } },
{ Instruction::MUL, { "MUL", 0, 2, 1 } },
{ Instruction::DIV, { "DIV", 0, 2, 1 } },
{ Instruction::SDIV, { "SDIV", 0, 2, 1 } },
{ Instruction::MOD, { "MOD", 0, 2, 1 } },
{ Instruction::SMOD, { "SMOD", 0, 2, 1 } },
{ Instruction::EXP, { "EXP", 0, 2, 1 } },
{ Instruction::NEG, { "NEG", 0, 1, 1 } },
{ Instruction::LT, { "LT", 0, 2, 1 } },
{ Instruction::GT, { "GT", 0, 2, 1 } },
{ Instruction::SLT, { "SLT", 0, 2, 1 } },
{ Instruction::SGT, { "SGT", 0, 2, 1 } },
{ Instruction::EQ, { "EQ", 0, 2, 1 } },
{ Instruction::NOT, { "NOT", 0, 1, 1 } },
{ Instruction::AND, { "AND", 0, 2, 1 } },
{ Instruction::OR, { "OR", 0, 2, 1 } },
{ Instruction::XOR, { "XOR", 0, 2, 1 } },
{ Instruction::BYTE, { "BYTE", 0, 2, 1 } },
{ Instruction::SHA3, { "SHA3", 0, 2, 1 } },
{ Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } },
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1 } },
{ Instruction::ORIGIN, { "ORIGIN", 0, 0, 1 } },
{ Instruction::CALLER, { "CALLER", 0, 0, 1 } },
{ Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1 } },
{ Instruction::CALLDATALOAD, { "CALLDATALOAD", 0, 1, 1 } },
{ Instruction::CALLDATASIZE, { "CALLDATASIZE", 0, 0, 1 } },
{ Instruction::CALLDATACOPY, { "CALLDATACOPY", 0, 3, 0 } },
{ Instruction::CODESIZE, { "CODESIZE", 0, 0, 1 } },
{ Instruction::CODECOPY, { "CODECOPY", 0, 3, 0 } },
{ Instruction::GASPRICE, { "GASPRICE", 0, 0, 1 } },
{ Instruction::PREVHASH, { "PREVHASH", 0, 0, 1 } },
{ Instruction::COINBASE, { "COINBASE", 0, 0, 1 } },
{ Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1 } },
{ Instruction::NUMBER, { "NUMBER", 0, 0, 1 } },
{ Instruction::DIFFICULTY, { "DIFFICULTY", 0, 0, 1 } },
{ Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1 } },
{ Instruction::POP, { "POP", 0, 1, 0 } },
{ Instruction::DUP, { "DUP", 0, 1, 2 } },
{ Instruction::SWAP, { "SWAP", 0, 2, 2 } },
{ Instruction::MLOAD, { "MLOAD", 0, 1, 1 } },
{ Instruction::MSTORE, { "MSTORE", 0, 2, 0 } },
{ Instruction::MSTORE8, { "MSTORE8", 0, 2, 0 } },
{ Instruction::SLOAD, { "SLOAD", 0, 1, 1 } },
{ Instruction::SSTORE, { "SSTORE", 0, 2, 0 } },
{ Instruction::JUMP, { "JUMP", 0, 1, 0 } },
{ Instruction::JUMPI, { "JUMPI", 0, 2, 0 } },
{ Instruction::PC, { "PC", 0, 0, 1 } },
{ Instruction::MEMSIZE, { "MEMSIZE", 0, 0, 1 } },
{ Instruction::GAS, { "GAS", 0, 0, 1 } },
{ Instruction::PUSH1, { "PUSH1", 1, 0, 1 } },
{ Instruction::PUSH2, { "PUSH2", 2, 0, 1 } },
{ Instruction::PUSH3, { "PUSH3", 3, 0, 1 } },
{ Instruction::PUSH4, { "PUSH4", 4, 0, 1 } },
{ Instruction::PUSH5, { "PUSH5", 5, 0, 1 } },
{ Instruction::PUSH6, { "PUSH6", 6, 0, 1 } },
{ Instruction::PUSH7, { "PUSH7", 7, 0, 1 } },
{ Instruction::PUSH8, { "PUSH8", 8, 0, 1 } },
{ Instruction::PUSH9, { "PUSH9", 9, 0, 1 } },
{ Instruction::PUSH10, { "PUSH10", 10, 0, 1 } },
{ Instruction::PUSH11, { "PUSH11", 11, 0, 1 } },
{ Instruction::PUSH12, { "PUSH12", 12, 0, 1 } },
{ Instruction::PUSH13, { "PUSH13", 13, 0, 1 } },
{ Instruction::PUSH14, { "PUSH14", 14, 0, 1 } },
{ Instruction::PUSH15, { "PUSH15", 15, 0, 1 } },
{ Instruction::PUSH16, { "PUSH16", 16, 0, 1 } },
{ Instruction::PUSH17, { "PUSH17", 17, 0, 1 } },
{ Instruction::PUSH18, { "PUSH18", 18, 0, 1 } },
{ Instruction::PUSH19, { "PUSH19", 19, 0, 1 } },
{ Instruction::PUSH20, { "PUSH20", 20, 0, 1 } },
{ Instruction::PUSH21, { "PUSH21", 21, 0, 1 } },
{ Instruction::PUSH22, { "PUSH22", 22, 0, 1 } },
{ Instruction::PUSH23, { "PUSH23", 23, 0, 1 } },
{ Instruction::PUSH24, { "PUSH24", 24, 0, 1 } },
{ Instruction::PUSH25, { "PUSH25", 25, 0, 1 } },
{ Instruction::PUSH26, { "PUSH26", 26, 0, 1 } },
{ Instruction::PUSH27, { "PUSH27", 27, 0, 1 } },
{ Instruction::PUSH28, { "PUSH28", 28, 0, 1 } },
{ Instruction::PUSH29, { "PUSH29", 29, 0, 1 } },
{ Instruction::PUSH30, { "PUSH30", 30, 0, 1 } },
{ Instruction::PUSH31, { "PUSH31", 31, 0, 1 } },
{ Instruction::PUSH32, { "PUSH32", 32, 0, 1 } },
{ Instruction::CREATE, { "CREATE", 0, 3, 1 } },
{ Instruction::CALL, { "CALL", 0, 7, 1 } },
{ Instruction::RETURN, { "RETURN", 0, 2, 0 } },
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} }
};
string eth::disassemble(bytes const& _mem)
{
stringstream ret;
uint numerics = 0;
for (auto it = _mem.begin(); it != _mem.end(); ++it)
{
byte n = *it;
auto iit = c_instructionInfo.find((Instruction)n);
if (numerics || iit == c_instructionInfo.end() || (byte)iit->first != n) // not an instruction or expecting an argument...
{
if (numerics)
numerics--;
ret << "0x" << hex << (int)n << " ";
}
else
{
auto const& ii = iit->second;
ret << ii.name << " ";
numerics = ii.additional;
}
}
return ret.str();
}

152
libethcore/Instruction.h

@ -0,0 +1,152 @@
/*
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 Instruction.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <libethsupport/Common.h>
#include "Exceptions.h"
namespace boost { namespace spirit { class utree; } }
namespace sp = boost::spirit;
namespace eth
{
// TODO: Update comments.
/// Virtual machine bytecode instruction.
enum class Instruction: uint8_t
{
STOP = 0x00, ///< halts execution
ADD,
MUL,
SUB,
DIV,
SDIV,
MOD,
SMOD,
EXP,
NEG,
LT,
GT,
SLT,
SGT,
EQ,
NOT,
AND = 0x10,
OR,
XOR,
BYTE,
SHA3 = 0x20,
ADDRESS = 0x30,
BALANCE,
ORIGIN,
CALLER,
CALLVALUE,
CALLDATALOAD,
CALLDATASIZE,
CALLDATACOPY,
CODESIZE,
CODECOPY,
GASPRICE,
PREVHASH = 0x40,
COINBASE,
TIMESTAMP,
NUMBER,
DIFFICULTY,
GASLIMIT,
POP = 0x50,
DUP,
SWAP,
MLOAD,
MSTORE,
MSTORE8,
SLOAD,
SSTORE,
JUMP,
JUMPI,
PC,
MEMSIZE,
GAS,
PUSH1 = 0x60,
PUSH2,
PUSH3,
PUSH4,
PUSH5,
PUSH6,
PUSH7,
PUSH8,
PUSH9,
PUSH10,
PUSH11,
PUSH12,
PUSH13,
PUSH14,
PUSH15,
PUSH16,
PUSH17,
PUSH18,
PUSH19,
PUSH20,
PUSH21,
PUSH22,
PUSH23,
PUSH24,
PUSH25,
PUSH26,
PUSH27,
PUSH28,
PUSH29,
PUSH30,
PUSH31,
PUSH32,
CREATE = 0xf0,
CALL,
RETURN,
SUICIDE = 0xff
};
/// Information structure for a particular instruction.
struct InstructionInfo
{
char const* name; ///< The name of the instruction.
int additional; ///< Additional items required in memory for this instructions (only for PUSH).
int args; ///< Number of items required on the stack for this instruction (and, for the purposes of ret, the number taken from the stack).
int ret; ///< Number of items placed (back) on the stack by this instruction, assuming args items were removed.
};
/// Information on all the instructions.
extern const std::map<Instruction, InstructionInfo> c_instructionInfo;
/// Convert from string mnemonic to Instruction type.
extern const std::map<std::string, Instruction> c_instructions;
/// Convert from EVM code to simple EVM assembly language.
std::string disassemble(bytes const& _mem);
}

73
libethcore/vector_ref.h

@ -1,73 +0,0 @@
#pragma once
#include <type_traits>
#include <cassert>
#include <vector>
#include <string>
#pragma warning(push)
#pragma warning(disable: 4100 4267)
#include <leveldb/db.h>
#pragma warning(pop)
namespace eth
{
template <class _T>
class vector_ref
{
public:
typedef _T value_type;
typedef _T element_type;
typedef typename std::conditional<std::is_const<_T>::value, typename std::remove_const<_T>::type, _T>::type mutable_value_type;
vector_ref(): m_data(nullptr), m_count(0) {}
vector_ref(_T* _data, size_t _count): m_data(_data), m_count(_count) {}
vector_ref(std::string* _data): m_data((_T*)_data->data()), m_count(_data->size() / sizeof(_T)) {}
vector_ref(typename std::conditional<std::is_const<_T>::value, std::vector<typename std::remove_const<_T>::type> const*, std::vector<_T>*>::type _data): m_data(_data->data()), m_count(_data->size()) {}
vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const&, std::string&>::type _data): m_data((_T*)_data.data()), m_count(_data.size() / sizeof(_T)) {}
vector_ref(leveldb::Slice const& _s): m_data(_s.data()), m_count(_s.size() / sizeof(_T)) {}
explicit operator bool() const { return m_data && m_count; }
bool contentsEqual(std::vector<mutable_value_type> const& _c) const { return _c.size() == m_count && !memcmp(_c.data(), m_data, m_count); }
std::vector<mutable_value_type> toVector() const { return std::vector<mutable_value_type>(m_data, m_data + m_count); }
std::vector<unsigned char> toBytes() const { return std::vector<unsigned char>((unsigned char const*)m_data, m_data + m_count * sizeof(_T)); }
std::string toString() const { return std::string((char const*)m_data, ((char const*)m_data) + m_count); }
template <class _T2> operator vector_ref<_T2>() const { assert(m_count * sizeof(_T) / sizeof(_T2) * sizeof(_T2) / sizeof(_T) == m_count); return vector_ref<_T2>((_T2*)m_data, m_count * sizeof(_T) / sizeof(_T2)); }
_T* data() const { return m_data; }
size_t count() const { return m_count; }
size_t size() const { return m_count; }
bool empty() const { return !m_count; }
vector_ref<_T> next() const { return vector_ref<_T>(m_data + m_count, m_count); }
vector_ref<_T> cropped(size_t _begin, size_t _count = ~size_t(0)) const { if (m_data && _begin + std::max(size_t(0), _count) <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); }
void retarget(_T const* _d, size_t _s) { m_data = _d; m_count = _s; }
void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); }
_T* begin() { return m_data; }
_T* end() { return m_data + m_count; }
_T const* begin() const { return m_data; }
_T const* end() const { return m_data + m_count; }
_T& operator[](size_t _i) { assert(m_data); assert(_i < m_count); return m_data[_i]; }
_T const& operator[](size_t _i) const { assert(m_data); assert(_i < m_count); return m_data[_i]; }
bool operator==(vector_ref<_T> const& _cmp) const { return m_data == _cmp.m_data && m_count == _cmp.m_count; }
bool operator!=(vector_ref<_T> const& _cmp) const { return !operator==(); }
operator leveldb::Slice() const { return leveldb::Slice((char const*)m_data, m_count * sizeof(_T)); }
void reset() { m_data = nullptr; m_count = 0; }
private:
_T* m_data;
size_t m_count;
};
template<class _T> vector_ref<_T const> ref(_T const& _t) { return vector_ref<_T const>(&_t, 1); }
template<class _T> vector_ref<_T> ref(_T& _t) { return vector_ref<_T>(&_t, 1); }
template<class _T> vector_ref<_T const> ref(std::vector<_T> const& _t) { return vector_ref<_T const>(&_t); }
template<class _T> vector_ref<_T> ref(std::vector<_T>& _t) { return vector_ref<_T>(&_t); }
}

2
libethereum/AddressState.cpp

@ -20,7 +20,7 @@
*/
#include "AddressState.h"
#include "CommonEth.h"
#include <libethcore/CommonEth.h>
using namespace std;
using namespace eth;

4
libethereum/AddressState.h

@ -21,8 +21,8 @@
#pragma once
#include <libethcore/Common.h>
#include <libethcore/RLP.h>
#include <libethsupport/Common.h>
#include <libethsupport/RLP.h>
namespace eth
{

61
libethereum/BlockChain.cpp

@ -22,12 +22,12 @@
#include "BlockChain.h"
#include <boost/filesystem.hpp>
#include <libethcore/Common.h>
#include <libethcore/RLP.h>
#include <libethcore/FileSystem.h>
#include "Exceptions.h"
#include "Dagger.h"
#include "BlockInfo.h"
#include <libethsupport/Common.h>
#include <libethsupport/RLP.h>
#include <libethsupport/FileSystem.h>
#include <libethcore/Exceptions.h>
#include <libethcore/Dagger.h>
#include <libethcore/BlockInfo.h>
#include "State.h"
#include "Defaults.h"
using namespace std;
@ -66,6 +66,51 @@ bytes BlockDetails::rlp() const
return rlpList(number, totalDifficulty, parent, children);
}
std::map<Address, AddressState> const& eth::genesisState()
{
static std::map<Address, AddressState> s_ret;
if (s_ret.empty())
{
// Initialise.
for (auto i: vector<string>({
"8a40bfaa73256b60764c1bf40675a99083efb075",
"e6716f9544a56c530d868e4bfbacb172315bdead",
"1e12515ce3e0f817a4ddef9ca55788a1d66bd2df",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"6c386a4b26f73c802f34673f7248bb118f97424a",
"e4157b34ea9615cfbde6b4fda419828124b70c78"
}))
s_ret[Address(fromHex(i))] = AddressState(u256(1) << 200, 0, h256(), EmptySHA3);
}
return s_ret;
}
BlockInfo* BlockChain::s_genesis = nullptr;
bytes BlockChain::createGenesisBlock()
{
RLPStream block(3);
auto sha3EmptyList = sha3(RLPEmptyList);
h256 stateRoot;
{
BasicMap db;
TrieDB<Address, BasicMap> state(&db);
state.init();
eth::commit(genesisState(), db, state);
stateRoot = state.root();
}
block.appendList(13) << h256() << sha3EmptyList << h160();
block.append(stateRoot, false, true) << bytes() << c_genesisDifficulty << 0 << 0 << 1000000 << 0 << (uint)0 << string() << sha3(bytes(1, 42));
block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList);
return block.out();
}
BlockChain::BlockChain(std::string _path, bool _killExisting)
{
if (_path.empty())
@ -85,8 +130,8 @@ BlockChain::BlockChain(std::string _path, bool _killExisting)
assert(m_detailsDB);
// Initialise with the genesis as the last block on the longest chain.
m_genesisHash = BlockInfo::genesis().hash;
m_genesisBlock = BlockInfo::createGenesisBlock();
m_genesisHash = BlockChain::genesis().hash;
m_genesisBlock = BlockChain::createGenesisBlock();
if (!details(m_genesisHash))
{

13
libethereum/BlockChain.h

@ -22,8 +22,9 @@
#pragma once
#include <mutex>
#include <libethcore/Log.h>
#include "CommonEth.h"
#include <libethsupport/Log.h>
#include <libethcore/CommonEth.h>
#include <libethcore/BlockInfo.h>
#include "AddressState.h"
namespace ldb = leveldb;
@ -63,6 +64,9 @@ class FutureTime: public std::exception {};
struct BlockChainChat: public LogChannel { static const char* name() { return "-B-"; } static const int verbosity = 7; };
struct BlockChainNote: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 4; };
// TODO: Move all this Genesis stuff into Genesis.h/.cpp
std::map<Address, AddressState> const& genesisState();
/**
* @brief Implements the blockchain database. All data this gives is disk-backed.
*/
@ -104,6 +108,9 @@ public:
void pushInterest(Address _a) { m_interest[_a]++; }
void popInterest(Address _a) { if (m_interest[_a] > 1) m_interest[_a]--; else if (m_interest[_a]) m_interest.erase(_a); }
static BlockInfo const& genesis() { if (!s_genesis) { auto gb = createGenesisBlock(); (s_genesis = new BlockInfo)->populate(&gb); } return *s_genesis; }
static bytes createGenesisBlock();
private:
void checkConsistency();
@ -128,6 +135,8 @@ private:
ldb::WriteOptions m_writeOptions;
friend std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc);
static BlockInfo* s_genesis;
};
std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc);

3
libethereum/CMakeLists.txt

@ -20,7 +20,10 @@ file(GLOB HEADERS "*.h")
include_directories(..)
include_directories(${LEVELDB_ID})
target_link_libraries(${EXECUTABLE} evm)
target_link_libraries(${EXECUTABLE} lll)
target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} ethsupport)
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})

2
libethereum/Client.cpp

@ -24,7 +24,7 @@
#include <chrono>
#include <thread>
#include <boost/filesystem.hpp>
#include <libethcore/Common.h>
#include <libethsupport/Common.h>
#include "Defaults.h"
#include "PeerServer.h"
using namespace std;

4
libethereum/Client.h

@ -24,11 +24,11 @@
#include <thread>
#include <mutex>
#include <atomic>
#include <libethcore/Common.h>
#include <libethsupport/Common.h>
#include <libethcore/Dagger.h>
#include "BlockChain.h"
#include "TransactionQueue.h"
#include "State.h"
#include "Dagger.h"
#include "PeerNetwork.h"
namespace eth

2
libethereum/Defaults.cpp

@ -21,7 +21,7 @@
#include "Defaults.h"
#include <libethcore/FileSystem.h>
#include <libethsupport/FileSystem.h>
using namespace std;
using namespace eth;

2
libethereum/Defaults.h

@ -21,7 +21,7 @@
#pragma once
#include <libethcore/Common.h>
#include <libethsupport/Common.h>
namespace eth
{

48
libethereum/Exceptions.h

@ -1,48 +0,0 @@
#pragma once
#include <libethcore/Exceptions.h>
namespace eth
{
class VMException: public Exception {};
class StepsDone: public VMException {};
class BreakPointHit: public VMException {};
class BadInstruction: public VMException {};
class OutOfGas: public VMException {};
class StackTooSmall: public VMException { public: StackTooSmall(u256 _req, u256 _got): req(_req), got(_got) {} u256 req; u256 got; };
class OperandOutOfRange: public VMException { public: OperandOutOfRange(u256 _min, u256 _max, u256 _got): mn(_min), mx(_max), got(_got) {} u256 mn; u256 mx; u256 got; };
class NotEnoughCash: public Exception {};
class GasPriceTooLow: public Exception {};
class BlockGasLimitReached: public Exception {};
class NoSuchContract: public Exception {};
class ContractAddressCollision: public Exception {};
class FeeTooSmall: public Exception {};
class TooMuchGasUsed: public Exception {};
class ExtraDataTooBig: public Exception {};
class InvalidSignature: public Exception {};
class InvalidTransactionFormat: public Exception { public: InvalidTransactionFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid transaction format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } };
class InvalidBlockFormat: public Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } };
class InvalidBlockHeaderFormat: public Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } };
class InvalidUnclesHash: public Exception {};
class InvalidUncle: public Exception {};
class UncleNotAnUncle: public Exception {};
class DuplicateUncleNonce: public Exception {};
class InvalidStateRoot: public Exception {};
class InvalidTransactionsHash: public Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual std::string description() const { return "Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref()); } };
class InvalidTransaction: public Exception {};
class InvalidDifficulty: public Exception {};
class InvalidGasLimit: public Exception {};
class InvalidMinGasPrice: public Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual std::string description() const { return "Invalid minimum gas price (provided: " + toString(provided) + " limit:" + toString(limit) + ")"; } };
class InvalidTransactionGasUsed: public Exception {};
class InvalidTransactionStateRoot: public Exception {};
class InvalidTimestamp: public Exception {};
class InvalidNonce: public Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0): required(_required), candidate(_candidate) {} u256 required; u256 candidate; virtual std::string description() const { return "Invalid nonce (r: " + toString(required) + " c:" + toString(candidate) + ")"; } };
class InvalidBlockNonce: public Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0): h(_h), n(_n), d(_d) {} h256 h; h256 n; u256 d; virtual std::string description() const { return "Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")"; } };
class InvalidParentHash: public Exception {};
class InvalidNumber: public Exception {};
class InvalidContractAddress: public Exception {};
}

2
libethereum/Executive.cpp

@ -19,10 +19,10 @@
* @date 2014
*/
#include <libevm/VM.h>
#include "Executive.h"
#include "State.h"
#include "ExtVM.h"
#include "VM.h"
using namespace std;
using namespace eth;

2
libethereum/Executive.h

@ -21,7 +21,7 @@
#pragma once
#include "CommonEth.h"
#include <libethcore/CommonEth.h>
#include "Transaction.h"
namespace eth

4
libethereum/ExtVM.h

@ -22,9 +22,9 @@
#pragma once
#include <map>
#include "CommonEth.h"
#include <libethcore/CommonEth.h>
#include <libevm/ExtVMFace.h>
#include "State.h"
#include "ExtVMFace.h"
namespace eth
{

4
libethereum/PeerNetwork.h

@ -27,8 +27,8 @@
#include <boost/asio.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <chrono>
#include <libethcore/Common.h>
#include <libethcore/Log.h>
#include <libethsupport/Common.h>
#include <libethsupport/Log.h>
namespace ba = boost::asio;
namespace bi = boost::asio::ip;

7
libethereum/PeerServer.cpp

@ -34,11 +34,10 @@
#include <set>
#include <chrono>
#include <thread>
#include <libethcore/Common.h>
#include <libethcore/UPnP.h>
#include "Exceptions.h"
#include <libethsupport/Common.h>
#include <libethsupport/UPnP.h>
#include <libethcore/Exceptions.h>
#include "BlockChain.h"
#include "BlockInfo.h"
#include "TransactionQueue.h"
#include "PeerSession.h"
using namespace std;

2
libethereum/PeerServer.h

@ -27,8 +27,8 @@
#include <memory>
#include <utility>
#include <thread>
#include <libethcore/CommonEth.h>
#include "PeerNetwork.h"
#include "CommonEth.h"
namespace ba = boost::asio;
namespace bi = boost::asio::ip;

5
libethereum/PeerSession.cpp

@ -22,10 +22,9 @@
#include "PeerSession.h"
#include <chrono>
#include <libethcore/Common.h>
#include "Exceptions.h"
#include <libethsupport/Common.h>
#include <libethcore/Exceptions.h>
#include "BlockChain.h"
#include "BlockInfo.h"
#include "PeerServer.h"
using namespace std;
using namespace eth;

4
libethereum/PeerSession.h

@ -25,8 +25,8 @@
#include <set>
#include <memory>
#include <utility>
#include <libethcore/RLP.h>
#include "CommonEth.h"
#include <libethsupport/RLP.h>
#include <libethcore/CommonEth.h>
#include "PeerNetwork.h"
namespace eth

40
libethereum/State.cpp

@ -21,44 +21,20 @@
#include "State.h"
#include <secp256k1/secp256k1.h>
#include <boost/filesystem.hpp>
#include <time.h>
#include <random>
#include <secp256k1/secp256k1.h>
#include <libethcore/Instruction.h>
#include <libethcore/Exceptions.h>
#include <libethcore/Dagger.h>
#include <libevm/VM.h>
#include "BlockChain.h"
#include "Instruction.h"
#include "Exceptions.h"
#include "Dagger.h"
#include "Defaults.h"
#include "ExtVM.h"
#include "VM.h"
using namespace std;
using namespace eth;
u256 eth::c_genesisDifficulty = (u256)1 << 22;
std::map<Address, AddressState> const& eth::genesisState()
{
static std::map<Address, AddressState> s_ret;
if (s_ret.empty())
{
// Initialise.
for (auto i: vector<string>({
"8a40bfaa73256b60764c1bf40675a99083efb075",
"e6716f9544a56c530d868e4bfbacb172315bdead",
"1e12515ce3e0f817a4ddef9ca55788a1d66bd2df",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"6c386a4b26f73c802f34673f7248bb118f97424a",
"e4157b34ea9615cfbde6b4fda419828124b70c78"
}))
s_ret[Address(fromHex(i))] = AddressState(u256(1) << 200, 0, h256(), EmptySHA3);
}
return s_ret;
}
Overlay State::openDB(std::string _path, bool _killExisting)
{
if (_path.empty())
@ -91,7 +67,7 @@ State::State(Address _coinbaseAddress, Overlay const& _db):
eth::commit(genesisState(), m_db, m_state);
m_db.commit();
m_previousBlock = BlockInfo::genesis();
m_previousBlock = BlockChain::genesis();
resetCurrent();
assert(m_state.root() == m_previousBlock.stateRoot);
@ -318,7 +294,7 @@ bool State::sync(BlockChain const& _bc, h256 _block)
// (Most recent state dump might end up being genesis.)
std::vector<h256> chain;
while (bi.stateRoot != BlockInfo::genesis().hash && m_db.lookup(bi.stateRoot).empty()) // while we don't have the state root of the latest block...
while (bi.stateRoot != BlockChain::genesis().hash && m_db.lookup(bi.stateRoot).empty()) // while we don't have the state root of the latest block...
{
chain.push_back(bi.hash); // push back for later replay.
bi.populate(_bc.block(bi.parentHash)); // move to parent.
@ -639,7 +615,7 @@ void State::commitToMine(BlockChain const& _bc)
RLPStream uncles;
Addresses uncleAddresses;
if (m_previousBlock != BlockInfo::genesis())
if (m_previousBlock != BlockChain::genesis())
{
// Find uncles if we're not a direct child of the genesis.
// cout << "Checking " << m_previousBlock.hash << ", parent=" << m_previousBlock.parentHash << endl;

19
libethereum/State.h

@ -24,17 +24,17 @@
#include <array>
#include <map>
#include <unordered_map>
#include <libethcore/Common.h>
#include <libethcore/RLP.h>
#include <libethcore/TrieDB.h>
#include <libethsupport/Common.h>
#include <libethsupport/RLP.h>
#include <libethsupport/TrieDB.h>
#include <libethcore/Exceptions.h>
#include <libethcore/BlockInfo.h>
#include <libethcore/Dagger.h>
#include <libevm/FeeStructure.h>
#include <libevm/ExtVMFace.h>
#include "TransactionQueue.h"
#include "Exceptions.h"
#include "BlockInfo.h"
#include "AddressState.h"
#include "Transaction.h"
#include "FeeStructure.h"
#include "Dagger.h"
#include "ExtVMFace.h"
#include "Executive.h"
namespace eth
@ -42,9 +42,6 @@ namespace eth
class BlockChain;
extern u256 c_genesisDifficulty;
std::map<Address, AddressState> const& genesisState();
struct StateChat: public LogChannel { static const char* name() { return "=S="; } static const int verbosity = 4; };
struct TransactionReceipt

6
libethereum/Transaction.cpp

@ -20,9 +20,9 @@
*/
#include <secp256k1/secp256k1.h>
#include <libethcore/vector_ref.h>
#include <libethcore/Log.h>
#include "Exceptions.h"
#include <libethsupport/vector_ref.h>
#include <libethsupport/Log.h>
#include <libethcore/Exceptions.h>
#include "Transaction.h"
using namespace std;
using namespace eth;

4
libethereum/Transaction.h

@ -21,8 +21,8 @@
#pragma once
#include <libethcore/RLP.h>
#include "CommonEth.h"
#include <libethsupport/RLP.h>
#include <libethcore/CommonEth.h>
namespace eth
{

4
libethereum/TransactionQueue.cpp

@ -21,8 +21,8 @@
#include "TransactionQueue.h"
#include <libethcore/Log.h>
#include "Exceptions.h"
#include <libethsupport/Log.h>
#include <libethcore/Exceptions.h>
#include "Transaction.h"
using namespace std;
using namespace eth;

2
libethereum/TransactionQueue.h

@ -21,7 +21,7 @@
#pragma once
#include <libethcore/Common.h>
#include <libethsupport/Common.h>
#include "Transaction.h"
namespace eth

68
libethsupport/CMakeLists.txt

@ -0,0 +1,68 @@
cmake_policy(SET CMP0015 NEW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
aux_source_directory(. SRC_LIST)
set(EXECUTABLE ethsupport)
if(APPLE)
# set(CMAKE_INSTALL_PREFIX ../lib)
add_library(${EXECUTABLE} SHARED ${SRC_LIST})
else()
add_library(${EXECUTABLE} ${SRC_LIST})
endif()
if (UNIX)
FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale)
endif()
file(GLOB HEADERS "*.h")
include_directories(..)
include_directories(${MINIUPNPC_ID})
include_directories(${LEVELDB_ID})
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
target_link_libraries(${EXECUTABLE} gmp)
if(${TARGET_PLATFORM} STREQUAL "w64")
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp)
target_link_libraries(${EXECUTABLE} cryptopp)
target_link_libraries(${EXECUTABLE} boost_system-mt-s)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
target_link_libraries(${EXECUTABLE} iphlpapi)
target_link_libraries(${EXECUTABLE} ws2_32)
target_link_libraries(${EXECUTABLE} mswsock)
target_link_libraries(${EXECUTABLE} shlwapi)
elseif (APPLE)
# Latest mavericks boost libraries only come with -mt
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} boost_system-mt)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt)
target_link_libraries(${EXECUTABLE} boost_thread-mt)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
elseif (UNIX)
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY})
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
else ()
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} boost_system)
target_link_libraries(${EXECUTABLE} boost_filesystem)
target_link_libraries(${EXECUTABLE} boost_thread)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
endif ()
message("Installation path: ${CMAKE_INSTALL_PREFIX}")
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

0
libethcore/Common.cpp → libethsupport/Common.cpp

0
libethcore/Common.h → libethsupport/Common.h

0
libethcore/CommonData.cpp → libethsupport/CommonData.cpp

0
libethcore/CommonData.h → libethsupport/CommonData.h

0
libethcore/CommonIO.cpp → libethsupport/CommonIO.cpp

0
libethcore/CommonIO.h → libethsupport/CommonIO.h

0
libethcore/FileSystem.cpp → libethsupport/FileSystem.cpp

0
libethcore/FileSystem.h → libethsupport/FileSystem.h

0
libethcore/FixedHash.cpp → libethsupport/FixedHash.cpp

0
libethcore/FixedHash.h → libethsupport/FixedHash.h

0
libethcore/Log.cpp → libethsupport/Log.cpp

0
libethcore/Log.h → libethsupport/Log.h

0
libethcore/RLP.cpp → libethsupport/RLP.cpp

0
libethcore/RLP.h → libethsupport/RLP.h

0
libethcore/TrieCommon.cpp → libethsupport/TrieCommon.cpp

0
libethcore/TrieCommon.h → libethsupport/TrieCommon.h

0
libethcore/TrieDB.cpp → libethsupport/TrieDB.cpp

0
libethcore/TrieDB.h → libethsupport/TrieDB.h

0
libethcore/UPnP.cpp → libethsupport/UPnP.cpp

0
libethcore/UPnP.h → libethsupport/UPnP.h

70
libevm/CMakeLists.txt

@ -0,0 +1,70 @@
cmake_policy(SET CMP0015 NEW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
aux_source_directory(. SRC_LIST)
set(EXECUTABLE evm)
if(APPLE)
# set(CMAKE_INSTALL_PREFIX ../lib)
add_library(${EXECUTABLE} SHARED ${SRC_LIST})
else()
add_library(${EXECUTABLE} ${SRC_LIST})
endif()
if (UNIX)
FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale)
endif()
file(GLOB HEADERS "*.h")
include_directories(..)
include_directories(${MINIUPNPC_ID})
include_directories(${LEVELDB_ID})
target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} ethsupport)
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
target_link_libraries(${EXECUTABLE} gmp)
if(${TARGET_PLATFORM} STREQUAL "w64")
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp)
target_link_libraries(${EXECUTABLE} cryptopp)
target_link_libraries(${EXECUTABLE} boost_system-mt-s)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
target_link_libraries(${EXECUTABLE} iphlpapi)
target_link_libraries(${EXECUTABLE} ws2_32)
target_link_libraries(${EXECUTABLE} mswsock)
target_link_libraries(${EXECUTABLE} shlwapi)
elseif (APPLE)
# Latest mavericks boost libraries only come with -mt
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} boost_system-mt)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt)
target_link_libraries(${EXECUTABLE} boost_thread-mt)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
elseif (UNIX)
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY})
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
else ()
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} boost_system)
target_link_libraries(${EXECUTABLE} boost_filesystem)
target_link_libraries(${EXECUTABLE} boost_thread)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
endif ()
message("Installation path: ${CMAKE_INSTALL_PREFIX}")
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

0
libethereum/ExtVMFace.cpp → libevm/ExtVMFace.cpp

5
libethereum/ExtVMFace.h → libevm/ExtVMFace.h

@ -21,8 +21,9 @@
#pragma once
#include <libethcore/Common.h>
#include "BlockInfo.h"
#include <libethsupport/Common.h>
#include <libethcore/CommonEth.h>
#include <libethcore/BlockInfo.h>
namespace eth
{

0
libethereum/FeeStructure.cpp → libevm/FeeStructure.cpp

2
libethereum/FeeStructure.h → libevm/FeeStructure.h

@ -21,7 +21,7 @@
#pragma once
#include <libethcore/Common.h>
#include <libethsupport/Common.h>
namespace eth
{

0
libethereum/VM.cpp → libevm/VM.cpp

16
libethereum/VM.h → libevm/VM.h

@ -22,16 +22,24 @@
#pragma once
#include <unordered_map>
#include "CommonEth.h"
#include "Exceptions.h"
#include <libethsupport/Exceptions.h>
#include <libethcore/CommonEth.h>
#include <libethcore/Instruction.h>
#include <libethcore/BlockInfo.h>
#include "FeeStructure.h"
#include "Instruction.h"
#include "BlockInfo.h"
#include "ExtVMFace.h"
namespace eth
{
class VMException: public Exception {};
class StepsDone: public VMException {};
class BreakPointHit: public VMException {};
class BadInstruction: public VMException {};
class OutOfGas: public VMException {};
class StackTooSmall: public VMException { public: StackTooSmall(u256 _req, u256 _got): req(_req), got(_got) {} u256 req; u256 got; };
class OperandOutOfRange: public VMException { public: OperandOutOfRange(u256 _min, u256 _max, u256 _got): mn(_min), mx(_max), got(_got) {} u256 mn; u256 mx; u256 got; };
// Convert from a 256-bit integer stack/memory entry into a 160-bit Address hash.
// Currently we just pull out the right (low-order in BE) 160-bits.
inline Address asAddress(u256 _item)

0
liblll/Assembly.cpp

0
liblll/Assembly.h

70
liblll/CMakeLists.txt

@ -0,0 +1,70 @@
cmake_policy(SET CMP0015 NEW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
aux_source_directory(. SRC_LIST)
set(EXECUTABLE lll)
if(APPLE)
# set(CMAKE_INSTALL_PREFIX ../lib)
add_library(${EXECUTABLE} SHARED ${SRC_LIST})
else()
add_library(${EXECUTABLE} ${SRC_LIST})
endif()
if (UNIX)
FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale)
endif()
file(GLOB HEADERS "*.h")
include_directories(..)
include_directories(${MINIUPNPC_ID})
include_directories(${LEVELDB_ID})
target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} ethsupport)
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
target_link_libraries(${EXECUTABLE} gmp)
if(${TARGET_PLATFORM} STREQUAL "w64")
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp)
target_link_libraries(${EXECUTABLE} cryptopp)
target_link_libraries(${EXECUTABLE} boost_system-mt-s)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
target_link_libraries(${EXECUTABLE} iphlpapi)
target_link_libraries(${EXECUTABLE} ws2_32)
target_link_libraries(${EXECUTABLE} mswsock)
target_link_libraries(${EXECUTABLE} shlwapi)
elseif (APPLE)
# Latest mavericks boost libraries only come with -mt
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} boost_system-mt)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt)
target_link_libraries(${EXECUTABLE} boost_thread-mt)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
elseif (UNIX)
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY})
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
else ()
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} boost_system)
target_link_libraries(${EXECUTABLE} boost_filesystem)
target_link_libraries(${EXECUTABLE} boost_thread)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
endif ()
message("Installation path: ${CMAKE_INSTALL_PREFIX}")
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

399
libethereum/Instruction.cpp → liblll/CodeFragment.cpp

@ -14,305 +14,49 @@
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 Instruction.cpp
/** @file CodeFragment.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Instruction.h"
#include "Parser.h"
#include "CodeFragment.h"
#include <boost/algorithm/string.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/support_utree.hpp>
#include <libethcore/Log.h>
#include "CommonEth.h"
#include <libethsupport/Log.h>
#include <libethcore/Instruction.h>
#include <libethcore/CommonEth.h>
#include "CompilerState.h"
using namespace std;
using namespace eth;
namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;
namespace sp = boost::spirit;
const std::map<std::string, Instruction> eth::c_instructions =
{
{ "STOP", Instruction::STOP },
{ "ADD", Instruction::ADD },
{ "SUB", Instruction::SUB },
{ "MUL", Instruction::MUL },
{ "DIV", Instruction::DIV },
{ "SDIV", Instruction::SDIV },
{ "MOD", Instruction::MOD },
{ "SMOD", Instruction::SMOD },
{ "EXP", Instruction::EXP },
{ "NEG", Instruction::NEG },
{ "LT", Instruction::LT },
{ "GT", Instruction::GT },
{ "SLT", Instruction::SLT },
{ "SGT", Instruction::SGT },
{ "EQ", Instruction::EQ },
{ "NOT", Instruction::NOT },
{ "AND", Instruction::AND },
{ "OR", Instruction::OR },
{ "XOR", Instruction::XOR },
{ "BYTE", Instruction::BYTE },
{ "SHA3", Instruction::SHA3 },
{ "ADDRESS", Instruction::ADDRESS },
{ "BALANCE", Instruction::BALANCE },
{ "ORIGIN", Instruction::ORIGIN },
{ "CALLER", Instruction::CALLER },
{ "CALLVALUE", Instruction::CALLVALUE },
{ "CALLDATALOAD", Instruction::CALLDATALOAD },
{ "CALLDATASIZE", Instruction::CALLDATASIZE },
{ "CALLDATACOPY", Instruction::CALLDATACOPY },
{ "CODESIZE", Instruction::CODESIZE },
{ "CODECOPY", Instruction::CODECOPY },
{ "GASPRICE", Instruction::GASPRICE },
{ "PREVHASH", Instruction::PREVHASH },
{ "COINBASE", Instruction::COINBASE },
{ "TIMESTAMP", Instruction::TIMESTAMP },
{ "NUMBER", Instruction::NUMBER },
{ "DIFFICULTY", Instruction::DIFFICULTY },
{ "GASLIMIT", Instruction::GASLIMIT },
{ "POP", Instruction::POP },
{ "DUP", Instruction::DUP },
{ "SWAP", Instruction::SWAP },
{ "MLOAD", Instruction::MLOAD },
{ "MSTORE", Instruction::MSTORE },
{ "MSTORE8", Instruction::MSTORE8 },
{ "SLOAD", Instruction::SLOAD },
{ "SSTORE", Instruction::SSTORE },
{ "JUMP", Instruction::JUMP },
{ "JUMPI", Instruction::JUMPI },
{ "PC", Instruction::PC },
{ "MEMSIZE", Instruction::MEMSIZE },
{ "GAS", Instruction::GAS },
{ "PUSH1", Instruction::PUSH1 },
{ "PUSH2", Instruction::PUSH2 },
{ "PUSH3", Instruction::PUSH3 },
{ "PUSH4", Instruction::PUSH4 },
{ "PUSH5", Instruction::PUSH5 },
{ "PUSH6", Instruction::PUSH6 },
{ "PUSH7", Instruction::PUSH7 },
{ "PUSH8", Instruction::PUSH8 },
{ "PUSH9", Instruction::PUSH9 },
{ "PUSH10", Instruction::PUSH10 },
{ "PUSH11", Instruction::PUSH11 },
{ "PUSH12", Instruction::PUSH12 },
{ "PUSH13", Instruction::PUSH13 },
{ "PUSH14", Instruction::PUSH14 },
{ "PUSH15", Instruction::PUSH15 },
{ "PUSH16", Instruction::PUSH16 },
{ "PUSH17", Instruction::PUSH17 },
{ "PUSH18", Instruction::PUSH18 },
{ "PUSH19", Instruction::PUSH19 },
{ "PUSH20", Instruction::PUSH20 },
{ "PUSH21", Instruction::PUSH21 },
{ "PUSH22", Instruction::PUSH22 },
{ "PUSH23", Instruction::PUSH23 },
{ "PUSH24", Instruction::PUSH24 },
{ "PUSH25", Instruction::PUSH25 },
{ "PUSH26", Instruction::PUSH26 },
{ "PUSH27", Instruction::PUSH27 },
{ "PUSH28", Instruction::PUSH28 },
{ "PUSH29", Instruction::PUSH29 },
{ "PUSH30", Instruction::PUSH30 },
{ "PUSH31", Instruction::PUSH31 },
{ "PUSH32", Instruction::PUSH32 },
{ "CREATE", Instruction::CREATE },
{ "CALL", Instruction::CALL },
{ "RETURN", Instruction::RETURN },
{ "SUICIDE", Instruction::SUICIDE }
};
const std::map<Instruction, InstructionInfo> eth::c_instructionInfo =
{ // Add, Args, Ret
{ Instruction::STOP, { "STOP", 0, 0, 0 } },
{ Instruction::ADD, { "ADD", 0, 2, 1 } },
{ Instruction::SUB, { "SUB", 0, 2, 1 } },
{ Instruction::MUL, { "MUL", 0, 2, 1 } },
{ Instruction::DIV, { "DIV", 0, 2, 1 } },
{ Instruction::SDIV, { "SDIV", 0, 2, 1 } },
{ Instruction::MOD, { "MOD", 0, 2, 1 } },
{ Instruction::SMOD, { "SMOD", 0, 2, 1 } },
{ Instruction::EXP, { "EXP", 0, 2, 1 } },
{ Instruction::NEG, { "NEG", 0, 1, 1 } },
{ Instruction::LT, { "LT", 0, 2, 1 } },
{ Instruction::GT, { "GT", 0, 2, 1 } },
{ Instruction::SLT, { "SLT", 0, 2, 1 } },
{ Instruction::SGT, { "SGT", 0, 2, 1 } },
{ Instruction::EQ, { "EQ", 0, 2, 1 } },
{ Instruction::NOT, { "NOT", 0, 1, 1 } },
{ Instruction::AND, { "AND", 0, 2, 1 } },
{ Instruction::OR, { "OR", 0, 2, 1 } },
{ Instruction::XOR, { "XOR", 0, 2, 1 } },
{ Instruction::BYTE, { "BYTE", 0, 2, 1 } },
{ Instruction::SHA3, { "SHA3", 0, 2, 1 } },
{ Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } },
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1 } },
{ Instruction::ORIGIN, { "ORIGIN", 0, 0, 1 } },
{ Instruction::CALLER, { "CALLER", 0, 0, 1 } },
{ Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1 } },
{ Instruction::CALLDATALOAD, { "CALLDATALOAD", 0, 1, 1 } },
{ Instruction::CALLDATASIZE, { "CALLDATASIZE", 0, 0, 1 } },
{ Instruction::CALLDATACOPY, { "CALLDATACOPY", 0, 3, 0 } },
{ Instruction::CODESIZE, { "CODESIZE", 0, 0, 1 } },
{ Instruction::CODECOPY, { "CODECOPY", 0, 3, 0 } },
{ Instruction::GASPRICE, { "GASPRICE", 0, 0, 1 } },
{ Instruction::PREVHASH, { "PREVHASH", 0, 0, 1 } },
{ Instruction::COINBASE, { "COINBASE", 0, 0, 1 } },
{ Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1 } },
{ Instruction::NUMBER, { "NUMBER", 0, 0, 1 } },
{ Instruction::DIFFICULTY, { "DIFFICULTY", 0, 0, 1 } },
{ Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1 } },
{ Instruction::POP, { "POP", 0, 1, 0 } },
{ Instruction::DUP, { "DUP", 0, 1, 2 } },
{ Instruction::SWAP, { "SWAP", 0, 2, 2 } },
{ Instruction::MLOAD, { "MLOAD", 0, 1, 1 } },
{ Instruction::MSTORE, { "MSTORE", 0, 2, 0 } },
{ Instruction::MSTORE8, { "MSTORE8", 0, 2, 0 } },
{ Instruction::SLOAD, { "SLOAD", 0, 1, 1 } },
{ Instruction::SSTORE, { "SSTORE", 0, 2, 0 } },
{ Instruction::JUMP, { "JUMP", 0, 1, 0 } },
{ Instruction::JUMPI, { "JUMPI", 0, 2, 0 } },
{ Instruction::PC, { "PC", 0, 0, 1 } },
{ Instruction::MEMSIZE, { "MEMSIZE", 0, 0, 1 } },
{ Instruction::GAS, { "GAS", 0, 0, 1 } },
{ Instruction::PUSH1, { "PUSH1", 1, 0, 1 } },
{ Instruction::PUSH2, { "PUSH2", 2, 0, 1 } },
{ Instruction::PUSH3, { "PUSH3", 3, 0, 1 } },
{ Instruction::PUSH4, { "PUSH4", 4, 0, 1 } },
{ Instruction::PUSH5, { "PUSH5", 5, 0, 1 } },
{ Instruction::PUSH6, { "PUSH6", 6, 0, 1 } },
{ Instruction::PUSH7, { "PUSH7", 7, 0, 1 } },
{ Instruction::PUSH8, { "PUSH8", 8, 0, 1 } },
{ Instruction::PUSH9, { "PUSH9", 9, 0, 1 } },
{ Instruction::PUSH10, { "PUSH10", 10, 0, 1 } },
{ Instruction::PUSH11, { "PUSH11", 11, 0, 1 } },
{ Instruction::PUSH12, { "PUSH12", 12, 0, 1 } },
{ Instruction::PUSH13, { "PUSH13", 13, 0, 1 } },
{ Instruction::PUSH14, { "PUSH14", 14, 0, 1 } },
{ Instruction::PUSH15, { "PUSH15", 15, 0, 1 } },
{ Instruction::PUSH16, { "PUSH16", 16, 0, 1 } },
{ Instruction::PUSH17, { "PUSH17", 17, 0, 1 } },
{ Instruction::PUSH18, { "PUSH18", 18, 0, 1 } },
{ Instruction::PUSH19, { "PUSH19", 19, 0, 1 } },
{ Instruction::PUSH20, { "PUSH20", 20, 0, 1 } },
{ Instruction::PUSH21, { "PUSH21", 21, 0, 1 } },
{ Instruction::PUSH22, { "PUSH22", 22, 0, 1 } },
{ Instruction::PUSH23, { "PUSH23", 23, 0, 1 } },
{ Instruction::PUSH24, { "PUSH24", 24, 0, 1 } },
{ Instruction::PUSH25, { "PUSH25", 25, 0, 1 } },
{ Instruction::PUSH26, { "PUSH26", 26, 0, 1 } },
{ Instruction::PUSH27, { "PUSH27", 27, 0, 1 } },
{ Instruction::PUSH28, { "PUSH28", 28, 0, 1 } },
{ Instruction::PUSH29, { "PUSH29", 29, 0, 1 } },
{ Instruction::PUSH30, { "PUSH30", 30, 0, 1 } },
{ Instruction::PUSH31, { "PUSH31", 31, 0, 1 } },
{ Instruction::PUSH32, { "PUSH32", 32, 0, 1 } },
{ Instruction::CREATE, { "CREATE", 0, 3, 1 } },
{ Instruction::CALL, { "CALL", 0, 7, 1 } },
{ Instruction::RETURN, { "RETURN", 0, 2, 0 } },
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} }
};
void killBigints(sp::utree const& _this)
void eth::debugOutAST(ostream& _out, sp::utree const& _this)
{
switch (_this.which())
{
case sp::utree_type::list_type: for (auto const& i: _this) killBigints(i); break;
case sp::utree_type::any_type: delete _this.get<bigint*>(); break;
default:;
}
}
void parseLLL(string const& _s, sp::utree& o_out)
{
using qi::ascii::space;
typedef sp::basic_string<std::string, sp::utree_type::symbol_type> symbol_type;
typedef string::const_iterator it;
qi::rule<it, qi::ascii::space_type, sp::utree()> element;
qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;())") + '\0'))];
qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" @[]{}:();\"\x01-\x1f\x7f") + '\0'))];
qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
qi::rule<it, bigint()> integer = intstr;
qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether];
qi::rule<it, qi::ascii::space_type, bigint()> quantity = integer[qi::_val = qi::_1] >> -multiplier[qi::_val *= qi::_1];
qi::rule<it, qi::ascii::space_type, sp::utree()> atom = quantity[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> seq = '{' > *element > '}';
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mload = '@' > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 2)] | mload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 1)] | sstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 4)] | mstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 3)] | seq[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 5)];
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
element = atom | list | extra;
try
{
string s;
s.reserve(_s.size());
bool incomment = false;
bool instring = false;
bool insstring = false;
for (auto i: _s)
case sp::utree_type::list_type:
switch (_this.tag())
{
if (i == ';' && !instring && !insstring)
incomment = true;
else if (i == '\n')
incomment = instring = insstring = false;
else if (i == '"' && !insstring)
instring = !instring;
else if (i == '\'')
insstring = true;
else if (i == ' ')
insstring = false;
if (!incomment)
s.push_back(i);
case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break;
case 1: _out << "@ "; debugOutAST(_out, _this.front()); break;
case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break;
case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
default:;
}
qi::phrase_parse(s.cbegin(), s.cend(), element, space, o_out);
}
catch (std::exception& _e)
{
cnote << _e.what();
}
}
namespace eth
{
struct Macro
{
std::vector<std::string> args;
sp::utree code;
std::map<std::string, CodeFragment> env;
};
static const CodeFragment NullCodeFragment;
struct CompilerState
{
CodeFragment const& getDef(std::string const& _s)
{
if (defs.count(_s))
return defs.at(_s);
else if (args.count(_s))
return args.at(_s);
else if (outers.count(_s))
return outers.at(_s);
else
return NullCodeFragment;
break;
case sp::utree_type::int_type: _out << _this.get<int>(); break;
case sp::utree_type::string_type: _out << "\"" << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>() << "\""; break;
case sp::utree_type::symbol_type: _out << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>(); break;
case sp::utree_type::any_type: _out << *_this.get<bigint*>(); break;
default: _out << "nil";
}
std::map<std::string, unsigned> vars;
std::map<std::string, CodeFragment> defs;
std::map<std::string, CodeFragment> args;
std::map<std::string, CodeFragment> outers;
std::map<std::string, Macro> macros;
std::vector<sp::utree> treesToKill;
};
}
CodeLocation::CodeLocation(CodeFragment* _f)
@ -371,6 +115,17 @@ void CodeFragment::appendFragment(CodeFragment const& _f)
m_deposit += _f.m_deposit;
}
CodeFragment CodeFragment::compile(string const& _src, CompilerState& _s)
{
CodeFragment ret;
sp::utree o;
parseTreeLLL(_src, o);
if (!o.empty())
ret = CodeFragment(o, _s);
_s.treesToKill.push_back(o);
return ret;
}
void CodeFragment::consolidateData()
{
m_code.push_back(0);
@ -432,31 +187,6 @@ void CodeFragment::appendInstruction(Instruction _i)
m_deposit += c_instructionInfo.at(_i).ret - c_instructionInfo.at(_i).args;
}
void debugOutAST(ostream& _out, sp::utree const& _this)
{
switch (_this.which())
{
case sp::utree_type::list_type:
switch (_this.tag())
{
case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break;
case 1: _out << "@ "; debugOutAST(_out, _this.front()); break;
case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break;
case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
default:;
}
break;
case sp::utree_type::int_type: _out << _this.get<int>(); break;
case sp::utree_type::string_type: _out << "\"" << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>() << "\""; break;
case sp::utree_type::symbol_type: _out << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>(); break;
case sp::utree_type::any_type: _out << *_this.get<bigint*>(); break;
default: _out << "nil";
}
}
CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM)
{
/* cdebug << "CodeFragment. Locals:";
@ -561,17 +291,9 @@ std::string CodeFragment::asPushedString() const
return ret;
}
CodeFragment compileLLLFragment(string const& _src, CompilerState& _s)
void CodeFragment::optimise()
{
CodeFragment ret;
sp::utree o;
parseLLL(_src, o);
debugOutAST(cerr, o);
cerr << endl;
if (!o.empty())
ret = CodeFragment(o, _s);
_s.treesToKill.push_back(o);
return ret;
// map<string, function<bytes(vector<u256> const&)>> pattern = { { "PUSH,PUSH,ADD", [](vector<u256> const& v) { return CodeFragment(appendPush(v[0] + v[1])); } } };
}
void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
@ -638,7 +360,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
n = _s.getDef(string(sr.begin(), sr.end())).asPushedString();
}
appendFragment(compileLLLFragment(asString(contents(n)), _s));
appendFragment(CodeFragment::compile(asString(contents(n)), _s));
}
else if (us == "DEF")
{
@ -977,50 +699,3 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
error<InvalidOperation>();
}
}
bytes eth::compileLLL(string const& _s, vector<string>* _errors)
{
try
{
CompilerState cs;
bytes ret = compileLLLFragment(_s, cs).code();
for (auto i: cs.treesToKill)
killBigints(i);
return ret;
}
catch (Exception const& _e)
{
if (_errors)
_errors->push_back(_e.description());
}
catch (std::exception)
{
if (_errors)
_errors->push_back("Parse error.");
}
return bytes();
}
string eth::disassemble(bytes const& _mem)
{
stringstream ret;
uint numerics = 0;
for (auto it = _mem.begin(); it != _mem.end(); ++it)
{
byte n = *it;
auto iit = c_instructionInfo.find((Instruction)n);
if (numerics || iit == c_instructionInfo.end() || (byte)iit->first != n) // not an instruction or expecting an argument...
{
if (numerics)
numerics--;
ret << "0x" << hex << (int)n << " ";
}
else
{
auto const& ii = iit->second;
ret << ii.name << " ";
numerics = ii.additional;
}
}
return ret.str();
}

185
libethereum/Instruction.h → liblll/CodeFragment.h

@ -14,14 +14,15 @@
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 Instruction.h
/** @file CodeFragment.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <libethcore/Common.h>
#include <libethsupport/Common.h>
#include <libethcore/Instruction.h>
#include "Exceptions.h"
namespace boost { namespace spirit { class utree; } }
@ -30,144 +31,11 @@ namespace sp = boost::spirit;
namespace eth
{
// TODO: Update comments.
/// Virtual machine bytecode instruction.
enum class Instruction: uint8_t
{
STOP = 0x00, ///< halts execution
ADD,
MUL,
SUB,
DIV,
SDIV,
MOD,
SMOD,
EXP,
NEG,
LT,
GT,
SLT,
SGT,
EQ,
NOT,
AND = 0x10,
OR,
XOR,
BYTE,
SHA3 = 0x20,
ADDRESS = 0x30,
BALANCE,
ORIGIN,
CALLER,
CALLVALUE,
CALLDATALOAD,
CALLDATASIZE,
CALLDATACOPY,
CODESIZE,
CODECOPY,
GASPRICE,
PREVHASH = 0x40,
COINBASE,
TIMESTAMP,
NUMBER,
DIFFICULTY,
GASLIMIT,
POP = 0x50,
DUP,
SWAP,
MLOAD,
MSTORE,
MSTORE8,
SLOAD,
SSTORE,
JUMP,
JUMPI,
PC,
MEMSIZE,
GAS,
PUSH1 = 0x60,
PUSH2,
PUSH3,
PUSH4,
PUSH5,
PUSH6,
PUSH7,
PUSH8,
PUSH9,
PUSH10,
PUSH11,
PUSH12,
PUSH13,
PUSH14,
PUSH15,
PUSH16,
PUSH17,
PUSH18,
PUSH19,
PUSH20,
PUSH21,
PUSH22,
PUSH23,
PUSH24,
PUSH25,
PUSH26,
PUSH27,
PUSH28,
PUSH29,
PUSH30,
PUSH31,
PUSH32,
CREATE = 0xf0,
CALL,
RETURN,
SUICIDE = 0xff
};
/// Information structure for a particular instruction.
struct InstructionInfo
{
char const* name; ///< The name of the instruction.
int additional; ///< Additional items required in memory for this instructions (only for PUSH).
int args; ///< Number of items required on the stack for this instruction (and, for the purposes of ret, the number taken from the stack).
int ret; ///< Number of items placed (back) on the stack by this instruction, assuming args items were removed.
};
/// Information on all the instructions.
extern const std::map<Instruction, InstructionInfo> c_instructionInfo;
/// Convert from string mnemonic to Instruction type.
extern const std::map<std::string, Instruction> c_instructions;
/// Convert from EVM code to simple EVM assembly language.
std::string disassemble(bytes const& _mem);
/// Compile a Low-level Lisp-like Language program into EVM-code.
class CompilerException: public Exception {};
class InvalidOperation: public CompilerException {};
class IntegerOutOfRange: public CompilerException {};
class StringTooLong: public CompilerException {};
class EmptyList: public CompilerException {};
class DataNotExecutable: public CompilerException {};
class IncorrectParameterCount: public CompilerException {};
class InvalidDeposit: public CompilerException {};
class InvalidName: public CompilerException {};
class InvalidMacroArgs: public CompilerException {};
class InvalidLiteral: public CompilerException {};
class BareSymbol: public CompilerException {};
class ExpectedLiteral: public CompilerException {};
bytes compileLLL(std::string const& _s, std::vector<std::string>* _errors = nullptr);
class CompilerState;
class CodeFragment;
void debugOutAST(std::ostream& _out, sp::utree const& _this);
class CodeLocation
{
friend class CodeFragment;
@ -191,6 +59,41 @@ private:
class CompilerState;
enum AssemblyItemType { Operation, Push, PushString, PushTag, Tag, PushData };
class AssemblyItem
{
public:
AssemblyItem(u256 _push): m_type(Push), m_data(_push) {}
AssemblyItem(std::string const& _push): m_type(PushString), m_pushString(_push) {}
AssemblyItem(AssemblyItemType _type, AssemblyItem const& _tag): m_type(_type), m_data(_tag.m_data) { assert(_type == PushTag); assert(_tag.m_type == Tag); }
AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {}
AssemblyItem(AssemblyItemType _type, u256 _data): m_type(_type), m_data(_data) {}
AssemblyItemType type() const { return m_type; }
u256 data() const { return m_data; }
std::string const& pushString() const { return m_pushString; }
private:
AssemblyItemType m_type;
u256 m_data;
std::string m_pushString;
};
class Assembly
{
public:
AssemblyItem newTag() { return AssemblyItem(Tag, m_usedTags++); }
AssemblyItem newData(bytes const& _data) { auto h = sha3(_data); m_data[h] = _data; return AssemblyItem(PushData, h); }
bytes assemble() const;
void append(Assembly const& _a);
private:
u256 m_usedTags = 0;
std::vector<AssemblyItem> m_items;
std::map<h256, bytes> m_data;
};
class CodeFragment
{
friend class CodeLocation;
@ -199,14 +102,15 @@ public:
CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM = false);
CodeFragment(bytes const& _c = bytes()): m_code(_c) {}
static CodeFragment compile(std::string const& _src, CompilerState& _s);
/// Consolidates data and returns code.
bytes const& code() { consolidateData(); return m_code; }
bytes const& code() { optimise(); consolidateData(); return m_code; }
unsigned appendPush(u256 _l);
void appendFragment(CodeFragment const& _f);
void appendFragment(CodeFragment const& _f, unsigned _i);
void appendInstruction(Instruction _i);
void appendString(std::string const& _s) { for (auto i: _s) m_code.push_back((char)i); }
CodeLocation appendPushLocation(unsigned _l = 0);
void appendPushLocation(CodeLocation _l) { assert(_l.m_f == this); appendPushLocation(_l.m_pos); }
@ -232,6 +136,7 @@ public:
unsigned size() const { return m_code.size(); }
void consolidateData();
void optimise();
private:
template <class T> void error() const { throw T(); }
@ -247,4 +152,6 @@ private:
std::multimap<bytes, unsigned> m_data;
};
static const CodeFragment NullCodeFragment;
}

61
liblll/Compiler.cpp

@ -0,0 +1,61 @@
/*
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 Compiler.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Compiler.h"
#include "Parser.h"
#include "CompilerState.h"
#include "CodeFragment.h"
using namespace std;
using namespace eth;
bytes eth::compileLLL(string const& _s, vector<string>* _errors)
{
try
{
CompilerState cs;
bytes ret = CodeFragment::compile(_s, cs).code();
for (auto i: cs.treesToKill)
killBigints(i);
return ret;
}
catch (Exception const& _e)
{
if (_errors)
_errors->push_back(_e.description());
}
catch (std::exception)
{
if (_errors)
_errors->push_back("Parse error.");
}
return bytes();
}
string eth::parseLLL(string const& _src)
{
sp::utree o;
parseTreeLLL(_src, o);
ostringstream ret;
debugOutAST(ret, o);
killBigints(o);
return ret.str();
}

35
liblll/Compiler.h

@ -0,0 +1,35 @@
/*
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 Compiler.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <string>
#include <vector>
#include <libethsupport/Common.h>
namespace eth
{
std::string parseLLL(std::string const& _src);
bytes compileLLL(std::string const& _s, std::vector<std::string>* _errors = nullptr);
}

37
liblll/CompilerState.cpp

@ -0,0 +1,37 @@
/*
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 CompilerState.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "CompilerState.h"
using namespace std;
using namespace eth;
CodeFragment const& CompilerState::getDef(std::string const& _s)
{
if (defs.count(_s))
return defs.at(_s);
else if (args.count(_s))
return args.at(_s);
else if (outers.count(_s))
return outers.at(_s);
else
return NullCodeFragment;
}

49
liblll/CompilerState.h

@ -0,0 +1,49 @@
/*
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 CompilerState.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <boost/spirit/include/support_utree.hpp>
#include "CodeFragment.h"
namespace eth
{
struct Macro
{
std::vector<std::string> args;
boost::spirit::utree code;
std::map<std::string, CodeFragment> env;
};
struct CompilerState
{
CodeFragment const& getDef(std::string const& _s);
std::map<std::string, unsigned> vars;
std::map<std::string, CodeFragment> defs;
std::map<std::string, CodeFragment> args;
std::map<std::string, CodeFragment> outers;
std::map<std::string, Macro> macros;
std::vector<boost::spirit::utree> treesToKill;
};
}

91
liblll/Parser.cpp

@ -0,0 +1,91 @@
/*
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 Parser.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Parser.h"
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/support_utree.hpp>
#include <libethcore/CommonEth.h>
using namespace std;
using namespace eth;
namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;
namespace sp = boost::spirit;
void eth::killBigints(sp::utree const& _this)
{
switch (_this.which())
{
case sp::utree_type::list_type: for (auto const& i: _this) killBigints(i); break;
case sp::utree_type::any_type: delete _this.get<bigint*>(); break;
default:;
}
}
void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
{
using qi::ascii::space;
typedef sp::basic_string<std::string, sp::utree_type::symbol_type> symbol_type;
typedef string::const_iterator it;
qi::rule<it, qi::ascii::space_type, sp::utree()> element;
qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;())") + '\0'))];
qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" @[]{}:();\"\x01-\x1f\x7f") + '\0'))];
qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
qi::rule<it, bigint()> integer = intstr;
qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether];
qi::rule<it, qi::ascii::space_type, bigint()> quantity = integer[qi::_val = qi::_1] >> -multiplier[qi::_val *= qi::_1];
qi::rule<it, qi::ascii::space_type, sp::utree()> atom = quantity[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> seq = '{' > *element > '}';
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mload = '@' > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 2)] | mload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 1)] | sstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 4)] | mstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 3)] | seq[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 5)];
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
element = atom | list | extra;
string s;
s.reserve(_s.size());
bool incomment = false;
bool instring = false;
bool insstring = false;
for (auto i: _s)
{
if (i == ';' && !instring && !insstring)
incomment = true;
else if (i == '\n')
incomment = instring = insstring = false;
else if (i == '"' && !insstring)
instring = !instring;
else if (i == '\'')
insstring = true;
else if (i == ' ')
insstring = false;
if (!incomment)
s.push_back(i);
}
qi::phrase_parse(s.cbegin(), s.cend(), element, space, o_out);
}

38
liblll/Parser.h

@ -0,0 +1,38 @@
/*
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 Parser.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <string>
#include <vector>
#include <libethsupport/Common.h>
namespace boost { namespace spirit { class utree; } }
namespace sp = boost::spirit;
namespace eth
{
void killBigints(sp::utree const& _this);
void parseTreeLLL(std::string const& _s, sp::utree& o_out);
}

7
libqethereum/QEthereum.cpp

@ -1,10 +1,11 @@
#include <QtQml/QtQml>
#include <QtCore/QtCore>
#include <QtWebKitWidgets/QWebFrame>
#include <libethcore/FileSystem.h>
#include <libethereum/Dagger.h>
#include <libethsupport/FileSystem.h>
#include <libethcore/Dagger.h>
#include <libethcore/Instruction.h>
#include <liblll/Compiler.h>
#include <libethereum/Client.h>
#include <libethereum/Instruction.h>
#include <libethereum/PeerServer.h>
#include "QEthereum.h"
using namespace std;

4
libqethereum/QEthereum.h

@ -2,8 +2,8 @@
#include <QtCore/QAbstractListModel>
#include <QtQml/QtQml>
#include <libethereum/CommonEth.h>
#include <libethcore/CommonIO.h>
#include <libethsupport/CommonIO.h>
#include <libethcore/CommonEth.h>
namespace eth {
class Client;

56
lllc/CMakeLists.txt

@ -0,0 +1,56 @@
cmake_policy(SET CMP0015 NEW)
aux_source_directory(. SRC_LIST)
include_directories(..)
#link_directories(../libethsupport)
#link_directories(../libethcore)
#link_directories(../liblll)
set(EXECUTABLE lllc)
add_executable(${EXECUTABLE} ${SRC_LIST})
if (JSONRPC_LS)
add_definitions(-DETH_JSONRPC)
include_directories(${JSONRPC_ID})
target_link_libraries(${EXECUTABLE} ${JSONRPC_LS})
endif ()
if (READLINE_LS)
add_definitions(-DETH_READLINE)
include_directories(${READLINE_ID})
target_link_libraries(${EXECUTABLE} ${READLINE_LS})
endif ()
if (${TARGET_PLATFORM} STREQUAL "w64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
target_link_libraries(${EXECUTABLE} gcc)
target_link_libraries(${EXECUTABLE} gdi32)
target_link_libraries(${EXECUTABLE} ws2_32)
target_link_libraries(${EXECUTABLE} mswsock)
target_link_libraries(${EXECUTABLE} shlwapi)
target_link_libraries(${EXECUTABLE} iphlpapi)
target_link_libraries(${EXECUTABLE} cryptopp)
target_link_libraries(${EXECUTABLE} boost_system-mt-s)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
elseif (UNIX)
else ()
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} boost_system)
target_link_libraries(${EXECUTABLE} boost_filesystem)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
endif ()
target_link_libraries(${EXECUTABLE} lll)
target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} ethsupport)
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
target_link_libraries(${EXECUTABLE} gmp)
install( TARGETS ${EXECUTABLE} DESTINATION bin )

106
lllc/main.cpp

@ -0,0 +1,106 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file main.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
* Ethereum client.
*/
#include <fstream>
#include <iostream>
#include <liblll/Compiler.h>
#include <libethsupport/CommonIO.h>
#include <libethsupport/CommonData.h>
#include "BuildInfo.h"
using namespace std;
using namespace eth;
void help()
{
cout
<< "Usage lllc [OPTIONS] <file>" << endl
<< "Options:" << endl
<< " -h,--help Show this help message and exit." << endl
<< " -V,--version Show the version and exit." << endl;
exit(0);
}
void version()
{
cout << "LLLC, the Lovely Little Language Compiler " << ETH_QUOTED(ETH_VERSION) << endl;
cout << " By Gav Wood, (c) 2014." << endl;
cout << "Build: " << ETH_QUOTED(ETH_BUILD_PLATFORM) << "/" << ETH_QUOTED(ETH_BUILD_TYPE) << endl;
exit(0);
}
enum Mode { Binary, Hex, ParseTree };
int main(int argc, char** argv)
{
string infile;
Mode mode = Hex;
for (int i = 1; i < argc; ++i)
{
string arg = argv[i];
if (arg == "-h" || arg == "--help")
help();
else if (arg == "-b" || arg == "--binary")
mode = Binary;
else if (arg == "-h" || arg == "--hex")
mode = Hex;
else if (arg == "-t" || arg == "--parse-tree")
mode = ParseTree;
else if (arg == "-V" || arg == "--version")
version();
else
infile = argv[i];
}
string src;
if (infile.empty())
{
string s;
while (!cin.eof())
{
getline(cin, s);
src.append(s);
}
}
else
src = asString(contents(infile));
if (src.empty())
cerr << "Empty file." << endl;
else if (mode == Binary || mode == Hex)
{
vector<string> errors;
auto bs = compileLLL(src, &errors);
if (mode == Hex)
cout << toHex(bs) << endl;
else if (mode == Binary)
cout.write((char const*)bs.data(), bs.size());
for (auto const& i: errors)
cerr << i << endl;
}
else if (mode == ParseTree)
{
cout << parseLLL(src) << endl;
}
return 0;
}

4
neth/main.cpp

@ -26,13 +26,13 @@
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim_all.hpp>
#include <libethcore/FileSystem.h>
#include <libethsupport/FileSystem.h>
#include <libethcore/Instruction.h>
#include <libethereum/Defaults.h>
#include <libethereum/Client.h>
#include <libethereum/PeerNetwork.h>
#include <libethereum/BlockChain.h>
#include <libethereum/State.h>
#include <libethereum/Instruction.h>
#if ETH_JSONRPC
#include <eth/EthStubServer.h>
#include <eth/EthStubServer.cpp>

4
test/MemTrie.cpp

@ -21,8 +21,8 @@
#include "MemTrie.h"
#include <libethcore/TrieCommon.h>
#include <libethereum/CommonEth.h>
#include <libethsupport/TrieCommon.h>
#include <libethcore/CommonEth.h>
using namespace std;
using namespace eth;

4
test/MemTrie.h

@ -21,8 +21,8 @@
#pragma once
#include <libethcore/Common.h>
#include <libethcore/FixedHash.h>
#include <libethsupport/Common.h>
#include <libethsupport/FixedHash.h>
namespace eth
{

4
test/TrieHash.cpp

@ -21,8 +21,8 @@
#include "TrieHash.h"
#include <libethcore/TrieCommon.h>
#include <libethereum/CommonEth.h>
#include <libethsupport/TrieCommon.h>
#include <libethcore/CommonEth.h>
using namespace std;
using namespace eth;

4
test/TrieHash.h

@ -21,8 +21,8 @@
#pragma once
#include <libethcore/Common.h>
#include <libethcore/FixedHash.h>
#include <libethsupport/Common.h>
#include <libethsupport/FixedHash.h>
namespace eth
{

6
test/crypto.cpp

@ -22,9 +22,9 @@
#include <random>
#include <secp256k1/secp256k1.h>
#include <libethcore/Common.h>
#include <libethcore/RLP.h>
#include <libethcore/Log.h>
#include <libethsupport/Common.h>
#include <libethsupport/RLP.h>
#include <libethsupport/Log.h>
#include <libethereum/Transaction.h>
#include <boost/test/unit_test.hpp>

4
test/dagger.cpp

@ -21,8 +21,8 @@
*/
#include <chrono>
#include <libethcore/Log.h>
#include <libethereum/Dagger.h>
#include <libethsupport/Log.h>
#include <libethcore/Dagger.h>
using namespace std;
using namespace std::chrono;
using namespace eth;

4
test/hexPrefix.cpp

@ -22,8 +22,8 @@
#include <fstream>
#include "JsonSpiritHeaders.h"
#include <libethcore/TrieCommon.h>
#include <libethcore/Log.h>
#include <libethsupport/TrieCommon.h>
#include <libethsupport/Log.h>
#include <boost/test/unit_test.hpp>
using namespace std;

4
test/main.cpp

@ -31,8 +31,8 @@ int vmTest();
int hexPrefixTest();
int peerTest(int argc, char** argv);
#include <libethcore/Log.h>
#include <libethereum/BlockInfo.h>
#include <libethsupport/Log.h>
#include <libethcore/BlockInfo.h>
using namespace std;
using namespace eth;

6
test/rlp.cpp

@ -23,9 +23,9 @@
#include <fstream>
#include <sstream>
#include "JsonSpiritHeaders.h"
#include <libethcore/Log.h>
#include <libethcore/RLP.h>
#include <libethcore/Common.h>
#include <libethsupport/Log.h>
#include <libethsupport/RLP.h>
#include <libethsupport/Common.h>
#include <boost/test/unit_test.hpp>
#include <algorithm>

2
test/trie.cpp

@ -23,7 +23,7 @@
#include <fstream>
#include <random>
#include "JsonSpiritHeaders.h"
#include <libethcore/TrieDB.h>
#include <libethsupport/TrieDB.h>
#include "TrieHash.h"
#include "MemTrie.h"
#include <boost/test/unit_test.hpp>

9
test/vm.cpp

@ -22,11 +22,12 @@
#include <fstream>
#include <cstdint>
#include <libethcore/Log.h>
#include <libethereum/ExtVMFace.h>
#include <libethsupport/Log.h>
#include <libethcore/Instruction.h>
#include <libevm/ExtVMFace.h>
#include <libevm/VM.h>
#include <liblll/Compiler.h>
#include <libethereum/Transaction.h>
#include <libethereum/VM.h>
#include <libethereum/Instruction.h>
#include "JsonSpiritHeaders.h"
#include <boost/test/unit_test.hpp>

6
walleth/MainWin.cpp

@ -7,10 +7,10 @@
#include <QtWidgets/QInputDialog>
#include <QtGui/QClipboard>
#include <QtCore/QtCore>
#include <libethcore/FileSystem.h>
#include <libethereum/Dagger.h>
#include <libethsupport/FileSystem.h>
#include <libethcore/Dagger.h>
#include <libethcore/Instruction.h>
#include <libethereum/Client.h>
#include <libethereum/Instruction.h>
#include <libethereum/PeerServer.h>
#include "BuildInfo.h"
#include "MainWin.h"

2
walleth/MainWin.h

@ -5,7 +5,7 @@
#include <QtCore/QAbstractListModel>
#include <QtCore/QMutex>
#include <QtWidgets/QMainWindow>
#include <libethereum/CommonEth.h>
#include <libethcore/CommonEth.h>
#include <libqethereum/QEthereum.h>
namespace Ui {

Loading…
Cancel
Save