CryptonightR support for Wownero
This commit is contained in:
parent
73852f44c6
commit
e3f2c38fff
32 changed files with 11251 additions and 131 deletions
|
@ -145,16 +145,50 @@ bool xmrig::CpuThread::isSoftAES(AlgoVariant av)
|
|||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_ASM
|
||||
template<xmrig::Algo algo, xmrig::Variant variant>
|
||||
static inline void add_asm_func(xmrig::CpuThread::cn_hash_fun(&asm_func_map)[xmrig::ALGO_MAX][xmrig::AV_MAX][xmrig::VARIANT_MAX][xmrig::ASM_MAX])
|
||||
{
|
||||
asm_func_map[algo][xmrig::AV_SINGLE][variant][xmrig::ASM_INTEL] = cryptonight_single_hash_asm<algo, variant, xmrig::ASM_INTEL>;
|
||||
asm_func_map[algo][xmrig::AV_SINGLE][variant][xmrig::ASM_RYZEN] = cryptonight_single_hash_asm<algo, variant, xmrig::ASM_RYZEN>;
|
||||
asm_func_map[algo][xmrig::AV_SINGLE][variant][xmrig::ASM_BULLDOZER] = cryptonight_single_hash_asm<algo, variant, xmrig::ASM_BULLDOZER>;
|
||||
|
||||
asm_func_map[algo][xmrig::AV_DOUBLE][variant][xmrig::ASM_INTEL] = cryptonight_double_hash_asm<algo, variant, xmrig::ASM_INTEL>;
|
||||
asm_func_map[algo][xmrig::AV_DOUBLE][variant][xmrig::ASM_RYZEN] = cryptonight_double_hash_asm<algo, variant, xmrig::ASM_RYZEN>;
|
||||
asm_func_map[algo][xmrig::AV_DOUBLE][variant][xmrig::ASM_BULLDOZER] = cryptonight_double_hash_asm<algo, variant, xmrig::ASM_BULLDOZER>;
|
||||
}
|
||||
#endif
|
||||
|
||||
xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly)
|
||||
{
|
||||
assert(variant >= VARIANT_0 && variant < VARIANT_MAX);
|
||||
|
||||
# ifndef XMRIG_NO_ASM
|
||||
constexpr const size_t count = VARIANT_MAX * 10 * ALGO_MAX + 12;
|
||||
# else
|
||||
constexpr const size_t count = VARIANT_MAX * 10 * ALGO_MAX;
|
||||
if (assembly == ASM_AUTO) {
|
||||
assembly = Cpu::info()->assembly();
|
||||
}
|
||||
|
||||
static cn_hash_fun asm_func_map[ALGO_MAX][AV_MAX][VARIANT_MAX][ASM_MAX] = {};
|
||||
static bool asm_func_map_initialized = false;
|
||||
|
||||
if (!asm_func_map_initialized) {
|
||||
add_asm_func<CRYPTONIGHT, VARIANT_2>(asm_func_map);
|
||||
add_asm_func<CRYPTONIGHT, VARIANT_HALF>(asm_func_map);
|
||||
add_asm_func<CRYPTONIGHT, VARIANT_WOW>(asm_func_map);
|
||||
|
||||
add_asm_func<CRYPTONIGHT_PICO, VARIANT_HALF>(asm_func_map);
|
||||
|
||||
asm_func_map_initialized = true;
|
||||
}
|
||||
|
||||
cn_hash_fun fun = asm_func_map[algorithm][av][variant][assembly];
|
||||
if (fun) {
|
||||
return fun;
|
||||
}
|
||||
# endif
|
||||
|
||||
constexpr const size_t count = VARIANT_MAX * 10 * ALGO_MAX;
|
||||
|
||||
static const cn_hash_fun func_table[] = {
|
||||
cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_0>,
|
||||
cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_0>,
|
||||
|
@ -265,6 +299,17 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU
|
||||
# endif
|
||||
|
||||
cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_WOW>,
|
||||
cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_WOW>,
|
||||
cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_WOW>,
|
||||
cryptonight_double_hash<CRYPTONIGHT, true, VARIANT_WOW>,
|
||||
cryptonight_triple_hash<CRYPTONIGHT, false, VARIANT_WOW>,
|
||||
cryptonight_quad_hash<CRYPTONIGHT, false, VARIANT_WOW>,
|
||||
cryptonight_penta_hash<CRYPTONIGHT, false, VARIANT_WOW>,
|
||||
cryptonight_triple_hash<CRYPTONIGHT, true, VARIANT_WOW>,
|
||||
cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_WOW>,
|
||||
cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_WOW>,
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
|
||||
cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
|
||||
|
@ -298,6 +343,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW
|
||||
# else
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
|
||||
|
@ -311,6 +357,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_SUMO
|
||||
|
@ -358,6 +405,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW
|
||||
# else
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
|
||||
|
@ -371,7 +419,9 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_CN_PICO
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
|
||||
|
@ -396,6 +446,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
cryptonight_penta_hash<CRYPTONIGHT_PICO, true, VARIANT_TRTL>,
|
||||
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW
|
||||
# else
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
|
||||
|
@ -409,30 +460,15 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU
|
||||
# endif
|
||||
# ifndef XMRIG_NO_ASM
|
||||
cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_INTEL>,
|
||||
cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_RYZEN>,
|
||||
cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_BULLDOZER>,
|
||||
cryptonight_double_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_INTEL>,
|
||||
|
||||
cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_HALF, ASM_INTEL>,
|
||||
cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_HALF, ASM_RYZEN>,
|
||||
cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_HALF, ASM_BULLDOZER>,
|
||||
cryptonight_double_hash_asm<CRYPTONIGHT, VARIANT_HALF, ASM_INTEL>,
|
||||
|
||||
cryptonight_single_hash_asm<CRYPTONIGHT_PICO, VARIANT_TRTL, ASM_INTEL>,
|
||||
cryptonight_single_hash_asm<CRYPTONIGHT_PICO, VARIANT_TRTL, ASM_RYZEN>,
|
||||
cryptonight_single_hash_asm<CRYPTONIGHT_PICO, VARIANT_TRTL, ASM_BULLDOZER>,
|
||||
cryptonight_double_hash_asm<CRYPTONIGHT_PICO, VARIANT_TRTL, ASM_INTEL>
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
static_assert(count == sizeof(func_table) / sizeof(func_table[0]), "func_table size mismatch");
|
||||
|
||||
const size_t index = VARIANT_MAX * 10 * algorithm + 10 * variant + av - 1;
|
||||
|
||||
# ifndef NDEBUG
|
||||
const size_t index = fnIndex(algorithm, av, variant, assembly);
|
||||
cn_hash_fun func = func_table[index];
|
||||
|
||||
assert(index < sizeof(func_table) / sizeof(func_table[0]));
|
||||
|
@ -440,7 +476,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
|
||||
return func;
|
||||
# else
|
||||
return func_table[fnIndex(algorithm, av, variant, assembly)];
|
||||
return func_table[index];
|
||||
# endif
|
||||
}
|
||||
|
||||
|
@ -602,49 +638,3 @@ rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const
|
|||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
size_t xmrig::CpuThread::fnIndex(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly)
|
||||
{
|
||||
const size_t index = VARIANT_MAX * 10 * algorithm + 10 * variant + av - 1;
|
||||
|
||||
# ifndef XMRIG_NO_ASM
|
||||
if (assembly == ASM_AUTO) {
|
||||
assembly = Cpu::info()->assembly();
|
||||
}
|
||||
|
||||
if (assembly == ASM_NONE) {
|
||||
return index;
|
||||
}
|
||||
|
||||
constexpr const size_t offset = VARIANT_MAX * 10 * ALGO_MAX;
|
||||
size_t extra_offset = 0;
|
||||
|
||||
if (algorithm == CRYPTONIGHT && (variant == VARIANT_2 || variant == VARIANT_HALF)) {
|
||||
if (variant == VARIANT_HALF) {
|
||||
extra_offset += 4;
|
||||
}
|
||||
|
||||
if (av == AV_SINGLE) {
|
||||
return offset + extra_offset + assembly - 2;
|
||||
}
|
||||
|
||||
if (av == AV_DOUBLE) {
|
||||
return offset + 3 + extra_offset;
|
||||
}
|
||||
}
|
||||
else if (algorithm == CRYPTONIGHT_PICO && variant == VARIANT_TRTL) {
|
||||
extra_offset = 8;
|
||||
|
||||
if (av == AV_SINGLE) {
|
||||
return offset + extra_offset + assembly - 2;
|
||||
}
|
||||
|
||||
if (av == AV_DOUBLE) {
|
||||
return offset + 3 + extra_offset;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
return index;
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
|
||||
CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly);
|
||||
|
||||
typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx);
|
||||
typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx, uint64_t height);
|
||||
typedef void (*cn_mainloop_fun)(cryptonight_ctx *ctx);
|
||||
typedef void (*cn_mainloop_double_fun)(cryptonight_ctx *ctx1, cryptonight_ctx *ctx2);
|
||||
|
||||
|
@ -98,8 +98,6 @@ protected:
|
|||
rapidjson::Value toConfig(rapidjson::Document &doc) const override;
|
||||
|
||||
private:
|
||||
static size_t fnIndex(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly);
|
||||
|
||||
const Algo m_algorithm;
|
||||
const AlgoVariant m_av;
|
||||
const Assembly m_assembly;
|
||||
|
|
|
@ -25,9 +25,11 @@
|
|||
|
||||
|
||||
#include <thread>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
#include "crypto/CryptoNight_test.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "workers/CpuThread.h"
|
||||
#include "workers/MultiWorker.h"
|
||||
#include "workers/Workers.h"
|
||||
|
@ -54,6 +56,11 @@ bool MultiWorker<N>::selfTest()
|
|||
using namespace xmrig;
|
||||
|
||||
if (m_thread->algorithm() == CRYPTONIGHT) {
|
||||
if (!verify2(VARIANT_WOW, test_input_WOW)) {
|
||||
LOG_WARN("CryptonightR (Wownero) self-test failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool rc = verify(VARIANT_0, test_output_v0) &&
|
||||
verify(VARIANT_1, test_output_v1) &&
|
||||
verify(VARIANT_2, test_output_v2) &&
|
||||
|
@ -121,7 +128,7 @@ void MultiWorker<N>::start()
|
|||
storeStats();
|
||||
}
|
||||
|
||||
m_thread->fn(m_state.job.algorithm().variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx);
|
||||
m_thread->fn(m_state.job.algorithm().variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx, m_state.job.height());
|
||||
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < m_state.job.target()) {
|
||||
|
@ -162,11 +169,71 @@ bool MultiWorker<N>::verify(xmrig::Variant variant, const uint8_t *referenceValu
|
|||
return false;
|
||||
}
|
||||
|
||||
func(test_input, 76, m_hash, m_ctx);
|
||||
func(test_input, 76, m_hash, m_ctx, 0);
|
||||
return memcmp(m_hash, referenceValue, sizeof m_hash) == 0;
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
bool MultiWorker<N>::verify2(xmrig::Variant variant, const char *test_data)
|
||||
{
|
||||
xmrig::CpuThread::cn_hash_fun func = m_thread->fn(variant);
|
||||
if (!func) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::stringstream s(test_data);
|
||||
std::string expected_hex;
|
||||
std::string input_hex;
|
||||
uint64_t height;
|
||||
while (!s.eof())
|
||||
{
|
||||
uint8_t referenceValue[N * 32];
|
||||
uint8_t input[N * 256];
|
||||
|
||||
s >> expected_hex;
|
||||
s >> input_hex;
|
||||
s >> height;
|
||||
|
||||
if ((expected_hex.length() != 64) || (input_hex.length() > 512))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool err = false;
|
||||
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
referenceValue[i] = (hf_hex2bin(expected_hex[i * 2], err) << 4) + hf_hex2bin(expected_hex[i * 2 + 1], err);
|
||||
}
|
||||
|
||||
const size_t input_len = input_hex.length() / 2;
|
||||
for (size_t i = 0; i < input_len; ++i)
|
||||
{
|
||||
input[i] = (hf_hex2bin(input_hex[i * 2], err) << 4) + hf_hex2bin(input_hex[i * 2 + 1], err);
|
||||
}
|
||||
|
||||
if (err)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < N; ++i)
|
||||
{
|
||||
memcpy(input + i * input_len, input, input_len);
|
||||
memcpy(referenceValue + i * 32, referenceValue, 32);
|
||||
}
|
||||
|
||||
func(input, input_len, m_hash, m_ctx, height);
|
||||
if (memcmp(m_hash, referenceValue, sizeof m_hash) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
void MultiWorker<N>::consumeJob()
|
||||
{
|
||||
|
|
|
@ -50,6 +50,7 @@ protected:
|
|||
private:
|
||||
bool resume(const Job &job);
|
||||
bool verify(xmrig::Variant variant, const uint8_t *referenceValue);
|
||||
bool verify2(xmrig::Variant variant, const char *test_data);
|
||||
void consumeJob();
|
||||
void save(const Job &job);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue