Browse Source

stratum failover

cl-refactor
Genoil 9 years ago
parent
commit
bd0494c9c4
  1. 79
      ethminer/MinerAux.h
  2. 74
      libstratum/EthStratumClient.cpp
  3. 32
      libstratum/EthStratumClient.h

79
ethminer/MinerAux.h

@ -120,10 +120,23 @@ public:
m_farmURL = argv[++i]; m_farmURL = argv[++i];
m_activeFarmURL = m_farmURL; m_activeFarmURL = m_farmURL;
} }
else if ((arg == "-FF" || arg == "--farm-failover") && i + 1 < argc) else if ((arg == "-FF" || arg == "-FS" || arg == "--farm-failover" || arg == "--stratum-failover") && i + 1 < argc)
{ {
mode = OperationMode::Farm; string url = argv[++i];
m_farmFailOverURL = argv[++i]; if (mode == OperationMode::Stratum)
{
size_t p = url.find_last_of(":");
if (p > 0)
{
m_farmFailOverURL = url.substr(0, p);
if (p + 1 <= url.length())
m_fport = url.substr(p + 1);
}
else
{
m_farmFailOverURL = url;
}
}
} }
else if (arg == "--farm-recheck" && i + 1 < argc) else if (arg == "--farm-recheck" && i + 1 < argc)
try { try {
@ -168,6 +181,14 @@ public:
if (p + 1 <= userpass.length()) if (p + 1 <= userpass.length())
m_pass = userpass.substr(p+1); m_pass = userpass.substr(p+1);
} }
else if ((arg == "-FO" || arg == "--failover-userpass") && i + 1 < argc)
{
string userpass = string(argv[++i]);
size_t p = userpass.find_first_of(":");
m_fuser = userpass.substr(0, p);
if (p + 1 <= userpass.length())
m_fpass = userpass.substr(p + 1);
}
else if ((arg == "-u" || arg == "--user") && i + 1 < argc) else if ((arg == "-u" || arg == "--user") && i + 1 < argc)
{ {
m_user = string(argv[++i]); m_user = string(argv[++i]);
@ -180,6 +201,18 @@ public:
{ {
m_port = string(argv[++i]); m_port = string(argv[++i]);
} }
else if ((arg == "-fu" || arg == "--failover-user") && i + 1 < argc)
{
m_fuser = string(argv[++i]);
}
else if ((arg == "-fp" || arg == "--failover-pass") && i + 1 < argc)
{
m_fpass = string(argv[++i]);
}
else if ((arg == "-fo" || arg == "--failover-port") && i + 1 < argc)
{
m_fport = string(argv[++i]);
}
#endif #endif
else if (arg == "--opencl-platform" && i + 1 < argc) else if (arg == "--opencl-platform" && i + 1 < argc)
try { try {
@ -540,7 +573,7 @@ public:
doSimulation(m_minerType); doSimulation(m_minerType);
#if ETH_STRATUM || !ETH_TRUE #if ETH_STRATUM || !ETH_TRUE
else if (mode == OperationMode::Stratum) else if (mode == OperationMode::Stratum)
doStratum(m_minerType, m_farmRecheckPeriod, m_farmURL, m_port, m_user, m_pass); doStratum();
#endif #endif
} }
@ -922,9 +955,13 @@ private:
if (m_farmFailOverURL != "") if (m_farmFailOverURL != "")
{ {
m_farmRetries++; m_farmRetries++;
if (m_farmRetries >= m_maxFarmRetries) if (m_farmRetries > m_maxFarmRetries)
{ {
if (_remote == m_farmURL) { if (_remote == "exit")
{
m_running = false;
}
else if (_remote == m_farmURL) {
_remote = m_farmFailOverURL; _remote = m_farmFailOverURL;
prpc = &rpcFailover; prpc = &rpcFailover;
} }
@ -934,10 +971,7 @@ private:
} }
m_farmRetries = 0; m_farmRetries = 0;
} }
if (_remote == "exit")
{
m_running = false;
}
} }
} }
#endif #endif
@ -945,7 +979,7 @@ private:
} }
#if ETH_STRATUM || !ETH_TRUE #if ETH_STRATUM || !ETH_TRUE
void doStratum(MinerType _m, unsigned _recheckPeriod, string const & host, string const & port, string const & user, string const & pass) void doStratum()
{ {
map<string, GenericFarm<EthashProofOfWork>::SealerDescriptor> sealers; map<string, GenericFarm<EthashProofOfWork>::SealerDescriptor> sealers;
sealers["cpu"] = GenericFarm<EthashProofOfWork>::SealerDescriptor{ &EthashCPUMiner::instances, [](GenericMiner<EthashProofOfWork>::ConstructionInfo ci){ return new EthashCPUMiner(ci); } }; sealers["cpu"] = GenericFarm<EthashProofOfWork>::SealerDescriptor{ &EthashCPUMiner::instances, [](GenericMiner<EthashProofOfWork>::ConstructionInfo ci){ return new EthashCPUMiner(ci); } };
@ -956,8 +990,18 @@ private:
sealers["cuda"] = GenericFarm<EthashProofOfWork>::SealerDescriptor{ &EthashCUDAMiner::instances, [](GenericMiner<EthashProofOfWork>::ConstructionInfo ci){ return new EthashCUDAMiner(ci); } }; sealers["cuda"] = GenericFarm<EthashProofOfWork>::SealerDescriptor{ &EthashCUDAMiner::instances, [](GenericMiner<EthashProofOfWork>::ConstructionInfo ci){ return new EthashCUDAMiner(ci); } };
#endif #endif
GenericFarm<EthashProofOfWork> f; GenericFarm<EthashProofOfWork> f;
EthStratumClient client(&f, _m, host, port, user, pass); EthStratumClient client(&f, m_minerType, m_farmURL, m_port, m_user, m_pass, m_maxFarmRetries);
if (m_farmFailOverURL != "")
{
if (m_fuser != "")
{
client.setFailover(m_farmFailOverURL, m_fport, m_fuser, m_fpass);
}
else
{
client.setFailover(m_farmFailOverURL, m_fport);
}
}
f.setSealers(sealers); f.setSealers(sealers);
f.onSolutionFound([&](EthashProofOfWork::Solution sol) f.onSolutionFound([&](EthashProofOfWork::Solution sol)
@ -966,7 +1010,7 @@ private:
return false; return false;
}); });
while (true) while (client.isRunning())
{ {
auto mp = f.miningProgress(); auto mp = f.miningProgress();
f.resetMiningProgress(); f.resetMiningProgress();
@ -977,7 +1021,7 @@ private:
else else
minelog << "Waiting for work package..."; minelog << "Waiting for work package...";
} }
this_thread::sleep_for(chrono::milliseconds(_recheckPeriod)); this_thread::sleep_for(chrono::milliseconds(m_farmRecheckPeriod));
} }
} }
#endif #endif
@ -1027,6 +1071,8 @@ private:
/// Farm params /// Farm params
string m_farmURL = "http://127.0.0.1:8545"; string m_farmURL = "http://127.0.0.1:8545";
string m_farmFailOverURL = ""; string m_farmFailOverURL = "";
string m_activeFarmURL = m_farmURL; string m_activeFarmURL = m_farmURL;
unsigned m_farmRetries = 0; unsigned m_farmRetries = 0;
unsigned m_maxFarmRetries = 3; unsigned m_maxFarmRetries = 3;
@ -1037,6 +1083,9 @@ private:
string m_user; string m_user;
string m_pass; string m_pass;
string m_port; string m_port;
string m_fuser = "";
string m_fpass = "";
string m_fport = "";
#endif #endif
}; };

