Skip to content

Commit

Permalink
Stratum: removed submitted shares memory pool
Browse files Browse the repository at this point in the history
It's faster to have stack allocation when possible
  • Loading branch information
SChernykh committed Oct 31, 2024
1 parent 74f056b commit 449e7f8
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 60 deletions.
101 changes: 43 additions & 58 deletions src/stratum_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,6 @@ StratumServer::StratumServer(p2pool* pool)

m_extraNonce = get_random32();

m_submittedSharesPool.resize(10);
for (size_t i = 0; i < m_submittedSharesPool.size(); ++i) {
SubmittedShare* share = new SubmittedShare{};
ASAN_POISON_MEMORY_REGION(share, sizeof(SubmittedShare));
m_submittedSharesPool[i] = share;
}

m_pendingShareChecks.reserve(10);

uv_async_init_checked(&m_loop, &m_blobsAsync, on_blobs_ready);
Expand Down Expand Up @@ -108,11 +101,6 @@ StratumServer::~StratumServer()
uv_mutex_destroy(&m_showWorkersLock);
uv_mutex_destroy(&m_rngLock);
uv_rwlock_destroy(&m_hashrateDataLock);

for (SubmittedShare* share : m_submittedSharesPool) {
ASAN_UNPOISON_MEMORY_REGION(share, sizeof(SubmittedShare));
delete share;
}
}

void StratumServer::on_block(const BlockTemplate& block)
Expand Down Expand Up @@ -442,83 +430,79 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo
}
}

SubmittedShare* share;

if (!m_submittedSharesPool.empty()) {
share = m_submittedSharesPool.back();
m_submittedSharesPool.pop_back();
ASAN_UNPOISON_MEMORY_REGION(share, sizeof(SubmittedShare));
}
else {
share = new SubmittedShare{};
}

if (target >= TARGET_4_BYTES_LIMIT) {
// "Low diff share" fix: adjust target to the same value as XMRig would use
target = std::numeric_limits<uint64_t>::max() / (std::numeric_limits<uint32_t>::max() / (target >> 32));
}

share->m_req.data = share;
share->m_server = this;
share->m_client = client;
share->m_clientIPv6 = client->m_isV6;
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_rpcId = client->m_rpcId;
share->m_id = id;
share->m_templateId = template_id;
share->m_nonce = nonce;
share->m_extraNonce = extra_nonce;
share->m_target = target;
share->m_resultHash = resultHash;
share->m_sidechainDifficulty = sidechain_diff;
share->m_mainchainHeight = height;
share->m_sidechainHeight = sidechain_height;
share->m_effort = -1.0;
share->m_timestamp = seconds_since_epoch();
SubmittedShare share{};

share.m_req.data = &share;
share.m_allocated = false;

share.m_server = this;
share.m_client = client;
share.m_clientIPv6 = client->m_isV6;
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_rpcId = client->m_rpcId;
share.m_id = id;
share.m_templateId = template_id;
share.m_nonce = nonce;
share.m_extraNonce = extra_nonce;
share.m_target = target;
share.m_resultHash = resultHash;
share.m_sidechainDifficulty = sidechain_diff;
share.m_mainchainHeight = height;
share.m_sidechainHeight = sidechain_height;
share.m_effort = -1.0;
share.m_timestamp = seconds_since_epoch();

uint64_t rem;
share->m_hashes = (target > 1) ? udiv128(1, 0, target, &rem) : 1;
share->m_highEnoughDifficulty = sidechain_diff.check_pow(resultHash);
share->m_score = 0;
share.m_hashes = (target > 1) ? udiv128(1, 0, target, &rem) : 1;
share.m_highEnoughDifficulty = sidechain_diff.check_pow(resultHash);
share.m_score = 0;

// Don't count shares that were found during sync
const SideChain& side_chain = m_pool->side_chain();
const PoolBlock* tip = side_chain.chainTip();
if (tip && (sidechain_height + side_chain.chain_window_size() < tip->m_sidechainHeight)) {
share->m_highEnoughDifficulty = false;
share.m_highEnoughDifficulty = false;
}

update_auto_diff(client, share->m_timestamp, share->m_hashes);
update_auto_diff(client, share.m_timestamp, share.m_hashes);

// If this share is below sidechain difficulty, process it in this thread because it'll be quick
if (!share->m_highEnoughDifficulty) {
on_share_found(&share->m_req);
on_after_share_found(&share->m_req, 0);
if (!share.m_highEnoughDifficulty) {
on_share_found(&share.m_req);
on_after_share_found(&share.m_req, 0);
return true;
}

// Else switch to a worker thread to check PoW which can take a long time
SubmittedShare* share2 = new SubmittedShare(share);
share2->m_allocated = true;

if (m_pendingShareChecks.empty()) {
const int err = uv_queue_work(&m_loop, &share->m_req, on_share_found, on_after_share_found);
const int err = uv_queue_work(&m_loop, &share2->m_req, on_share_found, on_after_share_found);
if (err) {
LOGERR(1, "uv_queue_work failed, error " << uv_err_name(err));

// If uv_queue_work failed, process this share here anyway
on_share_found(&share->m_req);
on_after_share_found(&share->m_req, 0);
on_share_found(&share2->m_req);
on_after_share_found(&share2->m_req, 0);
}
else {
m_pendingShareChecks.push_back(share);
m_pendingShareChecks.push_back(share2);
LOGINFO(5, "Pending share checks count = " << m_pendingShareChecks.size());
}
}
else {
// If there is a check running already, it will pick up this share in on_after_share_found
// This ensures that only one share at a time is checked
m_pendingShareChecks.push_back(share);
m_pendingShareChecks.push_back(share2);
LOGINFO(5, "Pending share checks count = " << m_pendingShareChecks.size());
}

Expand Down Expand Up @@ -1046,8 +1030,9 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
}
LOGINFO(5, "Pending share checks count = " << server->m_pendingShareChecks.size());

ASAN_POISON_MEMORY_REGION(share, sizeof(SubmittedShare));
server->m_submittedSharesPool.push_back(share);
if (share->m_allocated) {
delete share;
}

if (!server->m_pendingShareChecks.empty()) {
SubmittedShare* share2 = server->m_pendingShareChecks.front();
Expand Down
4 changes: 2 additions & 2 deletions src/stratum_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ class StratumServer : public TCPServer
struct SubmittedShare
{
uv_work_t m_req;
bool m_allocated;

StratumServer* m_server;
StratumClient* m_client;
bool m_clientIPv6;
Expand Down Expand Up @@ -180,8 +182,6 @@ class StratumServer : public TCPServer
} m_result;
};

std::vector<SubmittedShare*> m_submittedSharesPool;

struct HashrateData
{
uint64_t m_timestamp;
Expand Down

0 comments on commit 449e7f8

Please sign in to comment.