diff --git a/availability-store/src/worker.rs b/availability-store/src/worker.rs index d7461cea52901..153f5d5dd9598 100644 --- a/availability-store/src/worker.rs +++ b/availability-store/src/worker.rs @@ -21,8 +21,8 @@ use std::thread; use log::{error, info, trace, warn}; use sp_blockchain::{Result as ClientResult}; -use sp_runtime::traits::{Header as HeaderT, ProvideRuntimeApi}; -use sp_api::{ApiExt, ApiErrorFor}; +use sp_runtime::traits::{Header as HeaderT, ProvideRuntimeApi, Block as BlockT}; +use sp_api::ApiExt; use client::{ BlockchainEvents, BlockBody, blockchain::ProvideCache, @@ -206,30 +206,25 @@ where } -fn fetch_candidates

(client: &P, block: &BlockId, parent: &BlockId) - -> ClientResult>> +fn fetch_candidates

(client: &P, extrinsics: Vec<::Extrinsic>, parent: &BlockId) + -> ClientResult>> where - P: BlockBody + ProvideRuntimeApi, - P::Api: ParachainHost + ApiExt, + P: ProvideRuntimeApi, + P::Api: ParachainHost, { - let extrinsics = client.block_body(block)?; - Ok(match extrinsics { - Some(extrinsics) => { - let api = client.runtime_api(); - - if api.has_api_with::>, _>( - parent, - |version| version >= 2, - ).map_err(|_| ConsensusError::ChainLookup("outdated runtime API".into()))? { - api.get_heads(&parent, extrinsics) - .map_err(|_| ConsensusError::ChainLookup("".into()))? - .map(|v| v.into_iter()) - } else { - None - } - } - None => None, - }) + let api = client.runtime_api(); + + let candidates = if api.has_api_with::, _>( + parent, + |version| version >= 2, + ).map_err(|e| ConsensusError::ChainLookup(e.to_string()))? { + api.get_heads(&parent, extrinsics) + .map_err(|e| ConsensusError::ChainLookup(e.to_string()))? + } else { + None + }; + + Ok(candidates) } /// Creates a task to prune entries in availability store upon block finalization. @@ -244,12 +239,33 @@ where while let Some(notification) = finality_notification_stream.next().await { let hash = notification.hash; let parent_hash = notification.header.parent_hash; + let extrinsics = match client.block_body(&BlockId::hash(hash)) { + Ok(Some(extrinsics)) => extrinsics, + Ok(None) => { + error!( + target: LOG_TARGET, + "No block body found for imported block {:?}", + hash, + ); + continue; + } + Err(e) => { + error!( + target: LOG_TARGET, + "Failed to get block body for imported block {:?}: {:?}", + hash, + e, + ); + continue; + } + }; + let candidate_hashes = match fetch_candidates( &*client, - &BlockId::hash(hash), + extrinsics, &BlockId::hash(parent_hash) ) { - Ok(Some(candidates)) => candidates.map(|c| c.hash()).collect(), + Ok(Some(candidates)) => candidates.into_iter().map(|c| c.hash()).collect(), Ok(None) => { warn!( target: LOG_TARGET, @@ -629,8 +645,7 @@ impl BlockImport for AvailabilityBlockImport where I: BlockImport + Send + Sync, I::Error: Into, P: ProvideRuntimeApi + ProvideCache, - P::Api: ParachainHost, - P::Api: ApiExt, + P::Api: ParachainHost, { type Error = ConsensusError; @@ -656,7 +671,7 @@ impl BlockImport for AvailabilityBlockImport where let our_id = self.our_id(&validators); // Use a runtime API to extract all included erasure-roots from the imported block. - let candidates = self.client.runtime_api().get_heads(&parent_id, extrinsics.clone()) + let candidates = fetch_candidates(&*self.client, extrinsics.clone(), &parent_id) .map_err(|e| ConsensusError::ChainLookup(e.to_string()))?; match candidates { @@ -666,7 +681,8 @@ impl BlockImport for AvailabilityBlockImport where trace!( target: LOG_TARGET, "Our validator id is {}, the candidates included are {:?}", - our_id, candidates + our_id, + candidates, ); for candidate in &candidates {