fn import_many_blocks<B: BlockT, V: Verifier<B>, Transaction>(
	import_handle: BoxBlockImport<B, Transaction>,
	blocks_origin: BlockOrigin,
	blocks: Vec<IncomingBlock<B>>,
	verifier: V,
	delay_between_blocks: Duration,
	metrics: Option<Metrics>,
) -> impl Future<
	Output = (
		usize,
		usize,
		Vec<(Result<BlockImportResult<NumberFor<B>>, BlockImportError>, B::Hash)>,
		BoxBlockImport<B, Transaction>,
		V,
	),
> {
	let count = blocks.len();

	let blocks_range = match (
		blocks.first().and_then(|b| b.header.as_ref().map(|h| h.number())),
		blocks.last().and_then(|b| b.header.as_ref().map(|h| h.number())),
	) {
		(Some(first), Some(last)) if first != last => format!(" ({}..{})", first, last),
		(Some(first), Some(_)) => format!(" ({})", first),
		_ => Default::default(),
	};

	trace!(target: "sync", "Starting import of {} blocks {}", count, blocks_range);

	let mut imported = 0;
	let mut results = vec![];
	let mut has_error = false;
	let mut blocks = blocks.into_iter();
	let mut import_handle = Some(import_handle);
	let mut waiting = None;
	let mut verifier = Some(verifier);

	// Blocks in the response/drain should be in ascending order.

	future::poll_fn(move |cx| {
		// Handle the optional timer that makes us wait before the next import.
		if let Some(waiting) = &mut waiting {
			match Future::poll(Pin::new(waiting), cx) {
				Poll::Ready(_) => {},
				Poll::Pending => return Poll::Pending,
			}
		}
		waiting = None;

		// Is there any block left to import?
		let block = match blocks.next() {
			Some(b) => b,
			None => {
				// No block left to import, success!
				let import_handle = import_handle.take()
					.expect("Future polled again after it has finished (import handle is None)");
				let verifier = verifier.take()
					.expect("Future polled again after it has finished (verifier handle is None)");
				let results = mem::replace(&mut results, Vec::new());
				return Poll::Ready((imported, count, results, import_handle, verifier));
			},
		};

		// We extract the content of `import_handle` and `verifier` only when the future ends,
		// therefore `import_handle` and `verifier` are always `Some` here. It is illegal to poll
		// a `Future` again after it has ended.
		let import_handle = import_handle.as_mut()
			.expect("Future polled again after it has finished (import handle is None)");
		let verifier = verifier.as_mut()
			.expect("Future polled again after it has finished (verifier handle is None)");

		let block_number = block.header.as_ref().map(|h| h.number().clone());
		let block_hash = block.hash;
		let import_result = if has_error {
			Err(BlockImportError::Cancelled)
		} else {
			// The actual import.
			import_single_block_metered(
				&mut **import_handle,
				blocks_origin.clone(),
				block,
				verifier,
				metrics.clone(),
			)
		};

		if let Some(metrics) = metrics.as_ref() {
			metrics.report_import::<B>(&import_result);
		}

		if import_result.is_ok() {
			trace!(target: "sync", "Block imported successfully {:?} ({})", block_number, block_hash);
			imported += 1;
		} else {
			has_error = true;
		}

		results.push((import_result, block_hash));

		// Notifies the current task again so that we re-execute this closure again for the next
		// block.
		if delay_between_blocks != Duration::new(0, 0) {
			waiting = Some(Delay::new(delay_between_blocks));
		}
		cx.waker().wake_by_ref();
		Poll::Pending
	})
}
/// Import several blocks at once, returning import result for each block.
///
/// For lifetime reasons, the `BlockImport` implementation must be passed by value, and is yielded
/// back in the output once the import is finished.
///
/// The returned `Future` yields at every imported block, which makes the execution more
/// fine-grained and making it possible to interrupt the process.
Import several blocks at once, returning import result for each block.
For lifetime reasons, the `BlockImport` implementation must be passed by value, and is yielded
back in the output once the import is finished.

