Skip to content

Commit

Permalink
fix!: change position calculation in MTparams for mergemining (#6339)
Browse files Browse the repository at this point in the history
Description
---
Changes the way we calculate the position of the hash from the Merkle
tree params

Motivation and Context
---
Its possible to have the same proof for different sized merkle trees.
Verification needs to verify the total size from the decoded merkle tree
params


What process can a PR reviewer use to test or verify this change?
---
Ensure it's the same as here:
https://github.com/SChernykh/p2pool/blob/2c549f61a46a5f4f0be7c631dff6e928f73a52e2/src/merkle.cpp#L341-L369
  • Loading branch information
SWvheerden committed May 20, 2024
1 parent 34db82d commit 1d6e0d8
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 11 deletions.
4 changes: 3 additions & 1 deletion base_layer/core/src/proof_of_work/monero_rx/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ fn check_aux_chains(
)
.low_u32() %
u32::from(merkle_tree_params.number_of_chains());
let (merkle_root, pos) = monero_data.aux_chain_merkle_proof.calculate_root_with_pos(&t_hash);
let (merkle_root, pos) = monero_data
.aux_chain_merkle_proof
.calculate_root_with_pos(&t_hash, merkle_tree_params.number_of_chains());
if hash_position != pos {
return false;
}
Expand Down
47 changes: 37 additions & 10 deletions base_layer/core/src/proof_of_work/monero_rx/merkle_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,31 +196,58 @@ impl MerkleProof {
}

/// Calculates the merkle root hash from the provide Monero hash
pub fn calculate_root(&self, hash: &Hash) -> Hash {
self.calculate_root_with_pos(hash).0
pub fn calculate_root_with_pos(&self, hash: &Hash, aux_chain_count: u8) -> (Hash, u32) {
let root = self.calculate_root(hash);
let pos = self.get_position_from_path(u32::from(aux_chain_count));
(root, pos)
}

pub fn calculate_root_with_pos(&self, hash: &Hash) -> (Hash, u32) {
pub fn calculate_root(&self, hash: &Hash) -> Hash {
if self.branch.is_empty() {
return (*hash, 0);
return *hash;
}

let mut root = *hash;
let depth = self.branch.len();
let mut pos = 0;
let mut multiplier = 1;
for d in 0..depth {
if (self.path_bitmap >> (depth - d - 1)) & 1 > 0 {
root = cn_fast_hash2(&self.branch[d], &root);
} else {
root = cn_fast_hash2(&root, &self.branch[d]);
pos += multiplier;
}
// this cant overflow as the max depth is 32, and 2^32 == u32::MAX
multiplier *= 2;
}

(root, pos)
root
}

pub fn get_position_from_path(&self, aux_chain_count: u32) -> u32 {
if aux_chain_count <= 1 {
return 0;
}

let mut depth = 0;
let mut k = 1;

while k < aux_chain_count {
depth += 1;
k <<= 1;
}

k -= aux_chain_count;

let mut pos = 0;
let mut path = self.path_bitmap;

for _i in 1..depth {
pos = (pos << 1) | (path & 1);
path >>= 1;
}

if pos < k {
return pos;
}

(((pos - k) << 1) | (path & 1)) + k
}
}

Expand Down

0 comments on commit 1d6e0d8

Please sign in to comment.