Browse Source

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

cl-refactor
Paweł Bylica 10 years ago
parent
commit
10034778df
  1. 2
      CMakeLists.txt
  2. 2
      alethzero/DappLoader.cpp
  3. 2
      alethzero/MainWin.cpp
  4. 1
      libdevcore/Common.h
  5. 32
      libdevcore/StructuredLogger.cpp
  6. 2
      libdevcore/StructuredLogger.h
  7. 4
      libdevcrypto/Common.h
  8. 2
      libethcore/BlockInfo.cpp
  9. 2
      libethcore/BlockInfo.h
  10. 115
      libethcore/ProofOfWork.cpp
  11. 35
      libethcore/ProofOfWork.h
  12. 4
      libethereum/BlockChain.cpp
  13. 4
      libethereum/CMakeLists.txt
  14. 15
      libethereum/Client.cpp
  15. 14
      libethereum/Client.h
  16. 2
      libethereum/ExtVM.cpp
  17. 10
      libethereum/Interface.h
  18. 8
      libethereum/Miner.cpp
  19. 32
      libethereum/Miner.h
  20. 3
      libethereum/State.h
  21. 6
      libevm/VM.cpp
  22. 4
      libjsqrc/CMakeLists.txt
  23. 80
      libjsqrc/ethereumjs/dist/ethereum.js
  24. 20
      libjsqrc/ethereumjs/dist/ethereum.js.map
  25. 2
      libjsqrc/ethereumjs/dist/ethereum.min.js
  26. 16
      libjsqrc/ethereumjs/gulpfile.js
  27. 8
      libjsqrc/ethereumjs/lib/solidity/abi.js
  28. 6
      libjsqrc/ethereumjs/lib/solidity/types.js
  29. 36
      libjsqrc/ethereumjs/lib/web3.js
  30. 9
      libjsqrc/ethereumjs/lib/web3/db.js
  31. 8
      libjsqrc/ethereumjs/lib/web3/eth.js
  32. 1
      libjsqrc/ethereumjs/lib/web3/filter.js
  33. 2
      libjsqrc/ethereumjs/lib/web3/httpprovider.js
  34. 2
      libjsqrc/ethereumjs/lib/web3/requestmanager.js
  35. 2
      libjsqrc/ethereumjs/package.js
  36. 7
      libjsqrc/ethereumjs/package.json
  37. 66
      libjsqrc/ethereumjs/test/abi.inputParser.js
  38. 72
      libjsqrc/ethereumjs/test/abi.outputParser.js
  39. 4
      libjsqrc/ethereumjs/test/db.methods.js
  40. 2
      libjsqrc/ethereumjs/test/eth.methods.js
  41. 3
      libjsqrc/ethereumjs/version.json
  42. 2
      libsolidity/AST.cpp
  43. 1
      libsolidity/ArrayUtils.cpp
  44. 2
      libsolidity/Compiler.cpp
  45. 8
      libsolidity/CompilerStack.cpp
  46. 8
      libsolidity/CompilerUtils.cpp
  47. 70
      libsolidity/ExpressionCompiler.cpp
  48. 18
      libsolidity/GlobalContext.cpp
  49. 9
      libsolidity/LValue.cpp
  50. 103
      libsolidity/Token.h
  51. 131
      libsolidity/Types.cpp
  52. 27
      libsolidity/Types.h
  53. 1
      libweb3jsonrpc/CMakeLists.txt
  54. 81
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  55. 3
      libweb3jsonrpc/WebThreeStubServerBase.h
  56. 14
      libweb3jsonrpc/abstractwebthreestubserver.h
  57. 3
      libweb3jsonrpc/spec.json
  58. 8
      mix/CodeModel.cpp
  59. 3
      mix/CodeModel.h
  60. 10
      mix/MixClient.cpp
  61. 4
      mix/MixClient.h
  62. 30
      test/CMakeLists.txt
  63. 10
      test/SolidityABIJSON.cpp
  64. 192
      test/SolidityEndToEndTest.cpp
  65. 10
      test/SolidityInterface.cpp
  66. 147
      test/SolidityNameAndTypeResolution.cpp
  67. 52
      test/SolidityParser.cpp
  68. 83
      test/Stats.cpp
  69. 50
      test/Stats.h
  70. 62
      test/TestHelper.cpp
  71. 30
      test/TestHelper.h
  72. 1
      test/bcBlockChainTestFiller.json
  73. 14
      test/bcInvalidHeaderTestFiller.json
  74. 13
      test/bcUncleTestFiller.json
  75. 8
      test/bcValidBlockTestFiller.json
  76. 6
      test/blockchain.cpp
  77. 228
      test/checkRandomStateTest.cpp
  78. 6
      test/checkRandomVMTest.cpp
  79. 183
      test/createRandomStateTest.cpp
  80. 6
      test/createRandomVMTest.cpp
  81. 14
      test/stPreCompiledContractsFiller.json
  82. 639
      test/stSolidityTestFiller.json
  83. 4
      test/stSpecialTestFiller.json
  84. 118
      test/stSystemOperationsTestFiller.json
  85. 60
      test/state.cpp
  86. 45
      test/vm.cpp
  87. 28
      test/vmArithmeticTestFiller.json
  88. 28
      test/vmEnvironmentalInfoTestFiller.json
  89. 15
      test/webthreestubclient.h

2
CMakeLists.txt

@ -131,7 +131,7 @@ configureProject()
set (ETH_HAVE_WEBENGINE 1)
message(STATUS "CMAKE_VERSION: ${CMAKE_VERSION}")
message("-- VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}; EVMJIT: ${EVMJIT}; FATDB: ${FATDB}; CHROMIUM: ${ETH_HAVE_WEBENGINE}; USENPM: ${USENPM}")
message("-- VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}; EVMJIT: ${EVMJIT}; FATDB: ${FATDB}; CHROMIUM: ${ETH_HAVE_WEBENGINE}; USENPM: ${USENPM}; ETHASHCL: ${ETHASHCL}")
# Default TARGET_PLATFORM to "linux".

2
alethzero/DappLoader.cpp

@ -69,7 +69,7 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri)
while (address && partIndex < parts.length())
{
lastAddress = address;
string32 name = { 0 };
string32 name = ZeroString32;
QByteArray utf8 = parts[partIndex].toUtf8();
std::copy(utf8.data(), utf8.data() + utf8.size(), name.data());
address = abiOut<Address>(web3()->ethereum()->call(address, abiIn("addr(string32)", name)));

2
alethzero/MainWin.cpp

@ -263,7 +263,7 @@ unsigned Main::installWatch(LogFilter const& _tf, WatchHandler const& _f)
unsigned Main::installWatch(dev::h256 _tf, WatchHandler const& _f)
{
auto ret = ethereum()->installWatch(_tf);
auto ret = ethereum()->installWatch(_tf, Reaping::Manual);
m_handlers[ret] = _f;
return ret;
}

1
libdevcore/Common.h

@ -87,6 +87,7 @@ using strings = std::vector<std::string>;
// Fixed-length string types.
using string32 = std::array<char, 32>;
static const string32 ZeroString32 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// Null/Invalid values for convenience.
static const u256 Invalid256 = ~(u256)0;

32
libdevcore/StructuredLogger.cpp

@ -22,9 +22,10 @@
*/
#include "StructuredLogger.h"
#include <ctime>
#include <boost/asio/ip/tcp.hpp>
#include <json/json.h>
#include <libdevcore/CommonIO.h>
#include "Guards.h"
namespace ba = boost::asio;
@ -33,19 +34,6 @@ using namespace std;
namespace dev
{
string StructuredLogger::timePointToString(chrono::system_clock::time_point const& _ts)
{
// not using C++11 std::put_time due to gcc bug
// http://stackoverflow.com/questions/14136833/stdput-time-implementation-status-in-gcc
char buffer[64];
time_t time = chrono::system_clock::to_time_t(_ts);
tm* ptm = localtime(&time);
if (strftime(buffer, sizeof(buffer), get().m_timeFormat.c_str(), ptm))
return string(buffer);
return "";
}
void StructuredLogger::outputJson(Json::Value const& _value, std::string const& _name) const
{
Json::Value event;
@ -62,7 +50,7 @@ void StructuredLogger::starting(string const& _clientImpl, const char* _ethVersi
Json::Value event;
event["client_impl"] = _clientImpl;
event["eth_version"] = std::string(_ethVersion);
event["ts"] = timePointToString(std::chrono::system_clock::now());
event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str());
get().outputJson(event, "starting");
}
@ -75,7 +63,7 @@ void StructuredLogger::stopping(string const& _clientImpl, const char* _ethVersi
Json::Value event;
event["client_impl"] = _clientImpl;
event["eth_version"] = std::string(_ethVersion);
event["ts"] = timePointToString(std::chrono::system_clock::now());
event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str());
get().outputJson(event, "stopping");
}
@ -97,7 +85,7 @@ void StructuredLogger::p2pConnected(
event["remote_addr"] = addrStream.str();
event["remote_id"] = _id;
event["num_connections"] = Json::Value(_numConnections);
event["ts"] = timePointToString(_ts);
event["ts"] = dev::toString(_ts, get().m_timeFormat.c_str());
get().outputJson(event, "p2p.connected");
}
@ -113,7 +101,7 @@ void StructuredLogger::p2pDisconnected(string const& _id, bi::tcp::endpoint cons
event["remote_addr"] = addrStream.str();
event["remote_id"] = _id;
event["num_connections"] = Json::Value(_numConnections);
event["ts"] = timePointToString(chrono::system_clock::now());
event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str());
get().outputJson(event, "p2p.disconnected");
}
@ -131,7 +119,7 @@ void StructuredLogger::minedNewBlock(
event["block_hash"] = _hash;
event["block_number"] = _blockNumber;
event["chain_head_hash"] = _chainHeadHash;
event["ts"] = timePointToString(std::chrono::system_clock::now());
event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str());
event["block_prev_hash"] = _prevHash;
get().outputJson(event, "eth.miner.new_block");
@ -152,7 +140,7 @@ void StructuredLogger::chainReceivedNewBlock(
event["block_number"] = _blockNumber;
event["chain_head_hash"] = _chainHeadHash;
event["remote_id"] = _remoteID;
event["ts"] = timePointToString(chrono::system_clock::now());
event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str());
event["block_prev_hash"] = _prevHash;
get().outputJson(event, "eth.chain.received.new_block");
@ -171,7 +159,7 @@ void StructuredLogger::chainNewHead(
event["block_hash"] = _hash;
event["block_number"] = _blockNumber;
event["chain_head_hash"] = _chainHeadHash;
event["ts"] = timePointToString(chrono::system_clock::now());
event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str());
event["block_prev_hash"] = _prevHash;
get().outputJson(event, "eth.miner.new_block");
@ -185,7 +173,7 @@ void StructuredLogger::transactionReceived(string const& _hash, string const& _r
Json::Value event;
event["tx_hash"] = _hash;
event["remote_id"] = _remoteId;
event["ts"] = timePointToString(chrono::system_clock::now());
event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str());
get().outputJson(event, "eth.tx.received");
}

2
libdevcore/StructuredLogger.h

@ -98,8 +98,6 @@ private:
StructuredLogger(StructuredLogger const&) = delete;
void operator=(StructuredLogger const&) = delete;
/// @returns a string representation of a timepoint
static std::string timePointToString(std::chrono::system_clock::time_point const& _ts);
void outputJson(Json::Value const& _value, std::string const& _name) const;
bool m_enabled = false;

4
libdevcrypto/Common.h

@ -45,7 +45,7 @@ using Signature = h520;
struct SignatureStruct
{
SignatureStruct() {}
SignatureStruct() = default;
SignatureStruct(Signature const& _s) { *(h520*)this = _s; }
SignatureStruct(h256 const& _r, h256 const& _s, byte _v): r(_r), s(_s), v(_v) {}
operator Signature() const { return *(h520 const*)this; }
@ -55,7 +55,7 @@ struct SignatureStruct
h256 r;
h256 s;
byte v;
byte v = 0;
};
/// An Ethereum address: 20 bytes.

2
libethcore/BlockInfo.cpp

@ -61,7 +61,7 @@ void BlockInfo::setEmpty()
hash = headerHash(WithNonce);
}
h256 BlockInfo::seedHash() const
h256 const& BlockInfo::seedHash() const
{
if (!m_seedHash)
for (u256 n = number; n >= c_epochDuration; n -= c_epochDuration)

2
libethcore/BlockInfo.h

@ -128,7 +128,7 @@ public:
u256 calculateDifficulty(BlockInfo const& _parent) const;
u256 selectGasLimit(BlockInfo const& _parent) const;
h256 seedHash() const;
h256 const& seedHash() const;
/// sha3 of the header only.
h256 headerHash(IncludeNonce _n) const;

115
libethcore/ProofOfWork.cpp

@ -30,6 +30,9 @@
#include <libdevcrypto/CryptoPP.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/Common.h>
#if ETH_ETHASHCL
#include <libethash-cl/ethash_cl_miner.h>
#endif
#include "BlockInfo.h"
#include "Ethasher.h"
#include "ProofOfWork.h"
@ -41,12 +44,12 @@ namespace dev
namespace eth
{
bool Ethash::verify(BlockInfo const& _header)
bool EthashCPU::verify(BlockInfo const& _header)
{
return Ethasher::verify(_header);
}
std::pair<MineInfo, Ethash::Proof> Ethash::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo)
std::pair<MineInfo, EthashCPU::Proof> EthashCPU::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo)
{
Ethasher::Miner m(_header);
@ -93,5 +96,113 @@ std::pair<MineInfo, Ethash::Proof> Ethash::mine(BlockInfo const& _header, unsign
return ret;
}
#if ETH_ETHASHCL
/*
struct ethash_cl_search_hook
{
// reports progress, return true to abort
virtual bool found(uint64_t const* nonces, uint32_t count) = 0;
virtual bool searched(uint64_t start_nonce, uint32_t count) = 0;
};
class ethash_cl_miner
{
public:
ethash_cl_miner();
bool init(ethash_params const& params, const uint8_t seed[32], unsigned workgroup_size = 64);
void hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count);
void search(uint8_t const* header, uint64_t target, search_hook& hook);
};
*/
struct EthashCLHook: public ethash_cl_search_hook
{
virtual bool found(uint64_t const* _nonces, uint32_t _count)
{
Guard l(x_all);
for (unsigned i = 0; i < _count; ++i)
found.push_back((Nonce)(u64)_nonces[i]);
if (abort)
{
aborted = true;
return true;
}
return false;
}
virtual bool searched(uint64_t _startNonce, uint32_t _count)
{
Guard l(x_all);
total += _count;
last = _startNonce + _count;
if (abort)
{
aborted = true;
return true;
}
return false;
}
vector<Nonce> fetchFound() { vector<Nonce> ret; Guard l(x_all); std::swap(ret, found); return ret; }
uint64_t fetchTotal() { Guard l(x_all); auto ret = total; total = 0; return ret; }
Mutex x_all;
vector<Nonce> found;
uint64_t total;
uint64_t last;
bool abort = false;
bool aborted = false;
};
EthashCL::EthashCL():
m_miner(new ethash_cl_miner),
m_hook(new EthashCLHook)
{
}
EthashCL::~EthashCL()
{
m_hook->abort = true;
for (unsigned timeout = 0; timeout < 100 && !m_hook->aborted; ++timeout)
std::this_thread::sleep_for(chrono::milliseconds(30));
if (!m_hook->aborted)
cwarn << "Couldn't abort. Abandoning OpenCL process.";
}
bool EthashCL::verify(BlockInfo const& _header)
{
return Ethasher::verify(_header);
}
std::pair<MineInfo, Ethash::Proof> EthashCL::mine(BlockInfo const& _header, unsigned _msTimeout, bool, bool)
{
if (m_lastHeader.seedHash() != _header.seedHash())
{
m_miner->init(Ethasher::params(_header), _header.seedHash().data());
// TODO: reinit probably won't work when seed changes.
}
if (m_lastHeader != _header)
{
static std::random_device s_eng;
uint64_t tryNonce = (uint64_t)(u64)(m_last = Nonce::random(s_eng));
m_miner->search(_header.headerHash(WithoutNonce).data(), tryNonce, *m_hook);
}
m_lastHeader = _header;
std::this_thread::sleep_for(chrono::milliseconds(_msTimeout));
auto found = m_hook->fetchFound();
if (!found.empty())
{
h256 mixHash; // ?????
return std::make_pair(MineInfo{0.0, 1e99, 0, true}, EthashCL::Proof((Nonce)(u64)found[0], mixHash));
}
return std::make_pair(MineInfo{0.0, 1e99, 0, false}, EthashCL::Proof());
}
#endif
}
}

35
libethcore/ProofOfWork.h

@ -32,6 +32,9 @@
#define FAKE_DAGGER 1
class ethash_cl_miner;
struct ethash_cl_search_hook;
namespace dev
{
namespace eth
@ -46,7 +49,7 @@ struct MineInfo
bool completed = false;
};
class Ethash
class EthashCPU
{
public:
struct Proof
@ -63,6 +66,36 @@ protected:
Nonce m_last;
};
#if ETH_ETHASHCL
class EthashCL
{
public:
struct Proof
{
Nonce nonce;
h256 mixHash;
};
EthashCL();
~EthashCL();
static bool verify(BlockInfo const& _header);
std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false);
static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; }
protected:
Nonce m_last;
BlockInfo m_lastHeader;
Nonce m_mined;
std::unique_ptr<ethash_cl_miner> m_miner;
std::unique_ptr<ethash_cl_search_hook> m_hook;
};
using Ethash = EthashCL;
#else
using Ethash = EthashCPU;
#endif
template <class Evaluator>
class ProofOfWorkEngine: public Evaluator
{

4
libethereum/BlockChain.cpp

@ -610,8 +610,8 @@ void BlockChain::checkConsistency()
static inline unsigned upow(unsigned a, unsigned b) { while (b-- > 0) a *= a; return a; }
static inline unsigned ceilDiv(unsigned n, unsigned d) { return n / (n + d - 1); }
static inline unsigned floorDivPow(unsigned n, unsigned a, unsigned b) { return n / upow(a, b); }
static inline unsigned ceilDivPow(unsigned n, unsigned a, unsigned b) { return ceilDiv(n, upow(a, b)); }
//static inline unsigned floorDivPow(unsigned n, unsigned a, unsigned b) { return n / upow(a, b); }
//static inline unsigned ceilDivPow(unsigned n, unsigned a, unsigned b) { return ceilDiv(n, upow(a, b)); }
// Level 1
// [xxx. ]

4
libethereum/CMakeLists.txt

@ -36,6 +36,10 @@ target_link_libraries(${EXECUTABLE} devcrypto)
target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} secp256k1)
if (ETHASHCL)
target_link_libraries(${EXECUTABLE} ethash-cl)
endif ()
if (CMAKE_COMPILER_IS_MINGW)
target_link_libraries(${EXECUTABLE} ssp shlwapi)
endif()

15
libethereum/Client.cpp

