Browse Source

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

cl-refactor
Gav Wood 9 years ago
parent
commit
4cabfde25d
  1. 2
      alethzero/Main.ui
  2. 4
      alethzero/MainWin.cpp
  3. 3
      eth/main.cpp
  4. 39
      ethminer/MinerAux.h
  5. 21
      libdevcore/FixedHash.h
  6. 22
      libdevcore/TrieCommon.h
  7. 68
      libethash-cl/ethash_cl_miner.cpp
  8. 16
      libethash-cl/ethash_cl_miner.h
  9. 30
      libethcore/Ethash.cpp
  10. 11
      libethcore/Ethash.h
  11. 4
      libethereum/Account.h
  12. 11
      libethereum/BlockChainSync.cpp
  13. 3
      libethereum/BlockChainSync.h
  14. 2
      libethereum/VerifiedBlock.h
  15. 6
      libevm/ExtVMFace.cpp
  16. 2
      libevm/ExtVMFace.h
  17. 7
      libp2p/Session.cpp
  18. 10
      libtestutils/StateLoader.cpp
  19. 8
      mix/DebuggingStateWrapper.h
  20. 2
      mix/HttpServer.h
  21. 4
      test/TestHelper.cpp
  22. 106
      test/libdevcore/FixedHash.cpp
  23. 854
      test/libethereum/StateTestsFiller/stPreCompiledContractsTransactionFiller.json
  24. 5
      test/libethereum/state.cpp

2
alethzero/Main.ui

@ -707,7 +707,7 @@
</layout> </layout>
</widget> </widget>
</widget> </widget>
<widget class="QDockWidget" name="dockWidget_8"> <widget class="QDockWidget" name="blockChainDockWidget">
<property name="features"> <property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set> <set>QDockWidget::DockWidgetFeatureMask</set>
</property> </property>

4
alethzero/MainWin.cpp

@ -260,6 +260,8 @@ Main::Main(QWidget *parent) :
m_transact->setWindowFlags(Qt::Dialog); m_transact->setWindowFlags(Qt::Dialog);
m_transact->setWindowModality(Qt::WindowModal); m_transact->setWindowModality(Qt::WindowModal);
connect(ui->blockChainDockWidget, &QDockWidget::visibilityChanged, [=]() { refreshBlockChain(); });
#if !ETH_FATDB #if !ETH_FATDB
removeDockWidget(ui->dockWidget_accounts); removeDockWidget(ui->dockWidget_accounts);
#endif #endif
@ -1307,7 +1309,7 @@ void Main::on_turboMining_triggered()
void Main::refreshBlockChain() void Main::refreshBlockChain()
{ {
if (!ui->blocks->isVisible() && isVisible()) if (!(ui->blockChainDockWidget->isVisible() || !tabifiedDockWidgets(ui->blockChainDockWidget).isEmpty()))
return; return;
DEV_TIMED_FUNCTION_ABOVE(500); DEV_TIMED_FUNCTION_ABOVE(500);

3
eth/main.cpp

@ -37,6 +37,7 @@
#include <libevm/VM.h> #include <libevm/VM.h>
#include <libevm/VMFactory.h> #include <libevm/VMFactory.h>
#include <libethereum/All.h> #include <libethereum/All.h>
#include <libethereum/BlockChainSync.h>
#include <libethcore/KeyManager.h> #include <libethcore/KeyManager.h>
#include <libwebthree/WebThree.h> #include <libwebthree/WebThree.h>
@ -375,6 +376,8 @@ void interactiveMode(eth::Client* c, std::shared_ptr<eth::TrivialGasPricer> gasP
cout << "Current block: " << c->blockChain().details().number << endl; cout << "Current block: " << c->blockChain().details().number << endl;
else if (c && cmd == "blockqueue") else if (c && cmd == "blockqueue")
cout << "Current blockqueue status: " << endl << c->blockQueueStatus() << endl; cout << "Current blockqueue status: " << endl << c->blockQueueStatus() << endl;
else if (c && cmd == "sync")
cout << "Current sync status: " << endl << c->syncStatus() << endl;
else if (c && cmd == "hashrate") else if (c && cmd == "hashrate")
cout << "Current hash rate: " << toString(c->hashrate()) << " hashes per second." << endl; cout << "Current hash rate: " << toString(c->hashrate()) << " hashes per second." << endl;
else if (c && cmd == "findblock") else if (c && cmd == "findblock")

39
ethminer/MinerAux.h

@ -128,6 +128,33 @@ public:
cerr << "Bad " << arg << " option: " << argv[i] << endl; cerr << "Bad " << arg << " option: " << argv[i] << endl;
BOOST_THROW_EXCEPTION(BadArgument()); BOOST_THROW_EXCEPTION(BadArgument());
} }
else if (arg == "--cl-global-work" && i + 1 < argc)
try {
m_globalWorkSizeMultiplier = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
BOOST_THROW_EXCEPTION(BadArgument());
}
else if (arg == "--cl-local-work" && i + 1 < argc)
try {
m_localWorkSize = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
BOOST_THROW_EXCEPTION(BadArgument());
}
else if (arg == "--cl-ms-per-batch" && i + 1 < argc)
try {
m_msPerBatch = stol(argv[++i]);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
BOOST_THROW_EXCEPTION(BadArgument());
}
else if (arg == "--list-devices") else if (arg == "--list-devices")
m_shouldListDevices = true; m_shouldListDevices = true;
else if (arg == "--allow-opencl-cpu") else if (arg == "--allow-opencl-cpu")
@ -266,16 +293,16 @@ public:
else if (m_minerType == MinerType::GPU) else if (m_minerType == MinerType::GPU)
{ {
if (!ProofOfWork::GPUMiner::configureGPU( if (!ProofOfWork::GPUMiner::configureGPU(
m_localWorkSize,
m_globalWorkSizeMultiplier,
m_msPerBatch,
m_openclPlatform, m_openclPlatform,
m_openclDevice, m_openclDevice,
m_clAllowCPU, m_clAllowCPU,
m_extraGPUMemory, m_extraGPUMemory,
m_currentBlock m_currentBlock
)) ))
{
cout << "No GPU device with sufficient memory was found. Can't GPU mine. Remove the -G argument" << endl;
exit(1); exit(1);
}
ProofOfWork::GPUMiner::setNumInstances(m_miningThreads); ProofOfWork::GPUMiner::setNumInstances(m_miningThreads);
} }
if (mode == OperationMode::DAGInit) if (mode == OperationMode::DAGInit)
@ -318,6 +345,9 @@ public:
<< " --list-devices List the detected OpenCL devices and exit." << endl << " --list-devices List the detected OpenCL devices and exit." << endl
<< " --current-block Let the miner know the current block number at configuration time. Will help determine DAG size and required GPU memory." << endl << " --current-block Let the miner know the current block number at configuration time. Will help determine DAG size and required GPU memory." << endl
<< " --cl-extragpu-mem Set the memory (in MB) you believe your GPU requires for stuff other than mining. Windows rendering e.t.c.." << endl << " --cl-extragpu-mem Set the memory (in MB) you believe your GPU requires for stuff other than mining. Windows rendering e.t.c.." << endl
<< " --cl-local-work Set the OpenCL local work size. Default is " << toString(dev::eth::Ethash::defaultLocalWorkSize) << endl
<< " --cl-global-work Set the OpenCL global work size as a multiple of the local work size. Default is " << toString(dev::eth::Ethash::defaultGlobalWorkSizeMultiplier) << " * " << toString(dev::eth::Ethash::defaultLocalWorkSize) << endl
<< " --cl-ms-per-batch Set the OpenCL target milliseconds per batch (global workgroup size). Default is " << toString(dev::eth::Ethash::defaultMSPerBatch) << ". If 0 is given then no autoadjustment of global work size will happen" << endl
; ;
} }
@ -506,6 +536,9 @@ private:
unsigned m_miningThreads = UINT_MAX; unsigned m_miningThreads = UINT_MAX;
bool m_shouldListDevices = false; bool m_shouldListDevices = false;
bool m_clAllowCPU = false; bool m_clAllowCPU = false;
unsigned m_globalWorkSizeMultiplier = dev::eth::Ethash::defaultGlobalWorkSizeMultiplier;
unsigned m_localWorkSize = dev::eth::Ethash::defaultLocalWorkSize;
unsigned m_msPerBatch = dev::eth::Ethash::defaultMSPerBatch;
boost::optional<uint64_t> m_currentBlock; boost::optional<uint64_t> m_currentBlock;
// default value is 350MB of GPU memory for other stuff (windows system rendering, e.t.c.) // default value is 350MB of GPU memory for other stuff (windows system rendering, e.t.c.)
unsigned m_extraGPUMemory = 350000000; unsigned m_extraGPUMemory = 350000000;

