pub fn start_slot_worker<B, C, W, SO, SC, OnExit>(
	slot_duration: SlotDuration,
	client: Arc<C>,
	worker: Arc<W>,
	sync_oracle: SO,
	on_exit: OnExit,
	inherent_data_providers: InherentDataProviders,
) -> Result<impl Future<Item=(), Error=()>, consensus_common::Error> where
	B: Block,
	C: ChainHead<B>,
	W: SlotWorker<B>,
	SO: SyncOracle + Send + Clone,
	SC: SlotCompatible,
	OnExit: Future<Item=(), Error=()>,
{
	worker.on_start(slot_duration.0)?;

	let make_authorship = move || {
		let client = client.clone();
		let worker = worker.clone();
		let sync_oracle = sync_oracle.clone();
		let SlotDuration(slot_duration) = slot_duration;
		let inherent_data_providers = inherent_data_providers.clone();

		// rather than use a timer interval, we schedule our waits ourselves
		Slots::<SC>::new(slot_duration, inherent_data_providers)
			.map_err(|e| debug!(target: "aura", "Faulty timer: {:?}", e))
			.for_each(move |slot_info| {
				let client = client.clone();
				let worker = worker.clone();
				let sync_oracle = sync_oracle.clone();

				// only propose when we are not syncing.
				if sync_oracle.is_major_syncing() {
					debug!(target: "aura", "Skipping proposal slot due to sync.");
					return Either::B(future::ok(()));
				}

				let slot_num = slot_info.number;
				let chain_head = match client.best_block_header() {
					Ok(x) => x,
					Err(e) => {
						warn!(target: "aura", "Unable to author block in slot {}. \
							no best block header: {:?}", slot_num, e);
						return Either::B(future::ok(()))
					}
				};

				Either::A(
					worker.on_slot(chain_head, slot_info).into_future()
						.map_err(|e| debug!(target: "aura", "Encountered aura error: {:?}", e))
				)
			})
	};

	let work = future::loop_fn((), move |()| {
		let authorship_task = ::std::panic::AssertUnwindSafe(make_authorship());
		authorship_task.catch_unwind().then(|res| {
			match res {
				Ok(Ok(())) => (),
				Ok(Err(())) => warn!("Aura authorship task terminated unexpectedly. Restarting"),
				Err(e) => {
					if let Some(s) = e.downcast_ref::<&'static str>() {
						warn!("Aura authorship task panicked at {:?}", s);
					}

					warn!("Restarting Aura authorship task");
				}
			}

			Ok(future::Loop::Continue(()))
		})
	});

	Ok(work.select(on_exit).then(|_| Ok(())))
}
/// Start a new slot worker.
Start a new slot worker.
Start a new slot worker .
pub fn start_slot_worker<B, C, W, SO, SC, OnExit>(
	slot_duration: SlotDuration,
	client: Arc<C>,
	worker: Arc<W>,
	sync_oracle: SO,
	on_exit: OnExit,
	inherent_data_providers: InherentDataProviders,
) -> Result<impl Future<Item=(), Error=()>, consensus_common::Error> where
	B: Block,
	C: ChainHead<B>,
	W: SlotWorker<B>,
	SO: SyncOracle + Send + Clone,
	SC: SlotCompatible,
	OnExit: Future<Item=(), Error=()>,
{
	worker.on_start(slot_duration.0)?;
	let make_authorship = move || {
		let client = client.clone();
		let worker = worker.clone();
		let sync_oracle = sync_oracle.clone();
		let SlotDuration(slot_duration) = slot_duration;
		let inherent_data_providers = inherent_data_providers.clone();
		// rather than use a timer interval, we schedule our waits ourselves
		Slots::<SC>::new(slot_duration, inherent_data_providers)
			.map_err(|e| debug!(target: "aura", "Faulty timer: {:?}", e))
			.for_each(move |slot_info| {
				let client = client.clone();
				let worker = worker.clone();
				let sync_oracle = sync_oracle.clone();
				// only propose when we are not syncing.
				if sync_oracle.is_major_syncing() {
					debug!(target: "aura", "Skipping proposal slot due to sync.");
					return Either::B(future::ok(()));
				}
				let slot_num = slot_info.number;
				let chain_head = match client.best_block_header() {
					Ok(x) => x,
					Err(e) => {
						warn!(target: "aura", "Unable to author block in slot {}. \
							no best block header: {:?}", slot_num, e);
						return Either::B(future::ok(()))
					}
				};
				Either::A(
					worker.on_slot(chain_head, slot_info).into_future()
						.map_err(|e| debug!(target: "aura", "Encountered aura error: {:?}", e))
				)
			})
	};
	let work = future::loop_fn((), move |()| {
		let authorship_task = ::std::panic::AssertUnwindSafe(make_authorship());
		authorship_task.catch_unwind().then(|res| {
			match res {
				Ok(Ok(())) => (),
				Ok(Err(())) => warn!("Aura authorship task terminated unexpectedly. Restarting"),
				Err(e) => {
					if let Some(s) = e.downcast_ref::<&'static str>() {
						warn!("Aura authorship task panicked at {:?}", s);
					}
					warn!("Restarting Aura authorship task");
				}
			}
			Ok(future::Loop::Continue(()))
		})
	});
	Ok(work.select(on_exit).then(|_| Ok(())))
}
pub fn start_slot_worker < B , C , W , SO , SC , OnExit > ( slot_duration : SlotDuration , client : Arc < C > , worker : Arc < W > , sync_oracle : SO , on_exit : OnExit , inherent_data_providers : InherentDataProviders , ) -> Result < impl Future < Item = ( ) , Error = ( ) > , consensus_common :: Error > where B : Block , C : ChainHead < B > , W : SlotWorker < B > , SO : SyncOracle + Send + Clone , SC : SlotCompatible , OnExit : Future < Item = ( ) , Error = ( ) > , { worker . on_start ( slot_duration . 0 ) ? ; let make_authorship = move | | { let client = client . clone ( ) ; let worker = worker . clone ( ) ; let sync_oracle = sync_oracle . clone ( ) ; let SlotDuration ( slot_duration ) = slot_duration ; let inherent_data_providers = inherent_data_providers . clone ( ) ; // rather than use a timer interval, we schedule our waits ourselves Slots :: < SC > :: new ( slot_duration , inherent_data_providers ) . map_err ( | e | debug ! ( target " " " " e ) ) . for_each ( move | slot_info | { let client = client . clone ( ) ; let worker = worker . clone ( ) ; let sync_oracle = sync_oracle . clone ( ) ; // only propose when we are not syncing. if sync_oracle . is_major_syncing ( ) { debug ! ( target " " " " ) ; return Either :: B ( future :: ok ( ( ) ) ) ; } let slot_num = slot_info . number ; let chain_head = match client . best_block_header ( ) { Ok ( x ) => x , Err ( e ) => { warn ! ( target " " " \
 " slot_num e ) ; return Either :: B ( future :: ok ( ( ) ) ) } } ; Either :: A ( worker . on_slot ( chain_head , slot_info ) . into_future ( ) . map_err ( | e | debug ! ( target " " " " e ) ) ) } ) } ; let work = future :: loop_fn ( ( ) , move | ( ) | { let authorship_task = :: std :: panic :: AssertUnwindSafe ( make_authorship ( ) ) ; authorship_task . catch_unwind ( ) . then ( | res | { match res { Ok ( Ok ( ( ) ) ) => ( ) , Ok ( Err ( ( ) ) ) => warn ! ( " " ) , Err ( e ) => { if let Some ( s ) = e . downcast_ref :: < & ' static str > ( ) { warn ! ( " " s ) ; } warn ! ( " " ) ; } } Ok ( future :: Loop :: Continue ( ( ) ) ) } ) } ) ; Ok ( work . select ( on_exit ) . then ( | _ | Ok ( ( ) ) ) ) }
Start a new slot worker.
Start a new slot worker .
slot_duration
SlotDuration
client
Arc<C>
worker
Arc<W>
sync_oracle
SO
on_exit
OnExit
inherent_data_providers
InherentDataProviders
slot_duration
SlotDuration
client
Arc<C>
worker
Arc<W>
sync_oracle
SO
on_exit
OnExit
inherent_data_providers
InherentDataProviders