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_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;
m_farmFailOverURL = argv[++i];
string url = 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)
try {
@ -168,6 +181,14 @@ public:
if (p + 1 <= userpass.length())
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)
{
m_user = string(argv[++i]);
@ -180,6 +201,18 @@ public:
{
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
else if (arg == "--opencl-platform" && i + 1 < argc)
try {
@ -540,7 +573,7 @@ public:
doSimulation(m_minerType);
#if ETH_STRATUM || !ETH_TRUE
else if (mode == OperationMode::Stratum)
doStratum(m_minerType, m_farmRecheckPeriod, m_farmURL, m_port, m_user, m_pass);
doStratum();
#endif
}
@ -922,9 +955,13 @@ private:
if (m_farmFailOverURL != "")
{
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;
prpc = &rpcFailover;
}
@ -934,10 +971,7 @@ private:
}
m_farmRetries = 0;
}
if (_remote == "exit")
{
m_running = false;
}
}
}
#endif
@ -945,7 +979,7 @@ private:
}
#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;
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); } };
#endif
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.onSolutionFound([&](EthashProofOfWork::Solution sol)
@ -966,7 +1010,7 @@ private:
return false;
});
while (true)
while (client.isRunning())
{
auto mp = f.miningProgress();
f.resetMiningProgress();
@ -977,7 +1021,7 @@ private:
else
minelog << "Waiting for work package...";
}
this_thread::sleep_for(chrono::milliseconds(_recheckPeriod));
this_thread::sleep_for(chrono::milliseconds(m_farmRecheckPeriod));
}
}
#endif
@ -1027,6 +1071,8 @@ private:
/// Farm params
string m_farmURL = "http://127.0.0.1:8545";
string m_farmFailOverURL = "";
string m_activeFarmURL = m_farmURL;
unsigned m_farmRetries = 0;
unsigned m_maxFarmRetries = 3;
@ -1037,6 +1083,9 @@ private:
string m_user;
string m_pass;
string m_port;
string m_fuser = "";
string m_fpass = "";
string m_fport = "";
#endif
};

74
libstratum/EthStratumClient.cpp

@ -4,18 +4,23 @@
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_minerType = m;
m_host = host;
m_port = port;
m_user = user;
m_pass = pass;
m_primary.host = host;
m_primary.port = port;
m_primary.user = user;
m_primary.pass = pass;
p_active = &m_primary;
m_authorized = false;
m_connected = false;
m_precompute = true;
m_pending = 0;
m_maxRetries = retries;
p_farm = f;
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()
{
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,
this, boost::asio::placeholders::error,
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));
}
#define BOOST_ASIO_ENABLE_CANCELIO
void EthStratumClient::reconnect()
{
/*
@ -50,13 +70,36 @@ void EthStratumClient::reconnect()
p_farm->stop();
}
*/
m_socket.close();
m_io_service.reset();
m_socket.close();
m_authorized = 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...";
boost::asio::deadline_timer timer(m_io_service, boost::posix_time::seconds(3));
timer.wait();
connect();
}
@ -64,6 +107,7 @@ void EthStratumClient::disconnect()
{
cnote << "Disconnecting";
m_connected = false;
m_running = false;
if (p_farm->isMining())
{
cnote << "Stopping farm";
@ -83,7 +127,7 @@ void EthStratumClient::resolve_handler(const boost::system::error_code& ec, tcp:
}
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();
}
}
@ -93,7 +137,7 @@ void EthStratumClient::connect_handler(const boost::system::error_code& ec, tcp:
if (!ec)
{
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())
{
cnote << "Starting farm";
@ -114,7 +158,7 @@ void EthStratumClient::connect_handler(const boost::system::error_code& ec, tcp:
}
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();
}
@ -199,7 +243,7 @@ void EthStratumClient::processReponse(Json::Value& responseObject)
case 1:
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,
boost::bind(&EthStratumClient::handleResponse, this,
@ -212,7 +256,7 @@ void EthStratumClient::processReponse(Json::Value& responseObject)
disconnect();
return;
}
cnote << "Authorized worker " << m_user;
cnote << "Authorized worker " << p_active->user;
break;
case 4:
if (responseObject.get("result", false).asBool())
@ -284,7 +328,7 @@ void EthStratumClient::processReponse(Json::Value& responseObject)
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 << " Mixhash:" << "0x" + solution.mixHash.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();
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);
os << json;

32
libstratum/EthStratumClient.h

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

Loading…
Cancel
Save