From b78ab0f60b5f7bbcc7d9133771ac1f8a43fab02e Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 1 Jun 2018 18:46:10 -0400 Subject: [PATCH] Expose merkleroot(Vec) publicly In a project of mine I needed to check the merkle root before moving some Vecs around, so need to be able to calculate the merkle root on a Vec directly. --- src/util/hash.rs | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/util/hash.rs b/src/util/hash.rs index 03b5bb80..ec73a859 100644 --- a/src/util/hash.rs +++ b/src/util/hash.rs @@ -419,29 +419,31 @@ pub trait MerkleRoot { fn merkle_root(&self) -> Sha256dHash; } +/// Calculates the merkle root of a list of txids hashes directly +pub fn bitcoin_merkle_root(data: Vec) -> Sha256dHash { + // Base case + if data.len() < 1 { + return Default::default(); + } + if data.len() < 2 { + return data[0]; + } + // Recursion + let mut next = vec![]; + for idx in 0..((data.len() + 1) / 2) { + let idx1 = 2 * idx; + let idx2 = min(idx1 + 1, data.len() - 1); + let mut encoder = RawEncoder::new(Cursor::new(vec![])); + data[idx1].consensus_encode(&mut encoder).unwrap(); + data[idx2].consensus_encode(&mut encoder).unwrap(); + next.push(encoder.into_inner().into_inner().bitcoin_hash()); + } + bitcoin_merkle_root(next) +} + impl<'a, T: BitcoinHash> MerkleRoot for &'a [T] { fn merkle_root(&self) -> Sha256dHash { - fn merkle_root(data: Vec) -> Sha256dHash { - // Base case - if data.len() < 1 { - return Default::default(); - } - if data.len() < 2 { - return data[0]; - } - // Recursion - let mut next = vec![]; - for idx in 0..((data.len() + 1) / 2) { - let idx1 = 2 * idx; - let idx2 = min(idx1 + 1, data.len() - 1); - let mut encoder = RawEncoder::new(Cursor::new(vec![])); - data[idx1].consensus_encode(&mut encoder).unwrap(); - data[idx2].consensus_encode(&mut encoder).unwrap(); - next.push(encoder.into_inner().into_inner().bitcoin_hash()); - } - merkle_root(next) - } - merkle_root(self.iter().map(|obj| obj.bitcoin_hash()).collect()) + bitcoin_merkle_root(self.iter().map(|obj| obj.bitcoin_hash()).collect()) } }