From 4447c81afe102a7a9d92b282a32c1f69c0efb841 Mon Sep 17 00:00:00 2001 From: michael-EA <29688009+michael-EA@users.noreply.github.com> Date: Tue, 27 Sep 2022 10:10:27 +0100 Subject: [PATCH] Add Mike Algorithm * Mike algorithm is a variant of the ghostrider algorithm --- src/backend/cpu/CpuWorker.cpp | 28 ++++++++++++++++++----- src/backend/cpu/platform/HwlocCpuInfo.cpp | 4 ++-- src/base/crypto/Algorithm.cpp | 8 +++++-- src/base/crypto/Algorithm.h | 7 ++++-- src/base/net/stratum/EthStratumClient.cpp | 10 ++++---- src/crypto/cn/CryptoNight_test.h | 22 ++++++++++++++++++ src/crypto/ghostrider/ghostrider.cpp | 20 ++++++++++++++-- src/crypto/ghostrider/ghostrider.h | 2 ++ 8 files changed, 82 insertions(+), 19 deletions(-) diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index 39e46f6d..719e54e9 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -53,6 +53,8 @@ namespace xmrig { static constexpr uint32_t kReserveCount = 32768; +static constexpr size_t GHOSTRIDER_RTM_CORE_ALGO_LIMIT = 15; +static constexpr size_t GHOSTRIDER_MIKE_CORE_ALGO_LIMIT = 11; #ifdef XMRIG_ALGO_CN_HEAVY static std::mutex cn_heavyZen3MemoryMutex; @@ -159,8 +161,8 @@ bool xmrig::CpuWorker::selfTest() # ifdef XMRIG_ALGO_GHOSTRIDER if (m_algorithm.family() == Algorithm::GHOSTRIDER) { - return (N == 8) && verify(Algorithm::GHOSTRIDER_RTM, test_output_gr); - } + return (N == 8) && verify(Algorithm::GHOSTRIDER_RTM, test_output_gr) + && verify(Algorithm::GHOSTRIDER_MIKE, test_output_gr_mike); } # endif if (m_algorithm.family() == Algorithm::CN) { @@ -308,7 +310,11 @@ void xmrig::CpuWorker::start() # ifdef XMRIG_ALGO_GHOSTRIDER case Algorithm::GHOSTRIDER: if (N == 8) { - ghostrider::hash_octa(m_job.blob(), job.size(), m_hash, m_ctx, m_ghHelper); + if (job.algorithm().id() != Algorithm::GHOSTRIDER_MIKE) { + ghostrider::hash_octa(m_job.blob(), job.size(), m_hash, m_ctx, m_ghHelper); + } else { + ghostrider::hash_octa(m_job.blob(), job.size(), m_hash, m_ctx, m_ghHelper); + } } else { valid = false; @@ -378,7 +384,7 @@ template bool xmrig::CpuWorker::verify(const Algorithm &algorithm, const uint8_t *referenceValue) { # ifdef XMRIG_ALGO_GHOSTRIDER - if (algorithm == Algorithm::GHOSTRIDER_RTM) { + if (algorithm.family() == Algorithm::GHOSTRIDER) { uint8_t blob[N * 80] = {}; for (size_t i = 0; i < N; ++i) { blob[i * 80 + 0] = static_cast(i); @@ -387,7 +393,12 @@ bool xmrig::CpuWorker::verify(const Algorithm &algorithm, const uint8_t *refe } uint8_t hash1[N * 32] = {}; - ghostrider::hash_octa(blob, 80, hash1, m_ctx, 0, false); + if (algorithm.id() != Algorithm::GHOSTRIDER_MIKE) { + ghostrider::hash_octa(blob, 80, hash1, m_ctx, 0, false); + } + else { + ghostrider::hash_octa(blob, 80, hash1, m_ctx, 0, false); + } for (size_t i = 0; i < N; ++i) { blob[i * 80 + 0] = static_cast(i); @@ -396,7 +407,12 @@ bool xmrig::CpuWorker::verify(const Algorithm &algorithm, const uint8_t *refe } uint8_t hash2[N * 32] = {}; - ghostrider::hash_octa(blob, 80, hash2, m_ctx, 0, false); + if (algorithm.id() != Algorithm::GHOSTRIDER_MIKE) { + ghostrider::hash_octa(blob, 80, hash2, m_ctx, 0, false); + } + else { + ghostrider::hash_octa(blob, 80, hash2, m_ctx, 0, false); + } for (size_t i = 0; i < N * 32; ++i) { if ((hash1[i] ^ hash2[i]) != referenceValue[i]) { diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index ee2cfca0..dc3c443a 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -299,7 +299,7 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith findByType(cache, HWLOC_OBJ_CORE, [&cores](hwloc_obj_t found) { cores.emplace_back(found); }); # ifdef XMRIG_ALGO_GHOSTRIDER - if ((algorithm == Algorithm::GHOSTRIDER_RTM) && (PUs > cores.size()) && (PUs < cores.size() * 2)) { + if ((algorithm == Algorithm::GHOSTRIDER_RTM || algorithm == Algorithm::GHOSTRIDER_MIKE) && (PUs > cores.size()) && (PUs < cores.size() * 2)) { // Don't use E-cores on Alder Lake cores.erase(std::remove_if(cores.begin(), cores.end(), [](hwloc_obj_t c) { return hwloc_bitmap_weight(c->cpuset) == 1; }), cores.end()); @@ -359,7 +359,7 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith } # ifdef XMRIG_ALGO_GHOSTRIDER - if (algorithm == Algorithm::GHOSTRIDER_RTM) { + if (algorithm == Algorithm::GHOSTRIDER_RTM || algorithm == Algorithm::GHOSTRIDER_MIKE) { // GhostRider implementation runs 8 hashes at a time intensity = 8; // Always 1 thread per core (it uses additional helper thread when possible) diff --git a/src/base/crypto/Algorithm.cpp b/src/base/crypto/Algorithm.cpp index 6e76fd26..77a1aed4 100644 --- a/src/base/crypto/Algorithm.cpp +++ b/src/base/crypto/Algorithm.cpp @@ -98,7 +98,7 @@ const char *Algorithm::kKAWPOW_RVN = "kawpow"; #ifdef XMRIG_ALGO_GHOSTRIDER const char* Algorithm::kGHOSTRIDER = "ghostrider"; -const char* Algorithm::kGHOSTRIDER_RTM = "ghostrider"; +const char* Algorithm::kGHOSTRIDER_MIKE = "ghostrider/mike"; #endif @@ -162,6 +162,7 @@ static const std::map kAlgorithmNames = { # ifdef XMRIG_ALGO_GHOSTRIDER ALGO_NAME(GHOSTRIDER_RTM), + ALGO_NAME(GHOSTRIDER_MIKE), # endif }; @@ -278,6 +279,9 @@ static const std::map kAlgorithmAlias # ifdef XMRIG_ALGO_GHOSTRIDER ALGO_ALIAS_AUTO(GHOSTRIDER_RTM), ALGO_ALIAS(GHOSTRIDER_RTM, "ghostrider/rtm"), ALGO_ALIAS(GHOSTRIDER_RTM, "gr"), + ALGO_ALIAS_AUTO(GHOSTRIDER_MIKE), ALGO_ALIAS(GHOSTRIDER_MIKE, "ghostrider/mike"), + ALGO_ALIAS(GHOSTRIDER_MIKE, "gr/mike"), + ALGO_ALIAS(GHOSTRIDER_MIKE, "mike"), # endif }; @@ -353,7 +357,7 @@ std::vector xmrig::Algorithm::all(const std::function(m_extraNonce2Size * 2)), allocator); params.PushBack(Value(m_ntime.data(), allocator), allocator); @@ -114,7 +114,7 @@ int64_t xmrig::EthStratumClient::submit(const JobResult& result) uint64_t actual_diff; # ifdef XMRIG_ALGO_GHOSTRIDER - if (result.algorithm == Algorithm::GHOSTRIDER_RTM) { + if (result.algorithm == Algorithm::GHOSTRIDER_RTM || result.algorithm == Algorithm::GHOSTRIDER_MIKE) { actual_diff = reinterpret_cast(result.result())[3]; } else @@ -202,7 +202,7 @@ void xmrig::EthStratumClient::parseNotification(const char *method, const rapidj return; } - if (m_pool.algorithm().id() != Algorithm::GHOSTRIDER_RTM) { + if (m_pool.algorithm().id() != Algorithm::GHOSTRIDER_RTM && m_pool.algorithm().id() != Algorithm::GHOSTRIDER_MIKE) { return; } @@ -236,7 +236,7 @@ void xmrig::EthStratumClient::parseNotification(const char *method, const rapidj algo = m_pool.coin().algorithm(); } - const size_t min_arr_size = (algo.id() == Algorithm::GHOSTRIDER_RTM) ? 8 : 6; + const size_t min_arr_size = (algo.id() == Algorithm::GHOSTRIDER_RTM || algo.id() == Algorithm::GHOSTRIDER_MIKE) ? 8 : 6; if (arr.Size() < min_arr_size) { LOG_ERR("%s " RED("invalid mining.notify notification: params array has wrong size"), tag()); @@ -257,7 +257,7 @@ void xmrig::EthStratumClient::parseNotification(const char *method, const rapidj std::stringstream s; # ifdef XMRIG_ALGO_GHOSTRIDER - if (algo.id() == Algorithm::GHOSTRIDER_RTM) { + if (algo.id() == Algorithm::GHOSTRIDER_RTM || algo.id() == Algorithm::GHOSTRIDER_MIKE) { // Raptoreum uses Bitcoin's Stratum protocol // https://en.bitcoinwiki.org/wiki/Stratum_mining_protocol#mining.notify diff --git a/src/crypto/cn/CryptoNight_test.h b/src/crypto/cn/CryptoNight_test.h index 0ce7ca46..a02b69f9 100644 --- a/src/crypto/cn/CryptoNight_test.h +++ b/src/crypto/cn/CryptoNight_test.h @@ -452,6 +452,28 @@ const static uint8_t test_output_gr[256] = { 0xC4, 0xA7, 0xC7, 0x77, 0xAD, 0xF8, 0x09, 0x61, 0x16, 0xBB, 0xAA, 0x7E, 0xAB, 0xC3, 0x00, 0x25, 0xBA, 0xA8, 0x97, 0xC7, 0x7D, 0x38, 0x46, 0x0E, 0x59, 0xAC, 0xCB, 0xAE, 0xFE, 0x3C, 0x6F, 0x01 }; + +// "GhostRider/Mike" +const static uint8_t test_output_gr_mike[256] = { + 0x4a, 0xad, 0xfc, 0x1b, 0xad, 0x21, 0x65, 0xa7, 0x69, 0x6f, 0x87, 0x3e, 0x5d, 0xb7, 0x3c, 0x20, + 0x5f, 0x3a, 0x4b, 0x87, 0xa3, 0x4b, 0x54, 0x35, 0x70, 0xca, 0xfc, 0x95, 0x48, 0xab, 0x5b, + 0x74, 0xfc, 0x9c, 0xb, 0xd8, 0xe5, 0x98, 0x1, 0xf1, 0x9f, 0x9e, 0x7f, 0xd4, 0xe4, 0xaf, + 0x7d, 0x14, 0x7d, 0xde, 0x8e, 0x8a, 0xdf, 0xe6, 0x4a, 0x30, 0x9a, 0x92, 0xf5, 0x12, 0x3f, + 0x16, 0xf3, 0xf0, 0xc7, 0x2f, 0xf7, 0x4b, 0x6, 0x82, 0xa5, 0x50, 0xa0, 0xb3, 0xb8, 0x81, + 0xa, 0xde, 0x29, 0x4e, 0xcd, 0x72, 0x57, 0x60, 0x4e, 0xc1, 0x23, 0x46, 0x1b, 0x39, 0x23, + 0xcc, 0x4a, 0x64, 0x7b, 0x2d, 0x8b, 0x4, 0xa1, 0xea, 0xa4, 0xa0, 0xf9, 0x3d, 0x7d, 0x26, + 0x22, 0xf0, 0xa6, 0xa, 0x18, 0x2c, 0xd5, 0x88, 0x4f, 0x47, 0xb7, 0x72, 0x83, 0xa9, 0xcd, + 0x17, 0x24, 0xb, 0x39, 0x3c, 0x54, 0x51, 0x47, 0xef, 0x77, 0x55, 0xa, 0x9b, 0x56, 0x6, + 0x47, 0xbe, 0xdb, 0x85, 0x78, 0x3a, 0x15, 0x31, 0x8c, 0x60, 0xce, 0xe9, 0x9a, 0x1f, 0xdd, + 0x8c, 0xcc, 0xf0, 0x17, 0xa5, 0x99, 0x17, 0xb5, 0x5d, 0x30, 0xae, 0x8d, 0x7a, 0xd2, 0xfd, + 0xd5, 0x66, 0xdd, 0x23, 0xa0, 0xca, 0x56, 0x66, 0x64, 0x6c, 0x38, 0xda, 0xdf, 0x91, 0x12, + 0x6, 0x9a, 0x11, 0x13, 0x4e, 0xcf, 0x71, 0xf4, 0xb, 0x26, 0x50, 0x7d, 0x0, 0x6f, 0xc4, + 0x39, 0xb5, 0xd, 0xaa, 0xa3, 0x60, 0x5e, 0x41, 0x82, 0xe0, 0xce, 0x38, 0x7f, 0x37, 0x90, + 0xac, 0x53, 0xbe, 0x46, 0xb4, 0x6a, 0xc4, 0xb8, 0xe1, 0x9f, 0x31, 0x9f, 0xf4, 0xff, 0x46, + 0x73, 0x92, 0xee, 0x64, 0xa6, 0x44, 0xac, 0xd4, 0x33, 0xb8, 0x3b, 0x84, 0x42, 0x7e, 0x9a, + 0x80, 0xf0, 0xa8, 0x71, 0xf0, 0x81, 0xc4, 0xc1, 0x52, 0xff, 0x27, 0x4e, 0x7, 0xf0, 0x70 +}; + #endif diff --git a/src/crypto/ghostrider/ghostrider.cpp b/src/crypto/ghostrider/ghostrider.cpp index 0ce0976e..978b99c6 100644 --- a/src/crypto/ghostrider/ghostrider.cpp +++ b/src/crypto/ghostrider/ghostrider.cpp @@ -539,7 +539,7 @@ void destroy_helper_thread(HelperThread* t) delete t; } - +template void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ctx** ctx, HelperThread* helper, bool verbose) { enum { N = 8 }; @@ -550,7 +550,7 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct } // PrevBlockHash (GhostRider's seed) is stored in bytes [4; 36) - uint32_t core_indices[15]; + uint32_t core_indices[CORE_ALGO_LIMIT]; select_indices(core_indices, data + 4); uint32_t cn_indices[6]; @@ -601,6 +601,9 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct for (size_t i = 0; i < 5; ++i) { for (size_t j = n; j < N; ++j) { + if ((part * 5 + i) >= CORE_ALGO_LIMIT) { + break; + } core_hash[core_indices[part * 5 + i]](input + j * input_size, input_size, tmp + j * 64); } input = tmp; @@ -645,6 +648,9 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct for (size_t i = 0; i < 5; ++i) { for (size_t j = 0; j < n; ++j) { + if ((part * 5 + i) >= CORE_ALGO_LIMIT) { + break; + } core_hash[core_indices[part * 5 + i]](input + j * input_size, input_size, tmp + j * 64); } input = tmp; @@ -713,6 +719,9 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct for (size_t i = 0; i < 5; ++i) { for (size_t j = n; j < N; ++j) { + if ((part * 5 + i) >= CORE_ALGO_LIMIT) { + break; + } core_hash[core_indices[part * 5 + i]](input + j * input_size, input_size, tmp + j * 64); } input = tmp; @@ -733,6 +742,9 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct for (size_t i = 0; i < 5; ++i) { for (size_t j = 0; j < n; ++j) { + if ((part * 5 + i) >= CORE_ALGO_LIMIT) { + break; + } core_hash[core_indices[part * 5 + i]](data + j * size, size, tmp + j * 64); } data = tmp; @@ -769,6 +781,7 @@ HelperThread* create_helper_thread(int64_t, int, const std::vector&) { void destroy_helper_thread(HelperThread*) {} +template void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ctx** ctx, HelperThread*, bool verbose) { constexpr uint32_t N = 8; @@ -829,6 +842,9 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct for (size_t i = 0; i < 5; ++i) { for (size_t j = 0; j < N; ++j) { + if ((part * 5 + i) >= CORE_ALGO_LIMIT) { + break; + } core_hash[core_indices[part * 5 + i]](data + j * size, size, tmp + j * 64); } data = tmp; diff --git a/src/crypto/ghostrider/ghostrider.h b/src/crypto/ghostrider/ghostrider.h index e6c08df1..3e421232 100644 --- a/src/crypto/ghostrider/ghostrider.h +++ b/src/crypto/ghostrider/ghostrider.h @@ -41,6 +41,8 @@ struct HelperThread; void benchmark(); HelperThread* create_helper_thread(int64_t cpu_index, int priority, const std::vector& affinities); void destroy_helper_thread(HelperThread* t); + +template void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ctx** ctx, HelperThread* helper, bool verbose = true);