Browse Source

OpenCL stuff, Fix for eth_call.

cl-refactor
Gav Wood 10 years ago
parent
commit
c533f1cbda
  1. 18
      exp/CMakeLists.txt
  2. 29
      exp/main.cpp
  3. 6
      libdevcore/CommonIO.cpp
  4. 2
      libdevcore/CommonIO.h
  5. 1
      libdevcore/RangeMask.h
  6. 4
      libdevcore/TransientDirectory.cpp
  7. 4
      libdevcore/TransientDirectory.h
  8. 2
      libethash/util.h
  9. 38
      libethcore/Ethasher.cpp
  10. 2
      libethcore/Ethasher.h
  11. 117
      libethcore/ProofOfWork.cpp
  12. 6
      libethcore/ProofOfWork.h
  13. 7
      libethereum/CMakeLists.txt
  14. 1
      libethereum/Client.cpp
  15. 2
      libethereum/ClientBase.cpp
  16. 2
      libtestutils/BlockChainLoader.h
  17. 2
      libtestutils/StateLoader.h
  18. 67
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  19. 1
      test/TestUtils.cpp
  20. 2
      test/blockchain.cpp

18
exp/CMakeLists.txt

@ -10,8 +10,26 @@ set(EXECUTABLE exp)
add_executable(${EXECUTABLE} ${SRC_LIST}) add_executable(${EXECUTABLE} ${SRC_LIST})
target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES})
if (READLINE_FOUND)
target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES})
endif()
if (JSONRPC)
target_link_libraries(${EXECUTABLE} web3jsonrpc)
endif()
target_link_libraries(${EXECUTABLE} webthree)
target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} ethereum)
target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} p2p)
target_link_libraries(${EXECUTABLE} ethash-cl)
target_link_libraries(${EXECUTABLE} ethash)
target_link_libraries(${EXECUTABLE} OpenCL)
install( TARGETS ${EXECUTABLE} DESTINATION bin) install( TARGETS ${EXECUTABLE} DESTINATION bin)

29
exp/main.cpp

@ -19,18 +19,25 @@
* @date 2014 * @date 2014
* Ethereum client. * Ethereum client.
*/ */
#define __CL_ENABLE_EXCEPTIONS
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS
#include "libethash-cl/cl.hpp"
#include <functional> #include <functional>
#include <libethereum/AccountDiff.h>
#include <libdevcore/RangeMask.h> #include <libdevcore/RangeMask.h>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libdevcrypto/TrieDB.h> #include <libdevcore/TransientDirectory.h>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libdevcrypto/TrieDB.h>
#include <libp2p/All.h> #include <libp2p/All.h>
#include <libethereum/DownloadMan.h> #include <libethcore/Ethasher.h>
#include <libethcore/ProofOfWork.h>
#include <libethereum/All.h> #include <libethereum/All.h>
#include <libethereum/AccountDiff.h>
#include <libethereum/DownloadMan.h>
#include <liblll/All.h> #include <liblll/All.h>
#include <libwhisper/WhisperPeer.h> #include <libwhisper/WhisperPeer.h>
#include <libwhisper/WhisperHost.h> #include <libwhisper/WhisperHost.h>
@ -101,6 +108,22 @@ int main()
#else #else
int main() int main()
{ {
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
if (platforms.empty())
{
cdebug << "No OpenCL platforms found.";
return false;
}
EthashCL ecl;
BlockInfo genesis = CanonBlockChain::genesis();
TransientDirectory td;
std::pair<MineInfo, Ethash::Proof> r;
while (!r.first.completed)
r = ecl.mine(genesis, 1000);
EthashCL::assignResult(r.second, genesis);
assert(EthashCPU::verify(genesis));
return 0; return 0;
} }
#endif #endif

6
libdevcore/CommonIO.cpp

