/// Schedules the given batches
///
/// Performs the following actions:
/// * Verifies all batches' signers are permitted to make transactions
/// * Verifies that none of the batches or transactions are already committed or scheduled
/// * Verifies that all transaction dependencies are satisfied
/// * Verifies that the batches don't violate the block validation rules
/// * Schedules all batches for the candidate block
Schedules the given batches
Performs the following actions:
Verifies all batches' signers are permitted to make transactions
Verifies that none of the batches or transactions are already committed or scheduled
Verifies that all transaction dependencies are satisfied
Verifies that the batches don't violate the block validation rules
Schedules all batches for the candidate block
Schedules the given batches Performs the following actions : Verifies all batches ' signers are permitted to make transactions Verifies that none of the batches or transactions are already committed or scheduled Verifies that all transaction dependencies are satisfied Verifies that the batches don ' t violate the block validation rules Schedules all batches for the candidate block
fn schedule_batches(
    batches: Vec<BatchPair>,
    commit_store: &CommitStore,
    candidate_block: &mut CandidateBlock,
) -> Result<(), BlockPublisherError> {
    'batch: for batch in batches {
        let batch_id = batch.batch().header_signature().to_string();
        let txn_ids = batch.header().transaction_ids().to_vec();
        // Verify that the batch signer is permitted to make transactions based on the current
        // state
        if !candidate_block
            .permission_verifier
            .is_batch_signer_authorized(&batch)?
        {
            debug!(
                "Batch signer is not authorized, dropping batch: {}",
                batch_id
            );
            continue;
        }
        // Validate that the batch is not a duplicate
        if candidate_block.scheduled_batch_ids.contains(&batch_id) {
            debug!(
                "Dropping duplicate of already-scheduled batch: {}",
                batch_id
            );
            continue;
        }
        if commit_store.contains_batch(&batch_id)? {
            debug!(
                "Dropping duplicate of already-committed batch: {}",
                batch_id
            );
            continue;
        }
        // Validate that no transactions are duplicates and that all dependencies are satisfied
        for (i, txn) in batch.batch().transactions().iter().enumerate() {
            if candidate_block.scheduled_txn_ids.contains(&txn_ids[i]) {
                debug!(
                    "Transaction already scheduled in another batch, rejecting \
                     batch/transaction: ({}, {})",
                    batch_id,
                    txn.header_signature(),
                );
                continue 'batch;
            }
            if commit_store.contains_transaction(txn.header_signature())? {
                debug!(
                    "Transaction already committed, rejecting batch/transaction: ({}, {})",
                    batch_id,
                    txn.header_signature(),
                );
                continue 'batch;
            }
            let txn_header = match txn.clone().into_pair() {
                Ok(txn_pair) => txn_pair.take().1,
                Err(_) => {
                    debug!(
                        "Invalid transaction header, rejecting batch/transaction: ({}, {})",
                        batch_id,
                        txn.header_signature(),
                    );
                    continue 'batch;
                }
            };
            for dep in txn_header.dependencies() {
                let dep_str = hex::encode(dep);
                if !candidate_block.scheduled_txn_ids.contains(dep)
                    && !commit_store.contains_transaction(&dep_str)?
                {
                    debug!(
                        "Missing dependency {}, rejecting batch/transaction: ({}, {})",
                        dep_str,
                        batch_id,
                        txn.header_signature(),
                    );
                    continue 'batch;
                }
            }
        }
        match candidate_block
            .validation_rule_enforcer
            .add_batches(vec![batch.batch()])
        {
            Ok(true) => {}
            Ok(false) => {
                debug!(
                    "Block validation rules violated, rejecting batch: {}",
                    batch_id
                );
                continue;
            }
            Err(ValidationRuleEnforcerError::InvalidBatches(_)) => {
                debug!("Rejecting invalid batch: {}", batch_id);
                continue;
            }
            Err(err) => return Err(BlockPublisherError::Internal(err.to_string())),
        }
        if batch.batch().trace() {
            trace!("TRACE {}: scheduling", batch_id);
        }
        match candidate_block.scheduler.add_batch(batch) {
            Ok(_) => {
                candidate_block.scheduled_batch_ids.push(batch_id);
                candidate_block
                    .scheduled_txn_ids
                    .extend(txn_ids.into_iter());
            }
            Err(SchedulerError::DuplicateBatch(_)) => {} // Ignore duplicate batch
            Err(err) => return Err(BlockPublisherError::Internal(err.to_string())),
        }
    }
    Ok(())
}
fn schedule_batches ( batches : Vec < BatchPair > , commit_store : & CommitStore , candidate_block : & mut CandidateBlock , ) -> Result < ( ) , BlockPublisherError > { ' batch : for batch in batches { let batch_id = batch . batch ( ) . header_signature ( ) . to_string ( ) ; let txn_ids = batch . header ( ) . transaction_ids ( ) . to_vec ( ) ; // Verify that the batch signer is permitted to make transactions based on the current // state if ! candidate_block . permission_verifier . is_batch_signer_authorized ( & batch ) ? { debug ! ( " " batch_id ) ; continue ; } // Validate that the batch is not a duplicate if candidate_block . scheduled_batch_ids . contains ( & batch_id ) { debug ! ( " " batch_id ) ; continue ; } if commit_store . contains_batch ( & batch_id ) ? { debug ! ( " " batch_id ) ; continue ; } // Validate that no transactions are duplicates and that all dependencies are satisfied for ( i , txn ) in batch . batch ( ) . transactions ( ) . iter ( ) . enumerate ( ) { if candidate_block . scheduled_txn_ids . contains ( & txn_ids [ i ] ) { debug ! ( " \
 " batch_id txn header_signature ( ) ) ; continue ' batch ; } if commit_store . contains_transaction ( txn . header_signature ( ) ) ? { debug ! ( " " batch_id txn header_signature ( ) ) ; continue ' batch ; } let txn_header = match txn . clone ( ) . into_pair ( ) { Ok ( txn_pair ) => txn_pair . take ( ) . 1 , Err ( _ ) => { debug ! ( " " batch_id txn header_signature ( ) ) ; continue ' batch ; } } ; for dep in txn_header . dependencies ( ) { let dep_str = hex :: encode ( dep ) ; if ! candidate_block . scheduled_txn_ids . contains ( dep ) && ! commit_store . contains_transaction ( & dep_str ) ? { debug ! ( " " dep_str batch_id txn header_signature ( ) ) ; continue ' batch ; } } } match candidate_block . validation_rule_enforcer . add_batches ( vec ! [ batch batch ( ) ] ) { Ok ( true ) => { } Ok ( false ) => { debug ! ( " " batch_id ) ; continue ; } Err ( ValidationRuleEnforcerError :: InvalidBatches ( _ ) ) => { debug ! ( " " batch_id ) ; continue ; } Err ( err ) => return Err ( BlockPublisherError :: Internal ( err . to_string ( ) ) ) , } if batch . batch ( ) . trace ( ) { trace ! ( " " batch_id ) ; } match candidate_block . scheduler . add_batch ( batch ) { Ok ( _ ) => { candidate_block . scheduled_batch_ids . push ( batch_id ) ; candidate_block . scheduled_txn_ids . extend ( txn_ids . into_iter ( ) ) ; } Err ( SchedulerError :: DuplicateBatch ( _ ) ) => { } // Ignore duplicate batch Err ( err ) => return Err ( BlockPublisherError :: Internal ( err . to_string ( ) ) ) , } } Ok ( ( ) ) }
Schedules the given batches
Performs the following actions:
 Verifies all batches' signers are permitted to make transactions
 Verifies that none of the batches or transactions are already committed or scheduled
 Verifies that all transaction dependencies are satisfied
 Verifies that the batches don't violate the block validation rules
 Schedules all batches for the candidate block
Schedules the given batches Performs the following actions : Verifies all batches ' signers are permitted to make transactions Verifies that none of the batches or transactions are already committed or scheduled Verifies that all transaction dependencies are satisfied Verifies that the batches don ' t violate the block validation rules Schedules all batches for the candidate block
batches
Vec<BatchPair>
commit_store
&CommitStore
candidate_block
&mut CandidateBlock