Эх сурвалжийг харах

script/research/powdata: moved into blockchain/monero

skoupidi 1 жил өмнө
parent
commit
ee0b139e45

+ 2 - 0
Cargo.lock

@@ -2070,6 +2070,7 @@ dependencies = [
  "lazy_static",
  "libc",
  "log",
+ "monero",
  "num-bigint",
  "pin-project-lite 0.2.16",
  "plotters",
@@ -2088,6 +2089,7 @@ dependencies = [
  "structopt",
  "structopt-toml",
  "thiserror 2.0.12",
+ "tiny-keccak",
  "tinyjson",
  "toml 0.8.22",
  "tor-cell",

+ 4 - 0
Cargo.toml

@@ -127,6 +127,8 @@ sled-overlay = {version = "0.1.7", optional = true}
 
 # Miner
 randomx = {git = "https://codeberg.org/darkrenaissance/RandomX", optional = true}
+monero = {version = "0.21.0", optional = true}
+tiny-keccak = { version = "2.0.2", features = ["keccak"], optional = true }
 
 [dev-dependencies]
 clap = {version = "4.4.11", features = ["derive"]}
@@ -152,7 +154,9 @@ async-sdk = [
 
 blockchain = [
     "sled-overlay/serial",
+    "monero",
     "num-bigint",
+    "tiny-keccak",
 
     "darkfi-serial/num-bigint",
 

+ 0 - 2
script/research/powdata/.gitignore

@@ -1,2 +0,0 @@
-target/
-Cargo.lock

+ 0 - 15
script/research/powdata/Cargo.toml

@@ -1,15 +0,0 @@
-[package]
-name = "xmrpowdata"
-version = "0.4.1"
-authors = ["Dyne.org foundation <foundation@dyne.org>"]
-license = "AGPL-3.0-only"
-edition = "2021"
-
-[workspace]
-
-[dependencies]
-monero = "0.21.0"
-tiny-keccak = { version = "2.0.2", features = ["keccak"] }
-thiserror = "2.0.12"
-
-darkfi-serial = { path = "../../../src/serial" }

+ 0 - 5
script/research/powdata/src/error.rs

@@ -1,5 +0,0 @@
-#[derive(Debug, thiserror::Error)]
-pub enum MergeMineError {
-    #[error("Hashing of Monero data failed: {0}")]
-    HashingError(String),
-}

+ 3 - 0
src/blockchain/mod.rs

@@ -50,6 +50,9 @@ pub use contract_store::{
     ContractStore, ContractStoreOverlay, SLED_BINCODE_TREE, SLED_CONTRACTS_TREE,
 };
 
+/// Monero definitions needed for merge mining
+pub mod monero;
+
 /// Structure holding all sled trees that define the concept of Blockchain.
 #[derive(Clone)]
 pub struct Blockchain {

+ 107 - 0
src/blockchain/monero/keccak.rs

@@ -0,0 +1,107 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2025 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use std::io::{Cursor, Read, Result, Write};
+
+#[allow(unused_imports)]
+use tiny_keccak::{Hasher, Keccak};
+
+#[repr(C)]
+#[allow(unused)]
+enum Mode {
+    Absorbing,
+    Squeezing,
+}
+
+#[repr(C)]
+// https://docs.rs/tiny-keccak/latest/src/tiny_keccak/lib.rs.html#368
+struct KeccakState {
+    buffer: [u8; 200],
+    offset: usize,
+    rate: usize,
+    delim: u8,
+    mode: Mode,
+}
+
+unsafe fn serialize_keccak<W: Write>(keccak: &Keccak, writer: &mut W) -> Result<()> {
+    let keccak_ptr = keccak as *const Keccak as *const KeccakState;
+    let keccak_state = &*keccak_ptr;
+
+    writer.write_all(&keccak_state.buffer)?;
+    writer.write_all(&(keccak_state.offset as u64).to_le_bytes())?;
+    writer.write_all(&(keccak_state.rate as u64).to_le_bytes())?;
+    writer.write_all(&[keccak_state.delim])?;
+
+    Ok(())
+}
+
+unsafe fn deserialize_keccak<R: Read>(reader: &mut R) -> Result<Keccak> {
+    let mut keccak = Keccak::v256();
+
+    let keccak_ptr = &mut keccak as *mut Keccak as *mut KeccakState;
+    let keccak_state = &mut *keccak_ptr;
+
+    reader.read_exact(&mut keccak_state.buffer)?;
+
+    let mut offset_bytes = [0u8; 8];
+    reader.read_exact(&mut offset_bytes)?;
+    keccak_state.offset = u64::from_le_bytes(offset_bytes) as usize;
+
+    let mut rate_bytes = [0u8; 8];
+    reader.read_exact(&mut rate_bytes)?;
+    keccak_state.rate = u64::from_le_bytes(rate_bytes) as usize;
+
+    let mut delim_byte = [0u8; 1];
+    reader.read_exact(&mut delim_byte)?;
+    keccak_state.delim = delim_byte[0];
+
+    keccak_state.mode = Mode::Absorbing;
+
+    Ok(keccak)
+}
+
+pub fn keccak_to_bytes(keccak: &Keccak) -> Vec<u8> {
+    let mut bytes = vec![];
+    unsafe { serialize_keccak(keccak, &mut bytes).unwrap() }
+    bytes
+}
+
+pub fn keccak_from_bytes(bytes: &[u8]) -> Keccak {
+    let mut cursor = Cursor::new(bytes);
+    unsafe { deserialize_keccak(&mut cursor).unwrap() }
+}
+
+#[test]
+fn test_keccak_serde() {
+    let mut keccak = Keccak::v256();
+    keccak.update(b"foobar");
+
+    let ser = keccak_to_bytes(&keccak);
+
+    let mut digest1 = [0u8; 32];
+    keccak.finalize(&mut digest1);
+
+    let de = keccak_from_bytes(&ser);
+    let mut digest2 = [0u8; 32];
+    de.finalize(&mut digest2);
+
+    println!("{:?}", digest1);
+    println!("{:?}", digest2);
+
+    assert_eq!(digest1, digest2);
+}

+ 156 - 0
src/blockchain/monero/merkle_proof.rs

@@ -0,0 +1,156 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2025 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use std::io::{Error, Read, Result, Write};
+
+use darkfi_serial::{Decodable, Encodable, ReadExt};
+use monero::{
+    consensus::{Decodable as XmrDecodable, Encodable as XmrEncodable},
+    Hash,
+};
+
+use super::utils::cn_fast_hash2;
+
+const MAX_MERKLE_TREE_PROOF_SIZE: usize = 32;
+
+/// The Monero Merkle proof
+#[derive(Debug, Clone)]
+pub struct MerkleProof {
+    branch: Vec<Hash>,
+    path_bitmap: u32,
+}
+
+impl Encodable for MerkleProof {
+    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
+        let mut n = 0;
+
+        let len = self.branch.len() as u8;
+        n += len.encode(s)?;
+
+        for hash in &self.branch {
+            n += (*hash).consensus_encode(s)?;
+        }
+
+        n += self.path_bitmap.encode(s)?;
+
+        Ok(n)
+    }
+}
+
+impl Decodable for MerkleProof {
+    fn decode<D: Read>(d: &mut D) -> Result<Self> {
+        let len: u8 = d.read_u8()?;
+        let mut branch = Vec::with_capacity(len as usize);
+
+        for _ in 0..len {
+            branch.push(Hash::consensus_decode(d).map_err(|_| Error::other("Invalid XMR hash"))?);
+        }
+
+        let path_bitmap: u32 = Decodable::decode(d)?;
+
+        Ok(Self { branch, path_bitmap })
+    }
+}
+
+impl MerkleProof {
+    pub fn try_construct(branch: Vec<Hash>, path_bitmap: u32) -> Option<Self> {
+        if branch.len() >= MAX_MERKLE_TREE_PROOF_SIZE {
+            return None
+        }
+
+        Some(Self { branch, path_bitmap })
+    }
+
+    /// Returns the Merkle proof branch as a list of Monero hashes
+    #[inline]
+    pub fn branch(&self) -> &[Hash] {
+        &self.branch
+    }
+
+    /// Returns the path bitmap of the proof
+    pub fn path(&self) -> u32 {
+        self.path_bitmap
+    }
+
+    /// The coinbase must be the first transaction in the block, so
+    /// that you can't have multiple coinbases in a block. That means
+    /// the coinbase is always the leftmost branch in the Merkle tree.
+    /// This tests that the given proof is for the leftmost branch in
+    /// the Merkle tree.
+    pub fn check_coinbase_path(&self) -> bool {
+        if self.path_bitmap == 0b00000000 {
+            return true;
+        }
+        false
+    }
+
+    /// Calculates the Merkle root hash from the provided Monero hash
+    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(&self, hash: &Hash) -> Hash {
+        if self.branch.is_empty() {
+            return *hash;
+        }
+
+        let mut root = *hash;
+        let depth = self.branch.len();
+        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]);
+            }
+        }
+
+        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
+    }
+}

