1
0
mirror of https://github.com/xmrig/xmrig.git synced 2026-02-03 02:23:05 -05:00

Merge pull request #3776 from SChernykh/dev

Sync changes with xmrig-proxy
This commit is contained in:
xmrig
2026-02-02 18:24:25 +07:00
committed by GitHub
6 changed files with 114 additions and 46 deletions

View File

@@ -236,6 +236,10 @@ int64_t xmrig::Client::submit(const JobResult &result)
if (result.commitment()) {
params.AddMember("commitment", StringRef(commitment), allocator);
}
# else
if (result.commitment) {
params.AddMember("commitment", StringRef(result.commitment), allocator);
}
# endif
if (has<EXT_ALGO>() && result.algorithm.isValid()) {

View File

@@ -410,6 +410,7 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
m_blocktemplate.offset(BlockTemplate::TX_EXTRA_NONCE_OFFSET) - k,
m_blocktemplate.txExtraNonce().size(),
m_blocktemplate.minerTxMerkleTreeBranch(),
m_blocktemplate.minerTxMerkleTreePath(),
m_blocktemplate.outputType() == 3
);
# endif

View File

@@ -269,6 +269,7 @@ void xmrig::Job::copy(const Job &other)
m_minerTxExtraNonceOffset = other.m_minerTxExtraNonceOffset;
m_minerTxExtraNonceSize = other.m_minerTxExtraNonceSize;
m_minerTxMerkleTreeBranch = other.m_minerTxMerkleTreeBranch;
m_minerTxMerkleTreePath = other.m_minerTxMerkleTreePath;
m_hasViewTag = other.m_hasViewTag;
# else
memcpy(m_ephPublicKey, other.m_ephPublicKey, sizeof(m_ephPublicKey));
@@ -325,6 +326,7 @@ void xmrig::Job::move(Job &&other)
m_minerTxExtraNonceOffset = other.m_minerTxExtraNonceOffset;
m_minerTxExtraNonceSize = other.m_minerTxExtraNonceSize;
m_minerTxMerkleTreeBranch = std::move(other.m_minerTxMerkleTreeBranch);
m_minerTxMerkleTreePath = other.m_minerTxMerkleTreePath;
m_hasViewTag = other.m_hasViewTag;
# else
memcpy(m_ephPublicKey, other.m_ephPublicKey, sizeof(m_ephPublicKey));
@@ -349,7 +351,7 @@ void xmrig::Job::setSpendSecretKey(const uint8_t *key)
}
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, bool hasViewTag)
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, uint32_t minerTxMerkleTreePath, bool hasViewTag)
{
m_minerTxPrefix.assign(begin, end);
m_minerTxEphPubKeyOffset = minerTxEphPubKeyOffset;
@@ -357,6 +359,7 @@ void xmrig::Job::setMinerTx(const uint8_t *begin, const uint8_t *end, size_t min
m_minerTxExtraNonceOffset = minerTxExtraNonceOffset;
m_minerTxExtraNonceSize = minerTxExtraNonceSize;
m_minerTxMerkleTreeBranch = minerTxMerkleTreeBranch;
m_minerTxMerkleTreePath = minerTxMerkleTreePath;
m_hasViewTag = hasViewTag;
}
@@ -401,7 +404,7 @@ void xmrig::Job::generateHashingBlob(String &blob) const
{
uint8_t root_hash[32];
const uint8_t* p = m_minerTxPrefix.data();
BlockTemplate::calculateRootHash(p, p + m_minerTxPrefix.size(), m_minerTxMerkleTreeBranch, root_hash);
BlockTemplate::calculateRootHash(p, p + m_minerTxPrefix.size(), m_minerTxMerkleTreeBranch, m_minerTxMerkleTreePath, root_hash);
uint64_t root_hash_offset = nonceOffset() + nonceSize();

View File

@@ -121,7 +121,7 @@ public:
inline bool hasViewTag() const { return m_hasViewTag; }
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, bool hasViewTag);
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, uint32_t minerTxMerkleTreePath, bool hasViewTag);
void setViewTagInMinerTx(uint8_t view_tag);
void setExtraNonceInMinerTx(uint32_t extra_nonce);
void generateSignatureData(String& signatureData, uint8_t& view_tag) const;
@@ -179,6 +179,7 @@ private:
size_t m_minerTxExtraNonceOffset = 0;
size_t m_minerTxExtraNonceSize = 0;
Buffer m_minerTxMerkleTreeBranch;
uint32_t m_minerTxMerkleTreePath = 0;
bool m_hasViewTag = false;
# else
// Miner signatures

View File

