Skip to content

Commit

Permalink
Added path bitmap to get_merkle_proof
Browse files Browse the repository at this point in the history
  • Loading branch information
SChernykh committed May 10, 2024
1 parent e986e5d commit c53036b
Show file tree
Hide file tree
Showing 13 changed files with 49 additions and 15 deletions.
8 changes: 4 additions & 4 deletions src/block_template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1303,14 +1303,14 @@ std::vector<AuxChainData> BlockTemplate::get_aux_chains(const uint32_t template_
return m_poolBlockTemplate->m_auxChains;
}

bool BlockTemplate::get_aux_proof(const uint32_t template_id, uint32_t extra_nonce, const hash& h, std::vector<hash>& proof) const
bool BlockTemplate::get_aux_proof(const uint32_t template_id, uint32_t extra_nonce, const hash& h, std::vector<hash>& proof, uint32_t& path) 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_aux_proof(template_id, extra_nonce, h, proof);
return old->get_aux_proof(template_id, extra_nonce, h, proof, path);
}

return false;
Expand Down Expand Up @@ -1346,7 +1346,7 @@ bool BlockTemplate::get_aux_proof(const uint32_t template_id, uint32_t extra_non
std::vector<std::vector<hash>> tree;
merkle_hash_full_tree(hashes, tree);

return get_merkle_proof(tree, h, proof);
return get_merkle_proof(tree, h, proof, path);
}

std::vector<uint8_t> 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
Expand Down Expand Up @@ -1489,7 +1489,7 @@ void BlockTemplate::init_merge_mining_merkle_proof()
std::vector<std::vector<hash>> tree;
merkle_hash_full_tree(hashes, tree);

get_merkle_proof(tree, m_poolBlockTemplate->m_sidechainId, m_poolBlockTemplate->m_merkleProof);
get_merkle_proof(tree, m_poolBlockTemplate->m_sidechainId, m_poolBlockTemplate->m_merkleProof, m_poolBlockTemplate->m_merkleProofPath);
}

} // namespace p2pool
2 changes: 1 addition & 1 deletion src/block_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class BlockTemplate
uint32_t get_hashing_blobs(uint32_t extra_nonce_start, uint32_t count, std::vector<uint8_t>& blobs, uint64_t& height, difficulty_type& difficulty, difficulty_type& aux_diff, difficulty_type& sidechain_difficulty, hash& seed_hash, size_t& nonce_offset, uint32_t& template_id) const;

std::vector<AuxChainData> 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<hash>& proof) const;
bool get_aux_proof(const uint32_t template_id, uint32_t extra_nonce, const hash& h, std::vector<hash>& proof, uint32_t& path) const;

std::vector<uint8_t> 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;

Expand Down
2 changes: 1 addition & 1 deletion src/merge_mining_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class IMergeMiningClient
virtual ~IMergeMiningClient() {}

[[nodiscard]] virtual bool get_params(ChainParameters& out_params) const = 0;
virtual void submit_solution(const BlockTemplate* block_tpl, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof) = 0;
virtual void submit_solution(const BlockTemplate* block_tpl, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof, uint32_t merkle_proof_path) = 0;
};

} // namespace p2pool
2 changes: 1 addition & 1 deletion src/merge_mining_client_json_rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ bool MergeMiningClientJSON_RPC::parse_merge_mining_get_job(const char* data, siz
return true;
}

