diff --git a/ethminer/Farm.h b/ethminer/Farm.h deleted file mode 100644 index ae2ef5a7d..000000000 --- a/ethminer/Farm.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! - */ - -#ifndef JSONRPC_CPP_STUB_FARM_H_ -#define JSONRPC_CPP_STUB_FARM_H_ - -#include - -class Farm : public jsonrpc::Client -{ - public: - Farm(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {} - - Json::Value eth_getWork() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_getWork",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - p.append(param3); - Json::Value result = this->CallMethod("eth_submitWork",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } -}; - -#endif //JSONRPC_CPP_STUB_FARM_H_ diff --git a/ethminer/FarmClient.h b/ethminer/FarmClient.h new file mode 100644 index 000000000..7f5f29182 --- /dev/null +++ b/ethminer/FarmClient.h @@ -0,0 +1,70 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_FARMCLIENT_H_ +#define JSONRPC_CPP_STUB_FARMCLIENT_H_ + +#include + +class FarmClient : public jsonrpc::Client +{ + public: + FarmClient(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {} + + Json::Value eth_getWork() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_getWork",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + p.append(param3); + Json::Value result = this->CallMethod("eth_submitWork",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_submitHashrate(int param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_submitHashrate",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_awaitNewWork() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_awaitNewWork",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_progress() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_progress",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } +}; + +#endif //JSONRPC_CPP_STUB_FARMCLIENT_H_ diff --git a/ethminer/MinerAux.h b/ethminer/MinerAux.h index a378312ed..2f20d7db8 100644 --- a/ethminer/MinerAux.h +++ b/ethminer/MinerAux.h @@ -52,7 +52,7 @@ #include "BuildInfo.h" #if ETH_JSONRPC || !ETH_TRUE #include "PhoneHome.h" -#include "Farm.h" +#include "FarmClient.h" #endif using namespace std; using namespace dev; @@ -482,7 +482,8 @@ private: #if ETH_JSONRPC || !ETH_TRUE jsonrpc::HttpClient client(_remote); - Farm rpc(client); + h256 id = h256::random(); + ::FarmClient rpc(client); GenericFarm f; f.setSealers(sealers); if (_m == MinerType::CPU) @@ -504,10 +505,16 @@ private: }); for (unsigned i = 0; !completed; ++i) { + auto mp = f.miningProgress(); + f.resetMiningProgress(); if (current) - minelog << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress(); + minelog << "Mining on PoWhash" << current.headerHash << ": " << mp; else minelog << "Getting work package..."; + + auto rate = mp.rate(); + rpc.eth_submitHashrate((int)rate, "0x" + id.hex()); + Json::Value v = rpc.eth_getWork(); h256 hh(v[0].asString()); h256 newSeedHash(v[1].asString()); diff --git a/ethminer/farm.json b/ethminer/farm.json index ff0a2e9e7..4d4981510 100644 --- a/ethminer/farm.json +++ b/ethminer/farm.json @@ -1,6 +1,7 @@ [ { "name": "eth_getWork", "params": [], "order": [], "returns": []}, - { "name": "eth_submitWork", "params": ["", "", ""], "order": [], "returns": true} + { "name": "eth_submitWork", "params": ["", "", ""], "order": [], "returns": true}, + { "name": "eth_submitHashrate", "params": [0, ""], "order": [], "returns": true}, { "name": "eth_awaitNewWork", "params": [], "order": [], "returns": []}, { "name": "eth_progress", "params": [], "order": [], "returns": true} ] diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 2631a28cb..3a6087ea5 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -509,9 +509,10 @@ WorkingProgress Client::miningProgress() const uint64_t Client::hashrate() const { + uint64_t r = externalHashrate(); if (Ethash::isWorking(m_sealEngine.get())) - return Ethash::workingProgress(m_sealEngine.get()).rate(); - return 0; + r += Ethash::workingProgress(m_sealEngine.get()).rate(); + return r; } std::list Client::miningHistory() diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 60ac3f32d..f11d533a6 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -21,7 +21,7 @@ */ #include "ClientBase.h" - +#include #include #include "BlockChain.h" #include "Executive.h" @@ -492,11 +492,10 @@ int ClientBase::compareBlockHashes(h256 _h1, h256 _h2) const BlockNumber n1 = numberFromHash(_h1); BlockNumber n2 = numberFromHash(_h2); - if (n1 > n2) { + if (n1 > n2) return 1; - } else if (n1 == n2) { + else if (n1 == n2) return 0; - } return -1; } @@ -524,3 +523,19 @@ bool ClientBase::isKnownTransaction(h256 const& _blockHash, unsigned _i) const { return isKnown(_blockHash) && bc().transactions().size() > _i; } + +void ClientBase::submitExternalHashrate(int _rate, h256 const& _id) +{ + m_externalRates[_id] = make_pair(_rate, chrono::steady_clock::now()); +} + +uint64_t ClientBase::externalHashrate() const +{ + uint64_t ret = 0; + for (auto i = m_externalRates.begin(); i != m_externalRates.end();) + if (chrono::steady_clock::now() - i->second.second > chrono::seconds(5)) + i = m_externalRates.erase(i); + else + ret += i++->second.first; + return ret; +} diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 8cbc31be2..e5e93e5d1 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -167,6 +167,8 @@ public: virtual uint64_t hashrate() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::hashrate")); } virtual WorkingProgress miningProgress() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::miningProgress")); } + virtual void submitExternalHashrate(int _rate, h256 const& _id) override; + Block asOf(BlockNumber _h) const; protected: @@ -180,6 +182,8 @@ protected: virtual void prepareForTransaction() = 0; /// } + uint64_t externalHashrate() const; + TransactionQueue m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. // filters @@ -188,6 +192,9 @@ protected: std::unordered_map m_specialFilters = std::unordered_map>{{PendingChangedFilter, {}}, {ChainChangedFilter, {}}}; ///< The dictionary of special filters and their additional data std::map m_watches; ///< Each and every watch - these reference a filter. + + // external hashrate + mutable std::unordered_map> m_externalRates; }; }} diff --git a/libethereum/Interface.h b/libethereum/Interface.h index ef35d808c..9c109000f 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -217,7 +217,8 @@ public: virtual std::tuple getEthashWork() { BOOST_THROW_EXCEPTION(InterfaceNotSupported("Interface::getEthashWork")); } /// Submit the nonce for the proof-of-work. virtual bool submitEthashWork(h256 const&, h64 const&) { BOOST_THROW_EXCEPTION(InterfaceNotSupported("Interface::submitEthashWork")); } - + /// Submit the ongoing hashrate of a particular external miner. + virtual void submitExternalHashrate(int, h256 const&) { BOOST_THROW_EXCEPTION(InterfaceNotSupported("Interface::submitExternalHashrate")); } /// Check the progress of the mining. virtual WorkingProgress miningProgress() const = 0; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index e5d442acb..03b2be8d8 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -780,6 +780,12 @@ bool WebThreeStubServerBase::eth_submitWork(string const& _nonce, string const&, } } +bool WebThreeStubServerBase::eth_submitHashrate(int _hashes, string const& _id) +{ + client()->submitExternalHashrate(_hashes, jsToFixed<32>(_id)); + return true; +} + string WebThreeStubServerBase::eth_register(string const& _address) { try diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 8160c6cac..f4ca99d83 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -139,6 +139,7 @@ public: virtual Json::Value eth_getLogsEx(Json::Value const& _json); virtual Json::Value eth_getWork(); virtual bool eth_submitWork(std::string const& _nonce, std::string const&, std::string const& _mixHash); + virtual bool eth_submitHashrate(int _hashes, std::string const& _id); virtual std::string eth_register(std::string const& _address); virtual bool eth_unregister(std::string const& _accountId); virtual Json::Value eth_fetchQueuedTransactions(std::string const& _accountId); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 6ae546931..0009fdcc2 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -60,6 +60,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_getLogsEx", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_getLogsExI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_getWorkI); this->bindAndAddMethod(jsonrpc::Procedure("eth_submitWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_submitWorkI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_submitHashrate", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_submitHashrateI); this->bindAndAddMethod(jsonrpc::Procedure("eth_register", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_registerI); this->bindAndAddMethod(jsonrpc::Procedure("eth_unregister", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_unregisterI); this->bindAndAddMethod(jsonrpc::Procedure("eth_fetchQueuedTransactions", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_fetchQueuedTransactionsI); @@ -312,6 +313,10 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_submitWork(request[0u].asString(), request[1u].asString(), request[2u].asString()); } + inline virtual void eth_submitHashrateI(const Json::Value &request, Json::Value &response) + { + response = this->eth_submitHashrate(request[0u].asInt(), request[1u].asString()); + } inline virtual void eth_registerI(const Json::Value &request, Json::Value &response) { response = this->eth_register(request[0u].asString()); @@ -529,6 +534,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("eth_submitHashrate",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } std::string eth_register(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p;