@ -249,13 +249,13 @@ void Client::clearPending()
noteChanged(changeds);
}
unsigned Client::installWatch(h256 _h)
unsigned Client::installWatch(h256 _h, Reaping _r)
{
unsigned ret;
{
Guard l(m_filterLock);
ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0;
m_watches[ret] = ClientWatch(_h);
m_watches[ret] = ClientWatch(_h, _r);
cwatch << "+++" << ret << _h.abridged();
}
auto ch = logs(ret);
@ -268,7 +268,7 @@ unsigned Client::installWatch(h256 _h)
return ret;
}
unsigned Client::installWatch(LogFilter const& _f)
unsigned Client::installWatch(LogFilter const& _f, Reaping _r)
{
h256 h = _f.sha3();
{
@ -279,7 +279,7 @@ unsigned Client::installWatch(LogFilter const& _f)
m_filters.insert(make_pair(h, _f));
}
}
return installWatch(h);
return installWatch(h, _r);
}
bool Client::uninstallWatch(unsigned _i)
@ -411,8 +411,11 @@ void Client::setForceMining(bool _enable)
void Client::setMiningThreads(unsigned _threads)
{
stopMining();
#if ETH_ETHASHCL
unsigned t = 1;
#else
auto t = _threads ? _threads : thread::hardware_concurrency();
#endif
WriteGuard l(x_localMiners);
m_localMiners.clear();
m_localMiners.resize(t);
@ -689,7 +692,7 @@ void Client::doWork()
{
Guard l(m_filterLock);
for (auto key: keysOf(m_watches))
if (chrono::system_clock::now() - m_watches[key].lastPoll > chrono::seconds(20))
if (m_watches[key].lastPoll != chrono::system_clock::time_point::max() && chrono::system_clock::now() - m_watches[key].lastPoll > chrono::seconds(20))
{
toUninstall.push_back(key);
cnote << "GC: Uninstall" << key << "(" << chrono::duration_cast<chrono::seconds>(chrono::system_clock::now() - m_watches[key].lastPoll).count() << "s old)";

14
libethereum/Client.h

@ -92,7 +92,7 @@ static const LocalisedLogEntry InitialChange(SpecialLogEntry, 0);
struct ClientWatch
{
ClientWatch(): lastPoll(std::chrono::system_clock::now()) {}
explicit ClientWatch(h256 _id): id(_id), lastPoll(std::chrono::system_clock::now()) {}
explicit ClientWatch(h256 _id, Reaping _r): id(_id), lastPoll(_r == Reaping::Automatic ? std::chrono::system_clock::now() : std::chrono::system_clock::time_point::max()) {}
h256 id;
LocalisedLogEntries changes = LocalisedLogEntries{ InitialChange };
@ -246,8 +246,8 @@ public:
virtual bytes codeAt(Address _a, int _block) const;
virtual std::map<u256, u256> storageAt(Address _a, int _block) const;
virtual unsigned installWatch(LogFilter const& _filter) override;
virtual unsigned installWatch(h256 _filterId) override;
virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) override;
virtual unsigned installWatch(h256 _filterId, Reaping _r = Reaping::Automatic) override;
virtual bool uninstallWatch(unsigned _watchId) override;
virtual LocalisedLogEntries peekWatch(unsigned _watchId) const;
virtual LocalisedLogEntries checkWatch(unsigned _watchId);
@ -323,12 +323,12 @@ public:
virtual unsigned miningThreads() const { ReadGuard l(x_localMiners); return m_localMiners.size(); }
/// Start mining.
/// NOT thread-safe - call it & stopMining only from a single thread
virtual void startMining() { startWorking(); ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.start(); }
virtual void startMining() { startWorking(); { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.start(); } }
/// Stop mining.
/// NOT thread-safe
virtual void stopMining() { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.stop(); }
virtual void stopMining() { { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.stop(); } }
/// Are we mining now?
virtual bool isMining() { ReadGuard l(x_localMiners); return m_localMiners.size() && m_localMiners[0].isRunning(); }
virtual bool isMining() { { ReadGuard l(x_localMiners); if (!m_localMiners.empty() && m_localMiners[0].isRunning()) return true; } return false; }
/// Check the progress of the mining.
virtual MineProgress miningProgress() const;
/// Get and clear the mining history.
@ -405,8 +405,6 @@ private:
bool m_forceMining = false; ///< Mine even when there are no transactions pending?
bool m_verifyOwnBlocks = true; ///< Should be verify blocks that we mined?
mutable Mutex m_filterLock;
std::map<h256, InstalledFilter> m_filters;
std::map<unsigned, ClientWatch> m_watches;

2
libethereum/ExtVM.cpp

@ -29,7 +29,7 @@ using namespace dev::eth;
bool ExtVM::call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp, Address _myAddressOverride, Address _codeAddressOverride)
{
Executive e(m_s, lastHashes, depth + 1);
if (!e.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin))
if (!e.call(_receiveAddress, _codeAddressOverride, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin))
{
e.go(_onOp);
e.accrueSubState(sub);

10
libethereum/Interface.h

@ -39,6 +39,12 @@ namespace eth
using TransactionHashes = h256s;
enum class Reaping
{
Automatic,
Manual
};
/**
* @brief Main API hub for interfacing with Ethereum.
*/
@ -92,8 +98,8 @@ public:
virtual LocalisedLogEntries logs(LogFilter const& _filter) const = 0;
/// Install, uninstall and query watches.
virtual unsigned installWatch(LogFilter const& _filter) = 0;
virtual unsigned installWatch(h256 _filterId) = 0;
virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) = 0;
virtual unsigned installWatch(h256 _filterId, Reaping _r = Reaping::Automatic) = 0;
virtual bool uninstallWatch(unsigned _watchId) = 0;
LocalisedLogEntries peekWatchSafe(unsigned _watchId) const { try { return peekWatch(_watchId); } catch (...) { return LocalisedLogEntries(); } }
LocalisedLogEntries checkWatchSafe(unsigned _watchId) { try { return checkWatch(_watchId); } catch (...) { return LocalisedLogEntries(); } }

8
libethereum/Miner.cpp

@ -31,15 +31,15 @@ using namespace dev::eth;
Miner::~Miner() {}
LocalMiner::LocalMiner(MinerHost* _host, unsigned _id):
Worker("miner-" + toString(_id)),
m_host(_host)
AsyncMiner(_host, _id),
Worker("miner-" + toString(_id))
{
}
void LocalMiner::setup(MinerHost* _host, unsigned _id)
{
m_host = _host;
setName("miner-" + toString(_id));
AsyncMiner::setup(_host, _id);
setName("miner-" + toString(m_id));
}
void LocalMiner::doWork()

32
libethereum/Miner.h

@ -74,6 +74,32 @@ public:
virtual bytes const& blockData() const = 0;
};
class AsyncMiner: public Miner
{
public:
/// Null constructor.
AsyncMiner(): m_host(nullptr) {}
/// Constructor.
AsyncMiner(MinerHost* _host, unsigned _id = 0): m_host(_host), m_id(_id) {}
/// Setup its basics.
void setup(MinerHost* _host, unsigned _id = 0) { m_host = _host; m_id = _id; }
/// Start mining.
virtual void start() {}
/// Stop mining.
virtual void stop() {}
/// @returns true iff the mining has been start()ed. It may still not be actually mining, depending on the host's turbo() & force().
virtual bool isRunning() { return false; }
protected:
MinerHost* m_host = nullptr; ///< Our host.
unsigned m_id = 0; ///< Our unique id.
};
/**
* @brief Implements Miner.
* To begin mining, use start() & stop(). noteStateChange() can be used to reset the mining and set up the
@ -86,11 +112,11 @@ public:
* @threadsafe
* @todo Signal Miner to restart once with condition variables.
*/
class LocalMiner: public Miner, Worker
class LocalMiner: public AsyncMiner, Worker
{
public:
/// Null constructor.
LocalMiner(): m_host(nullptr) {}
LocalMiner() {}
/// Constructor.
LocalMiner(MinerHost* _host, unsigned _id = 0);
@ -138,8 +164,6 @@ private:
/// Do some work on the mining.
virtual void doWork();
MinerHost* m_host = nullptr; ///< Our host.
enum MiningStatus { Waiting, Preparing, Mining, Mined, Stopping, Stopped };
MiningStatus m_miningStatus = Waiting; ///< TODO: consider mutex/atomic variable.
State m_mineState; ///< The state on which we are mining, generally equivalent to m_postMine.

3
libethereum/State.h

@ -68,7 +68,8 @@ enum class TransactionPriority
class GasPricer
{
public:
GasPricer() {}
GasPricer() = default;
virtual ~GasPricer() = default;
virtual u256 ask(State const&) const = 0;
virtual u256 bid(TransactionPriority _p = TransactionPriority::Medium) const = 0;

6
libevm/VM.cpp

@ -341,8 +341,10 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
break;
case Instruction::CALLDATALOAD:
{
if ((unsigned)m_stack.back() + (uint64_t)31 < _ext.data.size())
m_stack.back() = (u256)*(h256 const*)(_ext.data.data() + (unsigned)m_stack.back());
if ((bigint)m_stack.back() + 31 < _ext.data.size())
m_stack.back() = (u256)*(h256 const*)(_ext.data.data() + (size_t)m_stack.back());
else if ((bigint)m_stack.back() >= _ext.data.size())
m_stack.back() = u256();
else
{
h256 r;

4
libjsqrc/CMakeLists.txt

@ -23,3 +23,7 @@ if (USENPM)
endif()
install( TARGETS jsqrc RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
file(GLOB_RECURSE JSFILES "ethereumjs/lib/*.js")
add_custom_target(aux_js SOURCES ${JSFILES})

80
libjsqrc/ethereumjs/dist/ethereum.js

@ -58,7 +58,7 @@ var isArrayType = function (type) {
*/
var dynamicTypeBytes = function (type, value) {
// TODO: decide what to do with array of strings
if (isArrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length.
if (isArrayType(type) || type === 'bytes')
return f.formatInputInt(value.length);
return "";
};
@ -99,7 +99,7 @@ var formatInput = function (inputs, params) {
toAppendArrayContent += params[i].reduce(function (acc, curr) {
return acc + formatter(curr);
}, "");
else if (inputs[i].type === 'string')
else if (inputs[i].type === 'bytes')
toAppendArrayContent += formatter(params[i]);
else
toAppendConstant += formatter(params[i]);
@ -118,7 +118,7 @@ var formatInput = function (inputs, params) {
* @returns {Number} length of dynamic type, 0 or multiplication of ETH_PADDING (32)
*/
var dynamicBytesLength = function (type) {
if (isArrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length.
if (isArrayType(type) || type === 'bytes')
return c.ETH_PADDING * 2;
return 0;
};
@ -168,7 +168,7 @@ var formatOutput = function (outs, output) {
}
result.push(array);
}
else if (types.prefixedType('string')(outs[i].type)) {
else if (types.prefixedType('bytes')(outs[i].type)) {
dynamicPart = dynamicPart.slice(padding);
result.push(formatter(output.slice(0, padding)));
output = output.slice(padding);
@ -509,8 +509,7 @@ var inputTypes = function () {
return [
{ type: prefixedType('uint'), format: f.formatInputInt },
{ type: prefixedType('int'), format: f.formatInputInt },
{ type: prefixedType('hash'), format: f.formatInputInt },
{ type: prefixedType('string'), format: f.formatInputString },
{ type: prefixedType('bytes'), format: f.formatInputString },
{ type: prefixedType('real'), format: f.formatInputReal },
{ type: prefixedType('ureal'), format: f.formatInputReal },
{ type: namedType('address'), format: f.formatInputInt },
@ -525,8 +524,7 @@ var outputTypes = function () {
return [
{ type: prefixedType('uint'), format: f.formatOutputUInt },
{ type: prefixedType('int'), format: f.formatOutputInt },
{ type: prefixedType('hash'), format: f.formatOutputHash },
{ type: prefixedType('string'), format: f.formatOutputString },
{ type: prefixedType('bytes'), format: f.formatOutputString },
{ type: prefixedType('real'), format: f.formatOutputReal },
{ type: prefixedType('ureal'), format: f.formatOutputUReal },
{ type: namedType('address'), format: f.formatOutputAddress },
@ -1087,10 +1085,12 @@ module.exports = {
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* Gav Wood <g@ethdev.com>
* @date 2014
*/
var version = require('../version.json');
var net = require('./web3/net');
var eth = require('./web3/eth');
var db = require('./web3/db');
@ -1103,11 +1103,14 @@ var requestManager = require('./web3/requestmanager');
var c = require('./utils/config');
/// @returns an array of objects describing web3 api methods
var web3Methods = function () {
return [
{ name: 'sha3', call: 'web3_sha3' }
];
};
var web3Methods = [
{ name: 'sha3', call: 'web3_sha3', inputFormatter: utils.toHex },
];
var web3Properties = [
{ name: 'version.client', getter: 'web3_clientVersion' },
{ name: 'version.network', getter: 'net_version' }
];
/// creates methods in a given object based on method description on input
/// setups api calls for these methods
@ -1167,7 +1170,9 @@ var setupMethods = function (obj, methods) {
/// setups api calls for these properties
var setupProperties = function (obj, properties) {
properties.forEach(function (property) {
var proto = {};
var objectProperties = property.name.split('.'),
proto = {};
proto.get = function () {
// show deprecated warning
@ -1197,7 +1202,14 @@ var setupProperties = function (obj, properties) {
}
proto.enumerable = !property.newProperty;
Object.defineProperty(obj, property.name, proto);
if(objectProperties.length > 1) {
if(!obj[objectProperties[0]])
obj[objectProperties[0]] = {};
Object.defineProperty(obj[objectProperties[0]], objectProperties[1], proto);
} else
Object.defineProperty(obj, property.name, proto);
});
};
@ -1227,6 +1239,11 @@ var shhWatch = {
/// setups web3 object, and it's in-browser executed methods
var web3 = {
version: {
api: version.version
},
manager: requestManager(),
providers: {},
@ -1334,7 +1351,8 @@ Object.defineProperty(web3.eth, 'defaultBlock', {
/// setups all api methods
setupMethods(web3, web3Methods());
setupMethods(web3, web3Methods);
setupProperties(web3, web3Properties);
setupMethods(web3.net, net.methods);
setupProperties(web3.net, net.properties);
setupMethods(web3.eth, eth.methods);
@ -1347,7 +1365,7 @@ setupMethods(shhWatch, watches.shh());
module.exports = web3;
},{"./solidity/formatters":2,"./utils/config":4,"./utils/utils":5,"./web3/db":8,"./web3/eth":9,"./web3/filter":11,"./web3/net":15,"./web3/requestmanager":17,"./web3/shh":18,"./web3/watches":20}],7:[function(require,module,exports){
},{"../version.json":21,"./solidity/formatters":2,"./utils/config":4,"./utils/utils":5,"./web3/db":8,"./web3/eth":9,"./web3/filter":11,"./web3/net":15,"./web3/requestmanager":17,"./web3/shh":18,"./web3/watches":20}],7:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -1615,13 +1633,14 @@ module.exports = contract;
* @date 2015
*/
/// @returns an array of objects describing web3.db api methods
var methods = function () {
return [
{ name: 'put', call: 'db_put' },
{ name: 'get', call: 'db_get' },
{ name: 'putString', call: 'db_putString' },
{ name: 'getString', call: 'db_getString' }
{ name: 'putString', call: 'db_putString'},
{ name: 'getString', call: 'db_getString'},
{ name: 'putHex', call: 'db_putHex'},
{ name: 'getHex', call: 'db_getHex'}
];
};
@ -1649,6 +1668,7 @@ module.exports = {
/** @file eth.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* @date 2015
*/
@ -1706,10 +1726,9 @@ var uncleCountCall = function (args) {
var methods = [
{ name: 'getBalance', call: 'eth_getBalance', addDefaultblock: 2,
outputFormatter: formatters.convertToBigNumber},
{ name: 'getStorage', call: 'eth_getStorage', addDefaultblock: 2},
{ name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3,
inputFormatter: utils.toHex},
{ name: 'getData', call: 'eth_getData', addDefaultblock: 2},
{ name: 'getCode', call: 'eth_getCode', addDefaultblock: 2},
{ name: 'getBlock', call: blockCall,
outputFormatter: formatters.outputBlockFormatter,
inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},
@ -1734,7 +1753,7 @@ var methods = [
inputFormatter: formatters.inputTransactionFormatter },
{ name: 'call', call: 'eth_call', addDefaultblock: 2,
inputFormatter: formatters.inputCallFormatter },
{ name: 'compile.solidity', call: 'eth_compileSolidity', inputFormatter: utils.toHex },
{ name: 'compile.solidity', call: 'eth_compileSolidity' },
{ name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex },
{ name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex },
{ name: 'flush', call: 'eth_flush' },
@ -1744,7 +1763,7 @@ var methods = [
{ name: 'stateAt', call: 'eth_stateAt', newMethod: 'eth.getStorageAt' },
{ name: 'storageAt', call: 'eth_storageAt', newMethod: 'eth.getStorage' },
{ name: 'countAt', call: 'eth_countAt', newMethod: 'eth.getTransactionCount' },
{ name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getData' },
{ name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getCode' },
{ name: 'transact', call: 'eth_transact', newMethod: 'eth.sendTransaction' },
{ name: 'block', call: blockCall, newMethod: 'eth.getBlock' },
{ name: 'transaction', call: transactionFromBlockCall, newMethod: 'eth.getTransaction' },
@ -1941,6 +1960,7 @@ module.exports = {
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* Gav Wood <g@ethdev.com>
* @date 2014
*/
@ -2322,6 +2342,7 @@ module.exports = {
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* @date 2014
*/
@ -2337,7 +2358,6 @@ var HttpProvider = function (host) {
HttpProvider.prototype.send = function (payload, callback) {
var request = new XMLHttpRequest();
request.open('POST', this.host, false);
// ASYNC
if(typeof callback === 'function') {
@ -2539,6 +2559,7 @@ module.exports = QtSyncProvider;
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* Gav Wood <g@ethdev.com>
* @date 2014
*/
@ -2609,7 +2630,6 @@ var requestManager = function() {
var result = provider.send(payload);
if (!jsonrpc.isValidResponse(result)) {
console.log(result);
if(typeof result === 'object' && result.error && result.error.message)
console.error(result.error.message);
return null;
@ -2819,6 +2839,10 @@ module.exports = {
};
},{}],21:[function(require,module,exports){
module.exports={
"version": "0.1.3"
}
},{}],"web3":[function(require,module,exports){
var web3 = require('./lib/web3');
web3.providers.HttpProvider = require('./lib/web3/httpprovider');
@ -2831,4 +2855,4 @@ module.exports = web3;
},{"./lib/solidity/abi":1,"./lib/web3":6,"./lib/web3/contract":7,"./lib/web3/httpprovider":13,"./lib/web3/qtsync":16}]},{},["web3"])
//# sourceMappingURL=ethereum.js.map
//# sourceMappingURL=ethereum.js.map

20
libjsqrc/ethereumjs/dist/ethereum.js.map

File diff suppressed because one or more lines are too long

2
libjsqrc/ethereumjs/dist/ethereum.min.js

File diff suppressed because one or more lines are too long

16
libjsqrc/ethereumjs/gulpfile.js

@ -2,6 +2,7 @@
'use strict';
var version = require('./version.json');
var path = require('path');
var del = require('del');
@ -14,6 +15,7 @@ var source = require('vinyl-source-stream');
var exorcist = require('exorcist');
var bower = require('bower');
var streamify = require('gulp-streamify');
var replace = require('gulp-replace');
var DEST = './dist/';
var src = 'index';
@ -26,6 +28,15 @@ var browserifyOptions = {
bundleExternal: false
};
gulp.task('versionReplace', function(){
gulp.src(['./package.json'])
.pipe(replace(/\"version\"\: \"(.{5})\"/, '"version": "'+ version.version + '"'))
.pipe(gulp.dest('./'));
gulp.src(['./package.js'])
.pipe(replace(/version\: \'(.{5})\'/, "version: '"+ version.version + "'"))
.pipe(gulp.dest('./'));
});
gulp.task('bower', function(cb){
bower.commands.install().on('end', function (installed){
console.log(installed);
@ -60,6 +71,9 @@ gulp.task('watch', function() {
gulp.watch(['./lib/*.js'], ['lint', 'build']);
});
gulp.task('dev', ['bower', 'lint', 'build']);
gulp.task('dev', ['versionReplace','bower', 'lint', 'build']);
gulp.task('default', ['dev']);
gulp.task('version', ['versionReplace']);

8
libjsqrc/ethereumjs/lib/solidity/abi.js

@ -57,7 +57,7 @@ var isArrayType = function (type) {
*/
var dynamicTypeBytes = function (type, value) {
// TODO: decide what to do with array of strings
if (isArrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length.
if (isArrayType(type) || type === 'bytes')
return f.formatInputInt(value.length);
return "";
};
@ -98,7 +98,7 @@ var formatInput = function (inputs, params) {
toAppendArrayContent += params[i].reduce(function (acc, curr) {
return acc + formatter(curr);
}, "");
else if (inputs[i].type === 'string')
else if (inputs[i].type === 'bytes')
toAppendArrayContent += formatter(params[i]);
else
toAppendConstant += formatter(params[i]);
@ -117,7 +117,7 @@ var formatInput = function (inputs, params) {
* @returns {Number} length of dynamic type, 0 or multiplication of ETH_PADDING (32)
*/
var dynamicBytesLength = function (type) {
if (isArrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length.
if (isArrayType(type) || type === 'bytes')
return c.ETH_PADDING * 2;
return 0;
};
@ -167,7 +167,7 @@ var formatOutput = function (outs, output) {
}
result.push(array);
}
else if (types.prefixedType('string')(outs[i].type)) {
else if (types.prefixedType('bytes')(outs[i].type)) {
dynamicPart = dynamicPart.slice(padding);
result.push(formatter(output.slice(0, padding)));
output = output.slice(padding);

6
libjsqrc/ethereumjs/lib/solidity/types.js

@ -45,8 +45,7 @@ var inputTypes = function () {
return [
{ type: prefixedType('uint'), format: f.formatInputInt },
{ type: prefixedType('int'), format: f.formatInputInt },
{ type: prefixedType('hash'), format: f.formatInputInt },
{ type: prefixedType('string'), format: f.formatInputString },
{ type: prefixedType('bytes'), format: f.formatInputString },
{ type: prefixedType('real'), format: f.formatInputReal },
{ type: prefixedType('ureal'), format: f.formatInputReal },
{ type: namedType('address'), format: f.formatInputInt },
@ -61,8 +60,7 @@ var outputTypes = function () {
return [
{ type: prefixedType('uint'), format: f.formatOutputUInt },
{ type: prefixedType('int'), format: f.formatOutputInt },
{ type: prefixedType('hash'), format: f.formatOutputHash },
{ type: prefixedType('string'), format: f.formatOutputString },
{ type: prefixedType('bytes'), format: f.formatOutputString },
{ type: prefixedType('real'), format: f.formatOutputReal },
{ type: prefixedType('ureal'), format: f.formatOutputUReal },
{ type: namedType('address'), format: f.formatOutputAddress },

36
libjsqrc/ethereumjs/lib/web3.js

@ -19,10 +19,12 @@
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* Gav Wood <g@ethdev.com>
* @date 2014
*/
var version = require('../version.json');
var net = require('./web3/net');
var eth = require('./web3/eth');
var db = require('./web3/db');
@ -35,11 +37,14 @@ var requestManager = require('./web3/requestmanager');
var c = require('./utils/config');
/// @returns an array of objects describing web3 api methods
var web3Methods = function () {
return [
{ name: 'sha3', call: 'web3_sha3' }
];
};
var web3Methods = [
{ name: 'sha3', call: 'web3_sha3', inputFormatter: utils.toHex },
];
var web3Properties = [
{ name: 'version.client', getter: 'web3_clientVersion' },
{ name: 'version.network', getter: 'net_version' }
];
/// creates methods in a given object based on method description on input
/// setups api calls for these methods
@ -99,7 +104,9 @@ var setupMethods = function (obj, methods) {
/// setups api calls for these properties
var setupProperties = function (obj, properties) {
properties.forEach(function (property) {
var proto = {};
var objectProperties = property.name.split('.'),
proto = {};
proto.get = function () {
// show deprecated warning
@ -129,7 +136,14 @@ var setupProperties = function (obj, properties) {
}
proto.enumerable = !property.newProperty;
Object.defineProperty(obj, property.name, proto);
if(objectProperties.length > 1) {
if(!obj[objectProperties[0]])
obj[objectProperties[0]] = {};
Object.defineProperty(obj[objectProperties[0]], objectProperties[1], proto);
} else
Object.defineProperty(obj, property.name, proto);
});
};
@ -159,6 +173,11 @@ var shhWatch = {
/// setups web3 object, and it's in-browser executed methods
var web3 = {
version: {
api: version.version
},
manager: requestManager(),
providers: {},
@ -266,7 +285,8 @@ Object.defineProperty(web3.eth, 'defaultBlock', {
/// setups all api methods
setupMethods(web3, web3Methods());
setupMethods(web3, web3Methods);
setupProperties(web3, web3Properties);
setupMethods(web3.net, net.methods);
setupProperties(web3.net, net.properties);
setupMethods(web3.eth, eth.methods);

9
libjsqrc/ethereumjs/lib/web3/db.js

@ -20,13 +20,14 @@
* @date 2015
*/
/// @returns an array of objects describing web3.db api methods
var methods = function () {
return [
{ name: 'put', call: 'db_put' },
{ name: 'get', call: 'db_get' },
{ name: 'putString', call: 'db_putString' },
{ name: 'getString', call: 'db_getString' }
{ name: 'putString', call: 'db_putString'},
{ name: 'getString', call: 'db_getString'},
{ name: 'putHex', call: 'db_putHex'},
{ name: 'getHex', call: 'db_getHex'}
];
};

8
libjsqrc/ethereumjs/lib/web3/eth.js

@ -17,6 +17,7 @@
/** @file eth.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* @date 2015
*/
@ -74,10 +75,9 @@ var uncleCountCall = function (args) {
var methods = [
{ name: 'getBalance', call: 'eth_getBalance', addDefaultblock: 2,
outputFormatter: formatters.convertToBigNumber},
{ name: 'getStorage', call: 'eth_getStorage', addDefaultblock: 2},
{ name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3,
inputFormatter: utils.toHex},
{ name: 'getData', call: 'eth_getData', addDefaultblock: 2},
{ name: 'getCode', call: 'eth_getCode', addDefaultblock: 2},
{ name: 'getBlock', call: blockCall,
outputFormatter: formatters.outputBlockFormatter,
inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},
@ -102,7 +102,7 @@ var methods = [
inputFormatter: formatters.inputTransactionFormatter },
{ name: 'call', call: 'eth_call', addDefaultblock: 2,
inputFormatter: formatters.inputCallFormatter },
{ name: 'compile.solidity', call: 'eth_compileSolidity', inputFormatter: utils.toHex },
{ name: 'compile.solidity', call: 'eth_compileSolidity' },
{ name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex },
{ name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex },
{ name: 'flush', call: 'eth_flush' },
@ -112,7 +112,7 @@ var methods = [
{ name: 'stateAt', call: 'eth_stateAt', newMethod: 'eth.getStorageAt' },
{ name: 'storageAt', call: 'eth_storageAt', newMethod: 'eth.getStorage' },
{ name: 'countAt', call: 'eth_countAt', newMethod: 'eth.getTransactionCount' },
{ name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getData' },
{ name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getCode' },
{ name: 'transact', call: 'eth_transact', newMethod: 'eth.sendTransaction' },
{ name: 'block', call: blockCall, newMethod: 'eth.getBlock' },
{ name: 'transaction', call: transactionFromBlockCall, newMethod: 'eth.getTransaction' },

1
libjsqrc/ethereumjs/lib/web3/filter.js

@ -19,6 +19,7 @@
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* Gav Wood <g@ethdev.com>
* @date 2014
*/

2
libjsqrc/ethereumjs/lib/web3/httpprovider.js

@ -18,6 +18,7 @@
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* @date 2014
*/
@ -33,7 +34,6 @@ var HttpProvider = function (host) {
HttpProvider.prototype.send = function (payload, callback) {
var request = new XMLHttpRequest();
request.open('POST', this.host, false);
// ASYNC
if(typeof callback === 'function') {

2
libjsqrc/ethereumjs/lib/web3/requestmanager.js

@ -19,6 +19,7 @@
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* Gav Wood <g@ethdev.com>
* @date 2014
*/
@ -89,7 +90,6 @@ var requestManager = function() {
var result = provider.send(payload);
if (!jsonrpc.isValidResponse(result)) {
console.log(result);
if(typeof result === 'object' && result.error && result.error.message)
console.error(result.error.message);
return null;

2
libjsqrc/ethereumjs/package.js

@ -1,7 +1,7 @@
/* jshint ignore:start */
Package.describe({
name: 'ethereum:js',
version: '0.1.2',
version: '0.1.3',
summary: 'Ethereum JavaScript API, middleware to talk to a ethreum node over RPC',
git: 'https://github.com/ethereum/ethereum.js',
// By default, Meteor will default to using README.md for documentation.

7
libjsqrc/ethereumjs/package.json

@ -1,7 +1,7 @@
{
"name": "ethereum.js",
"namespace": "ethereum",
"version": "0.1.2",
"version": "0.1.3",
"description": "Ethereum JavaScript API, middleware to talk to a ethreum node over RPC",
"main": "./index.js",
"directories": {
@ -23,6 +23,7 @@
"gulp": ">=3.4.0",
"gulp-jshint": ">=1.5.0",
"gulp-rename": ">=1.2.0",
"gulp-replace": "^0.5.3",
"gulp-streamify": "0.0.5",
"gulp-uglify": ">=1.0.0",
"istanbul": "^0.3.5",
@ -89,8 +90,8 @@
},
{
"name": "Fabian Vogelsteller",
"email": "fabian@ethdev.com",
"homepage": "https://github.com/frozeman"
"email": "fabian@frozeman.de",
"homepage": "http://frozeman.de"
}
],
"license": "LGPL-3.0"

66
libjsqrc/ethereumjs/test/abi.inputParser.js

@ -227,56 +227,6 @@ describe('abi', function() {
});
it('should parse input hash', function() {
// given
var d = clone(description);
d[0].inputs = [
{ type: "hash" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1");
});
it('should parse input hash256', function() {
// given
var d = clone(description);
d[0].inputs = [
{ type: "hash256" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1");
});
it('should parse input hash160', function() {
// given
var d = clone(description);
d[0].inputs = [
{ type: "hash160" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1");
});
it('should parse input address', function () {
// given
@ -294,13 +244,13 @@ describe('abi', function() {
});
it('should parse input string', function () {
it('should parse input fixed bytes type', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "string" }
{ type: "bytes" }
];
// when
@ -318,14 +268,14 @@ describe('abi', function() {
);
});
it('should parse input int followed by a string', function () {
it('should parse input int followed by a fixed bytes type', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "int" },
{ type: "string" }
{ type: "bytes" }
];
// when
@ -340,13 +290,13 @@ describe('abi', function() {
);
});
it('should parse input string followed by an int', function () {
it('should parse input fixed bytes type followed by an int', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "string" },
{ type: "bytes" },
{ type: "int" }
];
@ -391,8 +341,8 @@ describe('abi', function() {
},{
name: "test2",
type: "function",
inputs: [{ type: "string" }],
outputs: [{ type: "string" }]
inputs: [{ type: "bytes" }],
outputs: [{ type: "bytes" }]
}];
// when

72
libjsqrc/ethereumjs/test/abi.outputParser.js

@ -21,13 +21,13 @@ var description = [{
describe('abi', function() {
describe('outputParser', function() {
it('should parse output string', function() {
it('should parse output fixed bytes type', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: "string" }
{ type: "bytes" }
];
// when
@ -181,64 +181,6 @@ describe('abi', function() {
assert.equal(parser.test("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16);
});
it('should parse output hash', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'hash' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(
parser.test("0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0],
"0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"
);
});
it('should parse output hash256', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'hash256' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(
parser.test("0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0],
"0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"
);
});
it('should parse output hash160', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'hash160' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(
parser.test("0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0],
"0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"
);
// TODO shouldnt' the expected hash be shorter?
});
it('should parse output address', function() {
// given
@ -317,14 +259,14 @@ describe('abi', function() {
});
it('should parse multiple output strings', function() {
it('should parse multiple output fixed bytes type', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: "string" },
{ type: "string" }
{ type: "bytes" },
{ type: "bytes" }
];
// when
@ -380,8 +322,8 @@ describe('abi', function() {
},{
name: "test2",
type: "function",
inputs: [{ type: "string" }],
outputs: [{ type: "string" }]
inputs: [{ type: "bytes" }],
outputs: [{ type: "bytes" }]
}];
// when

4
libjsqrc/ethereumjs/test/db.methods.js

@ -5,8 +5,8 @@ var u = require('./test.utils.js');
describe('web3', function() {
describe('db', function() {
u.methodExists(web3.db, 'put');
u.methodExists(web3.db, 'get');
u.methodExists(web3.db, 'putHex');
u.methodExists(web3.db, 'getHex');
u.methodExists(web3.db, 'putString');
u.methodExists(web3.db, 'getString');
});

2
libjsqrc/ethereumjs/test/eth.methods.js

@ -8,7 +8,7 @@ describe('web3', function() {
u.methodExists(web3.eth, 'getStorageAt');
u.methodExists(web3.eth, 'getStorage');
u.methodExists(web3.eth, 'getTransactionCount');
u.methodExists(web3.eth, 'getData');
u.methodExists(web3.eth, 'getCode');
u.methodExists(web3.eth, 'sendTransaction');
u.methodExists(web3.eth, 'call');
u.methodExists(web3.eth, 'getBlock');

3
libjsqrc/ethereumjs/version.json

@ -0,0 +1,3 @@
{
"version": "0.1.3"
}

2
libsolidity/AST.cpp

@ -671,7 +671,7 @@ void IndexAccess::checkTypeRequirements()
BOOST_THROW_EXCEPTION(createTypeError("Index expression cannot be omitted."));
m_index->expectType(IntegerType(256));
if (type.isByteArray())
m_type = make_shared<IntegerType>(8, IntegerType::Modifier::Hash);
m_type = make_shared<FixedBytesType>(1);
else
m_type = type.getBaseType();
m_isLValue = type.getLocation() != ArrayType::Location::CallData;

1
libsolidity/ArrayUtils.cpp

@ -125,6 +125,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, true, true, false);
else
solAssert(false, "Copying of unknown type requested: " + sourceBaseType->toString());
solAssert(2 + sourceBaseType->getSizeOnStack() <= 16, "Stack too deep.");
m_context << eth::dupInstruction(2 + sourceBaseType->getSizeOnStack());
StorageItem(m_context, *targetBaseType).storeValue(*sourceBaseType, SourceLocation(), true);
}

2
libsolidity/Compiler.cpp

@ -228,6 +228,7 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
{
// Retrieve data start offset by adding length to start offset of previous dynamic type
unsigned stackDepth = m_context.getStackHeight() - stackHeightOfPreviousDynamicArgument;
solAssert(stackDepth <= 16, "Stack too deep.");
m_context << eth::dupInstruction(stackDepth) << eth::dupInstruction(stackDepth);
ArrayUtils(m_context).convertLengthToSize(*previousDynamicType, true);
m_context << eth::Instruction::ADD;
@ -359,6 +360,7 @@ bool Compiler::visit(FunctionDefinition const& _function)
stackLayout.push_back(i);
stackLayout += vector<int>(c_localVariablesSize, -1);
solAssert(stackLayout.size() <= 17, "Stack too deep.");
while (stackLayout.back() != int(stackLayout.size() - 1))
if (stackLayout.back() < 0)
{

8
libsolidity/CompilerStack.cpp

@ -41,14 +41,14 @@ namespace solidity
{
const map<string, string> StandardSources = map<string, string>{
{"coin", R"(import "CoinReg";import "Config";import "configUser";contract coin is configUser{function coin(string3 name, uint denom) {CoinReg(Config(configAddr()).lookup(3)).register(name, denom);}})"},
{"coin", R"(import "CoinReg";import "Config";import "configUser";contract coin is configUser{function coin(bytes3 name, uint denom) {CoinReg(Config(configAddr()).lookup(3)).register(name, denom);}})"},
{"Coin", R"(contract Coin{function isApprovedFor(address _target,address _proxy)constant returns(bool _r){}function isApproved(address _proxy)constant returns(bool _r){}function sendCoinFrom(address _from,uint256 _val,address _to){}function coinBalanceOf(address _a)constant returns(uint256 _r){}function sendCoin(uint256 _val,address _to){}function coinBalance()constant returns(uint256 _r){}function approve(address _a){}})"},
{"CoinReg", R"(contract CoinReg{function count()constant returns(uint256 r){}function info(uint256 i)constant returns(address addr,string3 name,uint256 denom){}function register(string3 name,uint256 denom){}function unregister(){}})"},
{"CoinReg", R"(contract CoinReg{function count()constant returns(uint256 r){}function info(uint256 i)constant returns(address addr,bytes3 name,uint256 denom){}function register(bytes3 name,uint256 denom){}function unregister(){}})"},
{"configUser", R"(contract configUser{function configAddr()constant returns(address a){ return 0xc6d9d2cd449a754c494264e1809c50e34d64562b;}})"},
{"Config", R"(contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}})"},
{"mortal", R"(import "owned";contract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }})"},
{"named", R"(import "Config";import "NameReg";import "configUser";contract named is configUser {function named(string32 name) {NameReg(Config(configAddr()).lookup(1)).register(name);}})"},
{"NameReg", R"(contract NameReg{function register(string32 name){}function addressOf(string32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(string32 name){}})"},
{"named", R"(import "Config";import "NameReg";import "configUser";contract named is configUser {function named(bytes32 name) {NameReg(Config(configAddr()).lookup(1)).register(name);}})"},
{"NameReg", R"(contract NameReg{function register(bytes32 name){}function addressOf(bytes32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(bytes32 name){}})"},
{"owned", R"(contract owned{function owned(){owner = msg.sender;}modifier onlyowner(){if(msg.sender==owner)_}address owner;})"},
{"service", R"(import "Config";import "configUser";contract service is configUser{function service(uint _n){Config(configAddr()).register(_n, this);}})"},
{"std", R"(import "owned";import "mortal";import "Config";import "configUser";import "NameReg";import "named";)"}

8
libsolidity/CompilerUtils.cpp

@ -138,6 +138,7 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable)
{
unsigned const stackPosition = m_context.baseToCurrentStackOffset(m_context.getBaseStackOffsetOfVariable(_variable));
unsigned const size = _variable.getType()->getSizeOnStack();
solAssert(stackPosition >= size, "Variable size and position mismatch.");
// move variable starting from its top end in the stack
if (stackPosition - size + 1 > 16)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_variable.getLocation())
@ -148,8 +149,7 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable)
void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
{
if (_stackDepth > 16)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Stack too deep."));
solAssert(_stackDepth <= 16, "Stack too deep.");
for (unsigned i = 0; i < _itemSize; ++i)
m_context << eth::dupInstruction(_stackDepth);
}
@ -178,7 +178,7 @@ void CompilerUtils::computeHashStatic(Type const& _type, bool _padToWordBoundari
unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries)
{
unsigned numBytes = _type.getCalldataEncodedSize(_padToWordBoundaries);
bool leftAligned = _type.getCategory() == Type::Category::String;
bool leftAligned = _type.getCategory() == Type::Category::FixedBytes;
if (numBytes == 0)
m_context << eth::Instruction::POP << u256(0);
else
@ -202,7 +202,7 @@ unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCallda
unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) const
{
unsigned numBytes = _type.getCalldataEncodedSize(_padToWordBoundaries);
bool leftAligned = _type.getCategory() == Type::Category::String;
bool leftAligned = _type.getCategory() == Type::Category::FixedBytes;
if (numBytes == 0)
m_context << eth::Instruction::POP;
else

70
libsolidity/ExpressionCompiler.cpp

@ -123,23 +123,25 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
Type::Category stackTypeCategory = _typeOnStack.getCategory();
Type::Category targetTypeCategory = _targetType.getCategory();
if (stackTypeCategory == Type::Category::String)
switch (stackTypeCategory)
{
StaticStringType const& typeOnStack = dynamic_cast<StaticStringType const&>(_typeOnStack);
case Type::Category::FixedBytes:
{
FixedBytesType const& typeOnStack = dynamic_cast<FixedBytesType const&>(_typeOnStack);
if (targetTypeCategory == Type::Category::Integer)
{
// conversion from string to hash. no need to clean the high bit
// conversion from bytes to integer. no need to clean the high bit
// only to shift right because of opposite alignment
IntegerType const& targetIntegerType = dynamic_cast<IntegerType const&>(_targetType);
solAssert(targetIntegerType.isHash(), "Only conversion between String and Hash is allowed.");
solAssert(targetIntegerType.getNumBits() == typeOnStack.getNumBytes() * 8, "The size should be the same.");
m_context << (u256(1) << (256 - typeOnStack.getNumBytes() * 8)) << eth::Instruction::SWAP1 << eth::Instruction::DIV;
if (targetIntegerType.getNumBits() < typeOnStack.getNumBytes() * 8)
appendTypeConversion(IntegerType(typeOnStack.getNumBytes() * 8), _targetType, _cleanupNeeded);
}
else
{
// clear lower-order bytes for conversion to shorter strings - we always clean
solAssert(targetTypeCategory == Type::Category::String, "Invalid type conversion requested.");
StaticStringType const& targetType = dynamic_cast<StaticStringType const&>(_targetType);
// clear lower-order bytes for conversion to shorter bytes - we always clean
solAssert(targetTypeCategory == Type::Category::FixedBytes, "Invalid type conversion requested.");
FixedBytesType const& targetType = dynamic_cast<FixedBytesType const&>(_targetType);
if (targetType.getNumBytes() < typeOnStack.getNumBytes())
{
if (targetType.getNumBytes() == 0)
@ -151,22 +153,24 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
}
}
}
else if (stackTypeCategory == Type::Category::Enum)
solAssert(targetTypeCategory == Type::Category::Integer ||
targetTypeCategory == Type::Category::Enum, "");
else if (stackTypeCategory == Type::Category::Integer ||
stackTypeCategory == Type::Category::Contract ||
stackTypeCategory == Type::Category::IntegerConstant)
{
if (targetTypeCategory == Type::Category::String && stackTypeCategory == Type::Category::Integer)
break;
case Type::Category::Enum:
solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Enum, "");
break;
case Type::Category::Integer:
case Type::Category::Contract:
case Type::Category::IntegerConstant:
if (targetTypeCategory == Type::Category::FixedBytes)
{
// conversion from hash to string. no need to clean the high bit
solAssert(stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::IntegerConstant,
"Invalid conversion to FixedBytesType requested.");
// conversion from bytes to string. no need to clean the high bit
// only to shift left because of opposite alignment
StaticStringType const& targetStringType = dynamic_cast<StaticStringType const&>(_targetType);
IntegerType const& typeOnStack = dynamic_cast<IntegerType const&>(_typeOnStack);
solAssert(typeOnStack.isHash(), "Only conversion between String and Hash is allowed.");
solAssert(typeOnStack.getNumBits() == targetStringType.getNumBytes() * 8, "The size should be the same.");
m_context << (u256(1) << (256 - typeOnStack.getNumBits())) << eth::Instruction::MUL;
FixedBytesType const& targetBytesType = dynamic_cast<FixedBytesType const&>(_targetType);
if (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack))
if (targetBytesType.getNumBytes() * 8 > typeOnStack->getNumBits())
appendHighBitsCleanup(*typeOnStack);
m_context << (u256(1) << (256 - targetBytesType.getNumBytes() * 8)) << eth::Instruction::MUL;
}
else if (targetTypeCategory == Type::Category::Enum)
// just clean
@ -176,7 +180,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Contract, "");
IntegerType addressType(0, IntegerType::Modifier::Address);
IntegerType const& targetType = targetTypeCategory == Type::Category::Integer
? dynamic_cast<IntegerType const&>(_targetType) : addressType;
? dynamic_cast<IntegerType const&>(_targetType) : addressType;
if (stackTypeCategory == Type::Category::IntegerConstant)
{
IntegerConstantType const& constType = dynamic_cast<IntegerConstantType const&>(_typeOnStack);
@ -188,7 +192,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
else
{
IntegerType const& typeOnStack = stackTypeCategory == Type::Category::Integer
? dynamic_cast<IntegerType const&>(_typeOnStack) : addressType;
? dynamic_cast<IntegerType const&>(_typeOnStack) : addressType;
// Widening: clean up according to source type width
// Non-widening and force: clean up according to target type bits
if (targetType.getNumBits() > typeOnStack.getNumBits())
@ -197,10 +201,12 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
appendHighBitsCleanup(targetType);
}
}
}
else if (_typeOnStack != _targetType)
break;
default:
// All other types should not be convertible to non-equal types.
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid type conversion requested."));
solAssert(_typeOnStack == _targetType, "Invalid type conversion requested.");
break;
}
}
bool ExpressionCompiler::visit(Assignment const& _assignment)
@ -227,9 +233,12 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
m_currentLValue->retrieveValue(_assignment.getLocation(), true);
appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType());
if (lvalueSize > 0)
{
solAssert(itemSize + lvalueSize <= 16, "Stack too deep.");
// value [lvalue_ref] updated_value
for (unsigned i = 0; i < itemSize; ++i)
m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP;
}
}
m_currentLValue->storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation());
m_currentLValue.reset();
@ -551,10 +560,13 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
case Location::SHA256:
case Location::RIPEMD160:
{
_functionCall.getExpression().accept(*this);
static const map<Location, u256> contractAddresses{{Location::ECRecover, 1},
{Location::SHA256, 2},
{Location::RIPEMD160, 3}};
m_context << contractAddresses.find(function.getLocation())->second;
for (unsigned i = function.getSizeOnStack(); i > 0; --i)
m_context << eth::swapInstruction(i);
appendExternalFunctionCall(function, arguments, true);
break;
}
@ -775,7 +787,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
// no lvalue, just retrieve the value
m_context
<< eth::Instruction::ADD << eth::Instruction::CALLDATALOAD
<< u256(0) << eth::Instruction::BYTE;
<< ((u256(0xff) << (256 - 8))) << eth::Instruction::AND;
break;
case ArrayType::Location::Memory:
solAssert(false, "Memory lvalues not yet implemented.");
@ -870,7 +882,7 @@ void ExpressionCompiler::endVisit(Literal const& _literal)
{
case Type::Category::IntegerConstant:
case Type::Category::Bool:
case Type::Category::String:
case Type::Category::FixedBytes:
m_context << _literal.getType()->literalValue(&_literal);
break;
default:

18
libsolidity/GlobalContext.cpp

@ -41,23 +41,23 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{make_shared<
make_shared<MagicVariableDeclaration>("suicide",
make_shared<FunctionType>(strings{"address"}, strings{}, FunctionType::Location::Suicide)),
make_shared<MagicVariableDeclaration>("sha3",
make_shared<FunctionType>(strings(), strings{"hash"}, FunctionType::Location::SHA3, true)),
make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Location::SHA3, true)),
make_shared<MagicVariableDeclaration>("log0",
make_shared<FunctionType>(strings{"hash"},strings{}, FunctionType::Location::Log0)),
make_shared<FunctionType>(strings{"bytes32"}, strings{}, FunctionType::Location::Log0)),
make_shared<MagicVariableDeclaration>("log1",
make_shared<FunctionType>(strings{"hash", "hash"},strings{}, FunctionType::Location::Log1)),
make_shared<FunctionType>(strings{"bytes32", "bytes32"}, strings{}, FunctionType::Location::Log1)),
make_shared<MagicVariableDeclaration>("log2",
make_shared<FunctionType>(strings{"hash", "hash", "hash"},strings{}, FunctionType::Location::Log2)),
make_shared<FunctionType>(strings{"bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Location::Log2)),
make_shared<MagicVariableDeclaration>("log3",
make_shared<FunctionType>(strings{"hash", "hash", "hash", "hash"},strings{}, FunctionType::Location::Log3)),
make_shared<FunctionType>(strings{"bytes32", "bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Location::Log3)),
make_shared<MagicVariableDeclaration>("log4",
make_shared<FunctionType>(strings{"hash", "hash", "hash", "hash", "hash"},strings{}, FunctionType::Location::Log4)),
make_shared<FunctionType>(strings{"bytes32", "bytes32", "bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Location::Log4)),
make_shared<MagicVariableDeclaration>("sha256",
make_shared<FunctionType>(strings(), strings{"hash"}, FunctionType::Location::SHA256, true)),
make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Location::SHA256, true)),
make_shared<MagicVariableDeclaration>("ecrecover",
make_shared<FunctionType>(strings{"hash", "hash8", "hash", "hash"}, strings{"address"}, FunctionType::Location::ECRecover)),
make_shared<FunctionType>(strings{"bytes32", "uint8", "bytes32", "bytes32"}, strings{"address"}, FunctionType::Location::ECRecover)),
make_shared<MagicVariableDeclaration>("ripemd160",
make_shared<FunctionType>(strings(), strings{"hash160"}, FunctionType::Location::RIPEMD160, true))})
make_shared<FunctionType>(strings(), strings{"bytes20"}, FunctionType::Location::RIPEMD160, true))})
{
}

9
libsolidity/LValue.cpp

@ -167,6 +167,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
// stack: source_ref target_ref member_offset source_member_ref
StorageItem(m_context, *memberType).retrieveValue(_location, true);
// stack: source_ref target_ref member_offset source_value...
solAssert(2 + memberType->getSizeOnStack() <= 16, "Stack too deep.");
m_context << eth::dupInstruction(2 + memberType->getSizeOnStack())
<< eth::dupInstruction(2 + memberType->getSizeOnStack()) << eth::Instruction::ADD;
// stack: source_ref target_ref member_offset source_value... target_member_ref
@ -234,7 +235,7 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const
}
/// Used in StorageByteArrayElement
static IntegerType byteType(8, IntegerType::Modifier::Hash);
static FixedBytesType byteType(1);
StorageByteArrayElement::StorageByteArrayElement(CompilerContext& _compilerContext):
LValue(_compilerContext, byteType)
@ -250,6 +251,7 @@ void StorageByteArrayElement::retrieveValue(SourceLocation const&, bool _remove)
else
m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD
<< eth::Instruction::DUP2 << eth::Instruction::BYTE;
m_context << (u256(1) << (256 - 8)) << eth::Instruction::MUL;
}
void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, bool _move) const
@ -265,8 +267,9 @@ void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, boo
m_context << eth::Instruction::DUP2 << u256(0xff) << eth::Instruction::MUL
<< eth::Instruction::NOT << eth::Instruction::AND;
// stack: value ref (1<<(32-byte_number)) old_full_value_with_cleared_byte
m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP4 << eth::Instruction::MUL
<< eth::Instruction::OR;
m_context << eth::Instruction::SWAP1;
m_context << (u256(1) << (256 - 8)) << eth::Instruction::DUP5 << eth::Instruction::DIV
<< eth::Instruction::MUL << eth::Instruction::OR;
// stack: value ref new_full_value
m_context << eth::Instruction::SWAP1 << eth::Instruction::SSTORE;
if (_move)

103
libsolidity/Token.h

@ -252,77 +252,44 @@ namespace solidity
K(UInt240, "uint240", 0) \
K(UInt248, "uint248", 0) \
K(UInt256, "uint256", 0) \
K(Hash, "hash", 0) \
K(Hash8, "hash8", 0) \
K(Hash16, "hash16", 0) \
K(Hash24, "hash24", 0) \
K(Hash32, "hash32", 0) \
K(Hash40, "hash40", 0) \
K(Hash48, "hash48", 0) \
K(Hash56, "hash56", 0) \
K(Hash64, "hash64", 0) \
K(Hash72, "hash72", 0) \
K(Hash80, "hash80", 0) \
K(Hash88, "hash88", 0) \
K(Hash96, "hash96", 0) \
K(Hash104, "hash104", 0) \
K(Hash112, "hash112", 0) \
K(Hash120, "hash120", 0) \
K(Hash128, "hash128", 0) \
K(Hash136, "hash136", 0) \
K(Hash144, "hash144", 0) \
K(Hash152, "hash152", 0) \
K(Hash160, "hash160", 0) \
K(Hash168, "hash168", 0) \
K(Hash176, "hash178", 0) \
K(Hash184, "hash184", 0) \
K(Hash192, "hash192", 0) \
K(Hash200, "hash200", 0) \
K(Hash208, "hash208", 0) \
K(Hash216, "hash216", 0) \
K(Hash224, "hash224", 0) \
K(Hash232, "hash232", 0) \
K(Hash240, "hash240", 0) \
K(Hash248, "hash248", 0) \
K(Hash256, "hash256", 0) \
K(Bytes0, "bytes0", 0) \
K(Bytes1, "bytes1", 0) \
K(Bytes2, "bytes2", 0) \
K(Bytes3, "bytes3", 0) \
K(Bytes4, "bytes4", 0) \
K(Bytes5, "bytes5", 0) \
K(Bytes6, "bytes6", 0) \
K(Bytes7, "bytes7", 0) \
K(Bytes8, "bytes8", 0) \
K(Bytes9, "bytes9", 0) \
K(Bytes10, "bytes10", 0) \
K(Bytes11, "bytes11", 0) \
K(Bytes12, "bytes12", 0) \
K(Bytes13, "bytes13", 0) \
K(Bytes14, "bytes14", 0) \
K(Bytes15, "bytes15", 0) \
K(Bytes16, "bytes16", 0) \
K(Bytes17, "bytes17", 0) \
K(Bytes18, "bytes18", 0) \
K(Bytes19, "bytes19", 0) \
K(Bytes20, "bytes20", 0) \
K(Bytes21, "bytes21", 0) \
K(Bytes22, "bytes22", 0) \
K(Bytes23, "bytes23", 0) \
K(Bytes24, "bytes24", 0) \
K(Bytes25, "bytes25", 0) \
K(Bytes26, "bytes26", 0) \
K(Bytes27, "bytes27", 0) \
K(Bytes28, "bytes28", 0) \
K(Bytes29, "bytes29", 0) \
K(Bytes30, "bytes30", 0) \
K(Bytes31, "bytes31", 0) \
K(Bytes32, "bytes32", 0) \
K(Bytes, "bytes", 0) \
K(Byte, "byte", 0) \
K(Address, "address", 0) \
K(Bool, "bool", 0) \
K(Bytes, "bytes", 0) \
K(StringType, "string", 0) \
K(String0, "string0", 0) \
K(String1, "string1", 0) \
K(String2, "string2", 0) \
K(String3, "string3", 0) \
K(String4, "string4", 0) \
K(String5, "string5", 0) \
K(String6, "string6", 0) \
K(String7, "string7", 0) \
K(String8, "string8", 0) \
K(String9, "string9", 0) \
K(String10, "string10", 0) \
K(String11, "string11", 0) \
K(String12, "string12", 0) \
K(String13, "string13", 0) \
K(String14, "string14", 0) \
K(String15, "string15", 0) \
K(String16, "string16", 0) \
K(String17, "string17", 0) \
K(String18, "string18", 0) \
K(String19, "string19", 0) \
K(String20, "string20", 0) \
K(String21, "string21", 0) \
K(String22, "string22", 0) \
K(String23, "string23", 0) \
K(String24, "string24", 0) \
K(String25, "string25", 0) \
K(String26, "string26", 0) \
K(String27, "string27", 0) \
K(String28, "string28", 0) \
K(String29, "string29", 0) \
K(String30, "string30", 0) \
K(String31, "string31", 0) \
K(String32, "string32", 0) \
K(Text, "text", 0) \
K(Real, "real", 0) \
K(UReal, "ureal", 0) \
T(TypesEnd, NULL, 0) /* used as type enum end marker */ \

131
libsolidity/Types.cpp

@ -37,26 +37,36 @@ namespace solidity
TypePointer Type::fromElementaryTypeName(Token::Value _typeToken)
{
solAssert(Token::isElementaryTypeName(_typeToken), "Elementary type name expected.");
char const* tokenCstr = Token::toString(_typeToken);
solAssert(Token::isElementaryTypeName(_typeToken),
"Expected an elementary type name but got " + ((tokenCstr) ? std::string(Token::toString(_typeToken)) : ""));
if (Token::Int <= _typeToken && _typeToken <= Token::Hash256)
if (Token::Int <= _typeToken && _typeToken <= Token::Bytes32)
{
int offset = _typeToken - Token::Int;
int bytes = offset % 33;
if (bytes == 0)
if (bytes == 0 && _typeToken != Token::Bytes0)
bytes = 32;
int modifier = offset / 33;
return make_shared<IntegerType>(bytes * 8,
modifier == 0 ? IntegerType::Modifier::Signed :
modifier == 1 ? IntegerType::Modifier::Unsigned :
IntegerType::Modifier::Hash);
switch(modifier)
{
case 0:
return make_shared<IntegerType>(bytes * 8, IntegerType::Modifier::Signed);
case 1:
return make_shared<IntegerType>(bytes * 8, IntegerType::Modifier::Unsigned);
case 2:
return make_shared<FixedBytesType>(bytes);
default:
solAssert(false, "Unexpected modifier value. Should never happen");
return TypePointer();
}
}
else if (_typeToken == Token::Byte)
return make_shared<FixedBytesType>(1);
else if (_typeToken == Token::Address)
return make_shared<IntegerType>(0, IntegerType::Modifier::Address);
else if (_typeToken == Token::Bool)
return make_shared<BoolType>();
else if (Token::String0 <= _typeToken && _typeToken <= Token::String32)
return make_shared<StaticStringType>(int(_typeToken) - int(Token::String0));
else if (_typeToken == Token::Bytes)
return make_shared<ArrayType>(ArrayType::Location::Storage);
else
@ -123,7 +133,7 @@ TypePointer Type::forLiteral(Literal const& _literal)
return make_shared<IntegerConstantType>(_literal);
case Token::StringLiteral:
//@todo put larger strings into dynamic strings
return StaticStringType::smallestTypeForLiteral(_literal.getValue());
return FixedBytesType::smallestTypeForLiteral(_literal.getValue());
default:
return shared_ptr<Type>();
}
@ -159,8 +169,6 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
return false;
if (isAddress())
return convertTo.isAddress();
else if (isHash())
return convertTo.isHash();
else if (isSigned())
return convertTo.isSigned();
else
@ -169,14 +177,10 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
if (_convertTo.getCategory() == Category::String)
{
StaticStringType const& convertTo = dynamic_cast<StaticStringType const&>(_convertTo);
return isHash() && (m_bits == convertTo.getNumBytes() * 8);
}
return _convertTo.getCategory() == getCategory() ||
_convertTo.getCategory() == Category::Contract ||
_convertTo.getCategory() == Category::Enum;
_convertTo.getCategory() == Category::Contract ||
_convertTo.getCategory() == Category::Enum ||
_convertTo.getCategory() == Category::FixedBytes;
}
TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const
@ -187,16 +191,10 @@ TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const
// no further unary operators for addresses
else if (isAddress())
return TypePointer();
// "~" is ok for all other types
else if (_operator == Token::BitNot)
return shared_from_this();
// nothing else for hashes
else if (isHash())
return TypePointer();
// for non-hash integers, we allow +, -, ++ and --
// for non-address integers, we allow +, -, ++ and --
else if (_operator == Token::Add || _operator == Token::Sub ||
_operator == Token::Inc || _operator == Token::Dec ||
_operator == Token::After)
_operator == Token::After || _operator == Token::BitNot)
return shared_from_this();
else
return TypePointer();
@ -214,7 +212,7 @@ string IntegerType::toString() const
{
if (isAddress())
return "address";
string prefix = isHash() ? "hash" : (isSigned() ? "int" : "uint");
string prefix = isSigned() ? "int" : "uint";
return prefix + dev::toString(m_bits);
}
@ -230,14 +228,11 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe
// All integer types can be compared
if (Token::isCompareOp(_operator))
return commonType;
// Nothing else can be done with addresses, but hashes can receive bit operators
// Nothing else can be done with addresses
if (commonType->isAddress())
return TypePointer();
else if (commonType->isHash() && !Token::isBitOp(_operator))
return TypePointer();
else
return commonType;
return commonType;
}
const MemberList IntegerType::AddressMemberList =
@ -284,8 +279,17 @@ IntegerConstantType::IntegerConstantType(Literal const& _literal)
bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) const
{
TypePointer integerType = getIntegerType();
return integerType && integerType->isImplicitlyConvertibleTo(_convertTo);
shared_ptr<IntegerType const> integerType = getIntegerType();
if (!integerType)
return false;
if (_convertTo.getCategory() == Category::FixedBytes)
{
FixedBytesType const& convertTo = dynamic_cast<FixedBytesType const&>(_convertTo);
return convertTo.getNumBytes() * 8 >= integerType->getNumBits();
}
return integerType->isImplicitlyConvertibleTo(_convertTo);
}
bool IntegerConstantType::isExplicitlyConvertibleTo(Type const& _convertTo) const
@ -433,50 +437,73 @@ shared_ptr<IntegerType const> IntegerConstantType::getIntegerType() const
: IntegerType::Modifier::Unsigned);
}
shared_ptr<StaticStringType> StaticStringType::smallestTypeForLiteral(string const& _literal)
shared_ptr<FixedBytesType> FixedBytesType::smallestTypeForLiteral(string const& _literal)
{
if (_literal.length() <= 32)
return make_shared<StaticStringType>(_literal.length());
return shared_ptr<StaticStringType>();
return make_shared<FixedBytesType>(_literal.length());
return shared_ptr<FixedBytesType>();
}
StaticStringType::StaticStringType(int _bytes): m_bytes(_bytes)
FixedBytesType::FixedBytesType(int _bytes): m_bytes(_bytes)
{
solAssert(m_bytes >= 0 && m_bytes <= 32,
"Invalid byte number for static string type: " + dev::toString(m_bytes));
"Invalid byte number for fixed bytes type: " + dev::toString(m_bytes));
}
bool StaticStringType::isImplicitlyConvertibleTo(Type const& _convertTo) const
bool FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const
{
if (_convertTo.getCategory() != getCategory())
return false;
StaticStringType const& convertTo = dynamic_cast<StaticStringType const&>(_convertTo);
FixedBytesType const& convertTo = dynamic_cast<FixedBytesType const&>(_convertTo);
return convertTo.m_bytes >= m_bytes;
}
bool StaticStringType::isExplicitlyConvertibleTo(Type const& _convertTo) const
bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
if (_convertTo.getCategory() == getCategory())
return true;
if (_convertTo.getCategory() == Category::Integer)
{
IntegerType const& convertTo = dynamic_cast<IntegerType const&>(_convertTo);
if (convertTo.isHash() && (m_bytes * 8 == convertTo.getNumBits()))
if (m_bytes * 8 <= convertTo.getNumBits())
return true;
}
return false;
return _convertTo.getCategory() == Category::Contract ||
_convertTo.getCategory() == getCategory();
}
TypePointer FixedBytesType::unaryOperatorResult(Token::Value _operator) const
{
// "delete" and "~" is okay for FixedBytesType
if (_operator == Token::Delete)
return make_shared<VoidType>();
else if (_operator == Token::BitNot)
return shared_from_this();
return TypePointer();
}
TypePointer FixedBytesType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
{
auto commonType = dynamic_pointer_cast<FixedBytesType const>(Type::commonType(shared_from_this(), _other));
if (!commonType)
return TypePointer();
// FixedBytes can be compared and have bitwise operators applied to them
if (Token::isCompareOp(_operator) || Token::isBitOp(_operator))
return commonType;
return TypePointer();
}
bool StaticStringType::operator==(Type const& _other) const
bool FixedBytesType::operator==(Type const& _other) const
{
if (_other.getCategory() != getCategory())
return false;
StaticStringType const& other = dynamic_cast<StaticStringType const&>(_other);
FixedBytesType const& other = dynamic_cast<FixedBytesType const&>(_other);
return other.m_bytes == m_bytes;
}
u256 StaticStringType::literalValue(const Literal* _literal) const
u256 FixedBytesType::literalValue(const Literal* _literal) const
{
solAssert(_literal, "");
u256 value = 0;
@ -1124,7 +1151,7 @@ MagicType::MagicType(MagicType::Kind _kind):
case Kind::Block:
m_members = MemberList({{"coinbase", make_shared<IntegerType>(0, IntegerType::Modifier::Address)},
{"timestamp", make_shared<IntegerType>(256)},
{"blockhash", make_shared<FunctionType>(strings{"uint"}, strings{"hash"}, FunctionType::Location::BlockHash)},
{"blockhash", make_shared<FunctionType>(strings{"uint"}, strings{"bytes32"}, FunctionType::Location::BlockHash)},
{"difficulty", make_shared<IntegerType>(256)},
{"number", make_shared<IntegerType>(256)},
{"gaslimit", make_shared<IntegerType>(256)}});

27
libsolidity/Types.h

@ -77,12 +77,12 @@ public:
enum class Category
{
Integer, IntegerConstant, Bool, Real, Array,
String, Contract, Struct, Function, Enum,
FixedBytes, Contract, Struct, Function, Enum,
Mapping, Void, TypeType, Modifier, Magic
};
///@{
///@name Factory functions
/// @{
/// @name Factory functions
/// Factory functions that convert an AST @ref TypeName to a Type.
static TypePointer fromElementaryTypeName(Token::Value _typeToken);
static TypePointer fromElementaryTypeName(std::string const& _name);
@ -158,14 +158,14 @@ protected:
};
/**
* Any kind of integer type including hash and address.
* Any kind of integer type (signed, unsigned, address).
*/
class IntegerType: public Type
{
public:
enum class Modifier
{
Unsigned, Signed, Hash, Address
Unsigned, Signed, Address
};
virtual Category getCategory() const override { return Category::Integer; }
@ -186,7 +186,6 @@ public:
virtual std::string toString() const override;
int getNumBits() const { return m_bits; }
bool isHash() const { return m_modifier == Modifier::Hash || m_modifier == Modifier::Address; }
bool isAddress() const { return m_modifier == Modifier::Address; }
bool isSigned() const { return m_modifier == Modifier::Signed; }
@ -232,27 +231,29 @@ private:
};
/**
* String type with fixed length, up to 32 bytes.
* Bytes type with fixed length of up to 32 bytes.
*/
class StaticStringType: public Type
class FixedBytesType: public Type
{
public:
virtual Category getCategory() const override { return Category::String; }
virtual Category getCategory() const override { return Category::FixedBytes; }
/// @returns the smallest string type for the given literal or an empty pointer
/// @returns the smallest bytes type for the given literal or an empty pointer
/// if no type fits.
static std::shared_ptr<StaticStringType> smallestTypeForLiteral(std::string const& _literal);
static std::shared_ptr<FixedBytesType> smallestTypeForLiteral(std::string const& _literal);
explicit StaticStringType(int _bytes);
explicit FixedBytesType(int _bytes);
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual bool operator==(Type const& _other) const override;
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
virtual unsigned getCalldataEncodedSize(bool _padded) const override { return _padded && m_bytes > 0 ? 32 : m_bytes; }
virtual bool isValueType() const override { return true; }
virtual std::string toString() const override { return "string" + dev::toString(m_bytes); }
virtual std::string toString() const override { return "bytes" + dev::toString(m_bytes); }
virtual u256 literalValue(Literal const* _literal) const override;
int getNumBytes() const { return m_bytes; }

1
libweb3jsonrpc/CMakeLists.txt

@ -56,4 +56,5 @@ endif()
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
add_custom_target(aux_json SOURCES "spec.json")

81
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -295,162 +295,99 @@ string WebThreeStubServerBase::eth_blockNumber()
string WebThreeStubServerBase::eth_getBalance(string const& _address, string const& _blockNumber)
{
Address address;
int number;
try
{
address = jsToAddress(_address);
number = toBlockNumber(_blockNumber);
}
catch (...)
{
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
}
return toJS(client()->balanceAt(address, number));
}
Json::Value WebThreeStubServerBase::eth_getStorage(string const& _address, string const& _blockNumber)
{
Address address;
int number;
try
{
address = jsToAddress(_address);
number = toBlockNumber(_blockNumber);
return toJS(client()->balanceAt(jsToAddress(_address), toBlockNumber(_blockNumber)));
}
catch (...)
{
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
}
//TODO: fix this naming !
return toJson(client()->storageAt(address, number));
}
string WebThreeStubServerBase::eth_getStorageAt(string const& _address, string const& _position, string const& _blockNumber)
{
Address address;
u256 position;
int number;
try
{
address = jsToAddress(_address);
position = jsToU256(_position);
number = toBlockNumber(_blockNumber);
return toJS(client()->stateAt(jsToAddress(_address), jsToU256(_position), toBlockNumber(_blockNumber)));
}
catch (...)
{
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
}
//TODO: fix this naming !
return toJS(client()->stateAt(address, position, number));
}
string WebThreeStubServerBase::eth_getTransactionCount(string const& _address, string const& _blockNumber)
{
Address address;
int number;
try
{
address = jsToAddress(_address);
number = toBlockNumber(_blockNumber);
return toJS(client()->countAt(jsToAddress(_address), toBlockNumber(_blockNumber)));
}
catch (...)
{
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
}
return toJS(client()->countAt(address, number));
}
string WebThreeStubServerBase::eth_getBlockTransactionCountByHash(string const& _blockHash)
{
h256 hash;
try
{
hash = jsToFixed<32>(_blockHash);
return toJS(client()->transactionCount(jsToFixed<32>(_blockHash)));
}
catch (...)
{
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
}
return toJS(client()->transactionCount(hash));
}
string WebThreeStubServerBase::eth_getBlockTransactionCountByNumber(string const& _blockNumber)
{
int number;
try
{
number = toBlockNumber(_blockNumber);
return toJS(client()->transactionCount(client()->hashFromNumber(toBlockNumber(_blockNumber))));
}
catch (...)
{
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
}
return toJS(client()->transactionCount(client()->hashFromNumber(number)));
}
string WebThreeStubServerBase::eth_getUncleCountByBlockHash(string const& _blockHash)
{
h256 hash;
try
{
hash = jsToFixed<32>(_blockHash);
return toJS(client()->uncleCount(jsToFixed<32>(_blockHash)));
}
catch (...)
{
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
}
return toJS(client()->uncleCount(hash));
}
string WebThreeStubServerBase::eth_getUncleCountByBlockNumber(string const& _blockNumber)
{
int number;
try
{
number = toBlockNumber(_blockNumber);
return toJS(client()->uncleCount(client()->hashFromNumber(toBlockNumber(_blockNumber))));
}
catch (...)
{
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
}
return toJS(client()->uncleCount(client()->hashFromNumber(number)));
}
string WebThreeStubServerBase::eth_getData(string const& _address, string const& _blockNumber)
string WebThreeStubServerBase::eth_getCode(string const& _address, string const& _blockNumber)
{
Address address;
int number;
try
{
address = jsToAddress(_address);
number = toBlockNumber(_blockNumber);
return toJS(client()->codeAt(jsToAddress(_address), toBlockNumber(_blockNumber)));
}
catch (...)
{
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
}
return toJS(client()->codeAt(address, number));
}
static TransactionSkeleton toTransaction(Json::Value const& _json)

3
libweb3jsonrpc/WebThreeStubServerBase.h

@ -80,14 +80,13 @@ public:
virtual Json::Value eth_accounts();
virtual std::string eth_blockNumber();
virtual std::string eth_getBalance(std::string const& _address, std::string const& _blockNumber);
virtual Json::Value eth_getStorage(std::string const& _address, std::string const& _blockNumber);
virtual std::string eth_getStorageAt(std::string const& _address, std::string const& _position, std::string const& _blockNumber);
virtual std::string eth_getTransactionCount(std::string const& _address, std::string const& _blockNumber);
virtual std::string eth_getBlockTransactionCountByHash(std::string const& _blockHash);
virtual std::string eth_getBlockTransactionCountByNumber(std::string const& _blockNumber);
virtual std::string eth_getUncleCountByBlockHash(std::string const& _blockHash);
virtual std::string eth_getUncleCountByBlockNumber(std::string const& _blockNumber);
virtual std::string eth_getData(std::string const& _address, std::string const& _blockNumber);
virtual std::string eth_getCode(std::string const& _address, std::string const& _blockNumber);
virtual std::string eth_sendTransaction(Json::Value const& _json);
virtual std::string eth_call(Json::Value const& _json, std::string const& _blockNumber);
virtual bool eth_flush();

14
libweb3jsonrpc/abstractwebthreestubserver.h

@ -23,14 +23,13 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
this->bindAndAddMethod(jsonrpc::Procedure("eth_accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_accountsI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_blockNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_blockNumberI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getBalance", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBalanceI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getStorage", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getStorageI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getStorageAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getStorageAtI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionCountI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByHashI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByNumberI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockHashI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockNumberI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getData", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getDataI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getCode", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getCodeI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_sendTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_sendTransactionI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_callI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_flush", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_flushI);
@ -122,10 +121,6 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
{
response = this->eth_getBalance(request[0u].asString(), request[1u].asString());
}
inline virtual void eth_getStorageI(const Json::Value &request, Json::Value &response)
{
response = this->eth_getStorage(request[0u].asString(), request[1u].asString());
}
inline virtual void eth_getStorageAtI(const Json::Value &request, Json::Value &response)
{
response = this->eth_getStorageAt(request[0u].asString(), request[1u].asString(), request[2u].asString());
@ -150,9 +145,9 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
{
response = this->eth_getUncleCountByBlockNumber(request[0u].asString());
}
inline virtual void eth_getDataI(const Json::Value &request, Json::Value &response)
inline virtual void eth_getCodeI(const Json::Value &request, Json::Value &response)
{
response = this->eth_getData(request[0u].asString(), request[1u].asString());
response = this->eth_getCode(request[0u].asString(), request[1u].asString());
}
inline virtual void eth_sendTransactionI(const Json::Value &request, Json::Value &response)
{
@ -313,14 +308,13 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
virtual Json::Value eth_accounts() = 0;
virtual std::string eth_blockNumber() = 0;
virtual std::string eth_getBalance(const std::string& param1, const std::string& param2) = 0;
virtual Json::Value eth_getStorage(const std::string& param1, const std::string& param2) = 0;
virtual std::string eth_getStorageAt(const std::string& param1, const std::string& param2, const std::string& param3) = 0;
virtual std::string eth_getTransactionCount(const std::string& param1, const std::string& param2) = 0;
virtual std::string eth_getBlockTransactionCountByHash(const std::string& param1) = 0;
virtual std::string eth_getBlockTransactionCountByNumber(const std::string& param1) = 0;
virtual std::string eth_getUncleCountByBlockHash(const std::string& param1) = 0;
virtual std::string eth_getUncleCountByBlockNumber(const std::string& param1) = 0;
virtual std::string eth_getData(const std::string& param1, const std::string& param2) = 0;
virtual std::string eth_getCode(const std::string& param1, const std::string& param2) = 0;
virtual std::string eth_sendTransaction(const Json::Value& param1) = 0;
virtual std::string eth_call(const Json::Value& param1, const std::string& param2) = 0;
virtual bool eth_flush() = 0;

3
libweb3jsonrpc/spec.json

@ -12,14 +12,13 @@
{ "name": "eth_accounts", "params": [], "order": [], "returns" : [] },
{ "name": "eth_blockNumber", "params": [], "order": [], "returns" : ""},
{ "name": "eth_getBalance", "params": ["", ""], "order": [], "returns" : ""},
{ "name": "eth_getStorage", "params": ["", ""], "order": [], "returns": {}},
{ "name": "eth_getStorageAt", "params": ["", "", ""], "order": [], "returns": ""},
{ "name": "eth_getTransactionCount", "params": ["", ""], "order": [], "returns" : ""},
{ "name": "eth_getBlockTransactionCountByHash", "params": [""], "order": [], "returns" : ""},
{ "name": "eth_getBlockTransactionCountByNumber", "params": [""], "order": [], "returns" : ""},
{ "name": "eth_getUncleCountByBlockHash", "params": [""], "order": [], "returns" : ""},
{ "name": "eth_getUncleCountByBlockNumber", "params": [""], "order": [], "returns" : ""},
{ "name": "eth_getData", "params": ["", ""], "order": [], "returns": ""},
{ "name": "eth_getCode", "params": ["", ""], "order": [], "returns": ""},
{ "name": "eth_sendTransaction", "params": [{}], "order": [], "returns": ""},
{ "name": "eth_call", "params": [{}, ""], "order": [], "returns": ""},
{ "name": "eth_flush", "params": [], "order": [], "returns" : true},

8
mix/CodeModel.cpp

@ -77,15 +77,15 @@ namespace
{
IntegerType const* it = dynamic_cast<IntegerType const*>(_type);
unsigned size = it->getNumBits() / 8;
SolidityType::Type typeCode = it->isAddress() ? SolidityType::Type::Address : it->isHash() ? SolidityType::Type::Hash : it->isSigned() ? SolidityType::Type::SignedInteger : SolidityType::Type::UnsignedInteger;
SolidityType::Type typeCode = it->isAddress() ? SolidityType::Type::Address : it->isSigned() ? SolidityType::Type::SignedInteger : SolidityType::Type::UnsignedInteger;
return SolidityType { typeCode, size };
}
case Type::Category::Bool:
return SolidityType { SolidityType::Type::Bool, _type->getSizeOnStack() * 32 };
case Type::Category::String:
case Type::Category::FixedBytes:
{
StaticStringType const* s = dynamic_cast<StaticStringType const*>(_type);
return SolidityType { SolidityType::Type::String, static_cast<unsigned>(s->getNumBytes()) };
FixedBytesType const* s = dynamic_cast<FixedBytesType const*>(_type);
return SolidityType { SolidityType::Type::FixedBytes, static_cast<unsigned>(s->getNumBytes()) };
}
case Type::Category::Contract:
return SolidityType { SolidityType::Type::Address, _type->getSizeOnStack() * 32 };

3
mix/CodeModel.h

@ -72,10 +72,9 @@ struct SolidityType
{
SignedInteger,
UnsignedInteger,
Hash,
Bool,
Address,
String,
FixedBytes,
};
Type type;
unsigned size; //bytes

10
mix/MixClient.cpp

@ -40,6 +40,8 @@ namespace dev
namespace mix
{
// TODO: merge as much as possible with the Client.cpp into a mutually inherited base class.
const Secret c_defaultUserAccountSecret = Secret("cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074");
const u256 c_mixGenesisDifficulty = c_minimumDifficulty; //TODO: make it lower for Mix somehow
@ -360,13 +362,13 @@ eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const
return ret;
}
unsigned MixClient::installWatch(h256 _h)
unsigned MixClient::installWatch(h256 _h, eth::Reaping _r)
{
unsigned ret;
{
Guard l(m_filterLock);
ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0;
m_watches[ret] = ClientWatch(_h);
m_watches[ret] = ClientWatch(_h, _r);
}
auto ch = logs(ret);
if (ch.empty())
@ -378,14 +380,14 @@ unsigned MixClient::installWatch(h256 _h)
return ret;
}
unsigned MixClient::installWatch(eth::LogFilter const& _f)
unsigned MixClient::installWatch(eth::LogFilter const& _f, eth::Reaping _r)
{
h256 h = _f.sha3();
{
Guard l(m_filterLock);
m_filters.insert(std::make_pair(h, _f));
}
return installWatch(h);
return installWatch(h, _r);
}
bool MixClient::uninstallWatch(unsigned _i)

4
mix/MixClient.h

@ -60,8 +60,8 @@ public:
std::map<u256, u256> storageAt(Address _a, int _block) const override;
eth::LocalisedLogEntries logs(unsigned _watchId) const override;
eth::LocalisedLogEntries logs(eth::LogFilter const& _filter) const override;
unsigned installWatch(eth::LogFilter const& _filter) override;
unsigned installWatch(h256 _filterId) override;
unsigned installWatch(eth::LogFilter const& _filter, eth::Reaping _r = eth::Reaping::Automatic) override;
unsigned installWatch(h256 _filterId, eth::Reaping _r = eth::Reaping::Automatic) override;
bool uninstallWatch(unsigned _watchId) override;
eth::LocalisedLogEntries peekWatch(unsigned _watchId) const override;
eth::LocalisedLogEntries checkWatch(unsigned _watchId) override;

30
test/CMakeLists.txt

@ -1,8 +1,10 @@
cmake_policy(SET CMP0015 NEW)
aux_source_directory(. SRC_LIST)
list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp")
list(REMOVE_ITEM SRC_LIST "./checkRandomTest.cpp")
list(REMOVE_ITEM SRC_LIST "./createRandomVMTest.cpp")
list(REMOVE_ITEM SRC_LIST "./createRandomStateTest.cpp")
list(REMOVE_ITEM SRC_LIST "./checkRandomVMTest.cpp")
list(REMOVE_ITEM SRC_LIST "./checkRandomStateTest.cpp")
if (NOT JSONRPC)
list(REMOVE_ITEM SRC_LIST "./AccountHolder.cpp")
@ -17,8 +19,10 @@ include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
file(GLOB HEADERS "*.h")
add_executable(testeth ${SRC_LIST} ${HEADERS})
add_executable(createRandomTest createRandomTest.cpp vm.cpp TestHelper.cpp)
add_executable(checkRandomTest checkRandomTest.cpp vm.cpp TestHelper.cpp)
add_executable(createRandomVMTest createRandomVMTest.cpp vm.cpp TestHelper.cpp Stats.cpp)
add_executable(createRandomStateTest createRandomStateTest.cpp TestHelper.cpp Stats.cpp)
add_executable(checkRandomVMTest checkRandomVMTest.cpp vm.cpp TestHelper.cpp Stats.cpp)
add_executable(checkRandomStateTest checkRandomStateTest.cpp TestHelper.cpp Stats.cpp)
target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
target_link_libraries(testeth ${CURL_LIBRARIES})
@ -35,10 +39,16 @@ if (JSONRPC)
target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES})
endif()
target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
target_link_libraries(createRandomTest ethereum)
target_link_libraries(createRandomTest ethcore)
target_link_libraries(checkRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
target_link_libraries(checkRandomTest ethereum)
target_link_libraries(checkRandomTest ethcore)
target_link_libraries(createRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
target_link_libraries(createRandomVMTest ethereum)
target_link_libraries(createRandomVMTest ethcore)
target_link_libraries(createRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
target_link_libraries(createRandomStateTest ethereum)
target_link_libraries(createRandomStateTest ethcore)
target_link_libraries(checkRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
target_link_libraries(checkRandomVMTest ethereum)
target_link_libraries(checkRandomVMTest ethcore)
target_link_libraries(checkRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
target_link_libraries(checkRandomStateTest ethereum)
target_link_libraries(checkRandomStateTest ethcore)

10
test/SolidityABIJSON.cpp

@ -339,10 +339,10 @@ BOOST_AUTO_TEST_CASE(inherited)
char const* sourceCode =
" contract Base { \n"
" function baseFunction(uint p) returns (uint i) { return p; } \n"
" event baseEvent(string32 indexed evtArgBase); \n"
" event baseEvent(bytes32 indexed evtArgBase); \n"
" } \n"
" contract Derived is Base { \n"
" function derivedFunction(string32 p) returns (string32 i) { return p; } \n"
" function derivedFunction(bytes32 p) returns (bytes32 i) { return p; } \n"
" event derivedEvent(uint indexed evtArgDerived); \n"
" }";
@ -369,12 +369,12 @@ BOOST_AUTO_TEST_CASE(inherited)
"inputs":
[{
"name": "p",
"type": "string32"
"type": "bytes32"
}],
"outputs":
[{
"name": "i",
"type": "string32"
"type": "bytes32"
}]
},
{
@ -394,7 +394,7 @@ BOOST_AUTO_TEST_CASE(inherited)
[{
"indexed": true,
"name": "evtArgBase",
"type": "string32"
"type": "bytes32"
}]
}])";

192
test/SolidityEndToEndTest.cpp

@ -507,23 +507,23 @@ BOOST_AUTO_TEST_CASE(small_signed_types)
BOOST_AUTO_TEST_CASE(strings)
{
char const* sourceCode = "contract test {\n"
" function fixed() returns(string32 ret) {\n"
" function fixed() returns(bytes32 ret) {\n"
" return \"abc\\x00\\xff__\";\n"
" }\n"
" function pipeThrough(string2 small, bool one) returns(string16 large, bool oneRet) {\n"
" function pipeThrough(bytes2 small, bool one) returns(bytes16 large, bool oneRet) {\n"
" oneRet = one;\n"
" large = small;\n"
" }\n"
"}\n";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("fixed()") == encodeArgs(string("abc\0\xff__", 7)));
BOOST_CHECK(callContractFunction("pipeThrough(string2,bool)", string("\0\x02", 2), true) == encodeArgs(string("\0\x2", 2), true));
BOOST_CHECK(callContractFunction("pipeThrough(bytes2,bool)", string("\0\x02", 2), true) == encodeArgs(string("\0\x2", 2), true));
}
BOOST_AUTO_TEST_CASE(empty_string_on_stack)
{
char const* sourceCode = "contract test {\n"
" function run(string0 empty, uint8 inp) returns(uint16 a, string0 b, string4 c) {\n"
" function run(bytes0 empty, uint8 inp) returns(uint16 a, bytes0 b, bytes4 c) {\n"
" var x = \"abc\";\n"
" var y = \"\";\n"
" var z = inp;\n"
@ -531,7 +531,7 @@ BOOST_AUTO_TEST_CASE(empty_string_on_stack)
" }\n"
"}\n";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("run(string0,uint8)", string(), byte(0x02)) == encodeArgs(0x2, string(""), string("abc\0")));
BOOST_CHECK(callContractFunction("run(bytes0,uint8)", string(), byte(0x02)) == encodeArgs(0x2, string(""), string("abc\0")));
}
BOOST_AUTO_TEST_CASE(state_smoke_test)
@ -948,8 +948,8 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
{
char const* sourceCode = "contract test {\n"
" uint256 public data;\n"
" string6 public name;\n"
" hash public a_hash;\n"
" bytes6 public name;\n"
" bytes32 public a_hash;\n"
" address public an_address;\n"
" function test() {\n"
" data = 8;\n"
@ -971,7 +971,7 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
BOOST_AUTO_TEST_CASE(complex_accessors)
{
char const* sourceCode = "contract test {\n"
" mapping(uint256 => string4) public to_string_map;\n"
" mapping(uint256 => bytes4) public to_string_map;\n"
" mapping(uint256 => bool) public to_bool_map;\n"
" mapping(uint256 => uint256) public to_uint_map;\n"
" mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;\n"
@ -1076,96 +1076,96 @@ BOOST_AUTO_TEST_CASE(type_conversions_cleanup)
0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22}));
}
BOOST_AUTO_TEST_CASE(convert_string_to_string)
BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_fixed_bytes_smaller_size)
{
char const* sourceCode = R"(
contract Test {
function pipeTrough(string3 input) returns (string3 ret) {
return string3(input);
function pipeTrough(bytes3 input) returns (bytes2 ret) {
return bytes2(input);
}
})";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("pipeTrough(string3)", "abc") == encodeArgs("abc"));
BOOST_CHECK(callContractFunction("pipeTrough(bytes3)", "abc") == encodeArgs("ab"));
}
BOOST_AUTO_TEST_CASE(convert_hash_to_string_same_size)
BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_same_size)
{
char const* sourceCode = R"(
contract Test {
function hashToString(hash h) returns (string32 s) {
return string32(h);
function uintToBytes(uint256 h) returns (bytes32 s) {
return bytes32(h);
}
})";
compileAndRun(sourceCode);
u256 a("0x6162630000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK(callContractFunction("hashToString(hash256)", a) == encodeArgs(a));
BOOST_CHECK(callContractFunction("uintToBytes(uint256)", a) == encodeArgs(a));
}
BOOST_AUTO_TEST_CASE(convert_hash_to_string_different_size)
BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_different_size)
{
char const* sourceCode = R"(
contract Test {
function hashToString(hash160 h) returns (string20 s) {
return string20(h);
function uintToBytes(uint160 h) returns (bytes20 s) {
return bytes20(h);
}
})";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("hashToString(hash160)", u160("0x6161626361626361626361616263616263616263")) ==
encodeArgs(string("aabcabcabcaabcabcabc")));
BOOST_CHECK(callContractFunction("uintToBytes(uint160)",
u160("0x6161626361626361626361616263616263616263")) == encodeArgs(string("aabcabcabcaabcabcabc")));
}
BOOST_AUTO_TEST_CASE(convert_string_to_hash_same_size)
BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_same_size)
{
char const* sourceCode = R"(
contract Test {
function stringToHash(string32 s) returns (hash h) {
return hash(s);
function bytesToUint(bytes32 s) returns (uint256 h) {
return uint(s);
}
})";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("stringToHash(string32)", string("abc2")) ==
encodeArgs(u256("0x6162633200000000000000000000000000000000000000000000000000000000")));
BOOST_CHECK(callContractFunction("bytesToUint(bytes32)", string("abc2")) ==
encodeArgs(u256("0x6162633200000000000000000000000000000000000000000000000000000000")));
}
BOOST_AUTO_TEST_CASE(convert_string_to_hash_different_size)
BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_different_size)
{
char const* sourceCode = R"(
contract Test {
function stringToHash(string20 s) returns (hash160 h) {
return hash160(s);
function bytesToUint(bytes20 s) returns (uint160 h) {
return uint160(s);
}
})";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("stringToHash(string20)", string("aabcabcabcaabcabcabc")) ==
encodeArgs(u160("0x6161626361626361626361616263616263616263")));
BOOST_CHECK(callContractFunction("bytesToUint(bytes20)", string("aabcabcabcaabcabcabc")) ==
encodeArgs(u160("0x6161626361626361626361616263616263616263")));
}
BOOST_AUTO_TEST_CASE(convert_string_to_hash_different_min_size)
BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_different_min_size)
{
char const* sourceCode = R"(
contract Test {
function stringToHash(string1 s) returns (hash8 h) {
return hash8(s);
function bytesToUint(bytes1 s) returns (uint8 h) {
return uint8(s);
}
})";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("stringToHash(string1)", string("a")) ==
encodeArgs(u256("0x61")));
BOOST_CHECK(callContractFunction("bytesToUint(bytes1)", string("a")) ==
encodeArgs(u256("0x61")));
}
BOOST_AUTO_TEST_CASE(convert_hash_to_string_different_min_size)
BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_different_min_size)
{
char const* sourceCode = R"(
contract Test {
function HashToString(hash8 h) returns (string1 s) {
return string1(h);
function UintToBytes(uint8 h) returns (bytes1 s) {
return bytes1(h);
}
})";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("HashToString(hash8)", u256("0x61")) ==
encodeArgs(string("a")));
BOOST_CHECK(callContractFunction("UintToBytes(uint8)", u256("0x61")) ==
encodeArgs(string("a")));
}
BOOST_AUTO_TEST_CASE(send_ether)
@ -1299,7 +1299,7 @@ BOOST_AUTO_TEST_CASE(suicide)
BOOST_AUTO_TEST_CASE(sha3)
{
char const* sourceCode = "contract test {\n"
" function a(hash input) returns (hash sha3hash) {\n"
" function a(bytes32 input) returns (bytes32 sha3hash) {\n"
" return sha3(input);\n"
" }\n"
"}\n";
@ -1308,15 +1308,15 @@ BOOST_AUTO_TEST_CASE(sha3)
{
return dev::sha3(toBigEndian(_x));
};
testSolidityAgainstCpp("a(hash256)", f, u256(4));
testSolidityAgainstCpp("a(hash256)", f, u256(5));
testSolidityAgainstCpp("a(hash256)", f, u256(-1));
testSolidityAgainstCpp("a(bytes32)", f, u256(4));
testSolidityAgainstCpp("a(bytes32)", f, u256(5));
testSolidityAgainstCpp("a(bytes32)", f, u256(-1));
}
BOOST_AUTO_TEST_CASE(sha256)
{
char const* sourceCode = "contract test {\n"
" function a(hash input) returns (hash sha256hash) {\n"
" function a(bytes32 input) returns (bytes32 sha256hash) {\n"
" return sha256(input);\n"
" }\n"
"}\n";
@ -1327,15 +1327,15 @@ BOOST_AUTO_TEST_CASE(sha256)
dev::sha256(dev::ref(toBigEndian(_input)), bytesRef(&ret[0], 32));
return ret;
};
testSolidityAgainstCpp("a(hash256)", f, u256(4));
testSolidityAgainstCpp("a(hash256)", f, u256(5));
testSolidityAgainstCpp("a(hash256)", f, u256(-1));
testSolidityAgainstCpp("a(bytes32)", f, u256(4));
testSolidityAgainstCpp("a(bytes32)", f, u256(5));
testSolidityAgainstCpp("a(bytes32)", f, u256(-1));
}
BOOST_AUTO_TEST_CASE(ripemd)
{
char const* sourceCode = "contract test {\n"
" function a(hash input) returns (hash sha256hash) {\n"
" function a(bytes32 input) returns (bytes32 sha256hash) {\n"
" return ripemd160(input);\n"
" }\n"
"}\n";
@ -1346,15 +1346,15 @@ BOOST_AUTO_TEST_CASE(ripemd)
dev::ripemd160(dev::ref(toBigEndian(_input)), bytesRef(&ret[0], 32));
return u256(ret) >> (256 - 160);
};
testSolidityAgainstCpp("a(hash256)", f, u256(4));
testSolidityAgainstCpp("a(hash256)", f, u256(5));
testSolidityAgainstCpp("a(hash256)", f, u256(-1));
testSolidityAgainstCpp("a(bytes32)", f, u256(4));
testSolidityAgainstCpp("a(bytes32)", f, u256(5));
testSolidityAgainstCpp("a(bytes32)", f, u256(-1));
}
BOOST_AUTO_TEST_CASE(ecrecover)
{
char const* sourceCode = "contract test {\n"
" function a(hash h, uint8 v, hash r, hash s) returns (address addr) {\n"
" function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) returns (address addr) {\n"
" return ecrecover(h, v, r, s);\n"
" }\n"
"}\n";
@ -1364,7 +1364,7 @@ BOOST_AUTO_TEST_CASE(ecrecover)
u256 r("0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f");
u256 s("0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549");
u160 addr("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b");
BOOST_CHECK(callContractFunction("a(hash256,uint8,hash256,hash256)", h, v, r, s) == encodeArgs(addr));
BOOST_CHECK(callContractFunction("a(bytes32,uint8,bytes32,bytes32)", h, v, r, s) == encodeArgs(addr));
}
BOOST_AUTO_TEST_CASE(inter_contract_calls)
@ -1524,17 +1524,17 @@ BOOST_AUTO_TEST_CASE(inter_contract_calls_with_local_vars)
BOOST_REQUIRE(callContractFunction("callHelper(uint256,uint256)", a, b) == encodeArgs(a * b + 9));
}
BOOST_AUTO_TEST_CASE(strings_in_calls)
BOOST_AUTO_TEST_CASE(fixed_bytes_in_calls)
{
char const* sourceCode = R"(
contract Helper {
function invoke(string3 x, bool stop) returns (string4 ret) {
function invoke(bytes3 x, bool stop) returns (bytes4 ret) {
return x;
}
}
contract Main {
Helper h;
function callHelper(string2 x, bool stop) returns (string5 ret) {
function callHelper(bytes2 x, bool stop) returns (bytes5 ret) {
return h.invoke(x, stop);
}
function getHelper() returns (address addr) {
@ -1549,21 +1549,21 @@ BOOST_AUTO_TEST_CASE(strings_in_calls)
compileAndRun(sourceCode, 0, "Main");
BOOST_REQUIRE(callContractFunction("setHelper(address)", c_helperAddress) == bytes());
BOOST_REQUIRE(callContractFunction("getHelper()", c_helperAddress) == encodeArgs(c_helperAddress));
BOOST_CHECK(callContractFunction("callHelper(string2,bool)", string("\0a", 2), true) == encodeArgs(string("\0a\0\0\0", 5)));
BOOST_CHECK(callContractFunction("callHelper(bytes2,bool)", string("\0a", 2), true) == encodeArgs(string("\0a\0\0\0", 5)));
}
BOOST_AUTO_TEST_CASE(constructor_arguments)
{
char const* sourceCode = R"(
contract Helper {
string3 name;
bytes3 name;
bool flag;
function Helper(string3 x, bool f) {
function Helper(bytes3 x, bool f) {
name = x;
flag = f;
}
function getName() returns (string3 ret) { return name; }
function getName() returns (bytes3 ret) { return name; }
function getFlag() returns (bool ret) { return flag; }
}
contract Main {
@ -1572,7 +1572,7 @@ BOOST_AUTO_TEST_CASE(constructor_arguments)
h = new Helper("abc", true);
}
function getFlag() returns (bool ret) { return h.getFlag(); }
function getName() returns (string3 ret) { return h.getName(); }
function getName() returns (bytes3 ret) { return h.getName(); }
})";
compileAndRun(sourceCode, 0, "Main");
BOOST_REQUIRE(callContractFunction("getFlag()") == encodeArgs(true));
@ -1583,13 +1583,13 @@ BOOST_AUTO_TEST_CASE(functions_called_by_constructor)
{
char const* sourceCode = R"(
contract Test {
string3 name;
bytes3 name;
bool flag;
function Test() {
setName("abc");
}
function getName() returns (string3 ret) { return name; }
function setName(string3 _name) private { name = _name; }
function getName() returns (bytes3 ret) { return name; }
function setName(bytes3 _name) private { name = _name; }
})";
compileAndRun(sourceCode);
BOOST_REQUIRE(callContractFunction("getName()") == encodeArgs("abc"));
@ -1647,6 +1647,21 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic)
BOOST_REQUIRE(callContractFunction("checkState()", 5) == encodeArgs(false, 20 - 5));
}
BOOST_AUTO_TEST_CASE(gas_for_builtin)
{
char const* sourceCode = R"(
contract Contract {
function test(uint g) returns (bytes32 data, bool flag) {
data = ripemd160.gas(g)("abc");
flag = true;
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test(uint256)", 500) == bytes());
BOOST_CHECK(callContractFunction("test(uint256)", 800) == encodeArgs(u256("0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"), true));
}
BOOST_AUTO_TEST_CASE(value_complex)
{
char const* sourceCode = R"(
@ -1697,13 +1712,13 @@ BOOST_AUTO_TEST_CASE(value_for_constructor)
{
char const* sourceCode = R"(
contract Helper {
string3 name;
bytes3 name;
bool flag;
function Helper(string3 x, bool f) {
function Helper(bytes3 x, bool f) {
name = x;
flag = f;
}
function getName() returns (string3 ret) { return name; }
function getName() returns (bytes3 ret) { return name; }
function getFlag() returns (bool ret) { return flag; }
}
contract Main {
@ -1712,7 +1727,7 @@ BOOST_AUTO_TEST_CASE(value_for_constructor)
h = new Helper.value(10)("abc", true);
}
function getFlag() returns (bool ret) { return h.getFlag(); }
function getName() returns (string3 ret) { return h.getName(); }
function getName() returns (bytes3 ret) { return h.getName(); }
function getBalances() returns (uint me, uint them) { me = this.balance; them = h.balance;}
})";
compileAndRun(sourceCode, 22, "Main");
@ -2090,13 +2105,13 @@ BOOST_AUTO_TEST_CASE(event)
{
char const* sourceCode = R"(
contract ClientReceipt {
event Deposit(address indexed _from, hash indexed _id, uint _value);
function deposit(hash _id, bool _manually) {
event Deposit(address indexed _from, bytes32 indexed _id, uint _value);
function deposit(bytes32 _id, bool _manually) {
if (_manually) {
hash s = 0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20;
log3(msg.value, s, hash32(msg.sender), _id);
bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;
log3(bytes32(msg.value), s, bytes32(msg.sender), _id);
} else
Deposit(hash32(msg.sender), _id, msg.value);
Deposit(msg.sender, _id, msg.value);
}
}
)";
@ -2105,12 +2120,12 @@ BOOST_AUTO_TEST_CASE(event)
u256 id(0x1234);
for (bool manually: {true, false})
{
callContractFunctionWithValue("deposit(hash256,bool)", value, id, manually);
callContractFunctionWithValue("deposit(bytes32,bool)", value, id, manually);
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(value)));
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 3);
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,hash256,uint256)")));
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,bytes32,uint256)")));
BOOST_CHECK_EQUAL(m_logs[0].topics[1], h256(m_sender));
BOOST_CHECK_EQUAL(m_logs[0].topics[2], h256(id));
}
@ -2139,21 +2154,21 @@ BOOST_AUTO_TEST_CASE(event_lots_of_data)
{
char const* sourceCode = R"(
contract ClientReceipt {
event Deposit(address _from, hash _id, uint _value, bool _flag);
function deposit(hash _id) {
Deposit(msg.sender, hash32(_id), msg.value, true);
event Deposit(address _from, bytes32 _id, uint _value, bool _flag);
function deposit(bytes32 _id) {
Deposit(msg.sender, _id, msg.value, true);
}
}
)";
compileAndRun(sourceCode);
u256 value(18);
u256 id(0x1234);
callContractFunctionWithValue("deposit(hash256)", value, id);
callContractFunctionWithValue("deposit(bytes32)", value, id);
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
BOOST_CHECK(m_logs[0].data == encodeArgs((u160)m_sender, id, value, true));
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,hash256,uint256,bool)")));
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,bytes32,uint256,bool)")));
}
BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
@ -2187,7 +2202,7 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments)
{
char const* sourceCode = R"(
contract c {
function foo(uint a, uint b, uint c) returns (hash d)
function foo(uint a, uint b, uint c) returns (bytes32 d)
{
d = sha3(a, b, c);
}
@ -2205,7 +2220,7 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals)
{
char const* sourceCode = R"(
contract c {
function foo(uint a, uint16 b) returns (hash d)
function foo(uint a, uint16 b) returns (bytes32 d)
{
d = sha3(a, b, 145);
}
@ -2223,11 +2238,11 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals)
{
char const* sourceCode = R"(
contract c {
function foo() returns (hash d)
function foo() returns (bytes32 d)
{
d = sha3("foo");
}
function bar(uint a, uint16 b) returns (hash d)
function bar(uint a, uint16 b) returns (bytes32 d)
{
d = sha3(a, b, 145, "foo");
}
@ -2254,7 +2269,7 @@ BOOST_AUTO_TEST_CASE(generic_call)
contract sender {
function doSend(address rec) returns (uint d)
{
string4 signature = string4(string32(sha3("receive(uint256)")));
bytes4 signature = bytes4(bytes32(sha3("receive(uint256)")));
rec.call.value(2)(signature, 23);
return receiver(rec).received();
}
@ -2290,7 +2305,7 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory)
{
char const* sourceCode = R"(
contract C {
function() returns (hash) {
function() returns (bytes32) {
return sha3("abc", msg.data);
}
}
@ -3181,7 +3196,6 @@ BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base_base_with_gap)
BOOST_CHECK(callContractFunction("m_i()") == encodeArgs(4));
}
BOOST_AUTO_TEST_SUITE_END()
}

10
test/SolidityInterface.cpp

@ -84,10 +84,10 @@ BOOST_AUTO_TEST_CASE(single_function)
BOOST_AUTO_TEST_CASE(single_constant_function)
{
ContractDefinition const& contract = checkInterface(
"contract test { function f(uint a) constant returns(hash8 x) { 1==2; } }");
"contract test { function f(uint a) constant returns(bytes1 x) { 1==2; } }");
BOOST_REQUIRE_EQUAL(1, contract.getDefinedFunctions().size());
BOOST_CHECK_EQUAL(getSourcePart(*contract.getDefinedFunctions().front()),
"function f(uint256 a)constant returns(hash8 x){}");
"function f(uint256 a)constant returns(bytes1 x){}");
}
BOOST_AUTO_TEST_CASE(multiple_functions)
@ -128,15 +128,15 @@ BOOST_AUTO_TEST_CASE(inheritance)
char const* sourceCode =
" contract Base { \n"
" function baseFunction(uint p) returns (uint i) { return p; } \n"
" event baseEvent(string32 indexed evtArgBase); \n"
" event baseEvent(bytes32 indexed evtArgBase); \n"
" } \n"
" contract Derived is Base { \n"
" function derivedFunction(string32 p) returns (string32 i) { return p; } \n"
" function derivedFunction(bytes32 p) returns (bytes32 i) { return p; } \n"
" event derivedEvent(uint indexed evtArgDerived); \n"
" }";
ContractDefinition const& contract = checkInterface(sourceCode);
set<string> expectedFunctions({"function baseFunction(uint256 p)returns(uint256 i){}",
"function derivedFunction(string32 p)returns(string32 i){}"});
"function derivedFunction(bytes32 p)returns(bytes32 i){}"});
BOOST_REQUIRE_EQUAL(2, contract.getDefinedFunctions().size());
BOOST_CHECK(expectedFunctions == set<string>({getSourcePart(*contract.getDefinedFunctions().at(0)),
getSourcePart(*contract.getDefinedFunctions().at(1))}));

147
test/SolidityNameAndTypeResolution.cpp

@ -75,6 +75,7 @@ static FunctionTypePointer const& retrieveFunctionBySignature(ContractDefinition
FixedHash<4> hash(dev::sha3(_signature));
return _contract->getInterfaceFunctions()[hash];
}
}
BOOST_AUTO_TEST_SUITE(SolidityNameAndTypeResolution)
@ -353,7 +354,7 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature)
" ret = arg1 + arg2;\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(sourceUnit = parseTextAndResolveNames(text));
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed");
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
@ -366,16 +367,16 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases)
{
ASTPointer<SourceUnit> sourceUnit;
char const* text = "contract Test {\n"
" function boo(uint arg1, hash arg2, address arg3) returns (uint ret) {\n"
" function boo(uint arg1, bytes32 arg2, address arg3) returns (uint ret) {\n"
" ret = 5;\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(sourceUnit = parseTextAndResolveNames(text));
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed");
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
auto functions = contract->getDefinedFunctions();
BOOST_CHECK_EQUAL("boo(uint256,hash256,address)", functions[0]->getCanonicalSignature());
BOOST_CHECK_EQUAL("boo(uint256,bytes32,address)", functions[0]->getCanonicalSignature());
}
}
@ -537,7 +538,7 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation)
contract B {
function f() mod1(2, true) mod2("0123456") { }
modifier mod1(uint a, bool b) { if (b) _ }
modifier mod2(string7 a) { while (a == "1234567") _ }
modifier mod2(bytes7 a) { while (a == "1234567") _ }
}
)";
ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed");
@ -558,9 +559,9 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters)
{
char const* text = R"(
contract B {
function f(uint8 a) mod1(a, true) mod2(r) returns (string7 r) { }
function f(uint8 a) mod1(a, true) mod2(r) returns (bytes7 r) { }
modifier mod1(uint a, bool b) { if (b) _ }
modifier mod2(string7 a) { while (a == "1234567") _ }
modifier mod2(bytes7 a) { while (a == "1234567") _ }
}
)";
ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed");
@ -631,8 +632,8 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors)
" uint64(2);\n"
" }\n"
"uint256 public foo;\n"
"mapping(uint=>string4) public map;\n"
"mapping(uint=>mapping(uint=>string4)) public multiple_map;\n"
"mapping(uint=>bytes4) public map;\n"
"mapping(uint=>mapping(uint=>bytes4)) public multiple_map;\n"
"}\n";
ASTPointer<SourceUnit> source;
@ -650,7 +651,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors)
auto params = function->getParameterTypeNames();
BOOST_CHECK_EQUAL(params.at(0), "uint256");
returnParams = function->getReturnParameterTypeNames();
BOOST_CHECK_EQUAL(returnParams.at(0), "string4");
BOOST_CHECK_EQUAL(returnParams.at(0), "bytes4");
BOOST_CHECK(function->isConstant());
function = retrieveFunctionBySignature(contract, "multiple_map(uint256,uint256)");
@ -659,7 +660,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors)
BOOST_CHECK_EQUAL(params.at(0), "uint256");
BOOST_CHECK_EQUAL(params.at(1), "uint256");
returnParams = function->getReturnParameterTypeNames();
BOOST_CHECK_EQUAL(returnParams.at(0), "string4");
BOOST_CHECK_EQUAL(returnParams.at(0), "bytes4");
BOOST_CHECK(function->isConstant());
}
@ -800,7 +801,7 @@ BOOST_AUTO_TEST_CASE(event)
{
char const* text = R"(
contract c {
event e(uint indexed a, string3 indexed s, bool indexed b);
event e(uint indexed a, bytes3 indexed s, bool indexed b);
function f() { e(2, "abc", true); }
})";
ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed");
@ -810,7 +811,7 @@ BOOST_AUTO_TEST_CASE(event_too_many_indexed)
{
char const* text = R"(
contract c {
event e(uint indexed a, string3 indexed b, bool indexed c, uint indexed d);
event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d);
function f() { e(2, "abc", true); }
})";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
@ -820,7 +821,7 @@ BOOST_AUTO_TEST_CASE(event_call)
{
char const* text = R"(
contract c {
event e(uint a, string3 indexed s, bool indexed b);
event e(uint a, bytes3 indexed s, bool indexed b);
function f() { e(2, "abc", true); }
})";
ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed");
@ -830,7 +831,7 @@ BOOST_AUTO_TEST_CASE(event_inheritance)
{
char const* text = R"(
contract base {
event e(uint a, string3 indexed s, bool indexed b);
event e(uint a, bytes3 indexed s, bool indexed b);
}
contract c is base {
function f() { e(2, "abc", true); }
@ -1287,6 +1288,122 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName)
{
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int) == *make_shared<IntegerType>(256, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int8) == *make_shared<IntegerType>(8, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int16) == *make_shared<IntegerType>(16, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int24) == *make_shared<IntegerType>(24, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int32) == *make_shared<IntegerType>(32, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int40) == *make_shared<IntegerType>(40, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int48) == *make_shared<IntegerType>(48, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int56) == *make_shared<IntegerType>(56, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int64) == *make_shared<IntegerType>(64, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int72) == *make_shared<IntegerType>(72, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int80) == *make_shared<IntegerType>(80, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int88) == *make_shared<IntegerType>(88, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int96) == *make_shared<IntegerType>(96, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int104) == *make_shared<IntegerType>(104, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int112) == *make_shared<IntegerType>(112, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int120) == *make_shared<IntegerType>(120, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int128) == *make_shared<IntegerType>(128, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int136) == *make_shared<IntegerType>(136, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int144) == *make_shared<IntegerType>(144, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int152) == *make_shared<IntegerType>(152, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int160) == *make_shared<IntegerType>(160, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int168) == *make_shared<IntegerType>(168, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int176) == *make_shared<IntegerType>(176, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int184) == *make_shared<IntegerType>(184, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int192) == *make_shared<IntegerType>(192, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int200) == *make_shared<IntegerType>(200, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int208) == *make_shared<IntegerType>(208, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int216) == *make_shared<IntegerType>(216, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int224) == *make_shared<IntegerType>(224, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int232) == *make_shared<IntegerType>(232, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int240) == *make_shared<IntegerType>(240, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int248) == *make_shared<IntegerType>(248, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int256) == *make_shared<IntegerType>(256, IntegerType::Modifier::Signed));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt) == *make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt8) == *make_shared<IntegerType>(8, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt16) == *make_shared<IntegerType>(16, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt24) == *make_shared<IntegerType>(24, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt32) == *make_shared<IntegerType>(32, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt40) == *make_shared<IntegerType>(40, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt48) == *make_shared<IntegerType>(48, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt56) == *make_shared<IntegerType>(56, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt64) == *make_shared<IntegerType>(64, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt72) == *make_shared<IntegerType>(72, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt80) == *make_shared<IntegerType>(80, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt88) == *make_shared<IntegerType>(88, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt96) == *make_shared<IntegerType>(96, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt104) == *make_shared<IntegerType>(104, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt112) == *make_shared<IntegerType>(112, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt120) == *make_shared<IntegerType>(120, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt128) == *make_shared<IntegerType>(128, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt136) == *make_shared<IntegerType>(136, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt144) == *make_shared<IntegerType>(144, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt152) == *make_shared<IntegerType>(152, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt160) == *make_shared<IntegerType>(160, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt168) == *make_shared<IntegerType>(168, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt176) == *make_shared<IntegerType>(176, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt184) == *make_shared<IntegerType>(184, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt192) == *make_shared<IntegerType>(192, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt200) == *make_shared<IntegerType>(200, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt208) == *make_shared<IntegerType>(208, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt216) == *make_shared<IntegerType>(216, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt224) == *make_shared<IntegerType>(224, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt232) == *make_shared<IntegerType>(232, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt240) == *make_shared<IntegerType>(240, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt248) == *make_shared<IntegerType>(248, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt256) == *make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Byte) == *make_shared<FixedBytesType>(1));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes0) == *make_shared<FixedBytesType>(0));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes1) == *make_shared<FixedBytesType>(1));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes2) == *make_shared<FixedBytesType>(2));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes3) == *make_shared<FixedBytesType>(3));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes4) == *make_shared<FixedBytesType>(4));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes5) == *make_shared<FixedBytesType>(5));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes6) == *make_shared<FixedBytesType>(6));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes7) == *make_shared<FixedBytesType>(7));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes8) == *make_shared<FixedBytesType>(8));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes9) == *make_shared<FixedBytesType>(9));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes10) == *make_shared<FixedBytesType>(10));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes11) == *make_shared<FixedBytesType>(11));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes12) == *make_shared<FixedBytesType>(12));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes13) == *make_shared<FixedBytesType>(13));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes14) == *make_shared<FixedBytesType>(14));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes15) == *make_shared<FixedBytesType>(15));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes16) == *make_shared<FixedBytesType>(16));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes17) == *make_shared<FixedBytesType>(17));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes18) == *make_shared<FixedBytesType>(18));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes19) == *make_shared<FixedBytesType>(19));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes20) == *make_shared<FixedBytesType>(20));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes21) == *make_shared<FixedBytesType>(21));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes22) == *make_shared<FixedBytesType>(22));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes23) == *make_shared<FixedBytesType>(23));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes24) == *make_shared<FixedBytesType>(24));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes25) == *make_shared<FixedBytesType>(25));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes26) == *make_shared<FixedBytesType>(26));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes27) == *make_shared<FixedBytesType>(27));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes28) == *make_shared<FixedBytesType>(28));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes29) == *make_shared<FixedBytesType>(29));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes30) == *make_shared<FixedBytesType>(30));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes31) == *make_shared<FixedBytesType>(31));
BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes32) == *make_shared<FixedBytesType>(32));
}
BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1)
{
char const* text = R"(
contract c {
bytes arr;
function f() { byte a = arr[0];}
})";
ETH_TEST_REQUIRE_NO_THROW(parseTextAndResolveNames(text), "Type resolving failed");
}
BOOST_AUTO_TEST_SUITE_END()
}

