2014-07-18 13:56:17 +00:00
|
|
|
// Rust Bitcoin Library
|
|
|
|
// Written in 2014 by
|
2015-04-07 22:51:57 +00:00
|
|
|
// Andrew Poelstra <apoelstra@wpsoftware.net>
|
2014-07-18 13:56:17 +00:00
|
|
|
// To the extent possible under law, the author(s) have dedicated all
|
|
|
|
// copyright and related and neighboring rights to this software to
|
|
|
|
// the public domain worldwide. This software is distributed without
|
|
|
|
// any warranty.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the CC0 Public Domain Dedication
|
|
|
|
// along with this software.
|
|
|
|
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
|
|
|
//
|
|
|
|
|
2018-08-08 21:38:50 +00:00
|
|
|
//! Hash functions
|
2014-07-18 13:56:17 +00:00
|
|
|
//!
|
|
|
|
//! Utility functions related to hashing data, including merkleization
|
|
|
|
|
2015-04-05 17:58:49 +00:00
|
|
|
use std::cmp::min;
|
2014-07-20 23:52:00 +00:00
|
|
|
use std::default::Default;
|
2014-07-18 13:56:17 +00:00
|
|
|
|
2019-12-06 09:01:15 +00:00
|
|
|
use hashes::Hash;
|
2019-12-18 11:00:18 +00:00
|
|
|
use hash_types::{Txid, TxidType, TxMerkleRoot};
|
2014-07-18 13:56:17 +00:00
|
|
|
|
2015-11-30 15:19:53 +00:00
|
|
|
|
2014-07-19 23:03:45 +00:00
|
|
|
/// Any collection of objects for which a merkle root makes sense to calculate
|
2019-12-06 09:01:15 +00:00
|
|
|
pub trait MerkleRooted {
|
2015-04-07 22:51:57 +00:00
|
|
|
/// Construct a merkle tree from a collection, with elements ordered as
|
|
|
|
/// they were in the original collection, and return the merkle root.
|
2019-12-06 09:01:15 +00:00
|
|
|
fn merkle_root(&self) -> TxMerkleRoot;
|
2014-07-19 23:03:45 +00:00
|
|
|
}
|
|
|
|
|
2018-06-01 22:46:10 +00:00
|
|
|
/// Calculates the merkle root of a list of txids hashes directly
|
2019-12-18 11:00:18 +00:00
|
|
|
pub fn bitcoin_merkle_root<T: TxidType>(data: Vec<T>) -> TxMerkleRoot {
|
2018-06-01 22:46:10 +00:00
|
|
|
// Base case
|
|
|
|
if data.len() < 1 {
|
|
|
|
return Default::default();
|
|
|
|
}
|
|
|
|
if data.len() < 2 {
|
2019-12-06 09:01:15 +00:00
|
|
|
return TxMerkleRoot::from_inner(data[0].into_inner());
|
2018-06-01 22:46:10 +00:00
|
|
|
}
|
|
|
|
// 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);
|
2019-12-06 09:01:15 +00:00
|
|
|
let mut encoder = TxMerkleRoot::engine();
|
2018-06-01 22:46:10 +00:00
|
|
|
data[idx1].consensus_encode(&mut encoder).unwrap();
|
|
|
|
data[idx2].consensus_encode(&mut encoder).unwrap();
|
2019-11-30 16:26:52 +00:00
|
|
|
next.push(Txid::from_engine(encoder));
|
2018-06-01 22:46:10 +00:00
|
|
|
}
|
|
|
|
bitcoin_merkle_root(next)
|
|
|
|
}
|
|
|
|
|
2018-09-03 05:41:08 +00:00
|
|
|
/// Objects which are referred to by hash
|
2019-11-30 16:26:52 +00:00
|
|
|
pub trait BitcoinHash<T: Hash> {
|
2018-09-03 05:41:08 +00:00
|
|
|
/// Produces a Sha256dHash which can be used to refer to the object
|
2019-11-30 16:26:52 +00:00
|
|
|
fn bitcoin_hash(&self) -> T;
|
2018-09-03 05:41:08 +00:00
|
|
|
}
|