>
-where
- B: BlockT,
- C: ProvideRuntimeApi + Send + Sync + 'static,
- C::Api: AuraApi,
- P: Pair,
- P::Public: Encode + Decode,
- P::Signature: Encode + Decode,
-{
- // load authorities
- let authorities = client.runtime_api().authorities(parent_hash).map_err(Box::new)?;
-
- // Determine the current slot.
- let slot_now = slot_now(slot_duration);
-
- // Try to claim the slot locally.
- let author_pub = {
- let res = aura_internal::claim_slot::(slot_now, &authorities, keystore).await;
- match res {
- Some(p) => p,
- None => return Ok(None),
- }
- };
-
- // Produce the pre-digest.
- let pre_digest = aura_internal::pre_digest::
(slot_now);
-
- Ok(Some(SlotClaim { author_pub, pre_digest }))
-}
-
-async fn create_inherent_data(
- relay_parent: PHash,
- validation_data: &PersistedValidationData,
- parent_hash: B::Hash,
- para_id: ParaId,
- relay_chain_interface: &impl RelayChainInterface,
- create_inherent_data_providers: &impl CreateInherentDataProviders,
-) -> Result<(ParachainInherentData, InherentData), Box> {
- let paras_inherent_data = ParachainInherentData::create_at(
- relay_parent,
- relay_chain_interface,
- validation_data,
- para_id,
- )
- .await;
-
- let paras_inherent_data = match paras_inherent_data {
- Some(p) => p,
- None =>
- return Err(format!("Could not create paras inherent data at {:?}", relay_parent).into()),
- };
-
- let other_inherent_data = create_inherent_data_providers
- .create_inherent_data_providers(parent_hash, ())
- .map_err(|e| e as Box)
- .await?
- .create_inherent_data()
- .await
- .map_err(Box::new)?;
-
- Ok((paras_inherent_data, other_inherent_data))
-}
-
-fn seal(
- pre_sealed: B,
- storage_changes: StorageChanges>,
- author_pub: &P::Public,
- keystore: &KeystorePtr,
-) -> Result, Box>
-where
- P: Pair,
- P::Signature: Encode + Decode + TryFrom>,
- P::Public: AppPublic,
-{
- let (pre_header, body) = pre_sealed.deconstruct();
- let pre_hash = pre_header.hash();
- let block_number = *pre_header.number();
-
- // seal the block.
- let block_import_params = {
- let seal_digest =
- aura_internal::seal::<_, P>(&pre_hash, &author_pub, keystore).map_err(Box::new)?;
- let mut block_import_params = BlockImportParams::new(BlockOrigin::Own, pre_header);
- block_import_params.post_digests.push(seal_digest);
- block_import_params.body = Some(body.clone());
- block_import_params.state_action =
- StateAction::ApplyChanges(sc_consensus::StorageChanges::Changes(storage_changes));
- block_import_params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
- block_import_params
- };
- let post_hash = block_import_params.post_hash();
-
- tracing::info!(
- target: crate::LOG_TARGET,
- "🔖 Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.",
- block_number,
- post_hash,
- pre_hash,
- );
-
- Ok(block_import_params)
-}
-
-struct Verifier {
- client: Arc,
- create_inherent_data_providers: CIDP,
- slot_duration: SlotDuration,
- telemetry: Option,
- _marker: std::marker::PhantomData<(Block, P)>,
-}
-
-#[async_trait::async_trait]
-impl VerifierT for Verifier
-where
- P: Pair,
- P::Signature: Encode + Decode,
- P::Public: Encode + Decode + PartialEq + Clone + Debug,
- Block: BlockT,
- Client: ProvideRuntimeApi + Send + Sync,
- >::Api: BlockBuilderApi + AuraApi,
-
- CIDP: CreateInherentDataProviders,
-{
- async fn verify(
- &mut self,
- mut block_params: BlockImportParams,
- ) -> Result, String> {
- // Skip checks that include execution, if being told so, or when importing only state.
- //
- // This is done for example when gap syncing and it is expected that the block after the gap
- // was checked/chosen properly, e.g. by warp syncing to this block using a finality proof.
- if block_params.state_action.skip_execution_checks() || block_params.with_state() {
- return Ok(block_params)
- }
-
- let post_hash = block_params.header.hash();
- let parent_hash = *block_params.header.parent_hash();
-
- // check seal and update pre-hash/post-hash
- {
- let authorities = aura_internal::fetch_authorities(self.client.as_ref(), parent_hash)
- .map_err(|e| {
- format!("Could not fetch authorities at {:?}: {}", parent_hash, e)
- })?;
-
- let slot_now = slot_now(self.slot_duration);
- let res = aura_internal::check_header_slot_and_seal::(
- slot_now,
- block_params.header,
- &authorities,
- );
-
- match res {
- Ok((pre_header, _slot, seal_digest)) => {
- telemetry!(
- self.telemetry;
- CONSENSUS_TRACE;
- "aura.checked_and_importing";
- "pre_header" => ?pre_header,
- );
-
- block_params.header = pre_header;
- block_params.post_digests.push(seal_digest);
- block_params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
- block_params.post_hash = Some(post_hash);
- },
- Err(aura_internal::SealVerificationError::Deferred(hdr, slot)) => {
- telemetry!(
- self.telemetry;
- CONSENSUS_DEBUG;
- "aura.header_too_far_in_future";
- "hash" => ?post_hash,
- "a" => ?hdr,
- "b" => ?slot,
- );
-
- return Err(format!(
- "Rejecting block ({:?}) from future slot {:?}",
- post_hash, slot
- ))
- },
- Err(e) =>
- return Err(format!(
- "Rejecting block ({:?}) with invalid seal ({:?})",
- post_hash, e
- )),
- }
- }
-
- // check inherents.
- if let Some(body) = block_params.body.clone() {
- let block = Block::new(block_params.header.clone(), body);
- let create_inherent_data_providers = self
- .create_inherent_data_providers
- .create_inherent_data_providers(parent_hash, ())
- .await
- .map_err(|e| format!("Could not create inherent data {:?}", e))?;
-
- let inherent_data = create_inherent_data_providers
- .create_inherent_data()
- .await
- .map_err(|e| format!("Could not create inherent data {:?}", e))?;
-
- let inherent_res = self
- .client
- .runtime_api()
- .check_inherents(parent_hash, block, inherent_data)
- .map_err(|e| format!("Unable to check block inherents {:?}", e))?;
-
- if !inherent_res.ok() {
- for (i, e) in inherent_res.into_errors() {
- match create_inherent_data_providers.try_handle_error(&i, &e).await {
- Some(res) => res.map_err(|e| format!("Inherent Error {:?}", e))?,
- None =>
- return Err(format!(
- "Unknown inherent error, source {:?}",
- String::from_utf8_lossy(&i[..])
- )),
- }
- }
- }
- }
-
- Ok(block_params)
- }
-}
-
-/// Start an import queue for a Cumulus node which checks blocks' seals and inherent data.
-///
-/// Pass in only inherent data providers which don't include aura or parachain consensus inherents,
-/// e.g. things like timestamp and custom inherents for the runtime.
-///
-/// The others are generated explicitly internally.
-///
-/// This should only be used for runtimes where the runtime does not check all inherents and
-/// seals in `execute_block` (see )
-pub fn fully_verifying_import_queue(
- client: Arc,
- block_import: I,
- create_inherent_data_providers: CIDP,
- slot_duration: SlotDuration,
- spawner: &impl sp_core::traits::SpawnEssentialNamed,
- registry: Option<&substrate_prometheus_endpoint::Registry>,
- telemetry: Option,
-) -> BasicQueue
-where
- P: Pair,
- P::Signature: Encode + Decode,
- P::Public: Encode + Decode + PartialEq + Clone + Debug,
- I: BlockImport
- + ParachainBlockImportMarker
- + Send
- + Sync
- + 'static,
- I::Transaction: Send,
- Client: ProvideRuntimeApi + Send + Sync + 'static,
- >::Api: BlockBuilderApi + AuraApi,
- CIDP: CreateInherentDataProviders + 'static,
-{
- let verifier = Verifier:: {
- client,
- create_inherent_data_providers,
- slot_duration,
- telemetry,
- _marker: std::marker::PhantomData,
- };
-
- BasicQueue::new(verifier, Box::new(block_import), None, spawner, registry)
-}