@@ -48,69 +48,98 @@ void xmrig::BlockTemplate::calculateMinerTxHash(const uint8_t *prefix_begin, con
}
void xmrig::BlockTemplate::calculateRootHash(const uint8_t *prefix_begin, const uint8_t *prefix_end, const Buffer &miner_tx_merkle_tree_branch, uint8_t *root_hash)
void xmrig::BlockTemplate::calculateRootHash(const uint8_t *prefix_begin, const uint8_t *prefix_end, const Buffer &miner_tx_merkle_tree_branch, uint32_t miner_tx_merkle_tree_path, uint8_t *root_hash)
{
calculateMinerTxHash(prefix_begin, prefix_end, root_hash);
for (size_t i = 0; i < miner_tx_merkle_tree_branch.size(); i += kHashSize) {
const size_t depth = miner_tx_merkle_tree_branch.size() / kHashSize;
for (size_t d = 0; d < depth; ++d) {
uint8_t h[kHashSize * 2];
memcpy(h, root_hash, kHashSize);
memcpy(h + kHashSize, miner_tx_merkle_tree_branch.data() + i, kHashSize);
const uint32_t t = (miner_tx_merkle_tree_path >> (depth - d - 1)) & 1;
memcpy(h + kHashSize * t, root_hash, kHashSize);
memcpy(h + kHashSize * (t ^ 1), miner_tx_merkle_tree_branch.data() + d * kHashSize, kHashSize);
keccak(h, kHashSize * 2, root_hash, kHashSize);
}
}
void xmrig::BlockTemplate::calculateMerkleTreeHash()
void xmrig::BlockTemplate::calculateMerkleTreeHash(uint32_t index)
{
m_minerTxMerkleTreeBranch.clear();
m_minerTxMerkleTreePath = 0;
const uint64_t count = m_numHashes + 1;
const size_t count = m_hashes.size() / kHashSize;
const uint8_t *h = m_hashes.data();
if (count == 1) {
if (count == 1) {
memcpy(m_rootHash, h, kHashSize);
}
else if (count == 2) {
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), h + kHashSize, h + kHashSize * 2);
}
else if (count == 2) {
keccak(h, kHashSize * 2, m_rootHash, kHashSize);
}
else {
size_t i = 0;
size_t j = 0;
size_t cnt = 0;
for (i = 0, cnt = 1; cnt <= count; ++i, cnt <<= 1) {}
m_minerTxMerkleTreeBranch.reserve(1);
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), h + kHashSize * (index ^ 1), h + kHashSize * ((index ^ 1) + 1));
m_minerTxMerkleTreePath = static_cast<uint32_t>(index);
}
else {
uint8_t h2[kHashSize];
memcpy(h2, h + kHashSize * index, kHashSize);
cnt >>= 1;
size_t cnt = 1, proof_max_size = 0;
do {
cnt <<= 1;
++proof_max_size;
} while (cnt <= count);
cnt >>= 1;
m_minerTxMerkleTreeBranch.reserve(kHashSize * (i - 1));
m_minerTxMerkleTreeBranch.reserve(proof_max_size);
Buffer ints(cnt * kHashSize);
memcpy(ints.data(), h, (cnt * 2 - count) * kHashSize);
for (i = cnt * 2 - count, j = cnt * 2 - count; j < cnt; i += 2, ++j) {
if (i == 0) {
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), h + kHashSize, h + kHashSize * 2);
}
keccak(h + i * kHashSize, kHashSize * 2, ints.data() + j * kHashSize, kHashSize);
}
const size_t k = cnt * 2 - count;
memcpy(ints.data(), h, k * kHashSize);
while (cnt > 2) {
cnt >>= 1;
for (i = 0, j = 0; j < cnt; i += 2, ++j) {
if (i == 0) {
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), ints.data() + kHashSize, ints.data() + kHashSize * 2);
}
keccak(ints.data() + i * kHashSize, kHashSize * 2, ints.data() + j * kHashSize, kHashSize);
}
}
for (size_t i = k, j = k; j < cnt; i += 2, ++j) {
keccak(h + i * kHashSize, kHashSize * 2, ints.data() + j * kHashSize, kHashSize);
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), ints.data() + kHashSize, ints.data() + kHashSize * 2);
keccak(ints.data(), kHashSize * 2, m_rootHash, kHashSize);
}
if (memcmp(h + i * kHashSize, h2, kHashSize) == 0) {
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), h + kHashSize * (i + 1), h + kHashSize * (i + 2));
memcpy(h2, ints.data() + j * kHashSize, kHashSize);
}
else if (memcmp(h + (i + 1) * kHashSize, h2, kHashSize) == 0) {
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), h + kHashSize * i, h + kHashSize * (i + 1));
memcpy(h2, ints.data() + j * kHashSize, kHashSize);
m_minerTxMerkleTreePath = 1;
}
}
while (cnt >= 2) {
cnt >>= 1;
for (size_t i = 0, j = 0; j < cnt; i += 2, ++j) {
uint8_t tmp[kHashSize];
keccak(ints.data() + i * kHashSize, kHashSize * 2, tmp, kHashSize);
if (memcmp(ints.data() + i * kHashSize, h2, kHashSize) == 0) {
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), ints.data() + kHashSize * (i + 1), ints.data() + kHashSize * (i + 2));
memcpy(h2, tmp, kHashSize);
m_minerTxMerkleTreePath <<= 1;
}
else if (memcmp(ints.data() + (i + 1) * kHashSize, h2, kHashSize) == 0) {
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), ints.data() + kHashSize * i, ints.data() + kHashSize * (i + 1));
memcpy(h2, tmp, kHashSize);
m_minerTxMerkleTreePath = (m_minerTxMerkleTreePath << 1) | 1;
}
memcpy(ints.data() + j * kHashSize, tmp, kHashSize);
}
}
memcpy(m_rootHash, ints.data(), kHashSize);
}
}
@@ -375,16 +404,42 @@ bool xmrig::BlockTemplate::parse(bool hashes)
ar(m_numHashes);
if (hashes) {
m_hashes.resize((m_numHashes + 1) * kHashSize);
calculateMinerTxHash(blob(MINER_TX_PREFIX_OFFSET), blob(MINER_TX_PREFIX_END_OFFSET), m_hashes.data());
// FCMP++ layout:
//
// index 0 fcmp_pp_n_tree_layers + 31 zero bytes
// index 1 fcmp_pp_tree_root
// index 2 coinbase transaction hash
// index 3+ other transaction hashes
//
// pre-FCMP++ layout:
//
// index 0 coinbase transaction hash
// index 1+ other transaction hashes
//
const uint32_t coinbase_tx_index = is_fcmp_pp ? 2 : 0;
m_hashes.clear();
m_hashes.resize((coinbase_tx_index + m_numHashes + 1) * kHashSize);
uint8_t* data = m_hashes.data() + coinbase_tx_index * kHashSize;
calculateMinerTxHash(blob(MINER_TX_PREFIX_OFFSET), blob(MINER_TX_PREFIX_END_OFFSET), data);
for (uint64_t i = 1; i <= m_numHashes; ++i) {
Span h;
ar(h, kHashSize);
memcpy(m_hashes.data() + i * kHashSize, h.data(), kHashSize);
memcpy(data + i * kHashSize, h.data(), kHashSize);
}
calculateMerkleTreeHash();
if (is_fcmp_pp) {
ar(m_FCMPTreeLayers);
ar(m_FCMPTreeRoot);
m_hashes[0] = m_FCMPTreeLayers;
memcpy(m_hashes.data() + kHashSize, m_FCMPTreeRoot, kHashSize);
}
calculateMerkleTreeHash(coinbase_tx_index);
}
return true;