@ -58,7 +58,7 @@ string dev::memDump(bytes const& _bytes, unsigned _width, bool _html)
} }
// Don't forget to delete[] later. // Don't forget to delete[] later.
bytesRef dev::contentsNew(std::string const& _file) bytesRef dev::contentsNew(std::string const& _file, bytesRef _dest)
{ {
std::ifstream is(_file, std::ifstream::binary); std::ifstream is(_file, std::ifstream::binary);
if (!is) if (!is)
@ -68,8 +68,10 @@ bytesRef dev::contentsNew(std::string const& _file)
streamoff length = is.tellg(); streamoff length = is.tellg();
if (length == 0) // return early, MSVC does not like reading 0 bytes if (length == 0) // return early, MSVC does not like reading 0 bytes
return bytesRef(); return bytesRef();
if (!_dest.empty() && _dest.size() != (unsigned)length)
return bytesRef();
is.seekg (0, is.beg); is.seekg (0, is.beg);
bytesRef ret(new byte[length], length); bytesRef ret = _dest.empty() ? bytesRef(new byte[length], length) : _dest;
is.read((char*)ret.data(), length); is.read((char*)ret.data(), length);
is.close(); is.close();
return ret; return ret;

2
libdevcore/CommonIO.h

@ -46,7 +46,7 @@ namespace dev
bytes contents(std::string const& _file); bytes contents(std::string const& _file);
std::string contentsString(std::string const& _file); std::string contentsString(std::string const& _file);
/// Retrieve and returns the allocated contents of the given file. If the file doesn't exist or isn't readable, returns nullptr. Don't forget to delete [] when finished. /// Retrieve and returns the allocated contents of the given file. If the file doesn't exist or isn't readable, returns nullptr. Don't forget to delete [] when finished.
bytesRef contentsNew(std::string const& _file); bytesRef contentsNew(std::string const& _file, bytesRef _dest = bytesRef());
/// Write the given binary data into the given file, replacing the file if it pre-exists. /// Write the given binary data into the given file, replacing the file if it pre-exists.
void writeFile(std::string const& _file, bytesConstRef _data); void writeFile(std::string const& _file, bytesConstRef _data);

1
libdevcore/RangeMask.h

@ -25,6 +25,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <assert.h>
namespace dev namespace dev
{ {

4
libtestutils/TransientDirectory.cpp → libdevcore/TransientDirectory.cpp

@ -20,11 +20,11 @@
*/ */
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <libdevcore/Exceptions.h> #include "Exceptions.h"
#include "TransientDirectory.h" #include "TransientDirectory.h"
#include "CommonIO.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::test;
TransientDirectory::TransientDirectory(): TransientDirectory::TransientDirectory():
TransientDirectory((boost::filesystem::temp_directory_path() / "eth_transient" / toString(FixedHash<4>::random())).string()) TransientDirectory((boost::filesystem::temp_directory_path() / "eth_transient" / toString(FixedHash<4>::random())).string())

4
libtestutils/TransientDirectory.h → libdevcore/TransientDirectory.h

@ -22,12 +22,9 @@
#pragma once #pragma once
#include <string> #include <string>
#include "Common.h"
namespace dev namespace dev
{ {
namespace test
{
/** /**
* @brief temporary directory implementation * @brief temporary directory implementation
@ -48,4 +45,3 @@ private:
}; };
} }
}

2
libethash/util.h

@ -29,7 +29,7 @@ extern "C" {
#ifdef _MSC_VER #ifdef _MSC_VER
void debugf(const char *str, ...); void debugf(const char *str, ...);
#else #else
#define debugf printf #define debugf(...) fprintf(stderr, __VA_ARGS__)
#endif #endif
static inline uint32_t min_u32(uint32_t a, uint32_t b) static inline uint32_t min_u32(uint32_t a, uint32_t b)

38
libethcore/Ethasher.cpp

@ -123,6 +123,44 @@ ethash_params Ethasher::params(BlockInfo const& _header)
return params((unsigned)_header.number); return params((unsigned)_header.number);
} }
void Ethasher::readFull(BlockInfo const& _header, void* _dest)
{
if (!m_fulls.count(_header.seedHash()))
{
// @memoryleak @bug place it on a pile for deletion - perhaps use shared_ptr.
/* if (!m_fulls.empty())
{
delete [] m_fulls.begin()->second.data();
m_fulls.erase(m_fulls.begin());
}*/
try {
boost::filesystem::create_directories(getDataDir("ethash"));
} catch (...) {}
auto info = rlpList(c_ethashRevision, _header.seedHash());
std::string oldMemoFile = getDataDir("ethash") + "/full";
std::string memoFile = getDataDir("ethash") + "/full-R" + toString(c_ethashRevision) + "-" + toHex(_header.seedHash().ref().cropped(0, 8));
if (boost::filesystem::exists(oldMemoFile) && contents(oldMemoFile + ".info") == info)
{
// memofile valid - rename.
boost::filesystem::rename(oldMemoFile, memoFile);
}
IGNORE_EXCEPTIONS(boost::filesystem::remove(oldMemoFile));
IGNORE_EXCEPTIONS(boost::filesystem::remove(oldMemoFile + ".info"));
ethash_params p = params((unsigned)_header.number);
bytesRef r = contentsNew(memoFile, bytesRef((byte*)_dest, p.full_size));
if (!r)
{
auto c = light(_header);
ethash_prep_full(_dest, &p, c);
writeFile(memoFile, bytesConstRef((byte*)_dest, p.full_size));
}
}
}
ethash_params Ethasher::params(unsigned _n) ethash_params Ethasher::params(unsigned _n)
{ {
ethash_params p; ethash_params p;

2
libethcore/Ethasher.h

@ -56,6 +56,8 @@ public:
static ethash_params params(BlockInfo const& _header); static ethash_params params(BlockInfo const& _header);
static ethash_params params(unsigned _n); static ethash_params params(unsigned _n);
void readFull(BlockInfo const& _header, void* _dest);
struct Result struct Result
{ {
h256 value; h256 value;

117
libethcore/ProofOfWork.cpp

@ -33,32 +33,6 @@
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#if ETH_ETHASHCL #if ETH_ETHASHCL
#include <libethash-cl/ethash_cl_miner.h> #include <libethash-cl/ethash_cl_miner.h>
#define ETHASH_REVISION REVISION
#define ETHASH_DATASET_BYTES_INIT DATASET_BYTES_INIT
#define ETHASH_DATASET_BYTES_GROWTH DATASET_BYTES_GROWTH
#define ETHASH_CACHE_BYTES_INIT CACHE_BYTES_INIT
#define ETHASH_CACHE_BYTES_GROWTH CACHE_BYTES_GROWTH
#define ETHASH_DAGSIZE_BYTES_INIT DAGSIZE_BYTES_INIT
#define ETHASH_DAG_GROWTH DAG_GROWTH
#define ETHASH_EPOCH_LENGTH EPOCH_LENGTH
#define ETHASH_MIX_BYTES MIX_BYTES
#define ETHASH_HASH_BYTES HASH_BYTES
#define ETHASH_DATASET_PARENTS DATASET_PARENTS
#define ETHASH_CACHE_ROUNDS CACHE_ROUNDS
#define ETHASH_ACCESSES ACCESSES
#undef REVISION
#undef DATASET_BYTES_INIT
#undef DATASET_BYTES_GROWTH
#undef CACHE_BYTES_INIT
#undef CACHE_BYTES_GROWTH
#undef DAGSIZE_BYTES_INIT
#undef DAG_GROWTH
#undef EPOCH_LENGTH
#undef MIX_BYTES
#undef HASH_BYTES
#undef DATASET_PARENTS
#undef CACHE_ROUNDS
#undef ACCESSES
#endif #endif
#include "BlockInfo.h" #include "BlockInfo.h"
#include "Ethasher.h" #include "Ethasher.h"
@ -131,16 +105,16 @@ std::pair<MineInfo, EthashCPU::Proof> EthashCPU::mine(BlockInfo const& _header,
#if ETH_ETHASHCL #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 class ethash_cl_miner
{ {
public: public:
struct 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;
};
ethash_cl_miner(); ethash_cl_miner();
bool init(ethash_params const& params, const uint8_t seed[32], unsigned workgroup_size = 64); bool init(ethash_params const& params, const uint8_t seed[32], unsigned workgroup_size = 64);
@ -150,58 +124,63 @@ public:
}; };
*/ */
struct EthashCLHook: public ethash_cl_search_hook struct EthashCLHook: public ethash_cl_miner::search_hook
{ {
virtual bool found(uint64_t const* _nonces, uint32_t _count) void abort()
{
if (m_aborted)
return;
m_abort = true;
for (unsigned timeout = 0; timeout < 100 && !m_aborted; ++timeout)
std::this_thread::sleep_for(chrono::milliseconds(30));
if (!m_aborted)
cwarn << "Couldn't abort. Abandoning OpenCL process.";
m_aborted = m_abort = false;
m_found.clear();
}
vector<Nonce> fetchFound() { vector<Nonce> ret; Guard l(x_all); std::swap(ret, m_found); return ret; }
uint64_t fetchTotal() { Guard l(x_all); auto ret = m_total; m_total = 0; return ret; }
protected:
virtual bool found(uint64_t const* _nonces, uint32_t _count) override
{ {
Guard l(x_all); Guard l(x_all);
for (unsigned i = 0; i < _count; ++i) for (unsigned i = 0; i < _count; ++i)
found.push_back((Nonce)(u64)_nonces[i]); m_found.push_back((Nonce)(u64)_nonces[i]);
if (abort) m_aborted = true;
{ return true;
aborted = true;
return true;
}
return false;
} }
virtual bool searched(uint64_t _startNonce, uint32_t _count) virtual bool searched(uint64_t _startNonce, uint32_t _count) override
{ {
Guard l(x_all); Guard l(x_all);
total += _count; m_total += _count;
last = _startNonce + _count; m_last = _startNonce + _count;
if (abort) if (m_abort)
{ {
aborted = true; m_aborted = true;
return true; return true;
} }
return false; return false;
} }
vector<Nonce> fetchFound() { vector<Nonce> ret; Guard l(x_all); std::swap(ret, found); return ret; } private:
uint64_t fetchTotal() { Guard l(x_all); auto ret = total; total = 0; return ret; }
Mutex x_all; Mutex x_all;
vector<Nonce> found; vector<Nonce> m_found;
uint64_t total; uint64_t m_total;
uint64_t last; uint64_t m_last;
bool abort = false; bool m_abort = false;
bool aborted = false; bool m_aborted = true;
}; };
EthashCL::EthashCL(): EthashCL::EthashCL():
m_miner(new ethash_cl_miner),
m_hook(new EthashCLHook) m_hook(new EthashCLHook)
{ {
} }
EthashCL::~EthashCL() 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) bool EthashCL::verify(BlockInfo const& _header)
@ -211,13 +190,16 @@ bool EthashCL::verify(BlockInfo const& _header)
std::pair<MineInfo, Ethash::Proof> EthashCL::mine(BlockInfo const& _header, unsigned _msTimeout, bool, bool) std::pair<MineInfo, Ethash::Proof> EthashCL::mine(BlockInfo const& _header, unsigned _msTimeout, bool, bool)
{ {
if (m_lastHeader.seedHash() != _header.seedHash()) if (!m_lastHeader || m_lastHeader.seedHash() != _header.seedHash())
{ {
m_miner->init(Ethasher::params(_header), _header.seedHash().data()); if (m_miner)
// TODO: reinit probably won't work when seed changes. m_hook->abort();
m_miner.reset(new ethash_cl_miner);
m_miner->init(Ethasher::params(_header), [&](void* d){ Ethasher::get()->readFull(_header, d); });
} }
if (m_lastHeader != _header) if (m_lastHeader != _header)
{ {
m_hook->abort();
static std::random_device s_eng; static std::random_device s_eng;
uint64_t tryNonce = (uint64_t)(u64)(m_last = Nonce::random(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_miner->search(_header.headerHash(WithoutNonce).data(), tryNonce, *m_hook);
@ -228,10 +210,11 @@ std::pair<MineInfo, Ethash::Proof> EthashCL::mine(BlockInfo const& _header, unsi
auto found = m_hook->fetchFound(); auto found = m_hook->fetchFound();
if (!found.empty()) if (!found.empty())
{ {
h256 mixHash; // ????? Nonce n = (Nonce)(u64)found[0];
return std::make_pair(MineInfo{0.0, 1e99, 0, true}, EthashCL::Proof((Nonce)(u64)found[0], mixHash)); auto result = Ethasher::eval(_header, n);
return std::make_pair(MineInfo(true), EthashCL::Proof{n, result.mixHash});
} }
return std::make_pair(MineInfo{0.0, 1e99, 0, false}, EthashCL::Proof()); return std::make_pair(MineInfo(false), EthashCL::Proof());
} }
#endif #endif

6
libethcore/ProofOfWork.h

@ -42,6 +42,8 @@ namespace eth
struct MineInfo struct MineInfo
{ {
MineInfo() = default;
MineInfo(bool _completed): completed(_completed) {}
void combine(MineInfo const& _m) { requirement = std::max(requirement, _m.requirement); best = std::min(best, _m.best); hashes += _m.hashes; completed = completed || _m.completed; } void combine(MineInfo const& _m) { requirement = std::max(requirement, _m.requirement); best = std::min(best, _m.best); hashes += _m.hashes; completed = completed || _m.completed; }
double requirement = 0; double requirement = 0;
double best = 1e99; double best = 1e99;
@ -67,6 +69,8 @@ protected:
}; };
#if ETH_ETHASHCL #if ETH_ETHASHCL
class EthashCLHook;
class EthashCL class EthashCL
{ {
public: public:
@ -88,7 +92,7 @@ protected:
BlockInfo m_lastHeader; BlockInfo m_lastHeader;
Nonce m_mined; Nonce m_mined;
std::unique_ptr<ethash_cl_miner> m_miner; std::unique_ptr<ethash_cl_miner> m_miner;
std::unique_ptr<ethash_cl_search_hook> m_hook; std::unique_ptr<EthashCLHook> m_hook;
}; };
using Ethash = EthashCL; using Ethash = EthashCL;

7
libethereum/CMakeLists.txt

@ -25,19 +25,18 @@ else()
add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
endif() endif()
target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES})
target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} evm)
target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} lll)
target_link_libraries(${EXECUTABLE} whisper) target_link_libraries(${EXECUTABLE} whisper)
target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} p2p)
target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcrypto)
target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES})
target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} secp256k1)
if (ETHASHCL) if (ETHASHCL)
target_link_libraries(${EXECUTABLE} ethash-cl) target_link_libraries(${EXECUTABLE} ethash-cl)
target_link_libraries(${EXECUTABLE} OpenCL)
endif () endif ()
if (CMAKE_COMPILER_IS_MINGW) if (CMAKE_COMPILER_IS_MINGW)