52
test/SolidityParser.cpp

@ -83,7 +83,7 @@ BOOST_AUTO_TEST_CASE(empty_function)
{
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" function functionName(hash160 arg1, address addr) constant\n"
" function functionName(bytes20 arg1, address addr) constant\n"
" returns (int id)\n"
" { }\n"
"}\n";
@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE(single_function_param)
{
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" function functionName(hash hashin) returns (hash hashout) {}\n"
" function functionName(bytes32 input) returns (bytes32 out) {}\n"
"}\n";
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed.");
}
@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation)
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" /// This is a test function\n"
" function functionName(hash hashin) returns (hash hashout) {}\n"
" function functionName(bytes32 input) returns (bytes32 out) {}\n"
"}\n";
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
auto functions = contract->getDefinedFunctions();
@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(function_normal_comments)
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" // We won't see this comment\n"
" function functionName(hash hashin) returns (hash hashout) {}\n"
" function functionName(bytes32 input) returns (bytes32 out) {}\n"
"}\n";
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
auto functions = contract->getDefinedFunctions();
@ -164,13 +164,13 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation)
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" /// This is test function 1\n"
" function functionName1(hash hashin) returns (hash hashout) {}\n"
" function functionName1(bytes32 input) returns (bytes32 out) {}\n"
" /// This is test function 2\n"
" function functionName2(hash hashin) returns (hash hashout) {}\n"
" function functionName2(bytes32 input) returns (bytes32 out) {}\n"
" // nothing to see here\n"
" function functionName3(hash hashin) returns (hash hashout) {}\n"
" function functionName3(bytes32 input) returns (bytes32 out) {}\n"
" /// This is test function 4\n"
" function functionName4(hash hashin) returns (hash hashout) {}\n"
" function functionName4(bytes32 input) returns (bytes32 out) {}\n"
"}\n";
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
auto functions = contract->getDefinedFunctions();
@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation)
" uint256 stateVar;\n"
" /// This is a test function\n"
" /// and it has 2 lines\n"
" function functionName1(hash hashin) returns (hash hashout) {}\n"
" function functionName1(bytes32 input) returns (bytes32 out) {}\n"
"}\n";
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
auto functions = contract->getDefinedFunctions();
@ -217,12 +217,12 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body)
" var b;\n"
" /// I should not interfere with actual natspec comments\n"
" uint256 c;\n"
" mapping(address=>hash) d;\n"
" string name = \"Solidity\";"
" mapping(address=>bytes32) d;\n"
" bytes7 name = \"Solidity\";"
" }\n"
" /// This is a test function\n"
" /// and it has 2 lines\n"
" function fun(hash hashin) returns (hash hashout) {}\n"
" function fun(bytes32 input) returns (bytes32 out) {}\n"
"}\n";
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
auto functions = contract->getDefinedFunctions();
@ -246,8 +246,8 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature)
" var b;\n"
" /// I should not interfere with actual natspec comments\n"
" uint256 c;\n"
" mapping(address=>hash) d;\n"
" string name = \"Solidity\";"
" mapping(address=>bytes32) d;\n"
" bytes7 name = \"Solidity\";"
" }\n"
"}\n";
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
@ -269,8 +269,8 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature)
" var b;\n"
" /// I should not interfere with actual natspec comments\n"
" uint256 c;\n"
" mapping(address=>hash) d;\n"
" string name = \"Solidity\";"
" mapping(address=>bytes32) d;\n"
" bytes7 name = \"Solidity\";"
" }\n"
"}\n";
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
@ -296,7 +296,7 @@ BOOST_AUTO_TEST_CASE(struct_definition)
BOOST_AUTO_TEST_CASE(mapping)
{
char const* text = "contract test {\n"
" mapping(address => string) names;\n"
" mapping(address => bytes32) names;\n"
"}\n";
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
}
@ -307,7 +307,7 @@ BOOST_AUTO_TEST_CASE(mapping_in_struct)
" struct test_struct {\n"
" address addr;\n"
" uint256 count;\n"
" mapping(hash => test_struct) self_reference;\n"
" mapping(bytes32 => test_struct) self_reference;\n"
" }\n"
"}\n";
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(mapping_to_mapping_in_struct)
char const* text = "contract test {\n"
" struct test_struct {\n"
" address addr;\n"
" mapping (uint64 => mapping (hash => uint)) complex_mapping;\n"
" mapping (uint64 => mapping (bytes32 => uint)) complex_mapping;\n"
" }\n"
"}\n";
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
@ -330,7 +330,7 @@ BOOST_AUTO_TEST_CASE(variable_definition)
" function fun(uint256 a) {\n"
" var b;\n"
" uint256 c;\n"
" mapping(address=>hash) d;\n"
" mapping(address=>bytes32) d;\n"
" customtype varname;\n"
" }\n"
"}\n";
@ -343,8 +343,8 @@ BOOST_AUTO_TEST_CASE(variable_definition_with_initialization)
" function fun(uint256 a) {\n"
" var b = 2;\n"
" uint256 c = 0x87;\n"
" mapping(address=>hash) d;\n"
" string name = \"Solidity\";"
" mapping(address=>bytes32) d;\n"
" bytes7 name = \"Solidity\";"
" customtype varname;\n"
" }\n"
"}\n";
@ -366,7 +366,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_mapping)
char const* text = R"(
contract test {
function fun() {
mapping(var=>hash) d;
mapping(var=>bytes32) d;
}
}
)";
@ -662,7 +662,7 @@ BOOST_AUTO_TEST_CASE(event_arguments)
{
char const* text = R"(
contract c {
event e(uint a, string32 s);
event e(uint a, bytes32 s);
})";
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
}
@ -671,7 +671,7 @@ BOOST_AUTO_TEST_CASE(event_arguments_indexed)
{
char const* text = R"(
contract c {
event e(uint a, string32 indexed s, bool indexed b);
event e(uint a, bytes32 indexed s, bool indexed b);
})";
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
}
@ -799,7 +799,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_events)
{
char const* text = R"(
contract c {
event e(uint[10] a, string7[8] indexed b, c[3] x);
event e(uint[10] a, bytes7[8] indexed b, c[3] x);
})";
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
}