74
libstratum/EthStratumClient.cpp

@ -4,18 +4,23 @@
using boost::asio::ip::tcp; using boost::asio::ip::tcp;
EthStratumClient::EthStratumClient(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass) EthStratumClient::EthStratumClient(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries)
: m_socket(m_io_service) : m_socket(m_io_service)
{ {
m_minerType = m; m_minerType = m;
m_host = host; m_primary.host = host;
m_port = port; m_primary.port = port;
m_user = user; m_primary.user = user;
m_pass = pass; m_primary.pass = pass;
p_active = &m_primary;
m_authorized = false; m_authorized = false;
m_connected = false; m_connected = false;
m_precompute = true; m_precompute = true;
m_pending = 0; m_pending = 0;
m_maxRetries = retries;
p_farm = f; p_farm = f;
connect(); connect();
} }
@ -25,22 +30,37 @@ EthStratumClient::~EthStratumClient()
} }
void EthStratumClient::setFailover(string const & host, string const & port)
{
setFailover(host, port, p_active->user, p_active->pass);
}
void EthStratumClient::setFailover(string const & host, string const & port, string const & user, string const & pass)
{
m_failover.host = host;
m_failover.port = port;
m_failover.user = user;
m_failover.pass = pass;
}
void EthStratumClient::connect() void EthStratumClient::connect()
{ {
tcp::resolver r(m_io_service); tcp::resolver r(m_io_service);
tcp::resolver::query q(m_host, m_port); tcp::resolver::query q(p_active->host, p_active->port);
r.async_resolve(q, boost::bind(&EthStratumClient::resolve_handler, r.async_resolve(q, boost::bind(&EthStratumClient::resolve_handler,
this, boost::asio::placeholders::error, this, boost::asio::placeholders::error,
boost::asio::placeholders::iterator)); boost::asio::placeholders::iterator));
cnote << "Connecting to stratum server " << m_host +":"+m_port; cnote << "Connecting to stratum server " << p_active->host + ":" + p_active->port;
boost::thread t(boost::bind(&boost::asio::io_service::run, &m_io_service)); boost::thread t(boost::bind(&boost::asio::io_service::run, &m_io_service));
} }
#define BOOST_ASIO_ENABLE_CANCELIO
void EthStratumClient::reconnect() void EthStratumClient::reconnect()
{ {
/* /*
@ -50,13 +70,36 @@ void EthStratumClient::reconnect()
p_farm->stop(); p_farm->stop();
} }
*/ */
m_socket.close();
m_io_service.reset(); m_io_service.reset();
m_socket.close();
m_authorized = false; m_authorized = false;
m_connected = false; m_connected = false;
if (!m_failover.host.empty())
{
m_retries++;
if (m_retries > m_maxRetries)
{
if (m_failover.host == "exit") {
disconnect();
return;
}
else if (p_active == &m_primary)
{
p_active = &m_failover;
}
else {
p_active = &m_primary;
}
m_retries = 0;
}
}
cnote << "Reconnecting in 3 seconds..."; cnote << "Reconnecting in 3 seconds...";
boost::asio::deadline_timer timer(m_io_service, boost::posix_time::seconds(3)); boost::asio::deadline_timer timer(m_io_service, boost::posix_time::seconds(3));
timer.wait(); timer.wait();
connect(); connect();
} }
@ -64,6 +107,7 @@ void EthStratumClient::disconnect()
{ {
cnote << "Disconnecting"; cnote << "Disconnecting";
m_connected = false; m_connected = false;
m_running = false;
if (p_farm->isMining()) if (p_farm->isMining())
{ {
cnote << "Stopping farm"; cnote << "Stopping farm";
@ -83,7 +127,7 @@ void EthStratumClient::resolve_handler(const boost::system::error_code& ec, tcp:
} }
else else
{ {
cerr << "Could not resolve host" << m_host + ":" + m_port + ", " << ec.message(); cerr << "Could not resolve host" << p_active->host + ":" + p_active->port + ", " << ec.message();
reconnect(); reconnect();
} }
} }
@ -93,7 +137,7 @@ void EthStratumClient::connect_handler(const boost::system::error_code& ec, tcp:
if (!ec) if (!ec)
{ {
m_connected = true; m_connected = true;
cnote << "Connected to stratum server " << m_host << ":" << m_port; cnote << "Connected to stratum server " << p_active->host << ":" << p_active->port;
if (!p_farm->isMining()) if (!p_farm->isMining())
{ {
cnote << "Starting farm"; cnote << "Starting farm";
@ -114,7 +158,7 @@ void EthStratumClient::connect_handler(const boost::system::error_code& ec, tcp:
} }
else else
{ {
cwarn << "Could not connect to stratum server " << m_host << ":" << m_port << ", " << ec.message(); cwarn << "Could not connect to stratum server " << p_active->host << ":" << p_active->port << ", " << ec.message();
reconnect(); reconnect();
} }
@ -199,7 +243,7 @@ void EthStratumClient::processReponse(Json::Value& responseObject)
case 1: case 1:
cnote << "Subscribed to stratum server"; cnote << "Subscribed to stratum server";
os << "{\"id\": 2, \"method\": \"mining.authorize\", \"params\": [\"" << m_user << "\",\"" << m_pass << "\"]}\n"; os << "{\"id\": 2, \"method\": \"mining.authorize\", \"params\": [\"" << p_active->user << "\",\"" << p_active->pass << "\"]}\n";
async_write(m_socket, m_requestBuffer, async_write(m_socket, m_requestBuffer,
boost::bind(&EthStratumClient::handleResponse, this, boost::bind(&EthStratumClient::handleResponse, this,
@ -212,7 +256,7 @@ void EthStratumClient::processReponse(Json::Value& responseObject)
disconnect(); disconnect();
return; return;
} }
cnote << "Authorized worker " << m_user; cnote << "Authorized worker " << p_active->user;
break; break;
case 4: case 4:
if (responseObject.get("result", false).asBool()) if (responseObject.get("result", false).asBool())
@ -284,7 +328,7 @@ void EthStratumClient::processReponse(Json::Value& responseObject)
bool EthStratumClient::submit(EthashProofOfWork::Solution solution) { bool EthStratumClient::submit(EthashProofOfWork::Solution solution) {
cnote << "Solution found; Submitting to" << m_host << "..."; cnote << "Solution found; Submitting to" << p_active->host << "...";
cnote << " Nonce:" << "0x"+solution.nonce.hex(); cnote << " Nonce:" << "0x"+solution.nonce.hex();
cnote << " Mixhash:" << "0x" + solution.mixHash.hex(); cnote << " Mixhash:" << "0x" + solution.mixHash.hex();
cnote << " Header-hash:" << "0x" + m_current.headerHash.hex(); cnote << " Header-hash:" << "0x" + m_current.headerHash.hex();
@ -293,7 +337,7 @@ bool EthStratumClient::submit(EthashProofOfWork::Solution solution) {
cnote << " Ethash: " << "0x" + h256(EthashAux::eval(m_current.seedHash, m_current.headerHash, solution.nonce).value).hex(); cnote << " Ethash: " << "0x" + h256(EthashAux::eval(m_current.seedHash, m_current.headerHash, solution.nonce).value).hex();
if (EthashAux::eval(m_current.seedHash, m_current.headerHash, solution.nonce).value < m_current.boundary) if (EthashAux::eval(m_current.seedHash, m_current.headerHash, solution.nonce).value < m_current.boundary)
{ {
string json = "{\"id\": 4, \"method\": \"mining.submit\", \"params\": [\"" + m_user + "\",\"" + m_job + "\",\"0x" + solution.nonce.hex() + "\",\"0x" + m_current.headerHash.hex() + "\",\"0x" + solution.mixHash.hex() + "\"]}\n"; string json = "{\"id\": 4, \"method\": \"mining.submit\", \"params\": [\"" + p_active->user + "\",\"" + m_job + "\",\"0x" + solution.nonce.hex() + "\",\"0x" + m_current.headerHash.hex() + "\",\"0x" + solution.mixHash.hex() + "\"]}\n";
std::ostream os(&m_requestBuffer); std::ostream os(&m_requestBuffer);
os << json; os << json;

32
libstratum/EthStratumClient.h

@ -17,12 +17,23 @@ using boost::asio::ip::tcp;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
typedef struct {
string host;
string port;
string user;
string pass;
} cred_t;
class EthStratumClient class EthStratumClient
{ {
public: public:
EthStratumClient(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass); EthStratumClient(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries);
~EthStratumClient(); ~EthStratumClient();
void setFailover(string const & host, string const & port);
void setFailover(string const & host, string const & port, string const & user, string const & pass);
bool isRunning() { return m_running; }
bool isConnected() { return m_connected; } bool isConnected() { return m_connected; }
h256 currentHeaderHash() { return m_current.headerHash; } h256 currentHeaderHash() { return m_current.headerHash; }
bool current() { return m_current; } bool current() { return m_current; }
@ -40,13 +51,18 @@ private:
void processReponse(Json::Value& responseObject); void processReponse(Json::Value& responseObject);
MinerType m_minerType; MinerType m_minerType;
string m_host;
string m_port; cred_t * p_active;
string m_user; cred_t m_primary;
string m_pass; cred_t m_failover;
bool m_authorized;
bool m_connected; bool m_authorized;
bool m_precompute; bool m_connected;
bool m_precompute;
bool m_running = true;
int m_retries = 0;
int m_maxRetries;
boost::mutex m_mtx; boost::mutex m_mtx;
int m_pending; int m_pending;

Loading…
Cancel
Save