void MergeMiningClientJSON_RPC::submit_solution(const BlockTemplate* /*block_tpl*/, const uint8_t (&/*hashing_blob*/)[128], size_t /*nonce_offset*/, const hash& /*seed_hash*/, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof)
void MergeMiningClientJSON_RPC::submit_solution(const BlockTemplate* /*block_tpl*/, const uint8_t (&/*hashing_blob*/)[128], size_t /*nonce_offset*/, const hash& /*seed_hash*/, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof, uint32_t /*merkle_proof_path*/)
{
ReadLock lock(m_lock);

Expand Down
2 changes: 1 addition & 1 deletion src/merge_mining_client_json_rpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class MergeMiningClientJSON_RPC : public IMergeMiningClient
~MergeMiningClientJSON_RPC() override;

bool get_params(ChainParameters& out_params) const override;
void submit_solution(const BlockTemplate* block_tpl, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof) override;
void submit_solution(const BlockTemplate* block_tpl, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof, uint32_t merkle_proof_path) override;

private:
static void loop(void* data);
Expand Down
2 changes: 1 addition & 1 deletion src/merge_mining_client_tari.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ bool MergeMiningClientTari::get_params(ChainParameters& out_params) const
return true;
}

void MergeMiningClientTari::submit_solution(const BlockTemplate* block_tpl, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& /*merkle_proof*/)
void MergeMiningClientTari::submit_solution(const BlockTemplate* block_tpl, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& /*merkle_proof*/, uint32_t /*merkle_proof_path*/)
{
Block block;
{
Expand Down
2 changes: 1 addition & 1 deletion src/merge_mining_client_tari.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 BlockTemplate* block_tpl, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof) override;
void submit_solution(const BlockTemplate* block_tpl, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof, uint32_t merkle_proof_path) override;

static constexpr char TARI_PREFIX[] = "tari://";

Expand Down
26 changes: 25 additions & 1 deletion src/merkle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void merkle_hash_full_tree(const std::vector<hash>& hashes, std::vector<std::vec
}
}

bool get_merkle_proof(const std::vector<std::vector<hash>>& tree, const hash& h, std::vector<hash>& proof)
bool get_merkle_proof(const std::vector<std::vector<hash>>& tree, const hash& h, std::vector<hash>& proof, uint32_t& path)
{
if (tree.empty()) {
return false;
Expand All @@ -137,12 +137,14 @@ bool get_merkle_proof(const std::vector<std::vector<hash>>& tree, const hash& h,
}

proof.clear();
path = 0;

if (count == 1) {
return true;
}
else if (count == 2) {
proof.emplace_back(hashes[index ^ 1]);
path = index & 1;
}
else {
size_t cnt = 1;
Expand All @@ -158,6 +160,7 @@ bool get_merkle_proof(const std::vector<std::vector<hash>>& tree, const hash& h,
return false;
}
proof.emplace_back(hashes[j]);
path = index & 1;
index = (index >> 1) + k;
}

Expand All @@ -169,6 +172,7 @@ bool get_merkle_proof(const std::vector<std::vector<hash>>& tree, const hash& h,
return false;
}
proof.emplace_back(tree[i][j]);
path = (static_cast<uint64_t>(path) << 1) | (index & 1);
}
}

Expand Down Expand Up @@ -260,6 +264,26 @@ bool verify_merkle_proof(hash h, const std::vector<hash>& proof, size_t index, s
return get_root_from_proof(h, proof, index, count) == root;
}

bool verify_merkle_proof(hash h, const std::vector<hash>& proof, uint32_t path, const root_hash& root)
{
for (size_t d = 0, depth = proof.size(); d < depth; ++d) {
hash tmp[2];

if ((path >> (depth - d - 1)) & 1) {
tmp[0] = proof[d];
tmp[1] = h;
}
else {
tmp[0] = h;
tmp[1] = proof[d];
}

keccak(tmp[0].h, HASH_SIZE * 2, h.h);
}

return h == root;
}