83
test/Stats.cpp

@ -0,0 +1,83 @@
/*
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/>.
*/
#include "Stats.h"
#include <iterator>
#include <numeric>
namespace dev
{
namespace test
{
Stats& Stats::get()
{
static Stats instance;
return instance;
}
void Stats::testStarted(std::string const& _name)
{
m_currentTest = _name;
m_tp = clock::now();
}
void Stats::testFinished()
{
m_stats[clock::now() - m_tp] = std::move(m_currentTest);
}
std::ostream& operator<<(std::ostream& out, Stats::clock::duration const& d)
{
return out << std::setw(10) << std::right << std::chrono::duration_cast<std::chrono::microseconds>(d).count() << " us";
}
Stats::~Stats()
{
if (m_stats.empty())
return;
auto& out = std::cout;
auto itr = m_stats.begin();
auto min = *itr;
auto max = *m_stats.rbegin();
std::advance(itr, m_stats.size() / 2);
auto med = *itr;
auto tot = std::accumulate(m_stats.begin(), m_stats.end(), clock::duration{}, [](clock::duration const& a, stats_t::value_type const& v)
{
return a + v.first;
});
out << "\nSTATS:\n\n" << std::setfill(' ');
if (Options::get().statsFull)
{
for (auto&& s: m_stats)
out << " " << std::setw(40) << std::left << s.second.substr(0, 40) << s.first << " \n";
out << "\n";
}
out << " tot: " << tot << "\n"
<< " avg: " << (tot / m_stats.size()) << "\n\n"
<< " min: " << min.first << " (" << min.second << ")\n"
<< " med: " << med.first << " (" << med.second << ")\n"
<< " max: " << max.first << " (" << max.second << ")\n";
}
}
}

