From 451778d7045b5b4a45bffb739515f96297dbc06b Mon Sep 17 00:00:00 2001 From: SChernykh Date: Tue, 17 Jan 2023 16:15:24 +0100 Subject: [PATCH] Optimized RNG usage --- src/block_template.cpp | 11 +++++++---- src/stratum_server.cpp | 12 ++++++------ src/stratum_server.h | 2 +- tests/src/block_template_tests.cpp | 4 ++-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/block_template.cpp b/src/block_template.cpp index a10d564..e31c402 100644 --- a/src/block_template.cpp +++ b/src/block_template.cpp @@ -198,9 +198,12 @@ static FORCEINLINE uint64_t get_block_reward(uint64_t base_reward, uint64_t medi void BlockTemplate::shuffle_tx_order() { - const int64_t n = static_cast(m_mempoolTxsOrder.size()); - for (int64_t i = n - 1; i > 0; --i) { - std::swap(m_mempoolTxsOrder[i], m_mempoolTxsOrder[m_rng() % (i + 1)]); + const uint64_t n = m_mempoolTxsOrder.size(); + if (n > 1) { + for (uint64_t i = 0, k; i < n - 1; ++i) { + umul128(m_rng(), n - i, &k); + std::swap(m_mempoolTxsOrder[i], m_mempoolTxsOrder[i + k]); + } } } @@ -636,7 +639,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, Wallet uint32_t* sidechain_extra = m_poolBlockTemplate->m_sidechainExtraBuf; sidechain_extra[0] = 0; sidechain_extra[1] = (P2POOL_VERSION_MAJOR << 16) | P2POOL_VERSION_MINOR; - sidechain_extra[2] = static_cast(m_rng()); + sidechain_extra[2] = static_cast(m_rng() >> 32); sidechain_extra[3] = 0; m_poolBlockTemplate->m_nonce = 0; diff --git a/src/stratum_server.cpp b/src/stratum_server.cpp index 6ff2913..755d10e 100644 --- a/src/stratum_server.cpp +++ b/src/stratum_server.cpp @@ -60,14 +60,14 @@ StratumServer::StratumServer(p2pool* pool) // Diffuse the initial state in case it has low quality m_rng.discard(10000); - m_extraNonce = PoolBlock::signal_v2_readiness(static_cast(m_rng())); - m_hashrateData[0] = { seconds_since_epoch(), 0 }; uv_mutex_init_checked(&m_blobsQueueLock); uv_mutex_init_checked(&m_rngLock); uv_rwlock_init_checked(&m_hashrateDataLock); + m_extraNonce = PoolBlock::signal_v2_readiness(get_random32()); + m_submittedSharesPool.resize(10); for (size_t i = 0; i < m_submittedSharesPool.size(); ++i) { m_submittedSharesPool[i] = new SubmittedShare{}; @@ -107,7 +107,7 @@ void StratumServer::on_block(const BlockTemplate& block) return; } - const uint32_t extra_nonce_start = PoolBlock::signal_v2_readiness(static_cast(get_random64())); + const uint32_t extra_nonce_start = PoolBlock::signal_v2_readiness(get_random32()); m_extraNonce.exchange(extra_nonce_start + num_connections); BlobsData* blobs_data = new BlobsData{}; @@ -283,7 +283,7 @@ bool StratumServer::on_login(StratumClient* client, uint32_t id, const char* log [client, id, &hashing_blob, job_id, blob_size, target, height, &seed_hash](void* buf, size_t buf_size) { do { - client->m_rpcId = static_cast(static_cast(client->m_owner)->get_random64()); + client->m_rpcId = static_cast(client->m_owner)->get_random32(); } while (!client->m_rpcId); log::hex_buf target_hex(reinterpret_cast(&target), sizeof(uint64_t)); @@ -463,10 +463,10 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo return result; } -uint64_t StratumServer::get_random64() +uint32_t StratumServer::get_random32() { MutexLock lock(m_rngLock); - return m_rng(); + return static_cast(m_rng() >> 32); } void StratumServer::print_status() diff --git a/src/stratum_server.h b/src/stratum_server.h index 19b24e4..5b5bec1 100644 --- a/src/stratum_server.h +++ b/src/stratum_server.h @@ -84,7 +84,7 @@ public: bool on_login(StratumClient* client, uint32_t id, const char* login); 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(); + uint32_t get_random32(); void print_status() override; void show_workers(); diff --git a/tests/src/block_template_tests.cpp b/tests/src/block_template_tests.cpp index 405f0bb..2831f1e 100644 --- a/tests/src/block_template_tests.cpp +++ b/tests/src/block_template_tests.cpp @@ -60,7 +60,7 @@ TEST(block_template, update) tpl.update(data, mempool, &wallet); const PoolBlock* b = tpl.pool_block_template(); - ASSERT_EQ(b->m_sidechainId, H("742f581765311fa069d3a90e3338fcffbc3d28de8598ee9fc968ebc092353246")); + ASSERT_EQ(b->m_sidechainId, H("16d6a5c45d452288fcc439e5a258e8230798dfb6bbfd32220303efe932061aa9")); std::vector blobs; uint64_t height; @@ -79,7 +79,7 @@ TEST(block_template, update) hash blobs_hash; keccak(blobs.data(), static_cast(blobs.size()), blobs_hash.h); - ASSERT_EQ(blobs_hash, H("082b9eb9d35e38cb3c8eb0fae6e03398ea865adba6103db25ed4a33c5face942")); + ASSERT_EQ(blobs_hash, H("27bd8678420c8a0948f71c71356252be790899d61f14e35b2d0440a30d730f4c")); // Test 2: mempool with high fee and low fee transactions, it must choose high fee transactions for (uint64_t i = 0; i < 512; ++i) {