uint32_t get_aux_slot(const hash &id, uint32_t nonce, uint32_t n_aux_chains)
{
if (n_aux_chains <= 1) {
Expand Down
4 changes: 3 additions & 1 deletion src/merkle.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ namespace p2pool {
void merkle_hash(const std::vector<hash>& hashes, root_hash& root);
void merkle_hash_full_tree(const std::vector<hash>& hashes, std::vector<std::vector<hash>>& tree);

bool get_merkle_proof(const std::vector<std::vector<hash>>& tree, const hash& h, std::vector<hash>& proof);
bool get_merkle_proof(const std::vector<std::vector<hash>>& tree, const hash& h, std::vector<hash>& proof, uint32_t& path);

root_hash get_root_from_proof(hash h, const std::vector<hash>& proof, size_t index, size_t count);

bool verify_merkle_proof(hash h, const std::vector<hash>& proof, size_t index, size_t count, const root_hash& root);
bool verify_merkle_proof(hash h, const std::vector<hash>& proof, uint32_t path, const root_hash& root);

uint32_t get_aux_slot(const hash &id, uint32_t nonce, uint32_t n_aux_chains);
bool find_aux_nonce(const std::vector<hash>& aux_id, uint32_t& nonce, uint32_t max_nonce = 0xFFFF);
Expand Down
5 changes: 3 additions & 2 deletions src/p2pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,9 @@ void p2pool::submit_aux_block(const hash& chain_id, uint32_t template_id, uint32

if (chain_id == params.aux_id) {
std::vector<hash> proof;
uint32_t path;

if (m_blockTemplate->get_aux_proof(template_id, extra_nonce, params.aux_hash, proof)) {
if (m_blockTemplate->get_aux_proof(template_id, extra_nonce, params.aux_hash, proof, path)) {
if (pool_block_debug()) {
const MinerData data = miner_data();
const uint32_t n_aux_chains = static_cast<uint32_t>(data.aux_chains.size() + 1);
Expand All @@ -679,7 +680,7 @@ void p2pool::submit_aux_block(const hash& chain_id, uint32_t template_id, uint32
}
}

c->submit_solution(block_tpl, hashing_blob, nonce_offset, seed_hash, blob, proof);
c->submit_solution(block_tpl, hashing_blob, nonce_offset, seed_hash, blob, proof, path);
}
else {
LOGWARN(3, "submit_aux_block: failed to get merkle proof for chain_id " << chain_id);
Expand Down
3 changes: 3 additions & 0 deletions src/pool_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ PoolBlock::PoolBlock()
, m_sidechainHeight(0)
, m_difficulty{}
, m_cumulativeDifficulty{}
, m_merkleProof{}
, m_merkleProofPath(0)
, m_sidechainExtraBuf{}
, m_sidechainId{}
, m_depth(0)
Expand Down Expand Up @@ -102,6 +104,7 @@ PoolBlock& PoolBlock::operator=(const PoolBlock& b)
m_difficulty = b.m_difficulty;
m_cumulativeDifficulty = b.m_cumulativeDifficulty;
m_merkleProof = b.m_merkleProof;
m_merkleProofPath = b.m_merkleProofPath;
memcpy(m_sidechainExtraBuf, b.m_sidechainExtraBuf, sizeof(m_sidechainExtraBuf));
m_sidechainId = b.m_sidechainId;
m_depth = b.m_depth;
Expand Down
1 change: 1 addition & 0 deletions src/pool_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ struct PoolBlock

// Merkle proof for merge mining
std::vector<hash> m_merkleProof;
uint32_t m_merkleProofPath;

// Arbitrary extra data
uint32_t m_sidechainExtraBuf[4];
Expand Down
5 changes: 4 additions & 1 deletion tests/src/merkle_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "keccak.h"
#include "merkle.h"
#include "pool_block.h"
#include "keccak.h"
#include "gtest/gtest.h"

namespace p2pool {
Expand Down Expand Up @@ -74,9 +75,11 @@ TEST(merkle, tree)
for (size_t i = 0, n = hashes.size(); i < n; ++i) {
const hash& h = hashes[i];
std::vector<hash> proof;
uint32_t path;

ASSERT_TRUE(get_merkle_proof(tree, h, proof));
ASSERT_TRUE(get_merkle_proof(tree, h, proof, path));
ASSERT_TRUE(verify_merkle_proof(h, proof, i, n, root));
ASSERT_TRUE(verify_merkle_proof(h, proof, path, root));
}
};

Expand Down

0 comments on commit c53036b

Please sign in to comment.