50
test/Stats.h

@ -0,0 +1,50 @@
/*
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/>.
*/
#pragma once
#include <chrono>
#include <map>
#include "TestHelper.h"
namespace dev
{
namespace test
{
class Stats: public Listener
{
public:
using clock = std::chrono::high_resolution_clock;
using stats_t = std::map<clock::duration, std::string>;
static Stats& get();
~Stats();
void testStarted(std::string const& _name) override;
void testFinished() override;
private:
clock::time_point m_tp;
std::string m_currentTest;
stats_t m_stats;
};
}
}

62
test/TestHelper.cpp

@ -84,12 +84,12 @@ ImportTest::ImportTest(json_spirit::mObject& _o, bool isFiller) : m_statePre(Add
void ImportTest::importEnv(json_spirit::mObject& _o)
{
BOOST_REQUIRE(_o.count("previousHash") > 0);
BOOST_REQUIRE(_o.count("currentGasLimit") > 0);
BOOST_REQUIRE(_o.count("currentDifficulty") > 0);
BOOST_REQUIRE(_o.count("currentTimestamp") > 0);
BOOST_REQUIRE(_o.count("currentCoinbase") > 0);
BOOST_REQUIRE(_o.count("currentNumber") > 0);
assert(_o.count("previousHash") > 0);
assert(_o.count("currentGasLimit") > 0);
assert(_o.count("currentDifficulty") > 0);
assert(_o.count("currentTimestamp") > 0);
assert(_o.count("currentCoinbase") > 0);
assert(_o.count("currentNumber") > 0);
m_environment.previousBlock.hash = h256(_o["previousHash"].get_str());
m_environment.currentBlock.number = toInt(_o["currentNumber"]);
@ -108,10 +108,10 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state)
{
json_spirit::mObject o = i.second.get_obj();
BOOST_REQUIRE(o.count("balance") > 0);
BOOST_REQUIRE(o.count("nonce") > 0);
BOOST_REQUIRE(o.count("storage") > 0);
BOOST_REQUIRE(o.count("code") > 0);
assert(o.count("balance") > 0);
assert(o.count("nonce") > 0);
assert(o.count("storage") > 0);
assert(o.count("code") > 0);
if (bigint(o["balance"].get_str()) >= c_max256plus1)
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'balance' is equal or greater than 2**256") );
@ -144,12 +144,12 @@ void ImportTest::importTransaction(json_spirit::mObject& _o)
{
if (_o.count("secretKey") > 0)
{
BOOST_REQUIRE(_o.count("nonce") > 0);
BOOST_REQUIRE(_o.count("gasPrice") > 0);
BOOST_REQUIRE(_o.count("gasLimit") > 0);
BOOST_REQUIRE(_o.count("to") > 0);
BOOST_REQUIRE(_o.count("value") > 0);
BOOST_REQUIRE(_o.count("data") > 0);
assert(_o.count("nonce") > 0);
assert(_o.count("gasPrice") > 0);
assert(_o.count("gasLimit") > 0);
assert(_o.count("to") > 0);
assert(_o.count("value") > 0);
assert(_o.count("data") > 0);
if (bigint(_o["nonce"].get_str()) >= c_max256plus1)
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") );
@ -473,7 +473,7 @@ void executeTests(const string& _name, const string& _testPathAppendix, std::fun
try
{
cnote << "Testing ..." << _name;
std::cout << "TEST " << _name << ":\n";
json_spirit::mValue v;
string s = asString(dev::contents(testPath + "/" + _name + ".json"));
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + testPath + "/" + _name + ".json is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?");
@ -551,6 +551,10 @@ Options::Options()
vmtrace = true;
else if (arg == "--filltests")
fillTests = true;
else if (arg == "--stats")
stats = true;
else if (arg == "--stats=full")
stats = statsFull = true;
else if (arg == "--performance")
performance = true;
else if (arg == "--quadratic")
@ -578,6 +582,7 @@ Options const& Options::get()
return instance;
}
LastHashes lastHashes(u256 _currentBlockNumber)
{
LastHashes ret;
@ -586,4 +591,27 @@ LastHashes lastHashes(u256 _currentBlockNumber)
return ret;
}
namespace
{
Listener* g_listener;
}
void Listener::registerListener(Listener& _listener)
{
g_listener = &_listener;
}
void Listener::notifyTestStarted(std::string const& _name)
{
if (g_listener)
g_listener->testStarted(_name);
}
void Listener::notifyTestFinished()
{
if (g_listener)
g_listener->testFinished();
}
} } // namespaces

30
test/TestHelper.h

@ -162,8 +162,9 @@ class Options
public:
bool jit = false; ///< Use JIT
bool vmtrace = false; ///< Create EVM execution tracer // TODO: Link with log verbosity?
bool showTimes = false; ///< Print test groups execution times
bool fillTests = false; ///< Create JSON test files from execution results
bool stats = false; ///< Execution time stats
bool statsFull = false; ///< Output full stats - execution times for every test
/// Test selection
/// @{
@ -183,5 +184,32 @@ private:
Options(Options const&) = delete;
};
/// Allows observing test execution process.
/// This class also provides methods for registering and notifying the listener
class Listener
{
public:
virtual ~Listener() = default;
virtual void testStarted(std::string const& _name) = 0;
virtual void testFinished() = 0;
static void registerListener(Listener& _listener);
static void notifyTestStarted(std::string const& _name);
static void notifyTestFinished();
/// Test started/finished notification RAII helper
class ExecTimeGuard
{
public:
ExecTimeGuard(std::string const& _testName) { notifyTestStarted(_testName); }
~ExecTimeGuard() { notifyTestFinished(); }
ExecTimeGuard(ExecTimeGuard const&) = delete;
ExecTimeGuard& operator=(ExecTimeGuard) = delete;
};
};
}
}