View File

@@ -93,6 +93,7 @@ public:
inline uint64_t numHashes() const { return m_numHashes; }
inline const Buffer &hashes() const { return m_hashes; }
inline const Buffer &minerTxMerkleTreeBranch() const { return m_minerTxMerkleTreeBranch; }
inline uint32_t minerTxMerkleTreePath() const { return m_minerTxMerkleTreePath; }
inline const uint8_t *rootHash() const { return m_rootHash; }
inline Buffer generateHashingBlob() const
@@ -104,13 +105,13 @@ public:
}
static void calculateMinerTxHash(const uint8_t *prefix_begin, const uint8_t *prefix_end, uint8_t *hash);
static void calculateRootHash(const uint8_t *prefix_begin, const uint8_t *prefix_end, const Buffer &miner_tx_merkle_tree_branch, uint8_t *root_hash);
static void calculateRootHash(const uint8_t *prefix_begin, const uint8_t *prefix_end, const Buffer &miner_tx_merkle_tree_branch, uint32_t miner_tx_merkle_tree_path, uint8_t *root_hash);
bool parse(const Buffer &blocktemplate, const Coin &coin, bool hashes = kCalcHashes);
bool parse(const char *blocktemplate, size_t size, const Coin &coin, bool hashes);
bool parse(const rapidjson::Value &blocktemplate, const Coin &coin, bool hashes = kCalcHashes);
bool parse(const String &blocktemplate, const Coin &coin, bool hashes = kCalcHashes);
void calculateMerkleTreeHash();
void calculateMerkleTreeHash(uint32_t index);
void generateHashingBlob(Buffer &out) const;
private:
@@ -147,9 +148,12 @@ private:
uint64_t m_numHashes = 0;
Buffer m_hashes;
Buffer m_minerTxMerkleTreeBranch;
uint32_t m_minerTxMerkleTreePath = 0;
uint8_t m_rootHash[kHashSize]{};
uint8_t m_carrotViewTag[3]{};
uint8_t m_janusAnchor[16]{};
uint8_t m_FCMPTreeLayers = 0;
uint8_t m_FCMPTreeRoot[kHashSize]{};
};