pub fn execute_user_transaction_block(
    txn_block: Vec<SignedTransaction>,
    runtime: &VMRuntime,
    data_cache: &mut BlockDataCache,
    state_view: &dyn StateView,
) -> Result<Vec<TransactionOutput>, VMStatus> {
    trace!("[VM] Execute block, transaction count: {}", txn_block.len());
    report_block_count(txn_block.len());

    let mode = if data_cache.is_genesis() {
        // The genesis transaction must be in a block of its own.
        if txn_block.len() != 1 {
            return Err(VMStatus::new(StatusCode::REJECTED_WRITE_SET));
        } else {
            ValidationMode::Genesis
        }
    } else {
        ValidationMode::Executing
    };

    let mut result = vec![];

    // If we fail to load the gas schedule, then we fail to process the block.
    let gas_schedule = match runtime.load_gas_schedule(data_cache, state_view) {
        // TODO/XXX: This is a hack to get around not having proper writesets yet. Once that gets
        // in remove this line.
        Err(_) if data_cache.is_genesis() => CostTable::zero(),
        Err(_) => {
            return Err(VMStatus::new(StatusCode::VM_STARTUP_FAILURE)
                .with_sub_status(sub_status::VSF_GAS_SCHEDULE_NOT_FOUND))
        }
        Ok(cost_table) => cost_table,
    };

    let signature_verified_block: Vec<Result<SignatureCheckedTransaction, VMStatus>> = txn_block
        .into_par_iter()
        .map(|txn| {
            txn.check_signature()
                .map_err(|_| VMStatus::new(StatusCode::INVALID_SIGNATURE))
        })
        .collect();

    for transaction in signature_verified_block {
        record_stats! {time_hist | TXN_TOTAL_TIME_TAKEN | {
                let output = match transaction {
                    Ok(t) => transaction_flow(
                        t,
                        runtime,
                        &gas_schedule,
                        data_cache,
                        state_view,
                        mode,
                    ),
                    Err(vm_status) => ExecutedTransaction::discard_error_output(vm_status),
                };
                report_execution_status(output.status());
                data_cache.push_write_set(&output.write_set());

                // `result` is initially empty, a single element is pushed per loop iteration and
                // the number of iterations is bound to the max size of `signature_verified_block`
                assume!(result.len() < usize::max_value());
                result.push(output);

            }
        }
    }
    trace!("[VM] Execute block finished");
    Ok(result)
}
/// Executes a block of `UserTransaction`.
Executes a block of `UserTransaction`.
Executes a block of ` UserTransaction ` .
pub fn execute_user_transaction_block(
    txn_block: Vec<SignedTransaction>,
    runtime: &VMRuntime,
    data_cache: &mut BlockDataCache,
    state_view: &dyn StateView,
) -> Result<Vec<TransactionOutput>, VMStatus> {
    trace!("[VM] Execute block, transaction count: {}", txn_block.len());
    report_block_count(txn_block.len());
    let mode = if data_cache.is_genesis() {
        // The genesis transaction must be in a block of its own.
        if txn_block.len() != 1 {
            return Err(VMStatus::new(StatusCode::REJECTED_WRITE_SET));
        } else {
            ValidationMode::Genesis
        }
    } else {
        ValidationMode::Executing
    };
    let mut result = vec![];
    // If we fail to load the gas schedule, then we fail to process the block.
    let gas_schedule = match runtime.load_gas_schedule(data_cache, state_view) {
        // TODO/XXX: This is a hack to get around not having proper writesets yet. Once that gets
        // in remove this line.
        Err(_) if data_cache.is_genesis() => CostTable::zero(),
        Err(_) => {
            return Err(VMStatus::new(StatusCode::VM_STARTUP_FAILURE)
                .with_sub_status(sub_status::VSF_GAS_SCHEDULE_NOT_FOUND))
        }
        Ok(cost_table) => cost_table,
    };
    let signature_verified_block: Vec<Result<SignatureCheckedTransaction, VMStatus>> = txn_block
        .into_par_iter()
        .map(|txn| {
            txn.check_signature()
                .map_err(|_| VMStatus::new(StatusCode::INVALID_SIGNATURE))
        })
        .collect();
    for transaction in signature_verified_block {
        record_stats! {time_hist | TXN_TOTAL_TIME_TAKEN | {
                let output = match transaction {
                    Ok(t) => transaction_flow(
                        t,
                        runtime,
                        &gas_schedule,
                        data_cache,
                        state_view,
                        mode,
                    ),
                    Err(vm_status) => ExecutedTransaction::discard_error_output(vm_status),
                };
                report_execution_status(output.status());
                data_cache.push_write_set(&output.write_set());
                // `result` is initially empty, a single element is pushed per loop iteration and
                // the number of iterations is bound to the max size of `signature_verified_block`
                assume!(result.len() < usize::max_value());
                result.push(output);
            }
        }
    }
    trace!("[VM] Execute block finished");
    Ok(result)
}
pub fn execute_user_transaction_block ( txn_block : Vec < SignedTransaction > , runtime : & VMRuntime , data_cache : & mut BlockDataCache , state_view : & dyn StateView , ) -> Result < Vec < TransactionOutput > , VMStatus > { trace ! ( " " txn_block len ( ) ) ; report_block_count ( txn_block . len ( ) ) ; let mode = if data_cache . is_genesis ( ) { // The genesis transaction must be in a block of its own. if txn_block . len ( ) != 1 { return Err ( VMStatus :: new ( StatusCode :: REJECTED_WRITE_SET ) ) ; } else { ValidationMode :: Genesis } } else { ValidationMode :: Executing } ; let mut result = vec ! [ ] ; // If we fail to load the gas schedule, then we fail to process the block. let gas_schedule = match runtime . load_gas_schedule ( data_cache , state_view ) { // TODO/XXX: This is a hack to get around not having proper writesets yet. Once that gets // in remove this line. Err ( _ ) if data_cache . is_genesis ( ) => CostTable :: zero ( ) , Err ( _ ) => { return Err ( VMStatus :: new ( StatusCode :: VM_STARTUP_FAILURE ) . with_sub_status ( sub_status :: VSF_GAS_SCHEDULE_NOT_FOUND ) ) } Ok ( cost_table ) => cost_table , } ; let signature_verified_block : Vec < Result < SignatureCheckedTransaction , VMStatus > > = txn_block . into_par_iter ( ) . map ( | txn | { txn . check_signature ( ) . map_err ( | _ | VMStatus :: new ( StatusCode :: INVALID_SIGNATURE ) ) } ) . collect ( ) ; for transaction in signature_verified_block { record_stats ! { time_hist TXN_TOTAL_TIME_TAKEN { let output match transaction { Ok ( t ) transaction_flow ( t runtime gas_schedule data_cache state_view mode ) Err ( vm_status ) ExecutedTransaction discard_error_output ( vm_status ) } report_execution_status ( output status ( ) ) data_cache push_write_set ( output write_set ( ) ) // `result` is initially empty, a single element is pushed per loop iteration and // the number of iterations is bound to the max size of `signature_verified_block` assume ( result len ( ) usize max_value ( ) ) result push ( output ) } } } trace ! ( " " ) ; Ok ( result ) }
Executes a block of `UserTransaction`.
Executes a block of ` UserTransaction ` .
txn_block
Vec<SignedTransaction>
runtime
&VMRuntime
data_cache
&mut BlockDataCache
state_view
&dyn StateView
txn_block
Vec<SignedTransaction>
runtime
&VMRuntime
data_cache
&mut BlockDataCache
state_view
&dyn StateView