1
test/bcBlockChainTestFiller.json

@ -13,7 +13,6 @@
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"

14
test/bcInvalidHeaderTestFiller.json

@ -8,7 +8,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -64,7 +63,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -120,7 +118,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -175,7 +172,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -230,7 +226,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -285,7 +280,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -341,7 +335,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -396,7 +389,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -451,7 +443,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -506,7 +497,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -561,7 +551,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -616,7 +605,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -671,7 +659,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -726,7 +713,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",

13
test/bcUncleTestFiller.json

@ -13,7 +13,6 @@
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
@ -68,7 +67,6 @@
"number" : "1",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "0x54c98c82",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
@ -93,7 +91,6 @@
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
@ -163,7 +160,6 @@
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "0x54c98c82",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
@ -188,7 +184,6 @@
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
@ -258,7 +253,6 @@
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "0x54c98c82",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
@ -286,7 +280,6 @@
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
@ -356,7 +349,6 @@
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "0x54c98c82",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
@ -375,7 +367,6 @@
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "0x54c98c82",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
@ -400,7 +391,6 @@
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
@ -470,7 +460,6 @@
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "0x54c98c82",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
@ -489,7 +478,6 @@
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "0x54c98c82",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
@ -508,7 +496,6 @@
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "0x54c98c82",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",

