|
|
@ -103,101 +103,21 @@ void EthStratumClient::readResponse(const boost::system::error_code& ec, std::si |
|
|
|
std::istream is(&m_responseBuffer); |
|
|
|
std::string response; |
|
|
|
getline(is, response); |
|
|
|
//cnote << response;
|
|
|
|
cnote << response; |
|
|
|
|
|
|
|
if (response.back() != '}') { |
|
|
|
m_response = response; |
|
|
|
} |
|
|
|
if (response.front() != '{') { |
|
|
|
response = m_response + response; |
|
|
|
} |
|
|
|
|
|
|
|
Json::Value responseObject; |
|
|
|
Json::Reader reader; |
|
|
|
if (reader.parse(response.c_str(), responseObject)) |
|
|
|
{ |
|
|
|
if (responseObject.isMember("id")) { |
|
|
|
Json::Value error = responseObject.get("error", NULL); |
|
|
|
if (error.isArray()) |
|
|
|
{ |
|
|
|
string msg = error.get(1, "Unknown error").asString(); |
|
|
|
cnote << msg; |
|
|
|
} |
|
|
|
std::ostream os(&m_requestBuffer); |
|
|
|
Json::Value params; |
|
|
|
int id = responseObject.get("id", NULL).asInt(); |
|
|
|
switch (id) |
|
|
|
{ |
|
|
|
case 1: |
|
|
|
cnote << "Subscribed to stratum server"; |
|
|
|
|
|
|
|
os << "{\"id\": 2, \"method\": \"mining.authorize\", \"params\": [\"" << m_user << "\",\"" << m_pass << "\"]}\n"; |
|
|
|
|
|
|
|
async_write(m_socket, m_requestBuffer, |
|
|
|
boost::bind(&EthStratumClient::handleResponse, this, |
|
|
|
boost::asio::placeholders::error)); |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
m_authorized = responseObject.get("result", NULL).asBool(); |
|
|
|
if (!m_authorized) |
|
|
|
{ |
|
|
|
disconnect(); |
|
|
|
return; |
|
|
|
} |
|
|
|
cnote << "Authorized worker " << m_user; |
|
|
|
break; |
|
|
|
case 4: |
|
|
|
cnote << response; |
|
|
|
default: |
|
|
|
string method = responseObject.get("method", "").asString(); |
|
|
|
if (method == "mining.notify") |
|
|
|
{ |
|
|
|
params = responseObject.get("params", NULL); |
|
|
|
if (params.isArray()) |
|
|
|
{ |
|
|
|
m_job = params.get((Json::Value::ArrayIndex)0, "").asString(); |
|
|
|
string sHeaderHash = params.get((Json::Value::ArrayIndex)1, "").asString(); |
|
|
|
string sSeedHash = params.get((Json::Value::ArrayIndex)2, "").asString(); |
|
|
|
string sShareTarget = params.get((Json::Value::ArrayIndex)3, "").asString(); |
|
|
|
bool cleanJobs = params.get((Json::Value::ArrayIndex)4, "").asBool(); |
|
|
|
if (sHeaderHash != "" && sSeedHash != "" && sShareTarget != "") |
|
|
|
{ |
|
|
|
cnote << "Received new job #" + m_job; |
|
|
|
cnote << "Header hash: 0x" + sHeaderHash; |
|
|
|
cnote << "Seed hash: 0x" + sSeedHash; |
|
|
|
cnote << "Share target: 0x" + sShareTarget; |
|
|
|
|
|
|
|
h256 seedHash = h256(sSeedHash); |
|
|
|
h256 headerHash = h256(sHeaderHash); |
|
|
|
EthashAux::FullType dag; |
|
|
|
|
|
|
|
|
|
|
|
if (seedHash != m_current.seedHash) |
|
|
|
cnote << "Grabbing DAG for" << seedHash; |
|
|
|
if (!(dag = EthashAux::full(seedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; }))) |
|
|
|
BOOST_THROW_EXCEPTION(DAGCreationFailure()); |
|
|
|
if (m_precompute) |
|
|
|
EthashAux::computeFull(sha3(seedHash), true); |
|
|
|
if (headerHash != m_current.headerHash) |
|
|
|
{ |
|
|
|
m_current.headerHash = h256(sHeaderHash); |
|
|
|
m_current.seedHash = seedHash; |
|
|
|
m_current.boundary = h256(sShareTarget, h256::AlignRight); |
|
|
|
p_farm->setWork(m_current); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else if (method == "mining.set_difficulty") |
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
else if (method == "client.get_version") |
|
|
|
{ |
|
|
|
os << "{\"error\": null, \"id\" : " << id << ", \"result\" : \"" << ETH_PROJECT_VERSION << "\"}"; |
|
|
|
async_write(m_socket, m_requestBuffer, |
|
|
|
boost::bind(&EthStratumClient::handleResponse, this, |
|
|
|
boost::asio::placeholders::error)); |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
async_read_until(m_socket, m_responseBuffer, "\n", |
|
|
|
boost::bind(&EthStratumClient::readResponse, this, |
|
|
|
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); |
|
|
|
processReponse(responseObject); |
|
|
|
m_response = response; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
@ -208,6 +128,98 @@ void EthStratumClient::readResponse(const boost::system::error_code& ec, std::si |
|
|
|
{ |
|
|
|
cwarn << "Read response failed: " << ec.message(); |
|
|
|
} |
|
|
|
|
|
|
|
async_read_until(m_socket, m_responseBuffer, "\n", |
|
|
|
boost::bind(&EthStratumClient::readResponse, this, |
|
|
|
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); |
|
|
|
} |
|
|
|
|
|
|
|
void EthStratumClient::processReponse(Json::Value& responseObject) |
|
|
|
{ |
|
|
|
Json::Value error = responseObject.get("error", NULL); |
|
|
|
if (error.isArray()) |
|
|
|
{ |
|
|
|
string msg = error.get(1, "Unknown error").asString(); |
|
|
|
cnote << msg; |
|
|
|
} |
|
|
|
std::ostream os(&m_requestBuffer); |
|
|
|
Json::Value params; |
|
|
|
int id = responseObject.get("id", NULL).asInt(); |
|
|
|
switch (id) |
|
|
|
{ |
|
|
|
case 1: |
|
|
|
cnote << "Subscribed to stratum server"; |
|
|
|
|
|
|
|
os << "{\"id\": 2, \"method\": \"mining.authorize\", \"params\": [\"" << m_user << "\",\"" << m_pass << "\"]}\n"; |
|
|
|
|
|
|
|
async_write(m_socket, m_requestBuffer, |
|
|
|
boost::bind(&EthStratumClient::handleResponse, this, |
|
|
|
boost::asio::placeholders::error)); |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
m_authorized = responseObject.get("result", NULL).asBool(); |
|
|
|
if (!m_authorized) |
|
|
|
{ |
|
|
|
disconnect(); |
|
|
|
return; |
|
|
|
} |
|
|
|
cnote << "Authorized worker " << m_user; |
|
|
|
break; |
|
|
|
case 4: |
|
|
|
cnote << m_response; |
|
|
|
default: |
|
|
|
string method = responseObject.get("method", "").asString(); |
|
|
|
if (method == "mining.notify") |
|
|
|
{ |
|
|
|
params = responseObject.get("params", NULL); |
|
|
|
if (params.isArray()) |
|
|
|
{ |
|
|
|
m_job = params.get((Json::Value::ArrayIndex)0, "").asString(); |
|
|
|
string sHeaderHash = params.get((Json::Value::ArrayIndex)1, "").asString(); |
|
|
|
string sSeedHash = params.get((Json::Value::ArrayIndex)2, "").asString(); |
|
|
|
string sShareTarget = params.get((Json::Value::ArrayIndex)3, "").asString(); |
|
|
|
bool cleanJobs = params.get((Json::Value::ArrayIndex)4, "").asBool(); |
|
|
|
if (sHeaderHash != "" && sSeedHash != "" && sShareTarget != "") |
|
|
|
{ |
|
|
|
cnote << "Received new job #" + m_job; |
|
|
|
cnote << "Header hash: 0x" + sHeaderHash; |
|
|
|
cnote << "Seed hash: 0x" + sSeedHash; |
|
|
|
cnote << "Share target: 0x" + sShareTarget; |
|
|
|
|
|
|
|
h256 seedHash = h256(sSeedHash); |
|
|
|
h256 headerHash = h256(sHeaderHash); |
|
|
|
EthashAux::FullType dag; |
|
|
|
|
|
|
|
|
|
|
|
if (seedHash != m_current.seedHash) |
|
|
|
cnote << "Grabbing DAG for" << seedHash; |
|
|
|
if (!(dag = EthashAux::full(seedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; }))) |
|
|
|
BOOST_THROW_EXCEPTION(DAGCreationFailure()); |
|
|
|
if (m_precompute) |
|
|
|
EthashAux::computeFull(sha3(seedHash), true); |
|
|
|
if (headerHash != m_current.headerHash) |
|
|
|
{ |
|
|
|
m_current.headerHash = h256(sHeaderHash); |
|
|
|
m_current.seedHash = seedHash; |
|
|
|
m_current.boundary = h256(sShareTarget, h256::AlignRight); |
|
|
|
p_farm->setWork(m_current); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else if (method == "mining.set_difficulty") |
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
else if (method == "client.get_version") |
|
|
|
{ |
|
|
|
os << "{\"error\": null, \"id\" : " << id << ", \"result\" : \"" << ETH_PROJECT_VERSION << "\"}"; |
|
|
|
async_write(m_socket, m_requestBuffer, |
|
|
|
boost::bind(&EthStratumClient::handleResponse, this, |
|
|
|
boost::asio::placeholders::error)); |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool EthStratumClient::submit(EthashProofOfWork::Solution solution) { |
|
|
|