+ 38 - 98
script/research/powdata/src/lib.rs → src/blockchain/monero/mod.rs

@@ -1,4 +1,22 @@
-use std::io::{self, Read, Write};
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2025 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use std::io::{Error, Read, Result, Write};
 
 use darkfi_serial::{Decodable, Encodable};
 use monero::{
@@ -6,18 +24,24 @@ use monero::{
     consensus::{Decodable as XmrDecodable, Encodable as XmrEncodable},
     cryptonote::hash::Hashable,
     util::ringct::{RctSigBase, RctType},
+    BlockHeader, Hash,
 };
 use tiny_keccak::{Hasher, Keccak};
 
-mod error;
+mod merkle_proof;
+use merkle_proof::MerkleProof;
 
-mod merkle_tree;
-use merkle_tree::MerkleProof;
+mod keccak;
+use keccak::{keccak_from_bytes, keccak_to_bytes};
 
+mod utils;
+
+/// This struct represents all the Proof of Work information required
+/// for merge mining.
 #[derive(Clone)]
 pub struct MoneroPowData {
     /// Monero Header fields
-    pub header: monero::BlockHeader,
+    pub header: BlockHeader,
     /// RandomX VM key - length varies to a max len of 60.
     /// TODO: Implement a type, or use randomx_key[0] to define len.
     pub randomx_key: [u8; 64],
@@ -25,7 +49,7 @@ pub struct MoneroPowData {
     /// This is used to produce the blockhashing_blob.
     pub transaction_count: u16,
     /// Transaction root
-    pub merkle_root: monero::Hash,
+    pub merkle_root: Hash,
     /// Coinbase Merkle proof hashes
     pub coinbase_merkle_proof: MerkleProof,
     /// Incomplete hashed state of the coinbase transaction
@@ -37,7 +61,7 @@ pub struct MoneroPowData {
 }
 
 impl Encodable for MoneroPowData {
-    fn encode<S: Write>(&self, s: &mut S) -> io::Result<usize> {
+    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
         let mut n = 0;
 
         n += self.header.consensus_encode(s)?;
@@ -58,15 +82,15 @@ impl Encodable for MoneroPowData {
 }
 
 impl Decodable for MoneroPowData {
-    fn decode<D: Read>(d: &mut D) -> io::Result<Self> {
-        let header = monero::BlockHeader::consensus_decode(d)
-            .map_err(|_| io::Error::other("Invalid XMR header"))?;
+    fn decode<D: Read>(d: &mut D) -> Result<Self> {
+        let header =
+            BlockHeader::consensus_decode(d).map_err(|_| Error::other("Invalid XMR header"))?;
 
         let randomx_key: [u8; 64] = Decodable::decode(d)?;
         let transaction_count: u16 = Decodable::decode(d)?;
 
         let merkle_root: [u8; 32] = Decodable::decode(d)?;
-        let merkle_root = monero::Hash::from_slice(&merkle_root);
+        let merkle_root = Hash::from_slice(&merkle_root);
 
         let coinbase_merkle_proof: MerkleProof = Decodable::decode(d)?;
 
@@ -101,7 +125,7 @@ impl MoneroPowData {
         let mut prefix_hash: [u8; 32] = [0; 32];
         finalised_prefix_keccak.finalize(&mut prefix_hash);
 
-        let final_prefix_hash = monero::Hash::from_slice(&prefix_hash);
+        let final_prefix_hash = Hash::from_slice(&prefix_hash);
 
         // let mut finalised_keccak = Keccak::v256();
         let rct_sig_base = RctSigBase {
@@ -112,96 +136,12 @@ impl MoneroPowData {
             out_pk: vec![],
         };
 
-        let hashes = vec![final_prefix_hash, rct_sig_base.hash(), monero::Hash::null()];
+        let hashes = vec![final_prefix_hash, rct_sig_base.hash(), Hash::null()];
         let encoder_final: Vec<u8> =
             hashes.into_iter().flat_map(|h| Vec::from(&h.to_bytes()[..])).collect();
-        let coinbase_hash = monero::Hash::new(encoder_final);
+        let coinbase_hash = Hash::new(encoder_final);
 
         let merkle_root = self.coinbase_merkle_proof.calculate_root(&coinbase_hash);
         (self.merkle_root == merkle_root) && self.coinbase_merkle_proof.check_coinbase_path()
     }
 }
-
-#[repr(C)]
-enum Mode {
-    Absorbing,
-    Squeezing,
-}
-
-#[repr(C)]
-// https://docs.rs/tiny-keccak/latest/src/tiny_keccak/lib.rs.html#368
-struct KeccakState {
-    buffer: [u8; 200],
-    offset: usize,
-    rate: usize,
-    delim: u8,
-    mode: Mode,
-}
-
-unsafe fn serialize_keccak<W: Write>(keccak: &Keccak, writer: &mut W) -> io::Result<()> {
-    let keccak_ptr = keccak as *const Keccak as *const KeccakState;
-    let keccak_state = &*keccak_ptr;
-
-    writer.write_all(&keccak_state.buffer)?;
-    writer.write_all(&(keccak_state.offset as u64).to_le_bytes())?;
-    writer.write_all(&(keccak_state.rate as u64).to_le_bytes())?;
-    writer.write_all(&[keccak_state.delim])?;
-
-    Ok(())
-}
-
-unsafe fn deserialize_keccak<R: Read>(reader: &mut R) -> io::Result<Keccak> {
-    let mut keccak = Keccak::v256();
-
-    let keccak_ptr = &mut keccak as *mut Keccak as *mut KeccakState;
-    let keccak_state = &mut *keccak_ptr;
-
-    reader.read_exact(&mut keccak_state.buffer)?;
-
-    let mut offset_bytes = [0u8; 8];
-    reader.read_exact(&mut offset_bytes)?;
-    keccak_state.offset = u64::from_le_bytes(offset_bytes) as usize;
-
-    let mut rate_bytes = [0u8; 8];
-    reader.read_exact(&mut rate_bytes)?;
-    keccak_state.rate = u64::from_le_bytes(rate_bytes) as usize;
-
-    let mut delim_byte = [0u8; 1];
-    reader.read_exact(&mut delim_byte)?;
-    keccak_state.delim = delim_byte[0];
-
-    keccak_state.mode = Mode::Absorbing;
-
-    Ok(keccak)
-}
-
-fn keccak_to_bytes(keccak: &Keccak) -> Vec<u8> {
-    let mut bytes = vec![];
-    unsafe { serialize_keccak(keccak, &mut bytes).unwrap() }
-    bytes
-}
-
-fn keccak_from_bytes(bytes: &[u8]) -> Keccak {
-    let mut cursor = io::Cursor::new(bytes);
-    unsafe { deserialize_keccak(&mut cursor).unwrap() }
-}
-
-#[test]
-fn test_keccak_serde() {
-    let mut keccak = Keccak::v256();
-    keccak.update(b"foobar");
-
-    let ser = keccak_to_bytes(&keccak);
-
-    let mut digest1 = [0u8; 32];
-    keccak.finalize(&mut digest1);
-
-    let de = keccak_from_bytes(&ser);
-    let mut digest2 = [0u8; 32];
-    de.finalize(&mut digest2);
-
-    println!("{:?}", digest1);
-    println!("{:?}", digest2);
-
-    assert_eq!(digest1, digest2);
-}

+ 33 - 147
script/research/powdata/src/merkle_tree.rs → src/blockchain/monero/utils.rs

@@ -1,22 +1,33 @@
-use std::io::{self, Read, Write};
-
-use darkfi_serial::{Decodable, Encodable, ReadExt};
-use monero::{
-    consensus::{Decodable as XmrDecodable, Encodable as XmrEncodable},
-    Hash,
-};
-
-use crate::error::MergeMineError;
-
-const MAX_MERKLE_TREE_PROOF_SIZE: usize = 32;
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2025 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use monero::Hash;
+
+use super::MerkleProof;
+use crate::{Error, Result};
 
 /// Returns the Keccak 256 hash of the byte input
-fn cn_fast_hash(data: &[u8]) -> Hash {
+pub fn cn_fast_hash(data: &[u8]) -> Hash {
     Hash::new(data)
 }
 
 /// Returns the Keccak 256 hash of 2 hashes
-fn cn_fast_hash2(hash1: &Hash, hash2: &Hash) -> Hash {
+pub fn cn_fast_hash2(hash1: &Hash, hash2: &Hash) -> Hash {
     let mut tmp = [0u8; 64];
     tmp[..32].copy_from_slice(hash1.as_bytes());
     tmp[32..].copy_from_slice(hash2.as_bytes());
@@ -26,16 +37,17 @@ fn cn_fast_hash2(hash1: &Hash, hash2: &Hash) -> Hash {
 /// Round down to power of two.
 /// Should error for count < 3 or if the count is unreasonably large
 /// for tree hash calculations.
-fn tree_hash_count(count: usize) -> Result<usize, MergeMineError> {
+#[allow(unused)]
+fn tree_hash_count(count: usize) -> Result<usize> {
     if count < 3 {
-        return Err(MergeMineError::HashingError(format!(
+        return Err(Error::MoneroHashingError(format!(
             "Cannot calculate tree hash root. Expected count to be >3 but got {}",
             count
         )));
     }
 
     if count > 0x10000000 {
-        return Err(MergeMineError::HashingError(format!(
+        return Err(Error::MoneroHashingError(format!(
             "Cannot calculate tree hash root. Expected count to be less than 0x10000000 but got {}",
             count
         )));
@@ -51,9 +63,10 @@ fn tree_hash_count(count: usize) -> Result<usize, MergeMineError> {
 }
 
 /// Tree hash algorithm in Monero
-pub fn tree_hash(hashes: &[Hash]) -> Result<Hash, MergeMineError> {
+#[allow(unused)]
+pub fn tree_hash(hashes: &[Hash]) -> Result<Hash> {
     if hashes.is_empty() {
-        return Err(MergeMineError::HashingError(
+        return Err(Error::MoneroHashingError(
             "Cannot calculate Merkle root, no hashes".to_string(),
         ));
     }
@@ -79,7 +92,7 @@ pub fn tree_hash(hashes: &[Hash]) -> Result<Hash, MergeMineError> {
             }
 
             if i != hashes.len() {
-                return Err(MergeMineError::HashingError(
+                return Err(Error::MoneroHashingError(
                     "Cannot calculate the Merkle root, hashes not equal to count".to_string(),
                 ));
             }
@@ -98,138 +111,11 @@ pub fn tree_hash(hashes: &[Hash]) -> Result<Hash, MergeMineError> {
     }
 }
 
-/// The Monero Merkle proof
-#[derive(Debug, Clone)]
-pub struct MerkleProof {
-    branch: Vec<Hash>,
-    path_bitmap: u32,
-}
-
-impl Encodable for MerkleProof {
-    fn encode<S: Write>(&self, s: &mut S) -> io::Result<usize> {
-        let mut n = 0;
-
-        let len = self.branch.len() as u8;
-        n += len.encode(s)?;
-
-        for hash in &self.branch {
-            n += (*hash).consensus_encode(s)?;
-        }
-
-        n += self.path_bitmap.encode(s)?;
-
-        Ok(n)
-    }
-}
-
-impl Decodable for MerkleProof {
-    fn decode<D: Read>(d: &mut D) -> io::Result<Self> {
-        let len: u8 = d.read_u8()?;
-        let mut branch = Vec::with_capacity(len as usize);
-
-        for _ in 0..len {
-            branch
-                .push(Hash::consensus_decode(d).map_err(|_| io::Error::other("Invalid XMR hash"))?);
-        }
-
-        let path_bitmap: u32 = Decodable::decode(d)?;
-
-        Ok(Self { branch, path_bitmap })
-    }
-}
-
-impl MerkleProof {
-    fn try_construct(branch: Vec<Hash>, path_bitmap: u32) -> Option<Self> {
-        if branch.len() >= MAX_MERKLE_TREE_PROOF_SIZE {
-            return None
-        }
-
-        Some(Self { branch, path_bitmap })
-    }
-
-    /// Returns the Merkle proof branch as a list of Monero hashes
-    #[inline]
-    pub fn branch(&self) -> &[Hash] {
-        &self.branch
-    }
-
-    /// Returns the path bitmap of the proof
-    pub fn path(&self) -> u32 {
-        self.path_bitmap
-    }
-
-    /// The coinbase must be the first transaction in the block, so
-    /// that you can't have multiple coinbases in a block. That means
-    /// the coinbase is always the leftmost branch in the Merkle tree.
-    /// This tests that the given proof is for the leftmost branch in
-    /// the Merkle tree.
-    pub fn check_coinbase_path(&self) -> bool {
-        if self.path_bitmap == 0b00000000 {
-            return true;
-        }
-        false
-    }
-
-    /// Calculates the Merkle root hash from the provided Monero hash
-    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(&self, hash: &Hash) -> Hash {
-        if self.branch.is_empty() {
-            return *hash;
-        }
-
-        let mut root = *hash;
-        let depth = self.branch.len();
-        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]);
-            }
-        }
-
-        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
-    }
-}
-
 /// Creates a Merkle proof for the given hash within the set of hashes.
 /// This function returns None if the hash is not in hashes.
 /// This is a port of Monero's tree_branch function.
 #[allow(clippy::cognitive_complexity)]
+#[allow(unused)]
 pub fn create_merkle_proof(hashes: &[Hash], hash: &Hash) -> Option<MerkleProof> {
     match hashes.len() {
         0 => None,

+ 3 - 0
src/error.rs

@@ -336,6 +336,9 @@ pub enum Error {
     #[error("Contracts states monotree root missmatch: {0} - {1}")]
     ContractsStatesRootError(String, String),
 
+    #[error("Hashing of Monero data failed: {0}")]
+    MoneroHashingError(String),
+
     // ===============
     // Database errors
     // ===============