From 3a61c2577e8e64812aaef2e3f6e4da712d876602 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 24 Jul 2015 23:23:39 +0200 Subject: [PATCH 01/10] CL: switch to chunks if clEnqueuWriteBuffer fails Probably fixes #2559 even though chunking is not stable at the moment. --- libethash-cl/ethash_cl_miner.cpp | 37 +++++++++++--------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index 982e4ec9d..8042888cb 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -361,15 +361,22 @@ bool ethash_cl_miner::init( try { m_dagChunksCount = 1; + ETHCL_LOG("Creating one big buffer for the DAG"); m_dagChunks.push_back(cl::Buffer(m_context, CL_MEM_READ_ONLY, _dagSize)); - ETHCL_LOG("Created one big buffer for the DAG"); + ETHCL_LOG("Loading single big chunk kernels"); + m_hashKernel = cl::Kernel(program, "ethash_hash"); + m_searchKernel = cl::Kernel(program, "ethash_search"); + ETHCL_LOG("Mapping one big chunk."); + m_queue.enqueueWriteBuffer(m_dagChunks[0], CL_TRUE, 0, _dagSize, _dag); } catch (cl::Error const& err) { int errCode = err.err(); if (errCode != CL_INVALID_BUFFER_SIZE || errCode != CL_MEM_OBJECT_ALLOCATION_FAILURE) - ETHCL_LOG("Allocating single buffer failed with: " << err.what() << "(" << errCode << ")"); + ETHCL_LOG("Allocating/mapping single buffer failed with: " << err.what() << "(" << errCode << ")"); cl_ulong result; + // if we fail midway on the try above make sure we start clean + m_dagChunks.clear(); device.getInfo(CL_DEVICE_MAX_MEM_ALLOC_SIZE, &result); ETHCL_LOG( "Failed to allocate 1 big chunk. Max allocateable memory is " @@ -387,32 +394,9 @@ bool ethash_cl_miner::init( (i == 3) ? (_dagSize - 3 * ((_dagSize >> 9) << 7)) : (_dagSize >> 9) << 7 )); } - } - - if (m_dagChunksCount == 1) - { - ETHCL_LOG("Loading single big chunk kernels"); - m_hashKernel = cl::Kernel(program, "ethash_hash"); - m_searchKernel = cl::Kernel(program, "ethash_search"); - } - else - { ETHCL_LOG("Loading chunk kernels"); m_hashKernel = cl::Kernel(program, "ethash_hash_chunks"); m_searchKernel = cl::Kernel(program, "ethash_search_chunks"); - } - - // create buffer for header - ETHCL_LOG("Creating buffer for header."); - m_header = cl::Buffer(m_context, CL_MEM_READ_ONLY, 32); - - if (m_dagChunksCount == 1) - { - ETHCL_LOG("Mapping one big chunk."); - m_queue.enqueueWriteBuffer(m_dagChunks[0], CL_TRUE, 0, _dagSize, _dag); - } - else - { // TODO Note: If we ever change to _dagChunksNum other than 4, then the size would need recalculation void* dag_ptr[4]; for (unsigned i = 0; i < m_dagChunksCount; i++) @@ -426,6 +410,9 @@ bool ethash_cl_miner::init( m_queue.enqueueUnmapMemObject(m_dagChunks[i], dag_ptr[i]); } } + // create buffer for header + ETHCL_LOG("Creating buffer for header."); + m_header = cl::Buffer(m_context, CL_MEM_READ_ONLY, 32); // create mining buffers for (unsigned i = 0; i != c_bufferCount; ++i) From c429b03ddb964c602c1b5fcd719fc55a6a24f1be Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 28 Jul 2015 09:55:27 +0200 Subject: [PATCH 02/10] Disable chunking until further notice --- libethash-cl/ethash_cl_miner.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index 8042888cb..2183de320 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -371,6 +371,9 @@ bool ethash_cl_miner::init( } catch (cl::Error const& err) { + ETHCL_LOG("Allocating/mapping single buffer failed with: " << err.what() << "(" << err.err() << "). GPU can't allocate the DAG in a single chunk. Bailing."); + return false; +#if 0 // Disabling chunking for release since it seems not to work. Never manages to mine a block. TODO: Fix when time is found. int errCode = err.err(); if (errCode != CL_INVALID_BUFFER_SIZE || errCode != CL_MEM_OBJECT_ALLOCATION_FAILURE) ETHCL_LOG("Allocating/mapping single buffer failed with: " << err.what() << "(" << errCode << ")"); @@ -409,6 +412,7 @@ bool ethash_cl_miner::init( memcpy(dag_ptr[i], (char *)_dag + i*((_dagSize >> 9) << 7), (i == 3) ? (_dagSize - 3 * ((_dagSize >> 9) << 7)) : (_dagSize >> 9) << 7); m_queue.enqueueUnmapMemObject(m_dagChunks[i], dag_ptr[i]); } +#endif } // create buffer for header ETHCL_LOG("Creating buffer for header."); From 665c7240f880a79f4d20c2a6028695dcfcb0de66 Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Tue, 28 Jul 2015 14:17:22 +0200 Subject: [PATCH 03/10] bugfix --- libethcore/Common.cpp | 29 ----------------------------- libethcore/Params.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/libethcore/Common.cpp b/libethcore/Common.cpp index eefc3052b..343d87be1 100644 --- a/libethcore/Common.cpp +++ b/libethcore/Common.cpp @@ -51,36 +51,7 @@ const unsigned c_databaseBaseVersion = 9; const unsigned c_databaseVersionModifier = 0; #endif -#if ETH_FRONTIER -Network c_network = resetNetwork(Network::Frontier); -#else -Network c_network = resetNetwork(Network::Olympic); -#endif -Network resetNetwork(Network _n) -{ - c_network = _n; - c_maximumExtraDataSize = c_network == Network::Olympic ? 1024 : 32; - switch(_n) - { - case Network::Turbo: - c_minGasLimit = 100000000; - break; - case Network::Olympic: - c_minGasLimit = 125000; - break; - case Network::Frontier: - c_minGasLimit = 5000; - break; - } - - c_gasLimitBoundDivisor = 1024; - c_minimumDifficulty = 131072; - c_difficultyBoundDivisor = 2048; - c_durationLimit = c_network == Network::Turbo ? 2 : c_network == Network::Olympic ? 8 : 13; - c_blockReward = c_network == Network::Olympic ? (1500 * finney) : (5 * ether); - return _n; -} const unsigned c_databaseVersion = c_databaseBaseVersion + (c_databaseVersionModifier << 8) + (23 << 9); diff --git a/libethcore/Params.cpp b/libethcore/Params.cpp index c1290219e..0612db84e 100644 --- a/libethcore/Params.cpp +++ b/libethcore/Params.cpp @@ -38,6 +38,37 @@ u256 c_durationLimit; u256 c_blockReward; //--- END: AUTOGENERATED FROM /feeStructure.json +#if ETH_FRONTIER +Network c_network = resetNetwork(Network::Frontier); +#else +Network c_network = resetNetwork(Network::Olympic); +#endif + +Network resetNetwork(Network _n) +{ + c_network = _n; + c_maximumExtraDataSize = c_network == Network::Olympic ? 1024 : 32; + switch(_n) + { + case Network::Turbo: + c_minGasLimit = 100000000; + break; + case Network::Olympic: + c_minGasLimit = 125000; + break; + case Network::Frontier: + c_minGasLimit = 5000; + break; + } + + c_gasLimitBoundDivisor = 1024; + c_minimumDifficulty = 131072; + c_difficultyBoundDivisor = 2048; + c_durationLimit = c_network == Network::Turbo ? 2 : c_network == Network::Olympic ? 8 : 13; + c_blockReward = c_network == Network::Olympic ? (1500 * finney) : (5 * ether); + return _n; +} + } } From f16cb2e23e309b36846e82de20e35e1dc18ef5d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 28 Jul 2015 14:34:55 +0200 Subject: [PATCH 04/10] Force Interpreter VM when VM tracing requested. Fixes https://github.com/ethereum/cpp-ethereum/issues/2585. --- libethereum/State.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 5639b8bb6..27263caf8 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -1137,6 +1137,12 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Permanence _p, OnOpFunc const& _onOp) { + auto onOp = _onOp; +#if ETH_VMTRACE + if (isChannelVisible()) + onOp = Executive::simpleTrace(); // override tracer +#endif + #if ETH_PARANOIA paranoia("start of execution.", true); State old(*this); @@ -1161,16 +1167,11 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per ctrace << toHex(e.t().rlp()); #endif if (!e.execute()) -#if ETH_VMTRACE { - if (isChannelVisible()) - e.go(e.simpleTrace()); - else - e.go(_onOp); + if (onOp) + VMFactory::setKind(VMKind::Interpreter); // force interpreter if a trace is wanted + e.go(onOp); } -#else - e.go(_onOp); -#endif e.finalize(); #if ETH_PARANOIA @@ -1183,13 +1184,13 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per else { commit(); - + #if ETH_PARANOIA && !ETH_FATDB ctrace << "Executed; now" << rootHash(); ctrace << old.diff(*this); - + paranoia("after execution commit.", true); - + if (e.t().receiveAddress()) { EnforceRefs r(m_db, true); @@ -1200,9 +1201,9 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per } } #endif - + // TODO: CHECK TRIE after level DB flush to make sure exactly the same. - + // Add to the user-originated transactions that we've executed. m_transactions.push_back(e.t()); m_receipts.push_back(TransactionReceipt(rootHash(), startGasUsed + e.gasUsed(), e.logs())); From a51037e64504bec6bcc673dd31436707436a9f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 28 Jul 2015 14:35:14 +0200 Subject: [PATCH 05/10] Fix incorrect std::move. --- libp2p/RLPXSocketIO.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libp2p/RLPXSocketIO.cpp b/libp2p/RLPXSocketIO.cpp index deb47a728..aa4df7e20 100644 --- a/libp2p/RLPXSocketIO.cpp +++ b/libp2p/RLPXSocketIO.cpp @@ -1,16 +1,16 @@ /* 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 . */ @@ -34,7 +34,7 @@ RLPXSocketIO::RLPXSocketIO(unsigned _protCount, RLPXFrameCoder& _coder, bi::tcp: m_flowControl(_flowControl), m_coder(_coder), m_socket(_socket), - m_writers(move(writers(_protCount))), + m_writers(writers(_protCount)), m_egressCapacity(m_flowControl ? _initialCapacity : MaxPacketSize * m_writers.size()) {} @@ -61,11 +61,11 @@ void RLPXSocketIO::send(unsigned _protocolType, unsigned _type, RLPStream& _payl void RLPXSocketIO::doWrite() { m_toSend.clear(); - + size_t capacity; DEV_GUARDED(x_queued) capacity = min(m_egressCapacity, MaxPacketSize); - + size_t active = 0; for (auto const& w: m_writers) if (w.size()) @@ -97,7 +97,7 @@ void RLPXSocketIO::write(size_t _dequed) { if (ec) return; // TCPSocketWriteError - + bool reschedule = false; DEV_GUARDED(x_queued) { @@ -109,4 +109,4 @@ void RLPXSocketIO::write(size_t _dequed) if (reschedule) doWrite(); }); -} \ No newline at end of file +} From 78fd8548edb0f0622fb1141b7ce3905cd002f159 Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 28 Jul 2015 14:44:55 +0200 Subject: [PATCH 06/10] fixed JitWorker initialization --- libevm/SmartVM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libevm/SmartVM.cpp b/libevm/SmartVM.cpp index 50a548002..565e88213 100644 --- a/libevm/SmartVM.cpp +++ b/libevm/SmartVM.cpp @@ -61,8 +61,8 @@ namespace class JitWorker { - std::thread m_worker; concurrent_queue m_queue; + std::thread m_worker; // Worker must be last to initialize void work() { From c30ae3216d5b7336c793b5f041b2f2e90744b7f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 28 Jul 2015 14:47:55 +0200 Subject: [PATCH 07/10] Force Interpreter VM when VM tracing requested (moved from State to Executive). Fixes https://github.com/ethereum/cpp-ethereum/issues/2585. --- libethereum/Executive.cpp | 3 ++- libethereum/State.cpp | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index d281a00fd..f78e8f7f4 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -325,7 +325,8 @@ bool Executive::go(OnOpFunc const& _onOp) #endif try { - auto vm = VMFactory::create(); + // Create VM instance. Force Interpreter if tracing requested. + auto vm = _onOp ? VMFactory::create(VMKind::Interpreter) : VMFactory::create(); if (m_isCreation) { auto out = vm->exec(m_gas, *m_ext, _onOp); diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 27263caf8..3127ad1f6 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -1167,11 +1167,7 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per ctrace << toHex(e.t().rlp()); #endif if (!e.execute()) - { - if (onOp) - VMFactory::setKind(VMKind::Interpreter); // force interpreter if a trace is wanted e.go(onOp); - } e.finalize(); #if ETH_PARANOIA From 8f1d5b4330e08a8369f9624cac377f4ff0b807aa Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 28 Jul 2015 14:51:47 +0200 Subject: [PATCH 08/10] Fixed typo. --- alethzero/MainWin.cpp | 2 +- eth/main.cpp | 6 +++--- libweb3jsonrpc/WebThreeStubServer.cpp | 2 +- libweb3jsonrpc/WebThreeStubServer.h | 4 ++-- libweb3jsonrpc/WebThreeStubServerBase.cpp | 2 +- libweb3jsonrpc/WebThreeStubServerBase.h | 10 +++++----- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 6858d7ecf..214dbab1e 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -233,7 +233,7 @@ Main::Main(QWidget *parent) : m_httpConnector.reset(new jsonrpc::HttpServer(SensibleHttpPort, "", "", dev::SensibleHttpThreads)); auto w3ss = new OurWebThreeStubServer(*m_httpConnector, this); m_server.reset(w3ss); - auto sessionKey = w3ss->newSession(SessionPermissions{{Priviledge::Admin}}); + auto sessionKey = w3ss->newSession(SessionPermissions{{Privilege::Admin}}); connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString))); m_server->setIdentities(keysAsVector(owned())); m_server->StartListening(); diff --git a/eth/main.cpp b/eth/main.cpp index 4d3707c10..157cc3b76 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -1779,9 +1779,9 @@ int main(int argc, char** argv) jsonrpcServer->setMiningBenefactorChanger([&](Address const& a) { beneficiary = a; }); jsonrpcServer->StartListening(); if (jsonAdmin.empty()) - jsonAdmin = jsonrpcServer->newSession(SessionPermissions{{Priviledge::Admin}}); + jsonAdmin = jsonrpcServer->newSession(SessionPermissions{{Privilege::Admin}}); else - jsonrpcServer->addSession(jsonAdmin, SessionPermissions{{Priviledge::Admin}}); + jsonrpcServer->addSession(jsonAdmin, SessionPermissions{{Privilege::Admin}}); cout << "JSONRPC Admin Session Key: " << jsonAdmin << endl; writeFile(getDataDir("web3") + "/session.key", jsonAdmin); writeFile(getDataDir("web3") + "/session.url", "http://localhost:" + toString(jsonRPCURL)); @@ -1810,7 +1810,7 @@ int main(int argc, char** argv) #if ETH_JSCONSOLE || !ETH_TRUE JSLocalConsole console; shared_ptr rpcServer = make_shared(*console.connector(), web3, make_shared([&](){ return web3.ethereum(); }, getAccountPassword, keyManager), vector(), keyManager, *gasPricer); - string sessionKey = rpcServer->newSession(SessionPermissions{{Priviledge::Admin}}); + string sessionKey = rpcServer->newSession(SessionPermissions{{Privilege::Admin}}); console.eval("web3.admin.setSessionKey('" + sessionKey + "')"); while (!g_exit) { diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp index 0a7277e06..7dd1ed246 100644 --- a/libweb3jsonrpc/WebThreeStubServer.cpp +++ b/libweb3jsonrpc/WebThreeStubServer.cpp @@ -77,7 +77,7 @@ bool WebThreeStubServer::eth_notePassword(string const& _password) return true; } -#define ADMIN requires(_session, Priviledge::Admin) +#define ADMIN requires(_session, Privilege::Admin) Json::Value WebThreeStubServer::admin_eth_blockQueueStatus(string const& _session) { diff --git a/libweb3jsonrpc/WebThreeStubServer.h b/libweb3jsonrpc/WebThreeStubServer.h index 2860f852b..35ea03737 100644 --- a/libweb3jsonrpc/WebThreeStubServer.h +++ b/libweb3jsonrpc/WebThreeStubServer.h @@ -40,7 +40,7 @@ class BlockQueue; struct SessionPermissions { - std::unordered_set priviledges; + std::unordered_set privileges; }; /** @@ -59,7 +59,7 @@ public: virtual void setMiningBenefactorChanger(std::function const& _f) { m_setMiningBenefactor = _f; } private: - virtual bool hasPriviledgeLevel(std::string const& _session, Priviledge _l) const override { auto it = m_sessions.find(_session); return it != m_sessions.end() && it->second.priviledges.count(_l); } + virtual bool hasPrivilegeLevel(std::string const& _session, Privilege _l) const override { auto it = m_sessions.find(_session); return it != m_sessions.end() && it->second.privileges.count(_l); } virtual dev::eth::Interface* client() override; virtual std::shared_ptr face() override; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index dbcbe03cd..bf0576039 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -510,7 +510,7 @@ string WebThreeStubServerBase::eth_compileSerpent(string const& _source) return res; } -#define ADMIN requires(_session, Priviledge::Admin) +#define ADMIN requires(_session, Privilege::Admin) bool WebThreeStubServerBase::admin_web3_setVerbosity(int _v, string const& _session) { diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 62209a5b4..4230f7237 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -59,7 +59,7 @@ public: virtual void put(std::string const& _name, std::string const& _key, std::string const& _value) = 0; }; -enum class Priviledge +enum class Privilege { Admin }; @@ -69,9 +69,9 @@ enum class Priviledge namespace std { -template<> struct hash +template<> struct hash { - size_t operator()(dev::Priviledge _value) const { return (size_t)_value; } + size_t operator()(dev::Privilege _value) const { return (size_t)_value; } }; } @@ -190,8 +190,8 @@ public: std::map const& ids() const { return m_shhIds; } protected: - void requires(std::string const& _session, Priviledge _l) const { if (!hasPriviledgeLevel(_session, _l)) throw jsonrpc::JsonRpcException("Invalid priviledges"); } - virtual bool hasPriviledgeLevel(std::string const& _session, Priviledge _l) const { (void)_session; (void)_l; return false; } + void requires(std::string const& _session, Privilege _l) const { if (!hasPrivilegeLevel(_session, _l)) throw jsonrpc::JsonRpcException("Invalid privileges"); } + virtual bool hasPrivilegeLevel(std::string const& _session, Privilege _l) const { (void)_session; (void)_l; return false; } virtual dev::eth::Interface* client() = 0; virtual std::shared_ptr face() = 0; From 1d4eeb3a665f8fb277208b52147a1868bc5412e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 28 Jul 2015 16:02:16 +0200 Subject: [PATCH 09/10] Fix evmjit Windows exports. --- evmjit/include/evmjit/JIT-c.h | 14 +++++++++++--- evmjit/libevmjit/JIT-c.cpp | 6 +++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/evmjit/include/evmjit/JIT-c.h b/evmjit/include/evmjit/JIT-c.h index a92b29090..d7c792451 100644 --- a/evmjit/include/evmjit/JIT-c.h +++ b/evmjit/include/evmjit/JIT-c.h @@ -1,6 +1,14 @@ #include "stdint.h" +#ifdef _MSC_VER +#define EXPORT __declspec(dllexport) +#define _ALLOW_KEYWORD_MACROS +#define noexcept throw() +#else +#define EXPORT +#endif + #ifdef __cplusplus extern "C" { #endif @@ -51,11 +59,11 @@ typedef enum evmjit_return_code typedef struct evmjit_context evmjit_context; -evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env); +EXPORT evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env); -evmjit_return_code evmjit_exec(evmjit_context* _context); +EXPORT evmjit_return_code evmjit_exec(evmjit_context* _context); -void evmjit_destroy(evmjit_context* _context); +EXPORT void evmjit_destroy(evmjit_context* _context); inline char const* evmjit_get_output(evmjit_runtime_data* _data) { return _data->callData; } diff --git a/evmjit/libevmjit/JIT-c.cpp b/evmjit/libevmjit/JIT-c.cpp index 2fd578108..7c5cd0b14 100644 --- a/evmjit/libevmjit/JIT-c.cpp +++ b/evmjit/libevmjit/JIT-c.cpp @@ -6,7 +6,7 @@ extern "C" { using namespace dev::evmjit; -EXPORT evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env) +evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env) { auto data = reinterpret_cast(_data); auto env = reinterpret_cast(_env); @@ -20,13 +20,13 @@ EXPORT evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env) return reinterpret_cast(context); } -EXPORT void evmjit_destroy(evmjit_context* _context) +void evmjit_destroy(evmjit_context* _context) { auto context = reinterpret_cast(_context); delete context; } -EXPORT evmjit_return_code evmjit_exec(evmjit_context* _context) +evmjit_return_code evmjit_exec(evmjit_context* _context) { auto context = reinterpret_cast(_context); From 8c6b653790634c2451068682a4534f836264937e Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 28 Jul 2015 16:02:44 +0200 Subject: [PATCH 10/10] clear state on dropping transactions from queue --- libethereum/Client.cpp | 16 ++++++++++++++++ libethereum/Client.h | 4 ++++ libethereum/TransactionQueue.cpp | 6 +++++- libethereum/TransactionQueue.h | 4 ++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 0ffc4dcd7..7a9172a90 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -94,6 +94,7 @@ void Client::init(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _ m_lastGetWork = std::chrono::system_clock::now() - chrono::seconds(30); m_tqReady = m_tq.onReady([=](){ this->onTransactionQueueReady(); }); // TODO: should read m_tq->onReady(thisThread, syncTransactionQueue); + m_tqReplaced = m_tq.onReplaced([=](h256 const&){ this->resetState(); }); m_bqReady = m_bq.onReady([=](){ this->onBlockQueueReady(); }); // TODO: should read m_bq->onReady(thisThread, syncBlockQueue); m_bq.setOnBad([=](Exception& ex){ this->onBadBlock(ex); }); bc().setOnBad([=](Exception& ex){ this->onBadBlock(ex); }); @@ -650,6 +651,21 @@ void Client::resyncStateFromChain() } } +void Client::resetState() +{ + State newPreMine; + DEV_READ_GUARDED(x_preMine) + newPreMine = m_preMine; + + DEV_WRITE_GUARDED(x_working) + m_working = newPreMine; + DEV_READ_GUARDED(x_working) DEV_WRITE_GUARDED(x_postMine) + m_postMine = m_working; + + onPostStateChanged(); + onTransactionQueueReady(); +} + void Client::onChainChanged(ImportRoute const& _ir) { h256Hash changeds; diff --git a/libethereum/Client.h b/libethereum/Client.h index 630898b20..973270877 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -254,6 +254,9 @@ protected: /// Called after processing blocks by onChainChanged(_ir) void resyncStateFromChain(); + /// Clear working state of transactions + void resetState(); + /// Magically called when the chain has changed. An import route is provided. /// Called by either submitWork() or in our main thread through syncBlockQueue(). void onChainChanged(ImportRoute const& _ir); @@ -307,6 +310,7 @@ protected: std::shared_ptr m_sealEngine; ///< Our block-sealing engine. Handler<> m_tqReady; + Handler m_tqReplaced; Handler<> m_bqReady; bool m_wouldMine = false; ///< True if we /should/ be mining. diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp index 5de86c818..aeeb35214 100644 --- a/libethereum/TransactionQueue.cpp +++ b/libethereum/TransactionQueue.cpp @@ -147,7 +147,11 @@ ImportResult TransactionQueue::manageImport_WITH_LOCK(h256 const& _h, Transactio if (_transaction.gasPrice() < (*t->second).transaction.gasPrice()) return ImportResult::OverbidGasPrice; else - remove_WITH_LOCK((*t->second).transaction.sha3()); + { + h256 dropped = (*t->second).transaction.sha3(); + remove_WITH_LOCK(dropped); + m_onReplaced(dropped); + } } } auto fs = m_future.find(_transaction.from()); diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h index f6c140e6f..9c8283aa2 100644 --- a/libethereum/TransactionQueue.h +++ b/libethereum/TransactionQueue.h @@ -117,6 +117,9 @@ public: /// Register a handler that will be called once asynchronous verification is comeplte an transaction has been imported template Handler onImport(T const& _t) { return m_onImport.add(_t); } + /// Register a handler that will be called once asynchronous verification is comeplte an transaction has been imported + template Handler onReplaced(T const& _t) { return m_onReplaced.add(_t); } + private: /// Verified and imported transaction @@ -184,6 +187,7 @@ private: Signal<> m_onReady; ///< Called when a subsequent call to import transactions will return a non-empty container. Be nice and exit fast. Signal m_onImport; ///< Called for each import attempt. Arguments are result, transaction id an node id. Be nice and exit fast. + Signal m_onReplaced; ///< Called whan transction is dropped during a call to import() to make room for another transaction. unsigned m_limit; ///< Max number of pending transactions unsigned m_futureLimit; ///< Max number of future transactions unsigned m_futureSize = 0; ///< Current number of future transactions