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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
use rayon::prelude::{IntoParallelRefIterator, IndexedParallelIterator, ParallelIterator}; use storage::Store; use network::ConsensusParams; use error::Error; use canon::CanonBlock; use accept_block::BlockAcceptor; use accept_header::HeaderAcceptor; use accept_transaction::TransactionAcceptor; use deployments::BlockDeployments; use duplex_store::DuplexTransactionOutputProvider; use VerificationLevel; pub struct ChainAcceptor<'a> { pub block: BlockAcceptor<'a>, pub header: HeaderAcceptor<'a>, pub transactions: Vec<TransactionAcceptor<'a>>, } impl<'a> ChainAcceptor<'a> { pub fn new(store: &'a Store, consensus: &'a ConsensusParams, verification_level: VerificationLevel, block: CanonBlock<'a>, height: u32, median_time_past: u32, deployments: &'a BlockDeployments) -> Self { trace!(target: "verification", "Block verification {}", block.hash().to_reversed_str()); let output_store = DuplexTransactionOutputProvider::new(store.as_transaction_output_provider(), block.raw()); let headers = store.as_block_header_provider(); ChainAcceptor { block: BlockAcceptor::new(store.as_transaction_output_provider(), consensus, block, height, median_time_past, deployments, headers), header: HeaderAcceptor::new(headers, consensus, block.header(), height, deployments), transactions: block.transactions() .into_iter() .enumerate() .map(|(tx_index, tx)| TransactionAcceptor::new( store.as_transaction_meta_provider(), output_store, consensus, tx, verification_level, block.hash(), height, block.header.raw.time, median_time_past, tx_index, deployments, )) .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)) } }