From d1e94d6e1a1f2970f618f6767e1367e13d42b651 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 30 Aug 2021 16:51:23 +0200 Subject: [PATCH] StartumServer: print average hashrate in status --- src/side_chain.cpp | 16 +++--- src/stratum_server.cpp | 118 ++++++++++++++++++++++++++++++++++++----- src/stratum_server.h | 22 ++++++++ 3 files changed, 134 insertions(+), 22 deletions(-) diff --git a/src/side_chain.cpp b/src/side_chain.cpp index 28e71a0..cb503df 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -650,14 +650,14 @@ void SideChain::print_status() const uint64_t hashrate_est = udiv128(product[1], product[0], block_reward, &rem); LOGINFO(0, "status" << - "\nMain chain height = " << m_pool->block_template().height() << - "\nMain chain hashrate = " << log::Hashrate(network_hashrate) << - "\nSide chain height = " << tip_height + 1 << - "\nSide chain hashrate = " << log::Hashrate(pool_hashrate) << - "\nYour hashrate (est) = " << log::Hashrate(hashrate_est) << - "\nPPLNS window = " << total_blocks_in_window << " blocks (+" << total_uncles_in_window << " uncles, " << total_orphans << " orphans)" - "\nYour shares = " << our_blocks_in_window << " blocks (+" << our_uncles_in_window << " uncles, " << our_orphans << " orphans)" - "\nNext payout (est) = " << log::XMRAmount(next_payout) + "\nMain chain height = " << m_pool->block_template().height() << + "\nMain chain hashrate = " << log::Hashrate(network_hashrate) << + "\nSide chain height = " << tip_height + 1 << + "\nSide chain hashrate = " << log::Hashrate(pool_hashrate) << + "\nYour hashrate (pool-side) = " << log::Hashrate(hashrate_est) << + "\nPPLNS window = " << total_blocks_in_window << " blocks (+" << total_uncles_in_window << " uncles, " << total_orphans << " orphans)" + "\nYour shares = " << our_blocks_in_window << " blocks (+" << our_uncles_in_window << " uncles, " << our_orphans << " orphans)" + "\nNext payout (estimated) = " << log::XMRAmount(next_payout) ); } diff --git a/src/stratum_server.cpp b/src/stratum_server.cpp index 4383641..d62cf16 100644 --- a/src/stratum_server.cpp +++ b/src/stratum_server.cpp @@ -26,6 +26,9 @@ static constexpr char log_category_prefix[] = "StratumServer "; static constexpr int DEFAULT_BACKLOG = 128; static constexpr uint64_t DEFAULT_BAN_TIME = 600; +// Use short target format (4 bytes) for diff <= 4 million +static constexpr uint64_t TARGET_4_BYTES_LIMIT = std::numeric_limits::max() / 4000000; + #include "tcp_server.inl" namespace p2pool { @@ -36,10 +39,18 @@ StratumServer::StratumServer(p2pool* pool) , m_extraNonce(0) , m_rd{} , m_rng(m_rd()) + , m_cumulativeHashes(0) + , m_hashrateDataHead(0) + , m_hashrateDataTail_15m(0) + , m_hashrateDataTail_1h(0) + , m_hashrateDataTail_24h(0) { + m_hashrateData[0] = { time(nullptr), 0 }; + uv_mutex_init_checked(&m_blobsQueueLock); uv_mutex_init_checked(&m_rngLock); uv_mutex_init_checked(&m_submittedSharesPoolLock); + uv_rwlock_init_checked(&m_hashrateDataLock); m_submittedSharesPool.resize(10); for (size_t i = 0; i < m_submittedSharesPool.size(); ++i) { @@ -66,6 +77,7 @@ StratumServer::~StratumServer() uv_mutex_destroy(&m_blobsQueueLock); uv_mutex_destroy(&m_rngLock); uv_mutex_destroy(&m_submittedSharesPoolLock); + uv_rwlock_destroy(&m_hashrateDataLock); for (SubmittedShare* share : m_submittedSharesPool) { delete share; @@ -198,8 +210,7 @@ bool StratumServer::on_login(StratumClient* client, uint32_t id, const char* log log::hex_buf target_hex(reinterpret_cast(&target), sizeof(uint64_t)); - // Use short target format (4 bytes) for diff <= ~4 million - if ((target >> 32) >= 1073) { + if (target >= TARGET_4_BYTES_LIMIT) { target_hex.m_data += sizeof(uint32_t); target_hex.m_size -= sizeof(uint32_t); } @@ -255,6 +266,7 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo uint32_t template_id = 0; uint32_t extra_nonce = 0; + uint64_t target = 0; bool found = false; { @@ -264,6 +276,7 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo if (saved_job.job_id == job_id) { template_id = saved_job.template_id; extra_nonce = saved_job.extra_nonce; + target = saved_job.target; found = true; } } @@ -292,6 +305,7 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo share->m_templateId = template_id; share->m_nonce = nonce; share->m_extraNonce = extra_nonce; + share->m_target = target; share->m_resultHash = resultHash; const int err = uv_queue_work(&m_loop, &share->m_req, on_share_found, on_after_share_found); @@ -324,6 +338,45 @@ uint64_t StratumServer::get_random64() return m_rng(); } +void StratumServer::print_stratum_status() const +{ + uint64_t hashes_15m, hashes_1h, hashes_24h, total_hashes; + int64_t dt_15m, dt_1h, dt_24h; + + { + ReadLock lock(m_hashrateDataLock); + + total_hashes = m_cumulativeHashes; + + const HashrateData* data = m_hashrateData; + const HashrateData& head = data[m_hashrateDataHead]; + const HashrateData& tail_15m = data[m_hashrateDataTail_15m]; + const HashrateData& tail_1h = data[m_hashrateDataTail_1h]; + const HashrateData& tail_24h = data[m_hashrateDataTail_24h]; + + hashes_15m = head.m_cumulativeHashes - tail_15m.m_cumulativeHashes; + dt_15m = static_cast(head.m_timestamp - tail_15m.m_timestamp); + + hashes_1h = head.m_cumulativeHashes - tail_1h.m_cumulativeHashes; + dt_1h = static_cast(head.m_timestamp - tail_1h.m_timestamp); + + hashes_24h = head.m_cumulativeHashes - tail_24h.m_cumulativeHashes; + dt_24h = static_cast(head.m_timestamp - tail_24h.m_timestamp); + } + + const uint64_t hashrate_15m = (dt_15m > 0) ? (hashes_15m / dt_15m) : 0; + const uint64_t hashrate_1h = (dt_1h > 0) ? (hashes_1h / dt_1h ) : 0; + const uint64_t hashrate_24h = (dt_24h > 0) ? (hashes_24h / dt_24h) : 0; + + LOGINFO(0, "status" << + "\nHashrate (15m est) = " << log::Hashrate(hashrate_15m) << + "\nHashrate (1h est) = " << log::Hashrate(hashrate_1h) << + "\nHashrate (24h est) = " << log::Hashrate(hashrate_24h) << + "\nTotal hashes = " << total_hashes << + "\nConnections = " << m_numConnections << " (" << m_numIncomingConnections << " incoming)" + ); +} + void StratumServer::on_blobs_ready() { std::vector blobs_queue; @@ -369,6 +422,11 @@ void StratumServer::on_blobs_ready() uint8_t* hashing_blob = data->m_blobs.data() + extra_nonce * data->m_blobSize; + uint64_t target = data->m_target; + if (client->m_customDiff.lo) { + target = std::max(target, client->m_customDiff.target()); + } + uint32_t job_id; { MutexLock lock3(client->m_jobsLock); @@ -379,12 +437,7 @@ void StratumServer::on_blobs_ready() saved_job.job_id = job_id; saved_job.extra_nonce = extra_nonce; saved_job.template_id = data->m_templateId; - saved_job.target = data->m_target; - } - - uint64_t target = data->m_target; - if (client->m_customDiff.lo) { - target = std::max(target, client->m_customDiff.target()); + saved_job.target = target; } const bool result = send(client, @@ -392,8 +445,7 @@ void StratumServer::on_blobs_ready() { log::hex_buf target_hex(reinterpret_cast(&target), sizeof(uint64_t)); - // Use short target format (4 bytes) for diff <= ~4 million - if ((target >> 32) >= 1073) { + if (target >= TARGET_4_BYTES_LIMIT) { target_hex.m_data += sizeof(uint32_t); target_hex.m_size -= sizeof(uint32_t); } @@ -424,6 +476,44 @@ void StratumServer::on_blobs_ready() LOGINFO(3, "sent new job to " << extra_nonce << '/' << numClientsProcessed << " clients"); } +void StratumServer::update_hashrate_data(uint64_t target) +{ + if (target <= 1) { + return; + } + + const time_t timestamp = time(nullptr); + + uint64_t hashes, rem; + hashes = udiv128(1, 0, target, &rem); + + WriteLock lock(m_hashrateDataLock); + + m_cumulativeHashes += hashes; + + HashrateData* data = m_hashrateData; + HashrateData& head = data[m_hashrateDataHead]; + if (head.m_timestamp == timestamp) { + head.m_cumulativeHashes = m_cumulativeHashes; + } + else { + m_hashrateDataHead = (m_hashrateDataHead + 1) % array_size(m_hashrateData); + data[m_hashrateDataHead] = { timestamp, m_cumulativeHashes }; + } + + while (data[m_hashrateDataTail_15m].m_timestamp + 15 * 60 < timestamp) { + m_hashrateDataTail_15m = (m_hashrateDataTail_15m + 1) % array_size(m_hashrateData); + } + + while (data[m_hashrateDataTail_1h].m_timestamp + 60 * 60 < timestamp) { + m_hashrateDataTail_1h = (m_hashrateDataTail_1h + 1) % array_size(m_hashrateData); + } + + while (data[m_hashrateDataTail_24h].m_timestamp + 60 * 60 * 24 < timestamp) { + m_hashrateDataTail_24h = (m_hashrateDataTail_24h + 1) % array_size(m_hashrateData); + } +} + void StratumServer::on_share_found(uv_work_t* req) { bkg_jobs_tracker.start("StratumServer::on_share_found"); @@ -489,13 +579,13 @@ void StratumServer::on_share_found(uv_work_t* req) // Send the response to miner const uint64_t value = *reinterpret_cast(share->m_resultHash.h + HASH_SIZE - sizeof(uint64_t)); - uint64_t target = std::max(difficulty.target(), sidechain_difficulty.target()); - - if (client->m_customDiff.lo) { - target = std::max(target, client->m_customDiff.target()); + uint64_t target = share->m_target; + if (target >= TARGET_4_BYTES_LIMIT) { + target = (target >> 32) << 32; } if (LIKELY(value < target)) { + server->update_hashrate_data(target); share->m_result = SubmittedShare::Result::OK; } else { diff --git a/src/stratum_server.h b/src/stratum_server.h index a7134da..dd4b4c9 100644 --- a/src/stratum_server.h +++ b/src/stratum_server.h @@ -70,7 +70,11 @@ public: bool on_submit(StratumClient* client, uint32_t id, const char* job_id_str, const char* nonce_str, const char* result_str); uint64_t get_random64(); + void print_status() override { print_stratum_status(); } + private: + void print_stratum_status() const; + static bool get_custom_diff(const char* s, difficulty_type& diff); static void on_share_found(uv_work_t* req); @@ -113,6 +117,7 @@ private: uint32_t m_templateId; uint32_t m_nonce; uint32_t m_extraNonce; + uint64_t m_target; hash m_resultHash; enum class Result { @@ -126,6 +131,23 @@ private: uv_mutex_t m_submittedSharesPoolLock; std::vector m_submittedSharesPool; + + struct HashrateData + { + time_t m_timestamp; + uint64_t m_cumulativeHashes; + }; + + mutable uv_rwlock_t m_hashrateDataLock; + + HashrateData m_hashrateData[131072]; + uint64_t m_cumulativeHashes; + uint64_t m_hashrateDataHead; + uint64_t m_hashrateDataTail_15m; + uint64_t m_hashrateDataTail_1h; + uint64_t m_hashrateDataTail_24h; + + void update_hashrate_data(uint64_t target); }; } // namespace p2pool