pub fn finalize_block(&self, consensus_data: Vec<u8>) -> Result<String, BlockPublisherError> {
        let mut candidate_block_opt = self
            .candidate_block
            .lock()
            .map_err(|_| BlockPublisherError::Internal("Candidate block lock poisoned".into()))?;

        if let Some(mut candidate_block) = candidate_block_opt.take() {
            match self.complete_candidate_block(&mut candidate_block) {
                Ok(_) => {}
                Err(err) => {
                    // If the block was just empty, put it back so the caller can try again later
                    if let BlockPublisherError::BlockCompletionFailed(
                        BlockCompletionError::BlockEmpty,
                    ) = err
                    {
                        candidate_block_opt.replace(candidate_block);
                    }
                    return Err(err);
                }
            }

            // Remove all batches from the pool that were executed for this block
            let executed_batch_ids = candidate_block
                .valid_batches
                .iter()
                .chain(candidate_block.invalid_batches.iter())
                .map(|batch| batch.header_signature())
                .collect::<HashSet<_>>();
            self.pending_batches
                .write()
                .map_err(|_| BlockPublisherError::Internal("Pending Batches lock poisoned".into()))?
                .update(executed_batch_ids);

            let state_root_hash = candidate_block.state_root_hash.ok_or_else(|| {
                BlockPublisherError::Internal(
                    "Candidate block completed but state root hash not set".into(),
                )
            })?;

            let block = BlockBuilder::new()
                .with_block_num(candidate_block.previous_block.header().block_num() + 1)
                .with_previous_block_id(
                    candidate_block
                        .previous_block
                        .block()
                        .header_signature()
                        .to_string(),
                )
                .with_consensus(consensus_data)
                .with_state_root_hash(hex::decode(state_root_hash)?)
                .with_batches(candidate_block.valid_batches)
                .build_pair(&*self.signer)?;

            let block_id = block.block().header_signature().to_string();

            let publishing_details = BlockPublishingDetails {
                injected_batch_ids: candidate_block.injected_batch_ids.into_iter().collect(),
            };

            self.block_broadcaster
                .broadcast(block, publishing_details)?;

            Ok(block_id)
        } else {
            Err(BlockCompletionError::BlockNotInitialized.into())
        }
    }
/// Completes the in-progress block, broadcasts it to the network, and returns its ID
///
/// Any batches that were scheduled but have not yet been executed will be descheduled.
///
/// # Errors
///
/// * Returns a `BlockNotInitialized` error if there is no in-progress block
/// * Returns a `BlockEmpty` error if there are no valid, non-injected batches in the block. In
///   this case, the block is not completed and any unexecuted batches are added back to the
///   scheduler; the caller will need to wait for these batches to be executed or new batches
///   to be submitted and executed before they can successfully finalize the block.
Completes the in-progress block, broadcasts it to the network, and returns its ID
Any batches that were scheduled but have not yet been executed will be descheduled.
Completes the in - progress block broadcasts it to the network and returns its ID Any batches that were scheduled but have not yet been executed will be descheduled .
pub fn finalize_block(&self, consensus_data: Vec<u8>) -> Result<String, BlockPublisherError> {
        let mut candidate_block_opt = self
            .candidate_block
            .lock()
            .map_err(|_| BlockPublisherError::Internal("Candidate block lock poisoned".into()))?;
        if let Some(mut candidate_block) = candidate_block_opt.take() {
            match self.complete_candidate_block(&mut candidate_block) {
                Ok(_) => {}
                Err(err) => {
                    // If the block was just empty, put it back so the caller can try again later
                    if let BlockPublisherError::BlockCompletionFailed(
                        BlockCompletionError::BlockEmpty,
                    ) = err
                    {
                        candidate_block_opt.replace(candidate_block);
                    }
                    return Err(err);
                }
            }
            // Remove all batches from the pool that were executed for this block
            let executed_batch_ids = candidate_block
                .valid_batches
                .iter()
                .chain(candidate_block.invalid_batches.iter())
                .map(|batch| batch.header_signature())
                .collect::<HashSet<_>>();
            self.pending_batches
                .write()
                .map_err(|_| BlockPublisherError::Internal("Pending Batches lock poisoned".into()))?
                .update(executed_batch_ids);
            let state_root_hash = candidate_block.state_root_hash.ok_or_else(|| {
                BlockPublisherError::Internal(
                    "Candidate block completed but state root hash not set".into(),
                )
            })?;
            let block = BlockBuilder::new()
                .with_block_num(candidate_block.previous_block.header().block_num() + 1)
                .with_previous_block_id(
                    candidate_block
                        .previous_block
                        .block()
                        .header_signature()
                        .to_string(),
                )
                .with_consensus(consensus_data)
                .with_state_root_hash(hex::decode(state_root_hash)?)
                .with_batches(candidate_block.valid_batches)
                .build_pair(&*self.signer)?;
            let block_id = block.block().header_signature().to_string();
            let publishing_details = BlockPublishingDetails {
                injected_batch_ids: candidate_block.injected_batch_ids.into_iter().collect(),
            };
            self.block_broadcaster
                .broadcast(block, publishing_details)?;
            Ok(block_id)
        } else {
            Err(BlockCompletionError::BlockNotInitialized.into())
        }
    }
