1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
use rayon::prelude::{IntoParallelRefIterator, IndexedParallelIterator, ParallelIterator}; use chain::IndexedBlock; use network::Network; use error::Error; use verify_block::BlockVerifier; use verify_header::HeaderVerifier; use verify_transaction::TransactionVerifier; pub struct ChainVerifier<'a> { pub block: BlockVerifier<'a>, pub header: HeaderVerifier<'a>, pub transactions: Vec<TransactionVerifier<'a>>, } impl<'a> ChainVerifier<'a> { pub fn new(block: &'a IndexedBlock, network: Network, current_time: u32) -> Self { trace!(target: "verification", "Block pre-verification {}", block.hash().to_reversed_str()); ChainVerifier { block: BlockVerifier::new(block), header: HeaderVerifier::new(&block.header, network, current_time), transactions: block.transactions.iter().map(TransactionVerifier::new).collect(), } } pub fn check(&self) -> Result<(), Error> { try!(self.block.check()); try!(self.header.check()); try!(self.check_transactions()); Ok(()) } fn check_transactions(&self) -> Result<(), Error> { self.transactions.par_iter() .enumerate() .fold(|| Ok(()), |result, (index, tx)| result.and_then(|_| tx.check().map_err(|err| Error::Transaction(index, err)))) .reduce(|| Ok(()), |acc, check| acc.and(check)) } }