21
libdevcore/FixedHash.h

@ -31,6 +31,10 @@
namespace dev namespace dev
{ {
/// Compile-time calculation of Log2 of constant values.
template <unsigned N> struct StaticLog2 { enum { result = 1 + StaticLog2<N/2>::result }; };
template <> struct StaticLog2<1> { enum { result = 0 }; };
extern std::random_device s_fixedHashEngine; extern std::random_device s_fixedHashEngine;
/// Fixed-size raw-byte array container type, with an API optimised for storing hashes. /// Fixed-size raw-byte array container type, with an API optimised for storing hashes.
@ -102,7 +106,7 @@ public:
FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; } FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; }
FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; } FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; }
/// @returns true if all bytes in @a _c are set in this object. /// @returns true if all one-bits in @a _c are set in this object.
bool contains(FixedHash const& _c) const { return (*this & _c) == _c; } bool contains(FixedHash const& _c) const { return (*this & _c) == _c; }
/// @returns a particular byte from the hash. /// @returns a particular byte from the hash.
@ -171,18 +175,21 @@ public:
template <unsigned P, unsigned M> inline FixedHash<M> bloomPart() const template <unsigned P, unsigned M> inline FixedHash<M> bloomPart() const
{ {
static_assert((M & (M - 1)) == 0, "M must be power-of-two"); unsigned const c_bloomBits = M * 8;
static const unsigned c_bloomBits = M * 8; unsigned const c_mask = c_bloomBits - 1;
unsigned mask = c_bloomBits - 1; unsigned const c_bloomBytes = (StaticLog2<c_bloomBits>::result + 7) / 8;
unsigned bloomBytes = (dev::toLog2(c_bloomBits) + 7) / 8;
static_assert((M & (M - 1)) == 0, "M must be power-of-two");
static_assert(P * c_bloomBytes <= N, "out of range");
FixedHash<M> ret; FixedHash<M> ret;
byte const* p = data(); byte const* p = data();
for (unsigned i = 0; i < P; ++i) for (unsigned i = 0; i < P; ++i)
{ {
unsigned index = 0; unsigned index = 0;
for (unsigned j = 0; j < bloomBytes; ++j, ++p) for (unsigned j = 0; j < c_bloomBytes; ++j, ++p)
index = (index << 8) | *p; index = (index << 8) | *p;
index &= mask; index &= c_mask;
ret[M - 1 - index / 8] |= (1 << (index % 8)); ret[M - 1 - index / 8] |= (1 << (index % 8));
} }
return ret; return ret;

22
libdevcore/TrieCommon.h

@ -32,26 +32,38 @@ inline byte nibble(bytesConstRef _data, unsigned _i)
return (_i & 1) ? (_data[_i / 2] & 15) : (_data[_i / 2] >> 4); return (_i & 1) ? (_data[_i / 2] & 15) : (_data[_i / 2] >> 4);
} }
inline unsigned sharedNibbles(bytesConstRef _a, unsigned _ab, unsigned _ae, bytesConstRef _b, unsigned _bb, unsigned _be) /// Interprets @a _first and @a _second as vectors of nibbles and returns the length of the longest common
/// prefix of _first[_beginFirst..._endFirst] and _second[_beginSecond..._endSecond].
inline unsigned sharedNibbles(bytesConstRef _first, unsigned _beginFirst, unsigned _endFirst, bytesConstRef _second, unsigned _beginSecond, unsigned _endSecond)
{ {
unsigned ret = 0; unsigned ret = 0;
for (unsigned ai = _ab, bi = _bb; ai < _ae && bi < _be && nibble(_a, ai) == nibble(_b, bi); ++ai, ++bi, ++ret) {} while (_beginFirst < _endFirst && _beginSecond < _endSecond && nibble(_first, _beginFirst) == nibble(_second, _beginSecond))
{
++_beginFirst;
++_beginSecond;
++ret;
}
return ret; return ret;
} }
/**
* Nibble-based view on a bytesConstRef.
*/
struct NibbleSlice struct NibbleSlice
{ {
bytesConstRef data; bytesConstRef data;
unsigned offset; unsigned offset;
NibbleSlice(bytesConstRef _d = bytesConstRef(), unsigned _o = 0): data(_d), offset(_o) {} NibbleSlice(bytesConstRef _data = bytesConstRef(), unsigned _offset = 0): data(_data), offset(_offset) {}
byte operator[](unsigned _index) const { return nibble(data, offset + _index); } byte operator[](unsigned _index) const { return nibble(data, offset + _index); }
unsigned size() const { return data.size() * 2 - offset; } unsigned size() const { return data.size() * 2 - offset; }
bool empty() const { return !size(); } bool empty() const { return !size(); }
NibbleSlice mid(unsigned _index) const { return NibbleSlice(data, offset + _index); } NibbleSlice mid(unsigned _index) const { return NibbleSlice(data, offset + _index); }
void clear() { data.reset(); offset = 0; } void clear() { data.reset(); offset = 0; }
/// @returns true iff _k is a prefix of this.
bool contains(NibbleSlice _k) const { return shared(_k) == _k.size(); } bool contains(NibbleSlice _k) const { return shared(_k) == _k.size(); }
/// @returns the number of shared nibbles at the beginning of this and _k.
unsigned shared(NibbleSlice _k) const { return sharedNibbles(data, offset, offset + size(), _k.data, _k.offset, _k.offset + _k.size()); } unsigned shared(NibbleSlice _k) const { return sharedNibbles(data, offset, offset + size(), _k.data, _k.offset, _k.offset + _k.size()); }
/** /**
* @brief Determine if we, a full key, are situated prior to a particular key-prefix. * @brief Determine if we, a full key, are situated prior to a particular key-prefix.
@ -60,8 +72,8 @@ struct NibbleSlice
*/ */
bool isEarlierThan(NibbleSlice _k) const bool isEarlierThan(NibbleSlice _k) const
{ {
unsigned i; unsigned i = 0;
for (i = 0; i < _k.size() && i < size(); ++i) for (; i < _k.size() && i < size(); ++i)
if (operator[](i) < _k[i]) // Byte is lower - we're earlier.. if (operator[](i) < _k[i]) // Byte is lower - we're earlier..
return true; return true;
else if (operator[](i) > _k[i]) // Byte is higher - we're not earlier. else if (operator[](i) > _k[i]) // Byte is higher - we're not earlier.

68
libethash-cl/ethash_cl_miner.cpp

@ -33,6 +33,7 @@
#include <vector> #include <vector>
#include <libethash/util.h> #include <libethash/util.h>
#include <libethash/ethash.h> #include <libethash/ethash.h>
#include <libethcore/Ethash.h>
#include <libethash/internal.h> #include <libethash/internal.h>
#include "ethash_cl_miner.h" #include "ethash_cl_miner.h"
#include "ethash_cl_miner_kernel.h" #include "ethash_cl_miner_kernel.h"
@ -49,6 +50,7 @@
#undef max #undef max
using namespace std; using namespace std;
using namespace dev::eth;
// TODO: If at any point we can use libdevcore in here then we should switch to using a LogChannel // TODO: If at any point we can use libdevcore in here then we should switch to using a LogChannel
#define ETHCL_LOG(_contents) cout << "[OPENCL]:" << _contents << endl #define ETHCL_LOG(_contents) cout << "[OPENCL]:" << _contents << endl
@ -140,11 +142,17 @@ unsigned ethash_cl_miner::getNumDevices(unsigned _platformId)
bool ethash_cl_miner::configureGPU( bool ethash_cl_miner::configureGPU(
unsigned _platformId, unsigned _platformId,
unsigned _localWorkSize,
unsigned _globalWorkSize,
unsigned _msPerBatch,
bool _allowCPU, bool _allowCPU,
unsigned _extraGPUMemory, unsigned _extraGPUMemory,
boost::optional<uint64_t> _currentBlock boost::optional<uint64_t> _currentBlock
) )
{ {
s_workgroupSize = _localWorkSize;
s_initialGlobalWorkSize = _globalWorkSize;
s_msPerBatch = _msPerBatch;
s_allowCPU = _allowCPU; s_allowCPU = _allowCPU;
s_extraRequiredGPUMem = _extraGPUMemory; s_extraRequiredGPUMem = _extraGPUMemory;
// by default let's only consider the DAG of the first epoch // by default let's only consider the DAG of the first epoch
@ -175,6 +183,9 @@ bool ethash_cl_miner::configureGPU(
bool ethash_cl_miner::s_allowCPU = false; bool ethash_cl_miner::s_allowCPU = false;
unsigned ethash_cl_miner::s_extraRequiredGPUMem; unsigned ethash_cl_miner::s_extraRequiredGPUMem;
unsigned ethash_cl_miner::s_msPerBatch = Ethash::defaultMSPerBatch;
unsigned ethash_cl_miner::s_workgroupSize = Ethash::defaultLocalWorkSize;
unsigned ethash_cl_miner::s_initialGlobalWorkSize = Ethash::defaultGlobalWorkSizeMultiplier * Ethash::defaultLocalWorkSize;
bool ethash_cl_miner::searchForAllDevices(function<bool(cl::Device const&)> _callback) bool ethash_cl_miner::searchForAllDevices(function<bool(cl::Device const&)> _callback)
{ {
@ -254,7 +265,6 @@ void ethash_cl_miner::finish()
bool ethash_cl_miner::init( bool ethash_cl_miner::init(
uint8_t const* _dag, uint8_t const* _dag,
uint64_t _dagSize, uint64_t _dagSize,
unsigned _workgroupSize,
unsigned _platformId, unsigned _platformId,
unsigned _deviceId unsigned _deviceId
) )
@ -299,14 +309,18 @@ bool ethash_cl_miner::init(
m_context = cl::Context(vector<cl::Device>(&device, &device + 1)); m_context = cl::Context(vector<cl::Device>(&device, &device + 1));
m_queue = cl::CommandQueue(m_context, device); m_queue = cl::CommandQueue(m_context, device);
// use requested workgroup size, but we require multiple of 8 // make sure that global work size is evenly divisible by the local workgroup size
m_workgroupSize = ((_workgroupSize + 7) / 8) * 8; m_globalWorkSize = s_initialGlobalWorkSize;
if (m_globalWorkSize % s_workgroupSize != 0)
m_globalWorkSize = ((m_globalWorkSize / s_workgroupSize) + 1) * s_workgroupSize;
// remember the device's address bits
m_deviceBits = device.getInfo<CL_DEVICE_ADDRESS_BITS>();
// patch source code // patch source code
// note: ETHASH_CL_MINER_KERNEL is simply ethash_cl_miner_kernel.cl compiled // note: ETHASH_CL_MINER_KERNEL is simply ethash_cl_miner_kernel.cl compiled
// into a byte array by bin2h.cmake. There is no need to load the file by hand in runtime // into a byte array by bin2h.cmake. There is no need to load the file by hand in runtime
string code(ETHASH_CL_MINER_KERNEL, ETHASH_CL_MINER_KERNEL + ETHASH_CL_MINER_KERNEL_SIZE); string code(ETHASH_CL_MINER_KERNEL, ETHASH_CL_MINER_KERNEL + ETHASH_CL_MINER_KERNEL_SIZE);
addDefinition(code, "GROUP_SIZE", m_workgroupSize); addDefinition(code, "GROUP_SIZE", s_workgroupSize);
addDefinition(code, "DAG_SIZE", (unsigned)(_dagSize / ETHASH_MIX_BYTES)); addDefinition(code, "DAG_SIZE", (unsigned)(_dagSize / ETHASH_MIX_BYTES));
addDefinition(code, "ACCESSES", ETHASH_ACCESSES); addDefinition(code, "ACCESSES", ETHASH_ACCESSES);
addDefinition(code, "MAX_OUTPUTS", c_maxSearchResults); addDefinition(code, "MAX_OUTPUTS", c_maxSearchResults);
@ -415,9 +429,8 @@ bool ethash_cl_miner::init(
return true; return true;
} }
void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook& hook, unsigned _msPerBatch) void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook& hook)
{ {
(void)_msPerBatch;
try try
{ {
struct pending_batch struct pending_batch
@ -454,10 +467,9 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
unsigned buf = 0; unsigned buf = 0;
random_device engine; random_device engine;
uint64_t start_nonce = uniform_int_distribution<uint64_t>()(engine); uint64_t start_nonce = uniform_int_distribution<uint64_t>()(engine);
for (;; start_nonce += m_batchSize) for (;; start_nonce += m_globalWorkSize)
{ {
// chrono::high_resolution_clock::time_point t = chrono::high_resolution_clock::now(); auto t = chrono::high_resolution_clock::now();
// supply output buffer to kernel // supply output buffer to kernel
m_searchKernel.setArg(0, m_searchBuffer[buf]); m_searchKernel.setArg(0, m_searchBuffer[buf]);
if (m_dagChunksCount == 1) if (m_dagChunksCount == 1)
@ -466,7 +478,7 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
m_searchKernel.setArg(6, start_nonce); m_searchKernel.setArg(6, start_nonce);
// execute it! // execute it!
m_queue.enqueueNDRangeKernel(m_searchKernel, cl::NullRange, m_batchSize, m_workgroupSize); m_queue.enqueueNDRangeKernel(m_searchKernel, cl::NullRange, m_globalWorkSize, s_workgroupSize);
pending.push({ start_nonce, buf }); pending.push({ start_nonce, buf });
buf = (buf + 1) % c_bufferCount; buf = (buf + 1) % c_bufferCount;
@ -486,7 +498,7 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
m_queue.enqueueUnmapMemObject(m_searchBuffer[batch.buf], results); m_queue.enqueueUnmapMemObject(m_searchBuffer[batch.buf], results);
bool exit = num_found && hook.found(nonces, num_found); bool exit = num_found && hook.found(nonces, num_found);
exit |= hook.searched(batch.start_nonce, m_batchSize); // always report searched before exit exit |= hook.searched(batch.start_nonce, m_globalWorkSize); // always report searched before exit
if (exit) if (exit)
break; break;
@ -497,19 +509,31 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
pending.pop(); pending.pop();
} }
/* chrono::high_resolution_clock::duration d = chrono::high_resolution_clock::now() - t; // adjust global work size depending on last search time
if (d > chrono::milliseconds(_msPerBatch * 10 / 9)) if (s_msPerBatch)
{ {
cerr << "Batch of" << m_batchSize << "took" << chrono::duration_cast<chrono::milliseconds>(d).count() << "ms, >>" << _msPerBatch << "ms."; // Global work size must be:
m_batchSize = max<unsigned>(128, m_batchSize * 9 / 10); // - less than or equal to 2 ^ DEVICE_BITS - 1
cerr << "New batch size" << m_batchSize; // - divisible by lobal work size (workgroup size)
auto d = chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - t);
if (d != chrono::milliseconds(0)) // if duration is zero, we did not get in the actual searh/or search not finished
{
if (d > chrono::milliseconds(s_msPerBatch * 10 / 9))
{
// cerr << "Batch of " << m_globalWorkSize << " took " << chrono::duration_cast<chrono::milliseconds>(d).count() << " ms, >> " << _msPerBatch << " ms." << endl;
m_globalWorkSize = max<unsigned>(128, m_globalWorkSize + s_workgroupSize);
// cerr << "New global work size" << m_globalWorkSize << endl;
}
else if (d < chrono::milliseconds(s_msPerBatch * 9 / 10))
{
// cerr << "Batch of " << m_globalWorkSize << " took " << chrono::duration_cast<chrono::milliseconds>(d).count() << " ms, << " << _msPerBatch << " ms." << endl;
m_globalWorkSize = min<unsigned>(pow(2, m_deviceBits) - 1, m_globalWorkSize - s_workgroupSize);
// Global work size should never be less than the workgroup size
m_globalWorkSize = max<unsigned>(s_workgroupSize, m_globalWorkSize);
// cerr << "New global work size" << m_globalWorkSize << endl;
}
}
} }
else if (d < chrono::milliseconds(_msPerBatch * 9 / 10))
{
cerr << "Batch of" << m_batchSize << "took" << chrono::duration_cast<chrono::milliseconds>(d).count() << "ms, <<" << _msPerBatch << "ms.";
m_batchSize = m_batchSize * 10 / 9;
cerr << "New batch size" << m_batchSize;
}*/
} }
// not safe to return until this is ready // not safe to return until this is ready

16
libethash-cl/ethash_cl_miner.h

@ -45,6 +45,9 @@ public:
static void listDevices(); static void listDevices();
static bool configureGPU( static bool configureGPU(
unsigned _platformId, unsigned _platformId,
unsigned _localWorkSize,
unsigned _globalWorkSize,
unsigned _msPerBatch,
bool _allowCPU, bool _allowCPU,
unsigned _extraGPUMemory, unsigned _extraGPUMemory,
boost::optional<uint64_t> _currentBlock boost::optional<uint64_t> _currentBlock
@ -53,12 +56,11 @@ public:
bool init( bool init(
uint8_t const* _dag, uint8_t const* _dag,
uint64_t _dagSize, uint64_t _dagSize,
unsigned _workgroupSize = 64,
unsigned _platformId = 0, unsigned _platformId = 0,
unsigned _deviceId = 0 unsigned _deviceId = 0
); );
void finish(); void finish();
void search(uint8_t const* _header, uint64_t _target, search_hook& _hook, unsigned _msPerBatch = 100); void search(uint8_t const* _header, uint64_t _target, search_hook& _hook);
void hash_chunk(uint8_t* _ret, uint8_t const* _header, uint64_t _nonce, unsigned _count); void hash_chunk(uint8_t* _ret, uint8_t const* _header, uint64_t _nonce, unsigned _count);
void search_chunk(uint8_t const*_header, uint64_t _target, search_hook& _hook); void search_chunk(uint8_t const*_header, uint64_t _target, search_hook& _hook);
@ -76,10 +78,16 @@ private:
cl::Buffer m_header; cl::Buffer m_header;
cl::Buffer m_hashBuffer[c_bufferCount]; cl::Buffer m_hashBuffer[c_bufferCount];
cl::Buffer m_searchBuffer[c_bufferCount]; cl::Buffer m_searchBuffer[c_bufferCount];
unsigned m_workgroupSize; unsigned m_globalWorkSize;
unsigned m_batchSize = c_searchBatchSize;
bool m_openclOnePointOne; bool m_openclOnePointOne;
unsigned m_deviceBits;
/// The local work size for the search
static unsigned s_workgroupSize;
/// The initial global work size for the searches
static unsigned s_initialGlobalWorkSize;
/// The target milliseconds per batch for the search. If 0, then no adjustment will happen
static unsigned s_msPerBatch;
/// Allow CPU to appear as an OpenCL device or not. Default is false /// Allow CPU to appear as an OpenCL device or not. Default is false
static bool s_allowCPU; static bool s_allowCPU;
/// GPU memory required for other things, like window rendering e.t.c. /// GPU memory required for other things, like window rendering e.t.c.

30
libethcore/Ethash.cpp

@ -54,6 +54,9 @@ namespace dev
namespace eth namespace eth
{ {
const unsigned Ethash::defaultLocalWorkSize = 64;
const unsigned Ethash::defaultGlobalWorkSizeMultiplier = 512; // * CL_DEFAULT_LOCAL_WORK_SIZE
const unsigned Ethash::defaultMSPerBatch = 100;
const Ethash::WorkPackage Ethash::NullWorkPackage = Ethash::WorkPackage(); const Ethash::WorkPackage Ethash::NullWorkPackage = Ethash::WorkPackage();
std::string Ethash::name() std::string Ethash::name()
@ -373,7 +376,7 @@ void Ethash::GPUMiner::workLoop()
this_thread::sleep_for(chrono::milliseconds(500)); this_thread::sleep_for(chrono::milliseconds(500));
} }
bytesConstRef dagData = dag->data(); bytesConstRef dagData = dag->data();
m_miner->init(dagData.data(), dagData.size(), 32, s_platformId, device); m_miner->init(dagData.data(), dagData.size(), s_platformId, device);
} }
uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192); uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192);
@ -409,6 +412,9 @@ void Ethash::GPUMiner::listDevices()
} }
bool Ethash::GPUMiner::configureGPU( bool Ethash::GPUMiner::configureGPU(
unsigned _localWorkSize,
unsigned _globalWorkSizeMultiplier,
unsigned _msPerBatch,
unsigned _platformId, unsigned _platformId,
unsigned _deviceId, unsigned _deviceId,
bool _allowCPU, bool _allowCPU,
@ -418,7 +424,27 @@ bool Ethash::GPUMiner::configureGPU(
{ {
s_platformId = _platformId; s_platformId = _platformId;
s_deviceId = _deviceId; s_deviceId = _deviceId;
return ethash_cl_miner::configureGPU(_platformId, _allowCPU, _extraGPUMemory, _currentBlock);
if (_localWorkSize != 32 && _localWorkSize != 64 && _localWorkSize != 128)
{
cout << "Given localWorkSize of " << toString(_localWorkSize) << "is invalid. Must be either 32,64, or 128" << endl;
return false;
}
if (!ethash_cl_miner::configureGPU(
_platformId,
_localWorkSize,
_globalWorkSizeMultiplier * _localWorkSize,
_msPerBatch,
_allowCPU,
_extraGPUMemory,
_currentBlock)
)
{
cout << "No GPU device with sufficient memory was found. Can't GPU mine. Remove the -G argument" << endl;
return false;
}
return true;
} }
#endif #endif

11
libethcore/Ethash.h

@ -88,7 +88,7 @@ public:
static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); } static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); }
static std::string platformInfo(); static std::string platformInfo();
static void listDevices() {} static void listDevices() {}
static bool configureGPU(unsigned, unsigned, bool, unsigned, boost::optional<uint64_t>) { return false; } static bool configureGPU(unsigned, unsigned, unsigned, unsigned, unsigned, bool, unsigned, boost::optional<uint64_t>) { return false; }
static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, std::thread::hardware_concurrency()); } static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, std::thread::hardware_concurrency()); }
protected: protected:
void kickOff() override void kickOff() override
@ -118,6 +118,9 @@ public:
static unsigned getNumDevices(); static unsigned getNumDevices();
static void listDevices(); static void listDevices();
static bool configureGPU( static bool configureGPU(
unsigned _localWorkSize,
unsigned _globalWorkSizeMultiplier,
unsigned _msPerBatch,
unsigned _platformId, unsigned _platformId,
unsigned _deviceId, unsigned _deviceId,
bool _allowCPU, bool _allowCPU,
@ -147,6 +150,12 @@ public:
#else #else
using GPUMiner = CPUMiner; using GPUMiner = CPUMiner;
#endif #endif
/// Default value of the local work size. Also known as workgroup size.
static const unsigned defaultLocalWorkSize;
/// Default value of the global work size as a multiplier of the local work size
static const unsigned defaultGlobalWorkSizeMultiplier;
/// Default value of the milliseconds per global work size (per batch)
static const unsigned defaultMSPerBatch;
}; };
} }

4
libethereum/Account.h

@ -152,8 +152,7 @@ public:
h256 codeHash() const { assert(!isFreshCode()); return m_codeHash; } h256 codeHash() const { assert(!isFreshCode()); return m_codeHash; }
/// Sets the code of the account. Must only be called when isFreshCode() returns true. /// Sets the code of the account. Must only be called when isFreshCode() returns true.
void setCode(bytes&& _code) { assert(isFreshCode()); m_codeCache = _code; changed(); } void setCode(bytes&& _code) { assert(isFreshCode()); m_codeCache = std::move(_code); changed(); }
void setCode(bytes const& _code) { assert(isFreshCode()); m_codeCache = _code; changed(); }
/// @returns true if the account's code is available through code(). /// @returns true if the account's code is available through code().
bool codeCacheValid() const { return m_codeHash == EmptySHA3 || m_codeHash == c_contractConceptionCodeHash || m_codeCache.size(); } bool codeCacheValid() const { return m_codeHash == EmptySHA3 || m_codeHash == c_contractConceptionCodeHash || m_codeCache.size(); }
@ -206,4 +205,3 @@ private:
} }
} }

11
libethereum/BlockChainSync.cpp

@ -41,6 +41,17 @@ using namespace p2p;
unsigned const c_chainReorgSize = 30000; /// Added to estimated hashes to account for potential chain reorganiation unsigned const c_chainReorgSize = 30000; /// Added to estimated hashes to account for potential chain reorganiation
unsigned const c_hashSubchainSize = 8192; /// PV61 subchain size unsigned const c_hashSubchainSize = 8192; /// PV61 subchain size
std::ostream& dev::eth::operator<<(std::ostream& _out, SyncStatus const& _sync)
{
_out << "protocol: " << _sync.protocolVersion << endl;
_out << "state: " << EthereumHost::stateName(_sync.state) << " ";
if (_sync.state == SyncState::Hashes)
_out << _sync.hashesReceived << "/" << (_sync.hashesEstimated ? "~" : "") << _sync.hashesTotal;
if (_sync.state == SyncState::Blocks || _sync.state == SyncState::NewBlocks)
_out << _sync.blocksReceived << "/" << _sync.blocksTotal;
return _out;
}
BlockChainSync::BlockChainSync(EthereumHost& _host): BlockChainSync::BlockChainSync(EthereumHost& _host):
m_host(_host) m_host(_host)
{ {

3
libethereum/BlockChainSync.h

@ -316,5 +316,8 @@ private:
unsigned m_syncingBlockNumber = 0; ///< Current subchain marker unsigned m_syncingBlockNumber = 0; ///< Current subchain marker
bool m_hashScanComplete = false; ///< True if leading peer completed hashchain scan and we have a list of subchains ready bool m_hashScanComplete = false; ///< True if leading peer completed hashchain scan and we have a list of subchains ready
}; };
std::ostream& operator<<(std::ostream& _out, SyncStatus const& _sync);
} }
} }

2
libethereum/VerifiedBlock.h

@ -47,7 +47,7 @@ struct VerifiedBlock
VerifiedBlock(BlockInfo&& _bi) VerifiedBlock(BlockInfo&& _bi)
{ {
verified.info = _bi; verified.info = std::move(_bi);
} }
VerifiedBlock(VerifiedBlock&& _other): VerifiedBlock(VerifiedBlock&& _other):

6
libevm/ExtVMFace.cpp

@ -21,22 +21,20 @@
#include "ExtVMFace.h" #include "ExtVMFace.h"
using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, h256 const& _codeHash, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth): ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, h256 const& _codeHash, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth):
myAddress(_myAddress), myAddress(_myAddress),
caller(_caller), caller(_caller),
origin(_origin), origin(_origin),
value(_value), value(_value),
gasPrice(_gasPrice), gasPrice(_gasPrice),
data(_data), data(_data),
code(_code), code(std::move(_code)),
codeHash(_codeHash), codeHash(_codeHash),
lastHashes(_lh), lastHashes(_lh),
previousBlock(_previousBlock), previousBlock(_previousBlock),
currentBlock(_currentBlock), currentBlock(_currentBlock),
depth(_depth) depth(_depth)
{} {}

2
libevm/ExtVMFace.h

@ -161,7 +161,7 @@ public:
ExtVMFace() = default; ExtVMFace() = default;
/// Full constructor. /// Full constructor.
ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, h256 const& _codeHash, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth); ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, h256 const& _codeHash, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth);
virtual ~ExtVMFace() = default; virtual ~ExtVMFace() = default;

