fn verify_and_store_transactions(store: &mut Store, block: &Block) -> BlockResult<Vec<Record>> {

    let timer = ::std::time::Instant::now();

    // We use chunked parallelization because otherwise we need to clone() the stores on each
    // iteration
    // The main procedure here is to hash and call verify_and_store for each transaction
    let chunks: Vec<_> =
        block.txs.par_chunks(PARALLEL_HASHING_THRESHOLD).map(|chunk_tx| {

        let len = chunk_tx.len();
        let p0  = Instant::now();

        let mut hashes:  Vec<Hash32Buf> = Vec::with_capacity(len); // accurate
        let mut records: Vec<Record>    = Vec::with_capacity(len * 3); // estimate (guessing 2 in per tx)

        let ref mut tx_index = &mut store.tx_index.clone();
        let ref mut tx_store = &mut store.transactions.clone();

        let cloning = Instant::now() - p0;
        let mut chunk_stats =   TransactionStats { cloning: cloning, ..Default::default() };

        for tx in chunk_tx {

            let p1  = Instant::now();

            let hash = Hash32Buf::double_sha256(tx.to_raw());
            hashes.push(hash);

            let p2  = Instant::now();

            let res = tx.verify_and_store(tx_index, tx_store, store.initial_sync, hash.as_ref()).unwrap();

            // AlreadyExists and VerifiedAndStored are both ok here;
            // Extract the TxPtr and the stats
            let (ptr,stats) = match res {
                transaction::TransactionOk::VerifiedAndStored {ptr, stats}  => (ptr, stats),
                transaction::TransactionOk::AlreadyExists     {ptr } => (ptr, Default::default())
            };

            records.push(Record::new_transaction(ptr));
            for rec in tx.get_output_records(tx_index) {
                records.push(rec);
            }

            chunk_stats = chunk_stats + stats;
            chunk_stats.hashing = chunk_stats.hashing + (p2 - p1);
        }
        (chunk_stats, (hashes, records))
    }).collect();


    let p3 = Instant::now();

    // split
    let (stats, hashes_records): (Vec<_>, Vec<_>) = chunks.into_iter().unzip();
    let (hashes, records):       (Vec<_>, Vec<_>) = hashes_records.into_iter().unzip();

    // flatten
    let hashes:  Vec<Hash32Buf> = hashes.into_iter().flat_map(|x| x).collect();
    let records: Vec<Record>    = records.into_iter().flat_map(|x| x).collect();
    let mut stats: TransactionStats = stats.into_iter().sum();

    let rec_count: usize = records.len();
    let tx_count: usize  = hashes.len();


    // check merkle roots
    let calculated_merkle_root = merkle_tree::get_merkle_root(hashes);
    block.verify_merkle_root(calculated_merkle_root.as_ref()).unwrap();
    stats.merkle = Instant::now() - p3;

    let elapsed : usize = timer.elapsed().as_secs() as usize * 1000 +
        timer.elapsed().subsec_nanos() as usize / 1_000_000 as usize;

    if rec_count > 0 && rec_count-tx_count > 0 {
        info!(store.logger, "add_block - transactions done";
            "input_avg_ms" => elapsed as f64 / (rec_count - tx_count) as f64,
            "tx_avg_ms"    => elapsed as f64 / tx_count as f64,
            "tx_stats"     => format!("{:?}", stats));
    }
    Ok(records)
}
/// Verifies and stores the transactions in the block.
/// This does not yet check the order
/// Also verifies the merkle_root & the amounts
///
/// Returns a list fileptrs to the transactions
///
Verifies and stores the transactions in the block.
This does not yet check the order
Also verifies the merkle_root & the amounts

