Merge rust-bitcoin/rust-bitcoin#1394: Format the `merkle_tree` module
f55c4099d5
Format the merkle_tree module (Tobin C. Harding) Pull request description: Run `cargo +nightly fmt` and commit the changes to the `merkle_tree` module. No manual changes, only those introduced by `rustfmt`. ACKs for top commit: tcharding: ACKf55c4099d5
apoelstra: ACKf55c4099d5
Tree-SHA512: 2f47fc426988b4755408fea5f8c4c47ebe23b53850737a1640fa9477cfd83f0ada046aec734986a92a9effbaaee0f34764ef87d82deff1a594f7b73bf2e93e93
This commit is contained in:
commit
7d6aa83389
|
@ -42,18 +42,15 @@
|
|||
|
||||
use core::fmt;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::io;
|
||||
|
||||
use crate::hashes::Hash;
|
||||
use crate::hash_types::{Txid, TxMerkleNode};
|
||||
|
||||
use crate::blockdata::block::{self, Block};
|
||||
use crate::blockdata::transaction::Transaction;
|
||||
use crate::blockdata::constants::{MAX_BLOCK_WEIGHT, MIN_TRANSACTION_WEIGHT};
|
||||
use crate::blockdata::transaction::Transaction;
|
||||
use crate::consensus::encode::{self, Decodable, Encodable};
|
||||
use crate::hash_types::{TxMerkleNode, Txid};
|
||||
use crate::hashes::Hash;
|
||||
use crate::io;
|
||||
use crate::merkle_tree::MerkleBlockError::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
/// An error when verifying the merkle block.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
|
@ -139,19 +136,13 @@ pub struct PartialMerkleTree {
|
|||
|
||||
impl PartialMerkleTree {
|
||||
/// Returns the total number of transactions in the block.
|
||||
pub fn num_transactions(&self) -> u32 {
|
||||
self.num_transactions
|
||||
}
|
||||
pub fn num_transactions(&self) -> u32 { self.num_transactions }
|
||||
|
||||
/// Returns the node-is-parent-of-matched-txid bits of the partial merkle tree.
|
||||
pub fn bits(&self) -> &Vec<bool> {
|
||||
&self.bits
|
||||
}
|
||||
pub fn bits(&self) -> &Vec<bool> { &self.bits }
|
||||
|
||||
/// Returns the transaction ids and internal hashes of the partial merkle tree.
|
||||
pub fn hashes(&self) -> &Vec<TxMerkleNode> {
|
||||
&self.hashes
|
||||
}
|
||||
pub fn hashes(&self) -> &Vec<TxMerkleNode> { &self.hashes }
|
||||
|
||||
/// Construct a partial merkle tree
|
||||
/// The `txids` are the transaction hashes of the block and the `matches` is the contains flags
|
||||
|
@ -372,8 +363,7 @@ impl PartialMerkleTree {
|
|||
|
||||
impl Encodable for PartialMerkleTree {
|
||||
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
||||
let ret = self.num_transactions.consensus_encode(w)?
|
||||
+ self.hashes.consensus_encode(w)?;
|
||||
let ret = self.num_transactions.consensus_encode(w)? + self.hashes.consensus_encode(w)?;
|
||||
let mut bytes: Vec<u8> = vec![0; (self.bits.len() + 7) / 8];
|
||||
for p in 0..self.bits.len() {
|
||||
bytes[p / 8] |= (self.bits[p] as u8) << (p % 8) as u8;
|
||||
|
@ -393,11 +383,7 @@ impl Decodable for PartialMerkleTree {
|
|||
for (p, bit) in bits.iter_mut().enumerate() {
|
||||
*bit = (bytes[p / 8] & (1 << (p % 8) as u8)) != 0;
|
||||
}
|
||||
Ok(PartialMerkleTree {
|
||||
num_transactions,
|
||||
hashes,
|
||||
bits,
|
||||
})
|
||||
Ok(PartialMerkleTree { num_transactions, hashes, bits })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,7 +439,7 @@ impl MerkleBlock {
|
|||
/// ```
|
||||
pub fn from_block_with_predicate<F>(block: &Block, match_txids: F) -> Self
|
||||
where
|
||||
F: Fn(&Txid) -> bool
|
||||
F: Fn(&Txid) -> bool,
|
||||
{
|
||||
let block_txids: Vec<_> = block.txdata.iter().map(Transaction::txid).collect();
|
||||
Self::from_header_txids_with_predicate(&block.header, &block_txids, match_txids)
|
||||
|
@ -469,18 +455,12 @@ impl MerkleBlock {
|
|||
match_txids: F,
|
||||
) -> Self
|
||||
where
|
||||
F: Fn(&Txid) -> bool
|
||||
F: Fn(&Txid) -> bool,
|
||||
{
|
||||
let matches: Vec<bool> = block_txids
|
||||
.iter()
|
||||
.map(match_txids)
|
||||
.collect();
|
||||
let matches: Vec<bool> = block_txids.iter().map(match_txids).collect();
|
||||
|
||||
let pmt = PartialMerkleTree::from_txids(block_txids, &matches);
|
||||
MerkleBlock {
|
||||
header: *header,
|
||||
txn: pmt,
|
||||
}
|
||||
MerkleBlock { header: *header, txn: pmt }
|
||||
}
|
||||
|
||||
/// Extract the matching txid's represented by this partial merkle tree
|
||||
|
@ -503,8 +483,7 @@ impl MerkleBlock {
|
|||
|
||||
impl Encodable for MerkleBlock {
|
||||
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
||||
let len = self.header.consensus_encode(w)?
|
||||
+ self.txn.consensus_encode(w)?;
|
||||
let len = self.header.consensus_encode(w)? + self.txn.consensus_encode(w)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
@ -520,22 +499,19 @@ impl Decodable for MerkleBlock {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use core::cmp::min;
|
||||
|
||||
use crate::hashes::Hash;
|
||||
use crate::hashes::hex::{FromHex, ToHex};
|
||||
use crate::hash_types::{Txid, TxMerkleNode};
|
||||
use secp256k1::rand::prelude::*;
|
||||
|
||||
use super::*;
|
||||
use crate::consensus::encode::{deserialize, serialize};
|
||||
use crate::hash_types::{TxMerkleNode, Txid};
|
||||
use crate::hashes::hex::{FromHex, ToHex};
|
||||
use crate::hashes::Hash;
|
||||
use crate::{merkle_tree, Block};
|
||||
|
||||
/// accepts `pmt_test_$num`
|
||||
fn pmt_test_from_name(name: &str) {
|
||||
pmt_test(name[9..].parse().unwrap())
|
||||
}
|
||||
fn pmt_test_from_name(name: &str) { pmt_test(name[9..].parse().unwrap()) }
|
||||
|
||||
macro_rules! pmt_tests {
|
||||
($($name:ident),* $(,)?) => {
|
||||
|
@ -547,8 +523,20 @@ mod tests {
|
|||
)*
|
||||
}
|
||||
}
|
||||
pmt_tests!(pmt_test_1, pmt_test_4, pmt_test_7, pmt_test_17, pmt_test_56, pmt_test_100,
|
||||
pmt_test_127, pmt_test_256, pmt_test_312, pmt_test_513, pmt_test_1000, pmt_test_4095);
|
||||
pmt_tests!(
|
||||
pmt_test_1,
|
||||
pmt_test_4,
|
||||
pmt_test_7,
|
||||
pmt_test_17,
|
||||
pmt_test_56,
|
||||
pmt_test_100,
|
||||
pmt_test_127,
|
||||
pmt_test_256,
|
||||
pmt_test_312,
|
||||
pmt_test_513,
|
||||
pmt_test_1000,
|
||||
pmt_test_4095
|
||||
);
|
||||
|
||||
fn pmt_test(tx_count: usize) {
|
||||
let mut rng = thread_rng();
|
||||
|
@ -559,7 +547,8 @@ mod tests {
|
|||
|
||||
// Calculate the merkle root and height
|
||||
let hashes = tx_ids.iter().map(|t| t.as_hash());
|
||||
let merkle_root_1: TxMerkleNode = merkle_tree::calculate_root(hashes).expect("hashes is not empty").into();
|
||||
let merkle_root_1: TxMerkleNode =
|
||||
merkle_tree::calculate_root(hashes).expect("hashes is not empty").into();
|
||||
let mut height = 1;
|
||||
let mut ntx = tx_count;
|
||||
while ntx > 1 {
|
||||
|
@ -616,9 +605,7 @@ mod tests {
|
|||
let mut pmt3: PartialMerkleTree = deserialize(&serialized).unwrap();
|
||||
pmt3.damage(&mut rng);
|
||||
let mut match_txid3 = vec![];
|
||||
let merkle_root_3 = pmt3
|
||||
.extract_matches(&mut match_txid3, &mut indexes)
|
||||
.unwrap();
|
||||
let merkle_root_3 = pmt3.extract_matches(&mut match_txid3, &mut indexes).unwrap();
|
||||
assert_ne!(merkle_root_3, merkle_root_1);
|
||||
}
|
||||
}
|
||||
|
@ -632,9 +619,8 @@ mod tests {
|
|||
.map(|i| Txid::from_hex(&format!("{:064x}", i)).unwrap())
|
||||
.collect();
|
||||
|
||||
let matches = vec![
|
||||
false, false, false, false, false, false, false, false, false, true, true, false,
|
||||
];
|
||||
let matches =
|
||||
vec![false, false, false, false, false, false, false, false, false, true, true, false];
|
||||
|
||||
let tree = PartialMerkleTree::from_txids(&txids, &matches);
|
||||
// Should fail due to duplicate txs found
|
||||
|
@ -690,10 +676,7 @@ mod tests {
|
|||
let mut index: Vec<u32> = vec![];
|
||||
|
||||
assert_eq!(
|
||||
merkle_block
|
||||
.txn
|
||||
.extract_matches(&mut matches, &mut index)
|
||||
.unwrap(),
|
||||
merkle_block.txn.extract_matches(&mut matches, &mut index).unwrap(),
|
||||
block.header.merkle_root
|
||||
);
|
||||
assert_eq!(matches.len(), 2);
|
||||
|
@ -723,10 +706,7 @@ mod tests {
|
|||
let mut index: Vec<u32> = vec![];
|
||||
|
||||
assert_eq!(
|
||||
merkle_block
|
||||
.txn
|
||||
.extract_matches(&mut matches, &mut index)
|
||||
.unwrap(),
|
||||
merkle_block.txn.extract_matches(&mut matches, &mut index).unwrap(),
|
||||
block.header.merkle_root
|
||||
);
|
||||
assert_eq!(matches.len(), 0);
|
||||
|
|
|
@ -16,17 +16,15 @@
|
|||
|
||||
mod block;
|
||||
|
||||
use core::cmp::min;
|
||||
use core::iter;
|
||||
|
||||
use crate::prelude::*;
|
||||
pub use block::{MerkleBlock, MerkleBlockError, PartialMerkleTree};
|
||||
|
||||
use crate::io;
|
||||
use core::cmp::min;
|
||||
|
||||
use crate::hashes::Hash;
|
||||
use crate::consensus::encode::Encodable;
|
||||
|
||||
pub use block::{MerkleBlock, PartialMerkleTree, MerkleBlockError};
|
||||
use crate::hashes::Hash;
|
||||
use crate::io;
|
||||
use crate::prelude::*;
|
||||
|
||||
/// Calculates the merkle root of a list of *hashes*, inline (in place) in `hashes`.
|
||||
///
|
||||
|
@ -60,7 +58,7 @@ pub fn calculate_root<T, I>(mut hashes: I) -> Option<T>
|
|||
where
|
||||
T: Hash + Encodable,
|
||||
<T as Hash>::Engine: io::Write,
|
||||
I: Iterator<Item=T>,
|
||||
I: Iterator<Item = T>,
|
||||
{
|
||||
let first = hashes.next()?;
|
||||
let second = match hashes.next() {
|
||||
|
@ -94,7 +92,7 @@ where
|
|||
<T as Hash>::Engine: io::Write,
|
||||
{
|
||||
if hashes.len() == 1 {
|
||||
return hashes[0]
|
||||
return hashes[0];
|
||||
}
|
||||
|
||||
for idx in 0..((hashes.len() + 1) / 2) {
|
||||
|
@ -112,12 +110,11 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::blockdata::block::Block;
|
||||
use crate::consensus::encode::deserialize;
|
||||
use crate::hashes::sha256d;
|
||||
|
||||
use crate::blockdata::block::Block;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn both_merkle_root_functions_return_the_same_result() {
|
||||
// testnet block 000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b
|
||||
|
|
Loading…
Reference in New Issue