8
test/bcValidBlockTestFiller.json

@ -9,7 +9,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -56,7 +55,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -102,7 +100,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -148,7 +145,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -194,7 +190,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -249,7 +244,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -304,7 +298,6 @@
"gasLimit" : "125000",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
@ -356,7 +349,6 @@
"gasLimit" : "125000",
"gasUsed" : "100",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"number" : "0",
"parentHash" : "0xefb4db878627027c81b3bb1c7dd3a18dae3914a49cdd24a3e40ab3bbfbb240c5",

6
test/blockchain.cpp

@ -386,7 +386,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
{
mObject uBlH = uBlHeaderObj.get_obj();
cout << "uBlH.size(): " << uBlH.size() << endl;
BOOST_REQUIRE(uBlH.size() == 17);
BOOST_REQUIRE(uBlH.size() == 16);
bytes uncleRLP = createBlockRLPFromFields(uBlH);
const RLP c_uRLP(uncleRLP);
BlockInfo uncleBlockHeader;
@ -533,7 +533,7 @@ void overwriteBlockHeader(BlockInfo& _current_BlockHeader, mObject& _blObj)
std::pair<MineInfo, Ethash::Proof> ret;
while (!ProofOfWork::verify(_current_BlockHeader))
{
ret = pow.mine(_current_BlockHeader, 1000, true, true); // tie(ret, blockFromFields.nonce)
ret = pow.mine(_current_BlockHeader, 1000, true, true);
Ethash::assignResult(ret.second, _current_BlockHeader);
}
}
@ -580,7 +580,7 @@ void updatePoW(BlockInfo& _bi)
std::pair<MineInfo, Ethash::Proof> ret;
while (!ProofOfWork::verify(_bi))
{
ret = pow.mine(_bi, 10000, true, true); // tie(ret, blockFromFields.nonce)
ret = pow.mine(_bi, 10000, true, true);
Ethash::assignResult(ret.second, _bi);
}
_bi.hash = _bi.headerHash(WithNonce);

228
test/checkRandomStateTest.cpp

@ -0,0 +1,228 @@
/*
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 checkRandomStateTest.cpp
* @author Christoph Jentzsch <jentzsch.simulationsoftware@gmail.com>
* @date 2015
* Check a random test and return 0/1 for success or failure. To be used for efficiency in the random test simulation.
*/
#include <libdevcore/Common.h>
#include <libdevcore/Exceptions.h>
#include <libdevcore/Log.h>
#include <libevm/VMFactory.h>
#include "TestHelper.h"
#include "vm.h"
#pragma GCC diagnostic ignored "-Wunused-parameter"
using namespace std;
using namespace json_spirit;
using namespace dev::test;
using namespace dev;
bool doStateTest(mValue& _v);
int main(int argc, char *argv[])
{
g_logVerbosity = 0;
bool ret = false;
try
{
mValue v;
string s;
for (int i = 1; i < argc; ++i)
s += argv[i];
if (asserts(s.length() > 0))
{
cout << "Content of argument is empty\n";
return 1;
}
read_string(s, v);
ret = doStateTest(v);
}
catch (Exception const& _e)
{
cout << "Failed test with Exception: " << diagnostic_information(_e) << endl;
ret = false;
}
catch (std::exception const& _e)
{
cout << "Failed test with Exception: " << _e.what() << endl;
ret = false;
}
return ret;
}
bool doStateTest(mValue& _v)
{
eth::VMFactory::setKind(eth::VMKind::JIT);
for (auto& i: _v.get_obj())
{
mObject& o = i.second.get_obj();
assert(o.count("env") > 0);
assert(o.count("pre") > 0);
assert(o.count("transaction") > 0);
ImportTest importer(o, false);
eth::State theState = importer.m_statePre;
bytes tx = importer.m_transaction.rlp();
bytes output;
try
{
theState.execute(lastHashes(importer.m_environment.currentBlock.number), tx, &output);
}
catch (Exception const& _e)
{
cnote << "state execution did throw an exception: " << diagnostic_information(_e);
theState.commit();
}
catch (std::exception const& _e)
{
cnote << "state execution did throw an exception: " << _e.what();
}
assert(o.count("post") > 0);
assert(o.count("out") > 0);
//checkOutput(output, o);
int j = 0;
if (o["out"].type() == array_type)
for (auto const& d: o["out"].get_array())
{
if (asserts(output[j] == toInt(d)))
{
cout << "Output byte [" << j << "] different!";
return 1;
}
++j;
}
else if (o["out"].get_str().find("0x") == 0)
{
if (asserts(output == fromHex(o["out"].get_str().substr(2))))
return 1;
}
else
{
if (asserts(output == fromHex(o["out"].get_str())))
return 1;
}
//checkLog(theState.pending().size() ? theState.log(0) : LogEntries(), importer.m_environment.sub.logs);
eth::LogEntries logs = theState.pending().size() ? theState.log(0) : eth::LogEntries();
if (assertsEqual(logs.size(), importer.m_environment.sub.logs.size()))
return 1;
for (size_t i = 0; i < logs.size(); ++i)
{
if (assertsEqual(logs[i].address, importer.m_environment.sub.logs[i].address))
return 1;
if (assertsEqual(logs[i].topics, importer.m_environment.sub.logs[i].topics))
return 1;
if (asserts(logs[i].data == importer.m_environment.sub.logs[i].data))
return 1;
}
// check addresses
#if ETH_FATDB
auto expectedAddrs = importer.m_statePost.addresses();
auto resultAddrs = theState.addresses();
for (auto& expectedPair : expectedAddrs)
{
auto& expectedAddr = expectedPair.first;
auto resultAddrIt = resultAddrs.find(expectedAddr);
if (resultAddrIt == resultAddrs.end())
{
cout << "Missing expected address " << expectedAddr;
return 1;
}
else
{
if (importer.m_statePost.balance(expectedAddr) != theState.balance(expectedAddr))
{
cout << expectedAddr << ": incorrect balance " << theState.balance(expectedAddr) << ", expected " << importer.m_statePost.balance(expectedAddr);
return 1;
}
if (importer.m_statePost.transactionsFrom(expectedAddr) != theState.transactionsFrom(expectedAddr))
{
cout << expectedAddr << ": incorrect txCount " << theState.transactionsFrom(expectedAddr) << ", expected " << importer.m_statePost.transactionsFrom(expectedAddr);
return 1;
}
if (importer.m_statePost.code(expectedAddr) != theState.code(expectedAddr))
{
cout << expectedAddr << ": incorrect code";
return 1;
}
//checkStorage(importer.m_statePost.storage(expectedAddr), theState.storage(expectedAddr), expectedAddr);
map<u256, u256> _resultStore = theState.storage(expectedAddr);
for (auto&& expectedStorePair : importer.m_statePost.storage(expectedAddr))
{
auto& expectedStoreKey = expectedStorePair.first;
auto resultStoreIt = _resultStore.find(expectedStoreKey);
if (resultStoreIt == _resultStore.end())
{
cout << expectedAddr << ": missing store key " << expectedStoreKey << endl;
return 1;
}
else
{
auto& expectedStoreValue = expectedStorePair.second;
auto& resultStoreValue = resultStoreIt->second;
if (asserts(expectedStoreValue == resultStoreValue))
{
cout << expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue << endl;
return 1;
}
}
}
if (assertsEqual(_resultStore.size(), importer.m_statePost.storage(expectedAddr).size()))
return 1;
for (auto&& resultStorePair: _resultStore)
{
if (!importer.m_statePost.storage(expectedAddr).count(resultStorePair.first))
{
cout << expectedAddr << ": unexpected store key " << resultStorePair.first << endl;
return 1;
}
}
}
}
//checkAddresses<map<Address, u256> >(expectedAddrs, resultAddrs);
for (auto& resultPair : resultAddrs)
{
auto& resultAddr = resultPair.first;
auto expectedAddrIt = expectedAddrs.find(resultAddr);
if (expectedAddrIt == expectedAddrs.end())
return 1;
}
if (expectedAddrs != resultAddrs)
return 1;
#endif
if (theState.rootHash() != h256(o["postStateRoot"].get_str()))
{
cout << "wrong post state root" << endl;
return 1;
}
}
return 0;
}

6
test/checkRandomTest.cpp → test/checkRandomVMTest.cpp

@ -32,7 +32,7 @@ using namespace json_spirit;
using namespace dev::test;
using namespace dev;
bool doVMTest(mValue& v);
bool doVMTest(mValue& _v);
int main(int argc, char *argv[])
{
@ -66,11 +66,11 @@ int main(int argc, char *argv[])
return ret;
}
bool doVMTest(mValue& v)
bool doVMTest(mValue& _v)
{
eth::VMFactory::setKind(eth::VMKind::JIT);
for (auto& i: v.get_obj())
for (auto& i: _v.get_obj())
{
cnote << i.first;
mObject& o = i.second.get_obj();

183
test/createRandomStateTest.cpp

@ -0,0 +1,183 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file createRandomStateTest.cpp
* @author Christoph Jentzsch <jentzsch.simulationsoftware@gmail.com>
* @date 2015
* Creating a random state test.
*/
#include <string>
#include <iostream>
#include <chrono>
#include <boost/random.hpp>
#include <boost/filesystem/path.hpp>
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <json_spirit/json_spirit.h>
#include <json_spirit/json_spirit_reader_template.h>
#include <json_spirit/json_spirit_writer_template.h>
#include <libdevcore/CommonIO.h>
#include <libdevcore/CommonData.h>
#include <libevmcore/Instruction.h>
#include <libevm/VMFactory.h>
#include "TestHelper.h"
#include "vm.h"
using namespace std;
using namespace json_spirit;
using namespace dev;
void doStateTests(json_spirit::mValue& _v);
int main(int argc, char *argv[])
{
g_logVerbosity = 0;
// create random code
boost::random::mt19937 gen;
auto now = chrono::steady_clock::now().time_since_epoch();
auto timeSinceEpoch = chrono::duration_cast<chrono::nanoseconds>(now).count();
gen.seed(static_cast<unsigned int>(timeSinceEpoch));
boost::random::uniform_int_distribution<> lengthOfCodeDist(2, 16);
boost::random::uniform_int_distribution<> opcodeDist(0, 255);
boost::random::uniform_int_distribution<> BlockInfoOpcodeDist(0x40, 0x45);
boost::random::variate_generator<boost::mt19937&, boost::random::uniform_int_distribution<> > randGen(gen, opcodeDist);
boost::random::variate_generator<boost::mt19937&, boost::random::uniform_int_distribution<> > randGenBlockInfoOpcode(gen, BlockInfoOpcodeDist);
int lengthOfCode = lengthOfCodeDist(gen);
string randomCode;
for (int i = 0; i < lengthOfCode; ++i)
{
if (i < 8 && (randGen() < 192))
{
randomCode += toHex(toCompactBigEndian((uint8_t)randGenBlockInfoOpcode()));
continue;
}
uint8_t opcode = randGen();
// disregard all invalid commands, except of one (0x0c)
if ((dev::eth::isValidInstruction(dev::eth::Instruction(opcode)) || (randGen() > 250)))
randomCode += toHex(toCompactBigEndian(opcode));
else
i--;
}
string const s = R"(
{
"randomStatetest" : {
"env" : {
"currentCoinbase" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
"currentDifficulty" : "5623894562375",
"currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"code" : "0x6001600101600055",
"nonce" : "0",
"storage" : {
}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "46",
"code" : "0x6000355415600957005b60203560003555",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x42",
"gasLimit" : "400000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000"
}
}
}
)";
mValue v;
read_string(s, v);
// insert new random code
v.get_obj().find("randomStatetest")->second.get_obj().find("pre")->second.get_obj().begin()->second.get_obj()["code"] = "0x" + randomCode + (randGen() > 128 ? "55" : "");
// fill test
doStateTests(v);
// stream to output for further handling by the bash script
cout << json_spirit::write_string(v, true);
return 0;
}
void doStateTests(json_spirit::mValue& _v)
{
eth::VMFactory::setKind(eth::VMKind::Interpreter);
for (auto& i: _v.get_obj())
{
//cerr << i.first << endl;
mObject& o = i.second.get_obj();
assert(o.count("env") > 0);
assert(o.count("pre") > 0);
assert(o.count("transaction") > 0);
test::ImportTest importer(o, true);
eth::State theState = importer.m_statePre;
bytes tx = importer.m_transaction.rlp();
bytes output;
try
{
theState.execute(test::lastHashes(importer.m_environment.currentBlock.number), tx, &output);
}
catch (Exception const& _e)
{
cnote << "state execution did throw an exception: " << diagnostic_information(_e);
theState.commit();
}
catch (std::exception const& _e)
{
cnote << "state execution did throw an exception: " << _e.what();
}
#if ETH_FATDB
importer.exportTest(output, theState);
#else
cout << "You can not fill tests when FATDB is switched off";
#endif
}
}

6
test/createRandomTest.cpp → test/createRandomVMTest.cpp

@ -41,7 +41,7 @@ using namespace std;
using namespace json_spirit;
using namespace dev;
void doMyTests(json_spirit::mValue& v);
void doMyTests(json_spirit::mValue& _v);
int main(int argc, char *argv[])
{
@ -127,11 +127,11 @@ int main(int argc, char *argv[])
return 0;
}
void doMyTests(json_spirit::mValue& v)
void doMyTests(json_spirit::mValue& _v)
{
eth::VMFactory::setKind(eth::VMKind::Interpreter);
for (auto& i: v.get_obj())
for (auto& i: _v.get_obj())
{
cnote << i.first;
mObject& o = i.second.get_obj();

14
test/stPreCompiledContractsFiller.json

@ -12,7 +12,7 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
"nonce" : "0",
"code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }",
"code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
@ -46,7 +46,7 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
"nonce" : "0",
"code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 100000 1 0 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }",
"code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
@ -81,7 +81,7 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
"nonce" : "0",
"code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) }",
"code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 3000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) }",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
@ -217,7 +217,7 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
"nonce" : "0",
"code": "{ [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }",
"code": "{ [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
@ -230,7 +230,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "365224",
"gasLimit" : "3652240",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -421,7 +421,7 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "200000000",
"nonce" : "0",
"code" : "{ [[ 2 ]] (CALL 20000000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}",
"code" : "{ [[ 2 ]] (CALL 200000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
@ -591,7 +591,7 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
"nonce" : "0",
"code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 500 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}",
"code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {

639
test/stSolidityTestFiller.json

@ -1,83 +1,24 @@
{
"SolidityTest" : {
"TestCryptographicFunctions" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000000000000000000000",
"currentGasLimit" : "1000000000000000000000",
"currentNumber" : "120",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"code" : "",
"nonce" : "0",
"storage" : {
}
},
"d94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000",
"//" : " ",
"//" : "contract TestContract ",
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100000",
"//" : "contract main ",
"//" : "{ ",
"//" : " function testMethod() returns (int res) ",
"//" : " function run() returns (bool) ",
"//" : " { ",
"//" : " return 225; ",
"//" : " } ",
"//" : " ",
"//" : " function destroy(address sendFoundsTo) ",
"//" : " { ",
"//" : " suicide(sendFoundsTo); ",
"//" : " } ",
"//" : "} ",
"//" : " ",
"//" : "contract TestSolidityContracts ",
"//" : "{ ",
"//" : "struct StructTest ",
"//" : " { ",
"//" : " address addr; ",
"//" : " int amount; ",
"//" : " string32 str; ",
"//" : " mapping (uint => address) funders; ",
"//" : " } ",
"//" : " ",
"//" : " int globalValue; ",
"//" : " StructTest globalData; ",
"//" : " function runSolidityTests() returns (hash res) ",
"//" : " { ",
"//" : " //res is a mask of failing tests given the first byte is first test ",
"//" : " res = 0x0000000000000000000000000000000000000000000000000000000000000000; ",
"//" : " ",
"//" : " createContractFromMethod(); ",
"//" : " ",
"//" : " if (!testKeywords()) ",
"//" : " res = hash(int(res) + int(0xf000000000000000000000000000000000000000000000000000000000000000)); ",
"//" : " ",
"//" : " if (!testContractInteraction()) ",
"//" : " res = hash(int(res) + int(0x0f00000000000000000000000000000000000000000000000000000000000000)); ",
"//" : " ",
"//" : " if (!testContractSuicide()) ",
"//" : " res = hash(int(res) + int(0x00f0000000000000000000000000000000000000000000000000000000000000)); ",
"//" : " ",
"//" : " if (!testBlockAndTransactionProperties()) ",
"//" : " res = hash(int(res) + int(0x000f000000000000000000000000000000000000000000000000000000000000)); ",
"//" : " ",
"//" : " globalValue = 255; ",
"//" : " globalData.addr = 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b; ",
"//" : " globalData.amount = 255; ",
"//" : " globalData.str = 'global data 32 length string'; ",
"//" : " globalData.funders[0] = 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b; ",
"//" : " if (!testStructuresAndVariabless()) ",
"//" : " res = hash(int(res) + int(0x0000f00000000000000000000000000000000000000000000000000000000000)); ",
"//" : " ",
"//" : " if (!testCryptographicFunctions()) ",
"//" : " res = hash(int(res) + int(0x00000f0000000000000000000000000000000000000000000000000000000000)); ",
"//" : " ",
"//" : " } ",
"//" : " ",
"//" : " return testCryptographicFunctions(); ",
"//" : " } ",
"//" : " ",
"//" : " function testCryptographicFunctions() returns (bool res) ",
"//" : " { ",
"//" : " res = true; ",
@ -92,139 +33,463 @@
"//" : " ",
"//" : " //ecrecover ",
"//" : " } ",
"//" : " ",
"//" : " function testStructuresAndVariabless() returns (bool res) ",
"//" : " { ",
"//" : " res = true; ",
"//" : " if (globalValue != 255) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (globalValue != globalData.amount) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (globalData.addr != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (globalData.str != 'global data 32 length string') ",
"//" : " return false; ",
"//" : " ",
"//" : " if (globalData.funders[0] != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ",
"//" : " return false; ",
"//" : " } ",
"//" : " ",
"//" : " function testBlockAndTransactionProperties() returns (bool res) ",
"//" : " { ",
"//" : " res = true; ",
"//" : " if (block.coinbase != 0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (block.difficulty != 45678256) ",
"//" : " return false; ",
"//" : " ",
"//" : " //for some reason does not work 27.01.2015 ",
"//" : " if (block.gaslimit != 1000000000000000000000) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (block.number != 120) ",
"//" : " return false; ",
"//" : " ",
"//" : " //try to call this ",
"//" : " block.blockhash(120); ",
"//" : " block.timestamp; ",
"//" : " msg.gas; ",
"//" : " ",
"//" : " if (msg.sender != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (msg.value != 100) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (tx.gasprice != 1) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (tx.origin != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ",
"//" : " return false; ",
"//" : " ",
"//" : " } ",
"//" : " ",
"//" : " function testContractSuicide() returns (bool res) ",
"//" : " { ",
"//" : " TestContract a = new TestContract(); ",
"//" : " a.destroy(block.coinbase); ",
"//" : " if (a.testMethod() == 225) //we should be able to call a contract ",
"//" : " return true; ",
"//" : " return false; ",
"//" : " } ",
"//" : " ",
"//" : " function testContractInteraction() returns (bool res) ",
"//" : " { ",
"//" : " TestContract a = new TestContract(); ",
"//" : " if (a.testMethod() == 225) ",
"//" : " return true; ",
"//" : " return false; ",
"//" : " } ",
"//" : " ",
"//" : " function testKeywords() returns (bool res) ",
"//" : " { ",
"//" : " //some simple checks for the if statemnt ",
"//" : " //if, else, while, for, break, continue, return ",
"//" : " int i = 0; ",
"//" : " res = false; ",
"//" : " ",
"//" : " if (i == 0) ",
"//" : " { ",
"//" : " if( i <= -25) ",
"//" : " { ",
"//" : " return false; ",
"//" : " } ",
"//" : " else ",
"//" : " { ",
"//" : " while(i < 10) ",
"//" : " i++; ",
"//" : " ",
"//" : " if (i == 10) ",
"//" : " { ",
"//" : " for(var j=10; j>0; j--) ",
"//" : " { ",
"//" : " i--; ",
"//" : " } ",
"//" : " } ",
"//" : " } ",
"//" : " } ",
"//" : " ",
"//" : " if (i == 0) ",
"//" : " return true; ",
"//" : " ",
"//" : " return false; ",
"//" : " } ",
"//" : " ",
"//" : " function createContractFromMethod() returns (TestContract a) ",
"//" : " { ",
"//" : " a = new TestContract(); ",
"//" : " } ",
"//" : "} ",
"code" : "0x60003560e060020a900480630c4c9a80146100635780632a9afb8314610075578063380e4396146100875780637ee17e1214610099578063a60eedda146100a7578063e0a9fd28146100b9578063e97384dc146100cb578063ed973fe9146100dd57005b61006b610473565b8060005260206000f35b61007d61064e565b8060005260206000f35b61008f61073f565b8060005260206000f35b6100a16107fe565b60006000f35b6100af6100ef565b8060005260206000f35b6100c1610196565b8060005260206000f35b6100d3610352565b8060005260206000f35b6100e56102eb565b8060005260206000f35b60006000600191506060610815600039606060006000f0905080600160a060020a031662f55d9d600060008260e060020a02600052600441600160a060020a03168152602001600060008660325a03f161014557005b505080600160a060020a031663b9c3d0a5602060008260e060020a026000526004600060008660325a03f161017657005b505060005160e1141561018857610191565b60009150610192565b5b5090565b60006001905060007f74657374737472696e67000000000000000000000000000000000000000000008152600a016000207f43c4b4524adb81e4e9a5c4648a98e9d320e3908ac5b6c889144b642cd08ae16d14156101f3576101fc565b600090506102e8565b60026020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a01600060008560325a03f161023a57005b506000517f3c8727e019a42b444667a587b6001251becadabbb36bfed8087a92c18882d111141561026a57610273565b600090506102e8565b60036020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a01600060008560325a03f16102b157005b50600051600160a060020a031673cd566972b5e50104011a92b59fa8e0b1234851ae14156102de576102e7565b600090506102e8565b5b90565b600060006060610815600039606060006000f0905080600160a060020a031663b9c3d0a5602060008260e060020a026000526004600060008660325a03f161032f57005b505060005160e11461034057610349565b6001915061034e565b600091505b5090565b60006001905041600160a060020a0316732adc25665018aa1fe0e6bc666dac8fc2697ff9ba14156103825761038b565b60009050610470565b446302b8feb0141561039c576103a5565b60009050610470565b45683635c9adc5dea0000014156103bb576103c4565b60009050610470565b43607814156103d2576103db565b60009050610470565b33600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156104055761040e565b60009050610470565b346064141561041c57610425565b60009050610470565b3a600114156104335761043c565b60009050610470565b32600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156104665761046f565b60009050610470565b5b90565b6000600090506104816107fe565b5061048a61073f565b15610494576104ba565b7ff000000000000000000000000000000000000000000000000000000000000000810190505b6104c26102eb565b156104cc576104f2565b7f0f00000000000000000000000000000000000000000000000000000000000000810190505b6104fa6100ef565b1561050457610529565b7ef0000000000000000000000000000000000000000000000000000000000000810190505b610531610352565b1561053b57610560565b7e0f000000000000000000000000000000000000000000000000000000000000810190505b60ff60008190555073a94f5374fce5edbc8e2a8697c15331677e6ebf0b60018190555060ff6002819055507f676c6f62616c2064617461203332206c656e67746820737472696e670000000060038190555073a94f5374fce5edbc8e2a8697c15331677e6ebf0b6004600060008152602001908152602001600020819055506105e761064e565b156105f157610615565b7df00000000000000000000000000000000000000000000000000000000000810190505b61061d610196565b156106275761064b565b7d0f0000000000000000000000000000000000000000000000000000000000810190505b90565b60006001905060005460ff14156106645761066d565b6000905061073c565b600254600054141561067e57610687565b6000905061073c565b600154600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156106b3576106bc565b6000905061073c565b6003547f676c6f62616c2064617461203332206c656e67746820737472696e670000000014156106eb576106f4565b6000905061073c565b600460006000815260200190815260200160002054600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156107325761073b565b6000905061073c565b5b90565b60006000600060009150600092508160001461075a576107de565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe78213156107d4575b600a821215610799578180600101925050610783565b81600a146107a6576107cf565b600a90505b60008160ff1611156107ce578180600190039250508080600190039150506107ab565b5b6107dd565b600092506107f9565b5b816000146107eb576107f4565b600192506107f9565b600092505b505090565b60006060610815600039606060006000f09050905600605480600c6000396000f30060003560e060020a90048062f55d9d14601e578063b9c3d0a514602d57005b60276004356046565b60006000f35b6033603d565b8060005260206000f35b600060e1905090565b80600160a060020a0316ff5056",
"code" : "0x60003560e060020a90048063c040622614610021578063e0a9fd281461003357005b610029610045565b8060005260206000f35b61003b610054565b8060005260206000f35b600061004f610054565b905090565b60006001905060007f74657374737472696e67000000000000000000000000000000000000000000008152600a017f030d40000000000000000000000000000000000000000000000000000000000081526003016000207f43c4b4524adb81e4e9a5c4648a98e9d320e3908ac5b6c889144b642cd08ae16d14156100d7576100e0565b60009050610218565b60026020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a017f030d4000000000000000000000000000000000000000000000000000000000008152600301600060008560325a03f161014457005b506000517f3c8727e019a42b444667a587b6001251becadabbb36bfed8087a92c18882d11114156101745761017d565b60009050610218565b60036020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a017f030d4000000000000000000000000000000000000000000000000000000000008152600301600060008560325a03f16101e157005b50600051600160a060020a031673cd566972b5e50104011a92b59fa8e0b1234851ae141561020e57610217565b60009050610218565b5b9056",
"nonce" : "0",
"storage" : {
}
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "50000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" :
{
"//" : "run()",
"data" : "0xc0406226",
"gasLimit" : "35000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100"
}
},
"TestStructuresAndVariabless" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000000000000000000",
"currentNumber" : "120",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100000",
"//" : "contract main ",
"//" : "{ ",
"//" : " struct StructTest ",
"//" : " { ",
"//" : " address addr; ",
"//" : " int amount; ",
"//" : " string32 str; ",
"//" : " mapping (uint => address) funders; ",
"//" : " } ",
"//" : " ",
"//" : " int globalValue; ",
"//" : " StructTest globalData; ",
"//" : " function run() returns (bool) ",
"//" : " { ",
"//" : " globalValue = 255; ",
"//" : " globalData.addr = 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b; ",
"//" : " globalData.amount = 255; ",
"//" : " globalData.str = 'global data 32 length string'; ",
"//" : " globalData.funders[0] = 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b; ",
"//" : " return testStructuresAndVariabless(); ",
"//" : " } ",
"//" : " ",
"//" : " function testStructuresAndVariabless() returns (bool res) ",
"//" : " { ",
"//" : " res = true; ",
"//" : " if (globalValue != 255) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (globalValue != globalData.amount) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (globalData.addr != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (globalData.str != 'global data 32 length string') ",
"//" : " return false; ",
"//" : " ",
"//" : " if (globalData.funders[0] != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ",
"//" : " return false; ",
"//" : " } ",
"//" : "} ",
"code" : "0x60003560e060020a900480632a9afb8314610021578063c04062261461003357005b610029610045565b8060005260206000f35b61003b610136565b8060005260206000f35b60006001905060005460ff141561005b57610064565b60009050610133565b60025460005414156100755761007e565b60009050610133565b600154600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156100aa576100b3565b60009050610133565b6003547f676c6f62616c2064617461203332206c656e67746820737472696e670000000014156100e2576100eb565b60009050610133565b600460006000815260200190815260200160002054600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b141561012957610132565b60009050610133565b5b90565b600060ff60008190555073a94f5374fce5edbc8e2a8697c15331677e6ebf0b60018190555060ff6002819055507f676c6f62616c2064617461203332206c656e67746820737472696e670000000060038190555073a94f5374fce5edbc8e2a8697c15331677e6ebf0b6004600060008152602001908152602001600020819055506101bf610045565b90509056",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" :
{
"//" : "createContractFromMethod()",
"data" : "0x7ee17e12",
"//" : "runSolidityTests()",
"data" : "0x0c4c9a80",
"gasLimit" : "15000000",
{
"//" : "run()",
"data" : "0xc0406226",
"gasLimit" : "350000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "d94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100"
}
},
"TestBlockAndTransactionProperties" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000000000000000000",
"currentNumber" : "120",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100000",
"//" : "contract main ",
"//" : "{ ",
"//" : " function run() returns (bool) ",
"//" : " { ",
"//" : " return testBlockAndTransactionProperties(); ",
"//" : " } ",
"//" : " ",
"//" : " function testBlockAndTransactionProperties() returns (bool res) ",
"//" : " { ",
"//" : " res = true; ",
"//" : " if (block.coinbase != 0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (block.difficulty != 45678256) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (block.gaslimit != 1000000000000000000000) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (block.number != 120) ",
"//" : " return false; ",
"//" : " ",
"//" : " //try to call this ",
"//" : " block.blockhash(120); ",
"//" : " block.timestamp; ",
"//" : " msg.gas; ",
"//" : " ",
"//" : " if (msg.sender != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (msg.value != 100) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (tx.gasprice != 1) ",
"//" : " return false; ",
"//" : " ",
"//" : " if (tx.origin != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ",
"//" : " return false; ",
"//" : " ",
"//" : " } ",
"//" : "} ",
"code" : "0x60003560e060020a90048063c040622614610021578063e97384dc1461003357005b610029610045565b8060005260206000f35b61003b610054565b8060005260206000f35b600061004f610054565b905090565b60006001905041600160a060020a0316732adc25665018aa1fe0e6bc666dac8fc2697ff9ba14156100845761008d565b60009050610172565b446302b8feb0141561009e576100a7565b60009050610172565b45683635c9adc5dea0000014156100bd576100c6565b60009050610172565b43607814156100d4576100dd565b60009050610172565b33600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b141561010757610110565b60009050610172565b346064141561011e57610127565b60009050610172565b3a600114156101355761013e565b60009050610172565b32600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b141561016857610171565b60009050610172565b5b9056",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" :
{
"//" : "run()",
"data" : "0xc0406226",
"gasLimit" : "350000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100"
}
},
"TestContractSuicide" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100000",
"//": "contract TestContract ",
"//": "{ ",
"//": " function testMethod() returns (int res) ",
"//": " { ",
"//": " return 225; ",
"//": " } ",
"//": " ",
"//": " function destroy(address sendFoundsTo) ",
"//": " { ",
"//": " suicide(sendFoundsTo); ",
"//": " } ",
"//": "} ",
"//": "contract main ",
"//": "{ ",
"//": " function run() returns (bool) ",
"//": " { ",
"//": " return testContractSuicide(); ",
"//": " } ",
"//": " ",
"//": " function testContractSuicide() returns (bool res) ",
"//": " { ",
"//": " TestContract a = new TestContract(); ",
"//": " a.destroy(block.coinbase); ",
"//": " if (a.testMethod() == 225) //we should be able to call a contract ",
"//": " return true; ",
"//": " return false; ",
"//": " } ",
"//": "} ",
"code" : "0x60003560e060020a90048063a60eedda14610021578063c04062261461003357005b610029610045565b8060005260206000f35b61003b6100eb565b8060005260206000f35b6000600060606100fb600039606060006000f0905080600160a060020a031662f55d9d600060008260e060020a02600052600441600160a060020a03168152602001600060008660325a03f161009757005b505080600160a060020a031663b9c3d0a5602060008260e060020a026000526004600060008660325a03f16100c857005b505060005160e1146100d9576100e2565b600191506100e7565b600091505b5090565b60006100f5610045565b9050905600605480600c6000396000f30060003560e060020a90048062f55d9d14601e578063b9c3d0a514602d57005b60276004356046565b60006000f35b6033603d565b8060005260206000f35b600060e1905090565b80600160a060020a0316ff5056",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" :
{
"//" : "run()",
"data" : "0xc0406226",
"gasLimit" : "350000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "1"
}
},
"TestContractInteraction" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100000",
"//": "contract TestContract ",
"//": "{ ",
"//": " function testMethod() returns (int res) ",
"//": " { ",
"//": " return 225; ",
"//": " } ",
"//": " ",
"//": " function destroy(address sendFoundsTo) ",
"//": " { ",
"//": " suicide(sendFoundsTo); ",
"//": " } ",
"//": "} ",
"//": "contract main ",
"//": "{ ",
"//": " function run() returns (bool) ",
"//": " { ",
"//": " return testContractInteraction(); ",
"//": " } ",
"//": " ",
"//" : " function testContractInteraction() returns (bool res) ",
"//" : " { ",
"//" : " TestContract a = new TestContract(); ",
"//" : " if (a.testMethod() == 225) ",
"//" : " return true; ",
"//" : " return false; ",
"//" : " } ",
"//": "} ",
"code" : "0x60003560e060020a90048063c040622614610021578063ed973fe91461003357005b6100296100ac565b8060005260206000f35b61003b610045565b8060005260206000f35b6000600060606100bc600039606060006000f0905080600160a060020a031663b9c3d0a5602060008260e060020a026000526004600060008660325a03f161008957005b505060005160e11461009a576100a3565b600191506100a8565b600091505b5090565b60006100b6610045565b9050905600605480600c6000396000f30060003560e060020a90048062f55d9d14601e578063b9c3d0a514602d57005b6027600435603d565b60006000f35b6033604b565b8060005260206000f35b80600160a060020a0316ff50565b600060e190509056",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" :
{
"//" : "run()",
"data" : "0xc0406226",
"gasLimit" : "350000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "1"
}
},
"TestKeywords" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100000",
"//": "contract main ",
"//": "{ ",
"//": " function run() returns (bool) ",
"//": " { ",
"//": " return testKeywords(); ",
"//": " } ",
"//": " ",
"//": " function testKeywords() returns (bool res) ",
"//": " { ",
"//": " //some simple checks for the if statemnt ",
"//": " //if, else, while, for, break, continue, return ",
"//": " int i = 0; ",
"//": " res = false; ",
"//": " ",
"//": " if (i == 0) ",
"//": " { ",
"//": " if( i <= -25) ",
"//": " { ",
"//": " return false; ",
"//": " } ",
"//": " else ",
"//": " { ",
"//": " while(i < 10) ",
"//": " i++; ",
"//": " ",
"//": " if (i == 10) ",
"//": " { ",
"//": " for(var j=10; j>0; j--) ",
"//": " { ",
"//": " i--; ",
"//": " } ",
"//": " } ",
"//": " } ",
"//": " } ",
"//": " ",
"//": " if (i == 0) ",
"//": " return true; ",
"//": " ",
"//": " return false; ",
"//": " } ",
"//": "} ",
"code" : "0x60003560e060020a90048063380e439614601f578063c040622614602f57005b6025603f565b8060005260206000f35b603560f0565b8060005260206000f35b60006000600060009150600092508160001460585760d3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe782131560ca575b600a82121560945781806001019250506080565b81600a14609f5760c6565b600a90505b60008160ff16111560c55781806001900392505080806001900391505060a4565b5b60d2565b6000925060eb565b5b8160001460de5760e6565b6001925060eb565b600092505b505090565b600060f8603f565b90509056",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" :
{
"//" : "run()",
"data" : "0xc0406226",
"gasLimit" : "350000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "1"
}
},
"CreateContractFromMethod" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100000",
"//": "contract TestContract ",
"//": "{ ",
"//": " function testMethod() returns (int res) ",
"//": " { ",
"//": " return 225; ",
"//": " } ",
"//": " ",
"//": " function destroy(address sendFoundsTo) ",
"//": " { ",
"//": " suicide(sendFoundsTo); ",
"//": " } ",
"//": "} ",
"//": " ",
"//": "contract main ",
"//": "{ ",
"//": " function run() returns (uint) ",
"//": " { ",
"//": " createContractFromMethod(); ",
"//": " } ",
"//": " ",
"//": " function createContractFromMethod() returns (TestContract a) ",
"//": " { ",
"//": " a = new TestContract(); ",
"//": " } ",
"//": "} ",
"code" : "0x60003560e060020a900480637ee17e1214601f578063c040622614602b57005b60256047565b60006000f35b6031603b565b8060005260206000f35b600060436047565b5090565b60006060605d600039606060006000f09050905600605480600c6000396000f30060003560e060020a90048062f55d9d14601e578063b9c3d0a514602d57005b60276004356046565b60006000f35b6033603d565b8060005260206000f35b600060e1905090565b80600160a060020a0316ff5056",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" :
{
"//" : "run()",
"data" : "0xc0406226",
"gasLimit" : "350000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "1"
}
},
"CallLowLevelCreatesSolidity" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",

