From fd953a0b26016556d986c6bc3f2e15e91c5c9715 Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Thu, 9 May 2024 20:35:41 +0200 Subject: [PATCH] Tari: serialize `pow_data` WIP --- src/block_template.cpp | 7 +++++-- src/block_template.h | 2 +- src/merge_mining_client.h | 3 ++- src/merge_mining_client_json_rpc.cpp | 2 +- src/merge_mining_client_json_rpc.h | 2 +- src/merge_mining_client_tari.cpp | 31 ++++++++++++++++++++++++---- src/merge_mining_client_tari.h | 2 +- src/p2pool.cpp | 16 +++++++++++--- src/pool_block_parser.inl | 4 ++-- src/util.h | 10 ++++++++- 10 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/block_template.cpp b/src/block_template.cpp index 0882b1d8..49d29579 100644 --- a/src/block_template.cpp +++ b/src/block_template.cpp @@ -1349,14 +1349,14 @@ bool BlockTemplate::get_aux_proof(const uint32_t template_id, uint32_t extra_non return get_merkle_proof(tree, h, proof); } -std::vector BlockTemplate::get_block_template_blob(uint32_t template_id, uint32_t sidechain_extra_nonce, size_t& nonce_offset, size_t& extra_nonce_offset, size_t& merkle_root_offset, hash& merge_mining_root) const +std::vector BlockTemplate::get_block_template_blob(uint32_t template_id, uint32_t sidechain_extra_nonce, size_t& nonce_offset, size_t& extra_nonce_offset, size_t& merkle_root_offset, hash& merge_mining_root, const BlockTemplate** pThis) const { ReadLock lock(m_lock); if (template_id != m_templateId) { const BlockTemplate* old = m_oldTemplates[template_id % array_size(&BlockTemplate::m_oldTemplates)]; if (old && (template_id == old->m_templateId)) { - return old->get_block_template_blob(template_id, sidechain_extra_nonce, nonce_offset, extra_nonce_offset, merkle_root_offset, merge_mining_root); + return old->get_block_template_blob(template_id, sidechain_extra_nonce, nonce_offset, extra_nonce_offset, merkle_root_offset, merge_mining_root, pThis); } nonce_offset = 0; @@ -1375,6 +1375,9 @@ std::vector BlockTemplate::get_block_template_blob(uint32_t template_id merge_mining_root = get_root_from_proof(sidechain_id, m_poolBlockTemplate->m_merkleProof, aux_slot, n_aux_chains); merkle_root_offset = m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize; + + *pThis = this; + return m_blockTemplateBlob; } diff --git a/src/block_template.h b/src/block_template.h index c4989a2d..4c6427d9 100644 --- a/src/block_template.h +++ b/src/block_template.h @@ -51,7 +51,7 @@ class BlockTemplate std::vector get_aux_chains(const uint32_t template_id) const; bool get_aux_proof(const uint32_t template_id, uint32_t extra_nonce, const hash& h, std::vector& proof) const; - std::vector get_block_template_blob(uint32_t template_id, uint32_t sidechain_extra_nonce, size_t& nonce_offset, size_t& extra_nonce_offset, size_t& merkle_root_offset, hash& merge_mining_root) const; + std::vector get_block_template_blob(uint32_t template_id, uint32_t sidechain_extra_nonce, size_t& nonce_offset, size_t& extra_nonce_offset, size_t& merkle_root_offset, hash& merge_mining_root, const BlockTemplate** pThis) const; FORCEINLINE uint64_t height() const { return m_height; } FORCEINLINE difficulty_type difficulty() const { return m_difficulty; } diff --git a/src/merge_mining_client.h b/src/merge_mining_client.h index 26e3bc95..a8277e54 100644 --- a/src/merge_mining_client.h +++ b/src/merge_mining_client.h @@ -20,6 +20,7 @@ namespace p2pool { class p2pool; +class BlockTemplate; class IMergeMiningClient { @@ -37,7 +38,7 @@ class IMergeMiningClient virtual ~IMergeMiningClient() {} [[nodiscard]] virtual bool get_params(ChainParameters& out_params) const = 0; - virtual void submit_solution(const std::vector& blob, const std::vector& merkle_proof) = 0; + virtual void submit_solution(const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector& blob, const std::vector& merkle_proof) = 0; }; } // namespace p2pool diff --git a/src/merge_mining_client_json_rpc.cpp b/src/merge_mining_client_json_rpc.cpp index a4c5368e..85f7ad6a 100644 --- a/src/merge_mining_client_json_rpc.cpp +++ b/src/merge_mining_client_json_rpc.cpp @@ -283,7 +283,7 @@ bool MergeMiningClientJSON_RPC::parse_merge_mining_get_job(const char* data, siz return true; } -void MergeMiningClientJSON_RPC::submit_solution(const std::vector& blob, const std::vector& merkle_proof) +void MergeMiningClientJSON_RPC::submit_solution(const uint8_t (&/*hashing_blob*/)[128], size_t /*nonce_offset*/, const hash& /*seed_hash*/, const std::vector& blob, const std::vector& merkle_proof) { ReadLock lock(m_lock); diff --git a/src/merge_mining_client_json_rpc.h b/src/merge_mining_client_json_rpc.h index cbe4351d..486e3710 100644 --- a/src/merge_mining_client_json_rpc.h +++ b/src/merge_mining_client_json_rpc.h @@ -30,7 +30,7 @@ class MergeMiningClientJSON_RPC : public IMergeMiningClient ~MergeMiningClientJSON_RPC() override; bool get_params(ChainParameters& out_params) const override; - void submit_solution(const std::vector& blob, const std::vector& merkle_proof) override; + void submit_solution(const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector& blob, const std::vector& merkle_proof) override; private: static void loop(void* data); diff --git a/src/merge_mining_client_tari.cpp b/src/merge_mining_client_tari.cpp index bb915b06..9e4dffcb 100644 --- a/src/merge_mining_client_tari.cpp +++ b/src/merge_mining_client_tari.cpp @@ -20,6 +20,7 @@ #include "merge_mining_client_tari.h" #include "p2pool.h" #include "params.h" +#include "block_template.h" LOG_CATEGORY(MergeMiningClientTari) @@ -124,7 +125,7 @@ bool MergeMiningClientTari::get_params(ChainParameters& out_params) const return true; } -void MergeMiningClientTari::submit_solution(const std::vector& /*blob*/, const std::vector& /*merkle_proof*/) +void MergeMiningClientTari::submit_solution(const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector& /*blob*/, const std::vector& /*merkle_proof*/) { Block block; { @@ -135,9 +136,31 @@ void MergeMiningClientTari::submit_solution(const std::vector& /*blob*/ ProofOfWork* pow = block.mutable_header()->mutable_pow(); pow->set_pow_algo(PowAlgo_PowAlgos_POW_ALGOS_RANDOMX); - // TODO fill in the data - std::string data; - pow->set_pow_data(data); + { + std::string data; + + // Monero header + nonce + data.append(reinterpret_cast(hashing_blob), nonce_offset + sizeof(uint32_t)); + + // Monero seed + data.append(1, HASH_SIZE); + data.append(reinterpret_cast(seed_hash.h), HASH_SIZE); + + uint64_t transaction_count; + if (!readVarint(hashing_blob + nonce_offset + sizeof(uint32_t) + HASH_SIZE, hashing_blob + 128, transaction_count)) { + return; + } + + // Total number of transactions in this block (including the miner tx) + data.append(reinterpret_cast(&transaction_count), 2); + + // Tx Merkle tree root + data.append(reinterpret_cast(hashing_blob + nonce_offset + sizeof(uint32_t)), HASH_SIZE); + + // TODO: serialize coinbase_merkle_proof, coinbase_tx_extra, coinbase_tx_hasher, aux_chain_merkle_proof + + pow->set_pow_data(data); + } grpc::ClientContext ctx; SubmitBlockResponse response; diff --git a/src/merge_mining_client_tari.h b/src/merge_mining_client_tari.h index d484be2f..8d2600b3 100644 --- a/src/merge_mining_client_tari.h +++ b/src/merge_mining_client_tari.h @@ -31,7 +31,7 @@ class MergeMiningClientTari : public IMergeMiningClient, public nocopy_nomove ~MergeMiningClientTari() override; bool get_params(ChainParameters& out_params) const override; - void submit_solution(const std::vector& blob, const std::vector& merkle_proof) override; + void submit_solution(const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector& blob, const std::vector& merkle_proof) override; static constexpr char TARI_PREFIX[] = "tari://"; diff --git a/src/p2pool.cpp b/src/p2pool.cpp index 29df7c37..706f90e1 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -635,8 +635,16 @@ void p2pool::submit_aux_block(const hash& chain_id, uint32_t template_id, uint32 size_t extra_nonce_offset = 0; size_t merkle_root_offset = 0; root_hash merge_mining_root; + const BlockTemplate* block_template = nullptr; - std::vector blob = m_blockTemplate->get_block_template_blob(template_id, extra_nonce, nonce_offset, extra_nonce_offset, merkle_root_offset, merge_mining_root); + std::vector blob = m_blockTemplate->get_block_template_blob(template_id, extra_nonce, nonce_offset, extra_nonce_offset, merkle_root_offset, merge_mining_root, &block_template); + + uint8_t hashing_blob[128] = {}; + uint64_t height = 0; + difficulty_type diff, aux_diff, sidechain_diff; + hash seed_hash; + + m_blockTemplate->get_hashing_blob(template_id, extra_nonce, hashing_blob, height, diff, aux_diff, sidechain_diff, seed_hash, nonce_offset); if (blob.empty()) { LOGWARN(3, "submit_aux_block: block template blob not found"); @@ -671,7 +679,7 @@ void p2pool::submit_aux_block(const hash& chain_id, uint32_t template_id, uint32 } } - c->submit_solution(blob, proof); + c->submit_solution(hashing_blob, nonce_offset, seed_hash, blob, proof); } else { LOGWARN(3, "submit_aux_block: failed to get merkle proof for chain_id " << chain_id); @@ -721,10 +729,12 @@ void p2pool::submit_block() const size_t extra_nonce_offset = 0; size_t merkle_root_offset = 0; hash merge_mining_root; + const BlockTemplate* block_template = nullptr; + bool is_external = false; if (submit_data.blob.empty()) { - submit_data.blob = m_blockTemplate->get_block_template_blob(submit_data.template_id, submit_data.extra_nonce, nonce_offset, extra_nonce_offset, merkle_root_offset, merge_mining_root); + submit_data.blob = m_blockTemplate->get_block_template_blob(submit_data.template_id, submit_data.extra_nonce, nonce_offset, extra_nonce_offset, merkle_root_offset, merge_mining_root, &block_template); LOGINFO(0, log::LightGreen() << "submit_block: height = " << height << ", template id = " << submit_data.template_id diff --git a/src/pool_block_parser.inl b/src/pool_block_parser.inl index 29eee72d..12d0afc9 100644 --- a/src/pool_block_parser.inl +++ b/src/pool_block_parser.inl @@ -61,10 +61,10 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si #define READ_BUF(buf, size) do { if (!read_buf((buf), (size))) return __LINE__; } while(0) - READ_BYTE(m_majorVersion); + READ_VARINT(m_majorVersion); if (m_majorVersion > HARDFORK_SUPPORTED_VERSION) return __LINE__; - READ_BYTE(m_minorVersion); + READ_VARINT(m_minorVersion); if (m_minorVersion < m_majorVersion) return __LINE__; READ_VARINT(m_timestamp); diff --git a/src/util.h b/src/util.h index b5b2400f..915edee8 100644 --- a/src/util.h +++ b/src/util.h @@ -167,10 +167,18 @@ const uint8_t* readVarint(const uint8_t* data, const uint8_t* data_end, T& b) const uint64_t cur_byte = *(data++); result |= (cur_byte & 0x7F) << k; + + if (shiftleft128(cur_byte & 0x7F, 0, k) != 0) { + return nullptr; + } + k += 7; if ((cur_byte & 0x80) == 0) { - b = result; + if (result > std::numeric_limits::max()) { + return nullptr; + } + b = static_cast(result); return data; } }