pub fn finalize_block ( & self , consensus_data : Vec < u8 > ) -> Result < String , BlockPublisherError > { let mut candidate_block_opt = self . candidate_block . lock ( ) . map_err ( | _ | BlockPublisherError :: Internal ( " " . into ( ) ) ) ? ; if let Some ( mut candidate_block ) = candidate_block_opt . take ( ) { match self . complete_candidate_block ( & mut candidate_block ) { Ok ( _ ) => { } Err ( err ) => { // If the block was just empty, put it back so the caller can try again later if let BlockPublisherError :: BlockCompletionFailed ( BlockCompletionError :: BlockEmpty , ) = err { candidate_block_opt . replace ( candidate_block ) ; } return Err ( err ) ; } } // Remove all batches from the pool that were executed for this block let executed_batch_ids = candidate_block . valid_batches . iter ( ) . chain ( candidate_block . invalid_batches . iter ( ) ) . map ( | batch | batch . header_signature ( ) ) . collect :: < HashSet < _ > > ( ) ; self . pending_batches . write ( ) . map_err ( | _ | BlockPublisherError :: Internal ( " " . into ( ) ) ) ? . update ( executed_batch_ids ) ; let state_root_hash = candidate_block . state_root_hash . ok_or_else ( | | { BlockPublisherError :: Internal ( " " . into ( ) , ) } ) ? ; let block = BlockBuilder :: new ( ) . with_block_num ( candidate_block . previous_block . header ( ) . block_num ( ) + 1 ) . with_previous_block_id ( candidate_block . previous_block . block ( ) . header_signature ( ) . to_string ( ) , ) . with_consensus ( consensus_data ) . with_state_root_hash ( hex :: decode ( state_root_hash ) ? ) . with_batches ( candidate_block . valid_batches ) . build_pair ( & * self . signer ) ? ; let block_id = block . block ( ) . header_signature ( ) . to_string ( ) ; let publishing_details = BlockPublishingDetails { injected_batch_ids : candidate_block . injected_batch_ids . into_iter ( ) . collect ( ) , } ; self . block_broadcaster . broadcast ( block , publishing_details ) ? ; Ok ( block_id ) } else { Err ( BlockCompletionError :: BlockNotInitialized . into ( ) ) } }
Completes the in-progress block, broadcasts it to the network, and returns its ID
Any batches that were scheduled but have not yet been executed will be descheduled.
Completes the in - progress block broadcasts it to the network and returns its ID Any batches that were scheduled but have not yet been executed will be descheduled .
&self
consensus_data
Vec<u8>
&self
consensus_data
Vec<u8>
errors
Returns a `BlockNotInitialized` error if there is no in-progress block
Returns a `BlockEmpty` error if there are no valid, non-injected batches in the block. In
this case, the block is not completed and any unexecuted batches are added back to the
scheduler; the caller will need to wait for these batches to be executed or new batches
to be submitted and executed before they can successfully finalize the block.
Returns a ` BlockNotInitialized ` error if there is no in - progress block Returns a ` BlockEmpty ` error if there are no valid non - injected batches in the block . In this case the block is not completed and any unexecuted batches are added back to the scheduler ; the caller will need to wait for these batches to be executed or new batches to be submitted and executed before they can successfully finalize the block .