4
test/stSpecialTestFiller.json

@ -22,7 +22,7 @@
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"balance" : "1000000",
"nonce" : "0",
"code" : "",
"storage": {}
@ -31,7 +31,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "22850",
"gasLimit" : "228500",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",

118
test/stSystemOperationsTestFiller.json

@ -3,7 +3,7 @@
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentGasLimit" : "100000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
@ -25,7 +25,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -60,7 +60,7 @@
},
"transaction" : {
"data" : "",
"gasLimit" : "30000",
"gasLimit" : "300000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -95,7 +95,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -129,7 +129,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -163,7 +163,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -197,7 +197,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -232,7 +232,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -257,7 +257,7 @@
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"balance" : "1000000",
"nonce" : "0",
"code" : "",
"storage": {}
@ -266,7 +266,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -300,7 +300,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -334,7 +334,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -368,7 +368,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -389,7 +389,7 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }",
"code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }",
"storage": {}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
@ -410,7 +410,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -452,7 +452,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -494,7 +494,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -536,7 +536,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -578,7 +578,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -619,7 +619,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -660,7 +660,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -701,7 +701,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -743,7 +743,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -785,7 +785,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -835,6 +835,40 @@
}
},
"callcodeTo0": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "30000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (CALLCODE 50000 0 1 0 0 0 0) }",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "3000000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"CallToNameRegistratorOutOfGas": {
"env" : {
@ -870,7 +904,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -911,7 +945,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -952,7 +986,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -993,7 +1027,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -1035,7 +1069,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -1076,7 +1110,7 @@
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "30000",
"gasLimit" : "300000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -1894,12 +1928,12 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }",
"code" : "{ [[ (PC) ]] (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }",
"storage": {}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
"code" : " { [[ (PC) ]] (ADD 1 (CALL 500 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ",
"code" : " { [[ (PC) ]] (ADD 1 (CALL 50000 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ",
"nonce" : "0",
"storage" : {
}
@ -1935,12 +1969,12 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ (PC) ]] (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }",
"code" : "{ [[ (PC) ]] (CALL (- (GAS) 100000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }",
"storage": {}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
"code" : " { [[ (PC) ]] (ADD 1 (CALL (- (GAS) 1000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ",
"code" : " { [[ (PC) ]] (ADD 1 (CALL (- (GAS) 100000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ",
"nonce" : "0",
"storage" : {
}
@ -1976,12 +2010,12 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }",
"code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 100000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }",
"storage": {}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "0",
"code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 0 0 0 0 0) } ",
"code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 100000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 0 0 0 0 0) } ",
"nonce" : "0",
"storage" : {
}
@ -2017,12 +2051,12 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1025000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }",
"code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 100000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }",
"storage": {}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "0",
"code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 0 0 0 0 0) } ",
"code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 100000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 0 0 0 0 0) } ",
"nonce" : "0",
"storage" : {
}
@ -2058,12 +2092,12 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) (SUICIDE 0x945304eb96065b2a98b57a48a06ae28d285a71b5) }",
"code" : "{ [[ (PC) ]] (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) (SUICIDE 0x945304eb96065b2a98b57a48a06ae28d285a71b5) }",
"storage": {}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
"code" : "{ [[ (PC) ]] (ADD 1 (CALL 500 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ",
"code" : "{ [[ (PC) ]] (ADD 1 (CALL 50000 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ",
"nonce" : "0",
"storage" : {
}
@ -2099,12 +2133,12 @@
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }",
"code" : "{ [[ (PC) ]] (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }",
"storage": {}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
"code" : "{ [[ (PC) ]] (ADD 1 (CALL 500 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) (SUICIDE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6) } ",
"code" : "{ [[ (PC) ]] (ADD 1 (CALL 50000 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) (SUICIDE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6) } ",
"nonce" : "0",
"storage" : {
}

60
test/state.cpp

@ -31,6 +31,7 @@
#include <libethereum/Defaults.h>
#include <libevm/VM.h>
#include "TestHelper.h"
#include "Stats.h"
using namespace std;
using namespace json_spirit;
@ -41,11 +42,12 @@ namespace dev { namespace test {
void doStateTests(json_spirit::mValue& v, bool _fillin)
{
Options::get(); // process command line options
if (Options::get().stats)
Listener::registerListener(Stats::get());
for (auto& i: v.get_obj())
{
cerr << i.first << endl;
std::cout << " " << i.first << "\n";
mObject& o = i.second.get_obj();
BOOST_REQUIRE(o.count("env") > 0);
@ -60,16 +62,17 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
try
{
Listener::ExecTimeGuard guard{i.first};
theState.execute(lastHashes(importer.m_environment.currentBlock.number), tx, &output);
}
catch (Exception const& _e)
{
cnote << "state execution did throw an exception: " << diagnostic_information(_e);
cnote << "Exception:\n" << diagnostic_information(_e);
theState.commit();
}
catch (std::exception const& _e)
{
cnote << "state execution did throw an exception: " << _e.what();
cnote << "state execution exception: " << _e.what();
}
if (_fillin)
@ -178,29 +181,13 @@ BOOST_AUTO_TEST_CASE(stBlockHashTest)
BOOST_AUTO_TEST_CASE(stQuadraticComplexityTest)
{
if (test::Options::get().quadratic)
{
auto start = chrono::steady_clock::now();
dev::test::executeTests("stQuadraticComplexityTest", "/StateTests", dev::test::doStateTests);
auto end = chrono::steady_clock::now();
auto duration(chrono::duration_cast<chrono::milliseconds>(end - start));
cnote << "test duration: " << duration.count() << " milliseconds.\n";
}
}
BOOST_AUTO_TEST_CASE(stMemoryStressTest)
{
if (test::Options::get().memory)
{
auto start = chrono::steady_clock::now();
dev::test::executeTests("stMemoryStressTest", "/StateTests", dev::test::doStateTests);
auto end = chrono::steady_clock::now();
auto duration(chrono::duration_cast<chrono::milliseconds>(end - start));
cnote << "test duration: " << duration.count() << " milliseconds.\n";
}
}
BOOST_AUTO_TEST_CASE(stSolidityTest)
@ -248,6 +235,39 @@ BOOST_AUTO_TEST_CASE(stCreateTest)
}
}
BOOST_AUTO_TEST_CASE(stRandom)
{
string testPath = dev::test::getTestPath();
testPath += "/StateTests/RandomTests";
vector<boost::filesystem::path> testFiles;
boost::filesystem::directory_iterator iterator(testPath);
for(; iterator != boost::filesystem::directory_iterator(); ++iterator)
if (boost::filesystem::is_regular_file(iterator->path()) && iterator->path().extension() == ".json")
testFiles.push_back(iterator->path());
for (auto& path: testFiles)
{
try
{
cnote << "Testing ..." << path.filename();
json_spirit::mValue v;
string s = asString(dev::contents(path.string()));
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + path.string() + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?");
json_spirit::read_string(s, v);
dev::test::doStateTests(v, false);
}
catch (Exception const& _e)
{
BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e));
}
catch (std::exception const& _e)
{
BOOST_ERROR("Failed test with Exception: " << _e.what());
}
}
}
BOOST_AUTO_TEST_CASE(userDefinedFileState)
{
dev::test::userDefinedTest("--singletest", dev::test::doStateTests);

45
test/vm.cpp

@ -20,13 +20,12 @@
* vm test functions.
*/
#include <chrono>
#include <boost/filesystem.hpp>
#include <libethereum/Executive.h>
#include <libevm/VMFactory.h>
#include "vm.h"
#include "Stats.h"
using namespace std;
using namespace json_spirit;
@ -312,11 +311,12 @@ namespace dev { namespace test {
void doVMTests(json_spirit::mValue& v, bool _fillin)
{
Options::get(); // process command line options // TODO: We need to control the main() function
if (Options::get().stats)
Listener::registerListener(Stats::get());
for (auto& i: v.get_obj())
{
cnote << i.first;
std::cout << " " << i.first << "\n";
mObject& o = i.second.get_obj();
BOOST_REQUIRE(o.count("env") > 0);
@ -340,17 +340,21 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
bytes output;
u256 gas;
bool vmExceptionOccured = false;
auto startTime = std::chrono::high_resolution_clock::now();
try
{
auto vm = eth::VMFactory::create(fev.gas);
auto vmtrace = Options::get().vmtrace ? fev.simpleTrace() : OnOpFunc{};
output = vm->go(fev, vmtrace).toBytes();
auto outputRef = bytesConstRef{};
{
Listener::ExecTimeGuard guard{i.first};
outputRef = vm->go(fev, vmtrace);
}
output = outputRef.toBytes();
gas = vm->gas();
}
catch (VMException const&)
{
cnote << "Safe VM Exception";
std::cout << " Safe VM Exception\n";
vmExceptionOccured = true;
}
catch (Exception const& _e)
@ -364,15 +368,6 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
BOOST_ERROR("Failed VM Test with Exception: " << _e.what());
}
auto endTime = std::chrono::high_resolution_clock::now();
if (Options::get().showTimes)
{
auto testDuration = endTime - startTime;
cnote << "Execution time: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(testDuration).count()
<< " ms";
}
// delete null entries in storage for the sake of comparison
for (auto &a: fev.addresses)
@ -513,29 +508,13 @@ BOOST_AUTO_TEST_CASE(vmSystemOperationsTest)
BOOST_AUTO_TEST_CASE(vmPerformanceTest)
{
if (test::Options::get().performance)
{
auto start = chrono::steady_clock::now();
dev::test::executeTests("vmPerformanceTest", "/VMTests", dev::test::doVMTests);
auto end = chrono::steady_clock::now();
auto duration(chrono::duration_cast<chrono::milliseconds>(end - start));
cnote << "test duration: " << duration.count() << " milliseconds.\n";
}
}
BOOST_AUTO_TEST_CASE(vmInputLimitsTest1)
{
if (test::Options::get().inputLimits)
{
auto start = chrono::steady_clock::now();
dev::test::executeTests("vmInputLimits1", "/VMTests", dev::test::doVMTests);
auto end = chrono::steady_clock::now();
auto duration(chrono::duration_cast<chrono::milliseconds>(end - start));
cnote << "test duration: " << duration.count() << " milliseconds.\n";
}
}
BOOST_AUTO_TEST_CASE(vmInputLimitsTest2)
@ -565,7 +544,7 @@ BOOST_AUTO_TEST_CASE(vmRandom)
{
try
{
cnote << "Testing ..." << path.filename();
std::cout << "TEST " << path.filename() << "\n";
json_spirit::mValue v;
string s = asString(dev::contents(path.string()));
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + path.string() + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?");

28
test/vmArithmeticTestFiller.json

@ -1485,6 +1485,34 @@
}
},
"addmodBigIntCast": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (ADDMOD 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 5) } ",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "100000"
}
},
"addmod1_overflow2": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",

28
test/vmEnvironmentalInfoTestFiller.json

@ -367,6 +367,34 @@
}
},
"calldataload_BigOffset": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "100000000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (CALLDATALOAD 0x4200000000000000000000000000000000000000000000000000000000000000)}",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "0x4200000000000000000000000000000000000000000000000000000000000000",
"gasPrice" : "1000000000",
"gas" : "100000000000"
}
},
"calldataload1": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",

15
test/webthreestubclient.h

@ -123,17 +123,6 @@ class WebThreeStubClient : public jsonrpc::Client
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getStorage(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getStorage",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_getStorageAt(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
@ -197,12 +186,12 @@ class WebThreeStubClient : public jsonrpc::Client
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_getData(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
std::string eth_getCode(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getData",p);
Json::Value result = this->CallMethod("eth_getCode",p);
if (result.isString())
return result.asString();
else

Loading…
Cancel
Save