feat: Add stratum integration and mining support for new algorithms
- Stratum protocol integration for ETChash, ProgPowZ, Blake3DCR - EthStratumClient selection for DAG-based algorithms - Nonce offset handling for all new algorithm families - AutoClient support for new algorithm detection - Coin definitions for ETC, ETH, ZANO, DCR Worker integration: - CPU worker support for Blake3DCR mining - GPU worker stubs for ETChash, ProgPowZ, Blake3 - Proper algorithm family handling in CpuWorker/OclWorker Go CLI integration: - Updated xmrig_start.go with coin field support - Improved pool configuration for new algorithms 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
9cf0db802a
commit
b1aced8341
9 changed files with 151 additions and 22 deletions
|
|
@ -44,6 +44,10 @@
|
|||
# include "crypto/randomx/randomx.h"
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_ALGO_BLAKE3DCR
|
||||
# include "crypto/blake3dcr/Blake3DCR.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_BENCHMARK
|
||||
# include "backend/common/benchmark/BenchState.h"
|
||||
|
|
@ -225,6 +229,27 @@ bool xmrig::CpuWorker<N>::selfTest()
|
|||
}
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_BLAKE3DCR
|
||||
if (m_algorithm.family() == Algorithm::BLAKE3) {
|
||||
// Blake3 is a simple hash, supports any N value
|
||||
return N >= 1;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_ETCHASH
|
||||
if (m_algorithm.family() == Algorithm::ETCHASH) {
|
||||
// ETChash/Ethash are GPU-only algorithms
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_PROGPOWZ
|
||||
if (m_algorithm.family() == Algorithm::PROGPOWZ) {
|
||||
// ProgPowZ is a GPU-only algorithm
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -325,6 +350,29 @@ void xmrig::CpuWorker<N>::start()
|
|||
break;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_BLAKE3DCR
|
||||
case Algorithm::BLAKE3:
|
||||
// Blake3 hash for each parallel hash slot
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
Blake3DCR::hash(m_job.blob() + (i * job.size()), job.size(), m_hash + (i * 32));
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_ETCHASH
|
||||
case Algorithm::ETCHASH:
|
||||
// ETChash/Ethash CPU mining not supported (GPU-only algorithm)
|
||||
valid = false;
|
||||
break;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_PROGPOWZ
|
||||
case Algorithm::PROGPOWZ:
|
||||
// ProgPowZ CPU mining not supported (GPU-only algorithm)
|
||||
valid = false;
|
||||
break;
|
||||
# endif
|
||||
|
||||
default:
|
||||
fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height());
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,30 @@ xmrig::OclWorker::OclWorker(size_t id, const OclLaunchData &data) :
|
|||
# endif
|
||||
break;
|
||||
|
||||
# ifdef XMRIG_ALGO_ETCHASH
|
||||
case Algorithm::ETCHASH:
|
||||
// ETChash/Ethash GPU support - uses ethash DAG similar to KawPow
|
||||
// TODO: Implement OclEtchashRunner with proper ethash kernel
|
||||
m_runner = nullptr;
|
||||
break;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_PROGPOWZ
|
||||
case Algorithm::PROGPOWZ:
|
||||
// ProgPowZ GPU support - ProgPow variant used by Zano
|
||||
// TODO: Implement OclProgPowZRunner with ProgPowZ kernel
|
||||
m_runner = nullptr;
|
||||
break;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_BLAKE3DCR
|
||||
case Algorithm::BLAKE3:
|
||||
// Blake3 GPU support - fast cryptographic hash for Decred
|
||||
// TODO: Implement OclBlake3Runner
|
||||
m_runner = nullptr;
|
||||
break;
|
||||
# endif
|
||||
|
||||
default:
|
||||
m_runner = new OclCnRunner(id, data);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ static const CoinInfo coinInfo[] = {
|
|||
{ Algorithm::RX_0, "ZEPH", "Zephyr", 120, 1000000000000, BLUE_BG_BOLD( WHITE_BOLD_S " zephyr ") },
|
||||
{ Algorithm::RX_0, "Townforge","Townforge", 30, 100000000, MAGENTA_BG_BOLD(WHITE_BOLD_S " townforge ") },
|
||||
{ Algorithm::RX_YADA, "YDA", "YadaCoin", 120, 100000000, BLUE_BG_BOLD( WHITE_BOLD_S " yada ") },
|
||||
{ Algorithm::ETCHASH_ETC, "ETC", "Ethereum Classic", 13, 1000000000000000000, GREEN_BG_BOLD( WHITE_BOLD_S " etc ") },
|
||||
{ Algorithm::ETHASH_ETH, "ETH", "Ethereum", 12, 1000000000000000000, BLUE_BG_BOLD( WHITE_BOLD_S " eth ") },
|
||||
{ Algorithm::PROGPOWZ_ZANO, "ZANO", "Zano", 60, 1000000000000, CYAN_BG_BOLD( WHITE_BOLD_S " zano ") },
|
||||
{ Algorithm::BLAKE3_DCR, "DCR", "Decred", 300, 100000000, GREEN_BG_BOLD( WHITE_BOLD_S " decred ") },
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ public:
|
|||
ZEPHYR,
|
||||
TOWNFORGE,
|
||||
YADA,
|
||||
ETHEREUM_CLASSIC,
|
||||
ETHEREUM,
|
||||
ZANO,
|
||||
DECRED,
|
||||
MAX
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,15 @@ bool xmrig::AutoClient::parseLogin(const rapidjson::Value &result, int *code)
|
|||
}
|
||||
|
||||
const Algorithm algo(Json::getString(result, "algo"));
|
||||
if (algo.family() != Algorithm::KAWPOW && algo.family() != Algorithm::GHOSTRIDER) {
|
||||
const auto family = algo.family();
|
||||
if (family != Algorithm::KAWPOW && family != Algorithm::GHOSTRIDER
|
||||
# ifdef XMRIG_ALGO_ETCHASH
|
||||
&& family != Algorithm::ETCHASH
|
||||
# endif
|
||||
# ifdef XMRIG_ALGO_PROGPOWZ
|
||||
&& family != Algorithm::PROGPOWZ
|
||||
# endif
|
||||
) {
|
||||
*code = 6;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,6 +161,21 @@ size_t xmrig::Job::nonceOffset() const
|
|||
case Algorithm::GHOSTRIDER:
|
||||
return 76;
|
||||
|
||||
# ifdef XMRIG_ALGO_ETCHASH
|
||||
case Algorithm::ETCHASH:
|
||||
return 32; // ETChash/Ethash uses 32-byte header hash + 8-byte nonce
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_PROGPOWZ
|
||||
case Algorithm::PROGPOWZ:
|
||||
return 32; // ProgPowZ follows same pattern as KawPow/Ethash
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_BLAKE3DCR
|
||||
case Algorithm::BLAKE3:
|
||||
return 140; // Decred block header nonce offset
|
||||
# endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,10 @@ public:
|
|||
inline const String &poolWallet() const { return m_poolWallet; }
|
||||
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + nonceOffset()); }
|
||||
inline const uint8_t *blob() const { return m_blob; }
|
||||
inline size_t nonceSize() const { return (algorithm().family() == Algorithm::KAWPOW) ? 8 : 4; }
|
||||
inline size_t nonceSize() const {
|
||||
const auto family = algorithm().family();
|
||||
return (family == Algorithm::KAWPOW || family == Algorithm::ETCHASH || family == Algorithm::PROGPOWZ) ? 8 : 4;
|
||||
}
|
||||
inline size_t size() const { return m_size; }
|
||||
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + nonceOffset()); }
|
||||
inline uint32_t backend() const { return m_backend; }
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include "base/kernel/Platform.h"
|
||||
#include "base/net/stratum/Client.h"
|
||||
|
||||
#if defined XMRIG_ALGO_KAWPOW || defined XMRIG_ALGO_GHOSTRIDER
|
||||
#if defined XMRIG_ALGO_KAWPOW || defined XMRIG_ALGO_GHOSTRIDER || defined XMRIG_ALGO_ETCHASH || defined XMRIG_ALGO_PROGPOWZ
|
||||
# include "base/net/stratum/AutoClient.h"
|
||||
# include "base/net/stratum/EthStratumClient.h"
|
||||
#endif
|
||||
|
|
@ -226,9 +226,18 @@ xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) con
|
|||
IClient *client = nullptr;
|
||||
|
||||
if (m_mode == MODE_POOL) {
|
||||
# if defined XMRIG_ALGO_KAWPOW || defined XMRIG_ALGO_GHOSTRIDER
|
||||
# if defined XMRIG_ALGO_KAWPOW || defined XMRIG_ALGO_GHOSTRIDER || defined XMRIG_ALGO_ETCHASH || defined XMRIG_ALGO_PROGPOWZ
|
||||
const uint32_t f = m_algorithm.family();
|
||||
if ((f == Algorithm::KAWPOW) || (f == Algorithm::GHOSTRIDER) || (m_coin == Coin::RAVEN)) {
|
||||
const bool isEthStratum = (f == Algorithm::KAWPOW) || (f == Algorithm::GHOSTRIDER) || (f == Algorithm::ETCHASH) || (f == Algorithm::PROGPOWZ)
|
||||
|| (m_coin == Coin::RAVEN)
|
||||
# ifdef XMRIG_ALGO_ETCHASH
|
||||
|| (m_coin == Coin::ETHEREUM_CLASSIC) || (m_coin == Coin::ETHEREUM)
|
||||
# endif
|
||||
# ifdef XMRIG_ALGO_PROGPOWZ
|
||||
|| (m_coin == Coin::ZANO)
|
||||
# endif
|
||||
;
|
||||
if (isEthStratum) {
|
||||
client = new EthStratumClient(id, Platform::userAgent(), listener);
|
||||
}
|
||||
else
|
||||
|
|
@ -245,7 +254,7 @@ xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) con
|
|||
client = new SelfSelectClient(id, Platform::userAgent(), listener, m_submitToOrigin);
|
||||
}
|
||||
# endif
|
||||
# if defined XMRIG_ALGO_KAWPOW || defined XMRIG_ALGO_GHOSTRIDER
|
||||
# if defined XMRIG_ALGO_KAWPOW || defined XMRIG_ALGO_GHOSTRIDER || defined XMRIG_ALGO_ETCHASH || defined XMRIG_ALGO_PROGPOWZ
|
||||
else if (m_mode == MODE_AUTO_ETH) {
|
||||
client = new AutoClient(id, Platform::userAgent(), listener);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,16 +167,20 @@ func (m *XMRigMiner) createConfig(config *Config) error {
|
|||
}
|
||||
|
||||
// Build pools array - CPU pool first
|
||||
pools := []map[string]interface{}{
|
||||
{
|
||||
"url": config.Pool,
|
||||
"user": config.Wallet,
|
||||
"pass": "x",
|
||||
"keepalive": true,
|
||||
"tls": config.TLS,
|
||||
"algo": config.Algo,
|
||||
},
|
||||
cpuPool := map[string]interface{}{
|
||||
"url": config.Pool,
|
||||
"user": config.Wallet,
|
||||
"pass": "x",
|
||||
"keepalive": true,
|
||||
"tls": config.TLS,
|
||||
}
|
||||
// Add algo or coin (coin takes precedence for algorithm auto-detection)
|
||||
if config.Coin != "" {
|
||||
cpuPool["coin"] = config.Coin
|
||||
} else if config.Algo != "" {
|
||||
cpuPool["algo"] = config.Algo
|
||||
}
|
||||
pools := []map[string]interface{}{cpuPool}
|
||||
|
||||
// Add separate GPU pool if configured
|
||||
if config.GPUEnabled && config.GPUPool != "" {
|
||||
|
|
@ -188,20 +192,27 @@ func (m *XMRigMiner) createConfig(config *Config) error {
|
|||
if gpuPass == "" {
|
||||
gpuPass = "x"
|
||||
}
|
||||
pools = append(pools, map[string]interface{}{
|
||||
gpuPool := map[string]interface{}{
|
||||
"url": config.GPUPool,
|
||||
"user": gpuWallet,
|
||||
"pass": gpuPass,
|
||||
"keepalive": true,
|
||||
"algo": config.GPUAlgo,
|
||||
})
|
||||
}
|
||||
// Add GPU algo (typically etchash, ethash, kawpow, progpowz for GPU mining)
|
||||
if config.GPUAlgo != "" {
|
||||
gpuPool["algo"] = config.GPUAlgo
|
||||
}
|
||||
pools = append(pools, gpuPool)
|
||||
}
|
||||
|
||||
// Build OpenCL (AMD/Intel GPU) config
|
||||
// GPU mining requires explicit device selection - no auto-picking
|
||||
openclConfig := map[string]interface{}{
|
||||
"enabled": config.GPUEnabled && config.OpenCL,
|
||||
"enabled": config.GPUEnabled && config.OpenCL && config.Devices != "",
|
||||
}
|
||||
if config.GPUEnabled && config.OpenCL {
|
||||
if config.GPUEnabled && config.OpenCL && config.Devices != "" {
|
||||
// User must explicitly specify devices (e.g., "0" or "0,1")
|
||||
openclConfig["devices"] = config.Devices
|
||||
if config.GPUIntensity > 0 {
|
||||
openclConfig["intensity"] = config.GPUIntensity
|
||||
}
|
||||
|
|
@ -211,10 +222,13 @@ func (m *XMRigMiner) createConfig(config *Config) error {
|
|||
}
|
||||
|
||||
// Build CUDA (NVIDIA GPU) config
|
||||
// GPU mining requires explicit device selection - no auto-picking
|
||||
cudaConfig := map[string]interface{}{
|
||||
"enabled": config.GPUEnabled && config.CUDA,
|
||||
"enabled": config.GPUEnabled && config.CUDA && config.Devices != "",
|
||||
}
|
||||
if config.GPUEnabled && config.CUDA {
|
||||
if config.GPUEnabled && config.CUDA && config.Devices != "" {
|
||||
// User must explicitly specify devices (e.g., "0" or "0,1")
|
||||
cudaConfig["devices"] = config.Devices
|
||||
if config.GPUIntensity > 0 {
|
||||
cudaConfig["intensity"] = config.GPUIntensity
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue