From a30ede04f36a3b54d9fcdae654bf21d72222e37f Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 5 Jul 2021 13:56:37 +0200 Subject: [PATCH] Updates from xmrig-proxy --- src/base/net/stratum/Client.cpp | 15 ++-- src/base/net/stratum/Client.h | 4 +- src/base/net/stratum/DaemonClient.cpp | 29 +++++--- src/base/net/stratum/DaemonClient.h | 1 + src/base/net/stratum/Job.cpp | 81 ++++++++++++++++----- src/base/net/stratum/Job.h | 27 ++++--- src/base/tools/cryptonote/BlobReader.h | 2 + src/base/tools/cryptonote/BlockTemplate.cpp | 30 +++++++- src/base/tools/cryptonote/BlockTemplate.h | 2 + 9 files changed, 139 insertions(+), 52 deletions(-) diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 1871b6df0..95e1d8d05 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2019 jtgrassie - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright 2018-2021 SChernykh + * Copyright 2016-2021 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -225,6 +225,10 @@ int64_t xmrig::Client::submit(const JobResult &result) if (result.minerSignature()) { params.AddMember("sig", StringRef(signature), allocator); } +# else + if (result.sig) { + params.AddMember("sig", StringRef(result.sig), allocator); + } # endif if (has() && result.algorithm.isValid()) { @@ -440,12 +444,7 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } -# ifndef XMRIG_PROXY_PROJECT - uint8_t signatureKeyBuf[32 * 2]; - if (Cvt::fromHex(signatureKeyBuf, sizeof(signatureKeyBuf), Json::getValue(params, "sig_key"))) { - job.setEphemeralKeys(signatureKeyBuf, signatureKeyBuf + 32); - } -# endif + job.setSigKey(Json::getString(params, "sig_key")); m_job.setClientId(m_rpcId); diff --git a/src/base/net/stratum/Client.h b/src/base/net/stratum/Client.h index fdaac9f15..d9164b8a3 100644 --- a/src/base/net/stratum/Client.h +++ b/src/base/net/stratum/Client.h @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2019 jtgrassie - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright 2018-2021 SChernykh + * Copyright 2016-2021 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 43493e752..c1d3d3a41 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -96,7 +96,7 @@ bool xmrig::DaemonClient::isTLS() const int64_t xmrig::DaemonClient::submit(const JobResult &result) { - if (result.jobId != (m_blocktemplateStr.data() + m_blocktemplateStr.size() - 32)) { + if (result.jobId != m_currentJobId) { return -1; } @@ -114,6 +114,10 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result) memcpy(data + m_blocktemplate.eph_public_key_index * 2, result.sig_data + 32 * 2, 32 * 2); } + if (result.extra_nonce >= 0) { + Cvt::toHex(data + m_blocktemplate.tx_extra_nonce_index * 2, 8, reinterpret_cast(&result.extra_nonce), 4); + } + # else Cvt::toHex(data + m_job.nonceOffset() * 2, 8, reinterpret_cast(&result.nonce), 4); @@ -277,6 +281,19 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code) return false; } +# ifdef XMRIG_PROXY_PROJECT + const size_t k = m_blocktemplate.miner_tx_prefix_begin_index; + job.setMinerTx( + m_blocktemplate.raw_blob.data() + k, + m_blocktemplate.raw_blob.data() + m_blocktemplate.miner_tx_prefix_end_index, + m_blocktemplate.eph_public_key_index - k, + m_blocktemplate.tx_pubkey_index - k, + m_blocktemplate.tx_extra_nonce_index - k, + m_blocktemplate.tx_extra_nonce_size, + m_blocktemplate.miner_tx_merkle_tree_branch + ); +# endif + m_blockhashingblob = Json::getString(params, "blockhashing_blob"); if (m_blocktemplate.has_miner_signature) { @@ -308,13 +325,6 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code) # ifdef XMRIG_PROXY_PROJECT job.setSpendSecretKey(secret_spendkey); - job.setMinerTx( - m_blocktemplate.raw_blob.data() + m_blocktemplate.miner_tx_prefix_begin_index, - m_blocktemplate.raw_blob.data() + m_blocktemplate.miner_tx_prefix_end_index, - m_blocktemplate.eph_public_key_index - m_blocktemplate.miner_tx_prefix_begin_index, - m_blocktemplate.tx_pubkey_index - m_blocktemplate.miner_tx_prefix_begin_index, - m_blocktemplate.miner_tx_merkle_tree_branch - ); # else uint8_t secret_viewkey[32]; derive_view_secret_key(secret_spendkey, secret_viewkey); @@ -377,7 +387,8 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code) job.setHeight(Json::getUint64(params, kHeight)); job.setDiff(Json::getUint64(params, "difficulty")); - job.setId(blocktemplate.data() + blocktemplate.size() - 32); + m_currentJobId = Cvt::toHex(Cvt::randomBytes(4)); + job.setId(m_currentJobId); m_job = std::move(job); m_blocktemplateStr = std::move(blocktemplate); diff --git a/src/base/net/stratum/DaemonClient.h b/src/base/net/stratum/DaemonClient.h index 45a844646..f701240e5 100644 --- a/src/base/net/stratum/DaemonClient.h +++ b/src/base/net/stratum/DaemonClient.h @@ -84,6 +84,7 @@ private: } m_apiVersion = API_MONERO; std::shared_ptr m_httpListener; + String m_currentJobId; String m_blocktemplateStr; String m_blockhashingblob; String m_prevHash; diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index c92f6f015..920bf95f7 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -7,8 +7,8 @@ * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett * Copyright 2019 Howard Chu - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright 2018-2021 SChernykh + * Copyright 2016-2021 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -144,6 +144,25 @@ void xmrig::Job::setDiff(uint64_t diff) } +void xmrig::Job::setSigKey(const char *sig_key) +{ + constexpr const size_t size = 64; + + if (!sig_key || strlen(sig_key) != size * 2) { + return; + } + +# ifndef XMRIG_PROXY_PROJECT + const auto buf = Cvt::fromHex(sig_key, size * 2); + if (buf.size() == size) { + setEphemeralKeys(buf.data(), buf.data() + 32); + } +# else + m_rawSigKey = sig_key; +# endif +} + + void xmrig::Job::copy(const Job &other) { m_algorithm = other.m_algorithm; @@ -164,6 +183,7 @@ void xmrig::Job::copy(const Job &other) # ifdef XMRIG_PROXY_PROJECT m_rawSeedHash = other.m_rawSeedHash; + m_rawSigKey = other.m_rawSigKey; memcpy(m_rawBlob, other.m_rawBlob, sizeof(m_rawBlob)); memcpy(m_rawTarget, other.m_rawTarget, sizeof(m_rawTarget)); @@ -181,6 +201,8 @@ void xmrig::Job::copy(const Job &other) m_minerTxPrefix = other.m_minerTxPrefix; m_minerTxEphPubKeyOffset = other.m_minerTxEphPubKeyOffset; m_minerTxPubKeyOffset = other.m_minerTxPubKeyOffset; + m_minerTxExtraNonceOffset = other.m_minerTxExtraNonceOffset; + m_minerTxExtraNonceSize = other.m_minerTxExtraNonceSize; m_minerTxMerkleTreeBranch = other.m_minerTxMerkleTreeBranch; # else memcpy(m_ephPublicKey, other.m_ephPublicKey, sizeof(m_ephPublicKey)); @@ -215,6 +237,7 @@ void xmrig::Job::move(Job &&other) # ifdef XMRIG_PROXY_PROJECT m_rawSeedHash = std::move(other.m_rawSeedHash); + m_rawSigKey = std::move(other.m_rawSigKey); memcpy(m_rawBlob, other.m_rawBlob, sizeof(m_rawBlob)); memcpy(m_rawTarget, other.m_rawTarget, sizeof(m_rawTarget)); @@ -229,10 +252,13 @@ void xmrig::Job::move(Job &&other) memcpy(m_viewSecretKey, other.m_viewSecretKey, sizeof(m_viewSecretKey)); memcpy(m_spendPublicKey, other.m_spendPublicKey, sizeof(m_spendPublicKey)); memcpy(m_viewPublicKey, other.m_viewPublicKey, sizeof(m_viewPublicKey)); - m_minerTxPrefix = std::move(other.m_minerTxPrefix); - m_minerTxEphPubKeyOffset = other.m_minerTxEphPubKeyOffset; - m_minerTxPubKeyOffset = other.m_minerTxPubKeyOffset; - m_minerTxMerkleTreeBranch = std::move(other.m_minerTxMerkleTreeBranch); + + m_minerTxPrefix = std::move(other.m_minerTxPrefix); + m_minerTxEphPubKeyOffset = other.m_minerTxEphPubKeyOffset; + m_minerTxPubKeyOffset = other.m_minerTxPubKeyOffset; + m_minerTxExtraNonceOffset = other.m_minerTxExtraNonceOffset; + m_minerTxExtraNonceSize = other.m_minerTxExtraNonceSize; + m_minerTxMerkleTreeBranch = std::move(other.m_minerTxMerkleTreeBranch); # else memcpy(m_ephPublicKey, other.m_ephPublicKey, sizeof(m_ephPublicKey)); memcpy(m_ephSecretKey, other.m_ephSecretKey, sizeof(m_ephSecretKey)); @@ -245,26 +271,35 @@ void xmrig::Job::move(Job &&other) #ifdef XMRIG_PROXY_PROJECT -void xmrig::Job::setSpendSecretKey(uint8_t* key) +void xmrig::Job::setSpendSecretKey(const uint8_t *key) { m_hasMinerSignature = true; memcpy(m_spendSecretKey, key, sizeof(m_spendSecretKey)); - xmrig::derive_view_secret_key(m_spendSecretKey, m_viewSecretKey); - xmrig::secret_key_to_public_key(m_spendSecretKey, m_spendPublicKey); - xmrig::secret_key_to_public_key(m_viewSecretKey, m_viewPublicKey); + + derive_view_secret_key(m_spendSecretKey, m_viewSecretKey); + secret_key_to_public_key(m_spendSecretKey, m_spendPublicKey); + secret_key_to_public_key(m_viewSecretKey, m_viewPublicKey); } -void xmrig::Job::setMinerTx(const uint8_t* begin, const uint8_t* end, size_t minerTxEphPubKeyOffset, size_t minerTxPubKeyOffset, const Buffer& minerTxMerkleTreeBranch) +void xmrig::Job::setMinerTx(const uint8_t *begin, const uint8_t *end, size_t minerTxEphPubKeyOffset, size_t minerTxPubKeyOffset, size_t minerTxExtraNonceOffset, size_t minerTxExtraNonceSize, const Buffer &minerTxMerkleTreeBranch) { m_minerTxPrefix.assign(begin, end); - m_minerTxEphPubKeyOffset = minerTxEphPubKeyOffset; - m_minerTxPubKeyOffset = minerTxPubKeyOffset; - m_minerTxMerkleTreeBranch = minerTxMerkleTreeBranch; + m_minerTxEphPubKeyOffset = minerTxEphPubKeyOffset; + m_minerTxPubKeyOffset = minerTxPubKeyOffset; + m_minerTxExtraNonceOffset = minerTxExtraNonceOffset; + m_minerTxExtraNonceSize = minerTxExtraNonceSize; + m_minerTxMerkleTreeBranch = minerTxMerkleTreeBranch; } -void xmrig::Job::generateHashingBlob(String& blob, String& signatureData) const +void xmrig::Job::setExtraNonceInMinerTx(uint32_t extra_nonce) +{ + memcpy(m_minerTxPrefix.data() + m_minerTxExtraNonceOffset, &extra_nonce, std::min(m_minerTxExtraNonceSize, sizeof(uint32_t))); +} + + +void xmrig::Job::generateSignatureData(String &signatureData) const { uint8_t* eph_public_key = m_minerTxPrefix.data() + m_minerTxEphPubKeyOffset; uint8_t* txkey_pub = m_minerTxPrefix.data() + m_minerTxPubKeyOffset; @@ -285,15 +320,23 @@ void xmrig::Job::generateHashingBlob(String& blob, String& signatureData) const generate_key_derivation(txkey_pub, m_viewSecretKey, derivation); derive_secret_key(derivation, 0, m_spendSecretKey, buf + 64); - signatureData = xmrig::Cvt::toHex(buf, sizeof(buf)); + signatureData = Cvt::toHex(buf, sizeof(buf)); +} +void xmrig::Job::generateHashingBlob(String &blob) const +{ uint8_t root_hash[32]; const uint8_t* p = m_minerTxPrefix.data(); - xmrig::BlockTemplate::CalculateRootHash(p, p + m_minerTxPrefix.size(), m_minerTxMerkleTreeBranch, root_hash); + BlockTemplate::CalculateRootHash(p, p + m_minerTxPrefix.size(), m_minerTxMerkleTreeBranch, root_hash); + + uint64_t root_hash_offset = nonceOffset() + nonceSize(); + + if (m_hasMinerSignature) { + root_hash_offset += BlockTemplate::SIGNATURE_SIZE + 2 /* vote */; + } blob = rawBlob(); - const uint64_t offset = nonceOffset() + nonceSize() + BlockTemplate::SIGNATURE_SIZE + 2 /* vote */; - xmrig::Cvt::toHex(blob.data() + offset * 2, 64, root_hash, 32); + Cvt::toHex(blob.data() + root_hash_offset * 2, 64, root_hash, BlockTemplate::HASH_SIZE); } diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index 85b01e789..c72902756 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -7,8 +7,8 @@ * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett * Copyright 2019 Howard Chu - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright 2018-2021 SChernykh + * Copyright 2016-2021 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -63,6 +63,7 @@ public: bool setSeedHash(const char *hash); bool setTarget(const char *target); void setDiff(uint64_t diff); + void setSigKey(const char *sig_key); inline bool isNicehash() const { return m_nicehash; } inline bool isValid() const { return (m_size > 0 && m_diff > 0) || !m_poolWallet.isEmpty(); } @@ -102,6 +103,7 @@ public: inline const char *rawBlob() const { return m_rawBlob; } inline const char *rawTarget() const { return m_rawTarget; } inline const String &rawSeedHash() const { return m_rawSeedHash; } + inline const String &rawSigKey() const { return m_rawSigKey; } # endif static inline uint64_t toDiff(uint64_t target) { return target ? (0xFFFFFFFFFFFFFFFFULL / target) : 0; } @@ -117,13 +119,15 @@ public: # endif # ifdef XMRIG_PROXY_PROJECT - void setSpendSecretKey(uint8_t* key); - void setMinerTx(const uint8_t* begin, const uint8_t* end, size_t minerTxEphPubKeyOffset, size_t minerTxPubKeyOffset, const Buffer& minerTxMerkleTreeBranch); - void generateHashingBlob(String& blob, String& signatureData) const; + void setSpendSecretKey(const uint8_t* key); + void setMinerTx(const uint8_t* begin, const uint8_t* end, size_t minerTxEphPubKeyOffset, size_t minerTxPubKeyOffset, size_t minerTxExtraNonceOffset, size_t minerTxExtraNonceSize, const Buffer& minerTxMerkleTreeBranch); + void setExtraNonceInMinerTx(uint32_t extra_nonce); + void generateSignatureData(String& signatureData) const; + void generateHashingBlob(String& blob) const; # else inline const uint8_t* ephSecretKey() const { return m_hasMinerSignature ? m_ephSecretKey : nullptr; } - inline void setEphemeralKeys(uint8_t* pub_key, uint8_t* sec_key) + inline void setEphemeralKeys(const uint8_t *pub_key, const uint8_t *sec_key) { m_hasMinerSignature = true; memcpy(m_ephPublicKey, pub_key, sizeof(m_ephSecretKey)); @@ -158,15 +162,18 @@ private: char m_rawBlob[kMaxBlobSize * 2 + 8]{}; char m_rawTarget[24]{}; String m_rawSeedHash; + String m_rawSigKey; // Miner signatures - uint8_t m_spendSecretKey[32]; - uint8_t m_viewSecretKey[32]; - uint8_t m_spendPublicKey[32]; - uint8_t m_viewPublicKey[32]; + uint8_t m_spendSecretKey[32]{}; + uint8_t m_viewSecretKey[32]{}; + uint8_t m_spendPublicKey[32]{}; + uint8_t m_viewPublicKey[32]{}; mutable Buffer m_minerTxPrefix; size_t m_minerTxEphPubKeyOffset = 0; size_t m_minerTxPubKeyOffset = 0; + size_t m_minerTxExtraNonceOffset = 0; + size_t m_minerTxExtraNonceSize = 0; Buffer m_minerTxMerkleTreeBranch; # else // Miner signatures diff --git a/src/base/tools/cryptonote/BlobReader.h b/src/base/tools/cryptonote/BlobReader.h index 58f81e2dd..f10bcd88b 100644 --- a/src/base/tools/cryptonote/BlobReader.h +++ b/src/base/tools/cryptonote/BlobReader.h @@ -61,6 +61,8 @@ public: inline size_t index() const { return m_index; } + inline void skip(size_t N) { m_index += N; } + private: inline bool getByte(uint8_t& data) { diff --git a/src/base/tools/cryptonote/BlockTemplate.cpp b/src/base/tools/cryptonote/BlockTemplate.cpp index 0b54c3998..5449ec23c 100644 --- a/src/base/tools/cryptonote/BlockTemplate.cpp +++ b/src/base/tools/cryptonote/BlockTemplate.cpp @@ -86,13 +86,35 @@ bool BlockTemplate::Init(const String& blockTemplate, Coin coin) ar(eph_public_key); ar(extra_size); - tx_pubkey_index = ar.index() + 1; + const uint64_t tx_extra_index = ar.index(); ar.readItems(extra, extra_size); - // First thing in tx_extra must be TX_EXTRA_TAG_PUBKEY - if (extra[0] != 0x01) - return false; + CBlobReader ar_extra(extra.data(), extra_size); + + tx_extra_nonce_size = 0; + tx_extra_nonce_index = 0; + + while (ar_extra.index() < extra_size) { + uint64_t extra_tag; + ar_extra(extra_tag); + + switch (extra_tag) { + case 0x01: // TX_EXTRA_TAG_PUBKEY + tx_pubkey_index = tx_extra_index + ar_extra.index(); + ar_extra.skip(KEY_SIZE); + break; + + case 0x02: // TX_EXTRA_NONCE + ar_extra(tx_extra_nonce_size); + tx_extra_nonce_index = tx_extra_index + ar_extra.index(); + ar_extra.skip(tx_extra_nonce_size); + break; + + default: + return false; // TODO: handle other tags + } + } miner_tx_prefix_end_index = ar.index(); // Prefix end diff --git a/src/base/tools/cryptonote/BlockTemplate.h b/src/base/tools/cryptonote/BlockTemplate.h index e80ece141..4a6ef8051 100644 --- a/src/base/tools/cryptonote/BlockTemplate.h +++ b/src/base/tools/cryptonote/BlockTemplate.h @@ -42,6 +42,8 @@ struct BlockTemplate Buffer raw_blob; size_t eph_public_key_index; size_t tx_pubkey_index; + uint64_t tx_extra_nonce_size; + size_t tx_extra_nonce_index; size_t miner_tx_prefix_begin_index; size_t miner_tx_prefix_end_index;