7
libp2p/Session.cpp

@ -256,9 +256,8 @@ bool Session::checkPacket(bytesConstRef _msg)
void Session::send(bytes&& _msg) void Session::send(bytes&& _msg)
{ {
clog(NetLeft) << RLP(bytesConstRef(&_msg).cropped(1));
bytesConstRef msg(&_msg); bytesConstRef msg(&_msg);
clog(NetLeft) << RLP(msg.cropped(1));
if (!checkPacket(msg)) if (!checkPacket(msg))
clog(NetWarn) << "INVALID PACKET CONSTRUCTED!"; clog(NetWarn) << "INVALID PACKET CONSTRUCTED!";
@ -268,7 +267,7 @@ void Session::send(bytes&& _msg)
bool doWrite = false; bool doWrite = false;
{ {
Guard l(x_writeQueue); Guard l(x_writeQueue);
m_writeQueue.push_back(_msg); m_writeQueue.push_back(std::move(_msg));
doWrite = (m_writeQueue.size() == 1); doWrite = (m_writeQueue.size() == 1);
} }
@ -387,7 +386,7 @@ void Session::doRead()
drop(BadProtocol); drop(BadProtocol);
return; return;
} }
/// read padded frame and mac /// read padded frame and mac
auto tlen = header.length + header.padding + h128::size; auto tlen = header.length + header.padding + h128::size;
ba::async_read(m_socket->ref(), boost::asio::buffer(m_data, tlen), [this, self, header, tlen](boost::system::error_code ec, std::size_t length) ba::async_read(m_socket->ref(), boost::asio::buffer(m_data, tlen), [this, self, header, tlen](boost::system::error_code ec, std::size_t length)

10
libtestutils/StateLoader.cpp

@ -1,16 +1,16 @@
/* /*
This file is part of cpp-ethereum. This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful, cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -36,10 +36,10 @@ StateLoader::StateLoader(Json::Value const& _json, std::string const& _dbPath):
Address address = Address(name); Address address = Address(name);
bytes code = fromHex(o["code"].asString().substr(2)); bytes code = fromHex(o["code"].asString().substr(2));
if (code.size()) if (!code.empty())
{ {
m_state.m_cache[address] = Account(u256(o["balance"].asString()), Account::ContractConception); m_state.m_cache[address] = Account(u256(o["balance"].asString()), Account::ContractConception);
m_state.m_cache[address].setCode(code); m_state.m_cache[address].setCode(std::move(code));
} }
else else
m_state.m_cache[address] = Account(u256(o["balance"].asString()), Account::NormalCreation); m_state.m_cache[address] = Account(u256(o["balance"].asString()), Account::NormalCreation);

8
mix/DebuggingStateWrapper.h

@ -69,7 +69,7 @@ class QSolState: public QObject
public: public:
QSolState(QObject* _parent, QVariantMap&& _storage, QVariantList&& _callStack, QVariantMap&& _locals, int _start, int _end, QString _sourceName): QSolState(QObject* _parent, QVariantMap&& _storage, QVariantList&& _callStack, QVariantMap&& _locals, int _start, int _end, QString _sourceName):
QObject(_parent), m_storage(_storage), m_callStack(_callStack), m_locals(_locals), m_start(_start), m_end(_end), m_sourceName(_sourceName) QObject(_parent), m_storage(std::move(_storage)), m_callStack(std::move(_callStack)), m_locals(std::move(_locals)), m_start(_start), m_end(_end), m_sourceName(_sourceName)
{ } { }
private: private:
@ -92,7 +92,7 @@ class QCode: public QObject
Q_PROPERTY(QString documentId MEMBER m_document CONSTANT) Q_PROPERTY(QString documentId MEMBER m_document CONSTANT)
public: public:
QCode(QObject* _owner, QString const& _address, QVariantList&& _instrunctions): QObject(_owner), m_instructions(_instrunctions), m_address(_address) {} QCode(QObject* _owner, QString const& _address, QVariantList&& _instrunctions): QObject(_owner), m_instructions(std::move(_instrunctions)), m_address(_address) {}
void setDocument(QString const& _documentId) { m_document = _documentId; } void setDocument(QString const& _documentId) { m_document = _documentId; }
private: private:
@ -110,7 +110,7 @@ class QCallData: public QObject
Q_PROPERTY(QVariantList items MEMBER m_items CONSTANT) Q_PROPERTY(QVariantList items MEMBER m_items CONSTANT)
public: public:
QCallData(QObject* _owner, QVariantList&& _items): QObject(_owner), m_items(_items) {} QCallData(QObject* _owner, QVariantList&& _items): QObject(_owner), m_items(std::move(_items)) {}
private: private:
QVariantList m_items; QVariantList m_items;
@ -126,7 +126,7 @@ class QDebugData: public QObject
public: public:
QDebugData() { } QDebugData() { }
void setStates(QVariantList&& _states) { m_states = _states; } void setStates(QVariantList&& _states) { m_states = std::move(_states); }
private: private:
QVariantList m_states; QVariantList m_states;

2
mix/HttpServer.h

@ -46,7 +46,7 @@ class HttpRequest: public QObject
private: private:
HttpRequest(QObject* _parent, QUrl&& _url, QString&& _content, QVariantMap&& _headers): HttpRequest(QObject* _parent, QUrl&& _url, QString&& _content, QVariantMap&& _headers):
QObject(_parent), m_url(_url), m_content(_content), m_headers(_headers) QObject(_parent), m_url(std::move(_url)), m_content(std::move(_content)), m_headers(std::move(_headers))
{ {
} }

4
test/TestHelper.cpp

@ -199,10 +199,10 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state, stateOptio
stateOptions.m_bHasCode = true; stateOptions.m_bHasCode = true;
} }
if (code.size()) if (!code.empty())
{ {
_state.m_cache[address] = Account(balance, Account::ContractConception); _state.m_cache[address] = Account(balance, Account::ContractConception);
_state.m_cache[address].setCode(code); _state.m_cache[address].setCode(std::move(code));
} }
else else
_state.m_cache[address] = Account(balance, Account::NormalCreation); _state.m_cache[address] = Account(balance, Account::NormalCreation);

106
test/libdevcore/FixedHash.cpp

@ -0,0 +1,106 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file FixedHash.cpp
* @author Lefterus <lefteris@ethdev.com>
* @date 2015
*/
#include <libdevcore/FixedHash.h>
#include "../TestHelper.h"
using namespace std;
using namespace dev;
namespace dev
{
namespace test
{
BOOST_AUTO_TEST_SUITE(FixedHashTests)
BOOST_AUTO_TEST_CASE(FixedHashComparisons)
{
FixedHash<4> h1(sha3("abcd"));
FixedHash<4> h2(sha3("abcd"));
FixedHash<4> h3(sha3("aadd"));
FixedHash<4> h4(0xBAADF00D);
FixedHash<4> h5(0xAAAAAAAA);
FixedHash<4> h6(0xBAADF00D);
BOOST_CHECK(h1 == h2);
BOOST_CHECK(h2 != h3);
BOOST_CHECK(h4 > h5);
BOOST_CHECK(h5 < h4);
BOOST_CHECK(h6 <= h4);
BOOST_CHECK(h6 >= h4);
}
BOOST_AUTO_TEST_CASE(FixedHashXOR)
{
FixedHash<2> h1("0xAAAA");
FixedHash<2> h2("0xBBBB");
BOOST_CHECK((h1 ^ h2) == FixedHash<2>("0x1111"));
h1 ^= h2;
BOOST_CHECK(h1 == FixedHash<2>("0x1111"));
}
BOOST_AUTO_TEST_CASE(FixedHashOR)
{
FixedHash<4> h1("0xD3ADB33F");
FixedHash<4> h2("0xBAADF00D");
FixedHash<4> res("0xFBADF33F");
BOOST_CHECK((h1 | h2) == res);
h1 |= h2;
BOOST_CHECK(h1 == res);
}
BOOST_AUTO_TEST_CASE(FixedHashAND)
{
FixedHash<4> h1("0xD3ADB33F");
FixedHash<4> h2("0xBAADF00D");
FixedHash<4> h3("0x92aDB00D");
BOOST_CHECK((h1 & h2) == h3);
h1 &= h2;
BOOST_CHECK(h1 = h3);
}
BOOST_AUTO_TEST_CASE(FixedHashInvert)
{
FixedHash<4> h1("0xD3ADB33F");
FixedHash<4> h2("0x2C524CC0");
BOOST_CHECK(~h1 == h2);
}
BOOST_AUTO_TEST_CASE(FixedHashContains)
{
FixedHash<4> h1("0xD3ADB331");
FixedHash<4> h2("0x0000B331");
FixedHash<4> h3("0x0000000C");
BOOST_CHECK(h1.contains(h2));
BOOST_CHECK(!h1.contains(h3));
}
BOOST_AUTO_TEST_SUITE_END()
}
}

854
test/libethereum/StateTestsFiller/stPreCompiledContractsTransactionFiller.json

File diff suppressed because one or more lines are too long

5
test/libethereum/state.cpp

@ -129,11 +129,6 @@ BOOST_AUTO_TEST_CASE(stPreCompiledContracts)
dev::test::executeTests("stPreCompiledContracts", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); dev::test::executeTests("stPreCompiledContracts", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
} }
BOOST_AUTO_TEST_CASE(stPreCompiledContractsTransaction)
{
dev::test::executeTests("stPreCompiledContractsTransaction", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
}
BOOST_AUTO_TEST_CASE(stLogTests) BOOST_AUTO_TEST_CASE(stLogTests)
{ {
dev::test::executeTests("stLogTests", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); dev::test::executeTests("stLogTests", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);

Loading…
Cancel
Save