StratumServer: fixed data races on disconnect

pull/277/head
SChernykh 2023-09-08 15:19:59 +02:00
parent 2503dca0e3
commit 390cf0257e
3 changed files with 27 additions and 12 deletions

View File

@ -238,6 +238,11 @@ static bool get_custom_diff(const char* s, difficulty_type& diff)
bool StratumServer::on_login(StratumClient* client, uint32_t id, const char* login) bool StratumServer::on_login(StratumClient* client, uint32_t id, const char* login)
{ {
if (client->m_rpcId) {
LOGWARN(4, "client " << static_cast<char*>(client->m_addrString) << " tried to login, but it's already logged in");
return false;
}
const uint32_t extra_nonce = m_extraNonce.fetch_add(1); const uint32_t extra_nonce = m_extraNonce.fetch_add(1);
uint8_t hashing_blob[128]; uint8_t hashing_blob[128];
@ -404,6 +409,8 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo
share->m_client = client; share->m_client = client;
share->m_clientIPv6 = client->m_isV6; share->m_clientIPv6 = client->m_isV6;
share->m_clientAddr = client->m_addr; share->m_clientAddr = client->m_addr;
memcpy(share->m_clientAddrString, client->m_addrString, sizeof(share->m_clientAddrString));
memcpy(share->m_clientCustomUser, client->m_customUser, sizeof(share->m_clientCustomUser));
share->m_clientResetCounter = client->m_resetCounter.load(); share->m_clientResetCounter = client->m_resetCounter.load();
share->m_rpcId = client->m_rpcId; share->m_rpcId = client->m_rpcId;
share->m_id = id; share->m_id = id;
@ -853,7 +860,6 @@ void StratumServer::on_share_found(uv_work_t* req)
BACKGROUND_JOB_START(StratumServer::on_share_found); BACKGROUND_JOB_START(StratumServer::on_share_found);
} }
StratumClient* client = share->m_client;
p2pool* pool = server->m_pool; p2pool* pool = server->m_pool;
const uint64_t target = share->m_target; const uint64_t target = share->m_target;
@ -873,7 +879,7 @@ void StratumServer::on_share_found(uv_work_t* req)
const uint32_t blob_size = pool->block_template().get_hashing_blob(share->m_templateId, share->m_extraNonce, blob, height, difficulty, sidechain_difficulty, seed_hash, nonce_offset); const uint32_t blob_size = pool->block_template().get_hashing_blob(share->m_templateId, share->m_extraNonce, blob, height, difficulty, sidechain_difficulty, seed_hash, nonce_offset);
if (!blob_size) { if (!blob_size) {
LOGWARN(4, "client " << static_cast<char*>(client->m_addrString) << " got a stale share"); LOGWARN(4, "client " << static_cast<char*>(share->m_clientAddrString) << " got a stale share");
share->m_result = SubmittedShare::Result::STALE; share->m_result = SubmittedShare::Result::STALE;
return; return;
} }
@ -885,13 +891,13 @@ void StratumServer::on_share_found(uv_work_t* req)
hash pow_hash; hash pow_hash;
if (!pool->calculate_hash(blob, blob_size, height, seed_hash, pow_hash, false)) { if (!pool->calculate_hash(blob, blob_size, height, seed_hash, pow_hash, false)) {
LOGWARN(3, "client " << static_cast<char*>(client->m_addrString) << " couldn't check share PoW"); LOGWARN(3, "client " << static_cast<char*>(share->m_clientAddrString) << " couldn't check share PoW");
share->m_result = SubmittedShare::Result::COULDNT_CHECK_POW; share->m_result = SubmittedShare::Result::COULDNT_CHECK_POW;
return; return;
} }
if (pow_hash != share->m_resultHash) { if (pow_hash != share->m_resultHash) {
LOGWARN(4, "client " << static_cast<char*>(client->m_addrString) << " submitted a share with invalid PoW"); LOGWARN(4, "client " << static_cast<char*>(share->m_clientAddrString) << " submitted a share with invalid PoW");
share->m_result = SubmittedShare::Result::INVALID_POW; share->m_result = SubmittedShare::Result::INVALID_POW;
share->m_score = BAD_SHARE_POINTS; share->m_score = BAD_SHARE_POINTS;
@ -938,7 +944,7 @@ void StratumServer::on_share_found(uv_work_t* req)
share->m_result = SubmittedShare::Result::OK; share->m_result = SubmittedShare::Result::OK;
} }
else { else {
LOGWARN(4, "client " << static_cast<char*>(client->m_addrString) << " got a low diff share"); LOGWARN(4, "client " << static_cast<char*>(share->m_clientAddrString) << " got a low diff share");
share->m_result = SubmittedShare::Result::LOW_DIFF; share->m_result = SubmittedShare::Result::LOW_DIFF;
share->m_score = BAD_SHARE_POINTS; share->m_score = BAD_SHARE_POINTS;
} }
@ -947,13 +953,11 @@ void StratumServer::on_share_found(uv_work_t* req)
void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/) void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
{ {
SubmittedShare* share = reinterpret_cast<SubmittedShare*>(req->data); SubmittedShare* share = reinterpret_cast<SubmittedShare*>(req->data);
StratumClient* client = share->m_client;
client->m_score += share->m_score;
if (share->m_highEnoughDifficulty) { if (share->m_highEnoughDifficulty) {
const char* s = client->m_customUser; const char* s = share->m_clientCustomUser;
if (share->m_result == SubmittedShare::Result::OK) { if (share->m_result == SubmittedShare::Result::OK) {
LOGINFO(0, log::Green() << "SHARE FOUND: mainchain height " << share->m_mainchainHeight << ", sidechain height " << share->m_sidechainHeight << ", diff " << share->m_sidechainDifficulty << ", client " << static_cast<char*>(client->m_addrString) << (*s ? ", user " : "") << s << ", effort " << share->m_effort << '%'); LOGINFO(0, log::Green() << "SHARE FOUND: mainchain height " << share->m_mainchainHeight << ", sidechain height " << share->m_sidechainHeight << ", diff " << share->m_sidechainDifficulty << ", client " << static_cast<char*>(share->m_clientAddrString) << (*s ? ", user " : "") << s << ", effort " << share->m_effort << '%');
} }
else { else {
static const char* reason_list[] = { static const char* reason_list[] = {
@ -967,7 +971,7 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
const size_t k = static_cast<size_t>(share->m_result); const size_t k = static_cast<size_t>(share->m_result);
const char* reason = (k < array_size(reason_list)) ? reason_list[k] : "unknown"; const char* reason = (k < array_size(reason_list)) ? reason_list[k] : "unknown";
LOGWARN(0, "INVALID SHARE: mainchain height " << share->m_mainchainHeight << ", sidechain height " << share->m_sidechainHeight << ", diff " << share->m_sidechainDifficulty << ", client " << static_cast<char*>(client->m_addrString) << (*s ? ", user " : "") << s << ", reason: " << reason); LOGWARN(0, "INVALID SHARE: mainchain height " << share->m_mainchainHeight << ", sidechain height " << share->m_sidechainHeight << ", diff " << share->m_sidechainDifficulty << ", client " << static_cast<char*>(share->m_clientAddrString) << (*s ? ", user " : "") << s << ", reason: " << reason);
} }
BACKGROUND_JOB_STOP(StratumServer::on_share_found); BACKGROUND_JOB_STOP(StratumServer::on_share_found);
} }
@ -982,6 +986,8 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
const bool bad_share = (share->m_result == SubmittedShare::Result::LOW_DIFF) || (share->m_result == SubmittedShare::Result::INVALID_POW); const bool bad_share = (share->m_result == SubmittedShare::Result::LOW_DIFF) || (share->m_result == SubmittedShare::Result::INVALID_POW);
StratumClient* client = share->m_client;
if ((client->m_resetCounter.load() == share->m_clientResetCounter) && (client->m_rpcId == share->m_rpcId)) { if ((client->m_resetCounter.load() == share->m_clientResetCounter) && (client->m_rpcId == share->m_rpcId)) {
const bool result = server->send(client, const bool result = server->send(client,
[share](uint8_t* buf, size_t buf_size) [share](uint8_t* buf, size_t buf_size)
@ -1010,6 +1016,8 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
return s.m_pos; return s.m_pos;
}); });
client->m_score += share->m_score;
if (bad_share && (client->m_score <= BAN_THRESHOLD_POINTS)) { if (bad_share && (client->m_score <= BAN_THRESHOLD_POINTS)) {
client->ban(DEFAULT_BAN_TIME); client->ban(DEFAULT_BAN_TIME);
client->close(); client->close();

View File

@ -61,6 +61,7 @@ public:
enum { enum {
JOBS_SIZE = 4, JOBS_SIZE = 4,
AUTO_DIFF_SIZE = 64, AUTO_DIFF_SIZE = 64,
CUSTOM_USER_SIZE = 32,
}; };
struct SavedJob { struct SavedJob {
@ -80,7 +81,7 @@ public:
difficulty_type m_customDiff; difficulty_type m_customDiff;
difficulty_type m_autoDiff; difficulty_type m_autoDiff;
char m_customUser[32]; char m_customUser[CUSTOM_USER_SIZE];
uint64_t m_lastJobTarget; uint64_t m_lastJobTarget;
@ -145,6 +146,8 @@ private:
StratumClient* m_client; StratumClient* m_client;
bool m_clientIPv6; bool m_clientIPv6;
raw_ip m_clientAddr; raw_ip m_clientAddr;
char m_clientAddrString[Client::ADDR_STRING_SIZE];
char m_clientCustomUser[StratumClient::CUSTOM_USER_SIZE];
uint32_t m_clientResetCounter; uint32_t m_clientResetCounter;
uint32_t m_rpcId; uint32_t m_rpcId;
uint32_t m_id; uint32_t m_id;

View File

@ -89,9 +89,13 @@ public:
bool m_isClosing; bool m_isClosing;
uint32_t m_numRead; uint32_t m_numRead;
enum {
ADDR_STRING_SIZE = 72,
};
raw_ip m_addr; raw_ip m_addr;
int m_port; int m_port;
char m_addrString[72]; char m_addrString[ADDR_STRING_SIZE];
enum class Socks5ProxyState { enum class Socks5ProxyState {
Default, Default,