1
libethereum/Client.cpp

@ -334,6 +334,7 @@ void Client::setMiningThreads(unsigned _threads)
{ {
stopMining(); stopMining();
#if ETH_ETHASHCL #if ETH_ETHASHCL
(void)_threads;
unsigned t = 1; unsigned t = 1;
#else #else
auto t = _threads ? _threads : thread::hardware_concurrency(); auto t = _threads ? _threads : thread::hardware_concurrency();

2
libethereum/ClientBase.cpp

@ -75,7 +75,7 @@ ExecutionResult ClientBase::call(Secret _secret, u256 _value, Address _dest, byt
u256 n = temp.transactionsFrom(a); u256 n = temp.transactionsFrom(a);
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret);
if (_ff == FudgeFactor::Lenient) if (_ff == FudgeFactor::Lenient)
temp.addBalance(a, (u256)(t.gasRequired() * t.gasPrice() + t.value())); temp.addBalance(a, (u256)(t.gas() * t.gasPrice() + t.value()));
ret = temp.execute(bc().lastHashes(), t, Permanence::Reverted); ret = temp.execute(bc().lastHashes(), t, Permanence::Reverted);
} }
catch (...) catch (...)

2
libtestutils/BlockChainLoader.h

@ -22,9 +22,9 @@
#pragma once #pragma once
#include <string> #include <string>
#include <json/json.h> #include <json/json.h>
#include <libdevcore/TransientDirectory.h>
#include <libethereum/BlockChain.h> #include <libethereum/BlockChain.h>
#include <libethereum/State.h> #include <libethereum/State.h>
#include "TransientDirectory.h"
namespace dev namespace dev
{ {

2
libtestutils/StateLoader.h

@ -22,8 +22,8 @@
#pragma once #pragma once
#include <json/json.h> #include <json/json.h>
#include <libdevcore/TransientDirectory.h>
#include <libethereum/State.h> #include <libethereum/State.h>
#include "TransientDirectory.h"
namespace dev namespace dev
{ {

67
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -449,64 +449,55 @@ static TransactionSkeleton toTransaction(Json::Value const& _json)
string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json) string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json)
{ {
TransactionSkeleton t;
try try
{ {
t = toTransaction(_json); string ret;
TransactionSkeleton t = toTransaction(_json);
if (!t.from)
t.from = m_accounts->getDefaultTransactAccount();
if (t.creation)
ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));;
if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow.
if (!t.gas)
t.gas = min<u256>(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice);
if (m_accounts->isRealAccount(t.from))
authenticate(t, false);
else if (m_accounts->isProxyAccount(t.from))
authenticate(t, true);
return ret;
} }
catch (...) catch (...)
{ {
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
} }
string ret;
if (!t.from)
t.from = m_accounts->getDefaultTransactAccount();
if (t.creation)
ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));;
if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow.
if (!t.gas)
t.gas = min<u256>(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice);
if (m_accounts->isRealAccount(t.from))
authenticate(t, false);
else if (m_accounts->isProxyAccount(t.from))
authenticate(t, true);
return ret;
} }
string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const& _blockNumber) string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const& _blockNumber)
{ {
TransactionSkeleton t;
int number;
try try
{ {
t = toTransaction(_json); TransactionSkeleton t = toTransaction(_json);
number = jsToBlockNumber(_blockNumber); if (!t.from)
t.from = m_accounts->getDefaultTransactAccount();
// if (!m_accounts->isRealAccount(t.from))
// return ret;
if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo;
if (!t.gas)
t.gas = client()->gasLimitRemaining();
return toJS(client()->call(m_accounts->secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice, jsToBlockNumber(_blockNumber), FudgeFactor::Lenient).output);
} }
catch (...) catch (...)
{ {
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
} }
string ret;
if (!t.from)
t.from = m_accounts->getDefaultTransactAccount();
// if (!m_accounts->isRealAccount(t.from))
// return ret;
if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo;
if (!t.gas)
t.gas = client()->gasLimitRemaining();
ret = toJS(client()->call(m_accounts->secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice, number).output);
return ret;
} }
bool WebThreeStubServerBase::eth_flush() bool WebThreeStubServerBase::eth_flush()

1
test/TestUtils.cpp

@ -22,6 +22,7 @@
#include <thread> #include <thread>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <libtestutils/Common.h>
#include <libtestutils/BlockChainLoader.h> #include <libtestutils/BlockChainLoader.h>
#include <libtestutils/FixedClient.h> #include <libtestutils/FixedClient.h>
#include "TestUtils.h" #include "TestUtils.h"

2
test/blockchain.cpp

@ -22,7 +22,7 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <libdevcrypto/FileSystem.h> #include <libdevcrypto/FileSystem.h>
#include <libtestutils/TransientDirectory.h> #include <libdevcore/TransientDirectory.h>
#include <libethereum/CanonBlockChain.h> #include <libethereum/CanonBlockChain.h>
#include "TestHelper.h" #include "TestHelper.h"

Loading…
Cancel
Save