Returns a list fileptrs to the transactions
Verifies and stores the transactions in the block . This does not yet check the order Also verifies the merkle_root & the amounts Returns a list fileptrs to the transactions
fn verify_and_store_transactions(store: &mut Store, block: &Block) -> BlockResult<Vec<Record>> {
    let timer = ::std::time::Instant::now();
    // We use chunked parallelization because otherwise we need to clone() the stores on each
    // iteration
    // The main procedure here is to hash and call verify_and_store for each transaction
    let chunks: Vec<_> =
        block.txs.par_chunks(PARALLEL_HASHING_THRESHOLD).map(|chunk_tx| {
        let len = chunk_tx.len();
        let p0  = Instant::now();
        let mut hashes:  Vec<Hash32Buf> = Vec::with_capacity(len); // accurate
        let mut records: Vec<Record>    = Vec::with_capacity(len * 3); // estimate (guessing 2 in per tx)
        let ref mut tx_index = &mut store.tx_index.clone();
        let ref mut tx_store = &mut store.transactions.clone();
        let cloning = Instant::now() - p0;
        let mut chunk_stats =   TransactionStats { cloning: cloning, ..Default::default() };
        for tx in chunk_tx {
            let p1  = Instant::now();
            let hash = Hash32Buf::double_sha256(tx.to_raw());
            hashes.push(hash);
            let p2  = Instant::now();
            let res = tx.verify_and_store(tx_index, tx_store, store.initial_sync, hash.as_ref()).unwrap();
            // AlreadyExists and VerifiedAndStored are both ok here;
            // Extract the TxPtr and the stats
            let (ptr,stats) = match res {
                transaction::TransactionOk::VerifiedAndStored {ptr, stats}  => (ptr, stats),
                transaction::TransactionOk::AlreadyExists     {ptr } => (ptr, Default::default())
            };
            records.push(Record::new_transaction(ptr));
            for rec in tx.get_output_records(tx_index) {
                records.push(rec);
            }
            chunk_stats = chunk_stats + stats;
            chunk_stats.hashing = chunk_stats.hashing + (p2 - p1);
        }
        (chunk_stats, (hashes, records))
    }).collect();
    let p3 = Instant::now();
    // split
    let (stats, hashes_records): (Vec<_>, Vec<_>) = chunks.into_iter().unzip();
    let (hashes, records):       (Vec<_>, Vec<_>) = hashes_records.into_iter().unzip();
    // flatten
    let hashes:  Vec<Hash32Buf> = hashes.into_iter().flat_map(|x| x).collect();
    let records: Vec<Record>    = records.into_iter().flat_map(|x| x).collect();
    let mut stats: TransactionStats = stats.into_iter().sum();
    let rec_count: usize = records.len();
    let tx_count: usize  = hashes.len();
    // check merkle roots
    let calculated_merkle_root = merkle_tree::get_merkle_root(hashes);
    block.verify_merkle_root(calculated_merkle_root.as_ref()).unwrap();
    stats.merkle = Instant::now() - p3;
    let elapsed : usize = timer.elapsed().as_secs() as usize * 1000 +
        timer.elapsed().subsec_nanos() as usize / 1_000_000 as usize;
    if rec_count > 0 && rec_count-tx_count > 0 {
        info!(store.logger, "add_block - transactions done";
            "input_avg_ms" => elapsed as f64 / (rec_count - tx_count) as f64,
            "tx_avg_ms"    => elapsed as f64 / tx_count as f64,
            "tx_stats"     => format!("{:?}", stats));
    }
    Ok(records)
}
fn verify_and_store_transactions ( store : & mut Store , block : & Block ) -> BlockResult < Vec < Record > > { let timer = :: std :: time :: Instant :: now ( ) ; // We use chunked parallelization because otherwise we need to clone() the stores on each // iteration // The main procedure here is to hash and call verify_and_store for each transaction let chunks : Vec < _ > = block . txs . par_chunks ( PARALLEL_HASHING_THRESHOLD ) . map ( | chunk_tx | { let len = chunk_tx . len ( ) ; let p0 = Instant :: now ( ) ; let mut hashes : Vec < Hash32Buf > = Vec :: with_capacity ( len ) ; // accurate let mut records : Vec < Record > = Vec :: with_capacity ( len * 3 ) ; // estimate (guessing 2 in per tx) let ref mut tx_index = & mut store . tx_index . clone ( ) ; let ref mut tx_store = & mut store . transactions . clone ( ) ; let cloning = Instant :: now ( ) - p0 ; let mut chunk_stats = TransactionStats { cloning : cloning , .. Default :: default ( ) } ; for tx in chunk_tx { let p1 = Instant :: now ( ) ; let hash = Hash32Buf :: double_sha256 ( tx . to_raw ( ) ) ; hashes . push ( hash ) ; let p2 = Instant :: now ( ) ; let res = tx . verify_and_store ( tx_index , tx_store , store . initial_sync , hash . as_ref ( ) ) . unwrap ( ) ; // AlreadyExists and VerifiedAndStored are both ok here; // Extract the TxPtr and the stats let ( ptr , stats ) = match res { transaction :: TransactionOk :: VerifiedAndStored { ptr , stats } => ( ptr , stats ) , transaction :: TransactionOk :: AlreadyExists { ptr } => ( ptr , Default :: default ( ) ) } ; records . push ( Record :: new_transaction ( ptr ) ) ; for rec in tx . get_output_records ( tx_index ) { records . push ( rec ) ; } chunk_stats = chunk_stats + stats ; chunk_stats . hashing = chunk_stats . hashing + ( p2 - p1 ) ; } ( chunk_stats , ( hashes , records ) ) } ) . collect ( ) ; let p3 = Instant :: now ( ) ; // split let ( stats , hashes_records ) : ( Vec < _ > , Vec < _ > ) = chunks . into_iter ( ) . unzip ( ) ; let ( hashes , records ) : ( Vec < _ > , Vec < _ > ) = hashes_records . into_iter ( ) . unzip ( ) ; // flatten let hashes : Vec < Hash32Buf > = hashes . into_iter ( ) . flat_map ( | x | x ) . collect ( ) ; let records : Vec < Record > = records . into_iter ( ) . flat_map ( | x | x ) . collect ( ) ; let mut stats : TransactionStats = stats . into_iter ( ) . sum ( ) ; let rec_count : usize = records . len ( ) ; let tx_count : usize = hashes . len ( ) ; // check merkle roots let calculated_merkle_root = merkle_tree :: get_merkle_root ( hashes ) ; block . verify_merkle_root ( calculated_merkle_root . as_ref ( ) ) . unwrap ( ) ; stats . merkle = Instant :: now ( ) - p3 ; let elapsed : usize = timer . elapsed ( ) . as_secs ( ) as usize * 1000 + timer . elapsed ( ) . subsec_nanos ( ) as usize / 1_000_000 as usize ; if rec_count > 0 && rec_count - tx_count > 0 { info ! ( store logger " " " " elapsed as f64 ( rec_count tx_count ) as f64 " " elapsed as f64 tx_count as f64 " " format ( " " stats ) ) ; } Ok ( records ) }
Verifies and stores the transactions in the block.
Verifies and stores the transactions in the block .
store
&mut Store
block
&Block
store
&mut Store
block
&Block