The returned `Future` yields at every imported block, which makes the execution more
fine-grained and making it possible to interrupt the process.
Import several blocks at once returning import result for each block . For lifetime reasons the ` BlockImport ` implementation must be passed by value and is yielded back in the output once the import is finished . The returned ` Future ` yields at every imported block which makes the execution more fine - grained and making it possible to interrupt the process .
fn import_many_blocks<B: BlockT, V: Verifier<B>, Transaction>(
	import_handle: BoxBlockImport<B, Transaction>,
	blocks_origin: BlockOrigin,
	blocks: Vec<IncomingBlock<B>>,
	verifier: V,
	delay_between_blocks: Duration,
	metrics: Option<Metrics>,
) -> impl Future<
	Output = (
		usize,
		usize,
		Vec<(Result<BlockImportResult<NumberFor<B>>, BlockImportError>, B::Hash)>,
		BoxBlockImport<B, Transaction>,
		V,
	),
> {
	let count = blocks.len();
	let blocks_range = match (
		blocks.first().and_then(|b| b.header.as_ref().map(|h| h.number())),
		blocks.last().and_then(|b| b.header.as_ref().map(|h| h.number())),
	) {
		(Some(first), Some(last)) if first != last => format!(" ({}..{})", first, last),
		(Some(first), Some(_)) => format!(" ({})", first),
		_ => Default::default(),
	};
	trace!(target: "sync", "Starting import of {} blocks {}", count, blocks_range);
	let mut imported = 0;
	let mut results = vec![];
	let mut has_error = false;
	let mut blocks = blocks.into_iter();
	let mut import_handle = Some(import_handle);
	let mut waiting = None;
	let mut verifier = Some(verifier);
	// Blocks in the response/drain should be in ascending order.
	future::poll_fn(move |cx| {
		// Handle the optional timer that makes us wait before the next import.
		if let Some(waiting) = &mut waiting {
			match Future::poll(Pin::new(waiting), cx) {
				Poll::Ready(_) => {},
				Poll::Pending => return Poll::Pending,
			}
		}
		waiting = None;
		// Is there any block left to import?
		let block = match blocks.next() {
			Some(b) => b,
			None => {
				// No block left to import, success!
				let import_handle = import_handle.take()
					.expect("Future polled again after it has finished (import handle is None)");
				let verifier = verifier.take()
					.expect("Future polled again after it has finished (verifier handle is None)");
				let results = mem::replace(&mut results, Vec::new());
				return Poll::Ready((imported, count, results, import_handle, verifier));
			},
		};
		// We extract the content of `import_handle` and `verifier` only when the future ends,
		// therefore `import_handle` and `verifier` are always `Some` here. It is illegal to poll
		// a `Future` again after it has ended.
		let import_handle = import_handle.as_mut()
			.expect("Future polled again after it has finished (import handle is None)");
		let verifier = verifier.as_mut()
			.expect("Future polled again after it has finished (verifier handle is None)");
		let block_number = block.header.as_ref().map(|h| h.number().clone());
		let block_hash = block.hash;
		let import_result = if has_error {
			Err(BlockImportError::Cancelled)
		} else {
			// The actual import.
			import_single_block_metered(
				&mut **import_handle,
				blocks_origin.clone(),
				block,
				verifier,
				metrics.clone(),
			)
		};
		if let Some(metrics) = metrics.as_ref() {
			metrics.report_import::<B>(&import_result);
		}
		if import_result.is_ok() {
			trace!(target: "sync", "Block imported successfully {:?} ({})", block_number, block_hash);
			imported += 1;
		} else {
			has_error = true;
		}
		results.push((import_result, block_hash));
		// Notifies the current task again so that we re-execute this closure again for the next
		// block.
		if delay_between_blocks != Duration::new(0, 0) {
			waiting = Some(Delay::new(delay_between_blocks));
		}
		cx.waker().wake_by_ref();
		Poll::Pending
	})
}
fn import_many_blocks < B : BlockT , V : Verifier < B > , Transaction > ( import_handle : BoxBlockImport < B , Transaction > , blocks_origin : BlockOrigin , blocks : Vec < IncomingBlock < B > > , verifier : V , delay_between_blocks : Duration , metrics : Option < Metrics > , ) -> impl Future < Output = ( usize , usize , Vec < ( Result < BlockImportResult < NumberFor < B > > , BlockImportError > , B :: Hash ) > , BoxBlockImport < B , Transaction > , V , ) , > { let count = blocks . len ( ) ; let blocks_range = match ( blocks . first ( ) . and_then ( | b | b . header . as_ref ( ) . map ( | h | h . number ( ) ) ) , blocks . last ( ) . and_then ( | b | b . header . as_ref ( ) . map ( | h | h . number ( ) ) ) , ) { ( Some ( first ) , Some ( last ) ) if first != last => format ! ( " " first last ) , ( Some ( first ) , Some ( _ ) ) => format ! ( " " first ) , _ => Default :: default ( ) , } ; trace ! ( target " " " " count blocks_range ) ; let mut imported = 0 ; let mut results = vec ! [ ] ; let mut has_error = false ; let mut blocks = blocks . into_iter ( ) ; let mut import_handle = Some ( import_handle ) ; let mut waiting = None ; let mut verifier = Some ( verifier ) ; // Blocks in the response/drain should be in ascending order. future :: poll_fn ( move | cx | { // Handle the optional timer that makes us wait before the next import. if let Some ( waiting ) = & mut waiting { match Future :: poll ( Pin :: new ( waiting ) , cx ) { Poll :: Ready ( _ ) => { } , Poll :: Pending => return Poll :: Pending , } } waiting = None ; // Is there any block left to import? let block = match blocks . next ( ) { Some ( b ) => b , None => { // No block left to import, success! let import_handle = import_handle . take ( ) . expect ( " " ) ; let verifier = verifier . take ( ) . expect ( " " ) ; let results = mem :: replace ( & mut results , Vec :: new ( ) ) ; return Poll :: Ready ( ( imported , count , results , import_handle , verifier ) ) ; } , } ; // We extract the content of `import_handle` and `verifier` only when the future ends, // therefore `import_handle` and `verifier` are always `Some` here. It is illegal to poll // a `Future` again after it has ended. let import_handle = import_handle . as_mut ( ) . expect ( " " ) ; let verifier = verifier . as_mut ( ) . expect ( " " ) ; let block_number = block . header . as_ref ( ) . map ( | h | h . number ( ) . clone ( ) ) ; let block_hash = block . hash ; let import_result = if has_error { Err ( BlockImportError :: Cancelled ) } else { // The actual import. import_single_block_metered ( & mut * * import_handle , blocks_origin . clone ( ) , block , verifier , metrics . clone ( ) , ) } ; if let Some ( metrics ) = metrics . as_ref ( ) { metrics . report_import :: < B > ( & import_result ) ; } if import_result . is_ok ( ) { trace ! ( target " " " " block_number block_hash ) ; imported += 1 ; } else { has_error = true ; } results . push ( ( import_result , block_hash ) ) ; // Notifies the current task again so that we re-execute this closure again for the next // block. if delay_between_blocks != Duration :: new ( 0 , 0 ) { waiting = Some ( Delay :: new ( delay_between_blocks ) ) ; } cx . waker ( ) . wake_by_ref ( ) ; Poll :: Pending } ) }
Import several blocks at once, returning import result for each block.
Import several blocks at once returning import result for each block .
import_handle
BoxBlockImport<B, Transaction>
blocks_origin
BlockOrigin
blocks
Vec<IncomingBlock<B>>
verifier
V
delay_between_blocks
Duration
metrics
Option<Metrics>
import_handle
BoxBlockImport<B, Transaction>
blocks_origin
BlockOrigin
blocks
Vec<IncomingBlock<B>>
verifier
V
delay_between_blocks
Duration
metrics
Option<Metrics>